Compare commits

..
1694 Commits
Author SHA1 Message Date
Cameron Gutman e7a2d9f44d Prepare for v6.0.0 2024-06-05 22:42:28 -05:00
Cameron Gutman ee5d0acc1f Rerun lupdate and lrelease 2024-06-05 00:28:11 -05:00
Cameron Gutman 6a5a69cabd Merge remote-tracking branch 'origin/weblate' 2024-06-05 00:26:59 -05:00
weng weng cd7391f908 Translated using Weblate (Chinese (Simplified))
Currently translated at 96.2% (231 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2024-06-04 02:09:15 +00:00
Cameron Gutman d6d28f1afd Remove unused libplacebo libraries 2024-06-02 21:52:35 -05:00
Cameron Gutman 5a6620a9ae Fix missing installer window icon with WiX 5 2024-06-02 21:40:40 -05:00
Cameron Gutman 5a47ddca33 Use EGL on X11 for non-x86 platforms
In theory we could do this everywhere, but I'd rather not risk major behavior changes on x86 right before a release.
2024-06-02 14:01:54 -05:00
Cameron Gutman b58f021fc8 Only set QT_SSL_USE_TEMPORARY_KEYCHAIN on macOS
It's useless on other platforms.
2024-06-02 13:58:42 -05:00
Cameron Gutman 12b93337d1 Fix SDL_VIDEODRIVER override when the Qt platform plugin was manually set 2024-06-01 22:43:52 -05:00
Cameron Gutman 807fc6b31c Opt out of macOS Game Mode due to various OS bugs
Fixes #1170
Fixes #1297
2024-06-01 16:36:24 -05:00
Cameron Gutman 959080aa95 Update moonlight-common-c with higher IPv6 MTU 2024-06-01 16:30:45 -05:00
Cameron Gutman 18a772aeba Update prebuilt libraries
opus -> 1.5.2
FFmpeg -> 7.0.1
dav1d -> 1.4.2
2024-06-01 16:30:20 -05:00
Cameron Gutman 9bdd17f1c3 Properly clean libavformat files with clean-libs.sh 2024-06-01 16:25:46 -05:00
sanhoe 3d1967bd1e Translated using Weblate (Korean)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2024-06-01 16:41:32 +02:00
Cameron Gutman 469bd32bde Update AppImage to FFmpeg 7.0.1 and dav1d 1.4.2 2024-05-31 20:43:03 -05:00
comsyspro 351b4edf0c Translated using Weblate (German)
Currently translated at 95.8% (230 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2024-05-29 09:09:23 +02:00
Cameron Gutman a0a8b70bc1 Strip session keys and IVs from the logs
Logging these isn't a major issue because they change each session and
the privilege level to access the logs is the same as those to access the
private key of Moonlight client itself, but there's also no good reason to
log them either.
2024-05-27 22:02:02 -04:00
Cameron Gutman e07f069222 Always use the custom logger
It was already used everywhere except macOS Debug builds.
2024-05-27 21:40:18 -04:00
Empotik 47ccd1e481 Translated using Weblate (Thai)
Currently translated at 57.5% (138 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/th/
2024-05-27 23:09:14 +00:00
Cameron Gutman 96fba43186 Add missing AV1 option in CLI video codec options
Fixes #1290
2024-05-27 13:06:49 -04:00
Cameron Gutman 9e7c212c6d Update moonlight-common-c 2024-05-25 18:32:58 -05:00
Cameron Gutman e67d83e097 Move declaration under ifdef to eliminate unused variable warning 2024-05-25 17:01:46 -05:00
Cameron Gutman 4474f815af Only use fallback VDPAU/VAAPI driver paths on AppImages
Native packages and Flatpak/Snap packages both have properly set
driver path values embedded in libva.so/libvdpau.so. Let's not go
splunking for drivers in random folders on those systems.
2024-05-25 14:39:09 -05:00
Cameron Gutman e130a15037 Remove dependency on AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES for VDPAU wrapper identification
These quirks may be deprecated and no longer populated in an upcoming FFmpeg version.
2024-05-25 14:24:31 -05:00
Cameron Gutman 845ef147c9 Add new libva driver path values for Fedora 40 2024-05-25 14:22:43 -05:00
Cameron Gutman fb17c15cfd Update VCRedist 2024-05-25 11:54:29 -05:00
Marocco2 bb74cedf59 Translated using Weblate (Italian)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2024-05-25 15:09:12 +02:00
Mike 9af6906380 Translated using Weblate (Polish)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2024-05-24 08:09:10 +00:00
gallegonovato c1ae3cceda Translated using Weblate (Spanish)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2024-05-24 08:09:10 +00:00
Loïc Hesling e1e3bd512f Translated using Weblate (French)
Currently translated at 100.0% (240 of 240 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-05-24 08:09:09 +00:00
Cameron Gutman cf3ff32340 Rerun lupdate and lrelease 2024-05-23 00:28:10 -07:00
Cameron Gutman 2c98deeae3 Merge remote-tracking branch 'origin/weblate' 2024-05-23 00:26:16 -07:00
Cameron Gutman a572681737 Add --hdr and --no-hdr command-line arguments
Fixes #1287
2024-05-22 23:28:14 -07:00
Cameron Gutman e78b389bc0 Fix passing incorrect 'this' pointer to quitRunningApp()
This worked before due to Qt behavior that was changed in https://codereview.qt-project.org/c/qt/qtdeclarative/+/450393
to generate a warning in this situation. The old behavior remains the default, but this change avoids a warning in the logs.
2024-05-22 23:11:52 -07:00
Роман 83ec929758 Translated using Weblate (Russian)
Currently translated at 83.6% (199 of 238 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2024-05-21 20:02:01 +02:00
Cameron Gutman 9117f6565e Don't clobber existing std handles when attaching to the parent console
Fixes #1270
2024-05-11 23:38:32 -05:00
Cameron Gutman aa33432c81 Detect whether to log to file based upon whether stderr was redirected 2024-05-11 23:24:36 -05:00
Cameron Gutman e25d9b0da2 Only use SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES=0 for native notched resolution
Full-screen and borderless windowed are now fully indistinguishable on macOS to avoid user confusion.

Fixes #861
2024-05-11 19:58:36 -05:00
Cameron Gutman 0dfa8a7b53 Override fullscreen mode if necessary for native resolutions to work as expected
Fixes #1244
2024-05-11 19:55:08 -05:00
Cameron Gutman 85a9f85c54 Add support for listing notch and notchless native resolution options 2024-05-11 19:48:01 -05:00
Cameron Gutman ed68f920f1 Avoid polluting source tree with NuGet cache files during WiX build 2024-05-11 15:08:30 -05:00
Cameron Gutman f9a4498f9b Upgrade to WiX v5.0.0 2024-05-11 15:08:10 -05:00
Cameron Gutman 4d1acf2e30 Don't invoke signal handlers directly
This generates a runtime warning on Qt 6.7
2024-05-06 19:16:10 -07:00
Cameron Gutman db4739b82d Remove warn_off configuration for moonlight-common-c subproject
We can just turn off unused parameter warnings instead of all warnings.
2024-05-05 18:52:21 -05:00
gallegonovato 38bf833708 Translated using Weblate (Spanish)
Currently translated at 100.0% (238 of 238 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2024-05-05 07:07:20 +02:00
Cameron Gutman 364093aef8 Prevent a deadlock if the audio device stops consuming data 2024-05-04 21:22:38 -05:00
Cameron Gutman 6d220a9062 Allow audio to recover if no audio devices were present during stream start 2024-05-04 21:13:00 -05:00
Jorys Paulin abec8b3fe1 Translated using Weblate (French)
Currently translated at 100.0% (238 of 238 strings)

Co-authored-by: Jorys Paulin <paulinjorys5@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
Translation: Moonlight Game Streaming/moonlight-qt
2024-05-02 09:07:13 +02:00
Cameron Gutman 93ed985043 Rerun lupdate and lrelease 2024-04-30 22:53:23 -05:00
Cameron Gutman 23c737cab9 Split details dialog into multiple lines for easier translation 2024-04-30 22:53:23 -05:00
Cameron Gutman cb850f013a Add Central Kurdish language (disabled until it's completed) 2024-04-30 22:53:15 -05:00
Cameron Gutman 6bd964a094 Merge remote-tracking branch 'origin/weblate' 2024-04-30 22:27:09 -05:00
Cameron Gutman 419c788ab5 Remove save() call that is no longer necessary since d1ccd19 2024-04-30 21:42:38 -05:00
Jorys Paulin a412100a11 feat: added show performance overlay preference (#1209) 2024-04-30 21:37:52 -05:00
Cameron Gutman 0531666f38 Apply some minor cosmetic improvements to the details dialog 2024-04-30 21:36:59 -05:00
Jorys Paulin c096238998 Add "View details" to PC list (#1221)
* feat: add view pc details menu item

* feat: show mac address

* fix: cast mac byte array to string
2024-04-30 21:23:25 -05:00
Hans Gaiser 211fec0ff0 Send WOL packet when seeking a computer. 2024-04-30 21:05:33 -05:00
Dylan Frankcom 58e27875ae Fix Raised Black Levels on Steam Deck OLED (#1265)
Add getDecoderColorRange to plvk
2024-04-30 20:31:00 -05:00
Ahmed kurdish 954e6608a1 Added translation using Weblate (Kurdish (Central))
Co-authored-by: Ahmed kurdish <nikogaming500@gmail.com>
2024-04-29 21:06:00 +02:00
Cameron Gutman 1cd588f25c Don't set relative warp mode based on absolute/relative mouse mode
This breaks pointer capture on Wayland when we start in absolute mouse
mode (since warp is not supported on Wayland). It's also confusing to
users because it leads to different relative mouse acceleration curves
based on whether you start a stream in relative mode or not.
2024-04-27 17:13:02 -05:00
Cameron Gutman ebfe035a18 Set SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP=0 to resolve pointer lock issue on Wayland
SDL will try to lock the mouse cursor on Wayland if it's not visible in order to
support applications that assume they can warp the cursor (which isn't possible on
Wayland). We don't want this behavior because it interferes with seamless mouse
mode when toggling between windowed and fullscreen modes by unexpectedly locking
the mouse cursor.
2024-04-27 16:49:51 -05:00
Yutaro Urata 6f22ed13c1 Translated using Weblate (Japanese)
Currently translated at 86.0% (185 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2024-04-24 21:07:16 +02:00
Cameron Gutman 4aa2b8570c Autorelease the system default Metal device 2024-04-19 00:29:51 -05:00
Cameron Gutman fe6562e31c Allow forcing Metal renderer on or off via VT_FORCE_METAL=1 and VT_FORCE_METAL=0 respectively 2024-04-19 00:27:45 -05:00
Cameron Gutman 654e386263 Only pace presentation if display sync is enabled 2024-04-19 00:17:13 -05:00
Cameron Gutman 76d0eb6b63 Avoid trying VDPAU when Vulkan is preferred
The VDPAU renderer causes interoperability issues with Vulkan.
2024-04-18 00:41:24 -05:00
Hans Gaiser 02d867fe09 Log to stderr instead of stdout. 2024-04-17 23:55:38 -05:00
Cameron Gutman 76ff53f09f Move warning dialog checks into the Window's onCompleted() function
The old issue with dialogs appearing behind the main window only impacts the old non-QC2 dialogs,
which we haven't used for several years.
2024-04-14 14:49:35 -05:00
Cameron Gutman 37d92dee16 Revert "Fix hiding the main UI window while streaming on Qt 6.7"
The original issue on Qt 6.7 was caused by conflicts with the window state set in main.qml
which was addressed by afbc49e39a.

The remaining issue with Qt 6.7 clobbering window state and position when hiding a window
looks like a legitimate Qt bug.

This reverts commit ebe270bec5.
2024-04-14 14:08:53 -05:00
Cameron Gutman afbc49e39a Apply the main window visibility property only at startup
Otherwise it can affect the state of the window when showing again streaming
2024-04-14 13:35:41 -05:00
Cameron Gutman d1ccd19fcc Make StreamingPreferences a proper singleton
This removes the need for several hacks in SettingsView to force updates and improves performance by not reloading preferences all over the place.
2024-04-14 13:01:30 -05:00
Cameron Gutman ebe270bec5 Fix hiding the main UI window while streaming on Qt 6.7 2024-04-13 00:05:49 -05:00
Cameron Gutman 784234c857 Fix updating bitrate text upon language change on Qt 6.7 2024-04-13 00:05:11 -05:00
Cameron Gutman 6a85996b4a Clear the minimized state on the Qt window if the SDL window is not minimized 2024-04-07 00:42:51 -05:00
Cameron Gutman c6710f93dc Enable Steam Controller detection on Steam Link
Fixes #697
2024-04-06 20:03:54 -05:00
Cameron Gutman 5e46c4ec2b Update Windows and Mac prebuilt libraries
SDL2 -> 1fa6142
FFmpeg -> 7.0
opus -> 1.5.1
dav1d -> 1.4.1
2024-04-06 19:56:38 -05:00
Cameron Gutman 011feab6ce Add workaround for broken Qt EGLFS card selection logic 2024-04-06 14:35:34 -05:00
Cameron Gutman f8c5d3c0ce Update AppImage libraries
FFmpeg -> 7.0
SDL2 -> 1fa61429
libplacebo -> 7b294350
2024-04-06 12:44:50 -05:00
Cameron Gutman 74d452bf35 Limit mDNS resolution retry count 2024-04-06 12:40:32 -05:00
Cameron Gutman fd2ff61a40 Support Vulkan AV1 decoding with FFmpeg 7.0 2024-04-06 12:31:14 -05:00
Cameron Gutman 8a87a09947 Flush stale gamepad events after checking for unmapped gamepads 2024-03-31 14:56:46 -05:00
Cameron Gutman cf544a8703 Don't reload preferences every time we poll for GUI gamepad input 2024-03-31 14:54:36 -05:00
Cameron Gutman 0e1190a059 Remove Optimus block for modern Nvidia drivers
Now that we use D3D11 and don't fall back to D3D9, it should be safe to allow Optimus again.

This will re-enable Optimus for D3D9 on Windows 8.1, but all of the reported problems were on Windows 10 so it will hopefully be a non-issue.

Fixes #1241
2024-03-28 21:06:15 -05:00
Cameron Gutman f2535f1e6e Avoid D3D9 fallback on lack of codec support unless a D3D11 FL11.0 GPU wasn't found
We'd rather not waste time (and risk crashes) loading the D3D9 driver if the GPU doesn't have the physical decoding hardware at all.
2024-03-26 23:59:18 -05:00
Cameron Gutman cefa567f95 Demote DXVA2 renderer to second pass of hwaccels 2024-03-26 23:04:54 -05:00
Cameron Gutman 9be782ae8e Fix some harmless compiler warnings 2024-03-26 21:59:39 -05:00
Cameron Gutman 610e07d4bd Improve state propagation between Qt and SDL windows 2024-03-26 21:42:13 -05:00
Marcos Del Sol Vives 75eb921a04 Improve VPN heuristics under Windows
The NDIS interface type will now be used also for matching, improving the
heuristics for multiple popular VPN implementations.

Fixes #1233
2024-03-26 01:20:53 -05:00
Cameron Gutman 97bd515b11 Remove leftover preferred Metal device logic 2024-03-26 01:16:57 -05:00
Cameron Gutman a45695a22a Rework Qt window handling during SDL window creation
- Avoids blindly enumeration all top-level windows
- Properly tracks screen changes during the connection process
- Starts stream window minimized if the Qt window was minimized

Fixes #1231
2024-03-24 21:38:54 -05:00
Cameron Gutman 0d67fd1ff0 Batch mouse motion events on the SDL side 2024-03-24 20:35:23 -05:00
Cameron Gutman a093a0ae59 Restore AVSampleDisplayLayer renderer for dGPU/eGPU systems
These sometimes have issues importing decoded frames for Metal rendering.
2024-03-24 17:47:29 -05:00
Cameron Gutman c9ad8ffa69 Stop using true fullscreen mode on Mac
It has numerous issues on modern Macs and seems to get worse every macOS release.
2024-03-24 13:55:43 -05:00
Cameron Gutman 9987914ebb Update SDL_GameControllerDB 2024-03-20 02:04:01 -05:00
Lukas Senionis fbfd6fb462 Update 0001-Vulkan-Don-t-try-to-reuse-old-swapchain.patch to compile with latest changes 2024-03-18 21:54:28 -05:00
Cameron Gutman bec053e3cf Update AppImage dependencies 2024-03-18 01:44:08 -05:00
Cameron Gutman d364b24378 Fix broken on-link detection that caused non-VPN WAN connections to use LAN MTU
Fixes #1101
2024-03-15 20:04:51 -05:00
Jorys Paulin 8c67586cd0 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-03-11 20:01:49 +01:00
Cameron Gutman 89a628a0dd Use 'git apply' instead of 'git am' 2024-03-02 12:18:14 -06:00
Cameron Gutman 4fb9681b7f Update moonlight-common-c 2024-03-02 11:26:54 -06:00
Cameron Gutman c13128ca1d Add libplacebo patch from Chiaki4Deck to resolve AppImage hangs on Steam Deck 2024-03-02 11:25:53 -06:00
Cameron Gutman ceca83346b Use FIFO present mode for VSync 2024-03-02 11:19:52 -06:00
Jorys Paulin fc6c51c75a fix: add explicit width and height to discord icon 2024-02-18 15:28:47 -06:00
Jorys Paulin 161d91acf8 fix: fix discord icon on qt 5 2024-02-18 15:28:47 -06:00
Cameron Gutman 06ef10a2ad Update README to clarify requirements for Vulkan video
See #1186
2024-02-18 15:23:35 -06:00
Cameron Gutman 7b29b22192 Update dependencies
SDL -> df00a7dd4
SDL_ttf -> 2.22.0
FFmpeg -> 3e79074c4 (n6.1)
dav1d -> 1.4.0
libplacebo -> 3ba18d
2024-02-17 16:14:39 -06:00
Cameron Gutman 289a7165b3 Remove dSYM files from macOS app bundle
macdeployqt incorrectly copies these if they are installed, which bloats the final DMG significantly.

See https://bugreports.qt.io/browse/QTBUG-56590
2024-02-17 14:19:05 -06:00
Cameron Gutman 62011c37f4 Fix build with SDL 2.0.20 and earlier
Fixes #1186
2024-02-17 13:31:53 -06:00
Cameron Gutman 919e44b29b Fix __builtin_cpu_supports(aes) for GCC 6-9 2024-02-17 13:28:32 -06:00
Cameron Gutman 32be1b158b Update VCRedist 2024-02-16 23:06:52 -06:00
Cameron Gutman f635860afd Update to WiX 4.0.4 2024-02-16 23:05:58 -06:00
Cameron Gutman 3b078f095b Update AppVeyor image for macOS 2024-02-16 23:01:44 -06:00
Jorys Paulin 72fc7ea31a feat: update discord icon 2024-02-16 22:36:26 -06:00
Vag Ko f4edd1e63a Translated using Weblate (Greek)
Currently translated at 79.5% (171 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/el/
2024-02-12 22:02:05 +01:00
Jorys Paulin 6011384afe Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2024-02-11 10:01:59 +01:00
Cameron Gutman 896456a8ac Wait for command buffer completion before returning from renderFrame() 2024-02-11 00:15:32 -06:00
Cameron Gutman 8959ddbeb6 Rewrite overlay support in Metal renderer to avoid additional subviews
Subviews cause our Metal layer to fall out of the direct composition path on Intel hardware
2024-02-11 00:15:07 -06:00
Cameron Gutman 767215fce5 Rewrite old frame pacing logic for Metal renderer 2024-02-10 22:49:13 -06:00
Cameron Gutman 3ef05f3a35 Completely switch to D3D11VA over DXVA2 for supported GPUs in all scenarios
Fixes #1179
2024-02-09 01:24:03 -06:00
Cameron Gutman 12624bc5c4 Avoid the composited display path for our Metal layer 2024-02-08 18:19:01 -06:00
Cameron Gutman 5bd0dea85d Enable Metal validation in debug builds 2024-02-08 18:07:43 -06:00
Cameron Gutman 80242f2e90 Fix Metal debug layer validation errors 2024-02-08 18:06:46 -06:00
Cameron Gutman cf3e328f9d Add seamless resize support for Metal renderer 2024-02-08 18:05:47 -06:00
Bàn Hải Dương 150002d4d4 Translated using Weblate (Vietnamese)
Currently translated at 90.2% (194 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2024-02-08 16:01:48 +01:00
Cameron Gutman b972a22459 Use SDL helpers to create Metal view 2024-02-07 03:26:09 -06:00
Cameron Gutman db06239018 Rewrite the macOS renderer using CAMetalLayer
This allows v-sync to be disabled on macOS and lets us remove a whole bunch of old hacks.

Further optimizations of the new renderer are still needed.
2024-02-07 02:40:35 -06:00
boogie bdc7d53515 Only give "pixel_format=nv12" option to v4l2m2m or v4l2requests decoders
pixel_format is a global option which changes avctx->pix_fmt to the
given format, and overrides the AV_PIX_FMT_DRM_PRIME requirement of a
decoder. So v4l2 out of tree patches has done some exception which is
not perfectly nice, therefore limit this option only if the given
decoder is v4l2 decoder. Otherwise rockchip mpp based ffmpeg decoders
can not work properly
2024-02-06 00:09:34 -06:00
Cameron Gutman 7f83b79c19 Update AppImage dependencies 2024-02-05 23:11:02 -06:00
Cameron Gutman 47b3aff352 Update moonlight-common-c with RTSP encryption 2024-02-05 23:01:25 -06:00
Cameron Gutman 679f237c1b Update bug report template 2024-02-05 22:16:49 -06:00
Cameron Gutman 3d8de56f25 Add fast AES detection for RISC-V using hwprobe() syscall 2024-01-23 02:28:28 -06:00
Vadym Nekhai 801cebbbc7 Translated using Weblate (Ukrainian)
Currently translated at 35.8% (77 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2024-01-22 06:01:48 +01:00
Cameron Gutman 66fb0465c4 Update moonlight-common-c with finalized encryption changes 2024-01-19 19:05:59 -06:00
Cameron Gutman 8bbc9b2c57 Fix build with old ARM headers and opt-out of fast AES on RISC-V for now 2024-01-15 17:36:57 -06:00
Cameron Gutman be7694dd8b Improve fast AES heuristic for Linux ARM and unknown platforms 2024-01-15 14:16:56 -06:00
Cameron Gutman ce8b24dfa7 Implement fast AES detection logic for Windows and macOS 2024-01-15 13:40:13 -06:00
Cameron Gutman 75ddac54c5 Update moonlight-common-c with new encryption features 2024-01-15 13:35:39 -06:00
Cameron Gutman b01a83ff39 Send pen input as pen events on Windows 2024-01-12 23:40:24 -06:00
Cameron Gutman c3e886fbcc Use drmIoctl() instead of bare ioctl() to handle EINTR/EAGAIN 2024-01-05 18:33:17 -06:00
Cameron Gutman e20d56041e Fix rare race condition in overlay update code 2023-12-31 15:21:18 -06:00
Cameron Gutman 114074bfd8 Don't set HDR metadata on the DXGI swapchain
This is no longer recommended by Microsoft due inconsistencies with display support for HDR metadata.
2023-12-31 15:15:06 -06:00
Cameron Gutman e44e29e7eb Update moonlight-common-c with X-SS-Connect-Data support 2023-12-29 23:15:41 -06:00
Cameron Gutman 03663d5552 Fix integer promotion issue in gamepad state merging 2023-12-29 16:06:53 -06:00
Cameron Gutman dce2a857f7 Merge all gamepad state when in single controller mode 2023-12-28 16:28:40 -06:00
Cameron Gutman 61f71a318e Expose PLVK_DEBUG_EXTRA for enabling extra debug layers 2023-12-27 15:40:01 -06:00
Cameron Gutman 646ce2bf66 Handle occlusion of the Vulkan window without recreating the renderer over and over 2023-12-27 15:36:59 -06:00
Cameron Gutman 2bbae90e2c Revert "Unconditionally override host-reported minimum luminance value"
This reverts commit 770872238d.
2023-12-26 15:46:25 -06:00
Cameron Gutman bb8e229814 Swap buffers in waitToRender() instead of renderFrame() 2023-12-26 15:45:31 -06:00
Cameron Gutman 9ed8252cc6 Display error codes when the connection is terminated 2023-12-22 14:12:59 -06:00
Cameron Gutman 2cef09471b Remove manual hwframe ctx setup for D3D11VA
It was apparently never necessary, since FFmpeg's default behavior of
avcodec_get_hw_frames_parameters() + av_hwframe_ctx_init() makes a
context that exactly matches the one we constructed manually.
2023-12-22 02:45:11 -06:00
Cameron Gutman 2d15382e31 Fix libplacebo renderer build on Windows 2023-12-21 18:12:19 -06:00
Cameron Gutman 770872238d Unconditionally override host-reported minimum luminance value 2023-12-18 16:43:17 -06:00
Cameron Gutman 2a05b890d8 Enable transparent resizing and display changes for supported renderers 2023-12-17 21:15:40 -06:00
Cameron Gutman 481f23b6e9 Remove some dependencies on fixed window and frame sizes 2023-12-17 20:39:26 -06:00
Cameron Gutman 4e7107a09e Use the crop rect from the pl_frame instead of the raw AVFrame dimensions 2023-12-17 19:06:56 -06:00
Cameron Gutman 0223394725 Fix manual codec options when using Vulkan for HDR
For now, we can't switch between GL and Vulkan on a single window, so performing decoder
probes with 8-bit formats may activate EGLRenderer which breaks Vulkan on our window.

It also speeds up stream launch validation for HDR cases in general, since we don't
perform unnecessary decoder probes for 8-bit profiles when the user wanted 10-bit.
2023-12-17 18:53:13 -06:00
Cameron Gutman 058739321c Move vkAcquireNextImageKHR() into waitToRender() so it can overlap with new frame arrival 2023-12-17 16:47:38 -06:00
Cameron Gutman 708bec2937 Rewrite Vulkan device selection logic to handle multi-GPU systems better 2023-12-17 15:46:10 -06:00
Cameron Gutman c939537c5c Synchronize swapchain and pl_frame colorspace values 2023-12-16 17:36:02 -06:00
Cameron Gutman 9497657c83 Fix handling of zero minimum HDR luminance 2023-12-16 17:28:35 -06:00
Cameron Gutman d4050f3a4f Add HDR metadata to each AVFrame 2023-12-16 17:02:53 -06:00
Cameron Gutman c74c4ef041 Fix native Vulkan video decoding (non-imported frames) 2023-12-16 16:21:54 -06:00
Cameron Gutman d75663052d Fix a few minor Vulkan renderer bugs 2023-12-16 16:18:19 -06:00
Cameron Gutman 8f2db99406 Enable libdrm in AppImage FFmpeg build to support DRM-PRIME to Vulkan hwframe mapping 2023-12-14 17:48:45 -06:00
Cameron Gutman 6a58dbb05e Disable 10-bit SDR swapchains on Vulkan due to inconsistent dithering behavior 2023-12-14 17:46:06 -06:00
Cameron Gutman 8aeb976128 Require a test frame for Vulkan video decoding 2023-12-14 17:44:58 -06:00
Cameron Gutman 7d51a4b67d Fix incorrect overlay colors in Vulkan renderer 2023-12-14 17:43:54 -06:00
Cameron Gutman f7d412e3bf Fix FFmpeg configure args 2023-12-14 00:21:39 -06:00
Cameron Gutman 4469c7fae3 Build AppImage with libplacebo and Vulkan video support 2023-12-13 18:26:00 -06:00
Cameron Gutman ee95efc0f1 Improve Vulkan renderer debuggability 2023-12-13 01:08:32 -06:00
Cameron Gutman 3ddc8ad68a Fix crash if pl_vulkan_create() fails 2023-12-13 01:04:54 -06:00
Cameron Gutman 333d97160e Add opt-in for Vulkan rendering for SDR content with PREFER_VULKAN=1 2023-12-13 01:03:27 -06:00
Cameron Gutman aac5ad3fd0 Add a libplacebo-based Vulkan renderer for HDR and Vulkan video decoding support
Vulkan H.264/HEVC video decoding isn't supported with Fedora's Mesa binaries due to
patent issues, so only the VAAPI/DRM-PRIME import path was tested locally with ANV.

HDR video is getting tonemapped to my SDR monitor reasonably, so HDR output probably
works with GameScope but I haven't confirmed yet.

See #1117
2023-12-12 23:54:23 -06:00
Cameron Gutman 1ef083c952 Update moonlight-common-c to remove per-codec bitrate adjustments 2023-12-03 22:21:10 -06:00
Cameron Gutman c63b918bb2 Don't hardcode the server signature length 2023-11-29 21:53:49 -06:00
Jorys Paulin 4dba4ad538 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-11-04 14:32:16 +01:00
NicolasS 83fcad6bd1 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-11-03 13:43:42 +01:00
Jorys Paulin e08178474d Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-11-03 13:43:42 +01:00
Cameron Gutman f374e88bac Update README.md
Added new SBC packages and updated build requirements
2023-11-03 00:13:50 -05:00
Cameron Gutman 3cb169ea26 Fix CUDA build without KMSDRM enabled 2023-11-01 22:49:18 -05:00
Cameron Gutman 58f87e39a9 Prepare for v5.0.1 2023-11-01 21:49:03 -05:00
Cameron Gutman b1c8005d1a Disable libdrm in AppImage build 2023-11-01 21:44:44 -05:00
Cathy J. Fitzpatrick f8a2e22a18 Update moonlight-common-c to eb67a2fd (2023-10-26) 2023-11-01 20:31:19 -05:00
Cameron Gutman 7ea118fbae Fix dark mode on Windows with Qt 6.5+ 2023-11-01 20:30:34 -05:00
Cameron Gutman 2149024c35 Rerun lupdate and lrelease 2023-11-01 20:02:40 -05:00
Cameron Gutman f5d71c8c9a Merge remote-tracking branch 'origin/weblate' 2023-11-01 20:01:25 -05:00
Cameron Gutman e108a05895 Bump WiX SDK to 4.0.2 2023-11-01 19:58:29 -05:00
Cameron Gutman ea8bccd508 Fix typo causing libva-drm only to be enabled if libva-wayland is present 2023-11-01 17:39:24 -05:00
maicolbattistini bca919c48c Translated using Weblate (Italian)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2023-10-21 04:13:46 +00:00
Jorys Paulin 511ffe03b5 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-10-21 04:13:45 +00:00
Cameron Gutman 413993ab6f Bump release date in appstream 2023-10-18 00:45:10 -05:00
Cameron Gutman 948b9c818a Add workarounds for some SDL joystick index issues 2023-10-18 00:42:59 -05:00
Cameron Gutman cf615ea88d Update SDL2 to fix HIDAPI joystick crash 2023-10-18 00:41:53 -05:00
Cameron Gutman 2d1e16fe50 Update moonlight-common-c 2023-10-16 22:42:46 -05:00
Cameron Gutman 089c3d3ad3 Prepare for v5.0.0 2023-10-16 19:04:40 -05:00
Cameron Gutman 63e3fa6609 Disable ATS 2023-10-16 18:13:13 -05:00
Cameron Gutman 8a7fa7e559 Update moonlight-common-c 2023-10-16 18:06:45 -05:00
Cameron Gutman 989a90a0f7 Rerun lupdate and lrelease 2023-10-15 20:30:46 -05:00
Cameron Gutman a707720577 Merge remote-tracking branch 'origin/weblate' 2023-10-15 20:28:04 -05:00
Cameron Gutman eef270de26 Fix HDR with external displays on macOS Sonoma
Fixes #1079
2023-10-15 15:30:41 -05:00
Cameron Gutman 0ac765bc32 Revert SDL audio buffer size on macOS to v4.3.1 value
Fixes #1071
2023-10-15 13:17:00 -05:00
Cameron Gutman e76551cb64 Use the PC name alone as the streaming window title on macOS 2023-10-15 13:15:38 -05:00
Cameron Gutman 4fd902a0d3 Update moonlight-common-c 2023-10-15 13:04:31 -05:00
Cameron Gutman 9cba449092 Add config option to allow EGL usage when built with MMAL 2023-10-15 13:03:47 -05:00
Cameron Gutman 905b2ecf9e Change AV1 bitrate multiplier to match HEVC 2023-10-15 12:51:23 -05:00
Cameron Gutman 53c2c612c9 Add Share+PS combo for clickpad button emulation on PS4/5 controllers 2023-10-14 01:46:50 -05:00
Cameron Gutman 8ffadde9cc Update SDL2 in AppImage for PulseAudio fix and gamepad sensor support 2023-10-14 00:39:42 -05:00
Jorys Paulin f569bf633c Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-10-13 12:01:28 +02:00
Cameron Gutman 6eb5e07007 Fix warnings in 32-bit builds 2023-10-12 19:05:52 -05:00
Cameron Gutman f07201baa9 Update moonlight-common-c 2023-10-12 18:46:35 -05:00
Cameron Gutman 9120fd01a8 Adjust MMAL and RPi workarounds for Pi 5 and Bookworm support 2023-10-12 18:46:11 -05:00
Cameron Gutman c14cc70a6a Also check for V3D compatible IDs 2023-10-08 16:52:54 -05:00
Cameron Gutman a66f91ae3c Update moonlight-common-c 2023-10-08 16:29:59 -05:00
Cameron Gutman 7e4fddbe62 Only block EGL rendering on Pi 4 and earlier
Hopefully Pi 5 is powerful enough to at least render 1080p 60 FPS.
2023-10-08 16:16:33 -05:00
Cameron Gutman 0ff9f8c55a Update dav1d to 1.3.0 2023-10-06 00:26:44 -05:00
Cameron Gutman 6f710faa8e Fix EGL loading in the AppImage 2023-10-05 23:05:07 -05:00
Cameron Gutman 2127e1d90b Allow h264_v4l2m2m to be used in RPi builds if manually specified 2023-10-05 18:37:14 -05:00
Cameron Gutman 9d73aa6b4a Fix DrmRenderer not falling back to swframes if DRM PRIME is available 2023-10-05 18:13:52 -05:00
Cameron Gutman a2f23b7053 Fix automatic VA DRM driver selection with libva 2.20 2023-10-05 18:12:12 -05:00
Cameron Gutman 5974980aff Use BT.709 in DrmRenderer only on Starfive devices 2023-10-05 18:10:36 -05:00
Cameron Gutman 6fa53691aa Fix implicit default constructor warning 2023-10-02 17:42:35 -05:00
Cameron Gutman 49e0679864 Synchronize with possible concurrent writers to the NvComputer object 2023-10-01 17:46:27 -05:00
Cameron Gutman 0976bc39b3 Only reserialize hosts if a serializable attribute changed 2023-10-01 17:28:06 -05:00
Cameron Gutman facd6e4e56 Revert "Batch delayed flushes to improve performance on macOS"
This reverts commit aa74e6930b.
2023-10-01 16:33:14 -05:00
Cameron Gutman d2dc0aa1b1 Don't serialize apps for the host backup
This takes a ton of time on macOS and most of the data is just a local cache anyway
2023-10-01 16:13:22 -05:00
Cameron Gutman aa74e6930b Batch delayed flushes to improve performance on macOS 2023-10-01 15:26:28 -05:00
Jorys Paulin b7811bf196 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-10-01 10:59:44 +00:00
Cameron Gutman 18130fd8de Use BT.601 for planes that lack COLOR_ENCODING properties 2023-09-29 18:30:39 -05:00
Cameron Gutman b6d4f97e96 Check that the chosen plane supports the decoded frame pixel format 2023-09-29 17:22:49 -05:00
Cameron Gutman 0dd0112518 Don't export EGLImages for software frames 2023-09-29 17:20:50 -05:00
Cameron Gutman 5711e6064e Allow reuse of an active plane for devices with only one usable plane per CRTC 2023-09-29 17:19:44 -05:00
Cameron Gutman 517b684f85 Handle EGL driver returning no supported formats or modifiers for DMA-BUF import 2023-09-27 01:31:01 -05:00
Cameron Gutman 39465f6d8a Override some Material 3 colors to improve contrast 2023-09-27 00:51:51 -05:00
Cameron Gutman 738813cbac Add fallback definition for EGLuint64KHR 2023-09-26 23:22:25 -05:00
Cameron Gutman c2778e040a Build fix for old EGL headers 2023-09-26 23:16:22 -05:00
Cameron Gutman 1efdeeb9dc Export composed VA surface layers for EGL import if supported
Importing composed formats is more efficient and performant because it allows
tiled and/or compressed surfaces to be directly sampled by shaders without
requiring a conversion to a linear planar format first.
2023-09-26 22:58:13 -05:00
Cameron Gutman b01dfea343 Refactor EGLImage creation into a separate shared class 2023-09-26 21:03:19 -05:00
Cameron Gutman e143293e91 Update our plist to activate Game Mode on Sonoma 2023-09-26 18:28:14 -05:00
Cameron Gutman f420dc740a Set EGL_IMAGE_PRESERVED_KHR=EGL_TRUE on our EGLImages
They're mapped read-only and may be saved internally as reference frames,
so they must not be modified by the EGL implementation.
2023-09-26 02:38:46 -05:00
Jen Kung-chih 2e532224b7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-09-24 19:59:50 +00:00
Jorys Paulin cb8366a7e5 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-09-24 19:59:49 +00:00
Cameron Gutman fee54a9d76 Update moonlight-common-c to pick up various fixes 2023-09-23 13:33:54 -04:00
Cameron Gutman dc556d3c9b Try to fix Windows build 2023-09-23 13:33:21 -04:00
Cameron Gutman 4fed3802aa Fix signed vs unsigned comparison warning 2023-09-23 11:15:41 -04:00
Cameron Gutman f7bb4611e9 Replace uses of strcpy() and sprintf() 2023-09-23 11:15:21 -04:00
Artur Szulc 57791eec62 Translated using Weblate (Polish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2023-09-22 20:59:07 +00:00
Cameron Gutman e1e3d8e710 Update AppImage to libva 2.20.0 2023-09-20 19:29:43 -05:00
Cameron Gutman 654be492a0 Avoid using LFS64 interfaces with Musl 2023-09-18 20:07:56 -05:00
Cameron Gutman 1df0da4d4a Also use test frame decoding parameters when creating a test renderer 2023-09-14 18:21:53 -05:00
Cameron Gutman 1dd6cdb567 Use the correct width and height of the test frame when performing the test decode
Using the stream resolution instead of the test frame resolution was causing all non-720p streams to fail on the VisionFive 2 board with the wave5 driver.

It also likely fixes a similar interoperability issue with the qcom-venus driver that was reported in #1042
2023-09-14 18:16:45 -05:00
Cameron Gutman edfb3cfdc8 Update OpenSSL to 1.1.1w for Windows and Mac builds 2023-09-12 19:36:48 -05:00
Cameron Gutman c6a8f44640 Don't set currentIndex to -1 while reinitializing
It causes warnings in other code that have property bindings to currentIndex
2023-09-12 19:28:33 -05:00
Cameron Gutman b7301d4415 Rerun lupdate and lrelease 2023-09-12 19:19:31 -05:00
Cameron Gutman 4d668702b5 Merge remote-tracking branch 'origin/weblate' 2023-09-12 19:18:14 -05:00
Cameron Gutman f4b0f4d78f Functionally revert f60e7241
Switching to indirect rendering has a high risk of performance and functionality regressions,
so let's just continue using AVSampleBufferDisplayLayer until we have a Metal renderer
since #973 is fixed.

This isn't an actual revert because we want to still keep the indirect override around.
2023-09-12 18:36:53 -05:00
Cameron Gutman 7100262e09 Update build requirements 2023-09-12 18:26:03 -05:00
Cameron Gutman e516943d53 Guard SDL_ControllerSensorEvent usage by SDL version check 2023-09-12 18:10:06 -05:00
Cameron Gutman fd41226cdd Support fully-planar output in DrmRenderer 2023-09-12 18:08:48 -05:00
Cameron Gutman 47b04eee3e Remove use of deprecated QByteArray::count() 2023-09-12 18:07:44 -05:00
Cameron Gutman 24ee6f96e1 Don't filter SOPS option by active resolutions with Sunshine 2023-09-11 21:25:29 -05:00
Cameron Gutman 6e34c21175 Fix signed integer overflow found by UBSan 2023-09-11 21:23:39 -05:00
Cameron Gutman 64789ea8bc Destroy the VTRenderer before leaving fullscreen
Fixes #973
2023-09-11 21:07:54 -05:00
Cameron Gutman 2ac7176787 Fix a bunch of memory leaks in the VTRenderer
It appears the leaked AVSampleBufferDisplayLayer may be causing the hang in #973
2023-09-11 20:49:35 -05:00
Cameron Gutman b968886594 Round default bitrates to the nearest megabit 2023-09-11 01:18:52 -05:00
Cameron Gutman 2f9c44103b Automatically scroll the SettingsView to ensure the focused item is visible
Also removed old manual scrolling code from SdlGamepadKeyNavigation as it was broken on Qt 6 anyway.
2023-09-11 00:08:20 -05:00
Cameron Gutman e9ed4940cd Interpolate between entries in our default bitrate table 2023-09-10 22:34:20 -05:00
Cameron Gutman 85b5845ebb Switch to Qt 6.5 for Windows ARM64 build 2023-09-10 18:43:51 -05:00
Cameron Gutman 6f4db913aa Update jom and vswhere
jom -> 1.1.4
vswhere -> 3.1.7
2023-09-10 16:55:19 -05:00
Cameron Gutman 2d20c711a6 Move Qt ARM64 patching into the install section 2023-09-10 16:50:41 -05:00
Cameron Gutman 2e829bc85f Fix corecrt_math_defines.h macro redefinition warnings with MSVC Qt 6 builds 2023-09-10 16:48:24 -05:00
Cameron Gutman acddc3cabd Fix ARM64 builds in AppVeyor
We have to replace some files that were built with incorrect paths
2023-09-10 16:32:42 -05:00
Cameron Gutman a16647f16c Always include ARM64 in the installer bundle 2023-09-10 15:16:02 -05:00
Cameron Gutman 3e3f384218 Fix indentation after WiX v4 autoconversion 2023-09-10 15:16:02 -05:00
Cameron Gutman 45a98a391a Produce Windows ARM64 binaries in CI 2023-09-10 15:15:53 -05:00
Cameron Gutman c9992201ce Support building with Qt 6's official ARM64 SDK binaries 2023-09-10 15:06:42 -05:00
Cameron Gutman 80062d262e Remove manual qmlcachegen invocation for internal Qt QML files
It's not safe to always assume we can always precompile everything.
Instead set QML_CACHE_DIR to ensure the files go to our desired location.
2023-09-10 15:03:53 -05:00
Zan 1456 652f7a7710 Translated using Weblate (Hungarian)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2023-09-09 21:55:43 +02:00
gallegonovato 7e7e50ada2 Translated using Weblate (Spanish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-09-09 21:55:42 +02:00
Cameron Gutman 87eba9bb89 Fix build on Qt 5.13 and earlier 2023-09-09 14:22:47 -05:00
Cameron Gutman da1fcd49fc Increase audio buffer size to reduce the chance of underruns 2023-09-09 12:56:05 -05:00
Cameron Gutman c98289a9e7 Use DMA_BUF_IOCTL_SYNC to synchronize swframe copies 2023-09-09 12:19:40 -05:00
Cameron Gutman 1d0b65f798 Log the active SDL audio driver 2023-09-09 11:46:06 -05:00
Cameron Gutman 3094185cd6 Also skip SDL_RENDERER_PRESENTVSYNC on Wayland 2023-09-09 10:41:33 -05:00
Cameron Gutman aaff04167b Only skip SDL_RENDERER_PRESENTVSYNC on Windows
macOS can still tear when using the Metal renderer backend.
2023-09-09 08:00:13 -05:00
Cameron Gutman 21bba02e6f Allow render thread usage with Metal 2023-09-09 07:45:42 -05:00
Cameron Gutman f60e724167 Default to indirect rendering on Apple Silicon
Hopefully the UMA makes the performance impact of reimporting frames negligible
until we can get a proper Metal renderer to replace AVSampleBufferDisplayLayer.
2023-09-09 07:44:11 -05:00
Cameron Gutman 7551e90899 Adjust AV1 surface alignment to match FFmpeg behavior 2023-09-08 23:13:29 -05:00
Cameron Gutman 715429c13c Print error dialogs and warning toasts to the log 2023-09-08 23:00:00 -05:00
Cameron Gutman 7976189d56 Bump macOS nightlies to Qt 6.4 2023-09-08 19:54:58 -05:00
Cameron Gutman 47d1eff45d Don't rasterize layers in fullscreen
The original artifacting bug didn't manifest in fullscreen anyway.
2023-09-08 19:53:01 -05:00
bittin1ddc447d824349b2 073df32b01 Translated using Weblate (Swedish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2023-09-08 11:59:30 +02:00
Zan 1456 e8ec7efa5c Translated using Weblate (Hungarian)
Currently translated at 33.4% (72 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2023-09-08 11:59:29 +02:00
sanhoe f08cdae2b4 Translated using Weblate (Korean)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2023-09-08 11:59:29 +02:00
weng weng 1389d29d8c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-09-08 11:59:28 +02:00
Jorys Paulin d4bfde7906 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-09-08 11:59:28 +02:00
reloxx13 fe73c36958 Translated using Weblate (German)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2023-09-08 11:59:28 +02:00
Cameron Gutman a97f6d90f4 Fix Linux build break 2023-09-08 02:04:15 -05:00
Cameron Gutman 0735f164a8 Revert back to model reset for updating the computer list
It's possible that multiple changes occur in parallel, so we can't rely on receiving them one at a time
even if the callbacks are synchronized. Handling this substantially complicates the logic such that
it's not really worth doing individual insertions and deletions anymore.

This reverts 94d821a4a9 and replaces it with a solution
that is basically the old code except that it properly handles changes to the structure of the list.
2023-09-08 02:02:21 -05:00
Cameron Gutman 9de0c215ba Don't allow custom frame rates below 10 FPS 2023-09-08 00:59:56 -05:00
Cameron Gutman 56474822f7 Don't scale bitrate linearly with frame rate beyond 60 FPS 2023-09-08 00:59:33 -05:00
Cameron Gutman 98b18d89eb Fix libva-x11 build in AppImage 2023-09-06 19:25:42 -05:00
Cameron Gutman 78ea79b95a Quiet new -Wswitch warnings 2023-09-05 22:51:08 -05:00
Cameron Gutman acbe503c12 Fix NVIDIA VAAPI X11 deprioritization check to actually check for X11 2023-09-05 20:46:43 -05:00
Cameron Gutman 0261c41574 Revert "Prefer nvidia-vaapi-driver over VDPAU for AV1"
libvdpau 1.5 has supported this for a while and we'll fall
back to VAAPI if VDPAU doesn't work.

This reverts commit 42960b7bf1.
2023-09-05 20:39:28 -05:00
Cameron Gutman c8182dfab3 Use BT.709 for DrmRenderer 2023-09-05 19:28:22 -05:00
Cameron Gutman 2eee9c019f Force the Material theme since our UI relies on it 2023-09-05 19:25:09 -05:00
Cameron Gutman 9ed40b5d9f Add chroma siting metadata to EGL exported frames 2023-09-05 18:30:01 -05:00
Cameron Gutman ebc4c71c72 Fix handling of non-standard hwaccel decoders that also set AV_CODEC_CAP_HARDWARE 2023-09-04 23:40:59 -05:00
Cameron Gutman dec5a6370e Fix build with Qt 5 2023-09-03 19:42:19 -05:00
Cameron Gutman 519858b708 Link to Sunshine 2023-09-03 18:04:31 -05:00
Cameron Gutman 8fcc4cf7fe Update readme and metadata with new features 2023-09-03 18:03:34 -05:00
Cameron Gutman 2f78350696 Change PC offline overlay to match new Play and Stop icons 2023-09-03 17:44:15 -05:00
FrogTheFrog 85d4037a89 Allow to specify gamepad GUIDs to be ignored when streaming 2023-09-03 16:24:05 -05:00
Cameron Gutman d165bf7498 Sort the host list 2023-09-03 16:20:29 -05:00
Cameron Gutman 94d821a4a9 Process insertions and moves in the ComputerModel without resetting 2023-09-03 16:19:24 -05:00
Cameron Gutman 6a854f7a64 Limit default bitrate to one decimal place 2023-09-02 20:15:18 -05:00
Cameron Gutman d76675f4b1 Fix handling of frame rates below 30 FPS 2023-09-02 20:05:27 -05:00
Cameron Gutman 4a7e43ccb6 Improve play and quit button visibility 2023-09-02 19:57:08 -05:00
Cameron Gutman b53333d1ba Refresh the bitrate text when the language changes 2023-09-02 18:47:42 -05:00
Cameron Gutman f1f3c8bfb9 Rerun lrelease 2023-09-02 18:42:39 -05:00
Cameron Gutman e580e7c672 Prune obsolete strings 2023-09-02 18:42:01 -05:00
Cameron Gutman a62fd96269 Rerun lupdate 2023-09-02 18:41:27 -05:00
Cameron Gutman a1d592bb87 Fix loss of all paired computers if Moonlight is terminated while writing the computer list 2023-09-02 16:43:25 -05:00
Cameron Gutman 83f5f6cefc Don't scale default bitrate further beyond 90 FPS 2023-09-02 15:54:12 -05:00
Cameron Gutman 9166e70524 Replace fixed "unsupported FPS" options with fully custom FPS option
Fixes #1003
2023-09-02 15:53:30 -05:00
Cameron Gutman 41f8fa95fe Rerun lupdate and lrelease 2023-08-29 23:46:18 -05:00
Cameron Gutman b140c21ed9 Merge remote-tracking branch 'origin/weblate' 2023-08-29 23:44:30 -05:00
Cameron Gutman 863712cb6e Update SDL2 to f032e8c1 2023-08-29 23:43:27 -05:00
Cameron Gutman 43f0aa7f06 Update moonlight-common-c 2023-08-29 23:41:56 -05:00
Cameron Gutman 12535d8142 Fix warning when quitting app after streaming is enabled 2023-08-29 18:19:43 -05:00
Cameron Gutman 8cf6a8bc98 Clean up old log files if more than 10 exist 2023-08-29 18:11:27 -05:00
Cameron Gutman 7073dd26de Fix race condition that could cause quit segue to never dismiss
Fixes #1060
2023-08-29 18:10:16 -05:00
Jorys Paulin 66bfd2fad8 Translated using Weblate (French)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-08-22 14:52:37 +02:00
Cameron Gutman bb444f306a Update SDL_GameControllerDB 2023-08-21 21:58:12 -05:00
Cameron Gutman 626fba4a8f Fix DXVA2 chroma subsampling assuming interlaced content 2023-08-19 18:09:07 -05:00
Cameron Gutman 9dc96bda58 Update moonlight-common-c 2023-08-19 18:08:57 -05:00
Cameron Gutman 1a2f1ed620 Enable AV1 RFI on all decoders capable of HEVC RFI 2023-08-13 16:41:48 -05:00
Cameron Gutman 50255dd896 Set Colorspace connector property when streaming HDR 2023-08-09 23:02:43 -05:00
Cameron Gutman c8b9fda258 Fall back to HEVC if AV1 is forced and unavailable
Fixes #1053
2023-08-05 22:56:12 -05:00
sanhoe bb41732e59 Translated using Weblate (Korean)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2023-08-04 17:06:03 +02:00
ld892012 7d9b984747 Translated using Weblate (French)
Currently translated at 96.7% (208 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-08-04 17:06:03 +02:00
Cameron Gutman 7404e5fce2 Prefer D3D11VA for FSE V-Sync off 2023-08-03 19:41:35 -05:00
Cameron Gutman dc5414bd0d Force immediate destruction of the D3D11 swapchain
Possible fix for #959
2023-08-03 19:18:07 -05:00
Cameron Gutman d147d36867 Fix leaking /dev/dri fds on each vaInitialize() failure 2023-08-01 22:53:22 -05:00
Cameron Gutman 7763ec3c5c Fix mapping frames on RPi with 64-bit kernel and 32-bit userland 2023-08-01 22:01:34 -05:00
weng weng c61083ccd9 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-07-26 12:06:20 +02:00
Cameron Gutman 841aeccd6b Don't call QHostInfo::fromName() to "resolve" an IP address literal
Fixes #1037
2023-07-26 01:59:00 -05:00
Cameron Gutman bfcd373eec Add PC name to streaming window title
Fixes #1039
2023-07-23 01:16:24 -05:00
Cameron Gutman 202ef41894 Fix scaling of touch coordinates 2023-07-23 01:13:54 -05:00
Cameron Gutman f112edc3c3 Disable touch feedback when sending touch natively 2023-07-23 00:17:58 -05:00
Cameron Gutman 05fd7b18b9 Update touch API 2023-07-22 17:23:09 -05:00
ns6089 9764174070 Add host processing latency to ffmpeg stats overlay 2023-07-20 22:30:26 -05:00
Luna Jernberg 6b0370f0bc Translated using Weblate (Swedish)
Currently translated at 96.7% (208 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2023-07-19 22:04:39 +02:00
gallegonovato 2e4313e7c3 Translated using Weblate (Spanish)
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-07-19 22:04:39 +02:00
Jen Kung-chih 2684d1874a Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (215 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-07-18 07:04:33 +02:00
Jen Kung-chih 882539a700 Translated using Weblate (Chinese (Traditional))
Currently translated at 97.2% (209 of 215 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-07-18 03:06:10 +02:00
Cameron Gutman 42960b7bf1 Prefer nvidia-vaapi-driver over VDPAU for AV1 2023-07-16 16:54:13 -05:00
Cameron Gutman 333f978186 Add dav1d software AV1 decoder to FFmpeg libraries 2023-07-16 16:41:55 -05:00
Cameron Gutman e7e9df3261 Populate AV1 bitrate multiplier 2023-07-16 15:54:58 -05:00
Cameron Gutman 24dbc96fe5 Regenerate translations 2023-07-16 15:47:31 -05:00
Cameron Gutman abc391f32a Improve AV1 support 2023-07-16 15:38:58 -05:00
Cameron Gutman a589e8e3de Merge remote-tracking branch 'origin/weblate' 2023-07-16 12:31:52 -05:00
Fernando Lopes 39fa9a91b8 Translated using Weblate (Portuguese (Brazil))
Currently translated at 19.6% (41 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2023-07-16 16:02:55 +02:00
Angus Wan e10d98fb79 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-07-16 16:02:55 +02:00
Cameron Gutman d17cdbda93 Replace another QSharedPointer::get() call with Qt 5.10 alternative 2023-07-16 00:18:17 -05:00
Cameron Gutman 2252abefbf Fix build break on Qt 5.10 and earlier 2023-07-16 00:13:09 -05:00
Cameron Gutman ce60a146dc Move RPi decoder hacks to correct location for new selection logic 2023-07-15 15:22:02 -05:00
Cameron Gutman cd4a6f3e17 Rewrite FFmpeg decoder selection logic to dynamically discover compatible decoders
This avoids having to maintain a hardcoded list of all known H.264/HEVC/AV1 decoders
and ensures new/unknown decoders will just work automatically (assuming we have
a renderer that can process their output pixel format).
2023-07-15 15:12:58 -05:00
Cameron Gutman fc5e1ed5d8 Work around broken APT config on AppVeyor Ubuntu2004 image 2023-07-15 01:20:26 -05:00
Cameron Gutman d70b98075e Upgrade AppImage to Ubuntu 20.04 base 2023-07-15 00:47:26 -05:00
Cameron Gutman a4d9952061 Migrate from altool to notarytool for notarization 2023-07-14 21:44:14 -05:00
Cameron Gutman 45e4dfe09c Don't globally install wix.exe in CI anymore 2023-07-14 20:32:18 -05:00
Cameron Gutman 34ba9063ad Move installer signing into MSBuild 2023-07-14 20:31:32 -05:00
Cameron Gutman d5e2d59fe9 Fixes for WiX v4 migration 2023-07-14 20:05:49 -05:00
Cameron Gutman d39bdb28d6 Update AppImage to libva 2.19 2023-07-14 19:55:44 -05:00
Cameron Gutman 8bf5622d21 Upgrade installer to WiX v4 2023-07-14 19:55:00 -05:00
Maciej Błędkowski 9cafd5e099 Translated using Weblate (Polish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2023-07-11 17:50:13 +02:00
gallegonovato d1b3bfd700 Translated using Weblate (Spanish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-07-11 17:50:12 +02:00
Cameron Gutman e60caf06f9 Update libraries
OpenSSL -> 1.1.1u
SDL -> 156c7ba
2023-07-09 17:49:04 -05:00
Cameron Gutman a243c6bb90 Don't build unneeded sources
Fixes #1010
2023-07-09 17:23:21 -05:00
Cameron Gutman 10523a7e27 Correct guards around newer SDL functionality 2023-07-09 16:36:41 -05:00
Casey Korver ea06ec0133 Correct spelling mistakes found with Codespell 2023-07-09 13:21:18 -05:00
jcj83429 e287ebcded Add support for Applications (context menu) key
I'm adding corresponding support in Sunshine
2023-07-08 20:08:02 -05:00
Cameron Gutman 2ee90289a1 Update moonlight-common-c 2023-07-08 19:17:22 -05:00
Cameron Gutman 193df861d1 Update moonlight-common-c 2023-07-05 19:48:25 -05:00
Cameron Gutman 9055496a19 Add AV1 test frames 2023-07-05 19:47:45 -05:00
Cameron Gutman 5424576f73 Ensure serverCodecModeSupport is always non-zero 2023-07-05 19:46:30 -05:00
Cameron Gutman a81c6a1c5e Initial work on AV1 support 2023-07-03 00:45:36 -05:00
Cameron Gutman 53a572a4a4 Add controller motion deduplication and fix gyro units 2023-07-02 19:22:00 -05:00
Cameron Gutman df283d80c6 Implement controller LED and battery protocol extensions 2023-07-02 16:44:41 -05:00
Cameron Gutman b6d203b6dd Pull latest protocol extension changes 2023-06-27 22:51:50 -05:00
Cameron Gutman ef988cc8af Destroy the QMdnsEngine Server and Cache when not polling
These set background timers to refresh state, rebind sockets,
and refresh the cache. This is all stuff that we don't want to
be doing while streaming.
2023-06-21 00:54:11 -05:00
Kung-chih ba46905243 Update SettingsView.qml 2023-06-20 21:58:10 -05:00
Cameron Gutman df0c4c8208 Delete the QNetworkAccessManager when we're done with it
Apparently having this object around can lead to background
network scans happening that cause WiFi perf degradation.
2023-06-20 21:51:28 -05:00
Cameron Gutman e5aaa1fc53 Implement controller arrival events using Sunshine protocol extension 2023-06-18 23:34:28 -05:00
James Le Cuirot 8b6df34d8b Allow forced disabling of features instead of relying on pkg-config
So-called "automagic" behaviour is considered unhelpful by
distributions. A user may unintentionally build Moonlight with VDPAU
support simply because they had that library installed, only for the
whole application to break when they uninstall the library later. This
could happen on any distribution, but it should especially be avoided on
source-based distributions, where the user would not expect the package
manager to encounter such issues.

This commit is best viewed without whitespace changes.
2023-06-18 16:43:16 -05:00
Cameron Gutman 7a719aa886 Allow up to 16 gamepads with Sunshine hosts 2023-06-18 16:39:24 -05:00
Cameron Gutman 9af58af5e4 Implement gyro/accel and touchpad input using Sunshine extension 2023-06-18 16:08:32 -05:00
Cameron Gutman b945c8c2dc Implement trigger rumble using Sunshine protocol extension 2023-06-18 16:04:49 -05:00
Cameron Gutman 2165f56aee Implement full multi-touch support using Sunshine protocol extension 2023-06-18 16:02:21 -05:00
Cameron Gutman e42de9d155 Add extended button support with Sunshine 2023-06-18 16:00:51 -05:00
sanhoe 7fd95b9de2 Translated using Weblate (Korean)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2023-05-22 11:50:36 +02:00
Jorys Paulin a42c85802e Translated using Weblate (French)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2023-05-22 11:50:36 +02:00
shakedex cb3730100d Translated using Weblate (Hebrew)
Currently translated at 2.8% (6 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/he/
2023-04-29 18:51:13 +02:00
Yutaro Urata 7a04d2ad2c Translated using Weblate (Japanese)
Currently translated at 89.4% (187 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2023-04-29 18:51:12 +02:00
shakedex 1f93976919 Translated using Weblate (Hebrew)
Currently translated at 1.4% (3 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/he/
2023-04-27 20:48:43 +02:00
shakedex 0b7505f109 Added translation using Weblate (Hebrew) 2023-04-26 00:54:28 +02:00
Jen Kung-chih 392ca2d8b7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-04-14 18:48:56 +02:00
Cameron Gutman 68daa90b7e Refactor non-hwaccel decoders to use a single list of known codec names 2023-04-02 17:31:31 -05:00
Cameron Gutman fb39ad896e Add h264_omx and hevc_omx decoders used by the Vision Five 2 2023-04-02 17:17:25 -05:00
Simon Nilsson cb199054e3 Translated using Weblate (Swedish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2023-04-01 20:38:06 +02:00
Cameron Gutman 7cf77211b0 Update AppImage to libva 2.18.0 2023-03-28 20:06:09 -05:00
Cameron Gutman a3d1e9a117 Allow negotation of 36 and 48 bit deep color modes 2023-03-27 01:02:50 -05:00
Cameron Gutman 755c7c9895 Set max BPC property when streaming in 10-bit color modes 2023-03-27 00:44:02 -05:00
Cameron Gutman 45b5136233 Update libs for Windows, macOS, and AppImage
SDL2_ttf -> 2.20.2
SDL2 -> b57a6a1a
OpenSSL -> 1.1.1t (eec3403 for WinARM64)
opus -> 8cf872a1
FFmpeg -> 6.0 (with DXVA2/D3D11VA AV1 decoders enabled)
2023-03-26 20:49:25 -05:00
Cameron Gutman f16b5cd337 Expose glslow config option 2023-03-26 20:27:03 -05:00
Cameron Gutman 21cda8141d Always request AV_PIX_FMT_DRM_PRIME to ensure we get it if available 2023-03-26 19:59:12 -05:00
Cameron Gutman 90f26dfa45 Support direct KMSDRM output for platforms with slow GL implementations 2023-03-26 19:46:22 -05:00
Cameron Gutman ba507d8046 Move hw->sw frame mapping into a separate class 2023-03-26 14:41:02 -05:00
Cameron Gutman 5639bcc0f5 Default SDL render driver to GLES2 when using EGLFS
Fixes #868
2023-03-26 13:43:09 -05:00
Cameron Gutman 4cd030582d Allow matching primary planes for direct rendering 2023-03-26 13:28:26 -05:00
Jen Kung-chih 7908076b39 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-03-26 10:40:35 +02:00
Cameron Gutman ca91f9b702 Allow use of the delete key to delete PCs 2023-03-25 16:33:16 -05:00
Jen Kung-chih 0e86af1c9b Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-03-22 09:37:22 +01:00
weng weng c5ad84e2ee Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-03-22 09:37:21 +01:00
gallegonovato bfb5d6e8fe Translated using Weblate (Spanish)
Currently translated at 100.0% (209 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2023-03-20 18:41:02 +01:00
weng weng d63b0b5978 Translated using Weblate (Chinese (Simplified))
Currently translated at 96.6% (202 of 209 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2023-03-20 18:41:02 +01:00
Cameron Gutman 5e6b60bae0 Fix handling of IPv6 literals with port numbers 2023-03-18 14:47:23 -05:00
Cameron Gutman 65b6885c61 Update VCRedist 2023-03-18 14:36:01 -05:00
Cameron Gutman e8ceaa4085 Update SDL_GameControllerDB 2023-03-18 14:34:13 -05:00
Cameron Gutman db2b120b68 Remove unused variable 2023-03-18 14:29:45 -05:00
Cameron Gutman 5f315d0093 Rerun lupdate and lrelease 2023-03-18 14:24:29 -05:00
Cameron Gutman 016b212ff7 Merge remote-tracking branch 'origin/weblate' 2023-03-18 14:22:11 -05:00
Cameron Gutman bccffe09e2 Purge NVIDIA-specific strings 2023-03-18 14:20:51 -05:00
Cameron Gutman a0365c8e1c Evaluate D3D9 quirks before calling CreateDeviceEx() 2023-03-17 00:53:47 -05:00
Cameron Gutman 38156c9f7f Default to D3D11VA on multi-GPU systems 2023-03-13 22:56:28 -05:00
Cameron Gutman 640db09a64 Update moonlight-common-c 2023-03-11 11:45:07 -06:00
Cameron Gutman 5baa8c680a Add upstreamed NV15 format used by Rockchip devices 2023-03-11 11:44:36 -06:00
Cameron Gutman e1c4a488ed Remove mouse throttling code
This should be managed inside moonlight-common-c instead.
2023-03-11 11:40:37 -06:00
Cameron Gutman 332d4433c4 Add horizontal scrolling in mouse emulation mode 2023-03-04 12:28:53 -06:00
Karnosio f5d535b1ef Translated using Weblate (Ukrainian)
Currently translated at 34.1% (71 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2023-02-21 19:36:41 +01:00
Cameron Gutman 35e226273c Tell the host if we want gamepads to persist after disconnection 2023-02-20 16:52:28 -06:00
Cameron Gutman 90e25e60d6 Add FPS values for all attached displays and support custom FPS values
Fixes #926
2023-02-03 00:45:27 -06:00
Cameron Gutman 80659160d3 Consolidate launch and resume and skip FPS hack for Sunshine 2023-02-03 00:36:30 -06:00
Cameron Gutman 5de29928cd Plumb HDR metadata for VideoToolbox 2023-02-02 19:16:18 -06:00
Cameron Gutman c65cea0f66 Update AppImage to libva 2.17 2023-01-17 21:45:29 -06:00
Cameron Gutman b3cfdbb835 Fix DRM renderer build 2023-01-17 21:45:02 -06:00
Cameron Gutman 9c15cceee7 Don't batch mouse motion for Sunshine 2023-01-16 22:01:34 -06:00
Cameron Gutman 8a0142bd0f Plumb HDR metadata and horizontal scrolling with Sunshine 2023-01-16 21:51:18 -06:00
ssantos 3d6e05d8c0 Translated using Weblate (Portuguese)
Currently translated at 94.2% (196 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2023-01-11 16:51:06 +01:00
Jen Kung-chih ddf0e6a935 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (208 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2023-01-02 07:47:19 +01:00
Dan 51852f044e Translated using Weblate (Ukrainian)
Currently translated at 32.6% (68 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-12-21 01:50:35 +01:00
Cameron Gutman 17cad6b3ca Fix a missed ZH_TW rename
Fixes #906
2022-12-15 22:48:44 -06:00
Jen Kung-chih 8912869077 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (208 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-12-07 11:48:30 +01:00
Zaraza225 a2697634ba Translated using Weblate (Ukrainian)
Currently translated at 32.6% (68 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-12-02 21:48:32 +01:00
Cameron Gutman 1bfb798107 Update SDL_GameControllerDB 2022-11-29 19:22:39 -06:00
Suzuran cf60568f53 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (208 of 208 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-11-29 11:47:36 +01:00
Cameron Gutman ddd18fdaf6 Rerun lupdate and lrelease 2022-11-25 14:18:44 -06:00
Cameron Gutman b04bb30930 Rename zh_Hant to zh_TW to match Qt's expected name 2022-11-25 14:18:06 -06:00
Cameron Gutman e41aaf980b Merge remote-tracking branch 'origin/weblate' 2022-11-25 14:06:13 -06:00
happyharryh 46df6601a1 Update translation for dialog buttons
Reference: https://github.com/qt/qttranslations/tree/dev/translations
2022-11-25 14:05:41 -06:00
happyharryh 5eb8b97469 Fix LANG_AUTO for Simplified Chinese 2022-11-25 14:05:41 -06:00
happyharryh 8cd0536fb1 Fix the translation of standard buttons in Dialogs 2022-11-25 14:05:41 -06:00
Zaraza225 99a6789720 Translated using Weblate (Ukrainian)
Currently translated at 30.0% (61 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-11-24 07:47:40 +01:00
Cameron Gutman 92670cc051 Add support for Qt 6's ARM64 qmake.bat 2022-11-21 21:37:16 -06:00
Cameron Gutman 89cbbfc291 Derive target architecture based on Qt path 2022-11-21 21:30:24 -06:00
Cameron Gutman 31869a7da2 Update to SDL 2.26.0 2022-11-21 20:50:44 -06:00
Cameron Gutman 68c6d6c932 Attempt to fix build with SDL 2.26 on systems with old GL headers 2022-11-21 20:32:10 -06:00
Loïc Hesling e4e140fa53 Translated using Weblate (French)
Currently translated at 97.0% (197 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-11-17 12:47:09 +01:00
Cameron Gutman b9709d0825 Fix build without SDL_VIDEO_DRIVER_WAYLAND 2022-11-14 21:11:26 -06:00
Cameron Gutman 324e3dffa0 Update MSVC Redist 2022-11-13 11:41:03 -06:00
Cameron Gutman dd9de3fcb4 Offset the ports used for WOL if the host is using alternate ports 2022-11-13 11:39:28 -06:00
Cameron Gutman 6710d0561a Use current HTTP port if ExternalPort is not present 2022-11-13 11:35:47 -06:00
Translator-3000 a30f97db0d Translated using Weblate (Italian)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-11-13 13:49:04 +01:00
Cameron Gutman cae666b834 Wake pacing queue waiters when Pacer is being destroyed 2022-11-12 15:55:36 -06:00
Cameron Gutman 5970ca49e9 Don't use swap interval on Wayland 2022-11-12 15:45:54 -06:00
Cameron Gutman 6ae6218043 Refactor Pacer to handle both blocking and non-blocking VsyncSources 2022-11-12 15:08:50 -06:00
Cameron Gutman 8e3e19a7f7 Removed unused NullThreadedVsyncSource 2022-11-12 14:30:38 -06:00
Cameron Gutman e3d51fd7f7 Implement a Wayland Vsync source using frame callbacks 2022-11-12 13:03:42 -06:00
Brandon Goldberg 95f5c1d104 Translated using Weblate (Spanish)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-11-09 16:47:06 +01:00
Jen Kung-chih 02a14069a3 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-11-05 14:04:04 +01:00
Cameron Gutman 394f28339e Update v4.3.1 changelog 2022-11-02 20:43:25 -05:00
Cameron Gutman 411998d4e3 Implement detection of local IPv6 addresses 2022-11-02 20:35:41 -05:00
Cameron Gutman 371906445e Prepare for v4.3.1 2022-11-02 19:44:44 -05:00
Cameron Gutman 34d91e58c0 Rerun lupdate and lrelease 2022-11-02 19:34:47 -05:00
Cameron Gutman f3f25bec7a Mark unfinished translation in zh_cn 2022-11-02 19:34:14 -05:00
Cameron Gutman 08d74bea75 Merge remote-tracking branch 'origin/weblate' 2022-11-02 19:30:25 -05:00
Dominik Chrástecký 63f917b317 Translated using Weblate (Czech)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2022-11-03 01:28:51 +01:00
Cameron Gutman 448633ec3c Fix some log messages with extra spaces 2022-11-02 19:25:44 -05:00
Cameron Gutman 09ce3c9ce4 Use CRLF line endings for the log file on Windows 2022-11-02 19:19:00 -05:00
Cameron Gutman 8fcc98102b Limit log by size rather than line count 2022-11-02 19:18:22 -05:00
Cameron Gutman e14075b464 Update moonlight-common-c to fix audio FEC OOS bug 2022-11-01 23:47:51 -05:00
Howard Wu ca89d14ec8 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.5% (202 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-11-02 03:03:38 +01:00
Cameron Gutman 3f51998065 Start the streaming window maximized if the GUI was maximized
Fixes #889
2022-10-30 11:56:15 -05:00
이정희 6e5b6a1a5c Translated using Weblate (Korean)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-10-30 15:02:46 +01:00
sanhoe 660f6c5bbf Translated using Weblate (Korean)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-10-29 06:02:07 +02:00
Cameron Gutman 5034bd72ed Bump v4.3.0 release date 2022-10-27 19:44:58 -05:00
Cameron Gutman 5b7c144796 Add workaround for DWM dark mode bug on Win10 2022-10-27 19:26:51 -05:00
Cameron Gutman e45b6b9b85 Avoid white flash when starting streaming on Windows 2022-10-27 18:18:47 -05:00
Cameron Gutman 245f242fb8 Add support for dark mode on Windows
Fixes #886
2022-10-27 18:12:26 -05:00
Cameron Gutman a6fccf93d1 Use a separate texture for rendering to avoid blending in the alignment padding
Fixes #885
2022-10-26 21:48:55 -05:00
Cameron Gutman 3dcab90752 Fix appdata for v4.3.0 2022-10-25 23:50:33 -05:00
Cameron Gutman 30a5f405f5 Enable HEVC RFI for the FFmpeg software decoder 2022-10-25 23:19:19 -05:00
Cameron Gutman bad1c9628e Prepare for v4.3.0 2022-10-25 23:11:12 -05:00
Cameron Gutman 1ab7bca43f Update SDL in AppImage 2022-10-25 22:47:29 -05:00
Cameron Gutman 7d0a53773c Rerun lupdate and lrelease 2022-10-25 22:45:03 -05:00
Cameron Gutman 789236ee8f Merge remote-tracking branch 'origin/weblate' 2022-10-25 22:44:21 -05:00
weng weng 21cba0b080 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-10-26 05:43:12 +02:00
Cameron Gutman 31eb0891e5 Update moonlight-common-c for improved audio FEC recovery 2022-10-25 22:42:12 -05:00
Cameron Gutman a13f8e7937 Ensure delayed flushes complete during shutdown 2022-10-25 02:43:55 -05:00
Cameron Gutman 5bfe56472f Fix build 2022-10-25 02:08:46 -05:00
Cameron Gutman 16a9ed682e Use a single flush thread for ComputerManager
Some QSettings backends don't like concurrent writes and using a
single thread improves write batching behavior.
2022-10-25 02:07:16 -05:00
Cameron Gutman 59cae610d2 Clarify encoding resolution limit comment 2022-10-25 01:24:57 -05:00
Cameron Gutman 29ac7893d7 Don't enforce the NVENC H.264 resolution limit on Sunshine hosts
Closes #882
2022-10-25 01:18:10 -05:00
Cameron Gutman c8aeca8ace Add an environment variable opt-out for the gamepad quit combo
See #870
2022-10-25 00:27:40 -05:00
Cameron Gutman 3da505c4c6 Minor perf optimization suggested by Clazy 2022-10-25 00:26:03 -05:00
Cameron Gutman 06bc05b708 Rerun lupdate and lrelease 2022-10-25 00:14:22 -05:00
Cameron Gutman a3dc9593c2 Merge remote-tracking branch 'origin/weblate' 2022-10-25 00:10:40 -05:00
Cameron Gutman 18a271a0ec Update moonlight-common-c for improved audio FEC recovery 2022-10-25 00:10:29 -05:00
Cameron Gutman cebd3bf751 Save hosts on a separate thread
QSettings on macOS Ventura performs horribly when saving a lot of values
(like several hosts or a host with a large app list). This change considerably
improves UI performance by moving the long operation off the main thread.
2022-10-25 00:07:07 -05:00
Cameron Gutman cb04925c6e Optimize locking in ComputerManager to reduce reader contention 2022-10-25 00:07:07 -05:00
Cameron Gutman b7a340bd00 Improve locking in NvComputer class 2022-10-24 23:53:02 -05:00
Cameron Gutman 2a0f837120 Stop issuing further HTTP requests when quitting 2022-10-24 23:46:57 -05:00
Cameron Gutman d00bdff495 Update SDL and FFmpeg for AppImage 2022-10-23 16:59:54 -05:00
Cameron Gutman 7e9c977b3d Update moonlight-common-c 2022-10-23 16:55:52 -05:00
reloxx13 1629151528 Translated using Weblate (German)
Currently translated at 100.0% (203 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-10-21 20:05:49 +02:00
reloxx13 24295197bd Translated using Weblate (German)
Currently translated at 98.0% (199 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-10-20 19:02:35 +02:00
Eric 807dd84daa Translated using Weblate (Chinese (Simplified))
Currently translated at 98.5% (200 of 203 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-10-18 13:05:01 +02:00
Cameron Gutman 17848c097c Don't switch between GLX and EGL if EGL worked 2022-10-16 22:57:08 -05:00
Cameron Gutman 563b760d31 Update packages for recent versions of Ubuntu 2022-10-16 22:23:27 -05:00
Cameron Gutman 8465a27a97 Deprioritize VAAPI for Gallium and Nvidia drivers and work around RFI latency bug 2022-10-16 21:51:10 -05:00
Cameron Gutman 255cbd1e7e Fix building with SDL 2.0.20 or earlier 2022-10-15 15:36:09 -05:00
Cameron Gutman 7717749b72 Reduce max queued frames to avoid exhausting the decoder buffer pool 2022-10-15 14:34:42 -05:00
Cameron Gutman 9e4337babf Revert "Increase the number of decoder surfaces for DXVA2/D3D11VA"
This reverts commit 02c781b8f4.
2022-10-15 14:32:12 -05:00
Cameron Gutman 6771877a84 Make scaleSourceToDestinationSurface() idempotent
Deviation between scaling done during window sizing and renderer
viewport configuration can lead to small errors that create visible
artifacts such as a single pixel pillarbox/letterbox on one side.
2022-10-15 13:12:18 -05:00
Cameron Gutman a860bd8dd5 Enable HEVC RFI on Tegra 2022-10-14 23:41:09 -05:00
Cameron Gutman 704ce4ff0c Add environment variable for overriding decoder capabilities 2022-10-14 23:39:49 -05:00
Cameron Gutman 21edcc8113 Add workaround for macOS fullscreen exit bug 2022-10-14 23:01:55 -05:00
Cameron Gutman 125738f13d Cancel overlay update callbacks before destroying VTRenderer 2022-10-14 22:49:33 -05:00
Cameron Gutman 02c781b8f4 Increase the number of decoder surfaces for DXVA2/D3D11VA
We forgot to take into account frames buffered within Moonlight itself
2022-10-14 21:20:35 -05:00
Cameron Gutman 453fe6aea0 Ensure the target window size is always even 2022-10-14 21:09:32 -05:00
Cameron Gutman e0fb7dfd14 Rework window creation, sizing, and fullscreen transition logic
- Fixes window position/size being lost when toggling full-screen
- Fixes initial window size not respecting stream aspect ratio
2022-10-14 20:24:12 -05:00
Cameron Gutman c4012225c2 Rerun lupdate and lrelease 2022-10-14 19:27:04 -05:00
Cameron Gutman 1750243537 Merge remote-tracking branch 'origin/weblate' 2022-10-14 19:26:38 -05:00
Cameron Gutman 84fc5f3008 Use colorspace helper with VAAPI direct rendering 2022-10-14 19:23:51 -05:00
Cameron Gutman 8a224fbae4 Revert "Fix macOS build"
This reverts commit 0928d1fab2.
2022-10-13 01:19:56 -05:00
Cameron Gutman e6c4332445 Revert "Use Rec 2020 colorspace for WCG support even if HDR is off on the host"
Rec 2020 conversion causes colors to be blown out in SDR

This reverts commit 472e8ee92e.
2022-10-13 01:19:49 -05:00
Cameron Gutman 0928d1fab2 Fix macOS build 2022-10-13 01:11:04 -05:00
Cameron Gutman 40dd588bef Use 10-bit format mask instead of hardcoding specific formats 2022-10-13 00:17:05 -05:00
Cameron Gutman 472e8ee92e Use Rec 2020 colorspace for WCG support even if HDR is off on the host 2022-10-13 00:14:10 -05:00
Cameron Gutman c55af7fff3 Add a decoder/renderer callback to specify the desired color range 2022-10-12 23:59:01 -05:00
Cameron Gutman 7a39daf179 Implement Rec 601 Full Range support in SDLRenderer 2022-10-12 23:52:29 -05:00
Cameron Gutman 8d087ba5b1 Allow localization of pairing error strings 2022-10-12 22:20:15 -05:00
Cameron Gutman c7a30d8728 Allow a pairing attempt even if the PC is busy
Pairing while busy doesn't work with GFE but works with Sunshine
2022-10-12 22:15:58 -05:00
LedyBacer 1f678cafba Translated using Weblate (Russian)
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2022-10-12 10:23:12 +02:00
Jen Kung-chih 579e0bc464 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-10-10 19:59:11 +02:00
Nikita Epifanov 7f36dc5aad Translated using Weblate (Russian)
Currently translated at 97.0% (194 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2022-10-10 19:59:11 +02:00
Eric a7c2026128 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-10-10 19:59:11 +02:00
Sargon-Isa 7b0d67ebbe Translated using Weblate (German)
Currently translated at 100.0% (200 of 200 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-10-10 19:59:10 +02:00
Cameron Gutman 63f0910eac Update AppImage to libva 2.16.0 2022-10-07 22:22:13 -05:00
Cameron Gutman b16cf9fcc5 Update moonlight-common-c with speculative RFI support 2022-10-07 22:21:16 -05:00
Cameron Gutman 5501d7bc6b Include opt-out variable in VAAPI avoidance log output 2022-10-05 18:50:53 -05:00
Cameron Gutman 413ef42a34 Enable HEVC RFI for CUDA, VAAPI, and VDPAU decoders 2022-10-05 18:47:43 -05:00
Cameron Gutman a1694ab951 Use nvidia-vaapi-driver on Wayland systems if available 2022-10-05 18:44:11 -05:00
Cameron Gutman fbbbd5e0b8 Use new LiRequestIdrFrame() API 2022-10-05 00:53:31 -05:00
Cameron Gutman f8c7e2ee41 Enable HEVC RFI for VideoToolbox 2022-10-05 00:25:59 -05:00
Cameron Gutman 2a4af0bc2c Use colorspace helpers for DRM EGL export 2022-10-05 00:20:33 -05:00
Cameron Gutman d24db13e9d Update SDL_GameControllerDB 2022-10-05 00:00:39 -05:00
Cameron Gutman bc68aad67b Print the frame number if decoding fails 2022-10-04 23:38:54 -05:00
Cameron Gutman 9e8a4cab7b Enable HEVC RFI for DXVA2 and D3D11VA 2022-10-04 22:56:21 -05:00
Cameron Gutman 3679964cf8 Rerun lupdate and lrelease 2022-10-04 22:06:57 -05:00
Cameron Gutman 225ec1a87f Merge remote-tracking branch 'origin/weblate' 2022-10-04 22:05:48 -05:00
Cameron Gutman 071c76c06a Add error text for ML_ERROR_FRAME_CONVERSION 2022-10-04 22:05:18 -05:00
Cameron Gutman d77a255721 Update moonlight-common-c with GFE 3.26 and HEVC RFI fixes 2022-10-04 22:03:27 -05:00
Cameron Gutman 26ee1aee25 Fix protected content error on GFE 3.22+ 2022-10-04 22:02:44 -05:00
Jen Kung-chih b047395938 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-09-29 15:16:28 +02:00
Cameron Gutman 483a601867 Display SDR/HDR status in performance overlay 2022-09-28 17:44:22 -05:00
bruh c4bc2f6adf Translated using Weblate (Vietnamese)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2022-09-25 17:18:44 +02:00
Cameron Gutman 439e8fe33f Constify frame colorspace helper functions 2022-09-24 18:37:51 -05:00
Cameron Gutman 99885f5b4b Centralize colorspace and color range handling 2022-09-24 12:28:23 -05:00
Cameron Gutman 78b522ec1d Fix large frame header size for GFE 3.26 2022-09-22 23:48:41 -05:00
Jorys Paulin dbfa5a9358 Translated using Weblate (French)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-09-14 15:20:55 +02:00
Howard Wu 3910b3862a Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-09-13 07:18:54 +02:00
Cameron Gutman 3b8e3b7d5c Prepare for v4.2.1 2022-09-12 00:12:35 -05:00
Cameron Gutman 6129000dde Rerun lupdate and lrelease 2022-09-12 00:08:31 -05:00
Cameron Gutman 65b274d695 Merge remote-tracking branch 'origin/weblate' 2022-09-12 00:07:42 -05:00
reloxx13 a13dd0076b Translated using Weblate (German)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-09-12 06:41:15 +02:00
Cameron Gutman cc026c995c Fix mishandling of IDR frames with a SEI or AUD NAL
Fixes #865
2022-09-11 23:36:20 -05:00
Cameron Gutman 81cfacaa3d Add fallback logic when the host doesn't send valid colorspace data 2022-09-11 23:13:10 -05:00
Cameron Gutman fabebc05d2 Prepare for v4.2.0 2022-09-10 12:19:04 -05:00
Cameron Gutman 07a97bab03 Rerun lupdate and lrelease 2022-09-10 12:06:22 -05:00
Cameron Gutman 69ac810c82 Merge remote-tracking branch 'origin/weblate' 2022-09-10 12:05:24 -05:00
Daniel Saburi 3f4609dc6e Translated using Weblate (Portuguese (Brazil))
Currently translated at 16.1% (32 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2022-09-09 04:16:43 +02:00
Daniel Saburi 1ddb529d26 Translated using Weblate (Portuguese)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2022-09-09 04:16:42 +02:00
Cameron Gutman ab6b88073c Fix build with _FILE_OFFSET_BITS=64 2022-09-05 22:04:24 -05:00
Cameron Gutman ad3ed97472 Fix handling of 3 byte Annex B start sequences 2022-09-05 17:56:42 -05:00
Cameron Gutman 07e902fe95 Fix build with open() defined to open64() 2022-09-04 23:45:18 -05:00
Cameron Gutman eb781ce689 Use __FUNCTION__ macro instead of hardcoding 2022-09-03 18:09:01 -05:00
Cameron Gutman 555a65c8ea Add open64() hook for _FILE_OFFSET_BITS=64 2022-09-03 18:05:03 -05:00
Cameron Gutman 58429f4172 Fix handling of the optional mode argument in our open() hook 2022-09-03 17:52:54 -05:00
sanhoe e2692a0abd Translated using Weblate (Korean)
Currently translated at 100.0% (198 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-09-03 00:21:34 +02:00
Brandon Goldberg d218c43edf Translated using Weblate (Spanish)
Currently translated at 97.4% (193 of 198 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-09-03 00:21:34 +02:00
Cameron Gutman fae9813127 Rebuild libraries built with CMake to get working PDBs and better optimizations
Additionally, disable WGI to work around an SDL bug

https://github.com/cgutman/moonlight-deps/commit/1810c6fba8b2377791e68d8829ee4c9a796788af
2022-08-28 20:34:44 -05:00
Cameron Gutman adc56d4ee5 Rerun lupdate and lrelease 2022-08-28 20:22:39 -05:00
Cameron Gutman f982e33fab Merge remote-tracking branch 'origin/weblate' 2022-08-28 20:20:53 -05:00
Cameron Gutman 9ab4479fcf Fix excessive flickering when switching between full-screen and windowed on Windows 2022-08-28 20:10:26 -05:00
Cameron Gutman 3e330b7929 Attach to the parent console to print list output on Win32 2022-08-27 14:54:45 -05:00
Cameron Gutman ecddada150 Improve verbose log suppression 2022-08-25 23:02:32 -05:00
Cameron Gutman 0c828cbb37 Suppress non-critical log output while running the list command 2022-08-25 22:45:42 -05:00
Cameron Gutman 84a32f8c16 Minor cleanup of new list code 2022-08-25 22:39:04 -05:00
Anselm Busse 4ee36fd405 Avoid GUI display for App listing 2022-08-25 22:18:05 -05:00
Anselm Busse 0802609fd8 Correcting for PR comments 2022-08-25 22:18:05 -05:00
Anselm Busse de88176995 Add a 'list' option for the CLI
This commit addresses Issue #448 by adding a command line option that allows the listing of all the Apps reported by the remote host as a CSV.
2022-08-25 22:18:00 -05:00
Cameron Gutman aca82f400a Never use fewer than 480 samples to avoid causing issues on PulseAudio systems
Fixes #830
Fixes #858
2022-08-25 21:27:05 -05:00
Brandon Goldberg 54bb6fe527 Translated using Weblate (Spanish)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-08-25 02:17:55 +02:00
Cameron Gutman c1f663cec1 Add missing files from previous commit 2022-08-24 17:31:22 -05:00
Cameron Gutman aaf59c2d01 Add CLI pairing support 2022-08-24 00:22:02 -05:00
Cameron Gutman 692942e5be Move PIN generation into ComputerManager to be shared with CLI pairing 2022-08-24 00:21:25 -05:00
Cameron Gutman f4acd629a1 Save hosts immediately after pairing concludes to ensure the server cert is persisted 2022-08-24 00:20:22 -05:00
Cameron Gutman 0ff8a44ec3 Allow 10-bit in DXVA2 as a fallback 2022-08-22 00:23:07 -05:00
Cameron Gutman c6d8f6e618 Allow D3D11VA to be disabled via environment variable 2022-08-22 00:19:46 -05:00
Cameron Gutman 1baa23cc43 Update SDL to 84004d1 for AppImage 2022-08-21 20:58:50 -05:00
Cameron Gutman 3be696e6bb Update SDL to 84004d1 2022-08-21 20:55:38 -05:00
Cameron Gutman 3cfcb01603 Add simple script to help updating libs 2022-08-21 20:55:25 -05:00
Cameron Gutman d39a29759c Don't draw with test-only renderers 2022-08-21 18:38:09 -05:00
Cameron Gutman bf4332b9e7 Prefer D3D11VA in non-FSE modes for improved performance 2022-08-21 17:50:56 -05:00
Cameron Gutman feaae7b684 Update moonlight-common-c to improve control stream failure diagnostics 2022-08-21 15:10:49 -05:00
Cameron Gutman be7852dfc0 Remove desktop resolution in favor of native (unscaled) resolution
Seeing 2 "native" resolutions for a single high DPI display is confusing.

If someone wants a lower resolution aspect-ratio match of a display, they
can use a custom resolution.
2022-08-16 01:22:26 -05:00
Cameron Gutman b0804ce048 Fix native resolution detection on high DPI wayland systems 2022-08-16 00:25:57 -05:00
Cameron Gutman aa7d5fa924 Don't use swap interval 1 by default on Wayland systems 2022-08-14 13:09:31 -05:00
Sargon-Isa b4cab12e9d Translated using Weblate (German)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-08-11 19:15:27 +02:00
Cameron Gutman 133dda2de0 Update SDL_GameControllerDB 2022-08-10 19:35:58 -05:00
Cameron Gutman ef5605ae39 Update FFmpeg to 5.1 2022-08-10 00:14:53 -05:00
Cameron Gutman 9b29b2702e Update VCRedist and add a script to update it in the future 2022-08-09 20:09:12 -05:00
Jorys Paulin abafa270e5 Translated using Weblate (French)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-08-06 14:19:54 +02:00
Cameron Gutman 15852ccf81 Update dependencies
SDL -> 602b7dd0f4
OpenSSL -> 1.1.1q
SDL_ttf -> 2.20.0
2022-08-02 00:38:33 -05:00
Kirill Korolev a427ecd029 Translated using Weblate (Russian)
Currently translated at 98.9% (190 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2022-07-22 18:18:21 +02:00
Wen-haur Chiu 77228dcb2c Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-07-21 14:19:41 +02:00
Cameron Gutman 3948cfe495 Update libva to 2.15 in AppImage 2022-07-02 13:05:47 -05:00
Cameron Gutman 36218b54f8 Don't hardcode /dev/dri/card0 and /dev/dri/renderD128 2022-06-30 19:25:33 -05:00
Cameron Gutman be2f4433db Avoid hardcoding VIDEO_FORMAT_H265_MAIN10 for HDR/10-bit color 2022-06-26 16:22:05 -05:00
Artur Szulc dd5d36cf07 Translated using Weblate (Polish)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2022-06-20 23:14:50 +02:00
Adam Lantos 685136d98f Make drmDropMaster() more reliable by checking for DRM master fds.
This should fix the majority of EACCES permission denied errors
when attempting to drop the DRM master.
2022-06-12 12:29:13 -07:00
Mattia Rombi 852937421e Translated using Weblate (Italian)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-06-07 11:15:33 +02:00
Jorys Paulin a5389b7be5 Translated using Weblate (French)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-05-31 10:15:58 +02:00
Cameron Gutman 1b96b18bc0 Fix handling of colorspace changes when using CUDA+SDL 2022-05-28 22:55:55 -05:00
Cameron Gutman e9edad6f8c Fix surface leak if SDLVideo_CreateOverlay() fails 2022-05-28 22:48:49 -05:00
Cameron Gutman f8a6012c3a Improve overlay format handling 2022-05-28 22:48:23 -05:00
Cameron Gutman e103f6c9b6 Avoid holding the overlay lock during vaPutSurface 2022-05-28 22:28:17 -05:00
Cameron Gutman 9daf7b5a36 Fix modesetting for non-EGL HEVC streams 2022-05-28 21:42:27 -05:00
Mattia Rombi d6142e1af0 Translated using Weblate (Italian)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-05-28 12:14:50 +02:00
Jorys Paulin b0491210ff Translated using Weblate (French)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-05-28 12:14:50 +02:00
Mattia Rombi 91d8550290 Translated using Weblate (Italian)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-05-26 19:36:07 +02:00
sanhoe dfaaa7d72a Translated using Weblate (Korean)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-05-26 19:15:29 +02:00
Dominik Chrástecký 5174a4f58a Translated using Weblate (Czech)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2022-05-25 14:20:23 +02:00
Cameron Gutman b9c73df488 Draw the black background even for the KMSDRM backend to fix modesetting 2022-05-24 19:41:37 -05:00
Cameron Gutman f99f1f6441 Disable EGL renderer on RPi due to very poor performance 2022-05-23 23:05:07 -05:00
Cameron Gutman 1ec1f5d3be Switch to D3D11VA by default on Windows ARM64
It performs much better at 4K on Surface Pro X
2022-05-22 22:29:18 -05:00
Cameron Gutman 713db06a05 Prepare for v4.1.0 release 2022-05-22 19:56:32 -05:00
Cameron Gutman a0adcbd90b Update SDL_GameControllerDB 2022-05-22 19:08:18 -05:00
Cameron Gutman b94776421c Rerun lupdate and lrelease 2022-05-22 19:03:55 -05:00
Thijs Lumeij 79c1043063 Translated using Weblate (Dutch)
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2022-05-23 02:02:14 +02:00
Cameron Gutman cfabae17c0 Rerun lupdate and lrelease 2022-05-22 19:01:18 -05:00
Cameron Gutman 71a1d25e90 Merge remote-tracking branch 'origin/weblate' 2022-05-22 18:59:38 -05:00
Cameron Gutman c2d7b835fb Try moving session.h prior to vaapi.h 2022-05-21 16:58:28 -05:00
Cameron Gutman f72888ce6f Attempt to fix build error with older Qt headers 2022-05-21 16:52:04 -05:00
Wen-haur Chiu 30f474d253 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (192 of 192 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-05-21 14:16:30 +02:00
Cameron Gutman 216f274a92 Fix UAF in SLVideo overlay update 2022-05-21 00:30:07 -05:00
Cameron Gutman 5ea79efe4b Work around broken overlay state restoration in Qt GUI 2022-05-21 00:20:36 -05:00
Cameron Gutman 197c1ba21b Add support for the status overlay on Steam Link 2022-05-21 00:10:49 -05:00
Cameron Gutman 95c4a24d99 Destroy subpictures before the associated image 2022-05-20 21:46:40 -05:00
Cameron Gutman f5f23a7c22 Implement overlay support for the VAAPI direct renderer 2022-05-20 21:40:37 -05:00
Cameron Gutman c469576460 Update SDL and FFmpeg for AppImage 2022-05-20 17:45:35 -05:00
Cameron Gutman 0001bb0e4c Default to borderless windowed mode on Wayland systems 2022-05-19 19:22:01 -05:00
Cameron Gutman 56f184393f Allow the cursor lock toggle to work in full-screen mode
Fixes #793
2022-05-19 19:14:55 -05:00
Cameron Gutman 85777e85fa Use newer AppVeyor image for macOS builds 2022-05-18 00:54:21 -05:00
Cameron Gutman c750ec3cc7 Add workaround for macOS scrolling acceleration
See #778
2022-05-18 00:24:58 -05:00
Cameron Gutman c75b781d3f Use SDL_WINDOWEVENT_DISPLAY_CHANGED on SDL 2.0.18+ 2022-05-17 17:13:07 -05:00
Cameron Gutman 8aa42ff1d9 Reset the EGL renderer when specialization fails 2022-05-17 17:10:40 -05:00
Cameron Gutman 63a5bc5e12 Only force pacing in true full-screen mode to be consistent with DXVA2 2022-05-15 13:38:58 -05:00
Cameron Gutman e0b7b6dc3d Fix DXGI_FEATURE_PRESENT_ALLOW_TEARING feature check 2022-05-11 22:48:15 -05:00
Cameron Gutman 3d7ecf98c2 Fix HEVC Main10 support check on macOS GPUFamily1 GPUs 2022-05-11 22:00:34 -05:00
Cameron Gutman ad5581c620 Use DWM MMCSS for D3D11VA like DXVA2 does 2022-05-09 23:52:13 -05:00
Cameron Gutman 69af991772 Improve DXVA2 performance in borderless windowed on AMD hardware 2022-05-09 22:55:58 -05:00
Cameron Gutman 2bb2745f91 Enhance frame pacing logic for HDR renderers 2022-05-07 16:21:17 -05:00
Cameron Gutman 5f682bb45f Revert addition of D3DCREATE_NOWINDOWCHANGES
This flag breaks Alt+Tab in full-screen exclusive mode
2022-05-07 16:21:04 -05:00
Cameron Gutman 48bcb6b9a6 Rerun lupdate and lrelease 2022-05-07 14:32:34 -05:00
Cameron Gutman 092c0a7392 Integrate Czech and Polish translations 2022-05-07 14:32:07 -05:00
Cameron Gutman 4e8618c512 Merge remote-tracking branch 'origin/weblate' 2022-05-07 14:19:06 -05:00
Cameron Gutman c51a69c0dc Update SDL to 8cd908e 2022-05-07 14:18:39 -05:00
Cameron Gutman 2480849f39 Clean up DXGI adapter enumeration code 2022-05-02 19:05:00 -05:00
DankXylese 6bfe40607d Translated using Weblate (Ukrainian)
Currently translated at 27.4% (53 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2022-04-28 22:13:27 +02:00
Cameron Gutman a1c350a537 Fix WARP device leak 2022-04-26 23:29:04 -05:00
Cameron Gutman f732b1978e Require a test frame with D3D11VA 2022-04-26 23:04:31 -05:00
Cameron Gutman d3a542bac4 Try all available GPUs in D3D11VA decoder 2022-04-26 22:49:46 -05:00
Cameron Gutman b12724db02 Reduce log spam when choosing a resolution 2022-04-24 17:11:10 -05:00
Cameron Gutman f8f5e8e869 Don't discard all excess frames before rendering
This prevents the render queue's pacing logic from working and
interferes with renderers that take a full v-sync period between
their waitToRender() and renderFrame() callbacks.
2022-04-24 17:04:32 -05:00
Cameron Gutman 0733f06103 Fix saving keep awake value
Fixes #781
2022-04-24 16:49:36 -05:00
Cameron Gutman 6fdaa6ee8a Avoid modesetting if the display didn't change 2022-04-24 16:48:21 -05:00
Cameron Gutman f10b547a49 Partially revert "Rework window management to fix issues restoring window state between windowed and full-screen"
This exposes all sorts of issues with full-screen transitions on Windows and macOS:
- Loss of proper window decorations when transitioning from full-screen to windowed on Windows
- Improper sizing when transitioning from true full-screen to windowed on macOS

This reverts commit 38396b2691.
2022-04-24 16:40:19 -05:00
Cameron Gutman 38396b2691 Rework window management to fix issues restoring window state between windowed and full-screen 2022-04-24 16:22:17 -05:00
Cameron Gutman 220f50ebe4 Revert "Allow renderers to apply size and display changes seamlessly"
This reverts commit c989133d27.
2022-04-24 16:12:12 -05:00
Cameron Gutman c989133d27 Allow renderers to apply size and display changes seamlessly 2022-04-24 15:42:08 -05:00
Cameron Gutman 6c339551eb Allow resolution changes on all platforms
Take aspect ratio into account when making the choice too.
2022-04-21 23:57:17 -05:00
Cameron Gutman ef23a80b16 Fix EGL build when using EGL 1.4 or earlier headers 2022-04-21 21:13:39 -05:00
Cameron Gutman a521093731 Update Visual C++ Runtime installer 2022-04-17 00:04:03 -05:00
Cameron Gutman 747d3eedf1 Cleanup D3D11VA renderer by removing unnecessary codepaths
Waitable swapchains seem to be worse than our existing DXVsyncSource for synchronizing with VBlank.

Full-screen exclusive mode isn't beneficial vs Independent Flip on modern Win10/Win11 systems.
2022-04-15 23:26:32 -05:00
Cameron Gutman fd563726f0 Fix blocking presents in borderless windowed flip modes 2022-04-15 23:21:52 -05:00
Cameron Gutman 62136a1a96 Increase buffer count to prevent starvation on AMD GPUs 2022-04-14 23:21:32 -05:00
Cameron Gutman cf16c31d38 Improve performance and latency of D3D11VA renderer 2022-04-14 22:46:13 -05:00
Cameron Gutman 0f5d4aa72f Enhance EGLRenderer's waitForRender() implementation 2022-04-10 20:20:44 -05:00
Cameron Gutman d8dbe77427 Tiny EGL code cleanup 2022-04-10 19:35:29 -05:00
Cameron Gutman 0e5670d50d Don't compare StackView items by localized name
Fixes #767
2022-04-10 15:42:50 -05:00
Cameron Gutman 22924a1e92 Reload the FPS and window mode comboboxes after changing language
Fixes #765
2022-04-10 13:17:42 -05:00
Cameron Gutman e3a7b54f90 Use EGL fences to reduce video latency 2022-04-08 19:28:22 -05:00
Cameron Gutman 81d5e7f014 Wait for the VDPAU output surface to be idle in waitToRender() 2022-04-07 22:16:52 -05:00
Cameron Gutman 9790c218dc Wait on the display link callback before rendering to reduce latency 2022-04-07 22:08:43 -05:00
Cameron Gutman 6d3d51553b Wait on our D3D11 swapchain before rendering to reduce latency 2022-04-07 21:46:48 -05:00
Cameron Gutman 474591c6a5 Use a separate callback to indicate EOS instead of renderFrame() 2022-04-07 21:30:20 -05:00
Cameron Gutman 5de0dc2713 Disable the decoder selection options when HDR is enabled 2022-04-05 20:09:09 -05:00
Cameron Gutman 57a34a7abb Update README.md 2022-04-05 19:56:20 -05:00
Cameron Gutman 54517bda1b Switch back to upstream SDL 2022-04-05 00:59:58 -05:00
Cameron Gutman 4291e15b60 Use NDC helpers in D3D11VA renderer 2022-04-05 00:57:14 -05:00
Cameron Gutman 940ae6406b Add helper functions to perform NDC transformations 2022-04-05 00:50:04 -05:00
Cameron Gutman 6a0cf4bfd3 Fix some #if -> #ifdefs 2022-04-05 00:26:13 -05:00
Cameron Gutman fee6f75223 Fix VAAPIRenderer build error with neither HAVE_EGL nor HAVE_DRM defined 2022-04-05 00:24:00 -05:00
Cameron Gutman 8c93b2d54c Fix VAAPIRenderer build error with HAVE_DRM but not HAVE_EGL 2022-04-04 19:40:31 -05:00
Artur Szulc dbbb1bd8a1 Translated using Weblate (Polish)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pl/
2022-04-04 23:12:28 +02:00
Dominik Chrástecký 5c838b2fc5 Translated using Weblate (Czech)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/cs/
2022-04-04 23:12:27 +02:00
Jorys Paulin 3a094d4ba8 Translated using Weblate (French)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-04-04 23:12:26 +02:00
Artur S 5d11c1ea6a Added translation using Weblate (Polish) 2022-04-03 20:52:00 +02:00
Dominik Chrástecký a7e2e15eac Added translation using Weblate (Czech) 2022-04-03 17:11:26 +02:00
Jorys Paulin 585a0ca1f4 Translated using Weblate (French)
Currently translated at 97.4% (188 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-04-03 09:12:06 +02:00
Cameron Gutman 09ed82db65 Fix build with HAVE_MMAL 2022-04-02 16:16:40 -05:00
Cameron Gutman a56cb0e88a Don't waste time retrying the same renderer again 2022-04-02 16:14:04 -05:00
Cameron Gutman 9acf5ff0ef Update workaround to prevent deadlock with h264_mmal 2022-04-02 16:06:39 -05:00
Cameron Gutman 64a7790aed Patch SDL to work around GLX crash 2022-04-02 15:50:32 -05:00
Cameron Gutman 9a5134ffcf Use QString not QByteArray for string equality 2022-04-02 15:49:07 -05:00
Cameron Gutman 1d2c4d0843 Prepare for v4.0.0 2022-04-01 19:18:51 -05:00
Cameron Gutman efad34be62 Set SDL_MOUSE_AUTO_CAPTURE=0 since we manage mouse capture ourselves 2022-03-31 23:54:58 -05:00
Cameron Gutman 52761ade87 Update SDL_ttf to 81f9e9b 2022-03-31 23:30:59 -05:00
Cameron Gutman e6b816e776 Update SDL in AppImage 2022-03-30 23:31:01 -05:00
Cameron Gutman 6d3bcba5d0 Update SDL, SDL_ttf, and FreeType
SDL -> 2c04df8
SDL_ttf -> 80d909 (Windows)
FreeType -> 3f83da (Windows)
2022-03-30 23:27:40 -05:00
Cameron Gutman 2e7ffa606b Fix missing DLL in ARM64 builds 2022-03-30 22:43:31 -05:00
Cameron Gutman 055cae90b8 Only apply the AMD color range workaround to new drivers
Applying it to older drivers introduces the very same issues it's meant to fix
2022-03-30 22:43:08 -05:00
Cameron Gutman 23acf92803 Update SDL_GameControllerDB 2022-03-30 22:07:33 -05:00
Cameron Gutman 91ee7d76eb Rerun lupdate and lrelease 2022-03-30 22:07:11 -05:00
Cameron Gutman 570888e2b8 Merge remote-tracking branch 'origin/weblate' 2022-03-30 22:06:02 -05:00
sanhoe 282f27f0c8 Translated using Weblate (Korean)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-03-30 18:10:36 +02:00
Cameron Gutman 98376ade45 Update SDL to cbdb67b 2022-03-29 22:39:09 -05:00
Cameron Gutman 9682968b55 Fix FFmpeg URL for AppImage 2022-03-29 21:34:34 -05:00
Cameron Gutman 877cb5f1b0 Update SDL2, SDL_ttf, and FFmpeg in AppImage build 2022-03-29 21:03:35 -05:00
Cameron Gutman 6972573a6e Add pointer lock key combo
Fixes #737
2022-03-29 18:26:09 -05:00
Cameron Gutman 742f1b1283 Prefer hevc_nvv4l2 over hevc_nvmpi 2022-03-26 22:54:54 -05:00
The Great Wizard Azkali 0b127a2f3b Add support for h264_nvv4l2 and hevc_nvv4l2 (#745)
* Add support for h264_nvv4l2

A new implementation of nvv4l2 decoder has been made by @CTCaer and will be released in thr next switchroot (Linux for Nintendo Switch) update. This implementation of ffmpeg can also be used by other Jetson boards. A repository will be soon hosted so Jetson users can install it.
Prior to the new implementation distribution, we add it to the project who currently use nvmpi implementation.

* Add support for hevc_nvv4l2

Following previous PR, add hevc support as well.
2022-03-26 22:02:00 -05:00
Wen-haur Chiu a6057835a8 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-03-25 18:11:42 +01:00
CorteX c32794477e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-03-23 06:58:35 +01:00
reloxx13 999ac60bda Translated using Weblate (German)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-03-21 09:59:13 +01:00
bruh bca4b832a8 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (193 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2022-03-19 22:58:21 +01:00
Cameron Gutman 2fc1dda232 Partially revert e64b15d and b85d5b8
These changes cause excessive window recreation using the Flatpak on Nvidia with Wayland
2022-03-19 14:50:38 -05:00
Cameron Gutman 99495cff90 Add logging for cases where color range/encoding cannot be set 2022-03-19 13:12:41 -05:00
Caio Gabriel 795962a4ba Translated using Weblate (Portuguese (Brazil))
Currently translated at 7.7% (15 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2022-03-18 22:29:44 +01:00
Caio Gabriel 7bde9f447a Translated using Weblate (Portuguese (Brazil))
Currently translated at 7.7% (15 of 193 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt_BR/
2022-03-18 20:05:48 +01:00
Cameron Gutman b45c3e3c7f Tweak wording on the keep awake option 2022-03-16 21:59:06 -05:00
Cameron Gutman ce2a01fc59 Allow the screensaver toggle to work even if running on an embedded platform 2022-03-16 21:57:03 -05:00
Cameron Gutman edeea65c3e Rerun lupdate and lrelease 2022-03-16 21:51:17 -05:00
Cameron Gutman 6e8ee94b91 Merge remote-tracking branch 'origin/weblate' 2022-03-16 21:49:44 -05:00
Cameron Gutman 97d8274911 Add option to allow PC to sleep while streaming 2022-03-16 21:48:56 -05:00
Cameron Gutman 73d84dc13f Update SDL and OpenSSL prebuilts 2022-03-15 22:30:55 -05:00
Cameron Gutman f32501d498 Update moonlight-common-c 2022-03-15 21:22:44 -05:00
Cameron Gutman 9c289c3fe9 Update SDL_GameControllerDB 2022-03-15 21:22:21 -05:00
Cameron Gutman 2a610584ee Fix handling of line continuations in FFmpeg logs (for real this time) 2022-03-11 19:15:36 -06:00
sanhoe 8e06421567 Translated using Weblate (Korean)
Currently translated at 100.0% (191 of 191 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2022-03-10 18:59:01 +01:00
Wen-haur Chiu 57dc3725f5 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (191 of 191 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-03-09 15:58:49 +01:00
Cameron Gutman d6ef8945f5 Replace Deviare In-Proc with Microsoft Detours 2022-03-08 20:58:40 -06:00
Cameron Gutman e078a8b7b6 Don't recreate the decoder while the window is minimized
Fixes #726
2022-03-06 15:21:43 -06:00
Cameron Gutman a6395b9025 Fix short UI hang when manually stopping the stream after losing connection with the host 2022-03-06 13:11:36 -06:00
Cameron Gutman 6c0983d77c Reset the audio device if it enters a failed state
Fixes #734
2022-03-05 16:50:06 -06:00
Cameron Gutman 4ae39f2bd5 Properly synchronize rumble with gamepad removal 2022-03-05 13:32:38 -06:00
bruh 71fc701809 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (191 of 191 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2022-03-02 11:57:09 +01:00
Aurora Robb Kristiansen d418921e4b Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.2% (140 of 191 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2022-02-28 11:55:22 +01:00
Cameron Gutman 4b83b022d3 Remove unnecessary assert 2022-02-25 22:47:20 -06:00
Cameron Gutman 8b13e5b47e Update AppImage to libva 2.14 2022-02-25 22:46:52 -06:00
Benjamín Bustos 0bfd565bda Translated using Weblate (Spanish)
Currently translated at 100.0% (191 of 191 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-02-23 16:56:13 +01:00
Emanuele Conti 2224a558ee Translated using Weblate (Italian)
Currently translated at 100.0% (191 of 191 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-02-22 15:56:43 +01:00
Cameron Gutman 93c02fb43a Print GPU info in D3D11VA renderer 2022-02-20 22:10:18 -06:00
Cameron Gutman 93ee51cabb Integrate new languages from Weblate 2022-02-20 14:15:08 -06:00
Cameron Gutman cd6ba554a4 Merge remote-tracking branch 'origin/weblate' 2022-02-20 13:44:11 -06:00
Cameron Gutman 89aa2be358 Rerun lupdate and lrelease 2022-02-20 13:41:48 -06:00
Cameron Gutman da261246b9 Change HDR to be a separate option like other clients 2022-02-19 11:21:06 -06:00
Cameron Gutman 4d3e09f4a0 Raise minimum custom resolution to 256x256 2022-02-19 10:47:25 -06:00
Cameron Gutman 9add6b3696 Add DXVA2 quirk for AMD GPUs to fix color range on the latest drivers 2022-02-17 00:35:33 -06:00
Cameron Gutman ef037e18d0 Add colorspace and color range override options 2022-02-17 00:26:56 -06:00
Cameron Gutman 36db791516 Refactor D3D11 shaders to reduce duplicated code 2022-02-16 19:38:18 -06:00
Emanuele Conti 25d2ea5e94 Translated using Weblate (Italian)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-02-16 13:57:22 +01:00
Jorys Paulin 34f2d18f27 Translated using Weblate (French)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-02-16 13:57:21 +01:00
Aurora Robb Kristiansen 4935c846aa Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.0% (138 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2022-02-14 01:57:01 +01:00
Cameron Gutman b1f980c216 Fix handling of line continuations in FFmpeg logs 2022-02-13 16:06:04 -06:00
Cameron Gutman 738f64c903 Use FP32 for position and texcoords
We need that extra precision for sampling large textures
2022-02-13 13:41:39 -06:00
Emanuele Conti 7235663447 Translated using Weblate (Italian)
Currently translated at 46.0% (87 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-02-11 11:55:30 +01:00
Emanuele Conti 9d78c416f7 Translated using Weblate (Italian)
Currently translated at 44.9% (85 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-02-10 10:57:51 +01:00
Cameron Gutman 9a64c026ea Use optimized pixel shaders for the normal SDR and HDR colorspaces 2022-02-09 20:46:02 -06:00
Cameron Gutman be2af1d17a Add environment variables to configure DXVA2 and D3D11VA options 2022-02-08 22:27:27 -06:00
Cameron Gutman b21131a466 Use FP16 in the D3D11 shaders 2022-02-08 21:43:25 -06:00
Emanuele Conti 41c5126472 Translated using Weblate (Italian)
Currently translated at 39.6% (75 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/it/
2022-02-08 18:54:36 +01:00
Cameron Gutman b96cb1abaf Remove per-app HDR support check
It doesn't seem to make a difference anymore whether it's supported or not.
GFE seems happy to enter HDR mode anyway.
2022-02-07 20:02:19 -06:00
Emanuele Conti 20143606e2 Added translation using Weblate (Italian) 2022-02-07 09:27:18 +01:00
Cameron Gutman 1d79bcc657 Disable waitable swapchains in full-screen mode 2022-02-06 00:28:59 -06:00
Cameron Gutman e8b4494fc3 Add an extra buffer for DirectFlip 2022-02-05 23:22:07 -06:00
Cameron Gutman 2518208c5c Don't set fullScreenDesc fields to prevent entering "proxy" full-screen mode 2022-02-05 19:32:05 -06:00
Cameron Gutman 918fea7d4b Precompute the aspect ratio stretch to avoid having to change viewports twice each frame 2022-02-05 15:44:37 -06:00
Cameron Gutman 4dc07bf63f Don't render the alignment padding area 2022-02-05 15:23:29 -06:00
Cameron Gutman 04a0aca221 Create SRVs for all textures in the pool during initialization 2022-02-05 14:49:08 -06:00
Cameron Gutman 1942e72474 Only bind the constant buffer once 2022-02-05 14:15:35 -06:00
Cameron Gutman f256407789 Implement D3D11VA video rendering 2022-02-04 21:51:34 -06:00
Cameron Gutman 67612f607e WIP: D3D11VA support
Overlays work, but drawing the actual video is unimplemented
2022-02-03 19:45:07 -06:00
Wh1t3st4r 7274c42126 Translated using Weblate (Portuguese)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2022-02-01 16:52:52 +01:00
Wh1t3st4r e288402e88 Added translation using Weblate (Portuguese (Brazil)) 2022-01-31 16:08:53 +01:00
Cameron Gutman 76bd4a1c7b Don't set the HDR metadata blob if we don't have one 2022-01-30 22:57:53 -06:00
Cameron Gutman 13dbad6f35 Fix build with old libdrm headers 2022-01-30 22:56:22 -06:00
Cameron Gutman cf089fdfe9 Add support for HDR with VAAPI using DRM frontend renderer 2022-01-29 18:16:39 -06:00
Cameron Gutman 9755e31fa2 Refactor VAAPI surface export check into separate function 2022-01-29 17:45:36 -06:00
Cameron Gutman 3fcf31d009 Improve robustness of EGL retry logic for 10-bit color 2022-01-29 01:12:38 -06:00
Cameron Gutman 1cbdd0e675 Display the HDR option if the platform has a decoder that supports it 2022-01-29 00:59:04 -06:00
Cameron Gutman e0fd84d6f5 Fix build with old libdrm headers 2022-01-29 00:28:46 -06:00
Cameron Gutman 443720c3de Plumb HDR metadata into DRM renderer 2022-01-28 22:40:07 -06:00
Cameron Gutman 254526a213 Plumb HDR mode information to the decoders 2022-01-28 22:10:50 -06:00
Cameron Gutman ad0afb5fc9 Prefer direct rendering when using HDR 2022-01-27 22:36:49 -06:00
Cameron Gutman e64b15d2a7 Rework how we deal with window re-creation for EGLRenderer
Previously we opted to just lie to SDL and tell it that the current
GL context is actually GLES 3.0 when it wasn't. This meant that
we avoided our window being recreated for GLES usage on Wayland
and KMSDRM, but that meant our 10-bit color change didn't apply
either. I suspect this hackery is what led EGLRenderer to get
stuck in a state where SDL_CreateRenderer() always failed.

Now SDL will recreate our window once to configure a compatible GL
API for our renderer. If that fails, we'll move on to a different
renderer (which may recreate the window again).
2022-01-27 21:49:03 -06:00
Cameron Gutman cdc3352318 Ensure SDL also uses X11 if Qt is using X11 2022-01-26 19:00:41 -06:00
Cameron Gutman 2416618b34 Don't require 2 bits of alpha for 10-bit color 2022-01-26 18:55:56 -06:00
GeraltOfTrivia c951d77a52 Translated using Weblate (Greek)
Currently translated at 96.2% (182 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/el/
2022-01-25 17:53:11 +01:00
GeraltOfTrivia 759ddc0b4b Added translation using Weblate (Greek) 2022-01-24 16:49:31 +01:00
Cameron Gutman a0709bec51 Improve debugging and add missing break 2022-01-23 21:12:32 -06:00
Cameron Gutman f5bc4e7a24 Add color properties to DRM renderer 2022-01-23 21:03:56 -06:00
Cameron Gutman b4665b6e5a Pick a 10-bit DRM overlay for Main10 streaming 2022-01-23 19:19:16 -06:00
Cameron Gutman b85d5b8822 Enable P010 surface export from VAAPI to EGL 2022-01-23 18:33:30 -06:00
Cameron Gutman 12ad75a6b0 Move hybrid decode detection logic into a central location 2022-01-23 15:41:33 -06:00
Cameron Gutman af92fe6ad1 Fix Apple silicon CPU check 2022-01-23 13:01:20 -06:00
Cameron Gutman fcf7ed4faa Only use the VT rasterization workaround on Apple silicon 2022-01-22 20:25:50 -06:00
Cameron Gutman a58649fd10 Update Windows and macOS to FFmpeg 5.0 2022-01-22 13:44:05 -06:00
Cameron Gutman ee5918cf4e Revert "Add workaround for duplicate size changed events on Wayland"
Skipping size changed events can cause EGLRenderer to get stuck in
a state where it can't reset itself properly. This seems to happen
consistently when starting a maximized stream then transitioning
to full-screen.

This reverts commit e1b3f90f8b.
2022-01-22 12:29:44 -06:00
Wh1t3st4r d7de3301ed Translated using Weblate (Portuguese)
Currently translated at 76.7% (145 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/pt/
2022-01-22 07:20:29 +01:00
Wh1t3st4r bd1988c775 Added translation using Weblate (Portuguese) 2022-01-22 00:51:36 +01:00
Faiq Chilmi 474010b31d Translated using Weblate (Hindi)
Currently translated at 18.5% (35 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hi/
2022-01-21 15:52:46 +01:00
Cameron Gutman dd941154d6 Fix EGL renderer overlay rendering with SDL_ttf 2.0.18
Fixes #721
2022-01-20 18:02:44 -06:00
WoweePaw cbb53745f6 Translated using Weblate (German)
Currently translated at 99.4% (188 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2022-01-20 15:09:46 +01:00
Faiq Chilmi 3dff62e0cf Added translation using Weblate (Hindi) 2022-01-20 15:09:46 +01:00
Cameron Gutman 719024ec01 Prepare for v3.2.0 release 2022-01-18 18:33:23 -06:00
Cameron Gutman f0659b4f3c Fix random crash on stream start with renderers that require test frames 2022-01-18 18:19:28 -06:00
Cameron Gutman a649f2736f Rerun lupdate and lrelease 2022-01-18 18:07:17 -06:00
Cameron Gutman 046ccb1dee Merge remote-tracking branch 'origin/weblate' 2022-01-18 18:05:42 -06:00
Tygo T d340556c28 Translated using Weblate (Dutch)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2022-01-19 01:04:10 +01:00
Wout Rombouts 32250db126 Translated using Weblate (Dutch)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2022-01-19 01:04:10 +01:00
Cameron Gutman cb8c30db2e Add workaround for keyboard and UTF-8 events interfering with each other 2022-01-17 21:56:39 -06:00
Cameron Gutman dacd5a9e3d Discard stale gamepad events when enabling gamepad navigation 2022-01-17 19:49:52 -06:00
Cameron Gutman 859d8b96a7 Don't use duplicate resize workaround on SDL 2.0.21+ 2022-01-17 19:25:43 -06:00
Cameron Gutman 02981e3cee Update SDL to pick up HIDAPI deadzone fix 2022-01-17 19:23:42 -06:00
Cameron Gutman 49892b3ce8 Only use SDL_WaitEventTimeout() on SDL 2.0.18+ 2022-01-17 16:59:45 -06:00
Cameron Gutman b223e7ec36 Update SDL_GameControllerDB 2022-01-17 15:57:36 -06:00
Cameron Gutman 0926337c1d Rerun lupdate and lrelease 2022-01-17 15:56:39 -06:00
Cameron Gutman 346e72a678 Merge remote-tracking branch 'origin/weblate' 2022-01-17 15:55:12 -06:00
Wout Rombouts d612e47b62 Translated using Weblate (Dutch)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2022-01-17 22:54:04 +01:00
Cameron Gutman c138cbf994 Fix Windows build 2022-01-17 15:47:36 -06:00
Cameron Gutman dfe275ab67 Avoid consuming stale data during/after decoder reset 2022-01-17 15:26:00 -06:00
Cameron Gutman d6cfbdb273 Rewrite FFmpeg decoder to use pull model
This allows us to keep asynchronous decoders like MMAL and V4L2M2M fed
while we're waiting for output frames. Behavior for synchronous decoders
should be identical.

Continuing to feed new data while waiting for output frames is crucial for
acceptable performance on 1080p video on the Raspberry Pi using V4L2M2M,
since it allows the decode and copy operations to be pipelined.
2022-01-17 15:06:12 -06:00
Cameron Gutman 8a27fa7bb5 Convert NeedsIdr member into an atomic variable with a getter 2022-01-17 14:30:12 -06:00
Cameron Gutman b9a6fb1fe5 Add workaround for AVSampleBufferDisplayLayer colorspace and artifacting issues
Fixes #493
2022-01-15 14:44:08 -06:00
Cameron Gutman 4b6194e15e Add chroma location buffer attachment 2022-01-15 12:17:31 -06:00
Cameron Gutman e1b3f90f8b Add workaround for duplicate size changed events on Wayland 2022-01-14 23:36:21 -06:00
Wen-haur Chiu c5cc0b8c59 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2022-01-13 12:56:43 +01:00
bruh 5c849ec666 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2022-01-13 12:56:42 +01:00
Eric c2a30cbe19 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2022-01-13 12:56:42 +01:00
Cameron Gutman 31eddd8da0 Remove superfluous colorspace check 2022-01-13 01:19:17 -06:00
Cameron Gutman abf2a14ee6 Handle colorspace changes in SDL renderer 2022-01-13 01:16:09 -06:00
Cameron Gutman e555874485 Refactor WiX bundle description of VCRedist package 2022-01-12 19:14:59 -06:00
Cameron Gutman a7aef8f147 Use new WiX 3.14 variable instead of BuildLabEx hack for ARM64 detection 2022-01-12 19:14:44 -06:00
Cameron Gutman 5b8c11f1a9 Update and rebuild all dependencies with Xcode 13 and VS 2022
macOS minimum target version is now 10.14 Mojave

Updates:
OpenSSL 1.1.1m
SDL 2.0.20
libopus 12a356

https://github.com/cgutman/moonlight-deps 5cd31601c3362562b52d8124dfc33029506d1744
2022-01-11 20:49:11 -06:00
Cameron Gutman 645040c943 Update AppImage to SDL 2.0.20 2022-01-10 20:03:47 -06:00
Cameron Gutman fcc5ea348c Remove old FFmpeg build scripts
Superseded by https://github.com/cgutman/moonlight-deps
2022-01-10 19:49:41 -06:00
Héctor 3fbb45448f Translated using Weblate (Spanish)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2022-01-10 20:56:47 +01:00
Cameron Gutman 8a83289709 Switch to VS2022 build image 2022-01-09 21:55:41 -06:00
Cameron Gutman 08175de069 Fix incorrect colorspace in MMAL renderer 2022-01-09 17:04:38 -06:00
Cameron Gutman 808933cd70 Use DT files to get status of FKMS and rpivid 2022-01-09 16:44:20 -06:00
Cameron Gutman 384dd2adab Prefer a render node in indirect rendering mode 2022-01-08 18:39:12 -06:00
Jorys Paulin 4a37952b41 Translated using Weblate (French)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-01-08 09:55:55 +01:00
lyashenko.v 1046d264d8 Fixed not working frame pacing on macOS 2022-01-06 23:23:00 -06:00
Cameron Gutman bb235ab1ae Rerun lupdate and lrelease 2022-01-06 23:19:16 -06:00
Cameron Gutman ef88b83727 Merge remote-tracking branch 'origin/weblate' 2022-01-06 23:15:48 -06:00
Cameron Gutman 5612e9864e Fix handling of some validation scenarios
- HEVC forced with no host or client hw support
- H.264 forced with no client hw support
- Client has hw HEVC only and host only supports H.264
- Client has no hw decode at all
2022-01-06 23:15:19 -06:00
Cameron Gutman 8302187dee Remove superfluous availability checks 2022-01-06 23:05:18 -06:00
Cameron Gutman 77d07c7c4d Fix incorrect error message when only HEVC decode is available but HEVC encode is not 2022-01-06 22:08:43 -06:00
Cameron Gutman b2265080fd Allow HEVC decoders to satisfy hardware decoding check if H.264 is unavailable 2022-01-06 22:07:31 -06:00
Cameron Gutman 0d70bd9ac0 Add (untested) VAAPI support for CCS planes on Tiger Lake
See https://github.com/intel/media-driver/issues/1210
2022-01-05 21:09:08 -06:00
Cameron Gutman 8f63d59b81 Correct comment to avoid confusion 2022-01-04 22:00:46 -06:00
Cameron Gutman 0395c0cc95 Revert "Revert "Don't attempt to use direct rendering without DRM master""
The correct fix was 154b5b6ded.

This reverts commit 8219dbef6f.
2022-01-04 21:59:02 -06:00
Cameron Gutman 72065412a3 Don't allow copyback rendering on RPi by default 2022-01-04 20:35:17 -06:00
Jorys Paulin 7af2cdd0ef Translated using Weblate (French)
Currently translated at 100.0% (187 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2022-01-03 11:52:50 +01:00
Cameron Gutman 67c801c4e7 Use av_frame_copy_props() to copy metadata 2022-01-02 17:38:58 -06:00
Cameron Gutman f7c8ad4c5a Fail render frame test for unsupported pixel formats 2022-01-02 15:03:49 -06:00
Cameron Gutman 61092b34de Properly handle mismatched pitch between frame and texture 2022-01-02 14:35:14 -06:00
Cameron Gutman 1e9e96fb8c Small code cleanup for hwframe code 2022-01-02 13:58:37 -06:00
Cameron Gutman 17d1ced07c Add support for mapping hwframes 2022-01-02 13:41:36 -06:00
Cameron Gutman a26ced04ff Add support for negotiating non-default transfer formats for hwframes 2022-01-01 22:15:43 -06:00
Cameron Gutman 154b5b6ded Fix fallback to SDL read-back for DRM contexts when !HAVE_EGL 2022-01-01 20:44:29 -06:00
Cameron Gutman 8219dbef6f Revert "Don't attempt to use direct rendering without DRM master"
We support indirect rendering via SDL, even if EGL is unavailable.

This reverts commit 6145913068.
2022-01-01 20:37:04 -06:00
Cameron Gutman 3da724e76a Fix and enhance the Full KMS check 2021-12-28 17:13:54 -06:00
Cameron Gutman 1616d237ae Avoid h264_v4l2m2m by default on RPi builds 2021-12-28 16:28:04 -06:00
Nikita Epifanov 3d21facc9f Translated using Weblate (Russian)
Currently translated at 100.0% (187 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2021-12-24 19:53:18 +01:00
Héctor fead2a08a3 Translated using Weblate (Spanish)
Currently translated at 96.2% (180 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-12-20 18:52:37 +01:00
Cameron Gutman d8acf24af0 Don't use SdlRenderer with MMAL 2021-12-19 20:58:50 -06:00
Cameron Gutman 97412b3c79 Display warnings about Full KMS mode and HEVC on the Pi 4 2021-12-19 20:33:48 -06:00
Cameron Gutman 6145913068 Don't attempt to use direct rendering without DRM master 2021-12-19 20:32:15 -06:00
Cameron Gutman e56bb6785f Change display mode when using KMSDRM backend 2021-12-18 21:07:35 -06:00
Cameron Gutman 6d63d6c54a Rerun lupdate and lrelease 2021-12-15 20:52:48 -06:00
Cameron Gutman 6e8a103e70 Merge remote-tracking branch 'origin/weblate' 2021-12-15 20:50:15 -06:00
Cameron Gutman 00d3530f64 Don't try VDPAU on XWayland by default 2021-12-15 20:49:12 -06:00
Cameron Gutman 1e6ca18193 Fix error checking in decode test 2021-12-15 17:33:28 -06:00
Cameron Gutman 5a32992497 Try to learn if decoders support retrying avcodec_receive_frame() 2021-12-14 20:41:27 -06:00
李俊緯 79ba00a2f4 Translated using Weblate (Chinese (Traditional))
Currently translated at 84.4% (158 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2021-12-14 11:53:41 +01:00
bruh fdfaf8ec70 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (187 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2021-12-14 11:53:41 +01:00
Héctor 162c58b697 Translated using Weblate (Spanish)
Currently translated at 60.9% (114 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-12-14 11:53:41 +01:00
Allan Nordhøy 75959ca692 Translated using Weblate (Norwegian Bokmål)
Currently translated at 70.5% (132 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2021-12-14 11:53:40 +01:00
Eric 06fbcd19c8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (187 of 187 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2021-12-14 11:53:40 +01:00
Cameron Gutman 36e0468a99 Optimize CUDA GL interop and provide fallback 2021-12-13 21:41:00 -06:00
Cameron Gutman c4d85cf928 Don't show HDR option if we know it's unsupported 2021-12-12 17:43:20 -06:00
Cameron Gutman daf8495acb Fix excessive high-res scroll speed on newer GFE versions 2021-12-12 16:50:22 -06:00
Cameron Gutman 9999ded933 Quiet down log spam for asynchronous decoders 2021-12-11 18:37:39 -06:00
Cameron Gutman 80128e8293 Properly support asynchronous decoders that return multiple frames at a time 2021-12-11 18:15:49 -06:00
Cameron Gutman 9579b2c85e Enable Spanish and Traditional Chinese language options 2021-12-11 14:32:38 -06:00
Cameron Gutman eb7f184848 Rerun lupdate and lrelease 2021-12-11 14:32:12 -06:00
Cameron Gutman 71b21920e2 Merge remote-tracking branch 'origin/weblate' 2021-12-11 14:24:07 -06:00
Cameron Gutman 91b787a5be Update SDL and switch to arch-specific headers on Windows
SDL -> e2ade2b
2021-12-11 14:06:26 -06:00
Cameron Gutman 11f659aadb Update Visual C++ Runtime installers 2021-12-11 13:28:48 -06:00
Cameron Gutman 0870dd15a8 Fix improper null termination when stripping clipboard text 2021-12-10 02:04:19 -06:00
Héctor 7cd52041d8 Translated using Weblate (Spanish)
Currently translated at 53.2% (99 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-12-09 17:52:51 +01:00
Cameron Gutman f2bcb49478 Update dependencies for AppImage
SDL -> 2.0.18
nv-codec-headers -> 8.1.24.13
FFmpeg -> 4.4.1
2021-12-06 23:03:53 -06:00
Cameron Gutman 60a4bda94f Switch macOS builds to Qt 6 2021-12-06 22:54:55 -06:00
Cameron Gutman 54cfc46500 Fix VDPAU on X11 2021-12-06 20:42:51 -06:00
Cameron Gutman c09559ade5 Don't try to initialize VDPAU on Wayland 2021-12-06 19:38:28 -06:00
Cameron Gutman 3e9aea1f7a Optimize CUDA support to avoid roundtrip to CPU memory 2021-12-06 18:23:40 -06:00
Cameron Gutman f0c292f508 Update SDL_GameControllerDB 2021-12-03 12:52:23 +03:00
Cameron Gutman 1444ba2c35 Use attached Layout attached properties to set tool button size 2021-12-03 12:24:31 +03:00
Cameron Gutman fac4c85133 Revert "Fix toolbar button size on Qt 6.2"
Breaks running with Qt 5.9

This reverts commit 84ea483b4c.
2021-12-03 12:17:25 +03:00
Cameron Gutman 97a09e0571 Send UTF-8 clipboard text directly rather than emulating keystrokes 2021-12-03 11:32:58 +03:00
Cameron Gutman c7121516c1 Remove workaround for window occlusion issue fixed in SDL 2.0.18 2021-11-29 23:13:50 +03:00
Cameron Gutman 56a5fbf63b Fix get_buffer2() thread-safety warning with FFmpeg 4.4 2021-11-29 19:45:28 +03:00
Cameron Gutman 80604a752b Set SDL_HINT_APP_NAME for SDL 2.0.18 2021-11-27 17:28:01 +03:00
Cameron Gutman 3fe6e18609 Use SDL_GameControllerHasRumble() on SDL 2.0.18 2021-11-27 17:06:02 +03:00
Cameron Gutman 47f3f30d83 Add high resolution scrolling support with SDL 2.0.18 2021-11-27 06:59:16 +03:00
Cameron Gutman 085a904970 Fix false warning when building without libva-x11 or libva-wayland 2021-11-25 17:52:54 +03:00
Cameron Gutman 0fa7723f51 Fix build without libva-x11 2021-11-25 17:51:08 +03:00
Cameron Gutman 84ea483b4c Fix toolbar button size on Qt 6.2 2021-11-25 12:26:29 +03:00
Cameron Gutman 4de3aa96b6 Add YUV colorspace and color range attributes to EGLImage 2021-11-19 01:15:33 -06:00
Cameron Gutman 1193943228 Re-add comment on color_range comparison 2021-11-19 00:56:46 -06:00
Cameron Gutman 2959faca0c Fix colorspace transitions in EGLRenderer 2021-11-19 00:54:59 -06:00
Cameron Gutman d0df4fa3a0 Fix handling of HDR colorspace transitions in VT renderer 2021-11-19 00:28:15 -06:00
liyu 0a301dd2f9 enables H265 HDR option and adds PQ transforeFunction to render HDR stream on macOS 10.13+ 2021-11-18 23:42:44 -06:00
Cameron Gutman 43e3679297 Revert "Disable the EGL render thread on Wayland"
This reverts commit dcc567ebda.
2021-11-15 21:33:28 -06:00
Cameron Gutman 0455063854 Fix driver version check for Intel's updated version schema in 100 and newer drivers
Fixes #673
2021-11-13 20:44:10 -06:00
Cameron Gutman 12d90d77c7 Fix unintentionally concatenated strings 2021-11-08 19:47:01 -06:00
Cameron Gutman 61d7749aaf Update pre-built dependencies
SDL -> 7f308ab
OpenSSL -> 1.1.1l
FFmpeg -> 4.4.1
2021-11-04 22:49:30 -05:00
曹恩逢 69fb4a0c37 Translated using Weblate (Chinese (Traditional))
Currently translated at 77.9% (145 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2021-11-01 07:34:45 +01:00
Cameron Gutman d2c9f058f8 Add names to session threads 2021-10-24 16:22:49 -05:00
Cameron Gutman acaa3afa0f Rerun lupdate and lrelease 2021-10-06 21:14:21 -05:00
Cameron Gutman 3c58e21cbf Merge remote-tracking branch 'origin/weblate' 2021-10-06 21:12:14 -05:00
曹恩逢 9d3c5b9bc6 Translated using Weblate (Chinese (Traditional))
Currently translated at 76.8% (143 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2021-10-07 04:07:30 +02:00
Eric ce34358d46 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2021-10-07 04:07:29 +02:00
Cameron Gutman 278bcec238 Integrate new languages 2021-10-06 21:03:02 -05:00
Cameron Gutman 128f458848 Merge remote-tracking branch 'origin/weblate' 2021-10-06 20:15:11 -05:00
Cameron Gutman 7ae2bcd6db Update AppImage to libva 2.13 2021-10-06 20:13:05 -05:00
Luna Jernberg 130f252f97 Translated using Weblate (Swedish)
Currently translated at 31.7% (59 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/sv/
2021-10-06 13:05:00 +02:00
SWZ d339e05a3b Added translation using Weblate (Swedish) 2021-10-01 20:57:41 +02:00
Jorys Paulin 933f4813aa Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-09-25 11:38:59 +02:00
BOYI LIN f14e71c1d6 Translated using Weblate (Chinese (Traditional))
Currently translated at 38.1% (71 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2021-08-27 17:33:01 +02:00
Mert d78dbd7b0f Translated using Weblate (Turkish)
Currently translated at 8.0% (15 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/tr/
2021-08-24 02:37:31 +02:00
Cameron Gutman 71a6ef6eba Update SDL to 402b86f in AppImage 2021-08-15 15:23:05 -05:00
Cameron Gutman 4873862d16 Use SDL_WaitEventTimeout() on SDL 2.0.16 2021-08-15 15:16:51 -05:00
Cameron Gutman 425efe3d72 Switch to SDL audio backend by default on Windows and macOS 2021-08-15 14:58:29 -05:00
Cameron Gutman 666dc13c01 Use SDL's new support for keyboard grab on macOS 2021-08-15 14:54:26 -05:00
Cameron Gutman 267f9f5759 Update SDL to 402b86f for Windows and macOS 2021-08-15 14:47:10 -05:00
Cameron Gutman c8d8c00f84 Update Visual C++ Runtime installers 2021-08-15 12:17:09 -05:00
Cameron Gutman dcc567ebda Disable the EGL render thread on Wayland 2021-07-31 17:24:18 -05:00
LiuAnnan a199a3ccc3 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.4% (185 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2021-07-30 08:34:39 +02:00
Cameron Gutman 8159e07427 Ensure our GL context is always current 2021-07-28 20:31:22 -05:00
Nikita Epifanov 32d70758c5 Translated using Weblate (Russian)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2021-07-23 10:32:32 +02:00
Jorys Paulin 3a9e284f29 Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-07-19 17:34:21 +02:00
Cameron Gutman c658daeac6 Remove unneccessary EVP_get_digestbyname() invocation
This causes problems with pre-OpenSSL 1.1.0 clients that don't
call OpenSSL_add_all_algorithms() during initialization. This
is known to affect Steam Link on firmware 815.
2021-07-17 20:32:50 -05:00
Jorys Paulin f605169b15 Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-07-15 15:33:00 +02:00
Cameron Gutman f82b495bcc Switch to the new Sectigo certificate 2021-07-14 21:09:48 -05:00
Tygo T 33b44a87c5 Translated using Weblate (Dutch)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2021-07-06 14:33:19 +02:00
Gerard Joling a88d994fcb Translated using Weblate (Dutch)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nl/
2021-07-05 13:48:27 +02:00
Gerard Joling dd9224d9a6 Added translation using Weblate (Dutch) 2021-07-05 10:39:15 +02:00
Cameron Gutman 48728efee0 Add support for dynamic HTTPS port 2021-07-03 00:00:27 -05:00
Cameron Gutman 043c55ae66 Add missing changes to fix build 2021-07-02 23:54:17 -05:00
Cameron Gutman fa3f822cf1 Rework handling of addresses to allow alternate HTTP ports 2021-07-02 23:34:54 -05:00
Cameron Gutman 5afab126b3 Refactor NvPairingManager, NvComputer, and NvHTTP to reduce passing of addresses 2021-07-02 17:14:48 -05:00
Cameron Gutman bee8378795 Pass RTSP session URL to moonlight-common-c for dynamic ports 2021-07-02 01:51:08 -05:00
Cameron Gutman cbd42f4a58 Log launch, resume, and quit responses 2021-07-02 01:18:57 -05:00
Furkan 3333fd7fc8 Added translation using Weblate (Turkish) 2021-07-01 17:52:59 +02:00
DankXylese 142258b4b5 Translated using Weblate (Ukrainian)
Currently translated at 1.6% (3 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/uk/
2021-06-30 13:32:33 +02:00
DankXylese 01213b58ba Added translation using Weblate (Ukrainian) 2021-06-29 12:59:43 +02:00
wkopiaspupn 51df7032bb Translated using Weblate (Chinese (Traditional))
Currently translated at 35.4% (66 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2021-06-27 14:32:49 +02:00
wkopiaspupn c033ce5ecf Translated using Weblate (Chinese (Traditional))
Currently translated at 1.6% (3 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hant/
2021-06-26 13:33:38 +02:00
wkopiaspupn bfaf57cfd0 Added translation using Weblate (Chinese (Traditional)) 2021-06-26 13:31:04 +02:00
Cameron Gutman 6c523570e5 Prepare for v3.1.4 2021-06-25 20:39:30 -05:00
Cameron Gutman 047e5bdd81 Update AppImage to libva 2.12 2021-06-24 21:47:01 -05:00
Cameron Gutman 6b1559d397 Update moonlight-common-c to fix audio problems with old GFE and Sunshine versions 2021-06-21 19:26:08 -05:00
WALKTHROUGH RAYMAND LEGENDS a3167b8152 Translated using Weblate (Hungarian)
Currently translated at 2.1% (4 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/hu/
2021-06-15 14:32:39 +02:00
Cameron Gutman cbeb23f16a Adjust Steam Link icon size to 116x116 2021-06-13 16:53:03 -05:00
WALKTHROUGH RAYMAND LEGENDS b4a6512784 Added translation using Weblate (Hungarian) 2021-06-13 21:47:33 +02:00
Cameron Gutman 1af2742013 Update moonlight-common-c to fix spurious exit of fast audio recovery mode on startup 2021-06-13 11:20:28 -05:00
Cameron Gutman 8048938158 Fix Linux build 2021-06-12 16:12:46 -05:00
Cameron Gutman 3689c7f982 Don't enable input capture if the window can't be foregrounded 2021-06-12 13:59:13 -05:00
Cameron Gutman 96c7057fee Update moonlight-common-c to avoid qwave.dll dependency 2021-06-12 12:21:55 -05:00
Cameron Gutman df7c4c82a9 Update moonlight-common-c with performance optimizations 2021-06-09 23:23:47 -05:00
Cameron Gutman 18d8db338b Update moonlight-common-c 2021-06-08 20:19:39 -05:00
Cameron Gutman 9637639e31 Update moonlight-common-c with audio FEC support 2021-06-04 18:46:36 -05:00
Héctor 17abe8f164 Translated using Weblate (Spanish)
Currently translated at 35.4% (66 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-05-27 21:33:27 +02:00
Cameron Gutman badaaece04 Update moonlight-common-c 2021-05-25 20:39:53 -05:00
Cameron Gutman 56119eebae Adapt to constification of AVCodec in FFmpeg master 2021-05-24 23:27:31 -05:00
Cameron Gutman c17c8e2a2c Remove receive time from performance overlay
It is largely superseded by network latency
2021-05-22 13:59:14 -05:00
Cameron Gutman e45a60f2ed Save RTT in VIDEO_STATS so it can be logged on disconnect 2021-05-22 13:57:12 -05:00
Cameron Gutman ebe9356937 Integrate Thai and Korean translations 2021-05-22 13:44:45 -05:00
Cameron Gutman 0094305299 Merge remote-tracking branch 'origin/weblate' 2021-05-22 13:33:20 -05:00
NicolasS b27050d3bf Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-05-22 18:32:19 +02:00
Jorys Paulin d941e596ad Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-05-22 18:32:19 +02:00
sanhoe ddaec92da5 Translated using Weblate (Korean)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2021-05-21 16:14:30 +02:00
sanhoe 1c0a4c92a8 Translated using Weblate (Korean)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ko/
2021-05-20 21:45:31 +02:00
sanhoe 383c00afbd Added translation using Weblate (Korean) 2021-05-20 16:32:05 +02:00
Krit789 d3b2bff8ad Translated using Weblate (Thai)
Currently translated at 41.9% (78 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/th/
2021-05-18 00:32:49 +02:00
Cameron Gutman 77aaa6141d Update moonlight-common-c to avoid excessive ENet retransmissions when RTT variance is 0 2021-05-16 15:40:38 -05:00
Krit789 2bb1af61d0 Added translation using Weblate (Thai) 2021-05-16 21:58:44 +02:00
Cameron Gutman 40b29472b3 Update moonlight-common-c with more accurate RTTs, minRequiredFecPackets, and input queue draining 2021-05-16 14:46:57 -05:00
Cameron Gutman 5d5029de59 Increase limit for the --fps option 2021-05-16 14:45:53 -05:00
Cameron Gutman cc96e6a222 Rebase AppImage on Ubuntu Bionic and Qt 5.15.2 2021-05-16 12:45:34 -05:00
Cameron Gutman 581c9438ca Add network latency to stats overlay 2021-05-15 14:40:31 -05:00
Cameron Gutman 54bd427f26 Integrate Japanese and Vietnamese translations 2021-05-13 00:24:00 -05:00
Cameron Gutman c55d184195 Rerun lupdate-pro and lrelease-pro 2021-05-13 00:13:58 -05:00
Cameron Gutman b279f94789 Merge remote-tracking branch 'origin/weblate' 2021-05-13 00:06:47 -05:00
bruh f3a897e99a Translated using Weblate (Vietnamese)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/vi/
2021-05-13 07:04:50 +02:00
bruh 392b1b5904 Added translation using Weblate (Vietnamese) 2021-05-12 07:36:31 +02:00
grtw2116 4daa8066a6 Translated using Weblate (Japanese)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ja/
2021-05-10 07:33:45 +02:00
NicolasS 8a89951286 Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-05-08 07:28:33 +02:00
grtw2116 c41ed55291 Added translation using Weblate (Japanese) 2021-05-08 07:28:33 +02:00
Cameron Gutman caba0499d7 Prepare for v3.1.3 2021-05-07 19:07:52 -05:00
Cameron Gutman 13deacfc3b Fix Spanish translation args 2021-05-07 18:56:08 -05:00
Cameron Gutman 7231085456 Run lupdate-pro and lrelease-pro 2021-05-06 17:26:26 -05:00
Cameron Gutman 663bb4aa10 Merge remote-tracking branch 'origin/weblate' 2021-05-06 17:24:39 -05:00
Cameron Gutman 18721b4542 Improve sanity checking and logging for unsupported GFE versions 2021-05-06 17:18:47 -05:00
NicolasS 19232722e2 Translated using Weblate (French)
Currently translated at 100.0% (186 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-05-05 22:32:11 +02:00
Cameron Gutman d2eca68484 Update moonlight-common-c to attempt to fix audio latency issues 2021-05-04 10:22:29 -05:00
Héctor 091167478e Translated using Weblate (Spanish)
Currently translated at 23.6% (44 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-05-04 10:32:11 +02:00
Cameron Gutman 547b8abc56 Prepare for v3.1.2 release 2021-05-03 17:38:14 -05:00
Héctor dbfac45d59 Translated using Weblate (Spanish)
Currently translated at 17.7% (33 of 186 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-05-03 09:32:23 +02:00
Cameron Gutman 086f6de867 Work around broken package repositories in AppVeyor 2021-05-02 14:49:07 -05:00
Cameron Gutman 0f93091848 Update SDL_GameControllerDB 2021-05-02 10:56:50 -05:00
Cameron Gutman ac19f62ed9 Never display placeholder text for an app collector game
Fixes #567
2021-05-02 10:39:25 -05:00
Cameron Gutman 8fcef63890 Don't waste time performing extra decoder initializations for EGL when it's not supported 2021-04-30 20:52:09 -05:00
Cameron Gutman 34cd2c1afa Run lupdate-pro and lrelease-pro 2021-04-30 20:09:15 -05:00
Cameron Gutman 5d1a19d49c Merge remote-tracking branch 'origin/weblate' 2021-04-30 20:07:59 -05:00
Cameron Gutman 2fbb320539 Refuse to stream if Moonlight is known incompatible with the host GFE version 2021-04-30 20:05:49 -05:00
Cameron Gutman b50e5ed7e6 Fix keyboard grab on X11
Fixes #584
2021-04-30 18:17:15 -05:00
Cameron Gutman 26c82ca72c Don't enable vsync on test decoders 2021-04-30 18:12:56 -05:00
Cameron Gutman f8a8a431a8 Revert warn_off removal
There are still a bunch of unused parameter warnings with GCC/Clang
2021-04-29 21:22:59 -05:00
Cameron Gutman fd27867195 Update moonlight-common-c and remove warn_off config option 2021-04-29 18:05:40 -05:00
Cameron Gutman 5e2a627795 Update moonlight-common-c with RTSP handshake retry logic 2021-04-28 17:38:59 -05:00
Cameron Gutman e081401c2d Update moonlight-common-c for multi-FEC support and audio latency fix 2021-04-26 22:51:46 -05:00
Cameron Gutman e62a268aac Avoid audio encryption on Steam Link for performance reasons 2021-04-23 19:49:03 -05:00
Cameron Gutman 140a9e5191 Enable audio stream encryption 2021-04-23 18:55:10 -05:00
Cameron Gutman 51b5f8046f Disable HTTP/2 on host PC connections for GFE 3.22 2021-04-19 18:41:01 -05:00
Cameron Gutman 91b965d1aa Update moonlight-common-c 2021-04-18 19:34:12 -05:00
Cameron Gutman f8faccee59 Remove qt5-devel which doesn't exist in Fedora 34 2021-04-17 11:11:37 -05:00
shower 6ac46a36a7 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (184 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2021-04-17 13:27:02 +02:00
Héctor 27572ba4bc Translated using Weblate (Spanish)
Currently translated at 16.3% (30 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-04-15 22:27:01 +02:00
Cameron Gutman 21be832161 Prepare for v3.1.1 release 2021-04-09 21:07:05 -05:00
Cameron Gutman 5769632793 Update moonlight-common-c for initial GFE 3.22 compatibility 2021-04-09 20:18:47 -05:00
Cameron Gutman 9efd959ed8 Merge branch 'weblate' 2021-04-09 20:17:39 -05:00
Cameron Gutman 5c72afe17e Run lupdate-pro and lrelease-pro 2021-04-04 20:45:57 -05:00
a dc24319333 Translated using Weblate (Russian)
Currently translated at 100.0% (184 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2021-04-05 03:42:34 +02:00
Jorys Paulin 1acbdf94aa Translated using Weblate (French)
Currently translated at 100.0% (184 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-04-05 03:42:33 +02:00
Cameron Gutman 44229dfe51 Update translations
- Add RU and ES to resources.qrc and app.pro
- Rerun lupdate-pro and lrelease-pro
2021-04-04 10:25:06 -05:00
a 13206227d9 Translated using Weblate (Russian)
Currently translated at 100.0% (184 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2021-04-04 17:03:35 +02:00
Cameron Gutman e3e8a57df6 Update to OpenSSL 1.1.1k and FFmpeg 4.3.2 2021-03-31 20:27:33 -05:00
Cameron Gutman 7afff80984 Update moonlight-common-c to pick up AMF HEVC parsing fix 2021-03-31 20:07:45 -05:00
Cameron Gutman 500522418e Fix AppImage build 2021-03-28 16:07:20 -05:00
a 5ccac5a5c3 Translated using Weblate (Russian)
Currently translated at 45.1% (83 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/ru/
2021-03-28 14:29:40 +02:00
Héctor 69822f4401 Translated using Weblate (Spanish)
Currently translated at 11.4% (21 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/es/
2021-03-28 14:29:39 +02:00
reloxx13 f290cfbd35 Translated using Weblate (German)
Currently translated at 100.0% (184 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2021-03-28 14:29:39 +02:00
Cameron Gutman fae30f59ce Add attribution for Cloudsmith 2021-03-27 12:40:51 -05:00
a a15f303c0a Added translation using Weblate (Russian) 2021-03-26 05:05:09 +01:00
Cameron Gutman 5e85038d78 Update AppImage to libva 2.11 2021-03-25 22:17:51 -05:00
Héctor 4e7b35c54e Added translation using Weblate (Spanish) 2021-03-25 09:04:18 +01:00
Cameron Gutman 48dde310ae Add Norwegian Bokmål to the build 2021-03-24 20:40:22 -05:00
Cameron Gutman 6b041e7657 Run lrelease-pro 2021-03-24 20:39:52 -05:00
Cameron Gutman 69576ee1e1 Run lupdate-pro 2021-03-24 20:39:39 -05:00
Cameron Gutman bd3105f62e Merge remote-tracking branch 'origin/weblate' 2021-03-24 20:28:24 -05:00
Cameron Gutman 02e3f0e71b Add missing declaration 2021-03-22 23:32:00 -05:00
Cameron Gutman 74bf981f3d Ensure hwframe read-back works in SDL renderer 2021-03-22 23:15:14 -05:00
Cameron Gutman 32f0678692 Only pass modifiers array if DRM_MODE_FB_MODIFIERS is set 2021-03-22 22:52:06 -05:00
Cameron Gutman e74753bec1 Allow fallback from EGL to direct on EGLImage export failure 2021-03-22 22:51:29 -05:00
Cameron Gutman 4a8c9ad17f Add support for 4-plane frames 2021-03-22 00:46:04 -05:00
Cameron Gutman 0c6c882f50 Fix attribute buffer overflow for fully planar YUV formats 2021-03-22 00:14:06 -05:00
Cameron Gutman 579f25c1ba Add missing EGL_DMA_BUF_PLANE2 definitions 2021-03-22 00:02:03 -05:00
Cameron Gutman d5eb5c8816 Fix build with EGL 1.4 headers 2021-03-21 23:59:35 -05:00
Cameron Gutman 26d04b5f9c Render DRM-PRIME frames as opaque images
We can't always assume they are NV12. Even if they _are_ NV12,
they may have DRM format modifiers that are incompatible with
simply assuming linear Y and UV buffers (such as tiling).
2021-03-21 23:23:12 -05:00
Cameron Gutman a0b9684504 Continue refactoring for non-NV12 support in EGLRenderer 2021-03-21 21:43:57 -05:00
Cameron Gutman 402b6d1f0c Begin refactoring for non-NV12 support in EGLRenderer 2021-03-21 19:20:52 -05:00
Cameron Gutman e87a5fa354 Pass DRM format modifiers to FB creation 2021-03-21 17:54:10 -05:00
Allan Nordhøy 63574f643e Translated using Weblate (Norwegian Bokmål)
Currently translated at 70.1% (129 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2021-03-21 10:36:54 +01:00
Cameron Gutman 1d6b1020c3 Translated using Weblate (French)
Currently translated at 73.9% (136 of 184 strings)

Translation: Moonlight Game Streaming/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-03-21 06:29:36 +01:00
Allan Nordhøy 96337a3230 Translated using Weblate (Norwegian Bokmål)
Currently translated at 16.3% (30 of 184 strings)

Translation: moonlight/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/nb_NO/
2021-03-21 02:33:56 +01:00
reloxx13 950c59d8b4 Translated using Weblate (German)
Currently translated at 100.0% (184 of 184 strings)

Translation: moonlight/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/de/
2021-03-21 02:33:56 +01:00
Allan Nordhøy 9cfd095281 Added translation using Weblate (Norwegian Bokmål) 2021-03-21 02:33:56 +01:00
Anonymous 996e049863 Translated using Weblate (Chinese (Simplified))
Currently translated at 96.1% (177 of 184 strings)

Translation: moonlight/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/zh_Hans/
2021-03-21 02:33:56 +01:00
Anonymous 6e42817c3e Translated using Weblate (French)
Currently translated at 74.4% (137 of 184 strings)

Translation: moonlight/moonlight-qt
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-qt/fr/
2021-03-21 02:33:56 +01:00
Cameron Gutman 7758344a57 Fix Weblate badge 2021-03-20 18:12:04 -05:00
Cameron Gutman b5df566b6b Add Weblate links to readme
Closes #539
2021-03-20 18:11:15 -05:00
Cameron Gutman e21fd19a70 Prepare for v3.1.0 release 2021-03-14 11:30:21 -05:00
Cameron Gutman 98672c8e44 Allow remote desktop mouse mode in embedded mode
It can be easier to control the mouse on the desktop that way
2021-03-13 16:58:58 -06:00
Cameron Gutman 2e92f0640b Update SDL_GameControllerDB 2021-03-13 15:50:01 -06:00
Cameron Gutman d6b314f573 Add option to build for embedded environments 2021-03-13 15:20:58 -06:00
Cameron Gutman d7a150ffa8 Only enable capture mode list if capture toggle is enabled 2021-03-13 14:59:32 -06:00
Cameron Gutman 955da6be30 Enable Gallium VAAPI driver on VAAPI 1.x 2021-03-13 14:37:13 -06:00
Cameron Gutman b5f8e6738a Move LANG_DE to the end of the Language enum 2021-03-09 20:13:55 -06:00
reloxx13 d7fa8c9795 Add german translation (#536)
* add german translation

* add german to language list

* donttranslate language names. always use the native name.

* add compiled german translation file

* german translation handling

* add german to getSuffixFromLanguage

* update german string and translation

* update all language files with new strings

* typo

* compile

* more typos and fixes for german
2021-03-09 20:10:36 -06:00
Cameron Gutman acb7a5b3c8 Fix XCB out-of-sequence abort after switching to non-threaded Qt renderer 2021-03-07 16:48:10 -06:00
Cameron Gutman 783a57ef89 Use separate thread for streaming on X11 and Wayland 2021-03-07 12:15:42 -06:00
Cameron Gutman d33ccce683 Hold a reference to the underlying DMA-BUFs until the next frame 2021-03-07 12:01:25 -06:00
Cameron Gutman d722bf10b9 Don't use glFinish() with KMSDRM backend 2021-03-07 11:23:31 -06:00
Cameron Gutman 41337475a2 Update SDL_GameControllerDB 2021-03-06 14:29:55 -06:00
Cameron Gutman f504a069d7 Update VCRedist version for VC 16.9 2021-03-05 17:51:26 -06:00
Cameron Gutman 96f79688dd Use av_packet_alloc() instead of av_init_packet()
sizeof(AVPacket) may be deprecated from ABI in the near future
2021-03-05 17:47:04 -06:00
Cameron Gutman c330898aeb Add workaround for AppView breaking after changing language at runtime 2021-03-05 17:44:31 -06:00
Cameron Gutman 94952cf0a4 Update issue template 2021-03-03 01:39:55 -06:00
Cameron Gutman a3c249abe9 Don't load the app label asynchronously 2021-03-02 19:03:09 -06:00
Cameron Gutman c26562fab8 Fix Steam Link build 2021-03-02 18:57:16 -06:00
Cameron Gutman b7cbd99212 Fix tooltip display in app grid 2021-03-02 18:35:50 -06:00
Cameron Gutman b53ef35a85 Improve loading speed of PC and app grids 2021-03-02 18:32:56 -06:00
Cameron Gutman 1ebb5fefb1 Address Clazy warnings 2021-03-02 18:14:15 -06:00
Cameron Gutman 164b3edd41 Fix viewport size on High DPI Wayland systems
Fixes #533
2021-03-01 22:47:14 -06:00
Cameron Gutman 819ea36cca Hack to fix build on AppVeyor 2021-02-28 16:47:39 -06:00
Cameron Gutman 088c9b9e4e Stop single-arch binary build before extracting dSYM 2021-02-28 16:02:50 -06:00
Cameron Gutman ab25a9b8ee Add Universal binary support to build script 2021-02-28 15:49:59 -06:00
Cameron Gutman b2aea9f8f0 Revert change to only fire special combos on key up 2021-02-28 15:06:46 -06:00
Cameron Gutman 5399b95936 Fix update checker on macOS with Qt 6.0 builds 2021-02-28 14:33:20 -06:00
Cameron Gutman 1d5c120748 Add support for specifying minimum kernel versions in the update manifest 2021-02-28 14:27:29 -06:00
jmt-gh 6be7301e69 Stats overlay controller combo (#495)
* Update gamepad.cpp

add gamepad combo to toggle stats overlay

* typo fixes
2021-02-27 17:03:52 -06:00
Maximiliano Bertacchini fff9f2b17d Add numpad Enter handlers (Keys.onEnterPressed) (#516) 2021-02-27 17:01:22 -06:00
Cameron Gutman 87a7d2e45c Add setting to only capture system keys in full-screen 2021-02-27 16:47:38 -06:00
Cameron Gutman 58803ef40d Update SDL to e561ce3 and OpenSSL to 1.1.1j 2021-02-27 13:08:21 -06:00
Cameron Gutman b27ca993aa Add support for system key capture in windowed mode on macOS 2021-02-26 21:43:47 -06:00
Cameron Gutman 28ecc6bcbf Remove old Qt Multimedia audio renderer 2021-02-25 23:23:08 -06:00
Cameron Gutman 30c5e3f237 Fix window icons on Wayland 2021-02-25 23:20:21 -06:00
Cameron Gutman 6a25a3a3d0 Don't require DRM master for SDL KMSDRM backend 2021-02-25 22:27:20 -06:00
Cameron Gutman 9a84c0ae30 Update AppImage to official SDL Git repo 2021-02-25 22:00:35 -06:00
Cameron Gutman 133cc5457d Use SDL_CaptureMouse() on macOS and Linux too 2021-02-08 18:30:22 -06:00
Cameron Gutman 05e4c5b507 Move clipboard processing to a separate thread to avoid blocking the main thread during pastes 2021-02-07 17:18:35 -06:00
Cameron Gutman 8372717a09 Improve Unicode support for some common characters 2021-02-07 16:00:00 -06:00
Cameron Gutman 5f3f2a96fd Improve detection of having no clipboard text 2021-02-07 13:53:03 -06:00
Cameron Gutman b83c6f0c28 Add support for pasting clipboard text 2021-02-07 13:46:38 -06:00
Cameron Gutman 36dc0f3e3c Use mouse capture for Win32 instead of our global mouse state hack 2021-02-07 12:38:57 -06:00
Cameron Gutman b4edde6f90 Disable Qt 6 threaded renderer on Windows
They switched from non-threaded to threaded by default in Qt 6
2021-02-07 11:21:47 -06:00
Cameron Gutman 395eb5581c Cache results of WMUtils::isRunningX11() and WMUtils::isRunningWayland() 2021-02-07 11:03:53 -06:00
Cameron Gutman 6dab251055 Don't overwrite window mode settings when switching between WM and non-WM environments 2021-02-07 10:49:29 -06:00
Cameron Gutman 3bd6a6a614 Fullscreen is no longer required for passing system keyboard shortcuts 2021-02-06 20:15:58 -06:00
Cameron Gutman 93d21a0d1d Fix EGLImage leak when not using a hwaccel backend 2021-02-06 17:59:05 -06:00
Cameron Gutman 2c2a73e320 Fix build and require SDL 2.0.15 to hook 2021-02-06 17:07:21 -06:00
Cameron Gutman a88a3c9ea3 Allow SDL to render with KMSDRM backend while Qt is also using DRM 2021-02-06 16:32:54 -06:00
Cameron Gutman e4df70cd56 Use the async connect thread on all platforms
It turned out that the cause of the random crashes was the threaded renderer
that we now turn off.
2021-02-06 15:14:15 -06:00
Cameron Gutman 90f7d35150 Always use a non-threaded renderer
This ensures we can block Qt's rendering as needed to synchronize with SDL
2021-02-06 14:58:30 -06:00
Cameron Gutman 75b19a60c1 Fix build on macOS and keyboard grab bugs 2021-02-06 11:29:18 -06:00
Cameron Gutman 9fc921f49f Use SDL's keyboard grab support now that it's been upstreamed 2021-02-05 00:13:20 -06:00
Cameron Gutman 4b9e90ac72 Update SDL for Windows and macOS to Hg 60b9ce4ee73e
https://github.com/cgutman/moonlight-deps/commit/ad955430988be24fd379a6152642c7ce4053bc7f
2021-02-04 20:51:33 -06:00
Cameron Gutman 36dd6c83e0 Fix assert failure when using v4l2m2m with EGL 2021-02-04 20:38:18 -06:00
Cameron Gutman d790313221 Use the existing install of Qt on macOS in CI 2021-02-04 19:39:58 -06:00
Cameron Gutman c3895f06c0 Fix handling of preferred/compatible pixel formats with EGLRenderer and VAAPI/DRM backends 2021-02-04 19:39:18 -06:00
Cameron Gutman 76e81fa651 Add windowed support for MMAL 2021-02-03 20:57:39 -06:00
Cameron Gutman d63a1b0eb0 Handle custom hwaccel decoders 2021-02-02 19:45:22 -06:00
Cameron Gutman 4dffac3c78 Ask for NV12 buffers for DRMRenderer 2021-02-02 19:40:06 -06:00
Cameron Gutman 88391b0274 Use the decoder's supported pix_fmts to select a suitable renderer 2021-02-02 19:05:27 -06:00
Cameron Gutman c3cea0238e Fix build with old EGL 1.5 headers without EGL_EGL_PROTOTYPES 2021-01-31 21:42:56 -06:00
Cameron Gutman 5bf4266973 Fix build with old Mesa EGL headers 2021-01-31 18:41:53 -06:00
Cameron Gutman ed57c54d06 Move EGL definitions into renderer.h to try to fix build on Armbian 2021-01-31 17:01:11 -06:00
Cameron Gutman 01936e000e Fix Steam Link bundle build 2021-01-31 16:27:38 -06:00
Cameron Gutman 80137848dc Add DMA-BUF export compatibility with EGL 1.4 2021-01-31 16:24:31 -06:00
Cameron Gutman 149575e0c4 Don't retranslate if the language didn't change 2021-01-31 15:28:00 -06:00
Cameron Gutman 6a66b462ce Allow DRMRenderer to be used for indirect rendering 2021-01-31 15:19:19 -06:00
Cameron Gutman 1e31f6fe77 Fix initialization of DRM backend with X running 2021-01-31 15:03:40 -06:00
Cameron Gutman f173b3ff09 Attempt to fix AppImage and Steam Link build errors 2021-01-31 14:48:42 -06:00
Cameron Gutman baffab62ce Fix uninitialized variable warning 2021-01-31 12:58:19 -06:00
Cameron Gutman d141cec2a8 Fix mangled macOS libraries after transition to submodule 2021-01-31 12:23:52 -06:00
Cameron Gutman df87ac3810 Update SDL in AppImage to Hg d75deb75464a 2021-01-31 12:13:20 -06:00
Cameron Gutman 46960ce0a4 Remove side-by-side support for Qt 5.9 on Steam Link 2021-01-31 12:08:15 -06:00
Cameron Gutman 522206b0bc Use shallow-cloned submodule for prebuilts 2021-01-31 11:50:41 -06:00
Cameron Gutman 24d60dd3ab Remove prebuilt binaries 2021-01-31 11:40:41 -06:00
Cameron Gutman dbfdc2fd14 Share DRM FD and GBM device with SDL
Depends on https://hg.libsdl.org/SDL/rev/d75deb75464a
2021-01-30 21:11:52 -06:00
Cameron Gutman a97912e297 Print the error when querying EGL_EXTENSIONS fails 2021-01-30 20:13:20 -06:00
Cameron Gutman cedba501ee Query the frontend renderer to determine fullscreen-only limitations 2021-01-30 17:57:34 -06:00
Cameron Gutman ac947d3bda Add EGLImage export support to DRMRenderer 2021-01-30 17:52:23 -06:00
Cameron Gutman 243ba371b3 Initialize a DRM hardware context for hwaccel usage 2021-01-30 16:33:58 -06:00
Cameron Gutman 3af24eafbb Build fixes 2021-01-30 12:53:57 -06:00
Cameron Gutman 69b6022afe Add language selection option in settings
Fixes #501
2021-01-30 12:14:31 -06:00
Cameron Gutman 1cd66419d4 Remember desired cursor hide state
Fixes #511
2021-01-30 11:08:01 -06:00
WLongandWLong 5309a02f6d Add simplified Chinese language (#506)
* 添加qml_zh_cn.ts

* 更新部分翻译

* 优化部分文字描述

* 优化部分文字描述

* 恢复README.md

Co-authored-by: WLong <a101084@126.com>
2021-01-30 10:10:36 -06:00
Cameron Gutman 541784382a Add support for AV_HWDEVICE_TYPE_DRM hwaccels 2021-01-30 10:00:01 -06:00
Cameron Gutman 2a7fae2c82 Revert "Add logic to try LibreELEC's out-of-tree stateless V4L2 decoders"
v4l2request is a hwaccel not a decoder

This reverts commit ed3a5448b1.
2021-01-29 20:30:01 -06:00
Cameron Gutman ed3a5448b1 Add logic to try LibreELEC's out-of-tree stateless V4L2 decoders 2021-01-29 20:19:27 -06:00
Cameron Gutman 2eb4769bbc Only trigger special key combos when all keys are up 2021-01-24 13:02:42 -06:00
Cameron Gutman 02019000df Ctrl+Alt+Shift+Down Arrow is a reserved key combo on GNOME, so switch to Ctrl+Alt+Shift+D 2021-01-21 23:05:48 -06:00
Cameron Gutman 6262f51c96 Key capture is supported on Wayland with latest SDL Hg 2021-01-21 21:07:54 -06:00
Cameron Gutman d38ff5759a Add Ctrl+Alt+Shift+Down Arrow shortcut to minimize 2021-01-21 19:39:17 -06:00
Cameron Gutman f6de2e4dd3 Revert "Disable the system keyboard capture option on Wayland"
SDL now supports keyboard grab with https://hg.libsdl.org/SDL/rev/b0e13627c656

This reverts commit bc10fd0aba.
2021-01-20 21:43:16 -06:00
Cameron Gutman 3959f447d4 Fix detection of x64 architecture on some machines 2021-01-17 12:58:08 -06:00
Cameron Gutman 14a6a69dc0 Version 3.0.0 2021-01-17 10:33:10 -06:00
Cameron Gutman 3191182009 Update Windows SDL to Hg a5b970d28bfd 2021-01-17 10:17:27 -06:00
Cameron Gutman e210dc748f Update macOS SDL to Hg a5b970d28bfd 2021-01-17 10:08:45 -06:00
Cameron Gutman 724dcb557f Hide irrelevant options on embedded devices 2021-01-15 19:46:27 -06:00
Cameron Gutman 11d274ff07 Fix X11 keyboard grab when starting in windowed mode 2021-01-15 19:32:38 -06:00
Cameron Gutman ae246b1005 Trim keyboard shortcut setting text slightly 2021-01-15 19:25:28 -06:00
Cameron Gutman ca0250280a Update moonlight-common-c submodule 2021-01-14 19:32:32 -06:00
Cameron Gutman f49d6e15a4 Fix clearing the wrong flag when activating mouse capture 2021-01-14 19:30:30 -06:00
Cameron Gutman 7172cfd889 Properly handle multiple window event flush barriers in flight at once
Fixes streaming on macOS Mojave without Metal support
2021-01-14 19:28:21 -06:00
Cameron Gutman 89e9652075 Save preferences on destruction in case the user closes Moonlight directly from the settings page 2021-01-13 19:43:52 -06:00
Cameron Gutman 53098edc85 Print which archs were bundled in the installer after the build completes 2021-01-13 19:36:46 -06:00
Cameron Gutman e9968fbab3 Add system key capture to the feature list 2021-01-13 19:36:17 -06:00
Cameron Gutman bc10fd0aba Disable the system keyboard capture option on Wayland 2021-01-12 20:41:20 -06:00
Cameron Gutman 76b4922bbe Add toggle for system key capture 2021-01-12 20:05:18 -06:00
Cameron Gutman 8e790c4745 Use real full-screen on macOS when capturing keys 2021-01-12 19:57:01 -06:00
Cameron Gutman c331b180cb Fix modifier keys being stuck down after key combos when capturing system keys on Windows 2021-01-12 18:40:00 -06:00
Cameron Gutman 30e3b02867 Start implementation of system key capture 2021-01-11 23:43:32 -06:00
Cameron Gutman bedea4a093 Rebuild SDL2_ttf.framework as a Universal binary 2021-01-10 14:32:43 -06:00
Cameron Gutman 5372cfba20 Minor fixes to kiosk mode PR
- UI_FULLSCREEN_WINDOWED -> UI_MAXIMIZED
- Propagate user configuration from old "start windowed" option
- Use FullScreen when a window manager isn't present
- Set disabled control to FullScreen with no window manager
2021-01-10 10:09:31 -06:00
jmt-ghandjmt-gh 19dac306d1 Add support for Fullscreen UI in Moonlight (#492)
* initial UI and window decoration removal toggle

* revert default height change

* add fullscreen support to kiosk mode

* add tool tip for kiosk mode

* change to fullscreen rather than kiosk

* update to Fullscreen instead of Full-screen or Full Screen

* update UI text

* convert to display mode picker

* add UI label for picker

* clean up references to startMaximized and fullScreenUIMode

* remove flags property, as fullscreen visiblity handles this already

* use Maximized in selection text

* account for running moonlight without a window manager

* lock display mode from being changed if there is no window manager running

Co-authored-by: jmt-gh <jmt-gh@users.noreply.github.com>
2021-01-10 09:50:12 -06:00
Cameron Gutman e9a98a3402 Add note about multi-monitor bug to remote desktop tooltip 2021-01-09 18:03:48 -06:00
Cameron Gutman 7020749987 Change mute on minimize to mute on focus loss
Minimization doesn't always happen on focus loss in full-screen mode,
so it could lead to unpredictable behavior.
2021-01-09 17:56:23 -06:00
Cameron Gutman 2d62d090df Use a barrier to ensure we don't flush important window events 2021-01-09 17:51:25 -06:00
Cameron Gutman e6f59062fa Update SDL to Hg d7abc11bb69a
https://github.com/cgutman/moonlight-deps/commit/20ce1c15eddb0ee9b216b0928844412e3e63e1d6
2021-01-08 21:43:37 -06:00
Cameron Gutman 0d3092d62c Update SDL to Hg d7abc11bb69a
https://github.com/cgutman/moonlight-deps/commit/20ce1c15eddb0ee9b216b0928844412e3e63e1d6
2021-01-08 21:35:07 -06:00
Cameron Gutman af0921c5b2 Set new hints present in SDL 2.0.15 development builds 2021-01-08 18:14:49 -06:00
Cameron Gutman 137454beff Use SDL_UpdateNVTexture on SDL 2.0.15+ 2021-01-08 18:05:27 -06:00
Cameron Gutman a0cc93b813 Fix EGL renderer build on SDL 2.0.9 and earlier 2021-01-03 14:24:30 -06:00
Cameron Gutman ff516f63b4 Set QT_QPA_EGLFS_ALWAYS_SET_MODE=1 by default for RetroPie compatibility 2021-01-03 11:16:59 -06:00
Cameron Gutman 68acb78ae6 Use specific resuming text when reconnecting to a game 2020-12-31 21:33:41 -06:00
Cameron Gutman 949aaaff2a Add tooltip for hide games option 2020-12-31 21:31:46 -06:00
Cameron Gutman 390544cd9a Charge time spent in the decode unit queue to the decoder rather than receive time 2020-12-31 16:10:01 -06:00
Cameron Gutman 766a923f86 Reduce size of Windows installers and portable packages 2020-12-31 11:44:59 -06:00
Cameron Gutman 202ce14afa Update SDL_GameControllerDB 2020-12-30 13:34:01 -06:00
Cameron Gutman 8ff9d8123d Switch VT renderer pacing logic to be enabled by the frame pacing checkbox 2020-12-29 20:26:56 -06:00
Cameron Gutman 2715367411 Fix default audio output change detection on macOS 2020-12-28 14:37:17 -06:00
Cameron Gutman 44b61d9252 Fix accidental static import of IsWow64Process2() and tweak message text 2020-12-28 13:32:02 -06:00
Cameron Gutman 565bba6e55 Point users to ARM64 version of Moonlight if running the x86 or x64 versions 2020-12-28 12:27:22 -06:00
Cameron Gutman 2ecfb7af64 Improve description of gamepad mouse mode 2020-12-27 15:41:47 -06:00
Cameron Gutman 998d3b2cc1 Fix tooltip line wrapping 2020-12-27 15:34:49 -06:00
Cameron Gutman c923d643b9 Rebuild FFmpeg 4.3.1 (patched), discord-rpc, Opus, and OpenSSL 1.1.1i as Universal binaries
https://github.com/cgutman/moonlight-deps
4c2815b5f2045ef0e8b098ed2fa8c4f9c1f5cd77

Built locally with Xcode 12.3 with ARM64 targets enabled
2020-12-27 00:14:39 -06:00
Cameron Gutman bc39c721e3 Add a key combo to toggle cursor display in remote desktop mouse mode 2020-12-26 19:47:00 -06:00
Cameron Gutman 5096ff6496 Add options to invert scroll direction and swap gamepad buttons
Fixes #463
Fixes #467
2020-12-25 22:21:20 -06:00
Cameron Gutman a11f623b17 Add option to mute audio on minimize and background gamepad input
Fixes #461
2020-12-25 15:32:11 -06:00
Cameron Gutman f7ffb30bc6 Reorganize settings and improve descriptions 2020-12-25 12:19:22 -06:00
Cameron Gutman c7ddb54e67 Add support for bundling ARM64 binaries into the installer
It is disabled by default because Qt doesn't have official ARM64 builds yet
2020-12-24 17:21:35 -06:00
Cameron Gutman c4108feb15 Add SDL 2.0.14 hints 2020-12-24 14:31:47 -06:00
Cameron Gutman 47cad71fcd Add special error text for an early termination 2020-12-24 11:24:01 -06:00
Cameron Gutman 0b56b1685a Use LiStringifyPortFlags() instead of coding it ourselves 2020-12-23 14:08:20 -06:00
Cameron Gutman c414e1a168 Display the failing ports when the connection fails 2020-12-23 13:56:15 -06:00
Cameron Gutman 22bebb6bbc Maxwell 2 doesn't support 8K HEVC encoding 2020-12-22 18:57:45 -06:00
Cameron Gutman c3f9742bb6 Update to SDL 2.0.14 for Windows
Defines:
#undef SDL_JOYSTICK_RAWINPUT
#undef SDL_JOYSTICK_WGI
#define USE_D3D9EX 1
2020-12-21 21:00:55 -06:00
Cameron Gutman 3defccb6e2 Work around poor video scaling quality on Qualcomm GPUs 2020-12-21 21:00:55 -06:00
Cameron Gutman 1197b17509 Update AppImage to SDL 2.0.14 2020-12-21 20:30:21 -06:00
Cameron Gutman 265e28e7c3 Update to SDL 2.0.14 for macOS
This is a fat binary with both Intel and ARM64 code.
2020-12-21 20:29:55 -06:00
Cameron Gutman 9c758f1628 Create power-of-2 overlay surfaces for better performance
This lets us take the fast copy path in the DXVA2 renderer.
2020-12-20 17:31:02 -06:00
Cameron Gutman 5f4975ca5c Fix DXVA2 overlay rendering quality issus 2020-12-20 17:30:06 -06:00
Cameron Gutman e5bcc793e5 Implement overlay support in EGLRenderer
Fixes #405
2020-12-19 23:01:41 -06:00
Cameron Gutman cd5b0e74e3 Draw background in MMAL renderer on X11
Fixes #412
2020-12-19 21:25:20 -06:00
Cameron Gutman 3162d2c17d Fix aspect ratio of MMAL renderer output 2020-12-19 17:48:36 -06:00
Cameron Gutman 6a54fb649c Fix synchronization issues between render and overlay update threads in DXVA2 2020-12-18 20:23:52 -06:00
Cameron Gutman 8031ed7fe1 Run a GC before and after streaming 2020-12-18 19:54:11 -06:00
Cameron Gutman dcbf5affda Fix use-after-free in VDPAU overlay rendering 2020-12-18 19:39:24 -06:00
Cameron Gutman 027c8dcd41 Add overlay support to VDPAU renderer 2020-12-17 18:35:08 -06:00
Cameron Gutman 94b46a2173 Use a vertex buffer for rendering the DXVA2 overlays 2020-12-16 18:16:35 -06:00
Cameron Gutman b66f7f6c8b Don't persist the server cert until pairing is successful
Fixes #484
2020-12-15 21:24:21 -06:00
Cameron Gutman 355e4a5c67 Handle MSVC mkspecs with version number suffixes
ARM64 build uses win32-arm64-msvc2017
2020-12-13 23:58:13 -06:00
Cameron Gutman 1e7cb7f13e Replace D3DX9 with SDL_ttf for overlay rendering 2020-12-13 23:43:31 -06:00
Cameron Gutman d58837421f Refactor SDL overlay drawing into OverlayManager for sharing with other renderers 2020-12-13 15:51:50 -06:00
Cameron Gutman 19d5358b97 Add a PC menu header to show the current PC status 2020-12-13 12:50:56 -06:00
Cameron Gutman a6551c320d Finish Windows ARM64 bringup
SDL2  for ARM64 is not yet checked-in, but I will do that when SDL 2.0.14 is released.
2020-12-12 16:44:41 -06:00
Cameron Gutman 59a73817c8 Don't use AntiHooking.dll or use D3DX9 on ARM64 2020-12-12 13:59:47 -06:00
Cameron Gutman 1231f3eeb1 Stub out ARM64 build support in build-arch.bat 2020-12-12 13:08:45 -06:00
Cameron Gutman cd40c1dacd Update bundled libraries for AppImage 2020-12-12 12:51:00 -06:00
Cameron Gutman 33286a5bde Add ARM64 VCRedist definitions for later use 2020-12-12 12:43:21 -06:00
Cameron Gutman b61c35aff9 Rebuild SDL_ttf 2.0.15 for x86, x64, and ARM64 using FreeType 2.10.4 2020-12-10 21:16:16 -06:00
Cameron Gutman 2a3e1ba62e Rebuild FFmpeg 4.3.1, discord-rpc, Opus, and OpenSSL 1.1.1i for x86, x64, and ARM64
https://github.com/cgutman/moonlight-deps
382270e6c9a9c42addce06ef5dc6522b1368b5e2
2020-12-10 21:03:34 -06:00
Cameron Gutman d95f3277b2 Merge pull request #479 from TotalCaesar659/patch-1
Update URLs to HTTPS
2020-12-10 09:06:35 -06:00
TotalCaesar659 e0a2c8cb8a Update URLs to HTTPS 2020-12-10 16:37:29 +03:00
Cameron Gutman 0aa46a57fe Update moonlight-common-c submodule 2020-12-07 20:05:25 -06:00
Cameron Gutman 53e3cd143e Refresh display resolutions when opening the settings page 2020-12-07 19:58:42 -06:00
Cameron Gutman 8381039f97 Remove extra includes 2020-12-06 17:15:30 -06:00
Cameron Gutman a91c61e5e2 Remove Raspberry Pi PulseAudio avoidance hack
Not only is it no longer required (PA works great now), it actually breaks audio with Pi OS's new PA config
2020-12-06 16:58:41 -06:00
Cameron Gutman f90efd7e38 Fix infinite polish() loop when quitting a game due to removal of the 'overlay' property on Qt 6.0 2020-12-01 20:46:28 -06:00
Cameron Gutman fab142dd38 Add workaround for problems with Qt 6.0's Metal renderer 2020-12-01 19:13:17 -06:00
Cameron Gutman 125d546cea Fix installer build warning 2020-11-29 21:22:30 -06:00
Cameron Gutman 179f7ecc23 Fix AppVeyor artifact archival 2020-11-29 21:22:16 -06:00
Cameron Gutman 0fc30a70ca Build unified Windows installer bundles 2020-11-29 21:13:27 -06:00
Cameron Gutman f81509a892 Download VCRedist on demand rather than always bundling it in the installer 2020-11-29 20:24:23 -06:00
watchhaandwatchha fc4488f17f French update (#476)
Co-authored-by: watchha <watchha@users.noreply.github.com>
2020-11-29 11:20:25 -06:00
Cameron Gutman 2748f3d22e Update build instructions 2020-11-29 11:10:16 -06:00
Cameron Gutman e0d42cbe9c Fix index out of bounds when an app is hidden 2020-11-28 17:33:15 -06:00
Cameron Gutman 1780d9417f Disable app menu options instead of hiding them 2020-11-28 17:32:39 -06:00
Cameron Gutman 5f182b1e62 Remove "View Apps" and change "View Hidden Apps" to "View All Apps" 2020-11-28 17:29:13 -06:00
Cameron Gutman 80cee8367f Make sure the last modified time for the GCDB is not in the future 2020-11-24 00:18:34 -06:00
Cameron Gutman 7325d5657d Add custom resolution option 2020-11-24 00:13:39 -06:00
Cameron Gutman 72182c7caa Add support for selecting an app to launch directly 2020-11-23 21:38:22 -06:00
Cameron Gutman d7ca3801be Fix build on Qt 5.14 and earlier 2020-11-23 20:39:50 -06:00
Cameron Gutman 2ef714f87b Avoid runtime QT_OPENGL warning on Qt 6.0 2020-11-23 18:36:32 -06:00
Cameron Gutman 46940eb15a Enable HTTP/2 for update checking and mapping updates 2020-11-23 18:35:46 -06:00
Cameron Gutman 3485983553 Delete the cached mappings if they are empty or corrupt 2020-11-23 18:34:53 -06:00
Cameron Gutman 861ebc151a Only update gamepad mappings if they're newer than what we already have 2020-11-23 18:31:21 -06:00
Cameron Gutman ae5df938b6 Update macOS icon to match new Big Sur style 2020-11-21 16:37:56 -06:00
Cameron Gutman e224a7f0c7 Fetch updated gamepad mappings each launch 2020-11-21 14:45:34 -06:00
Cameron Gutman aa4684077d Fix inability to open app menu with gamepad 2020-11-21 13:28:04 -06:00
Cameron Gutman 193e196c46 Update searching message 2020-11-21 13:18:17 -06:00
Cameron Gutman 6e7a42065c Translation updates and refactoring 2020-11-21 13:15:54 -06:00
watchhaandwatchha 2c987d2912 French translation (#451)
* french translation

* Update main.cpp

* Update main.cpp

Co-authored-by: watchha <watchha@users.noreply.github.com>
2020-11-21 11:42:16 -06:00
Cameron Gutman 19f5dc12fb Fix fill color of Discord logo on Qt 5.9 2020-11-21 11:29:55 -06:00
Cameron Gutman 38b59aa1a9 Fix DXVA2 renderer compilation with Qt 6.0 2020-11-21 11:12:40 -06:00
Cameron Gutman 201b59cd4c Compilation fixes for Qt 6.0 Beta 3 2020-11-07 19:23:23 -06:00
Cameron Gutman de3afe27c1 Fix LSMinimumSystemVersion to match Qt 5.15 2020-11-01 09:42:03 -06:00
Cameron Gutman 7bee8e73f0 Update moonlight-common-c with QoS fix 2020-10-28 20:39:37 -05:00
Cameron Gutman 17e0fbbaf8 Update moonlight-common-c with MTU test 2020-10-17 21:53:33 -05:00
Cameron Gutman ec486e89e4 Use char16_t overload of QString::fromUtf16() for Qt 6.0 compatibility 2020-10-16 00:07:58 -05:00
Cameron Gutman ec3b000264 QTextStream::setCodec() is gone in Qt 6.0, so use the replacement setEncoding() function 2020-10-15 18:57:04 -05:00
Cameron Gutman 90a513dc3d Improve source compatibility with Qt 6.0 2020-10-15 18:54:12 -05:00
Cameron Gutman 32a74e3416 Update qmdnsengine to build with Qt 6.0 2020-10-14 22:40:25 -05:00
Cameron Gutman 1d90bf9230 Trim spaces from the provided IP address or hostname 2020-10-06 21:39:01 -05:00
Cameron Gutman 81943b12c0 Version 2.2.0 2020-09-09 22:26:12 -07:00
Cameron Gutman 18fa7c2832 Add Discord button in Settings 2020-09-09 21:49:45 -07:00
Cameron Gutman dd02bf809e Don't require linking to wlanapi.dll
This is not always available on Windows Server
2020-09-08 18:27:01 -07:00
Cameron Gutman 2f3a1a5d79 Work around bug where GLES surface creation repeatedly fails on X11 2020-09-07 23:53:29 -07:00
Cameron Gutman 18654cb011 Work around QSGRenderThread crash on Wayland 2020-09-07 23:07:31 -07:00
Cameron Gutman 5954f80645 Update common-c to avoid TCP tests for single addresses 2020-09-07 10:57:23 -07:00
Cameron Gutman 3e36357315 Remove HDR option because it doesn't currently work 2020-09-06 17:33:40 -07:00
Cameron Gutman a06a454ade Ignore ICMP Port Unreachable messages on our UDP sockets 2020-09-06 15:02:11 -07:00
Cameron Gutman c0fab4b41f Try TCP 47989 and TCP 48010 as fallbacks if 47984 doesn't work 2020-09-06 11:56:12 -07:00
Cameron Gutman 80b79f3636 Rebuild SDL for macOS
changeset 8f1abe5e7d8f

Patches:
https://bugzilla.libsdl.org/show_bug.cgi?id=5276
https://bugzilla.libsdl.org/show_bug.cgi?id=5282
2020-09-05 15:16:19 -07:00
Cameron Gutman b97ae25f93 Flush mouse position before sending a mouse button event 2020-09-05 14:50:38 -07:00
Cameron Gutman 4722ea6096 Update SDL_GameControllerDB 2020-09-05 14:08:13 -07:00
Cameron Gutman 3e9781033a Create windows with SDL_WINDOW_METAL on macOS
This prevents the window from being recreated when initializing a Metal renderer.
2020-09-05 14:06:58 -07:00
Cameron Gutman 62b296cf85 Rebuild SDL for macOS
changeset 8f1abe5e7d8f

Patches:
https://bugzilla.libsdl.org/show_bug.cgi?id=5276
2020-09-05 14:06:58 -07:00
Cameron Gutman dcbaa52683 Rebuild SDL2 for Windows
changeset 8f1abe5e7d8f

Patches:
https://bugzilla.libsdl.org/show_bug.cgi?id=5272
https://bugzilla.libsdl.org/show_bug.cgi?id=5274
https://bugzilla.libsdl.org/show_bug.cgi?id=5276

Defines:
#undef SDL_JOYSTICK_RAWINPUT
#undef SDL_JOYSTICK_WGI
#define USE_D3D9EX 1
2020-09-05 11:28:47 -07:00
Cameron Gutman 1e29f61656 Merge pull request #433 from annk15/master
Added option to switch primary and secondary mouse buttons
2020-09-05 10:40:00 -07:00
Anton 89319dc7aa Added option to swap left and right mouse buttons
Changed the use of SDL buttons to Moonlight buttons definitions
2020-09-05 08:32:00 +02:00
Cameron Gutman 5755afc4ea Fix app window not hiding when streaming starts 2020-09-04 22:38:54 -07:00
Cameron Gutman d00c434ccc Don't try STUN for manually added PCs over VPNs 2020-09-02 22:56:59 -07:00
Cameron Gutman 4ada59ba48 Populate the external IP address when a PC is added manually using an RFC 1918 IPv4 address 2020-08-30 19:03:55 -07:00
Cameron Gutman 14ccc38f4c Fix certain CLI options not overriding GUI preferences. Fixes #435 2020-08-30 01:38:26 -07:00
Cameron Gutman a8be299bbd Fix compile warnings in moonlight-common-c 2020-08-29 21:37:34 -07:00
Cameron Gutman 2e87f5ff85 Add warning if no key frames can be received in 10 seconds 2020-08-29 21:02:22 -07:00
Cameron Gutman 829ebba622 Fix STUN socket errors being clobbered by closeSocket() 2020-08-29 13:45:20 -07:00
Cameron Gutman 81019fa2a8 Initialize gamepad navigation when streaming from the terminal 2020-08-29 12:59:27 -07:00
Cameron Gutman 1bc3675548 Update AppImage to libva 2.8.0 2020-08-23 16:08:43 -07:00
Cameron Gutman 678ec979c9 Update ASan flags for x64 support in MSVC 16.7
https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/
2020-08-22 17:36:16 -07:00
Cameron Gutman d1a48ae641 Update SDL_GameControllerDB 2020-08-22 14:39:05 -07:00
Cameron Gutman eded86bc10 Allow game controllers to be ignored during streaming only
STREAM_GAMECONTROLLER_IGNORE_DEVICES and STREAM_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT environment variables provide the same functionality as SDL_GAMECONTROLLER_IGNORE_DEVICES and SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, with the difference being SDL_* variables take effect at all times (UI and streaming) while STREAM_* variables take place only while streaming.

Fixes #425
2020-08-22 12:02:26 -07:00
Cameron Gutman 5a7a49d1d5 Display resolution and codec in OSD 2020-08-20 20:52:05 -07:00
Cameron Gutman d3de8049bf QTBUG-80947 is fixed for real in Qt 5.15.1 2020-08-19 21:47:45 -07:00
Cameron Gutman d09dd90a73 Fix hardcoded tick unit duration which is incorrect on Apple silicon 2020-08-12 18:07:10 -07:00
Cameron Gutman 78203eb9be Enable media streaming mode for 802.11 WLAN interfaces on Windows 2020-08-11 22:14:26 -07:00
Cameron Gutman 31c7d4e36f Don't hide the games immediately 2020-08-11 18:46:06 -07:00
Cameron Gutman d3949806f5 Move connection establishment to a separate thread to keep the UI responsive 2020-08-10 22:21:54 -07:00
Cameron Gutman 28ff15c99e Update common-c to prevent server-side log spam 2020-08-09 17:57:12 -07:00
Cameron Gutman bd2c74fe90 Remove UDP 7 and add UDP 47009 for WoL 2020-08-09 14:49:33 -07:00
Cameron Gutman fb6995db94 Add network test option to PC context menu 2020-08-08 20:25:26 -07:00
Cameron Gutman 8c2c4d3282 Reorder PC context menu to place destructive actions at the bottom 2020-08-08 18:32:36 -07:00
Cameron Gutman b81392b818 Add an option to disable the automatic connection testing 2020-08-08 18:29:36 -07:00
Cameron Gutman ad08440023 Test for blocked ports when adding a PC fails 2020-08-08 18:11:25 -07:00
Cameron Gutman ec17623400 Test for blocked ports when a stream fails 2020-08-08 17:59:26 -07:00
Cameron Gutman 288eca7849 Display a friendly error when the Windows Firewall service is disabled 2020-08-08 17:18:25 -07:00
Cameron Gutman b5f202150e Update Windows AppVeyor builds to Qt 5.15 2020-08-02 23:08:12 -07:00
Cameron Gutman 539bf0cb30 Add support for hiding games
Fixes #255
2020-08-01 21:06:01 -07:00
Cameron Gutman 9385d62c89 Enable poll() in ENet for Linux/BSD 2020-07-27 00:04:25 -07:00
Cameron Gutman 897f916552 Update common-c with client connectivity test and select() replacement 2020-07-26 21:05:11 -07:00
Cameron Gutman 914cf6753e Update AppImage to FFmpeg 4.3.1 2020-07-14 20:53:52 -07:00
Cameron Gutman 392208057e Update moonlight-common-c to fix FEC validation assert on GFE 3.20.4 2020-07-14 20:52:49 -07:00
Cameron Gutman 8d2cbf806d Improve message for broken Intel drivers to indicate that users should update their driver 2020-07-12 15:26:38 -07:00
Cameron Gutman ab5025efbf Ignore mouse events outside the video region 2020-07-12 15:06:36 -07:00
Cameron Gutman 912e51d863 Synchronize the client and host cursor when starting absolute mode capture 2020-07-12 15:03:08 -07:00
Cameron Gutman d1c4ca5eae Use uniform_int_distribution for generating PINs 2020-07-12 13:19:26 -07:00
Cameron Gutman 16bb4a148e Only use libsoundio on Windows or macOS 2020-07-08 18:57:27 -05:00
Cameron Gutman d7071cb67f Improve verbiage around quit app and optimize game settings options 2020-06-23 22:17:40 -07:00
Cameron Gutman a13fb3d7c5 Update AppImage to FFmpeg 4.3 2020-06-20 17:03:52 -07:00
Cameron Gutman 85558904a4 Update SDL_GameControllerDB 2020-06-20 17:02:30 -07:00
Cameron Gutman 88ed72fdc1 Use regular VSync when enabled because adaptive VSync still tears 2020-06-20 14:44:21 -07:00
Cameron Gutman 586a93d7aa Use the new EGL renderer for VAAPI by default 2020-06-13 20:21:54 -07:00
Cameron Gutman a446699c6c Update moonlight-common-c to fix QoS-related connection issues 2020-06-12 22:00:24 -07:00
Cameron Gutman f1c459fd6c Fix leak of renderer when we fail to create a GL context 2020-06-08 20:39:12 -07:00
Cameron Gutman 752f0a988b Fix crash during key generation introduced by dcba5762c7 2020-06-08 20:16:42 -07:00
Cameron Gutman 719b266691 Fix build with OpenSSL versions prior to 1.1.0 2020-06-07 16:58:47 -07:00
Cameron Gutman dcba5762c7 Avoid using functions deprecated in OpenSSL 3.0 2020-06-07 16:26:19 -07:00
Cameron Gutman 0757717bea Address const-correctness issues in NvPairingManager 2020-06-07 15:15:33 -07:00
Cameron Gutman a9f762aa96 Fix macOS AppVeyor build 2020-06-07 14:14:06 -07:00
Cameron Gutman db45f46d9e Update AppImage to FFmpeg 4.2.3 2020-06-07 12:17:43 -07:00
Cameron Gutman f00653964e Batch absolute mouse motion like we do for relative motion 2020-05-31 13:34:50 -07:00
Cameron Gutman e0154f9314 Rebuild SDL for macOS
changeset a564e72e3b2d

Patches:
https://bugzilla-attachments.libsdl.org/attachment.cgi?id=4322 for bug #5111
https://bugzilla-attachments.libsdl.org/attachment.cgi?id=4356 for bug #5158
2020-05-31 12:01:50 -07:00
Cameron Gutman 4408a3a354 Delete cached box art when the host is deleted 2020-05-29 21:44:38 -07:00
Cameron Gutman 5abf5a157d Update metadata for Quadro streaming 2020-05-27 20:05:24 -07:00
Cameron Gutman d55d5f60a5 Update common-c 2020-05-26 18:22:39 -07:00
Cameron Gutman feacf2c359 Include stdexcept for std::runtime_error 2020-05-26 17:44:18 -07:00
Cameron Gutman 72ea1601e9 Use a better workaround for the GFE 3.20.3 high FPS bug 2020-05-25 18:57:42 -07:00
Cameron Gutman 02cfd8d978 Revert "Disable SOPS for streams over 60 FPS for GFE 3.20.3"
This reverts commit d6b5c5f63e.
2020-05-25 18:46:34 -07:00
Cameron Gutman 728377cba3 Set AV_PKT_FLAG_KEY for key frames 2020-05-25 18:31:19 -07:00
Cameron Gutman f2283b56b9 Version 2.1.0 2020-05-16 23:45:09 -07:00
Cameron Gutman b515f2a599 Update SDL_GameControllerDB 2020-05-16 22:45:29 -07:00
Cameron Gutman 4354b49496 Fix CLI video decoder options being reversed 2020-05-16 17:44:04 -07:00
Cameron Gutman 994312c212 Force GL to block after the current frame instead during the next frame 2020-05-16 16:25:13 -07:00
Cameron Gutman 5f25e0d4e2 Add limited support for frame pacing to EGLRenderer 2020-05-16 15:59:10 -07:00
Cameron Gutman 4bbe571f5f Fix build without FFmpeg and with older EGL 1.5 headers 2020-05-16 13:25:10 -07:00
Cameron Gutman c58d21375c EGL 1.4 doesn't have EGLAttrib either 2020-05-16 12:20:52 -07:00
Cameron Gutman ed128c558f Add support for EGLRenderer on EGL 1.4 2020-05-16 12:13:00 -07:00
Cameron Gutman 828932d95c Fix EGL detection on RPi 2020-05-16 11:10:45 -07:00
Cameron Gutman 42ced309d3 Restore the original GL attributes after EGLRenderer is destroyed 2020-05-15 20:22:11 -07:00
Cameron Gutman 1fcd306879 Fix EGLRenderer when SDL isn't built with X11 or Wayland backends 2020-05-15 20:01:22 -07:00
Cameron Gutman 26c9ad7f06 Use eglGetProcAddress() for all GLES 2.0 extensions 2020-05-15 19:39:41 -07:00
Cameron Gutman 4b7b01ce0a Fix EGL build 2020-05-15 17:54:45 -07:00
Cameron Gutman 6632154906 Remove some unnecessary headers and definitions 2020-05-15 16:59:29 -07:00
Cameron Gutman ca67c7ef43 Provide a main function for the compile test 2020-05-15 16:57:09 -07:00
Cameron Gutman c4039a929c Use a compile test for EGL support 2020-05-15 16:46:03 -07:00
Cameron Gutman a1b74e1220 Fix vaExportSurfaceHandle() detection with i965 VAAPI driver 2020-05-14 20:56:24 -07:00
Cameron Gutman 01f6188824 Add VAAPI_FORCE_DIRECT and VAAPI_FORCE_INDIRECT env vars to control rendering technique 2020-05-13 19:45:30 -07:00
Cameron Gutman 283f31a734 Test if vaExportSurfaceHandle() works before claiming EGL export is supported 2020-05-13 19:39:45 -07:00
Cameron Gutman b800ce9ebe Allow use of VA drivers without VAEntrypointVideoProc 2020-05-13 19:31:25 -07:00
Cameron Gutman eb9d54465c Don't use EGLRenderer if not built with SDL 2.0.10+ 2020-05-13 19:19:11 -07:00
Cameron Gutman eb9e1f81d4 Enable the EGLRenderer to use the render thread 2020-05-13 19:09:20 -07:00
Cameron Gutman ddfbd70b55 Remove Wayland performance warning message 2020-05-13 18:56:18 -07:00
Cameron Gutman 51e9ab83ad Send a null AVFrame to indicate end of stream to allow renderers to do render thread cleanup 2020-05-13 18:55:21 -07:00
Cameron Gutman 5ed7e03b2e Merge pull request #365 from xdbob/wayland_for_upstream
Introduce a new FFMPEG frontend renderer: EGLRenderer
2020-05-13 18:39:18 -07:00
Cameron Gutman 0cb8d5b12f Add the older dList DLLs for the 390 drivers to the blacklist
Fixes #386
2020-05-13 04:25:53 -07:00
Cameron Gutman b4548c1af2 Flush all window events after SDL_CreateRenderer() 2020-05-12 18:41:36 -07:00
Antoine Damhet 0a396f3112 Introduce a new FFMPEG frontend renderer: EGLRenderer
Right now this renderer works on X11 & Wayland with VAAPI as a backend.

Some rendering latency benchmarks on my `i7-10510U` (with
`intel-media-driver` 20.1.1 which cause a *huge* regression with the
SDL_Renderer):
|             | X11    | Wayland |
| Before      | 6.78ms | 22.50ms |
| EGLRenderer | 0.76ms | 00.77ms |

Signed-off-by: Antoine Damhet <antoine.damhet@lse.epita.fr>
2020-05-12 11:11:35 +02:00
Cameron Gutman 2aa18dc88f Add a bit of extra padding on the right for the scrollbar 2020-05-10 13:02:10 -07:00
Cameron Gutman 8d89983eeb Parent ScrollBars to their Flingables, not the StackView
This ensures they disappear when navigating to a new page
2020-05-10 12:53:27 -07:00
Cameron Gutman 573c470965 Ensure the title label doesn't get drawn over when the window is small 2020-05-10 12:38:56 -07:00
Cameron Gutman daa0c751e2 Fix settings layout spacing and centering 2020-05-10 12:30:15 -07:00
Cameron Gutman e1babefc80 Center toolbar text 2020-05-10 11:48:24 -07:00
Cameron Gutman ce99b0e162 Improve settings page behavior when the window is too small 2020-05-10 11:12:37 -07:00
Cameron Gutman 4c3a23b1bd Resize toolbar text 2020-05-09 23:02:09 -07:00
Cameron Gutman 12016af326 Display version number in toolbar on the settings page
Fixes #341
2020-05-09 22:20:39 -07:00
Cameron Gutman fc9871b075 Delay mouse capture until after SDL_RecreateWindow() has been called 2020-05-09 19:48:13 -07:00
Cameron Gutman 3cb3c1c6d8 Revert "Use the physical desktop size in pixels rather than the native resolution on macOS"
Let's wait until functionality is confirmed on a 5K iMac before doing this.

This reverts commit 8fe3474589.
2020-05-09 16:52:18 -07:00
Cameron Gutman 8fe3474589 Use the physical desktop size in pixels rather than the native resolution on macOS
It seems like some Macs (5K iMacs at least) don't have kDisplayModeNativeFlag set
2020-05-09 16:34:48 -07:00
Cameron Gutman dc3c565ec0 Move serialization and deserialization into NvApp class 2020-05-07 19:54:36 -07:00
Cameron Gutman 350c7d7081 Persist the IsAppCollectorGame attribute 2020-05-07 19:37:10 -07:00
Cameron Gutman 0428bc8fe3 Generate synthetic mouse button up if the mouse has left the window and the button is raised 2020-05-07 19:26:02 -07:00
Cameron Gutman 514a8575a2 Use the viewport size for computing the overlay position 2020-05-07 18:56:53 -07:00
Cameron Gutman fc11377552 Fix build on Qt 5.11 and earlier 2020-05-07 17:13:16 -07:00
Cameron Gutman fbaa70a2ae Enable the right stick to scroll the settings page. Fixes #220 2020-05-06 22:38:52 -07:00
Cameron Gutman f30c11ddf4 Properly fix SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH on macOS VTRenderer 2020-05-06 22:20:21 -07:00
Cameron Gutman 51c4ecc879 Revert "Partially unrevert 05e82c24 for macOS which still needs it"
This reverts commit 080421f2fb.
2020-05-06 21:41:57 -07:00
Cameron Gutman 080421f2fb Partially unrevert 05e82c24 for macOS which still needs it 2020-05-06 21:18:23 -07:00
Cameron Gutman 8cc61ca8b8 Use SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH to get click events on focus gain 2020-05-06 20:43:41 -07:00
Cameron Gutman 400754c5b3 Revert "Pass through focus-gain clicks to the host in absolute mouse mode"
This reverts commit 05e82c24f8.
2020-05-06 20:04:07 -07:00
Cameron Gutman 05e82c24f8 Pass through focus-gain clicks to the host in absolute mouse mode 2020-05-06 18:58:43 -07:00
Cameron Gutman 97c15c7876 Ensure the Info.plist is included for builds in the IDE
It is required for SDL_WINDOW_ALLOW_HIGHDPI to work
2020-05-04 20:25:19 -07:00
Cameron Gutman 36e7cc8e89 Use a smaller MaximumUncompressedMediaSize for unofficial builds to speed up compression a bit 2020-05-04 18:32:38 -07:00
Cameron Gutman ad2ce4de53 Update moonlight-common-c 2020-05-04 18:29:55 -07:00
Cameron Gutman 2a28f7c4d2 Use jom to parallelize command-line builds on Windows 2020-05-04 18:06:32 -07:00
Cameron Gutman 0cdbe080a6 Don't archive installers on Windows AppVeyor build
They interact poorly with installed official versions.
2020-05-04 17:51:57 -07:00
Cameron Gutman 96fe1a7da1 Revert "Allow side-by-side installation of nightly and release builds"
This reverts commit 33e814122e.
2020-05-04 17:51:57 -07:00
Cameron Gutman 4f73af2920 Revert "Fix AppVeyor build archiving"
This reverts commit 402e8c1897.
2020-05-04 17:51:57 -07:00
Cameron Gutman 7ca4e49bf5 Compile in parallel on macOS 2020-05-04 17:49:24 -07:00
Cameron Gutman dfa63297fc Fix incorrectly scaled output from the SDL renderer on macOS 2020-05-04 17:48:32 -07:00
Cameron Gutman 402e8c1897 Fix AppVeyor build archiving 2020-05-02 20:59:22 -07:00
Cameron Gutman 33e814122e Allow side-by-side installation of nightly and release builds 2020-05-02 17:56:55 -07:00
Cameron Gutman f28a4df5ee Restore the full QTBUG-80947 hack as it appears to still be required sometimes 2020-05-02 10:14:54 -07:00
Cameron Gutman 417aa2815c Add a friendly error message when no video traffic is received 2020-05-01 21:28:48 -07:00
Cameron Gutman 2fdabe37aa Raise the window before capturing in relative mode 2020-05-01 18:44:22 -07:00
Cameron Gutman d8270dfb6a Capture mouse by default on debug builds too 2020-05-01 18:43:54 -07:00
Cameron Gutman b75f662c41 Add the ability to rename PCs 2020-05-01 18:34:15 -07:00
Cameron Gutman 0d9d0845f5 Add --touchscreen-trackpad options 2020-04-30 21:10:53 -07:00
Cameron Gutman 5d66a1f298 Fix absolute mouse mode help text 2020-04-30 21:05:53 -07:00
Cameron Gutman 9bf52eb63a Improve relative touch deadzone behavior 2020-04-30 21:04:51 -07:00
Cameron Gutman 0c9d72a9a1 Restore the option for relative touch mode 2020-04-30 20:55:15 -07:00
Cameron Gutman c2c2bd2df6 Split input.cpp into smaller files 2020-04-30 20:22:43 -07:00
Cameron Gutman 78fc594d84 Move input code into a subfolder 2020-04-30 20:09:36 -07:00
Cameron Gutman 53b1e7c573 Update moonlight-common-c 2020-04-29 20:22:02 -07:00
Cameron Gutman c14404a7c1 Restore the QTBUG-80947 hack for support for direct connections without a router 2020-04-29 20:20:17 -07:00
Cameron Gutman 96e6750f9c Don't confine the cursor to the full-screen window when not capturing input 2020-04-28 20:37:00 -07:00
Cameron Gutman dbafd05a4e Store a pointer to the window inside the input handler 2020-04-28 20:24:27 -07:00
Cameron Gutman d7fd578cc3 Don't set MODIFIER_META when meta key is disabled 2020-04-28 20:06:30 -07:00
Cameron Gutman 0e8572e1db Version 2.0.0 2020-04-28 02:08:10 -07:00
Cameron Gutman 98a997bd8e Update AppImage to Qt 5.14.2 2020-04-27 17:09:52 -07:00
Cameron Gutman 6fbc95cc41 Update readme with links for new platforms 2020-04-26 21:31:29 -07:00
Cameron Gutman 1852f74e8b Add missing return statement 2020-04-26 20:42:01 -07:00
Cameron Gutman 55e3e16860 Try radeonsi if other VAAPI drivers fail 2020-04-26 20:18:46 -07:00
Cameron Gutman 7cf2a55b43 Allow radeonsi to direct render on XWayland 2020-04-26 20:13:00 -07:00
Cameron Gutman c41cbbd2da Allow the radeonsi VAAPI driver on XWayland 2020-04-26 20:06:53 -07:00
Cameron Gutman 7283bb046b Disable initial mouse capture on XWayland 2020-04-26 19:33:25 -07:00
Cameron Gutman dd2df6cbcf Default to starting in a non-maximized window 2020-04-26 17:57:28 -07:00
Cameron Gutman 01f1cac811 Update readme and metadata 2020-04-26 16:12:10 -07:00
Cameron Gutman aaa112c3f3 Don't use VAAPI drivers that lack VPP support
intel-media-va-driver (free) is one example of such a driver which
is apparently missing the shaders to perform colorspace conversion.
2020-04-26 15:38:05 -07:00
Cameron Gutman dc0fa9c64d Update AppImage's libva to 2.7.1 for compatibility with VA-API 1.7 drivers 2020-04-26 11:38:31 -07:00
Cameron Gutman f749b38aa2 Warn when starting a game with remote desktop mouse mode enabled 2020-04-25 23:50:12 -07:00
Cameron Gutman 43d79673e1 Rebuild SDL2 for Windows
changeset:   13787:a564e72e3b2d
2020-04-25 21:04:44 -07:00
Cameron Gutman fc841f572c Rebuild SDL2 for macOS
changeset: 13787:a564e72e3b2d

with https://bugzilla-attachments.libsdl.org/attachment.cgi?id=4322 for bug #5111
2020-04-25 19:53:00 -07:00
Cameron Gutman df9f117a08 Update SDL_GameControllerDB 2020-04-25 19:02:24 -07:00
Cameron Gutman bedc46a1be Rebuild SDL2 for macOS
changeset:   13787:a564e72e3b2d
2020-04-25 16:56:25 -07:00
Cameron Gutman a7c6095be5 Add special error text for the -1 launch error code 2020-04-25 16:05:39 -07:00
Cameron Gutman f2d5cf785e Don't cancel mouse capture on focus loss in absolute mode 2020-04-25 15:42:13 -07:00
Cameron Gutman f926ad9b5e Fix inverted capture-by-default setting 2020-04-25 15:41:45 -07:00
Cameron Gutman 68acf969f2 Move focus handling into the input code 2020-04-25 15:37:33 -07:00
Cameron Gutman 65d53e800b Confine the cursor to the window in full-screen exclusive mode 2020-04-25 13:15:14 -07:00
Cameron Gutman e44d8ac7e9 Only enable the absolute mouse checkbox if the platform has a window manager 2020-04-25 13:04:22 -07:00
Cameron Gutman d1823dd6e1 Capture the mouse by default always on release builds and in absolute mode for debug builds 2020-04-25 13:01:15 -07:00
Cameron Gutman 80bfd3b8e9 Change raw input checkbox to adjust absolute vs relative mouse mode 2020-04-25 13:00:39 -07:00
Cameron Gutman 07128cc7fe Allow keyboard input when the mouse is not captured 2020-04-24 21:35:38 -07:00
Cameron Gutman 0892f0b0bb Don't capture the cursor on a touch event 2020-04-24 21:26:59 -07:00
Cameron Gutman 8cf7f3ac08 Fix absolute mouse positioning on SDL renderer 2020-04-24 19:37:15 -07:00
Cameron Gutman ab2bb51879 Clamp mouse motion to the video region rather than dropping it 2020-04-24 17:35:35 -07:00
Cameron Gutman 8cb98b5365 Rewrite touchscreen support for direct input 2020-04-23 21:34:03 -07:00
Cameron Gutman 782c5f8a34 Fix parsing rare GFE status code of 0xFFFFFFFF 2020-04-23 18:34:14 -07:00
Cameron Gutman d6b5c5f63e Disable SOPS for streams over 60 FPS for GFE 3.20.3 2020-04-12 11:39:25 -07:00
Cameron Gutman ef6dfa6d91 Add basic support for absolute mouse input 2020-04-11 21:28:11 -07:00
Cameron Gutman 3840ee8ee7 Add MSVC ASan support 2020-04-10 17:21:17 -07:00
Cameron Gutman f47e40fa2a Blacklist more broken A-Volute DLLs 2020-04-10 17:20:21 -07:00
Cameron Gutman 49a4a61876 Enable QoS for ENet on Windows and fix disconnect delay on GFE 3.20.3 2020-04-09 18:02:49 -07:00
Khalid Jebbari 669c1a6f0d Add comment that describe kb shortcut of overlay (#358) 2020-04-06 18:31:02 -07:00
Cameron Gutman 15342190fa Make audio debug logs more readable 2020-04-04 12:53:03 -07:00
Cameron Gutman c98ef6e8a9 Display a friendly error when trying to stream over 4K with H.264 2020-04-04 12:47:44 -07:00
Cameron Gutman d36d5936da Don't include resolutions over 8K in settings list 2020-04-04 12:46:42 -07:00
Cameron Gutman 70de75ae3d Use EF instead of CS7 for DSCP on ENet traffic 2020-04-04 10:59:03 -07:00
Cameron Gutman ea62e33e51 Add 7.1 surround sound support to libsoundio audio renderer 2020-04-04 09:49:10 -07:00
Cameron Gutman 524e92c81a Add 7.1 surround sound support to SLAudio 2020-04-03 19:04:11 -07:00
Cameron Gutman d5a26b1d70 Enable auto-update for AppImages 2020-04-03 17:03:12 -07:00
Cameron Gutman cd7649a666 Add 7.1 surround sound support for SDL audio output 2020-04-03 00:12:52 -07:00
Cameron Gutman 847cc0a38a Migrate to the new audio configuration macros 2020-03-31 21:36:16 -07:00
Cameron Gutman 3588eb9bf8 Reduce retransmission delay on packet loss and enable QoS marking on ENet traffic 2020-03-29 15:49:52 -07:00
Cameron Gutman 296e22d3ca Remove the Wayland post-cleanup hack
It seems to do more harm than good on Fedora 32, causing deadlocks
when the stream is closed. The original bug it was trying to avoid
seems to have already been fixed.
2020-03-28 00:46:04 -07:00
Cameron Gutman 923e590da1 Delay the spinner on the stream segue to prevent animation glitching on Windows 2020-03-27 23:32:46 -07:00
Cameron Gutman e56329d05a Don't render with vaPutSurface() on XWayland 2020-03-27 19:11:03 -07:00
Cameron Gutman 2452e80e57 Add VDPAU driver path fallbacks for AppImage 2020-03-26 19:06:24 -07:00
Cameron Gutman b9019831a9 Fix failure to try the default VAAPI driver with the modified LIBVA_DRIVERS_PATH 2020-03-26 18:25:52 -07:00
Cameron Gutman b3b49b440e Add VAAPI driver path fallbacks for AppImage 2020-03-24 00:09:03 -07:00
Cameron Gutman cbedf0f74f Bundle a newer libva, FFmpeg, and Qt Wayland plugin into the AppImage 2020-03-23 23:57:38 -07:00
Cameron Gutman 6c980eba68 Fix build on Qt 5.15 Beta 2
Reverts most of 10dae7482c
2020-03-23 18:30:56 -07:00
Cameron Gutman e9f766904e Build AppImages on AppVeyor 2020-03-23 01:04:08 -07:00
Cameron Gutman 62d76c006d Move all builds to AppVeyor 2020-03-22 21:26:07 -07:00
Cameron Gutman 615b78a612 Update SDL_GameControllerDB to d222918bd6f786a35f9c42fd87921ca29493b785 2020-03-22 18:41:21 -07:00
Cameron Gutman aaf0340d6c Use 10 ms audio samples on low bandwidth connections 2020-03-21 01:04:41 -07:00
Cameron Gutman 93ea437760 Key repeat is handled server-side, so don't send repeat events 2020-03-20 23:56:44 -07:00
Cameron Gutman fe6a1244ed Fix a couple compiler warnings 2020-03-18 22:46:32 -07:00
Cameron Gutman 953858b0e7 Add workaround for Steam Link graphics bug. Fixes #254 2020-03-18 22:26:15 -07:00
Cameron Gutman f3da46833f Revert "Temporarily switch to gamecontrollerdb to fix build after DMCA takedown of SDL_GameControllerDB"
The DMCA takedown has been disputed and the repo is back up.

This reverts commit 6314676b9c.
2020-03-18 19:48:26 -07:00
Cameron Gutman ba2488b6e2 Try the iHD VA driver as a fallback to fix Comet Lake and later 2020-03-18 18:39:43 -07:00
Cameron Gutman 4e7e0d67e5 Add a workaround for Mesa Iris returning the wrong VA driver 2020-03-17 17:34:35 -07:00
Cameron Gutman faa16b207c Implement a more reliable mouse capture workaround for GNOME+Wayland 2020-03-14 00:33:53 -07:00
Cameron Gutman 2d9f62761c Don't pass through the super key to the host 2020-03-13 18:11:31 -07:00
Cameron Gutman 60689f531d Update to SDL 2.0.12 with USE_D3D9EX 2020-03-11 21:27:45 -07:00
Cameron Gutman 3f97692311 Update macOS to SDL 2.0.12 2020-03-11 17:51:46 -07:00
Cameron Gutman 81221336f4 Rec 601 seems to be a bit more accurate on macOS 2020-03-10 23:21:00 -07:00
Cameron Gutman ecfc758ce4 Attach colorspace data to CVPixelBuffer. Fixes #323 2020-03-10 22:21:09 -07:00
Cameron Gutman 2cb3a132c6 Fix false positives in SDL_GameControllerRumble() support detection 2020-03-07 17:00:38 -08:00
Cameron Gutman 519473e498 Enable rumble on Bluetooth PS4 controllers 2020-03-07 16:46:41 -08:00
Cameron Gutman 9b271d918a Use SDL_GameControllerSetPlayerIndex() to indicate player index 2020-03-03 20:15:35 -08:00
Cameron Gutman 5b4d874851 Avoid sending excessively large mDNS queries on networks with lots of mDNS traffic 2020-03-02 02:52:02 -08:00
Cameron Gutman 9dc1dbc002 Update qmdnsengine to address mDNS traffic amplification 2020-03-02 02:33:50 -08:00
Cameron Gutman 7ee323f0d5 Fix deprecation warning on macOS 2020-02-29 15:54:10 -08:00
Cameron Gutman 4bb6f711b9 Avoid using the QTBUG-80947 workaround on Qt 5.14.2 and later 2020-02-27 18:03:28 -08:00
Cameron Gutman 816cec8f5c Remove deprecated listener callbacks 2020-02-25 00:31:05 -08:00
Cameron Gutman 2394dfe88a Change errorCode to an int type 2020-02-24 23:03:34 -08:00
Cameron Gutman dfc0d2303b Fix incorrect #endif location 2020-02-24 20:55:07 -08:00
Cameron Gutman 598a48ec50 Remove the Wayland mouse capture hack that is not necessary on SDL 2.0.11 2020-02-24 20:33:33 -08:00
Cameron Gutman 9f41e98e3f Remove RPi hacks that are not necessary on SDL 2.0.11 2020-02-24 19:55:22 -08:00
Cameron Gutman 489891ff3c Fix build on Windows and macOS with Qt 5.13 and earlier 2020-02-24 18:17:23 -08:00
Cameron Gutman a44ed0b047 Allow initial destination position to be used as an offset with scaleSourceToDestinationSurface() 2020-02-24 18:01:30 -08:00
Cameron Gutman 1aaa97b91d Override SDL 2.0.12 default of mapping buttons to labels rather than position 2020-02-24 17:44:56 -08:00
Cameron Gutman 13d68e789f Fix Clazy warnings 2020-02-24 17:44:21 -08:00
Cameron Gutman 10dae7482c Fix build with Qt 5.15 2020-02-24 17:39:24 -08:00
Cameron Gutman 979de190dc Cap resolution options at 1080p on Steam Link and Raspberry Pi due to hardware limitations 2020-02-23 00:43:43 -08:00
Cameron Gutman 46bcbda972 MMAL is always full-screen 2020-02-23 00:25:01 -08:00
Cameron Gutman 43bdc353fb Fix 720p streaming on MMAL 2020-02-23 00:22:44 -08:00
Cameron Gutman 6314676b9c Temporarily switch to gamecontrollerdb to fix build after DMCA takedown of SDL_GameControllerDB 2020-02-22 19:20:52 -08:00
Cameron Gutman 9f77f3d968 Don't leave 0 byte files if saving the box art image failed and deal with those that may already exist. Fixes #346 2020-02-20 19:06:19 -08:00
Cameron Gutman f4733dbbe8 Fix unused parameter warning on Linux 2020-02-20 14:13:03 -08:00
Cameron Gutman 61fc0e4893 Don't allow Flickables to be dragged beyond bounds 2020-02-20 13:38:01 -08:00
Cameron Gutman 652ad86cad Update SDL_GameControllerDB to cc4b7f603698914fad9a172a5e47bfece93a45f6 2020-02-20 13:29:36 -08:00
Cameron Gutman 60f308bd76 Build dual binary bundles for Steam Link 2020-02-12 18:20:15 -08:00
Cameron Gutman b2113ff95b Raspberry Pi's full KMS driver is broken with MMAL, so just advise fake KMS 2020-02-09 12:52:11 -08:00
Cameron Gutman b8188a46a9 Display a friendly warning when running without a KMS driver 2020-02-09 12:40:07 -08:00
Cameron Gutman e790b0761e Add another RPi hack to fix mouse capture in full-screen in LXDE 2020-02-09 12:00:30 -08:00
Cameron Gutman fa3317f6cd Enable double buffering on SDL backends that support it 2020-02-09 11:54:09 -08:00
Cameron Gutman b080f7a81c Don't display browser links in non-GUI environment 2020-02-09 11:41:44 -08:00
Cameron Gutman 57a1c5eb76 Disable the window mode options for always full-screen renderers 2020-02-09 11:35:05 -08:00
Cameron Gutman 5b7e2521cc Ignore unbind and full-screen key combos on EGLFS 2020-02-09 10:20:41 -08:00
Cameron Gutman fced653c1c Add a hack to avoid PulseAudio on RPi 2020-02-08 23:35:42 -08:00
Cameron Gutman 9253e6ac5e Fix GLES library not being found on RPi when running from console 2020-02-08 22:34:07 -08:00
Cameron Gutman aff2ed22b9 Use EGLFS platform plugin if X and Wayland aren't detected 2020-02-08 21:37:17 -08:00
Cameron Gutman 5520a52379 Force full-screen mode on EGLFS 2020-02-08 21:31:04 -08:00
Cameron Gutman 505050e936 Fix high DPI check in 0437835b 2020-02-08 18:47:59 -08:00
Cameron Gutman 0437835bde Avoid enabling High DPI mode on EGLFS to fix font rendering 2020-02-08 18:11:33 -08:00
Cameron Gutman 77386f8dfc Reduce buffering for MMAL to avoid requiring 128 MB VRAM split 2020-02-08 17:56:30 -08:00
Cameron Gutman 529fdf0341 Add decoder options dictionary to prepareDecoderContext() 2020-02-08 17:47:26 -08:00
Cameron Gutman fa74700ad9 Fix build with new Steam Link SDK 2020-02-05 17:24:05 -08:00
Cameron Gutman caca491943 Add build script to generate AppImage 2020-02-01 15:46:53 -08:00
Cameron Gutman 4794f44a6d Charge decoders for time spent holding on to frames 2020-01-26 20:15:11 -08:00
Cameron Gutman f0119b1231 Add support for the out-of-tree Jetson FFmpeg NVMPI decoders
https://github.com/jocover/jetson-ffmpeg
2020-01-26 19:16:03 -08:00
Cameron Gutman 4c579aa826 Provide another frame if avcodec_receive_frame() returns EAGAIN 2020-01-26 15:36:22 -08:00
Cameron Gutman b9463b3c0e Allow NV12 and NV21 to be selected for non-hwaccel decoders using the SDL renderer 2020-01-26 15:02:29 -08:00
Cameron Gutman cede6ce8a9 Add H264_DECODER_HINT and HEVC_DECODER_HINT envvars to specify a decoder manually 2020-01-26 14:40:48 -08:00
Cameron Gutman 956e6e3638 Avoid slicing for hardware decoders that use SDL as the renderer 2020-01-26 14:13:42 -08:00
Cameron Gutman b282c7d815 Fix parsing CLI flags that accept values when passed before 'action' argument 2020-01-26 13:32:24 -08:00
Cameron Gutman 5b6142e2d9 Always create IdentityManager on the main thread 2020-01-25 19:34:37 -08:00
Cameron Gutman 58313ad8fc Allow default mouse polling interval to be overridden by setting MOUSE_POLLING_INTERVAL 2020-01-21 19:15:17 -08:00
Cameron Gutman 7aff148e9f Add --packet-size command-line option 2020-01-21 19:10:10 -08:00
Cameron Gutman ee5c61fb74 Centralize Discord invite links 2020-01-18 10:53:05 -08:00
Cameron Gutman 91be6c8028 Only hide Qt's mouse cursor on EGLFS 2020-01-15 18:23:02 -08:00
Cameron Gutman 2e0bd2ec28 Invoke avcodec_receive_frame() during decoder testing 2020-01-15 18:09:59 -08:00
Cameron Gutman a0151fbc04 Fix memory leak if 10-bit color is not supported 2020-01-15 17:56:11 -08:00
Cameron Gutman d853782fea Add support for the Meta/Super/Windows key on macOS and Linux 2020-01-15 17:54:57 -08:00
Cameron Gutman c6638a7154 Add support for 10-bit output in full-screen with DXVA2 2020-01-14 17:12:55 -08:00
Cameron Gutman 4abebe3aec Hide the Qt cursor when streaming 2020-01-11 02:06:08 -08:00
Cameron Gutman 5aed8f928a Add V4L2M2M support using SDL renderer
Note: This requires FFmpeg master to work, since it depends on:
https://github.com/FFmpeg/FFmpeg/commit/d61cf1b1ebc2477749d7d7825a072400ed24af9
2020-01-10 20:52:16 -08:00
Cameron Gutman afe6cfc383 Update build dependencies in README 2020-01-05 23:32:48 -08:00
Cameron Gutman 174983ce1e Update Windows builds to FFmpeg 4.2.1 with D3D11VA+DXVA2 enabled 2020-01-01 01:09:33 -06:00
Cameron Gutman 1313c7b3bf Enable HDR as an experimental option 2019-12-30 18:05:43 -06:00
Cameron Gutman bee622bcad Improve speed of initial PC status poll 2019-12-30 17:51:23 -06:00
Cameron Gutman 8cefdeae49 Update macOS builds to FFmpeg 4.2.1 2019-12-30 02:10:26 -06:00
Cameron Gutman 7cf70b9607 Clear Add PC textbox when closing the dialog 2019-12-29 20:13:45 -06:00
Cameron Gutman add4b582b5 Update issue template configuration 2019-12-28 21:02:14 -06:00
Cameron Gutman b419d21940 Only use the QTBUG-80947 hack on Qt 5.14 2019-12-21 13:54:09 -08:00
Cameron Gutman 227ff4e13a Version 1.2.1 (hotfix for Windows and macOS) 2019-12-21 13:01:44 -08:00
Cameron Gutman 8e6e70683e Add workaround for QTBUG-80947 2019-12-21 12:58:45 -08:00
Cameron Gutman 626f0aec6a Rebuild SDL 2.0.10 for macOS with https://bugzilla.libsdl.org/show_bug.cgi?id=4888 patch 2019-12-21 12:49:40 -08:00
Cameron Gutman 973d174a30 Version 1.2.0 (take 2) 2019-12-17 18:25:37 -08:00
Cameron Gutman 9f35690b95 Update DMG signing to support disambiguating identity shortnames 2019-12-17 18:10:39 -08:00
Cameron Gutman d961f2bc13 Switch to QElapsedTimer since QTime is deprecated for our usecase in Qt 5.14 2019-12-16 23:16:31 -08:00
Cameron Gutman 10e8277044 Version 1.2.0 2019-12-16 22:51:11 -08:00
Cameron Gutman b4c40d9b18 Update SDL_GameControllerDB submodule 2019-12-16 22:38:58 -08:00
Cameron Gutman e1603f0808 Explicitly use Rec 601 for VDPAU 2019-12-16 18:02:28 -08:00
Cameron Gutman d4c2350d63 Fix DXVA2 rendering with the wrong colorspace on AMD GPUs 2019-12-15 13:29:19 -08:00
Cameron Gutman 5e5470ae12 Specify video transfer matrix for SLVideo 2019-12-15 11:27:47 -08:00
Cameron Gutman 6230a99360 Fix colorspace conversion with SDL as frontend renderer 2019-12-14 17:17:29 -08:00
Cameron Gutman 801adb6af7 Add colorspace support to VAAPI renderer 2019-12-14 16:58:04 -08:00
Cameron Gutman 8b9b96f422 Only enable slicing when CPU decoding 2019-12-14 15:34:48 -08:00
Cameron Gutman 160684f23e Allow decoders to choose a desired colorspace 2019-12-14 15:25:56 -08:00
Cameron Gutman 88930a9de4 Optimize decoder capability checking 2019-12-14 15:20:44 -08:00
Cameron Gutman af6b8c9b88 Update common-c with colorspace configuration support 2019-12-14 14:40:02 -08:00
Cameron Gutman bf52d3189d Switch to Bionic build image on Travis CI 2019-12-14 13:25:57 -08:00
Cameron Gutman 5d872e8b5b Add auto update check to Steam Link 2019-12-13 20:21:35 -08:00
Cameron Gutman 4832d8007b Print joystick haptic capabilities to log 2019-12-13 18:43:35 -08:00
Cameron Gutman 879e084383 Enable Qt 5.14's new fractional DPI scaling 2019-12-12 20:36:23 -08:00
Cameron Gutman 1ae16bb657 Add source archival script 2019-12-09 18:27:51 -08:00
Cameron Gutman 2177bc68db Add git-archive-all.sh script from https://github.com/meitar/git-archive-all.sh 2019-12-09 18:27:51 -08:00
Cameron Gutman c8b887fe32 Use the new SDL_GameControllerRumble() API on SDL 2.0.9 to fix rumble on HIDAPI gamepads 2019-12-07 16:17:01 -08:00
Cameron Gutman 7205242f38 Improve VPN detection on Windows 2019-12-07 16:00:03 -08:00
Cameron Gutman be33b5b387 Update default window mode on macOS after upgrading 2019-12-07 13:27:47 -08:00
Cameron Gutman 66a123f4b9 Store binaries on the symbol server too 2019-12-03 19:14:19 -08:00
Cameron Gutman 76a4ee22b3 Update SDL_GameControllerDB submodule 2019-12-03 19:02:29 -08:00
Cameron Gutman 3a6bf4d20b Disable arbitrary audio duration for libsoundio until further testing is done 2019-12-03 19:00:43 -08:00
Cameron Gutman 09cf105cdc Block RTSS hooks due to user reported crashes 2019-12-03 18:31:18 -08:00
Cameron Gutman ce02e086a3 Add missing return when no interface address matches 2019-12-02 17:27:57 -08:00
Cameron Gutman e8d4313454 Fix build on Qt 5.10 and earlier 2019-12-02 17:18:29 -08:00
Cameron Gutman 49046f88cf Ignore unknown MTUs 2019-12-01 22:10:07 -08:00
Cameron Gutman 5e2f32e3eb Force remote streaming mode if connecting through a VPN 2019-12-01 21:50:36 -08:00
Cameron Gutman b4a1393bf6 Update common-c with PMTUD and low bitrate audio fixes 2019-12-01 19:45:15 -08:00
Cameron Gutman 0ccee9d806 Support arbitrary audio duration in libsoundio renderer 2019-12-01 19:43:22 -08:00
Cameron Gutman 5700272dc4 Improve low bandwidth audio performance for SDL and SLAudio and fix RTSP issues with broken PMTUD 2019-11-30 22:24:28 -06:00
Cameron Gutman 7e5a3925b3 Fix typo in channel mapping 2019-11-17 14:35:37 -08:00
Cameron Gutman 1febe32e73 Fix 5.1 channel mapping on Steam Link 2019-11-17 12:22:57 -08:00
Cameron Gutman 6059c982cf Fix auto-comment line breaks 2019-11-16 11:58:07 -08:00
Cameron Gutman de7b973239 Plumb presentation time from server into AVFrame.pts field 2019-11-11 18:03:47 -08:00
Cameron Gutman 741113a607 Add configuration for auto-comment bot 2019-11-09 15:04:28 -08:00
Cameron Gutman c20daa8867 Add compatibility checks for HEVC Main10 in VT backend 2019-11-05 18:36:43 -08:00
Cameron Gutman 5e57a7d5c0 Prevent SDL renderer from trying to render 10-bit output 2019-11-05 17:29:21 -08:00
Cameron Gutman 7c8d27700e Add 10-bit output support to VDPAU renderer 2019-11-05 17:09:44 -08:00
Cameron Gutman f8621be5ee Add an HEVC Main10 test frame 2019-11-05 17:08:25 -08:00
Cameron Gutman 8ed87e10b4 Change PC icon to be consistent with iOS and Android 2019-11-05 17:06:57 -08:00
Cameron Gutman ca26fa2dd0 Add basic HEVC Main10 support in DXVA2 renderer 2019-11-04 22:57:12 -08:00
Cameron Gutman 1669095fb1 Prevent double-clicks from triggering pairing twice. Fixes #286 2019-11-04 19:30:38 -08:00
Cameron Gutman 13eed48877 Update moonlight-common-c submodule 2019-11-02 21:49:00 -07:00
Cameron Gutman 07494e6eff Fix Linux build 2019-10-12 19:44:59 -07:00
Cameron Gutman 41b1d72825 Update moonlight-common-c submodule 2019-10-12 19:22:19 -07:00
Cameron Gutman 4d2965e74f Always install the VC redistributable 2019-09-30 00:11:37 -07:00
Cameron Gutman 12526bfca4 Version 1.1.1 2019-09-29 22:11:39 -07:00
Cameron Gutman 3e2c344140 Display the Moonlight icon in Discord Rich Presence info 2019-09-29 22:06:12 -07:00
Cameron Gutman 33730dd584 Display the update tooltip on launch if an update is available 2019-09-29 21:32:24 -07:00
Cameron Gutman 1cb03b1882 Add padding to app labels 2019-09-29 21:26:07 -07:00
Cameron Gutman 2f0a6db414 Add hacks for SDL+Mutter interaction bugs 2019-09-29 21:05:31 -07:00
Cameron Gutman a42328d971 Use VSWhere to locate Visual Studio and redistributables 2019-09-29 15:01:53 -07:00
Cameron Gutman 96ff51d598 Use SDL audio for platforms that libsoundio doesn't support 2019-09-22 12:03:53 -07:00
Cameron Gutman 7c3d3af681 Fix control stream connection error on multi-homed hosts 2019-09-14 14:08:38 -07:00
Cameron Gutman 6942bca5a7 Link to download page from download badge 2019-08-25 23:24:34 -07:00
Cameron Gutman 9eac9a190e Add Downloads badge 2019-08-25 23:20:55 -07:00
Cameron Gutman 40e4fbd9a6 Update common-c for parallel STUN requests 2019-08-20 19:05:54 -07:00
Cameron Gutman 7b6996ed80 Add a little help to the build scripts 2019-08-13 18:07:42 -07:00
Cameron Gutman ef2827a9d8 Update common-c for STUN fallback 2019-08-07 23:14:07 -07:00
Cameron Gutman dbf98ce3a6 Require keyframes even for software H.264 decoding 2019-08-07 22:38:31 -07:00
947 changed files with 56902 additions and 215938 deletions
+14 -4
View File
@@ -1,10 +1,12 @@
---
name: Bug report
about: Create a report to help us address issues in Moonlight
about: Follow the troubleshooting guide before reporting a bug
---
**READ ME FIRST!**
This issue tracker is not the right place to ask for troubleshooting help if you're not able to connect or stream at all. For those requests, please use the #pc-help channel on our Discord server where there are many more people who can help (or direct you back here if it looks like a Moonlight bug after all). https://discord.gg/MySTSdq
If you're here because something basic is not working (like gamepad input, video, or similar), it's probably something specific to your setup, so make sure you've gone through the Troubleshooting Guide first: https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting
If you still have trouble with basic functionality after following the guide, join our Discord server where there are many other volunteers who can help (or direct you back here if it looks like a Moonlight bug after all). https://moonlight-stream.org/discord
**Describe the bug**
A clear and concise description of what the bug is.
@@ -26,14 +28,22 @@ List the games you've tried that exhibit the issue. To see if the issue is game-
- If so, which settings have been changed?
- Does the problem still occur after reverting settings back to default?
**Gamepad-related issues (please complete if problem is gamepad-related)**
- Do you have any gamepads connected to your host PC directly?
- Does the problem still remain if you stream the desktop and use https://html5gamepad.com to test your gamepad?
- Instructions for streaming the desktop can be found here: https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide
**Client PC details (please complete the following information)**
- OS: [e.g. Windows 10 1809]
- Moonlight Version: [e.g. v0.9.0]
- GPU: [e.g. Intel HD Graphics 520]
- Linux package type (if applicable): [e.g. Flatpak]
**Server PC details (please complete the following information)**
- OS: [e.g. Windows 10 1809]
- GeForce Experience version: [e.g. 3.16.0.140]
- Nvidia GPU driver: [e.g. 417.35]
- Sunshine or GeForce Experience version: [e.g. Sunshine v0.21.0]
- GPU: [e.g. AMD Radeon RX 7900 XT]
- GPU driver: [e.g. 24.1.1]
**Moonlight Logs (please attach)**
- On Windows, `Moonlight-###.log` files can be found in `%TEMP%`. Simply type that into the File Explorer path field to navigate there.
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+4
View File
@@ -0,0 +1,4 @@
issuesOpened: >
If this is a question about Moonlight or you need help troubleshooting a streaming problem, please use the help channels on our [Discord server](https://moonlight-stream.org/discord) instead of GitHub issues. There are many more people available on Discord to help you and answer your questions.<br /><br />
This issue tracker should only be used for specific bugs or feature requests.<br /><br />
Thank you, and happy streaming!
+5 -1
View File
@@ -9,7 +9,11 @@
url = https://github.com/gabomdq/SDL_GameControllerDB.git
[submodule "soundio/libsoundio"]
path = soundio/libsoundio
url = https://github.com/andrewrk/libsoundio.git
url = https://github.com/cgutman/libsoundio.git
[submodule "h264bitstream/h264bitstream"]
path = h264bitstream/h264bitstream
url = https://github.com/aizvorski/h264bitstream.git
[submodule "libs"]
path = libs
url = https://github.com/cgutman/moonlight-qt-prebuilts.git
shallow = true
-71
View File
@@ -1,71 +0,0 @@
language: cpp
git:
depth: 1
matrix:
include:
- os: osx
osx_image: xcode10.2
compiler: clang
env: TRAVIS_TARGET=osx
addons:
homebrew:
packages:
- qt
- os: linux
sudo: required
dist: xenial
compiler: gcc
env: TRAVIS_TARGET=steamlink
addons:
apt:
packages:
- libc6:i386
- libstdc++6:i386
- os: linux
sudo: required
dist: xenial
compiler: gcc
env: TRAVIS_TARGET=linux
addons:
apt:
sources:
- sourceline: 'ppa:beineri/opt-qt597-xenial'
- sourceline: 'ppa:jonathonf/ffmpeg-4'
packages:
- qt59base
- qt59quickcontrols2
- qt59svg
- libesd0-dev
- libgl-dev
- libegl1-mesa-dev
- libxkbcommon-dev
- wayland-protocols
- libopus-dev
- libavcodec-dev
- libavutil-dev
- libva-dev
- libvdpau-dev
install:
- '[ "$TRAVIS_TARGET" != osx ] || brew link --force qt'
- if [[ "$TRAVIS_TARGET" = "osx" ]]; then nvm use node && npm install --global create-dmg; fi
- if [[ "$TRAVIS_TARGET" = "linux" ]]; then export SDL2_VER=2.0.9 && wget https://www.libsdl.org/release/SDL2-$SDL2_VER.tar.gz && tar -xvf SDL2-$SDL2_VER.tar.gz && cd SDL2-$SDL2_VER && ./configure && make -j$(nproc) && sudo make install && cd ..; fi
- if [[ "$TRAVIS_TARGET" = "linux" ]]; then export SDL2_TTF_VER=2.0.15 && wget https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-$SDL2_TTF_VER.tar.gz && tar -xvf SDL2_ttf-$SDL2_TTF_VER.tar.gz && cd SDL2_ttf-$SDL2_TTF_VER && ./configure && make -j$(nproc) && sudo make install && cd ..; fi
- if [[ "$TRAVIS_TARGET" = "steamlink" ]]; then git clone --depth=1 https://github.com/ValveSoftware/steamlink-sdk.git $HOME/steamlink-sdk; fi
before_script:
- '[ "$TRAVIS_TARGET" != "linux" ] || source /opt/qt59/bin/qt59-env.sh'
- '[ "$TRAVIS_TARGET" = "steamlink" ] || qmake -v'
- '[[ "$TRAVIS_TARGET" != linux || "$CXX" != clang++ ]] || export QMAKESPEC=linux-clang'
- '[[ "$TRAVIS_TARGET" != linux || "$CXX" != g++ ]] || export QMAKESPEC=linux-g++'
- '[ "$TRAVIS_TARGET" != osx ] || export QMAKESPEC=macx-clang'
- '[ "$TRAVIS_TARGET" != "steamlink" ] || export STEAMLINK_SDK_PATH=$HOME/steamlink-sdk'
script:
- '[ "$TRAVIS_TARGET" != "linux" ] || qmake moonlight-qt.pro -spec $QMAKESPEC'
- '[ "$TRAVIS_TARGET" != "linux" ] || make -j$(nproc) debug'
- '[ "$TRAVIS_TARGET" != "linux" ] || make -j$(nproc) release'
- '[ "$TRAVIS_TARGET" != "osx" ] || scripts/generate-dmg.sh Release'
- '[ "$TRAVIS_TARGET" != "steamlink" ] || scripts/build-steamlink-app.sh'
+4 -1
View File
@@ -12,8 +12,11 @@ contains(QT_ARCH, i386) {
contains(QT_ARCH, x86_64) {
LIBS += -L$$PWD/../libs/windows/lib/x64
}
contains(QT_ARCH, arm64) {
LIBS += -L$$PWD/../libs/windows/lib/arm64
}
LIBS += -lNktHookLib
LIBS += -ldetours
DEFINES += ANTIHOOKING_LIBRARY
SOURCES += antihookingprotection.cpp
HEADERS += antihookingprotection.h
+100 -33
View File
@@ -1,6 +1,9 @@
#include "antihookingprotection.h"
#include <NktHookLib.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <detours.h>
typedef HMODULE (WINAPI *LoadLibraryAFunc)(LPCSTR lpLibFileName);
typedef HMODULE (WINAPI *LoadLibraryWFunc)(LPCWSTR lpLibFileName);
@@ -12,25 +15,35 @@ class AntiHookingProtection
public:
static void enable()
{
#ifdef QT_DEBUG
s_HookManager.SetEnableDebugOutput(true);
#endif
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
HINSTANCE kernel32Handle = NktHookLibHelpers::GetModuleBaseAddress(L"kernel32.dll");
SIZE_T hookId;
s_RealLoadLibraryA = LoadLibraryA;
DetourAttach(&(PVOID&)s_RealLoadLibraryA, LoadLibraryAHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryA,
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryA"),
(LPVOID)AntiHookingProtection::LoadLibraryAHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryW,
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryW"),
(LPVOID)AntiHookingProtection::LoadLibraryWHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryExA,
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryExA"),
(LPVOID)AntiHookingProtection::LoadLibraryExAHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryExW,
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryExW"),
(LPVOID)AntiHookingProtection::LoadLibraryExWHook);
s_RealLoadLibraryW = LoadLibraryW;
DetourAttach(&(PVOID&)s_RealLoadLibraryW, LoadLibraryWHook);
s_RealLoadLibraryExA = LoadLibraryExA;
DetourAttach(&(PVOID&)s_RealLoadLibraryExA, LoadLibraryExAHook);
s_RealLoadLibraryExW = LoadLibraryExW;
DetourAttach(&(PVOID&)s_RealLoadLibraryExW, LoadLibraryExWHook);
DetourTransactionCommit();
}
static void disable()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)s_RealLoadLibraryA, LoadLibraryAHook);
DetourDetach(&(PVOID&)s_RealLoadLibraryW, LoadLibraryWHook);
DetourDetach(&(PVOID&)s_RealLoadLibraryExA, LoadLibraryExAHook);
DetourDetach(&(PVOID&)s_RealLoadLibraryExW, LoadLibraryExWHook);
DetourTransactionCommit();
}
private:
@@ -124,37 +137,79 @@ private:
return s_RealLoadLibraryExW(lpLibFileName, hFile, dwFlags);
}
static CNktHookLib s_HookManager;
static LoadLibraryAFunc s_RealLoadLibraryA;
static LoadLibraryWFunc s_RealLoadLibraryW;
static LoadLibraryExAFunc s_RealLoadLibraryExA;
static LoadLibraryExWFunc s_RealLoadLibraryExW;
static constexpr LPCWSTR k_BlacklistedDlls[] = {
// This DLL shipped with ASUS Sonic Radar 3 improperly handles
// D3D9 exclusive fullscreen in a way that causes CreateDeviceEx()
// to deadlock. https://github.com/moonlight-stream/moonlight-qt/issues/102
L"NahimicOSD.dll",
// These A-Volute DLLs shipped with various audio driver packages improperly handle
// D3D9 exclusive fullscreen in a way that causes CreateDeviceEx() to deadlock.
// https://github.com/moonlight-stream/moonlight-qt/issues/102
L"NahimicOSD.dll", // ASUS Sonic Radar 3
L"SSAudioOSD.dll", // SteelSeries headsets
L"SS2OSD.dll", // ASUS Sonic Studio 2
L"Nahimic2OSD.dll",
L"NahimicMSIOSD.dll",
L"nhAsusPhoebusOSD.dll", // ASUS Phoebus
// This DLL has been seen in several crash reports. Some Googling
// suggests it's highly unstable and causes issues in many games.
L"EZFRD32.dll",
L"EZFRD64.dll",
// These are the dList DLLs for Optimus hybrid graphics DDI.
// These are the older dList/AppInit DLLs for Optimus hybrid graphics DDI.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/display/hybrid-system-ddi
//
// We forcefully block them from loading because Optimus has a bug that
// deadlocks DXVA2 when we present with D3DPRESENT_DONOTWAIT. This will prevent
// Optimus from ever using the dGPU even if the user has requested it.
// https://github.com/moonlight-stream/moonlight-qt/issues/240
// https://github.com/moonlight-stream/moonlight-qt/issues/235
L"nvdlist.dll",
L"nvdlistx.dll",
// These seem to cause a crash in PresentEx() in full-screen exclusive mode.
// This block will prevent Optimus from ever using the dGPU even if the user has requested it.
// https://github.com/moonlight-stream/moonlight-qt/issues/386
//
// d3d9!CSwapChain::BltToHybridPrimary+0x200:
// 00007ffa`23f37e58 488b01 mov rax,qword ptr [rcx] ds:00000000`00000038=????????????????
// 00 0000004e`496ff4e0 00007ffa`23f39e2c d3d9!CSwapChain::BltToHybridPrimary+0x200
// 01 0000004e`496ff880 00007ffa`23ee39ce d3d9!CSwapChain::FlipToSurface+0x15c
// 02 0000004e`496ff900 00007ffa`23f4dd75 d3d9!CSwapChain::PresentMain+0x3e13e
// 03 0000004e`496ffab0 00007ffa`23f4dccd d3d9!CBaseDevice::PresentMain+0x9d
// 04 0000004e`496ffb00 00007ff7`8e31016f d3d9!CBaseDevice::PresentEx+0xbd
// 05 0000004e`496ffb50 00007ff7`8e30df1e Moonlight!DXVA2Renderer::renderFrame+0x61f [C:\moonlight-qt\app\streaming\video\ffmpeg-renderers\dxva2.cpp @ 1035]
// 06 0000004e`496ffd50 00007ff7`8e30e46a Moonlight!Pacer::renderFrame+0x3e [C:\moonlight-qt\app\streaming\video\ffmpeg-renderers\pacer\pacer.cpp @ 265]
// 07 (Inline Function) --------`-------- Moonlight!Pacer::renderLastFrameAndUnlock+0x197 [C:\moonlight-qt\app\streaming\video\ffmpeg-renderers\pacer\pacer.cpp @ 156]
// 08 0000004e`496ffda0 00007ffa`14476978 Moonlight!Pacer::renderThread+0x1ca [C:\moonlight-qt\app\streaming\video\ffmpeg-renderers\pacer\pacer.cpp @ 88]
// 09 0000004e`496ffde0 00007ffa`14476ee2 SDL2!SDL_RunThread+0x38 [C:\Users\camer\SDL\src\thread\SDL_thread.c @ 276]
// 0a 0000004e`496ffe10 00007ffa`2aae0e82 SDL2!RunThread+0x12 [C:\Users\camer\SDL\src\thread\windows\SDL_systhread.c @ 83]
// 0b 0000004e`496ffe40 00007ffa`2d627bd4 ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x42
// 0c 0000004e`496ffe70 00007ffa`2da4ce51 kernel32!BaseThreadInitThunk+0x14
// 0d 0000004e`496ffea0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
//
L"nvinit.dll",
L"nvinitx.dll",
// In some unknown circumstances, RTSS tries to hook in the middle of an instruction, leaving garbage
// code inside d3d9.dll that causes a crash when executed:
//
// 0:000> u
// d3d9!D3D9GetCurrentOwnershipMode+0x5d:
// 00007ff8`95b95861 9b wait
// 00007ff8`95b95862 a7 cmps dword ptr [rsi],dword ptr [rdi] <--- crash happens here
// 00007ff8`95b95863 ff ???
// 00007ff8`95b95864 bfe8ca8a00 mov edi,8ACAE8h
// 00007ff8`95b95869 00eb add bl,ch
// 00007ff8`95b9586b f1 ???
// 00007ff8`95b9586c b808000000 mov eax,8
// 00007ff8`95b95871 ebe6 jmp d3d9!D3D9GetCurrentOwnershipMode+0x55 (00007ff8`95b95859)
//
// Disassembling starting at the exact address of the attempted hook yields the intended jmp instruction
//
// 0:000> u d3d9!D3D9GetCurrentOwnershipMode+0x5c:
// 00007ff8`95b95860 e99ba7ffbf jmp 00007ff8`55b90000
//
// Since the RTSS OSD doesn't even work with DXVA2, we'll just block the hooks entirely.
L"RTSSHooks.dll",
L"RTSSHooks64.dll",
};
};
CNktHookLib AntiHookingProtection::s_HookManager;
LoadLibraryAFunc AntiHookingProtection::s_RealLoadLibraryA;
LoadLibraryWFunc AntiHookingProtection::s_RealLoadLibraryW;
LoadLibraryExAFunc AntiHookingProtection::s_RealLoadLibraryExA;
@@ -163,14 +218,26 @@ LoadLibraryExWFunc AntiHookingProtection::s_RealLoadLibraryExW;
AH_EXPORT void AntiHookingDummyImport() {}
extern "C"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (DetourIsHelperProcess()) {
return TRUE;
}
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DetourRestoreAfterWith();
AntiHookingProtection::enable();
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_PROCESS_DETACH:
// Ignore DLL_PROCESS_DETACH on process exit. No need to waste time
// unhooking everything if the whole process is being destroyed.
if (lpvReserved == NULL) {
AntiHookingProtection::disable();
}
break;
}
return TRUE;
+45 -29
View File
@@ -1,51 +1,64 @@
# Moonlight PC
[Moonlight PC](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built to run on Windows, Mac, and Linux. This client is the successor to [Moonlight Chrome](https://github.com/moonlight-stream/moonlight-chrome) for streaming on PC.
[Moonlight PC](https://moonlight-stream.org) is an open source PC client for NVIDIA GameStream and [Sunshine](https://github.com/LizardByte/Sunshine).
Moonlight also has mobile versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [iOS](https://github.com/moonlight-stream/moonlight-ios).
Moonlight also has mobile versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [iOS](https://github.com/moonlight-stream/moonlight-ios).
You can follow development on our [Discord server](https://discord.gg/6ERtzFY).
You can follow development on our [Discord server](https://moonlight-stream.org/discord) and help translate Moonlight into your language on [Weblate](https://hosted.weblate.org/projects/moonlight/moonlight-qt/).
[![Windows AppVeyor Status](https://ci.appveyor.com/api/projects/status/glj5cxqwy2w3bglv/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-qt/branch/master)
[![Mac and Linux Travis CI Status](https://travis-ci.org/moonlight-stream/moonlight-qt.svg?branch=master)](https://travis-ci.org/moonlight-stream/moonlight-qt)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/glj5cxqwy2w3bglv/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-qt/branch/master)
[![Downloads](https://img.shields.io/github/downloads/moonlight-stream/moonlight-qt/total)](https://github.com/moonlight-stream/moonlight-qt/releases)
[![Translation Status](https://hosted.weblate.org/widgets/moonlight/-/moonlight-qt/svg-badge.svg)](https://hosted.weblate.org/projects/moonlight/moonlight-qt/)
## Features
- Hardware accelerated video decoding on Windows, Mac, and Linux
- Supports streaming at up to 120 FPS (high refresh rate monitor recommended)
- Supports streaming at 720p, 1080p, 1440p, 4K, and the client PC's native screen resolution
- 5.1 surround sound audio
- HEVC support for better image quality at reduced bandwidth
- Keyboard and mouse support
- Gamepad support with force feedback for up to 4 players
- H.264, HEVC, and AV1 codec support (AV1 requires Sunshine and a supported host GPU)
- HDR streaming support
- 7.1 surround sound audio support
- 10-point multitouch support (Sunshine only)
- Gamepad support with force feedback and motion controls for up to 16 players
- Support for both pointer capture (for games) and direct mouse control (for remote desktop)
- Support for passing system-wide keyboard shortcuts like Alt+Tab to the host
## Downloads
- [Windows, macOS, and Steam Link](https://github.com/moonlight-stream/moonlight-qt/releases)
- [Snap (for Ubuntu-based Linux distros)](https://snapcraft.io/moonlight)
- [Flatpak (for other Linux distros)](https://flathub.org/apps/details/com.moonlight_stream.Moonlight)
- [AppImage](https://github.com/moonlight-stream/moonlight-qt/releases)
- [Raspberry Pi 4](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-Raspberry-Pi-4)
- [Generic ARM SBC packages for Debian](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-ARM%E2%80%90based-Single-Board-Computers) (not for Raspberry Pi)
- [Experimental RISC-V SBC packages for Debian](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-RISC%E2%80%90V-Single-Board-Computers)
- [NVIDIA Jetson and Nintendo Switch (Ubuntu L4T)](https://github.com/moonlight-stream/moonlight-docs/wiki/Installing-Moonlight-Qt-on-Linux4Tegra-(L4T)-Ubuntu)
#### Special Thanks
[![Hosted By: Cloudsmith](https://img.shields.io/badge/OSS%20hosting%20by-cloudsmith-blue?logo=cloudsmith&style=flat-square)](https://cloudsmith.com)
Hosting for Moonlight's Debian and L4T package repositories is graciously provided for free by [Cloudsmith](https://cloudsmith.com).
## Building
### General Build Requirements
* Qt 5.9 SDK or later
### Windows-specific Build Requirements
* Windows 7 or later
* [Visual Studio](https://visualstudio.microsoft.com/downloads/) 2017 (Community edition is fine)
* Select MSVC Desktop toolchain during Qt installation
* [DirectX SDK](https://www.microsoft.com/en-us/download/details.aspx?id=6812)
### Windows Build Requirements
* Qt 5.15 SDK or later. Qt 6 is also supported for x64 and ARM64 builds.
* [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) (Community edition is fine)
* Select **MSVC** option during Qt installation. MinGW is not supported.
* [7-Zip](https://www.7-zip.org/) (only if building installers for non-development PCs)
* [WiX Toolset](http://wixtoolset.org/releases/) v3.11 or later (only if building installers for non-development PCs)
### Mac-specific Build Requirements
* macOS Sierra (10.12) or later
* Xcode 10
### macOS Build Requirements
* Qt 6.4 SDK or later
* Xcode 13 or later
* [create-dmg](https://github.com/sindresorhus/create-dmg) (only if building DMGs for use on non-development Macs)
### Linux-specific Build Requirements
### Linux/Unix Build Requirements
* Qt 5.9 SDK or later. Qt 6 is also supported.
* GCC or Clang
* Install your distro equivalents of: `openssl-devel qt5-devel SDL2-devel ffmpeg-devel qt5-qtquickcontrols2-devel libva-devel libvdpau-devel opus-devel pulseaudio-libs-devel alsa-lib-devel SDL2_ttf-devel`
* FFmpeg 4.0 is required to build. If your distro doesn't package FFmpeg 4.0, you can build and install it from source on http://ffmpeg.org/
* Install the required packages:
* Debian/Ubuntu: `libegl1-mesa-dev libgl1-mesa-dev libopus-dev libqt5svg5-dev libsdl2-dev libsdl2-ttf-dev libssl-dev libavcodec-dev libavformat-dev libva-dev libvdpau-dev libxkbcommon-dev qtwayland5 qt5-qmake qtbase5-dev qtdeclarative5-dev qtquickcontrols2-5-dev wayland-protocols qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtquick-window2 qml-module-qtquick2`
* RedHat/Fedora: `openssl-devel SDL2-devel SDL2_ttf-devel ffmpeg-devel qt5-qtsvg-devel qt5-qtquickcontrols2-devel libva-devel libvdpau-devel opus-devel pulseaudio-libs-devel alsa-lib-devel`
* FFmpeg 4.0 or later is required to build. If your distro doesn't package FFmpeg 4.0 or later, you can build and install it from source on https://ffmpeg.org/
* Building the Vulkan HDR renderer requires a `libplacebo-dev`/`libplacebo-devel` version of at least v338.0 and FFmpeg 6.1 or later.
### Steam Link-specific Build Requirements
### Steam Link Build Requirements
* [Steam Link SDK](https://github.com/ValveSoftware/steamlink-sdk) cloned on your build system
* STEAMLINK_SDK_PATH environment variable set to the Steam Link SDK path
@@ -53,14 +66,17 @@ You can follow development on our [Discord server](https://discord.gg/6ERtzFY).
1. Install the latest Qt SDK (and optionally, the Qt Creator IDE) from https://www.qt.io/download
* You can install Qt via Homebrew on macOS, but you will need to use `brew install qt --with-debug` to be able to create debug builds of Moonlight.
* You may also use your Linux distro's package manager for the Qt SDK as long as the packages are Qt 5.9 or later.
* This step is not required for building on Steam Link, because the Steam Link SDK includes Qt 5.9.
* This step is not required for building on Steam Link, because the Steam Link SDK includes Qt 5.14.
2. Run `git submodule update --init --recursive` from within `moonlight-qt/`
3. Open the project in Qt Creator or build from qmake on the command line.
* To build a binary for use on non-development machines, use the scripts in the `scripts` folder.
* For Windows builds, use `scripts\generate-installers.bat`. Execute this script from the root of the repository within a Qt command prompt. Ensure WiX and 7-Zip binary directories are in your `%PATH%`.
* For Windows builds, use `scripts\build-arch.bat` and `scripts\generate-bundle.bat`. Execute these scripts from the root of the repository within a Qt command prompt. Ensure 7-Zip binary directory is on your `%PATH%`.
* For macOS builds, use `scripts/generate-dmg.sh`. Execute this script from the root of the repository and ensure Qt's `bin` folder is in your `$PATH`.
* For Steam Link builds, run `scripts/build-steamlink-app.sh` from the root of the repository.
* To build from the command line for development use, run `qmake moonlight-qt.pro` then `make debug` or `make release`
* To build from the command line for development use on macOS or Linux, run `qmake moonlight-qt.pro` then `make debug` or `make release`
* To create an embedded build for a single-purpose device, use `qmake "CONFIG+=embedded" moonlight-qt.pro` and build normally.
* This build will lack windowed mode, Discord/Help links, and other features that don't make sense on an embedded device.
* For platforms with poor GPU performance, add `"CONFIG+=gpuslow"` to prefer direct KMSDRM rendering over GL/Vulkan renderers. Direct KMSDRM rendering can use dedicated YUV/RGB conversion and scaling hardware rather than slower GPU shaders for these operations.
## Contribute
1. Fork us
+16 -2
View File
@@ -5,7 +5,7 @@
<key>CFBundleExecutable</key>
<string>Moonlight</string>
<key>CFBundleGetInfoString</key>
<string>Stream games from your NVIDIA GameStream-enabled PC</string>
<string>Stream games and other applications from another PC</string>
<key>CFBundleIconFile</key>
<string>moonlight</string>
<key>CFBundleIdentifier</key>
@@ -17,11 +17,25 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<string>10.14</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>GCSupportedGameControllers</key>
<array>
<dict>
<key>ProfileName</key>
<string>ExtendedGamepad</string>
</dict>
</array>
<key>GCSupportsControllerUserInteraction</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleVersion</key>
<string>VERSION</string>
<key>CFBundleShortVersionString</key>
+227 -58
View File
@@ -33,88 +33,127 @@ DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
win32 {
INCLUDEPATH += \
$$PWD/../libs/windows/include \
$$(DXSDK_DIR)/Include
contains(QT_ARCH, i386) {
LIBS += -L$$PWD/../libs/windows/lib/x86
LIBS += -L$$(DXSDK_DIR)/Lib/x86
INCLUDEPATH += $$PWD/../libs/windows/include/x86
}
contains(QT_ARCH, x86_64) {
LIBS += -L$$PWD/../libs/windows/lib/x64
LIBS += -L$$(DXSDK_DIR)/Lib/x64
INCLUDEPATH += $$PWD/../libs/windows/include/x64
}
contains(QT_ARCH, arm64) {
LIBS += -L$$PWD/../libs/windows/lib/arm64
INCLUDEPATH += $$PWD/../libs/windows/include/arm64
}
INCLUDEPATH += $$PWD/../libs/windows/include
LIBS += ws2_32.lib winmm.lib dxva2.lib ole32.lib gdi32.lib user32.lib d3d9.lib dwmapi.lib dbghelp.lib
# Work around a conflict with math.h inclusion between SDL and Qt 6
DEFINES += _USE_MATH_DEFINES
}
macx {
INCLUDEPATH += $$PWD/../libs/mac/include
INCLUDEPATH += $$PWD/../libs/mac/Frameworks/SDL2.framework/Versions/A/Headers
INCLUDEPATH += $$PWD/../libs/mac/Frameworks/SDL2_ttf.framework/Versions/A/Headers
LIBS += -L$$PWD/../libs/mac/lib -F$$PWD/../libs/mac/Frameworks
# QMake doesn't handle framework-style includes correctly on its own
QMAKE_CFLAGS += -F$$PWD/../libs/mac/Frameworks
QMAKE_CXXFLAGS += -F$$PWD/../libs/mac/Frameworks
QMAKE_OBJECTIVE_CFLAGS += -F$$PWD/../libs/mac/Frameworks
}
unix:!macx {
CONFIG += link_pkgconfig
PKGCONFIG += openssl sdl2 SDL2_ttf opus
# SLAudio is used on Steam Link
!config_SL {
CONFIG += soundio
}
!disable-ffmpeg {
packagesExist(libavcodec) {
PKGCONFIG += libavcodec libavutil
CONFIG += ffmpeg
soundio {
packagesExist(libpulse) {
PKGCONFIG += libpulse
}
packagesExist(alsa) {
PKGCONFIG += alsa
}
}
packagesExist(libavcodec) {
PKGCONFIG += libavcodec libavutil
CONFIG += ffmpeg
packagesExist(libva) {
packagesExist(libva-x11) {
CONFIG += libva-x11
!disable-libva {
packagesExist(libva) {
!disable-x11 {
packagesExist(libva-x11) {
CONFIG += libva-x11
}
}
!disable-wayland {
packagesExist(libva-wayland) {
CONFIG += libva-wayland
}
}
!disable-libdrm {
packagesExist(libva-drm) {
CONFIG += libva-drm
}
}
CONFIG += libva
}
}
packagesExist(libva-wayland) {
CONFIG += libva-wayland
!disable-libvdpau {
packagesExist(vdpau) {
CONFIG += libvdpau
}
}
packagesExist(libva-drm) {
CONFIG += libva-drm
!disable-mmal {
packagesExist(mmal) {
PKGCONFIG += mmal
CONFIG += mmal
}
}
!disable-libdrm {
packagesExist(libdrm) {
PKGCONFIG += libdrm
CONFIG += libdrm
}
}
!disable-cuda {
packagesExist(ffnvcodec) {
PKGCONFIG += ffnvcodec
CONFIG += cuda
}
}
!disable-libplacebo {
packagesExist(libplacebo) {
PKGCONFIG += libplacebo
CONFIG += libplacebo
}
}
CONFIG += libva
}
packagesExist(vdpau) {
CONFIG += libvdpau
!disable-wayland {
packagesExist(wayland-client) {
CONFIG += wayland
PKGCONFIG += wayland-client
}
}
packagesExist(mmal) {
PKGCONFIG += mmal
CONFIG += mmal
}
packagesExist(libdrm) {
PKGCONFIG += libdrm
CONFIG += libdrm
!disable-x11 {
packagesExist(x11) {
DEFINES += HAS_X11
PKGCONFIG += x11
}
}
}
}
win32 {
LIBS += -llibssl -llibcrypto -lSDL2 -lSDL2_ttf -lavcodec -lavutil -lopus -ld3dx9
LIBS += -llibssl -llibcrypto -lSDL2 -lSDL2_ttf -lavcodec -lavutil -lopus -ldxgi -ld3d11
CONFIG += ffmpeg
}
win32:!winrt {
CONFIG += soundio discord-rpc
}
macx {
LIBS += -lssl -lcrypto -lavcodec.58 -lavutil.56 -lopus -framework SDL2 -framework SDL2_ttf
LIBS += -lobjc -framework VideoToolbox -framework AVFoundation -framework CoreVideo -framework CoreGraphics -framework CoreMedia -framework AppKit
LIBS += -lssl -lcrypto -lavcodec.61 -lavutil.59 -lopus -framework SDL2 -framework SDL2_ttf
LIBS += -lobjc -framework VideoToolbox -framework AVFoundation -framework CoreVideo -framework CoreGraphics -framework CoreMedia -framework AppKit -framework Metal -framework QuartzCore
# For libsoundio
LIBS += -framework CoreAudio -framework AudioUnit
@@ -123,6 +162,9 @@ macx {
}
SOURCES += \
backend/nvaddress.cpp \
backend/nvapp.cpp \
cli/pair.cpp \
main.cpp \
backend/computerseeker.cpp \
backend/identitymanager.cpp \
@@ -133,10 +175,18 @@ SOURCES += \
backend/boxartmanager.cpp \
backend/richpresencemanager.cpp \
cli/commandlineparser.cpp \
cli/listapps.cpp \
cli/quitstream.cpp \
cli/startstream.cpp \
settings/compatfetcher.cpp \
settings/mappingfetcher.cpp \
settings/streamingpreferences.cpp \
streaming/input.cpp \
streaming/input/abstouch.cpp \
streaming/input/gamepad.cpp \
streaming/input/input.cpp \
streaming/input/keyboard.cpp \
streaming/input/mouse.cpp \
streaming/input/reltouch.cpp \
streaming/session.cpp \
streaming/audio/audio.cpp \
streaming/audio/renderers/sdlaud.cpp \
@@ -148,9 +198,15 @@ SOURCES += \
settings/mappingmanager.cpp \
gui/sdlgamepadkeynavigation.cpp \
streaming/video/overlaymanager.cpp \
backend/systemproperties.cpp
backend/systemproperties.cpp \
wm.cpp
HEADERS += \
backend/nvaddress.h \
backend/nvapp.h \
cli/pair.h \
settings/compatfetcher.h \
settings/mappingfetcher.h \
utils.h \
backend/computerseeker.h \
backend/identitymanager.h \
@@ -161,10 +217,11 @@ HEADERS += \
backend/boxartmanager.h \
backend/richpresencemanager.h \
cli/commandlineparser.h \
cli/listapps.h \
cli/quitstream.h \
cli/startstream.h \
settings/streamingpreferences.h \
streaming/input.h \
streaming/input/input.h \
streaming/session.h \
streaming/audio/renderers/renderer.h \
streaming/audio/renderers/sdl.h \
@@ -187,17 +244,15 @@ ffmpeg {
SOURCES += \
streaming/video/ffmpeg.cpp \
streaming/video/ffmpeg-renderers/sdlvid.cpp \
streaming/video/ffmpeg-renderers/cuda.cpp \
streaming/video/ffmpeg-renderers/pacer/pacer.cpp \
streaming/video/ffmpeg-renderers/pacer/nullthreadedvsyncsource.cpp
streaming/video/ffmpeg-renderers/swframemapper.cpp \
streaming/video/ffmpeg-renderers/pacer/pacer.cpp
HEADERS += \
streaming/video/ffmpeg.h \
streaming/video/ffmpeg-renderers/renderer.h \
streaming/video/ffmpeg-renderers/sdlvid.h \
streaming/video/ffmpeg-renderers/cuda.h \
streaming/video/ffmpeg-renderers/pacer/pacer.h \
streaming/video/ffmpeg-renderers/pacer/nullthreadedvsyncsource.h
streaming/video/ffmpeg-renderers/swframemapper.h \
streaming/video/ffmpeg-renderers/pacer/pacer.h
}
libva {
message(VAAPI renderer selected)
@@ -219,7 +274,7 @@ libva-wayland {
PKGCONFIG += libva-wayland
DEFINES += HAVE_LIBVA_WAYLAND
}
libva-wayland {
libva-drm {
message(VAAPI DRM support enabled)
PKGCONFIG += libva-drm
@@ -238,6 +293,18 @@ mmal {
DEFINES += HAVE_MMAL
SOURCES += streaming/video/ffmpeg-renderers/mmal.cpp
HEADERS += streaming/video/ffmpeg-renderers/mmal.h
# We suppress EGL usage when MMAL is available because MMAL has
# significantly better performance than EGL on the Pi. Setting
# this option allows EGL usage even if built with MMAL support.
#
# It is highly recommended to also build with 'gpuslow' to avoid
# EGL being preferred if direct DRM rendering is available.
allow-egl-with-mmal {
message(Allowing EGL usage with MMAL enabled)
DEFINES += ALLOW_EGL_WITH_MMAL
}
}
libdrm {
message(DRM renderer selected)
@@ -245,11 +312,50 @@ libdrm {
DEFINES += HAVE_DRM
SOURCES += streaming/video/ffmpeg-renderers/drm.cpp
HEADERS += streaming/video/ffmpeg-renderers/drm.h
linux {
message(Master hooks enabled)
SOURCES += masterhook.c masterhook_internal.c
LIBS += -ldl
}
}
cuda {
message(CUDA support enabled)
DEFINES += HAVE_CUDA
SOURCES += streaming/video/ffmpeg-renderers/cuda.cpp
HEADERS += streaming/video/ffmpeg-renderers/cuda.h
# ffnvcodec uses libdl in cuda_load_functions()/cuda_free_functions()
LIBS += -ldl
}
libplacebo {
message(Vulkan support enabled via libplacebo)
DEFINES += HAVE_LIBPLACEBO_VULKAN
SOURCES += \
streaming/video/ffmpeg-renderers/plvk.cpp \
streaming/video/ffmpeg-renderers/plvk_c.c
HEADERS += \
streaming/video/ffmpeg-renderers/plvk.h
}
config_EGL {
message(EGL renderer selected)
CONFIG += egl
DEFINES += HAVE_EGL
SOURCES += \
streaming/video/ffmpeg-renderers/eglvid.cpp \
streaming/video/ffmpeg-renderers/egl_extensions.cpp \
streaming/video/ffmpeg-renderers/eglimagefactory.cpp
HEADERS += \
streaming/video/ffmpeg-renderers/eglvid.h \
streaming/video/ffmpeg-renderers/eglimagefactory.h
}
config_SL {
message(Steam Link build configuration selected)
DEFINES += STEAM_LINK HAVE_SLVIDEO HAVE_SLAUDIO
DEFINES += EMBEDDED_BUILD STEAM_LINK HAVE_SLVIDEO HAVE_SLAUDIO
LIBS += -lSLVideo -lSLAudio
SOURCES += \
@@ -259,22 +365,28 @@ config_SL {
streaming/video/slvid.h \
streaming/audio/renderers/slaud.h
}
win32 {
HEADERS += streaming/video/ffmpeg-renderers/dxutil.h
}
win32:!winrt {
message(DXVA2 renderer selected)
message(DXVA2 and D3D11VA renderers selected)
SOURCES += \
streaming/video/ffmpeg-renderers/dxva2.cpp \
streaming/video/ffmpeg-renderers/d3d11va.cpp \
streaming/video/ffmpeg-renderers/pacer/dxvsyncsource.cpp
HEADERS += \
streaming/video/ffmpeg-renderers/dxva2.h \
streaming/video/ffmpeg-renderers/d3d11va.h \
streaming/video/ffmpeg-renderers/pacer/dxvsyncsource.h
}
macx {
message(VideoToolbox renderer selected)
SOURCES += \
streaming/video/ffmpeg-renderers/vt.mm
streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm \
streaming/video/ffmpeg-renderers/vt_metal.mm
HEADERS += \
streaming/video/ffmpeg-renderers/vt.h
@@ -292,11 +404,65 @@ discord-rpc {
LIBS += -ldiscord-rpc
DEFINES += HAVE_DISCORD
}
embedded {
message(Embedded build)
DEFINES += EMBEDDED_BUILD
}
glslow {
message(GL slow build)
DEFINES += GL_IS_SLOW
}
vkslow {
message(Vulkan slow build)
DEFINES += VULKAN_IS_SLOW
}
gpuslow {
message(GPU slow build)
DEFINES += GL_IS_SLOW VULKAN_IS_SLOW
}
wayland {
message(Wayland extensions enabled)
DEFINES += HAS_WAYLAND
SOURCES += streaming/video/ffmpeg-renderers/pacer/waylandvsyncsource.cpp
HEADERS += streaming/video/ffmpeg-renderers/pacer/waylandvsyncsource.h
}
RESOURCES += \
resources.qrc \
qml.qrc
TRANSLATIONS += \
languages/qml_zh_CN.ts \
languages/qml_de.ts \
languages/qml_fr.ts \
languages/qml_nb_NO.ts \
languages/qml_ru.ts \
languages/qml_es.ts \
languages/qml_ja.ts \
languages/qml_vi.ts \
languages/qml_th.ts \
languages/qml_ko.ts \
languages/qml_hu.ts \
languages/qml_nl.ts \
languages/qml_sv.ts \
languages/qml_tr.ts \
languages/qml_uk.ts \
languages/qml_zh_TW.ts \
languages/qml_el.ts \
languages/qml_hi.ts \
languages/qml_it.ts \
languages/qml_pt.ts \
languages/qml_pt_BR.ts \
languages/qml_pl.ts \
languages/qml_cs.ts \
languages/qml_he.ts \
languages/qml_ckb.ts
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
@@ -387,7 +553,10 @@ macx {
APP_BUNDLE_FRAMEWORKS.files = $$files(../libs/mac/Frameworks/*.framework, true) $$files(../libs/mac/lib/*.dylib, true)
APP_BUNDLE_FRAMEWORKS.path = Contents/Frameworks
QMAKE_BUNDLE_DATA += APP_BUNDLE_RESOURCES APP_BUNDLE_FRAMEWORKS
APP_BUNDLE_PLIST.files = $$OUT_PWD/Info.plist
APP_BUNDLE_PLIST.path = Contents
QMAKE_BUNDLE_DATA += APP_BUNDLE_RESOURCES APP_BUNDLE_FRAMEWORKS APP_BUNDLE_PLIST
QMAKE_RPATHDIR += @executable_path/../Frameworks
}
+115 -43
View File
@@ -6,17 +6,18 @@
#include <QJsonObject>
AutoUpdateChecker::AutoUpdateChecker(QObject *parent) :
QObject(parent),
m_Nam(this)
QObject(parent)
{
m_Nam = new QNetworkAccessManager(this);
// Never communicate over HTTP
m_Nam.setStrictTransportSecurityEnabled(true);
m_Nam->setStrictTransportSecurityEnabled(true);
// Allow HTTP redirects
m_Nam.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
m_Nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
connect(&m_Nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(handleUpdateCheckRequestFinished(QNetworkReply*)));
connect(m_Nam, &QNetworkAccessManager::finished,
this, &AutoUpdateChecker::handleUpdateCheckRequestFinished);
QString currentVersion(VERSION_STR);
qDebug() << "Current Moonlight version:" << currentVersion;
@@ -28,10 +29,29 @@ AutoUpdateChecker::AutoUpdateChecker(QObject *parent) :
void AutoUpdateChecker::start()
{
#if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN) // Only run update checker on platforms without auto-update
if (!m_Nam) {
Q_ASSERT(m_Nam);
return;
}
#if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN) || defined(STEAM_LINK) || defined(APP_IMAGE) // Only run update checker on platforms without auto-update
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 1) && !defined(QT_NO_BEARERMANAGEMENT)
// HACK: Set network accessibility to work around QTBUG-80947 (introduced in Qt 5.14.0 and fixed in Qt 5.15.1)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
m_Nam->setNetworkAccessible(QNetworkAccessManager::Accessible);
QT_WARNING_POP
#endif
// We'll get a callback when this is finished
QUrl url("https://moonlight-stream.org/updates/qt.json");
m_Nam.get(QNetworkRequest(url));
QNetworkRequest request(url);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true);
#else
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
#endif
m_Nam->get(request);
#endif
}
@@ -43,13 +63,64 @@ void AutoUpdateChecker::parseStringToVersionQuad(QString& string, QVector<int>&
}
}
QString AutoUpdateChecker::getPlatform()
{
#if defined(STEAM_LINK)
return QStringLiteral("steamlink");
#elif defined(APP_IMAGE)
return QStringLiteral("appimage");
#elif defined(Q_OS_DARWIN) && QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
// Qt 6 changed this from 'osx' to 'macos'. Use the old one
// to be consistent (and not require another entry in the manifest).
return QStringLiteral("osx");
#else
return QSysInfo::productType();
#endif
}
int AutoUpdateChecker::compareVersion(QVector<int>& version1, QVector<int>& version2) {
for (int i = 0;; i++) {
int v1Val = 0;
int v2Val = 0;
// Treat missing decimal places as 0
if (i < version1.count()) {
v1Val = version1[i];
}
if (i < version2.count()) {
v2Val = version2[i];
}
if (i >= version1.count() && i >= version2.count()) {
// Equal versions
return 0;
}
if (v1Val < v2Val) {
return -1;
}
else if (v1Val > v2Val) {
return 1;
}
}
}
void AutoUpdateChecker::handleUpdateCheckRequestFinished(QNetworkReply* reply)
{
Q_ASSERT(reply->isFinished());
// Delete the QNetworkAccessManager to free resources and
// prevent the bearer plugin from polling in the background.
m_Nam->deleteLater();
m_Nam = nullptr;
if (reply->error() == QNetworkReply::NoError) {
QTextStream stream(reply);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
stream.setEncoding(QStringConverter::Utf8);
#else
stream.setCodec("UTF-8");
#endif
// Read all data and queue the reply for deletion
QString jsonString = stream.readAll();
@@ -88,47 +159,48 @@ void AutoUpdateChecker::handleUpdateCheckRequestFinished(QNetworkReply* reply)
}
if (updateObj["arch"] == QSysInfo::buildCpuArchitecture() &&
updateObj["platform"] == QSysInfo::productType()) {
updateObj["platform"] == getPlatform()) {
// Check the kernel version minimum if one exists
if (updateObj.contains("kernel_version_at_least") && updateObj["kernel_version_at_least"].isString()) {
QVector<int> requiredVersionQuad;
QVector<int> actualVersionQuad;
QString requiredVersion = updateObj["kernel_version_at_least"].toString();
QString actualVersion = QSysInfo::kernelVersion();
parseStringToVersionQuad(requiredVersion, requiredVersionQuad);
parseStringToVersionQuad(actualVersion, actualVersionQuad);
if (compareVersion(actualVersionQuad, requiredVersionQuad) < 0) {
qDebug() << "Skipping manifest entry due to kernel version (" << actualVersion << "<" << requiredVersion << ")";
continue;
}
}
qDebug() << "Found update manifest match for current platform";
QString latestVersion = updateObj["version"].toString();
qDebug() << "Latest version of Moonlight for this platform is:" << latestVersion;
QVector<int> latestVersionQuad;
parseStringToVersionQuad(latestVersion, latestVersionQuad);
for (int i = 0;; i++) {
int latestVer = 0;
int currentVer = 0;
// Treat missing decimal places as 0
if (i < latestVersionQuad.count()) {
latestVer = latestVersionQuad[i];
}
if (i < m_CurrentVersionQuad.count()) {
currentVer = m_CurrentVersionQuad[i];
}
if (i >= latestVersionQuad.count() && i >= m_CurrentVersionQuad.count()) {
break;
}
if (currentVer < latestVer) {
qDebug() << "Update available";
emit onUpdateAvailable(updateObj["version"].toString(),
updateObj["browser_url"].toString());
return;
}
else if (currentVer > latestVer) {
qDebug() << "Update manifest version lower than current version";
return;
}
int res = compareVersion(m_CurrentVersionQuad, latestVersionQuad);
if (res < 0) {
// m_CurrentVersionQuad < latestVersionQuad
qDebug() << "Update available";
emit onUpdateAvailable(updateObj["version"].toString(),
updateObj["browser_url"].toString());
return;
}
else if (res > 0) {
qDebug() << "Update manifest version lower than current version";
return;
}
else {
qDebug() << "Update manifest version equal to current version";
return;
}
qDebug() << "Update manifest version equal to current version";
return;
}
}
else {
@@ -136,11 +208,11 @@ void AutoUpdateChecker::handleUpdateCheckRequestFinished(QNetworkReply* reply)
}
}
qWarning() << "No entry in update manifest found for current platform: "
<< QSysInfo::buildCpuArchitecture() << QSysInfo::productType();
qWarning() << "No entry in update manifest found for current platform:"
<< QSysInfo::buildCpuArchitecture() << getPlatform() << QSysInfo::kernelVersion();
}
else {
qWarning() << "Update checking failed with error: " << reply->error();
qWarning() << "Update checking failed with error:" << reply->error();
reply->deleteLater();
}
}
+5 -1
View File
@@ -20,6 +20,10 @@ private slots:
private:
void parseStringToVersionQuad(QString& string, QVector<int>& version);
int compareVersion(QVector<int>& version1, QVector<int>& version2);
QString getPlatform();
QVector<int> m_CurrentVersionQuad;
QNetworkAccessManager m_Nam;
QNetworkAccessManager* m_Nam;
};
+21 -7
View File
@@ -46,8 +46,8 @@ public:
m_Computer(computer),
m_App(app)
{
connect(this, SIGNAL(boxArtFetchCompleted(NvComputer*,NvApp,QUrl)),
boxArtManager, SLOT(handleBoxArtLoadComplete(NvComputer*,NvApp,QUrl)));
connect(this, &NetworkBoxArtLoadTask::boxArtFetchCompleted,
boxArtManager, &BoxArtManager::handleBoxArtLoadComplete);
}
signals:
@@ -71,10 +71,10 @@ private:
QUrl BoxArtManager::loadBoxArt(NvComputer* computer, NvApp& app)
{
// Try to open the cached file
QString cacheFilePath = getFilePathForBoxArt(computer, app.id);
if (QFile::exists(cacheFilePath)) {
return QUrl::fromLocalFile(cacheFilePath);
// Try to open the cached file if it exists and contains data
QFile cacheFile(getFilePathForBoxArt(computer, app.id));
if (cacheFile.exists() && cacheFile.size() > 0) {
return QUrl::fromLocalFile(cacheFile.fileName());
}
// If we get here, we need to fetch asynchronously.
@@ -87,6 +87,16 @@ QUrl BoxArtManager::loadBoxArt(NvComputer* computer, NvApp& app)
return QUrl("qrc:/res/no_app_image.png");
}
void BoxArtManager::deleteBoxArt(NvComputer* computer)
{
QDir dir(Path::getBoxArtCacheDir());
// Delete everything in this computer's box art directory
if (dir.cd(computer->uuid)) {
dir.removeRecursively();
}
}
void BoxArtManager::handleBoxArtLoadComplete(NvComputer* computer, NvApp app, QUrl image)
{
if (!image.isEmpty()) {
@@ -96,7 +106,7 @@ void BoxArtManager::handleBoxArtLoadComplete(NvComputer* computer, NvApp app, QU
QUrl BoxArtManager::loadBoxArtFromNetwork(NvComputer* computer, int appId)
{
NvHTTP http(computer->activeAddress, computer->serverCert);
NvHTTP http(computer);
QString cachePath = getFilePathForBoxArt(computer, appId);
QImage image;
@@ -109,6 +119,10 @@ QUrl BoxArtManager::loadBoxArtFromNetwork(NvComputer* computer, int appId)
if (image.save(cachePath)) {
return QUrl::fromLocalFile(cachePath);
}
else {
// A failed save() may leave a zero byte file. Make sure that's removed.
QFile(cachePath).remove();
}
}
return QUrl();
+4
View File
@@ -18,6 +18,10 @@ public:
QUrl
loadBoxArt(NvComputer* computer, NvApp& app);
static
void
deleteBoxArt(NvComputer* computer);
signals:
void
boxArtLoadComplete(NvComputer* computer, NvApp app, QUrl image);
+306 -81
View File
@@ -1,6 +1,7 @@
#include "computermanager.h"
#include "boxartmanager.h"
#include "nvhttp.h"
#include "settings/streamingpreferences.h"
#include "nvpairingmanager.h"
#include <Limelight.h>
#include <QtEndian>
@@ -9,7 +10,10 @@
#include <QThreadPool>
#include <QCoreApplication>
#include <random>
#define SER_HOSTS "hosts"
#define SER_HOSTS_BACKUP "hostsbackup"
class PcMonitorThread : public QThread
{
@@ -26,22 +30,22 @@ public:
}
private:
bool tryPollComputer(QString address, bool& changed)
bool tryPollComputer(NvAddress address, bool& changed)
{
NvHTTP http(address, m_Computer->serverCert);
NvHTTP http(address, 0, m_Computer->serverCert);
QString serverInfo;
try {
serverInfo = http.getServerInfo(NvHTTP::NvLogLevel::NVLL_NONE);
serverInfo = http.getServerInfo(NvHTTP::NvLogLevel::NVLL_NONE, true);
} catch (...) {
return false;
}
NvComputer newState(address, serverInfo, QSslCertificate());
NvComputer newState(http, serverInfo);
// Ensure the machine that responded is the one we intended to contact
if (m_Computer->uuid != newState.uuid) {
qInfo() << "Found unexpected PC " << newState.name << " looking for " << m_Computer->name;
qInfo() << "Found unexpected PC" << newState.name << "looking for" << m_Computer->name;
return false;
}
@@ -51,9 +55,7 @@ private:
bool updateAppList(bool& changed)
{
Q_ASSERT(m_Computer->activeAddress != nullptr);
NvHTTP http(m_Computer->activeAddress, m_Computer->serverCert);
NvHTTP http(m_Computer);
QVector<NvApp> appList;
@@ -67,12 +69,7 @@ private:
}
QWriteLocker lock(&m_Computer->lock);
if (m_Computer->appList != appList) {
m_Computer->appList = appList;
m_Computer->sortAppList();
changed = true;
}
changed = m_Computer->updateAppList(appList);
return true;
}
@@ -84,7 +81,7 @@ private:
bool stateChanged = false;
bool online = false;
bool wasOnline = m_Computer->state == NvComputer::CS_ONLINE;
for (int i = 0; i < TRIES_BEFORE_OFFLINING && !online; i++) {
for (int i = 0; i < (wasOnline ? TRIES_BEFORE_OFFLINING : 1) && !online; i++) {
for (auto& address : m_Computer->uniqueAddresses()) {
if (isInterruptionRequested()) {
return;
@@ -92,7 +89,7 @@ private:
if (tryPollComputer(address, stateChanged)) {
if (!wasOnline) {
qInfo() << m_Computer->name << "is now online at" << m_Computer->activeAddress;
qInfo() << m_Computer->name << "is now online at" << m_Computer->activeAddress.toString();
}
online = true;
break;
@@ -147,32 +144,65 @@ private:
NvComputer* m_Computer;
};
ComputerManager::ComputerManager(QObject *parent)
: QObject(parent),
ComputerManager::ComputerManager(StreamingPreferences* prefs)
: m_Prefs(prefs),
m_PollingRef(0),
m_MdnsBrowser(nullptr)
m_MdnsBrowser(nullptr),
m_CompatFetcher(nullptr),
m_NeedsDelayedFlush(false)
{
QSettings settings;
// If there's a hosts backup copy, we must have failed to commit
// a previous update before exiting. Restore the backup now.
int hosts = settings.beginReadArray(SER_HOSTS_BACKUP);
if (hosts == 0) {
// If there's no host backup, read from the primary location.
settings.endArray();
hosts = settings.beginReadArray(SER_HOSTS);
}
// Inflate our hosts from QSettings
int hosts = settings.beginReadArray(SER_HOSTS);
for (int i = 0; i < hosts; i++) {
settings.setArrayIndex(i);
NvComputer* computer = new NvComputer(settings);
m_KnownHosts[computer->uuid] = computer;
m_LastSerializedHosts[computer->uuid] = *computer;
}
settings.endArray();
// Fetch latest compatibility data asynchronously
m_CompatFetcher.start();
// Start the delayed flush thread to handle saveHosts() calls
m_DelayedFlushThread = new DelayedFlushThread(this);
m_DelayedFlushThread->start();
// To quit in a timely manner, we must block additional requests
// after we receive the aboutToQuit() signal. This is neccessary
// because NvHTTP uses aboutToQuit() to abort requests in progres
// after we receive the aboutToQuit() signal. This is necessary
// because NvHTTP uses aboutToQuit() to abort requests in progress
// while quitting, however this is a one time signal - additional
// requests would not be aborted and block termination.
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(handleAboutToQuit()));
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &ComputerManager::handleAboutToQuit);
}
ComputerManager::~ComputerManager()
{
// Stop the delayed flush thread before acquiring the lock in write mode
// to avoid deadlocking with a flush that needs the lock in read mode.
{
// Wake the delayed flush thread
m_DelayedFlushThread->requestInterruption();
m_DelayedFlushCondition.wakeOne();
// Wait for it to terminate (and finish any pending flush)
m_DelayedFlushThread->wait();
delete m_DelayedFlushThread;
// Delayed flushes should have completed by now
Q_ASSERT(!m_NeedsDelayedFlush);
}
QWriteLocker lock(&m_Lock);
// Delete machines that haven't been resolved yet
@@ -202,18 +232,80 @@ ComputerManager::~ComputerManager()
}
}
void DelayedFlushThread::run() {
for (;;) {
// Wait for a delayed flush request or an interruption
{
QMutexLocker locker(&m_ComputerManager->m_DelayedFlushMutex);
while (!QThread::currentThread()->isInterruptionRequested() && !m_ComputerManager->m_NeedsDelayedFlush) {
m_ComputerManager->m_DelayedFlushCondition.wait(&m_ComputerManager->m_DelayedFlushMutex);
}
// Bail without flushing if we woke up for an interruption alone.
// If we have both an interruption and a flush request, do the flush.
if (!m_ComputerManager->m_NeedsDelayedFlush) {
Q_ASSERT(QThread::currentThread()->isInterruptionRequested());
break;
}
// Reset the delayed flush flag to ensure any racing saveHosts() call will set it again
m_ComputerManager->m_NeedsDelayedFlush = false;
// Update the last serialized hosts map under the delayed flush mutex
m_ComputerManager->m_LastSerializedHosts.clear();
for (const NvComputer* computer : m_ComputerManager->m_KnownHosts) {
// Copy the current state of the NvComputer to allow us to check later if we need
// to serialize it again when attribute updates occur.
QReadLocker computerLock(&computer->lock);
m_ComputerManager->m_LastSerializedHosts[computer->uuid] = *computer;
}
}
// Perform the flush
{
QSettings settings;
// First, write to the backup location
settings.beginWriteArray(SER_HOSTS_BACKUP);
{
QReadLocker lock(&m_ComputerManager->m_Lock);
int i = 0;
for (const NvComputer* computer : m_ComputerManager->m_KnownHosts) {
settings.setArrayIndex(i++);
computer->serialize(settings, false);
}
}
settings.endArray();
// Next, write to the primary location
settings.remove(SER_HOSTS);
settings.beginWriteArray(SER_HOSTS);
{
QReadLocker lock(&m_ComputerManager->m_Lock);
int i = 0;
for (const NvComputer* computer : m_ComputerManager->m_KnownHosts) {
settings.setArrayIndex(i++);
computer->serialize(settings, true);
}
}
settings.endArray();
// Finally, delete the backup copy
settings.remove(SER_HOSTS_BACKUP);
}
}
}
void ComputerManager::saveHosts()
{
QSettings settings;
QReadLocker lock(&m_Lock);
Q_ASSERT(m_DelayedFlushThread != nullptr && m_DelayedFlushThread->isRunning());
settings.remove(SER_HOSTS);
settings.beginWriteArray(SER_HOSTS);
for (int i = 0; i < m_KnownHosts.count(); i++) {
settings.setArrayIndex(i);
m_KnownHosts.value(m_KnownHosts.keys()[i])->serialize(settings);
}
settings.endArray();
// Punt to a worker thread because QSettings on macOS can take ages (> 500 ms)
// to persist our host list to disk (especially when a host has a bunch of apps).
QMutexLocker locker(&m_DelayedFlushMutex);
m_NeedsDelayedFlush = true;
m_DelayedFlushCondition.wakeOne();
}
QHostAddress ComputerManager::getBestGlobalAddressV6(QVector<QHostAddress> &addresses)
@@ -260,16 +352,15 @@ void ComputerManager::startPolling()
return;
}
StreamingPreferences prefs;
if (prefs.enableMdns) {
if (m_Prefs->enableMdns) {
// Start an MDNS query for GameStream hosts
m_MdnsBrowser = new QMdnsEngine::Browser(&m_MdnsServer, "_nvstream._tcp.local.", &m_MdnsCache);
m_MdnsServer.reset(new QMdnsEngine::Server());
m_MdnsBrowser = new QMdnsEngine::Browser(m_MdnsServer.data(), "_nvstream._tcp.local.");
connect(m_MdnsBrowser, &QMdnsEngine::Browser::serviceAdded,
this, [this](const QMdnsEngine::Service& service) {
qInfo() << "Discovered mDNS host:" << service.hostname();
MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(&m_MdnsServer, service);
MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(m_MdnsServer, service);
connect(pendingComputer, &MdnsPendingComputer::resolvedHost,
this, &ComputerManager::handleMdnsServiceResolved);
m_PendingResolution.append(pendingComputer);
@@ -305,8 +396,8 @@ void ComputerManager::startPollingComputer(NvComputer* computer)
if (!pollingEntry->isActive()) {
PcMonitorThread* thread = new PcMonitorThread(computer);
connect(thread, SIGNAL(computerStateChanged(NvComputer*)),
this, SLOT(handleComputerStateChanged(NvComputer*)));
connect(thread, &PcMonitorThread::computerStateChanged,
this, &ComputerManager::handleComputerStateChanged);
pollingEntry->setActiveThread(thread);
thread->start();
}
@@ -325,7 +416,7 @@ void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
// address may not be reachable (if the user hasn't installed the IPv6 helper yet
// or if this host lacks outbound IPv6 capability). We want to add IPv6 even if
// it's not currently reachable.
addNewHost(address.toString(), true, v6Global);
addNewHost(NvAddress(address, computer->port()), true, NvAddress(v6Global, computer->port()));
added = true;
break;
}
@@ -339,8 +430,7 @@ void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
if (address.isInSubnet(QHostAddress("fe80::"), 10) ||
address.isInSubnet(QHostAddress("fec0::"), 10) ||
address.isInSubnet(QHostAddress("fc00::"), 7)) {
addNewHost(address.toString(), true, v6Global);
added = true;
addNewHost(NvAddress(address, computer->port()), true, NvAddress(v6Global, computer->port()));
break;
}
}
@@ -351,6 +441,19 @@ void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
computer->deleteLater();
}
void ComputerManager::saveHost(NvComputer *computer)
{
// If no serializable properties changed, don't bother saving hosts
QMutexLocker lock(&m_DelayedFlushMutex);
QReadLocker computerLock(&computer->lock);
if (!m_LastSerializedHosts.value(computer->uuid).isEqualSerialized(*computer)) {
// Queue a request for a delayed flush to QSettings outside of the lock
computerLock.unlock();
lock.unlock();
saveHosts();
}
}
void ComputerManager::handleComputerStateChanged(NvComputer* computer)
{
emit computerStateChanged(computer);
@@ -360,15 +463,20 @@ void ComputerManager::handleComputerStateChanged(NvComputer* computer)
emit quitAppCompleted(QVariant());
}
// Save updated hosts to QSettings
saveHosts();
// Save updates to this host
saveHost(computer);
}
QVector<NvComputer*> ComputerManager::getComputers()
{
QReadLocker lock(&m_Lock);
return QVector<NvComputer*>::fromList(m_KnownHosts.values());
// Return a sorted host list
auto hosts = QVector<NvComputer*>::fromList(m_KnownHosts.values());
std::stable_sort(hosts.begin(), hosts.end(), [](const NvComputer* host1, const NvComputer* host2) {
return host1->name.toLower() < host2->name.toLower();
});
return hosts;
}
class DeferredHostDeletionTask : public QRunnable
@@ -392,12 +500,15 @@ public:
m_ComputerManager->m_KnownHosts.remove(m_Computer->uuid);
}
// Persist the new host list
// Persist the new host list with this computer deleted
m_ComputerManager->saveHosts();
// Delete the polling entry first. This will stop all polling threads too.
delete pollingEntry;
// Delete cached box art
BoxArtManager::deleteBoxArt(m_Computer);
// Finally, delete the computer itself. This must be done
// last because the polling thread might be using it.
delete m_Computer;
@@ -415,9 +526,28 @@ void ComputerManager::deleteHost(NvComputer* computer)
QThreadPool::globalInstance()->start(new DeferredHostDeletionTask(this, computer));
}
void ComputerManager::renameHost(NvComputer* computer, QString name)
{
{
QWriteLocker lock(&computer->lock);
computer->name = name;
computer->hasCustomName = true;
}
// Notify the UI of the state change
handleComputerStateChanged(computer);
}
void ComputerManager::clientSideAttributeUpdated(NvComputer* computer)
{
// Notify the UI of the state change
handleComputerStateChanged(computer);
}
void ComputerManager::handleAboutToQuit()
{
QWriteLocker lock(&m_Lock);
QReadLocker lock(&m_Lock);
// Interrupt polling threads immediately, so they
// avoid making additional requests while quitting
@@ -432,7 +562,8 @@ class PendingPairingTask : public QObject, public QRunnable
public:
PendingPairingTask(ComputerManager* computerManager, NvComputer* computer, QString pin)
: m_Computer(computer),
: m_ComputerManager(computerManager),
m_Computer(computer),
m_Pin(pin)
{
connect(this, &PendingPairingTask::pairingCompleted,
@@ -445,32 +576,41 @@ signals:
private:
void run()
{
NvPairingManager pairingManager(m_Computer->activeAddress);
NvPairingManager pairingManager(m_Computer);
try {
NvPairingManager::PairState result = pairingManager.pair(m_Computer->appVersion, m_Pin, m_Computer->serverCert);
switch (result)
{
case NvPairingManager::PairState::PIN_WRONG:
emit pairingCompleted(m_Computer, "The PIN from the PC didn't match. Please try again.");
emit pairingCompleted(m_Computer, tr("The PIN from the PC didn't match. Please try again."));
break;
case NvPairingManager::PairState::FAILED:
emit pairingCompleted(m_Computer, "Pairing failed. Please try again.");
if (m_Computer->currentGameId != 0) {
emit pairingCompleted(m_Computer, tr("You cannot pair while a previous session is still running on the host PC. Quit any running games or reboot the host PC, then try pairing again."));
}
else {
emit pairingCompleted(m_Computer, tr("Pairing failed. Please try again."));
}
break;
case NvPairingManager::PairState::ALREADY_IN_PROGRESS:
emit pairingCompleted(m_Computer, "Another pairing attempt is already in progress.");
emit pairingCompleted(m_Computer, tr("Another pairing attempt is already in progress."));
break;
case NvPairingManager::PairState::PAIRED:
// Persist the newly pinned server certificate for this host
m_ComputerManager->saveHost(m_Computer);
emit pairingCompleted(m_Computer, nullptr);
break;
}
} catch (const GfeHttpResponseException& e) {
emit pairingCompleted(m_Computer, "GeForce Experience returned error: " + e.toQString());
emit pairingCompleted(m_Computer, tr("GeForce Experience returned error: %1").arg(e.toQString()));
} catch (const QtNetworkReplyException& e) {
emit pairingCompleted(m_Computer, e.toQString());
}
}
ComputerManager* m_ComputerManager;
NvComputer* m_Computer;
QString m_Pin;
};
@@ -501,7 +641,7 @@ signals:
private:
void run()
{
NvHTTP http(m_Computer->activeAddress, m_Computer->serverCert);
NvHTTP http(m_Computer);
try {
if (m_Computer->currentGameId != 0) {
@@ -514,8 +654,8 @@ private:
}
if (e.getStatusCode() == 599) {
// 599 is a special code we make a custom message for
emit quitAppFailed("The running game wasn't started by this PC. "
"You must quit the game on the host PC manually or use the device that originally started the game.");
emit quitAppFailed(tr("The running game wasn't started by this PC. "
"You must quit the game on the host PC manually or use the device that originally started the game."));
}
else {
emit quitAppFailed(e.toQString());
@@ -557,9 +697,10 @@ void ComputerManager::stopPollingAsync()
m_PendingResolution.removeFirst();
}
// Delete the browser to stop discovery
// Delete the browser and server to stop discovery and refresh polling
delete m_MdnsBrowser;
m_MdnsBrowser = nullptr;
m_MdnsServer.reset();
// Interrupt all threads, but don't wait for them to terminate
for (ComputerPollingEntry* entry : m_PollEntries) {
@@ -567,32 +708,58 @@ void ComputerManager::stopPollingAsync()
}
}
void ComputerManager::addNewHostManually(QString address)
{
QUrl url = QUrl::fromUserInput("moonlight://" + address);
if (url.isValid() && !url.host().isEmpty() && url.scheme() == "moonlight") {
// If there wasn't a port specified, use the default
addNewHost(NvAddress(url.host(), url.port(DEFAULT_HTTP_PORT)), false);
}
else {
emit computerAddCompleted(false, false);
}
}
class PendingAddTask : public QObject, public QRunnable
{
Q_OBJECT
public:
PendingAddTask(ComputerManager* computerManager, QString address, QHostAddress mdnsIpv6Address, bool mdns)
PendingAddTask(ComputerManager* computerManager, NvAddress address, NvAddress mdnsIpv6Address, bool mdns)
: m_ComputerManager(computerManager),
m_Address(address),
m_MdnsIpv6Address(mdnsIpv6Address),
m_Mdns(mdns)
m_Mdns(mdns),
m_AboutToQuit(false)
{
connect(this, &PendingAddTask::computerAddCompleted,
computerManager, &ComputerManager::computerAddCompleted);
connect(this, &PendingAddTask::computerStateChanged,
computerManager, &ComputerManager::handleComputerStateChanged);
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
this, &PendingAddTask::handleAboutToQuit);
}
signals:
void computerAddCompleted(QVariant success);
void computerAddCompleted(QVariant success, QVariant detectedPortBlocking);
void computerStateChanged(NvComputer* computer);
private:
void handleAboutToQuit()
{
m_AboutToQuit = true;
}
QString fetchServerInfo(NvHTTP& http)
{
QString serverInfo;
// Do nothing if we're quitting
if (m_AboutToQuit) {
return QString();
}
try {
// There's a race condition between GameStream servers reporting presence over
// mDNS and the HTTPS server being ready to respond to our queries. To work
@@ -615,7 +782,19 @@ private:
return serverInfo;
} catch (...) {
if (!m_Mdns) {
emit computerAddCompleted(false);
unsigned int portTestResult;
if (m_ComputerManager->m_Prefs->detectNetworkBlocking) {
// We failed to connect to the specified PC. Let's test to make sure this network
// isn't blocking Moonlight, so we can tell the user about it.
portTestResult = LiTestClientConnectivity("qt.conntest.moonlight-stream.org", 443,
ML_PORT_FLAG_TCP_47984 | ML_PORT_FLAG_TCP_47989);
}
else {
portTestResult = 0;
}
emit computerAddCompleted(false, portTestResult != 0 && portTestResult != ML_TEST_RESULT_INCONCLUSIVE);
}
return QString();
}
@@ -623,15 +802,15 @@ private:
void run()
{
NvHTTP http(m_Address, QSslCertificate());
NvHTTP http(m_Address, 0, QSslCertificate());
qInfo() << "Processing new PC at" << m_Address << "from" << (m_Mdns ? "mDNS" : "user") << m_MdnsIpv6Address;
qInfo() << "Processing new PC at" << m_Address.toString() << "from" << (m_Mdns ? "mDNS" : "user") << "with IPv6 address" << m_MdnsIpv6Address.toString();
// Perform initial serverinfo fetch over HTTP since we don't know which cert to use
QString serverInfo = fetchServerInfo(http);
if (serverInfo.isEmpty() && !m_MdnsIpv6Address.isNull()) {
// Retry using the global IPv6 address if the IPv4 or link-local IPv6 address fails
http.setAddress(m_MdnsIpv6Address.toString());
http.setAddress(m_MdnsIpv6Address);
serverInfo = fetchServerInfo(http);
}
if (serverInfo.isEmpty()) {
@@ -639,7 +818,7 @@ private:
}
// Create initial newComputer using HTTP serverinfo with no pinned cert
NvComputer* newComputer = new NvComputer(http.address(), serverInfo, QSslCertificate());
NvComputer* newComputer = new NvComputer(http, serverInfo);
// Check if we have a record of this host UUID to pull the pinned cert
NvComputer* existingComputer;
@@ -653,13 +832,14 @@ private:
// Fetch serverinfo again over HTTPS with the pinned cert
if (existingComputer != nullptr) {
Q_ASSERT(http.httpsPort() != 0);
serverInfo = fetchServerInfo(http);
if (serverInfo.isEmpty()) {
return;
}
// Update the polled computer with the HTTPS information
NvComputer httpsComputer(http.address(), serverInfo, QSslCertificate());
NvComputer httpsComputer(http, serverInfo);
newComputer->update(httpsComputer);
}
@@ -673,11 +853,11 @@ private:
}
// Get the WAN IP address using STUN if we're on mDNS over IPv4
if (QHostAddress(newComputer->localAddress).protocol() == QAbstractSocket::IPv4Protocol) {
if (QHostAddress(newComputer->localAddress.address()).protocol() == QAbstractSocket::IPv4Protocol) {
quint32 addr;
int err = LiFindExternalAddressIP4("stun.moonlight-stream.org", 3478, &addr);
if (err == 0) {
newComputer->remoteAddress = QHostAddress(qFromBigEndian(addr)).toString();
newComputer->setRemoteAddress(QHostAddress(qFromBigEndian(addr)));
}
else {
qWarning() << "STUN failed to get WAN address:" << err;
@@ -685,34 +865,55 @@ private:
}
if (!m_MdnsIpv6Address.isNull()) {
Q_ASSERT(m_MdnsIpv6Address.protocol() == QAbstractSocket::IPv6Protocol);
newComputer->ipv6Address = m_MdnsIpv6Address.toString();
Q_ASSERT(QHostAddress(m_MdnsIpv6Address.address()).protocol() == QAbstractSocket::IPv6Protocol);
newComputer->ipv6Address = m_MdnsIpv6Address;
}
}
else {
newComputer->manualAddress = m_Address;
}
QHostAddress hostAddress(m_Address.address());
bool addressIsSiteLocalV4 =
hostAddress.isInSubnet(QHostAddress("10.0.0.0"), 8) ||
hostAddress.isInSubnet(QHostAddress("172.16.0.0"), 12) ||
hostAddress.isInSubnet(QHostAddress("192.168.0.0"), 16);
{
// Check if this PC already exists
QWriteLocker lock(&m_ComputerManager->m_Lock);
// Check if this PC already exists using opportunistic read lock
m_ComputerManager->m_Lock.lockForRead();
NvComputer* existingComputer = m_ComputerManager->m_KnownHosts.value(newComputer->uuid);
// If it doesn't already exist, convert to a write lock in preparation for updating.
//
// NB: ComputerManager's lock protects the host map itself, not the elements inside.
// Those are protected by their individual locks. Since we only mutate the map itself
// when the PC doesn't exist, we need the lock in write-mode for that case only.
if (existingComputer == nullptr) {
m_ComputerManager->m_Lock.unlock();
m_ComputerManager->m_Lock.lockForWrite();
// Since we had to unlock to lock for write, someone could have raced and added
// this PC before us. We have to check again whether it already exists.
existingComputer = m_ComputerManager->m_KnownHosts.value(newComputer->uuid);
}
if (existingComputer != nullptr) {
// Fold it into the existing PC
bool changed = existingComputer->update(*newComputer);
delete newComputer;
// Drop the lock before notifying
lock.unlock();
m_ComputerManager->m_Lock.unlock();
// For non-mDNS clients, let them know it succeeded
if (!m_Mdns) {
emit computerAddCompleted(true);
emit computerAddCompleted(true, false);
}
// Tell our client if something changed
if (changed) {
qInfo() << existingComputer->name << "is now at" << existingComputer->activeAddress;
qInfo() << existingComputer->name << "is now at" << existingComputer->activeAddress.toString();
emit computerStateChanged(existingComputer);
}
}
@@ -724,11 +925,24 @@ private:
m_ComputerManager->startPollingComputer(newComputer);
// Drop the lock before notifying
lock.unlock();
m_ComputerManager->m_Lock.unlock();
// If this wasn't added via mDNS but it is a RFC 1918 IPv4 address and not a VPN,
// go ahead and do the STUN request now to populate an external address.
if (!m_Mdns && addressIsSiteLocalV4 && newComputer->getActiveAddressReachability() != NvComputer::RI_VPN) {
quint32 addr;
int err = LiFindExternalAddressIP4("stun.moonlight-stream.org", 3478, &addr);
if (err == 0) {
newComputer->setRemoteAddress(QHostAddress(qFromBigEndian(addr)));
}
else {
qWarning() << "STUN failed to get WAN address:" << err;
}
}
// For non-mDNS clients, let them know it succeeded
if (!m_Mdns) {
emit computerAddCompleted(true);
emit computerAddCompleted(true, false);
}
// Tell our client about this new PC
@@ -738,12 +952,13 @@ private:
}
ComputerManager* m_ComputerManager;
QString m_Address;
QHostAddress m_MdnsIpv6Address;
NvAddress m_Address;
NvAddress m_MdnsIpv6Address;
bool m_Mdns;
bool m_AboutToQuit;
};
void ComputerManager::addNewHost(QString address, bool mdns, QHostAddress mdnsIpv6Address)
void ComputerManager::addNewHost(NvAddress address, bool mdns, NvAddress mdnsIpv6Address)
{
// Punt to a worker thread to avoid stalling the
// UI while waiting for serverinfo query to complete
@@ -751,4 +966,14 @@ void ComputerManager::addNewHost(QString address, bool mdns, QHostAddress mdnsIp
QThreadPool::globalInstance()->start(addTask);
}
// TODO: Use QRandomGenerator when we drop Qt 5.9 support
QString ComputerManager::generatePinString()
{
std::uniform_int_distribution<int> dist(0, 9999);
std::random_device rd;
std::mt19937 engine(rd());
return QString::asprintf("%04u", dist(engine));
}
#include "computermanager.moc"
+89 -15
View File
@@ -1,7 +1,8 @@
#pragma once
#include "nvcomputer.h"
#include "nvpairingmanager.h"
#include "settings/streamingpreferences.h"
#include "settings/compatfetcher.h"
#include <qmdnsengine/server.h>
#include <qmdnsengine/cache.h>
@@ -14,16 +15,38 @@
#include <QSettings>
#include <QRunnable>
#include <QTimer>
#include <QMutex>
#include <QWaitCondition>
class ComputerManager;
class DelayedFlushThread : public QThread
{
Q_OBJECT
public:
DelayedFlushThread(ComputerManager* cm)
: m_ComputerManager(cm)
{
setObjectName("CM Delayed Flush Thread");
}
void run();
private:
ComputerManager* m_ComputerManager;
};
class MdnsPendingComputer : public QObject
{
Q_OBJECT
public:
explicit MdnsPendingComputer(QMdnsEngine::Server* server,
explicit MdnsPendingComputer(const QSharedPointer<QMdnsEngine::Server> server,
const QMdnsEngine::Service& service)
: m_Hostname(service.hostname()),
m_Server(server),
m_Port(service.port()),
m_ServerWeak(server),
m_Resolver(nullptr)
{
// Start resolving
@@ -40,13 +63,24 @@ public:
return m_Hostname;
}
uint16_t port()
{
return m_Port;
}
private slots:
void handleResolvedTimeout()
{
if (m_Addresses.isEmpty()) {
// Try again
qInfo() << "Resolving" << hostname() << "timed out. Retrying...";
resolve();
if (m_Retries-- > 0) {
// Try again
qInfo() << "Resolving" << hostname() << "timed out. Retrying...";
resolve();
}
else {
qWarning() << "Giving up on resolving" << hostname() << "after repeated failures";
cleanup();
}
}
else {
Q_ASSERT(!m_Addresses.isEmpty());
@@ -64,19 +98,41 @@ signals:
void resolvedHost(MdnsPendingComputer*,QVector<QHostAddress>&);
private:
void cleanup()
{
// Delete our resolver, so we're guaranteed that nothing is referencing m_Server.
delete m_Resolver;
m_Resolver = nullptr;
// Now delete our strong reference that we held on behalf of m_Resolver.
// The server may be destroyed after we make this call.
m_Server.reset();
}
void resolve()
{
delete m_Resolver;
m_Resolver = new QMdnsEngine::Resolver(m_Server, m_Hostname);
// Clean up any existing resolver object and server references
cleanup();
// Re-acquire a strong reference if the server still exists.
m_Server = m_ServerWeak.toStrongRef();
if (!m_Server) {
return;
}
m_Resolver = new QMdnsEngine::Resolver(m_Server.data(), m_Hostname);
connect(m_Resolver, &QMdnsEngine::Resolver::resolved,
this, &MdnsPendingComputer::handleResolvedAddress);
QTimer::singleShot(2000, this, SLOT(handleResolvedTimeout()));
QTimer::singleShot(2000, this, &MdnsPendingComputer::handleResolvedTimeout);
}
QByteArray m_Hostname;
QMdnsEngine::Server* m_Server;
uint16_t m_Port;
QWeakPointer<QMdnsEngine::Server> m_ServerWeak;
QSharedPointer<QMdnsEngine::Server> m_Server;
QMdnsEngine::Resolver* m_Resolver;
QVector<QHostAddress> m_Addresses;
int m_Retries = 10;
};
class ComputerPollingEntry
@@ -158,9 +214,11 @@ class ComputerManager : public QObject
friend class DeferredHostDeletionTask;
friend class PendingAddTask;
friend class PendingPairingTask;
friend class DelayedFlushThread;
public:
explicit ComputerManager(QObject *parent = nullptr);
explicit ComputerManager(StreamingPreferences* prefs);
virtual ~ComputerManager();
@@ -168,7 +226,11 @@ public:
Q_INVOKABLE void stopPollingAsync();
Q_INVOKABLE void addNewHost(QString address, bool mdns, QHostAddress mdnsIpv6Address = QHostAddress());
Q_INVOKABLE void addNewHostManually(QString address);
void addNewHost(NvAddress address, bool mdns, NvAddress mdnsIpv6Address = NvAddress());
QString generatePinString();
void pairHost(NvComputer* computer, QString pin);
@@ -179,12 +241,16 @@ public:
// computer is deleted inside this call
void deleteHost(NvComputer* computer);
void renameHost(NvComputer* computer, QString name);
void clientSideAttributeUpdated(NvComputer* computer);
signals:
void computerStateChanged(NvComputer* computer);
void pairingCompleted(NvComputer* computer, QString error);
void computerAddCompleted(QVariant success);
void computerAddCompleted(QVariant success, QVariant detectedPortBlocking);
void quitAppCompleted(QVariant error);
@@ -198,16 +264,24 @@ private slots:
private:
void saveHosts();
void saveHost(NvComputer* computer);
QHostAddress getBestGlobalAddressV6(QVector<QHostAddress>& addresses);
void startPollingComputer(NvComputer* computer);
StreamingPreferences* m_Prefs;
int m_PollingRef;
QReadWriteLock m_Lock;
QMap<QString, NvComputer*> m_KnownHosts;
QMap<QString, ComputerPollingEntry*> m_PollEntries;
QMdnsEngine::Server m_MdnsServer;
QHash<QString, NvComputer> m_LastSerializedHosts; // Protected by m_DelayedFlushMutex
QSharedPointer<QMdnsEngine::Server> m_MdnsServer;
QMdnsEngine::Browser* m_MdnsBrowser;
QMdnsEngine::Cache m_MdnsCache;
QVector<MdnsPendingComputer*> m_PendingResolution;
CompatFetcher m_CompatFetcher;
DelayedFlushThread* m_DelayedFlushThread;
QMutex m_DelayedFlushMutex; // Lock ordering: Must never be acquired while holding NvComputer lock
QWaitCondition m_DelayedFlushCondition;
bool m_NeedsDelayedFlush;
};
+10 -3
View File
@@ -6,6 +6,13 @@ ComputerSeeker::ComputerSeeker(ComputerManager *manager, QString computerName, Q
: QObject(parent), m_ComputerManager(manager), m_ComputerName(computerName),
m_TimeoutTimer(new QTimer(this))
{
// If we know this computer, send a WOL packet to wake it up in case it is asleep.
for (NvComputer * computer: m_ComputerManager->getComputers()) {
if (this->matchComputer(computer)) {
computer->wake();
}
}
m_TimeoutTimer->setSingleShot(true);
connect(m_TimeoutTimer, &QTimer::timeout,
this, &ComputerSeeker::onTimeout);
@@ -20,7 +27,7 @@ void ComputerSeeker::start(int timeout)
// if m_ComputerName is UUID, or the name that doesn't resolve to an IP
// address) and by polling it using mDNS, hopefully one of these methods
// would find the host
m_ComputerManager->addNewHost(m_ComputerName, false);
m_ComputerManager->addNewHostManually(m_ComputerName);
m_ComputerManager->startPolling();
}
@@ -44,8 +51,8 @@ bool ComputerSeeker::matchComputer(NvComputer *computer) const
return true;
}
for (const QString& addr : computer->uniqueAddresses()) {
if (addr.toLower() == value) {
for (const NvAddress& addr : computer->uniqueAddresses()) {
if (addr.address().toLower() == value || addr.toString().toLower() == value) {
return true;
}
}
+15 -15
View File
@@ -5,7 +5,6 @@
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
@@ -32,20 +31,19 @@ void IdentityManager::createCredentials(QSettings& settings)
X509* cert = X509_new();
THROW_BAD_ALLOC_IF_NULL(cert);
EVP_PKEY* pk = EVP_PKEY_new();
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
THROW_BAD_ALLOC_IF_NULL(ctx);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048);
// pk must be initialized on input
EVP_PKEY* pk = NULL;
EVP_PKEY_keygen(ctx, &pk);
EVP_PKEY_CTX_free(ctx);
THROW_BAD_ALLOC_IF_NULL(pk);
BIGNUM* bne = BN_new();
THROW_BAD_ALLOC_IF_NULL(bne);
RSA* rsa = RSA_new();
THROW_BAD_ALLOC_IF_NULL(rsa);
BN_set_word(bne, RSA_F4);
RSA_generate_key_ex(rsa, 2048, bne, nullptr);
EVP_PKEY_assign_RSA(pk, rsa);
X509_set_version(cert, 2);
ASN1_INTEGER_set(X509_get_serialNumber(cert), 0);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
@@ -94,7 +92,6 @@ void IdentityManager::createCredentials(QSettings& settings)
X509_free(cert);
EVP_PKEY_free(pk);
BN_free(bne);
BIO_free(biokey);
BIO_free(biocert);
@@ -146,7 +143,10 @@ QSslKey
IdentityManager::getSslKey()
{
if (m_CachedSslKey.isNull()) {
BIO* bio = BIO_new_mem_buf(m_CachedPrivateKey.data(), -1);
// This seemingly useless const_cast is required for old OpenSSL headers
// where BIO_new_mem_buf's parameter is not declared const like those on
// the Steam Link hardware.
BIO* bio = BIO_new_mem_buf(const_cast<char*>(m_CachedPrivateKey.constData()), -1);
THROW_BAD_ALLOC_IF_NULL(bio);
EVP_PKEY* pk = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
+65
View File
@@ -0,0 +1,65 @@
#include "nvaddress.h"
#include <QHostAddress>
NvAddress::NvAddress()
{
setAddress(nullptr);
setPort(0);
}
NvAddress::NvAddress(QString addr, uint16_t port)
{
setAddress(addr);
setPort(port);
}
NvAddress::NvAddress(QHostAddress addr, uint16_t port)
{
setAddress(addr);
setPort(port);
}
uint16_t NvAddress::port() const
{
return m_Port;
}
QString NvAddress::address() const
{
return m_Address;
}
void NvAddress::setPort(uint16_t port)
{
m_Port = port;
}
void NvAddress::setAddress(QString addr)
{
m_Address = addr;
}
void NvAddress::setAddress(QHostAddress addr)
{
m_Address = addr.toString();
}
bool NvAddress::isNull() const
{
return m_Address.isEmpty();
}
QString NvAddress::toString() const
{
if (m_Address.isEmpty()) {
return "<NULL>";
}
if (QHostAddress(m_Address).protocol() == QAbstractSocket::IPv6Protocol) {
return QString("[%1]:%2").arg(m_Address).arg(m_Port);
}
else {
return QString("%1:%2").arg(m_Address).arg(m_Port);
}
}
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include <QHostAddress>
#define DEFAULT_HTTP_PORT 47989
#define DEFAULT_HTTPS_PORT 47984
class NvAddress
{
public:
NvAddress();
explicit NvAddress(QString addr, uint16_t port);
explicit NvAddress(QHostAddress addr, uint16_t port);
uint16_t port() const;
void setPort(uint16_t port);
QString address() const;
void setAddress(QString addr);
void setAddress(QHostAddress addr);
bool isNull() const;
QString toString() const;
bool operator==(const NvAddress& other) const
{
return m_Address == other.m_Address &&
m_Port == other.m_Port;
}
bool operator!=(const NvAddress& other) const
{
return !operator==(other);
}
private:
QString m_Address;
uint16_t m_Port;
};
+28
View File
@@ -0,0 +1,28 @@
#include "nvapp.h"
#define SER_APPNAME "name"
#define SER_APPID "id"
#define SER_APPHDR "hdr"
#define SER_APPCOLLECTOR "appcollector"
#define SER_HIDDEN "hidden"
#define SER_DIRECTLAUNCH "directlaunch"
NvApp::NvApp(QSettings& settings)
{
name = settings.value(SER_APPNAME).toString();
id = settings.value(SER_APPID).toInt();
hdrSupported = settings.value(SER_APPHDR).toBool();
isAppCollectorGame = settings.value(SER_APPCOLLECTOR).toBool();
hidden = settings.value(SER_HIDDEN).toBool();
directLaunch = settings.value(SER_DIRECTLAUNCH).toBool();
}
void NvApp::serialize(QSettings& settings) const
{
settings.setValue(SER_APPNAME, name);
settings.setValue(SER_APPID, id);
settings.setValue(SER_APPHDR, hdrSupported);
settings.setValue(SER_APPCOLLECTOR, isAppCollectorGame);
settings.setValue(SER_HIDDEN, hidden);
settings.setValue(SER_DIRECTLAUNCH, directLaunch);
}
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <QSettings>
class NvApp
{
public:
NvApp() {}
explicit NvApp(QSettings& settings);
bool operator==(const NvApp& other) const
{
return id == other.id &&
name == other.name &&
hdrSupported == other.hdrSupported &&
isAppCollectorGame == other.isAppCollectorGame &&
hidden == other.hidden &&
directLaunch == other.directLaunch;
}
bool operator!=(const NvApp& other) const
{
return !operator==(other);
}
bool isInitialized()
{
return id != 0 && !name.isEmpty();
}
void
serialize(QSettings& settings) const;
int id = 0;
QString name;
bool hdrSupported = false;
bool isAppCollectorGame = false;
bool hidden = false;
bool directLaunch = false;
};
Q_DECLARE_METATYPE(NvApp)
+330 -77
View File
@@ -1,50 +1,56 @@
#include "nvcomputer.h"
#include "nvapp.h"
#include "settings/compatfetcher.h"
#include <QUdpSocket>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QNetworkProxy>
#define SER_NAME "hostname"
#define SER_UUID "uuid"
#define SER_MAC "mac"
#define SER_LOCALADDR "localaddress"
#define SER_LOCALPORT "localport"
#define SER_REMOTEADDR "remoteaddress"
#define SER_REMOTEPORT "remoteport"
#define SER_MANUALADDR "manualaddress"
#define SER_MANUALPORT "manualport"
#define SER_IPV6ADDR "ipv6address"
#define SER_IPV6PORT "ipv6port"
#define SER_APPLIST "apps"
#define SER_SRVCERT "srvcert"
#define SER_APPNAME "name"
#define SER_APPID "id"
#define SER_APPHDR "hdr"
#define SER_CUSTOMNAME "customname"
#define SER_NVIDIASOFTWARE "nvidiasw"
NvComputer::NvComputer(QSettings& settings)
{
this->name = settings.value(SER_NAME).toString();
this->uuid = settings.value(SER_UUID).toString();
this->hasCustomName = settings.value(SER_CUSTOMNAME).toBool();
this->macAddress = settings.value(SER_MAC).toByteArray();
this->localAddress = settings.value(SER_LOCALADDR).toString();
this->remoteAddress = settings.value(SER_REMOTEADDR).toString();
this->ipv6Address = settings.value(SER_IPV6ADDR).toString();
this->manualAddress = settings.value(SER_MANUALADDR).toString();
this->localAddress = NvAddress(settings.value(SER_LOCALADDR).toString(),
settings.value(SER_LOCALPORT, QVariant(DEFAULT_HTTP_PORT)).toUInt());
this->remoteAddress = NvAddress(settings.value(SER_REMOTEADDR).toString(),
settings.value(SER_REMOTEPORT, QVariant(DEFAULT_HTTP_PORT)).toUInt());
this->ipv6Address = NvAddress(settings.value(SER_IPV6ADDR).toString(),
settings.value(SER_IPV6PORT, QVariant(DEFAULT_HTTP_PORT)).toUInt());
this->manualAddress = NvAddress(settings.value(SER_MANUALADDR).toString(),
settings.value(SER_MANUALPORT, QVariant(DEFAULT_HTTP_PORT)).toUInt());
this->serverCert = QSslCertificate(settings.value(SER_SRVCERT).toByteArray());
this->isNvidiaServerSoftware = settings.value(SER_NVIDIASOFTWARE).toBool();
int appCount = settings.beginReadArray(SER_APPLIST);
this->appList.reserve(appCount);
for (int i = 0; i < appCount; i++) {
NvApp app;
settings.setArrayIndex(i);
app.name = settings.value(SER_APPNAME).toString();
app.id = settings.value(SER_APPID).toInt();
app.hdrSupported = settings.value(SER_APPHDR).toBool();
NvApp app(settings);
this->appList.append(app);
}
settings.endArray();
sortAppList();
this->activeAddress = nullptr;
this->currentGameId = 0;
this->pairState = PS_UNKNOWN;
this->state = CS_UNKNOWN;
@@ -54,36 +60,66 @@ NvComputer::NvComputer(QSettings& settings)
this->serverCodecModeSupport = 0;
this->pendingQuit = false;
this->gpuModel = nullptr;
this->isSupportedServerVersion = true;
this->externalPort = this->remoteAddress.port();
this->activeHttpsPort = 0;
}
void NvComputer::serialize(QSettings& settings)
void NvComputer::setRemoteAddress(QHostAddress address)
{
QWriteLocker lock(&this->lock);
Q_ASSERT(this->externalPort != 0);
this->remoteAddress = NvAddress(address, this->externalPort);
}
void NvComputer::serialize(QSettings& settings, bool serializeApps) const
{
QReadLocker lock(&this->lock);
settings.setValue(SER_NAME, name);
settings.setValue(SER_CUSTOMNAME, hasCustomName);
settings.setValue(SER_UUID, uuid);
settings.setValue(SER_MAC, macAddress);
settings.setValue(SER_LOCALADDR, localAddress);
settings.setValue(SER_REMOTEADDR, remoteAddress);
settings.setValue(SER_IPV6ADDR, ipv6Address);
settings.setValue(SER_MANUALADDR, manualAddress);
settings.setValue(SER_LOCALADDR, localAddress.address());
settings.setValue(SER_LOCALPORT, localAddress.port());
settings.setValue(SER_REMOTEADDR, remoteAddress.address());
settings.setValue(SER_REMOTEPORT, remoteAddress.port());
settings.setValue(SER_IPV6ADDR, ipv6Address.address());
settings.setValue(SER_IPV6PORT, ipv6Address.port());
settings.setValue(SER_MANUALADDR, manualAddress.address());
settings.setValue(SER_MANUALPORT, manualAddress.port());
settings.setValue(SER_SRVCERT, serverCert.toPem());
settings.setValue(SER_NVIDIASOFTWARE, isNvidiaServerSoftware);
// Avoid deleting an existing applist if we couldn't get one
if (!appList.isEmpty()) {
if (!appList.isEmpty() && serializeApps) {
settings.remove(SER_APPLIST);
settings.beginWriteArray(SER_APPLIST);
for (int i = 0; i < appList.count(); i++) {
settings.setArrayIndex(i);
settings.setValue(SER_APPNAME, appList[i].name);
settings.setValue(SER_APPID, appList[i].id);
settings.setValue(SER_APPHDR, appList[i].hdrSupported);
appList[i].serialize(settings);
}
settings.endArray();
}
}
bool NvComputer::isEqualSerialized(const NvComputer &that) const
{
return this->name == that.name &&
this->hasCustomName == that.hasCustomName &&
this->uuid == that.uuid &&
this->macAddress == that.macAddress &&
this->localAddress == that.localAddress &&
this->remoteAddress == that.remoteAddress &&
this->ipv6Address == that.ipv6Address &&
this->manualAddress == that.manualAddress &&
this->serverCert == that.serverCert &&
this->isNvidiaServerSoftware == that.isNvidiaServerSoftware &&
this->appList == that.appList;
}
void NvComputer::sortAppList()
{
std::stable_sort(appList.begin(), appList.end(), [](const NvApp& app1, const NvApp& app2) {
@@ -91,10 +127,11 @@ void NvComputer::sortAppList()
});
}
NvComputer::NvComputer(QString address, QString serverInfo, QSslCertificate serverCert)
NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
{
this->serverCert = serverCert;
this->serverCert = http.serverCert();
this->hasCustomName = false;
this->name = NvHTTP::getXmlString(serverInfo, "hostname");
if (this->name.isEmpty()) {
this->name = "UNKNOWN";
@@ -104,7 +141,7 @@ NvComputer::NvComputer(QString address, QString serverInfo, QSslCertificate serv
QString newMacString = NvHTTP::getXmlString(serverInfo, "mac");
if (newMacString != "00:00:00:00:00:00") {
QStringList macOctets = newMacString.split(':');
for (QString macOctet : macOctets) {
for (const QString& macOctet : macOctets) {
this->macAddress.append((char) macOctet.toInt(nullptr, 16));
}
}
@@ -114,7 +151,8 @@ NvComputer::NvComputer(QString address, QString serverInfo, QSslCertificate serv
this->serverCodecModeSupport = codecSupport.toInt();
}
else {
this->serverCodecModeSupport = 0;
// Assume H.264 is always supported
this->serverCodecModeSupport = SCM_H264;
}
QString maxLumaPixelsHEVC = NvHTTP::getXmlString(serverInfo, "MaxLumaPixelsHEVC");
@@ -128,58 +166,99 @@ NvComputer::NvComputer(QString address, QString serverInfo, QSslCertificate serv
this->displayModes = NvHTTP::getDisplayModeList(serverInfo);
std::stable_sort(this->displayModes.begin(), this->displayModes.end(),
[](const NvDisplayMode& mode1, const NvDisplayMode& mode2) {
return mode1.width * mode1.height * mode1.refreshRate <
mode2.width * mode2.height * mode2.refreshRate;
return (uint64_t)mode1.width * mode1.height * mode1.refreshRate <
(uint64_t)mode2.width * mode2.height * mode2.refreshRate;
});
// We can get an IPv4 loopback address if we're using the GS IPv6 Forwarder
this->localAddress = NvHTTP::getXmlString(serverInfo, "LocalIP");
if (this->localAddress.startsWith("127.")) {
this->localAddress = QString();
this->localAddress = NvAddress(NvHTTP::getXmlString(serverInfo, "LocalIP"), http.httpPort());
if (this->localAddress.address().startsWith("127.")) {
this->localAddress = NvAddress();
}
this->remoteAddress = NvHTTP::getXmlString(serverInfo, "ExternalIP");
QString httpsPort = NvHTTP::getXmlString(serverInfo, "HttpsPort");
if (httpsPort.isEmpty() || (this->activeHttpsPort = httpsPort.toUShort()) == 0) {
this->activeHttpsPort = DEFAULT_HTTPS_PORT;
}
// This is an extension which is not present in GFE. It is present for Sunshine to be able
// to support dynamic HTTP WAN ports without requiring the user to manually enter the port.
QString remotePortStr = NvHTTP::getXmlString(serverInfo, "ExternalPort");
if (remotePortStr.isEmpty() || (this->externalPort = remotePortStr.toUShort()) == 0) {
this->externalPort = http.httpPort();
}
QString remoteAddress = NvHTTP::getXmlString(serverInfo, "ExternalIP");
if (!remoteAddress.isEmpty()) {
this->remoteAddress = NvAddress(remoteAddress, this->externalPort);
}
else {
this->remoteAddress = NvAddress();
}
// Real Nvidia host software (GeForce Experience and RTX Experience) both use the 'Mjolnir'
// codename in the state field and no version of Sunshine does. We can use this to bypass
// some assumptions about Nvidia hardware that don't apply to Sunshine hosts.
this->isNvidiaServerSoftware = NvHTTP::getXmlString(serverInfo, "state").contains("MJOLNIR");
this->pairState = NvHTTP::getXmlString(serverInfo, "PairStatus") == "1" ?
PS_PAIRED : PS_NOT_PAIRED;
this->currentGameId = NvHTTP::getCurrentGame(serverInfo);
this->appVersion = NvHTTP::getXmlString(serverInfo, "appversion");
this->gfeVersion = NvHTTP::getXmlString(serverInfo, "GfeVersion");
this->gpuModel = NvHTTP::getXmlString(serverInfo, "gputype");
this->activeAddress = address;
this->activeAddress = http.address();
this->state = NvComputer::CS_ONLINE;
this->pendingQuit = false;
this->isSupportedServerVersion = CompatFetcher::isGfeVersionSupported(this->gfeVersion);
}
bool NvComputer::wake()
bool NvComputer::wake() const
{
if (state == NvComputer::CS_ONLINE) {
qWarning() << name << "is already online";
return true;
QByteArray wolPayload;
{
QReadLocker readLocker(&lock);
if (state == NvComputer::CS_ONLINE) {
qWarning() << name << "is already online";
return true;
}
if (macAddress.isEmpty()) {
qWarning() << name << "has no MAC address stored";
return false;
}
// Create the WoL payload
wolPayload.append(QByteArray::fromHex("FFFFFFFFFFFF"));
for (int i = 0; i < 16; i++) {
wolPayload.append(macAddress);
}
Q_ASSERT(wolPayload.size() == 102);
}
if (macAddress.isEmpty()) {
qWarning() << name << "has no MAC address stored";
return false;
}
const quint16 WOL_PORTS[] = {
7, 9, // Standard WOL ports
47998, 47999, 48000, 48002, 48010, // Ports opened by GFE
// Ports used as-is
const quint16 STATIC_WOL_PORTS[] = {
9, // Standard WOL port (privileged port)
47009, // Port opened by Moonlight Internet Hosting Tool for WoL (non-privileged port)
};
// Create the WoL payload
QByteArray wolPayload;
wolPayload.append(QByteArray::fromHex("FFFFFFFFFFFF"));
for (int i = 0; i < 16; i++) {
wolPayload.append(macAddress);
}
Q_ASSERT(wolPayload.count() == 102);
// Ports offset by the HTTP base port for hosts using alternate ports
const quint16 DYNAMIC_WOL_PORTS[] = {
47998, 47999, 48000, 48002, 48010, // Ports opened by GFE
};
// Add the addresses that we know this host to be
// and broadcast addresses for this link just in
// case the host has timed out in ARP entries.
QVector<QString> addressList = uniqueAddresses();
addressList.append("255.255.255.255");
QMap<QString, quint16> addressMap;
QSet<quint16> basePortSet;
for (const NvAddress& addr : uniqueAddresses()) {
addressMap.insert(addr.address(), addr.port());
basePortSet.insert(addr.port());
}
addressMap.insert("255.255.255.255", 0);
// Try to broadcast on all available NICs
for (const QNetworkInterface& nic : QNetworkInterface::allInterfaces()) {
@@ -198,31 +277,42 @@ bool NvComputer::wake()
// Skip IPv6 which doesn't support broadcast
if (!addr.broadcast().isNull()) {
addressList.append(addr.broadcast().toString());
addressMap.insert(addr.broadcast().toString(), 0);
}
}
if (!allNodesMulticast.scopeId().isEmpty()) {
addressList.append(allNodesMulticast.toString());
addressMap.insert(allNodesMulticast.toString(), 0);
}
}
// Try all unique address strings or host names
bool success = false;
for (QString& addressString : addressList) {
QHostInfo hostInfo = QHostInfo::fromName(addressString);
for (auto i = addressMap.constBegin(); i != addressMap.constEnd(); i++) {
QHostAddress literalAddress;
QList<QHostAddress> addressList;
if (hostInfo.error() != QHostInfo::NoError) {
qWarning() << "Error resolving" << addressString << ":" << hostInfo.errorString();
continue;
// If this is an IPv4/IPv6 literal, don't use QHostInfo::fromName() because that will
// try to perform a reverse DNS lookup that leads to delays sending WoL packets.
if (literalAddress.setAddress(i.key())) {
addressList.append(literalAddress);
}
else {
QHostInfo hostInfo = QHostInfo::fromName(i.key());
if (hostInfo.error() != QHostInfo::NoError) {
qWarning() << "Error resolving" << i.key() << ":" << hostInfo.errorString();
continue;
}
addressList.append(hostInfo.addresses());
}
// Try all IP addresses that this string resolves to
for (QHostAddress& address : hostInfo.addresses()) {
for (QHostAddress& address : addressList) {
QUdpSocket sock;
// Send to all ports
for (quint16 port : WOL_PORTS) {
// Send to all static ports
for (quint16 port : STATIC_WOL_PORTS) {
if (sock.writeDatagram(wolPayload, address, port)) {
qInfo().nospace().noquote() << "Sent WoL packet to " << name << " via " << address.toString() << ":" << port;
success = true;
@@ -231,15 +321,166 @@ bool NvComputer::wake()
qWarning() << "Send failed:" << sock.error();
}
}
QList<quint16> basePorts;
if (i.value() != 0) {
// If we have a known base port for this address, use only that port
basePorts.append(i.value());
}
else {
// If this is a broadcast address without a known HTTP port, try all of them
basePorts.append(basePortSet.values());
}
// Send to all dynamic ports using the HTTP port offset(s) for this address
for (quint16 basePort : basePorts) {
for (quint16 port : DYNAMIC_WOL_PORTS) {
port = (port - 47989) + basePort;
if (sock.writeDatagram(wolPayload, address, port)) {
qInfo().nospace().noquote() << "Sent WoL packet to " << name << " via " << address.toString() << ":" << port;
success = true;
}
else {
qWarning() << "Send failed:" << sock.error();
}
}
}
}
}
return success;
}
QVector<QString> NvComputer::uniqueAddresses()
NvComputer::ReachabilityType NvComputer::getActiveAddressReachability() const
{
QVector<QString> uniqueAddressList;
NvAddress copyOfActiveAddress;
{
QReadLocker readLocker(&lock);
if (activeAddress.isNull()) {
return ReachabilityType::RI_UNKNOWN;
}
// Grab a copy of the active address to avoid having to hold
// the computer lock while doing socket operations
copyOfActiveAddress = activeAddress;
}
QTcpSocket s;
s.setProxy(QNetworkProxy::NoProxy);
s.connectToHost(copyOfActiveAddress.address(), copyOfActiveAddress.port());
if (s.waitForConnected(3000)) {
Q_ASSERT(!s.localAddress().isNull());
Q_ASSERT(!s.peerAddress().isNull());
for (const QNetworkInterface& nic : QNetworkInterface::allInterfaces()) {
// Ensure the interface is up
if ((nic.flags() & QNetworkInterface::IsUp) == 0) {
continue;
}
for (const QNetworkAddressEntry& addr : nic.addressEntries()) {
if (addr.ip() == s.localAddress()) {
qInfo() << "Found matching interface:" << nic.humanReadableName() << nic.hardwareAddress() << nic.flags();
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
qInfo() << "Interface Type:" << nic.type();
qInfo() << "Interface MTU:" << nic.maximumTransmissionUnit();
if (nic.type() == QNetworkInterface::Virtual ||
nic.type() == QNetworkInterface::Ppp) {
// Treat PPP and virtual interfaces as likely VPNs
return ReachabilityType::RI_VPN;
}
if (nic.maximumTransmissionUnit() != 0 && nic.maximumTransmissionUnit() < 1500) {
// Treat MTUs under 1500 as likely VPNs
return ReachabilityType::RI_VPN;
}
#endif
if (nic.flags() & QNetworkInterface::IsPointToPoint) {
// Treat point-to-point links as likely VPNs.
// This check detects OpenVPN on Unix-like OSes.
return ReachabilityType::RI_VPN;
}
#ifdef Q_OS_WINDOWS
if (nic.name().startsWith("iftype53_") || nic.name().startsWith("iftype131_")) {
// Match by NDIS interface type. These values are Microsoft's recommended values for VPN connections:
// https://learn.microsoft.com/en-US/troubleshoot/windows-client/networking/windows-connection-manager-disconnects-wlan#more-information
//
// The following VPNs use IF_TYPE_PROP_VIRTUAL under Windows:
// - WireguardNT VPNs
// - All WinTun-based VPNs (such as Slack Nebula)
// - OpenVPN with tap-windows6
return ReachabilityType::RI_VPN;
}
#endif
if (nic.hardwareAddress().startsWith("00:FF", Qt::CaseInsensitive)) {
// OpenVPN TAP interfaces have a MAC address starting with 00:FF on Windows
return ReachabilityType::RI_VPN;
}
if (nic.humanReadableName().startsWith("ZeroTier")) {
// ZeroTier interfaces always start with "ZeroTier"
return ReachabilityType::RI_VPN;
}
if (nic.humanReadableName().contains("VPN")) {
// This one is just a final VPN heuristic if all else fails
return ReachabilityType::RI_VPN;
}
// Didn't meet any of our VPN heuristics. Let's see if the peer address is on-link.
Q_ASSERT(addr.prefixLength() >= 0);
if (addr.prefixLength() >= 0 && s.localAddress().isInSubnet(s.peerAddress(), addr.prefixLength())) {
return ReachabilityType::RI_LAN;
}
// Default to unknown if nothing else matched
return ReachabilityType::RI_UNKNOWN;
}
}
}
qWarning() << "No match found for address:" << s.localAddress();
return ReachabilityType::RI_UNKNOWN;
}
else {
// If we fail to connect, just pretend that it's not a VPN
qWarning() << "Unable to check for reachability within 3 seconds";
return ReachabilityType::RI_UNKNOWN;
}
}
bool NvComputer::updateAppList(QVector<NvApp> newAppList) {
if (appList == newAppList) {
return false;
}
// Propagate client-side attributes to the new app list
for (const NvApp& existingApp : appList) {
for (NvApp& newApp : newAppList) {
if (existingApp.id == newApp.id) {
newApp.hidden = existingApp.hidden;
newApp.directLaunch = existingApp.directLaunch;
}
}
}
appList = newAppList;
sortAppList();
return true;
}
QVector<NvAddress> NvComputer::uniqueAddresses() const
{
QReadLocker readLocker(&lock);
QVector<NvAddress> uniqueAddressList;
// Start with addresses correctly ordered
uniqueAddressList.append(activeAddress);
@@ -250,7 +491,7 @@ QVector<QString> NvComputer::uniqueAddresses()
// Prune duplicates (always giving precedence to the first)
for (int i = 0; i < uniqueAddressList.count(); i++) {
if (uniqueAddressList[i].isEmpty()) {
if (uniqueAddressList[i].isNull()) {
uniqueAddressList.remove(i);
i--;
continue;
@@ -270,7 +511,7 @@ QVector<QString> NvComputer::uniqueAddresses()
return uniqueAddressList;
}
bool NvComputer::update(NvComputer& that)
bool NvComputer::update(const NvComputer& that)
{
bool changed = false;
@@ -301,12 +542,17 @@ bool NvComputer::update(NvComputer& that)
changed = true; \
}
ASSIGN_IF_CHANGED(name);
if (!hasCustomName) {
// Only overwrite the name if it's not custom
ASSIGN_IF_CHANGED(name);
}
ASSIGN_IF_CHANGED_AND_NONEMPTY(macAddress);
ASSIGN_IF_CHANGED_AND_NONEMPTY(localAddress);
ASSIGN_IF_CHANGED_AND_NONEMPTY(remoteAddress);
ASSIGN_IF_CHANGED_AND_NONEMPTY(ipv6Address);
ASSIGN_IF_CHANGED_AND_NONEMPTY(manualAddress);
ASSIGN_IF_CHANGED_AND_NONNULL(localAddress);
ASSIGN_IF_CHANGED_AND_NONNULL(remoteAddress);
ASSIGN_IF_CHANGED_AND_NONNULL(ipv6Address);
ASSIGN_IF_CHANGED_AND_NONNULL(manualAddress);
ASSIGN_IF_CHANGED(activeHttpsPort);
ASSIGN_IF_CHANGED(externalPort);
ASSIGN_IF_CHANGED(pairState);
ASSIGN_IF_CHANGED(serverCodecModeSupport);
ASSIGN_IF_CHANGED(currentGameId);
@@ -314,10 +560,17 @@ bool NvComputer::update(NvComputer& that)
ASSIGN_IF_CHANGED(state);
ASSIGN_IF_CHANGED(gfeVersion);
ASSIGN_IF_CHANGED(appVersion);
ASSIGN_IF_CHANGED(isSupportedServerVersion);
ASSIGN_IF_CHANGED(isNvidiaServerSoftware);
ASSIGN_IF_CHANGED(maxLumaPixelsHEVC);
ASSIGN_IF_CHANGED(gpuModel);
ASSIGN_IF_CHANGED_AND_NONNULL(serverCert);
ASSIGN_IF_CHANGED_AND_NONEMPTY(appList);
ASSIGN_IF_CHANGED_AND_NONEMPTY(displayModes);
if (!that.appList.isEmpty()) {
// updateAppList() handles merging client-side attributes
updateAppList(that.appList);
}
return changed;
}
+59 -13
View File
@@ -1,12 +1,23 @@
#pragma once
#include "nvhttp.h"
#include "nvaddress.h"
#include <QThread>
#include <QReadWriteLock>
#include <QSettings>
#include <QRunnable>
class CopySafeReadWriteLock : public QReadWriteLock
{
public:
CopySafeReadWriteLock() = default;
// Don't actually copy the QReadWriteLock
CopySafeReadWriteLock(const CopySafeReadWriteLock&) : QReadWriteLock() {}
CopySafeReadWriteLock& operator=(const CopySafeReadWriteLock &) { return *this; }
};
class NvComputer
{
friend class PcMonitorThread;
@@ -16,24 +27,51 @@ class NvComputer
private:
void sortAppList();
bool updateAppList(QVector<NvApp> newAppList);
bool pendingQuit;
public:
explicit NvComputer(QString address, QString serverInfo, QSslCertificate serverCert);
NvComputer() = default;
// Caller is responsible for synchronizing read access to the other host
NvComputer(const NvComputer&) = default;
// Caller is responsible for synchronizing read access to the other host
NvComputer& operator=(const NvComputer &) = default;
explicit NvComputer(NvHTTP& http, QString serverInfo);
explicit NvComputer(QSettings& settings);
bool
update(NvComputer& that);
void
setRemoteAddress(QHostAddress);
bool
wake();
update(const NvComputer& that);
QVector<QString>
uniqueAddresses();
bool
wake() const;
enum ReachabilityType
{
RI_UNKNOWN,
RI_LAN,
RI_VPN,
};
ReachabilityType
getActiveAddressReachability() const;
QVector<NvAddress>
uniqueAddresses() const;
void
serialize(QSettings& settings);
serialize(QSettings& settings, bool serializeApps) const;
// Caller is responsible for synchronizing read access to both hosts
bool
isEqualSerialized(const NvComputer& that) const;
enum PairState
{
@@ -52,7 +90,8 @@ public:
// Ephemeral traits
ComputerState state;
PairState pairState;
QString activeAddress;
NvAddress activeAddress;
uint16_t activeHttpsPort;
int currentGameId;
QString gfeVersion;
QString appVersion;
@@ -60,18 +99,25 @@ public:
int maxLumaPixelsHEVC;
int serverCodecModeSupport;
QString gpuModel;
bool isSupportedServerVersion;
// Persisted traits
QString localAddress;
QString remoteAddress;
QString ipv6Address;
QString manualAddress;
NvAddress localAddress;
NvAddress remoteAddress;
NvAddress ipv6Address;
NvAddress manualAddress;
QByteArray macAddress;
QString name;
bool hasCustomName;
QString uuid;
QSslCertificate serverCert;
QVector<NvApp> appList;
bool isNvidiaServerSoftware;
// Remember to update isEqualSerialized() when adding fields here!
// Synchronization
QReadWriteLock lock;
mutable CopySafeReadWriteLock lock;
private:
uint16_t externalPort;
};
+137 -90
View File
@@ -1,4 +1,4 @@
#include "nvhttp.h"
#include "nvcomputer.h"
#include <Limelight.h>
#include <QDebug>
@@ -12,20 +12,20 @@
#include <QtEndian>
#include <QNetworkProxy>
#define FAST_FAIL_TIMEOUT_MS 2000
#define REQUEST_TIMEOUT_MS 5000
#define LAUNCH_TIMEOUT_MS 120000
#define RESUME_TIMEOUT_MS 30000
#define QUIT_TIMEOUT_MS 30000
NvHTTP::NvHTTP(QString address, QSslCertificate serverCert) :
NvHTTP::NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert) :
m_ServerCert(serverCert)
{
m_BaseUrlHttp.setScheme("http");
m_BaseUrlHttps.setScheme("https");
m_BaseUrlHttp.setPort(47989);
m_BaseUrlHttps.setPort(47984);
setAddress(address);
setHttpsPort(httpsPort);
// Never use a proxy server
QNetworkProxy noProxy(QNetworkProxy::NoProxy);
@@ -34,26 +34,54 @@ NvHTTP::NvHTTP(QString address, QSslCertificate serverCert) :
connect(&m_Nam, &QNetworkAccessManager::sslErrors, this, &NvHTTP::handleSslErrors);
}
NvHTTP::NvHTTP(NvComputer* computer) :
NvHTTP(computer->activeAddress, computer->activeHttpsPort, computer->serverCert)
{
}
void NvHTTP::setServerCert(QSslCertificate serverCert)
{
m_ServerCert = serverCert;
}
void NvHTTP::setAddress(QString address)
void NvHTTP::setAddress(NvAddress address)
{
Q_ASSERT(!address.isEmpty());
Q_ASSERT(!address.isNull());
m_Address = address;
m_BaseUrlHttp.setHost(address);
m_BaseUrlHttps.setHost(address);
m_BaseUrlHttp.setHost(address.address());
m_BaseUrlHttps.setHost(address.address());
m_BaseUrlHttp.setPort(address.port());
}
QString NvHTTP::address()
void NvHTTP::setHttpsPort(uint16_t port)
{
m_BaseUrlHttps.setPort(port);
}
NvAddress NvHTTP::address()
{
return m_Address;
}
QSslCertificate NvHTTP::serverCert()
{
return m_ServerCert;
}
uint16_t NvHTTP::httpPort()
{
return m_BaseUrlHttp.port();
}
uint16_t NvHTTP::httpsPort()
{
return m_BaseUrlHttps.port();
}
QVector<int>
NvHTTP::parseQuad(QString quad)
{
@@ -66,7 +94,8 @@ NvHTTP::parseQuad(QString quad)
}
QStringList parts = quad.split(".");
for (int i = 0; i < 4; i++)
ret.reserve(parts.length());
for (int i = 0; i < parts.length(); i++)
{
ret.append(parts.at(i).toInt());
}
@@ -92,12 +121,12 @@ NvHTTP::getCurrentGame(QString serverInfo)
}
QString
NvHTTP::getServerInfo(NvLogLevel logLevel)
NvHTTP::getServerInfo(NvLogLevel logLevel, bool fastFail)
{
QString serverInfo;
// Check if we have a pinned cert for this host yet
if (!m_ServerCert.isNull())
// Check if we have a pinned cert and HTTPS port for this host yet
if (!m_ServerCert.isNull() && httpsPort() != 0)
{
try
{
@@ -106,7 +135,7 @@ NvHTTP::getServerInfo(NvLogLevel logLevel)
serverInfo = openConnectionToString(m_BaseUrlHttps,
"serverinfo",
nullptr,
REQUEST_TIMEOUT_MS,
fastFail ? FAST_FAIL_TIMEOUT_MS : REQUEST_TIMEOUT_MS,
logLevel);
// Throws if the request failed
verifyResponseStatus(serverInfo);
@@ -119,7 +148,7 @@ NvHTTP::getServerInfo(NvLogLevel logLevel)
serverInfo = openConnectionToString(m_BaseUrlHttp,
"serverinfo",
nullptr,
REQUEST_TIMEOUT_MS,
fastFail ? FAST_FAIL_TIMEOUT_MS : REQUEST_TIMEOUT_MS,
logLevel);
verifyResponseStatus(serverInfo);
}
@@ -132,48 +161,41 @@ NvHTTP::getServerInfo(NvLogLevel logLevel)
}
else
{
// Only use HTTP prior to pairing
// Only use HTTP prior to pairing or fetching HTTPS port
serverInfo = openConnectionToString(m_BaseUrlHttp,
"serverinfo",
nullptr,
REQUEST_TIMEOUT_MS,
fastFail ? FAST_FAIL_TIMEOUT_MS : REQUEST_TIMEOUT_MS,
logLevel);
verifyResponseStatus(serverInfo);
// Populate the HTTPS port
uint16_t httpsPort = getXmlString(serverInfo, "HttpsPort").toUShort();
if (httpsPort == 0) {
httpsPort = DEFAULT_HTTPS_PORT;
}
setHttpsPort(httpsPort);
// If we just needed to determine the HTTPS port, we'll try again over
// HTTPS now that we have the port number
if (!m_ServerCert.isNull()) {
return getServerInfo(logLevel, fastFail);
}
}
return serverInfo;
}
static QString
getSurroundAudioInfoString(int audioConfig)
{
int channelMask;
int channelCount;
switch (audioConfig)
{
case AUDIO_CONFIGURATION_STEREO:
channelCount = 2;
channelMask = 0x3;
break;
case AUDIO_CONFIGURATION_51_SURROUND:
channelCount = 6;
channelMask = 0xFC;
break;
default:
Q_ASSERT(false);
return 0;
}
return QString::number(channelMask << 16 | channelCount);
}
void
NvHTTP::launchApp(int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask)
NvHTTP::startApp(QString verb,
bool isGfe,
int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask,
bool persistGameControllersOnDisconnect,
QString& rtspSessionUrl)
{
int riKeyId;
@@ -182,48 +204,35 @@ NvHTTP::launchApp(int appId,
QString response =
openConnectionToString(m_BaseUrlHttps,
"launch",
verb,
"appid="+QString::number(appId)+
"&mode="+QString::number(streamConfig->width)+"x"+
QString::number(streamConfig->height)+"x"+
// Using an FPS value over 60 causes SOPS to default to 720p60,
// so force it to 60 when starting. This won't impact our ability
// to get > 60 FPS while actually streaming though.
QString::number(streamConfig->fps > 60 ? 60 : streamConfig->fps)+
// so force it to 0 to ensure the correct resolution is set. We
// used to use 60 here but that locked the frame rate to 60 FPS
// on GFE 3.20.3. We don't need this hack for Sunshine.
QString::number((streamConfig->fps > 60 && isGfe) ? 0 : streamConfig->fps)+
"&additionalStates=1&sops="+QString::number(sops ? 1 : 0)+
"&rikey="+QByteArray(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey)).toHex()+
"&rikeyid="+QString::number(riKeyId)+
(streamConfig->enableHdr ?
((streamConfig->supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) ?
"&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0" :
"")+
"&localAudioPlayMode="+QString::number(localAudio ? 1 : 0)+
"&surroundAudioInfo="+getSurroundAudioInfoString(streamConfig->audioConfiguration)+
"&surroundAudioInfo="+QString::number(SURROUNDAUDIOINFO_FROM_AUDIO_CONFIGURATION(streamConfig->audioConfiguration))+
"&remoteControllersBitmap="+QString::number(gamepadMask)+
"&gcmap="+QString::number(gamepadMask),
"&gcmap="+QString::number(gamepadMask)+
"&gcpersist="+QString::number(persistGameControllersOnDisconnect ? 1 : 0)+
LiGetLaunchUrlQueryParameters(),
LAUNCH_TIMEOUT_MS);
// Throws if the request failed
verifyResponseStatus(response);
}
void
NvHTTP::resumeApp(PSTREAM_CONFIGURATION streamConfig)
{
int riKeyId;
memcpy(&riKeyId, streamConfig->remoteInputAesIv, sizeof(riKeyId));
riKeyId = qFromBigEndian(riKeyId);
QString response =
openConnectionToString(m_BaseUrlHttps,
"resume",
"rikey="+QString(QByteArray(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey)).toHex())+
"&rikeyid="+QString::number(riKeyId)+
"&surroundAudioInfo="+getSurroundAudioInfoString(streamConfig->audioConfiguration),
RESUME_TIMEOUT_MS);
qInfo() << "Launch response:" << response;
// Throws if the request failed
verifyResponseStatus(response);
rtspSessionUrl = getXmlString(response, "sessionUrl0");
}
void
@@ -235,11 +244,13 @@ NvHTTP::quitApp()
nullptr,
QUIT_TIMEOUT_MS);
qInfo() << "Quit response:" << response;
// Throws if the request failed
verifyResponseStatus(response);
// Newer GFE versions will just return success even if quitting fails
// if we're not the original requestor.
// if we're not the original requester.
if (getCurrentGame(getServerInfo(NvHTTP::NVLL_ERROR)) != 0) {
// Generate a synthetic GfeResponseException letting the caller know
// that they can't kill someone else's stream.
@@ -255,17 +266,17 @@ NvHTTP::getDisplayModeList(QString serverInfo)
while (!xmlReader.atEnd()) {
while (xmlReader.readNextStartElement()) {
QStringRef name = xmlReader.name();
if (xmlReader.name() == "DisplayMode") {
auto name = xmlReader.name();
if (name == QString("DisplayMode")) {
modes.append(NvDisplayMode());
}
else if (xmlReader.name() == "Width") {
else if (name == QString("Width")) {
modes.last().width = xmlReader.readElementText().toInt();
}
else if (xmlReader.name() == "Height") {
else if (name == QString("Height")) {
modes.last().height = xmlReader.readElementText().toInt();
}
else if (xmlReader.name() == "RefreshRate") {
else if (name == QString("RefreshRate")) {
modes.last().refreshRate = xmlReader.readElementText().toInt();
}
}
@@ -288,8 +299,8 @@ NvHTTP::getAppList()
QVector<NvApp> apps;
while (!xmlReader.atEnd()) {
while (xmlReader.readNextStartElement()) {
QStringRef name = xmlReader.name();
if (xmlReader.name() == "App") {
auto name = xmlReader.name();
if (name == QString("App")) {
// We must have a valid app before advancing to the next one
if (!apps.isEmpty() && !apps.last().isInitialized()) {
qWarning() << "Invalid applist XML";
@@ -298,15 +309,18 @@ NvHTTP::getAppList()
}
apps.append(NvApp());
}
else if (xmlReader.name() == "AppTitle") {
else if (name == QString("AppTitle")) {
apps.last().name = xmlReader.readElementText();
}
else if (xmlReader.name() == "ID") {
else if (name == QString("ID")) {
apps.last().id = xmlReader.readElementText().toInt();
}
else if (xmlReader.name() == "IsHdrSupported") {
else if (name == QString("IsHdrSupported")) {
apps.last().hdrSupported = xmlReader.readElementText() == "1";
}
else if (name == QString("IsAppCollectorGame")) {
apps.last().isAppCollectorGame = xmlReader.readElementText() == "1";
}
}
}
@@ -320,9 +334,12 @@ NvHTTP::verifyResponseStatus(QString xml)
while (xmlReader.readNextStartElement())
{
if (xmlReader.name() == "root")
if (xmlReader.name() == QString("root"))
{
int statusCode = xmlReader.attributes().value("status_code").toInt();
// Status code can be 0xFFFFFFFF in some rare cases on GFE 3.20.3, and
// QString::toInt() will fail in that case, so use QString::toUInt()
// and cast the result to an int instead.
int statusCode = (int)xmlReader.attributes().value("status_code").toUInt();
if (statusCode == 200)
{
// Successful
@@ -335,10 +352,18 @@ NvHTTP::verifyResponseStatus(QString xml)
// 401 is expected for unpaired PCs when we fetch serverinfo over HTTPS
qWarning() << "Request failed:" << statusCode << statusMessage;
}
if (statusCode == -1 && statusMessage == "Invalid") {
// Special case handling an audio capture error which GFE doesn't
// provide any useful status message for.
statusCode = 418;
statusMessage = tr("Missing audio capture device. Reinstalling GeForce Experience should resolve this error.");
}
throw GfeHttpResponseException(statusCode, statusMessage);
}
}
}
throw GfeHttpResponseException(-1, "Malformed XML (missing root element)");
}
QImage
@@ -401,7 +426,7 @@ void NvHTTP::handleSslErrors(QNetworkReply* reply, const QList<QSslError>& error
return;
}
for (auto error : errors) {
for (const QSslError& error : errors) {
if (m_ServerCert != error.certificate()) {
ignoreErrors = false;
break;
@@ -424,7 +449,13 @@ NvHTTP::openConnectionToString(QUrl baseUrl,
QString ret;
QTextStream stream(reply);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
stream.setEncoding(QStringConverter::Utf8);
#else
stream.setCodec("UTF-8");
#endif
ret = stream.readAll();
delete reply;
@@ -438,6 +469,9 @@ NvHTTP::openConnection(QUrl baseUrl,
int timeoutMs,
NvLogLevel logLevel)
{
// Port must be set
Q_ASSERT(baseUrl.port(0) != 0);
// Build a URL for the request
QUrl url(baseUrl);
url.setPath("/" + command);
@@ -454,14 +488,27 @@ NvHTTP::openConnection(QUrl baseUrl,
// Add our client certificate
request.setSslConfiguration(IdentityManager::get()->getSslConfig());
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
// Disable HTTP/2 (GFE 3.22 doesn't like it) and Qt 6 enables it by default
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 1) && !defined(QT_NO_BEARERMANAGEMENT)
// HACK: Set network accessibility to work around QTBUG-80947 (introduced in Qt 5.14.0 and fixed in Qt 5.15.1)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
m_Nam.setNetworkAccessible(QNetworkAccessManager::Accessible);
QT_WARNING_POP
#endif
QNetworkReply* reply = m_Nam.get(request);
// Run the request with a timeout if requested
QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), &loop, SLOT(quit()));
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, &loop, &QEventLoop::quit);
if (timeoutMs) {
QTimer::singleShot(timeoutMs, &loop, SLOT(quit()));
QTimer::singleShot(timeoutMs, &loop, &QEventLoop::quit);
}
if (logLevel >= NvLogLevel::NVLL_VERBOSE) {
qInfo() << "Executing request:" << url.toString();
@@ -485,7 +532,7 @@ NvHTTP::openConnection(QUrl baseUrl,
if (reply->error() != QNetworkReply::NoError)
{
if (logLevel >= NvLogLevel::NVLL_ERROR) {
qWarning() << command << " request failed with error " << reply->error();
qWarning() << command << "request failed with error:" << reply->error();
}
if (reply->error() == QNetworkReply::SslHandshakeFailedError) {
+27 -32
View File
@@ -1,6 +1,8 @@
#pragma once
#include "identitymanager.h"
#include "nvapp.h"
#include "nvaddress.h"
#include <Limelight.h>
@@ -8,25 +10,7 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
class NvApp
{
public:
bool operator==(const NvApp& other) const
{
return id == other.id;
}
bool isInitialized()
{
return id != 0 && !name.isEmpty();
}
int id;
QString name;
bool hdrSupported;
};
Q_DECLARE_METATYPE(NvApp)
class NvComputer;
class NvDisplayMode
{
@@ -42,6 +26,7 @@ public:
int height;
int refreshRate;
};
Q_DECLARE_TYPEINFO(NvDisplayMode, Q_PRIMITIVE_TYPE);
class GfeHttpResponseException : public std::exception
{
@@ -124,14 +109,16 @@ public:
NVLL_VERBOSE
};
explicit NvHTTP(QString address, QSslCertificate serverCert);
explicit NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert);
explicit NvHTTP(NvComputer* computer);
static
int
getCurrentGame(QString serverInfo);
QString
getServerInfo(NvLogLevel logLevel);
getServerInfo(NvLogLevel logLevel, bool fastFail = false);
static
void
@@ -156,9 +143,16 @@ public:
void setServerCert(QSslCertificate serverCert);
void setAddress(QString address);
void setAddress(NvAddress address);
void setHttpsPort(uint16_t port);
QString address();
NvAddress address();
QSslCertificate serverCert();
uint16_t httpPort();
uint16_t httpsPort();
static
QVector<int>
@@ -168,14 +162,15 @@ public:
quitApp();
void
resumeApp(PSTREAM_CONFIGURATION streamConfig);
void
launchApp(int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask);
startApp(QString verb,
bool isGfe,
int appId,
PSTREAM_CONFIGURATION streamConfig,
bool sops,
bool localAudio,
int gamepadMask,
bool persistGameControllersOnDisconnect,
QString& rtspSessionUrl);
QVector<NvApp>
getAppList();
@@ -200,7 +195,7 @@ private:
int timeoutMs,
NvLogLevel logLevel);
QString m_Address;
NvAddress m_Address;
QNetworkAccessManager m_Nam;
QSslCertificate m_ServerCert;
};
+67 -41
View File
@@ -1,8 +1,9 @@
#include "nvpairingmanager.h"
#include "utils.h"
#include <stdexcept>
#include <openssl/bio.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
@@ -10,8 +11,8 @@
#define REQUEST_TIMEOUT_MS 5000
NvPairingManager::NvPairingManager(QString address) :
m_Http(address, QSslCertificate())
NvPairingManager::NvPairingManager(NvComputer* computer) :
m_Http(computer)
{
QByteArray cert = IdentityManager::get()->getCertificate();
BIO *bio = BIO_new_mem_buf(cert.data(), -1);
@@ -51,39 +52,63 @@ NvPairingManager::generateRandomBytes(int length)
}
QByteArray
NvPairingManager::encrypt(QByteArray plaintext, AES_KEY* key)
NvPairingManager::encrypt(const QByteArray& plaintext, const QByteArray& key)
{
QByteArray ciphertext(plaintext.size(), 0);
EVP_CIPHER_CTX* cipher;
int ciphertextLen;
for (int i = 0; i < plaintext.size(); i += 16)
{
AES_encrypt(reinterpret_cast<unsigned char*>(&plaintext.data()[i]),
reinterpret_cast<unsigned char*>(&ciphertext.data()[i]),
key);
}
cipher = EVP_CIPHER_CTX_new();
THROW_BAD_ALLOC_IF_NULL(cipher);
EVP_EncryptInit(cipher, EVP_aes_128_ecb(), reinterpret_cast<const unsigned char*>(key.data()), NULL);
EVP_CIPHER_CTX_set_padding(cipher, 0);
EVP_EncryptUpdate(cipher,
reinterpret_cast<unsigned char*>(ciphertext.data()),
&ciphertextLen,
reinterpret_cast<const unsigned char*>(plaintext.data()),
plaintext.length());
Q_ASSERT(ciphertextLen == ciphertext.length());
EVP_CIPHER_CTX_free(cipher);
return ciphertext;
}
QByteArray
NvPairingManager::decrypt(QByteArray ciphertext, AES_KEY* key)
NvPairingManager::decrypt(const QByteArray& ciphertext, const QByteArray& key)
{
QByteArray plaintext(ciphertext.size(), 0);
EVP_CIPHER_CTX* cipher;
int plaintextLen;
for (int i = 0; i < plaintext.size(); i += 16)
{
AES_decrypt(reinterpret_cast<unsigned char*>(&ciphertext.data()[i]),
reinterpret_cast<unsigned char*>(&plaintext.data()[i]),
key);
}
cipher = EVP_CIPHER_CTX_new();
THROW_BAD_ALLOC_IF_NULL(cipher);
EVP_DecryptInit(cipher, EVP_aes_128_ecb(), reinterpret_cast<const unsigned char*>(key.data()), NULL);
EVP_CIPHER_CTX_set_padding(cipher, 0);
EVP_DecryptUpdate(cipher,
reinterpret_cast<unsigned char*>(plaintext.data()),
&plaintextLen,
reinterpret_cast<const unsigned char*>(ciphertext.data()),
ciphertext.length());
Q_ASSERT(plaintextLen == plaintext.length());
EVP_CIPHER_CTX_free(cipher);
return plaintext;
}
QByteArray
NvPairingManager::getSignatureFromPemCert(QByteArray certificate)
NvPairingManager::getSignatureFromPemCert(const QByteArray& certificate)
{
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
BIO* bio = BIO_new_mem_buf(const_cast<char*>(certificate.data()), -1);
#else
BIO* bio = BIO_new_mem_buf(certificate.data(), -1);
#endif
THROW_BAD_ALLOC_IF_NULL(bio);
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
@@ -107,9 +132,13 @@ NvPairingManager::getSignatureFromPemCert(QByteArray certificate)
}
bool
NvPairingManager::verifySignature(QByteArray data, QByteArray signature, QByteArray serverCertificate)
NvPairingManager::verifySignature(const QByteArray& data, const QByteArray& signature, const QByteArray& serverCertificate)
{
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
BIO* bio = BIO_new_mem_buf(const_cast<char*>(serverCertificate.data()), -1);
#else
BIO* bio = BIO_new_mem_buf(serverCertificate.data(), -1);
#endif
THROW_BAD_ALLOC_IF_NULL(bio);
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
@@ -123,7 +152,7 @@ NvPairingManager::verifySignature(QByteArray data, QByteArray signature, QByteAr
EVP_DigestVerifyInit(mdctx, nullptr, EVP_sha256(), nullptr, pubKey);
EVP_DigestVerifyUpdate(mdctx, data.data(), data.length());
int result = EVP_DigestVerifyFinal(mdctx, reinterpret_cast<unsigned char*>(signature.data()), signature.length());
int result = EVP_DigestVerifyFinal(mdctx, reinterpret_cast<unsigned char*>(const_cast<char*>(signature.data())), signature.length());
EVP_PKEY_free(pubKey);
EVP_MD_CTX_destroy(mdctx);
@@ -133,17 +162,13 @@ NvPairingManager::verifySignature(QByteArray data, QByteArray signature, QByteAr
}
QByteArray
NvPairingManager::signMessage(QByteArray message)
NvPairingManager::signMessage(const QByteArray& message)
{
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
THROW_BAD_ALLOC_IF_NULL(ctx);
const EVP_MD *md = EVP_get_digestbyname("SHA256");
THROW_BAD_ALLOC_IF_NULL(md);
EVP_DigestInit_ex(ctx, md, NULL);
EVP_DigestSignInit(ctx, NULL, md, NULL, m_PrivateKey);
EVP_DigestSignUpdate(ctx, reinterpret_cast<unsigned char*>(message.data()), message.length());
EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, m_PrivateKey);
EVP_DigestSignUpdate(ctx, reinterpret_cast<unsigned char*>(const_cast<char*>(message.data())), message.length());
size_t signatureLength = 0;
EVP_DigestSignFinal(ctx, NULL, &signatureLength);
@@ -157,7 +182,7 @@ NvPairingManager::signMessage(QByteArray message)
}
QByteArray
NvPairingManager::saltPin(QByteArray salt, QString pin)
NvPairingManager::saltPin(const QByteArray& salt, QString pin)
{
return QByteArray().append(salt).append(pin.toLatin1());
}
@@ -186,9 +211,8 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
QByteArray salt = generateRandomBytes(16);
QByteArray saltedPin = saltPin(salt, pin);
AES_KEY encKey, decKey;
AES_set_decrypt_key(reinterpret_cast<const unsigned char*>(QCryptographicHash::hash(saltedPin, hashAlgo).data()), 128, &decKey);
AES_set_encrypt_key(reinterpret_cast<const unsigned char*>(QCryptographicHash::hash(saltedPin, hashAlgo).data()), 128, &encKey);
QByteArray aesKey = QCryptographicHash::hash(saltedPin, hashAlgo).constData();
aesKey.truncate(16);
QString getCert = m_Http.openConnectionToString(m_Http.m_BaseUrlHttp,
"pair",
@@ -210,20 +234,21 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
return PairState::ALREADY_IN_PROGRESS;
}
serverCert = QSslCertificate(serverCertStr);
if (serverCert.isNull()) {
Q_ASSERT(!serverCert.isNull());
QSslCertificate unverifiedServerCert = QSslCertificate(serverCertStr);
if (unverifiedServerCert.isNull()) {
Q_ASSERT(!unverifiedServerCert.isNull());
qCritical() << "Failed to parse plaincert";
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
return PairState::FAILED;
}
// Pin this cert for TLS
m_Http.setServerCert(serverCert);
// Pin this cert for TLS until pairing is complete. If successful, we will propagate
// the cert into the NvComputer object and persist it.
m_Http.setServerCert(unverifiedServerCert);
QByteArray randomChallenge = generateRandomBytes(16);
QByteArray encryptedChallenge = encrypt(randomChallenge, &encKey);
QByteArray encryptedChallenge = encrypt(randomChallenge, aesKey);
QString challengeXml = m_Http.openConnectionToString(m_Http.m_BaseUrlHttp,
"pair",
"devicename=roth&updateState=1&clientchallenge=" +
@@ -237,7 +262,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
return PairState::FAILED;
}
QByteArray challengeResponseData = decrypt(m_Http.getXmlStringFromHex(challengeXml, "challengeresponse"), &decKey);
QByteArray challengeResponseData = decrypt(m_Http.getXmlStringFromHex(challengeXml, "challengeresponse"), aesKey);
QByteArray clientSecretData = generateRandomBytes(16);
QByteArray challengeResponse;
QByteArray serverResponse(challengeResponseData.data(), hashLength);
@@ -258,7 +283,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
QByteArray paddedHash = QCryptographicHash::hash(challengeResponse, hashAlgo);
paddedHash.resize(32);
QByteArray encryptedChallengeResponseHash = encrypt(paddedHash, &encKey);
QByteArray encryptedChallengeResponseHash = encrypt(paddedHash, aesKey);
QString respXml = m_Http.openConnectionToString(m_Http.m_BaseUrlHttp,
"pair",
"devicename=roth&updateState=1&serverchallengeresp=" +
@@ -273,8 +298,8 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
}
QByteArray pairingSecret = NvHTTP::getXmlStringFromHex(respXml, "pairingsecret");
QByteArray serverSecret = QByteArray(pairingSecret.data(), 16);
QByteArray serverSignature = QByteArray(&pairingSecret.data()[16], 256);
QByteArray serverSecret = pairingSecret.left(16);
QByteArray serverSignature = pairingSecret.mid(16);
if (!verifySignature(serverSecret,
serverSignature,
@@ -325,5 +350,6 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
return PairState::FAILED;
}
serverCert = std::move(unverifiedServerCert);
return PairState::PAIRED;
}
+7 -8
View File
@@ -3,7 +3,6 @@
#include "identitymanager.h"
#include "nvhttp.h"
#include <openssl/aes.h>
#include <openssl/x509.h>
#include <openssl/evp.h>
@@ -18,7 +17,7 @@ public:
ALREADY_IN_PROGRESS
};
explicit NvPairingManager(QString address);
explicit NvPairingManager(NvComputer* computer);
~NvPairingManager();
@@ -30,22 +29,22 @@ private:
generateRandomBytes(int length);
QByteArray
saltPin(QByteArray salt, QString pin);
saltPin(const QByteArray& salt, QString pin);
QByteArray
encrypt(QByteArray plaintext, AES_KEY* key);
encrypt(const QByteArray& plaintext, const QByteArray& key);
QByteArray
decrypt(QByteArray ciphertext, AES_KEY* key);
decrypt(const QByteArray& ciphertext, const QByteArray& key);
QByteArray
getSignatureFromPemCert(QByteArray certificate);
getSignatureFromPemCert(const QByteArray& certificate);
bool
verifySignature(QByteArray data, QByteArray signature, QByteArray serverCertificate);
verifySignature(const QByteArray& data, const QByteArray& signature, const QByteArray& serverCertificate);
QByteArray
signMessage(QByteArray message);
signMessage(const QByteArray& message);
NvHTTP m_Http;
X509* m_Cert;
+4
View File
@@ -21,8 +21,12 @@ RichPresenceManager::RichPresenceManager(StreamingPreferences& prefs, QString ga
DiscordRichPresence discordPresence = {};
discordPresence.state = stateStr.data();
discordPresence.startTimestamp = time(nullptr);
discordPresence.largeImageKey = "icon";
Discord_UpdatePresence(&discordPresence);
}
#else
Q_UNUSED(prefs)
Q_UNUSED(gameName)
#endif
}
+179 -52
View File
@@ -1,26 +1,64 @@
#include "systemproperties.h"
#include "utils.h"
#include <QGuiApplication>
#include <QLibraryInfo>
#include "streaming/session.h"
#include "streaming/streamutils.h"
#ifdef Q_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
SystemProperties::SystemProperties()
{
isRunningWayland = qgetenv("XDG_SESSION_TYPE") == "wayland";
isRunningXWayland = qgetenv("XDG_SESSION_TYPE") == "wayland" && QGuiApplication::platformName() == "xcb";
versionString = QString(VERSION_STR);
hasDesktopEnvironment = WMUtils::isRunningDesktopEnvironment();
isRunningWayland = WMUtils::isRunningWayland();
isRunningXWayland = isRunningWayland && QGuiApplication::platformName() == "xcb";
usesMaterial3Theme = QLibraryInfo::version() >= QVersionNumber(6, 5, 0);
QString nativeArch = QSysInfo::currentCpuArchitecture();
#ifdef Q_OS_WIN32
isWow64 = QSysInfo::currentCpuArchitecture() != QSysInfo::buildCpuArchitecture();
{
USHORT processArch, machineArch;
// Use IsWow64Process2 on TH2 and later, because it supports ARM64
auto fnIsWow64Process2 = (decltype(IsWow64Process2)*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process2");
if (fnIsWow64Process2 != nullptr && fnIsWow64Process2(GetCurrentProcess(), &processArch, &machineArch)) {
switch (machineArch) {
case IMAGE_FILE_MACHINE_I386:
nativeArch = "i386";
break;
case IMAGE_FILE_MACHINE_AMD64:
nativeArch = "x86_64";
break;
case IMAGE_FILE_MACHINE_ARM64:
nativeArch = "arm64";
break;
}
}
isWow64 = nativeArch != QSysInfo::buildCpuArchitecture();
}
#else
isWow64 = false;
#endif
#ifndef STEAM_LINK
hasBrowser = true;
#else
hasBrowser = false;
#endif
if (nativeArch == "i386") {
friendlyNativeArchName = "x86";
}
else if (nativeArch == "x86_64") {
friendlyNativeArchName = "x64";
}
else {
friendlyNativeArchName = nativeArch.toUpper();
}
// Assume we can probably launch a browser if we're in a GUI environment
hasBrowser = hasDesktopEnvironment;
#ifdef HAVE_DISCORD
hasDiscordIntegration = true;
@@ -34,15 +72,9 @@ SystemProperties::SystemProperties()
// and cache the results to speed up future queries on this data.
querySdlVideoInfo();
Q_ASSERT(maximumStreamingFrameRate >= 60);
Q_ASSERT(!monitorDesktopResolutions.isEmpty());
Q_ASSERT(!monitorRefreshRates.isEmpty());
Q_ASSERT(!monitorNativeResolutions.isEmpty());
}
QRect SystemProperties::getDesktopResolution(int displayIndex)
{
// Returns default constructed QRect if out of bounds
return monitorDesktopResolutions.value(displayIndex);
Q_ASSERT(!monitorSafeAreaResolutions.isEmpty());
}
QRect SystemProperties::getNativeResolution(int displayIndex)
@@ -51,14 +83,50 @@ QRect SystemProperties::getNativeResolution(int displayIndex)
return monitorNativeResolutions.value(displayIndex);
}
QRect SystemProperties::getSafeAreaResolution(int displayIndex)
{
// Returns default constructed QRect if out of bounds
return monitorSafeAreaResolutions.value(displayIndex);
}
int SystemProperties::getRefreshRate(int displayIndex)
{
// Returns 0 if out of bounds
return monitorRefreshRates.value(displayIndex);
}
class QuerySdlVideoThread : public QThread
{
public:
QuerySdlVideoThread(SystemProperties* me) :
QThread(nullptr),
m_Me(me) {}
void run() override
{
m_Me->querySdlVideoInfoInternal();
}
SystemProperties* m_Me;
};
void SystemProperties::querySdlVideoInfo()
{
monitorDesktopResolutions.clear();
monitorNativeResolutions.clear();
hasHardwareAcceleration = false;
if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) {
// Use a separate thread to temporarily initialize SDL
// video to avoid stomping on Qt's X11 and OGL state.
QuerySdlVideoThread thread(this);
thread.start();
thread.wait();
}
else {
querySdlVideoInfoInternal();
}
}
// Never let the maximum drop below 60 FPS
maximumStreamingFrameRate = 60;
void SystemProperties::querySdlVideoInfoInternal()
{
hasHardwareAcceleration = false;
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
@@ -67,23 +135,89 @@ void SystemProperties::querySdlVideoInfo()
return;
}
// Update display related attributes (max FPS, native resolution, etc).
// We call the internal variant because we're already in a safe thread context.
refreshDisplaysInternal();
SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720,
SDL_WINDOW_HIDDEN | StreamUtils::getPlatformWindowFlags());
if (!testWindow) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create test window with platform flags: %s",
SDL_GetError());
testWindow = SDL_CreateWindow("", 0, 0, 1280, 720, SDL_WINDOW_HIDDEN);
if (!testWindow) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create window for hardware decode test: %s",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return;
}
}
Session::getDecoderInfo(testWindow, hasHardwareAcceleration, rendererAlwaysFullScreen, supportsHdr, maximumResolution);
SDL_DestroyWindow(testWindow);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
class RefreshDisplaysThread : public QThread
{
public:
RefreshDisplaysThread(SystemProperties* me) :
QThread(nullptr),
m_Me(me) {}
void run() override
{
m_Me->refreshDisplaysInternal();
}
SystemProperties* m_Me;
};
void SystemProperties::refreshDisplays()
{
if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) {
// Use a separate thread to temporarily initialize SDL
// video to avoid stomping on Qt's X11 and OGL state.
RefreshDisplaysThread thread(this);
thread.start();
thread.wait();
}
else {
refreshDisplaysInternal();
}
}
void SystemProperties::refreshDisplaysInternal()
{
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s",
SDL_GetError());
return;
}
monitorNativeResolutions.clear();
SDL_DisplayMode bestMode;
for (int displayIndex = 0; displayIndex < SDL_GetNumVideoDisplays(); displayIndex++) {
SDL_DisplayMode desktopMode;
int err;
SDL_Rect safeArea;
err = SDL_GetDesktopDisplayMode(displayIndex, &desktopMode);
if (err == 0) {
monitorDesktopResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h));
}
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetDesktopDisplayMode() failed: %s",
SDL_GetError());
}
if (StreamUtils::getRealDesktopMode(displayIndex, &desktopMode)) {
monitorNativeResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h));
if (StreamUtils::getNativeDesktopMode(displayIndex, &desktopMode, &safeArea)) {
if (desktopMode.w <= 8192 && desktopMode.h <= 8192) {
monitorNativeResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h));
monitorSafeAreaResolutions.insert(displayIndex, QRect(0, 0, safeArea.w, safeArea.h));
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Skipping resolution over 8K: %dx%d",
desktopMode.w, desktopMode.h);
}
// Start at desktop mode and work our way up
bestMode = desktopMode;
@@ -98,26 +232,19 @@ void SystemProperties::querySdlVideoInfo()
}
}
maximumStreamingFrameRate = qMax(maximumStreamingFrameRate, bestMode.refresh_rate);
// Try to normalize values around our our standard refresh rates.
// Some displays/OSes report values that are slightly off.
if (bestMode.refresh_rate >= 58 && bestMode.refresh_rate <= 62) {
monitorRefreshRates.append(60);
}
else if (bestMode.refresh_rate >= 28 && bestMode.refresh_rate <= 32) {
monitorRefreshRates.append(30);
}
else {
monitorRefreshRates.append(bestMode.refresh_rate);
}
}
}
SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720, SDL_WINDOW_HIDDEN);
if (!testWindow) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create window for hardware decode test: %s",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return;
}
hasHardwareAcceleration =
Session::isHardwareDecodeAvailable(testWindow,
StreamingPreferences::VDS_AUTO,
VIDEO_FORMAT_H264,
1920, 1080, 60);
SDL_DestroyWindow(testWindow);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
+24 -4
View File
@@ -7,36 +7,56 @@ class SystemProperties : public QObject
{
Q_OBJECT
friend class QuerySdlVideoThread;
friend class RefreshDisplaysThread;
public:
SystemProperties();
Q_PROPERTY(bool hasHardwareAcceleration MEMBER hasHardwareAcceleration CONSTANT)
Q_PROPERTY(bool rendererAlwaysFullScreen MEMBER rendererAlwaysFullScreen CONSTANT)
Q_PROPERTY(bool isRunningWayland MEMBER isRunningWayland CONSTANT)
Q_PROPERTY(bool isRunningXWayland MEMBER isRunningXWayland CONSTANT)
Q_PROPERTY(bool isWow64 MEMBER isWow64 CONSTANT)
Q_PROPERTY(QString friendlyNativeArchName MEMBER friendlyNativeArchName CONSTANT)
Q_PROPERTY(bool hasDesktopEnvironment MEMBER hasDesktopEnvironment CONSTANT)
Q_PROPERTY(bool hasBrowser MEMBER hasBrowser CONSTANT)
Q_PROPERTY(bool hasDiscordIntegration MEMBER hasDiscordIntegration CONSTANT)
Q_PROPERTY(QString unmappedGamepads MEMBER unmappedGamepads NOTIFY unmappedGamepadsChanged)
Q_PROPERTY(int maximumStreamingFrameRate MEMBER maximumStreamingFrameRate CONSTANT)
Q_PROPERTY(QSize maximumResolution MEMBER maximumResolution CONSTANT)
Q_PROPERTY(QString versionString MEMBER versionString CONSTANT)
Q_PROPERTY(bool supportsHdr MEMBER supportsHdr CONSTANT)
Q_PROPERTY(bool usesMaterial3Theme MEMBER usesMaterial3Theme CONSTANT)
Q_INVOKABLE QRect getDesktopResolution(int displayIndex);
Q_INVOKABLE void refreshDisplays();
Q_INVOKABLE QRect getNativeResolution(int displayIndex);
Q_INVOKABLE QRect getSafeAreaResolution(int displayIndex);
Q_INVOKABLE int getRefreshRate(int displayIndex);
signals:
void unmappedGamepadsChanged();
private:
void querySdlVideoInfo();
void querySdlVideoInfoInternal();
void refreshDisplaysInternal();
bool hasHardwareAcceleration;
bool rendererAlwaysFullScreen;
bool isRunningWayland;
bool isRunningXWayland;
bool isWow64;
QString friendlyNativeArchName;
bool hasDesktopEnvironment;
bool hasBrowser;
bool hasDiscordIntegration;
QString unmappedGamepads;
int maximumStreamingFrameRate;
QList<QRect> monitorDesktopResolutions;
QSize maximumResolution;
QList<QRect> monitorNativeResolutions;
QList<QRect> monitorSafeAreaResolutions;
QList<int> monitorRefreshRates;
QString versionString;
bool supportsHdr;
bool usesMaterial3Theme;
};
+203 -21
View File
@@ -52,7 +52,7 @@ public:
void handleUnknownOptions()
{
if (unknownOptionNames().length()) {
if (!unknownOptionNames().isEmpty()) {
showError(QString("Unknown options: %1").arg(unknownOptionNames().join(", ")));
}
}
@@ -164,28 +164,45 @@ GlobalCommandLineParser::ParseResult GlobalCommandLineParser::parse(const QStrin
"Starts Moonlight normally if no arguments are given.\n"
"\n"
"Available actions:\n"
" list List the available apps on a host\n"
" quit Quit the currently running app\n"
" stream Start streaming an app\n"
" pair Pair a new host\n"
"\n"
"See 'moonlight <action> --help' for help of specific action."
);
parser.addPositionalArgument("action", "Action to execute", "<action>");
parser.parse(args);
auto posArgs = parser.positionalArguments();
QString action = posArgs.isEmpty() ? QString() : posArgs.first().toLower();
if (action == "") {
if (posArgs.isEmpty()) {
// This method will not return and terminates the process if --version
// or --help is specified
parser.handleHelpAndVersionOptions();
parser.handleUnknownOptions();
return NormalStartRequested;
} else if (action == "quit") {
return QuitRequested;
} else if (action == "stream") {
return StreamRequested;
} else {
parser.showError(QString("Invalid action: %1").arg(action));
}
else {
// If users supply arguments that accept values prior to the "quit"
// or "stream" positional arguments, we will not be able to correctly
// parse the value out of the input because this QCommandLineParser
// doesn't know about all of the options that "quit" and "stream"
// commands can accept. To work around this issue, we just look
// for "quit" or "stream" positional arguments anywhere.
for (int i = 0; i < posArgs.size(); i++) {
QString action = posArgs.at(i).toLower();
if (action == "quit") {
return QuitRequested;
} else if (action == "stream") {
return StreamRequested;
} else if (action == "pair") {
return PairRequested;
} else if (action == "list") {
return ListRequested;
}
}
parser.showError(QString("Invalid action"));
}
}
@@ -231,6 +248,58 @@ QString QuitCommandLineParser::getHost() const
return m_Host;
}
PairCommandLineParser::PairCommandLineParser()
{
}
PairCommandLineParser::~PairCommandLineParser()
{
}
void PairCommandLineParser::parse(const QStringList &args)
{
CommandLineParser parser;
parser.setupCommonOptions();
parser.setApplicationDescription(
"\n"
"Pair with the specified host."
);
parser.addPositionalArgument("pair", "pair host");
parser.addPositionalArgument("host", "Host computer name, UUID, or IP address", "<host>");
parser.addValueOption("pin", "4 digit pairing PIN");
if (!parser.parse(args)) {
parser.showError(parser.errorText());
}
parser.handleUnknownOptions();
// This method will not return and terminates the process if --version or
// --help is specified
parser.handleHelpAndVersionOptions();
// Verify that host has been provided
auto posArgs = parser.positionalArguments();
if (posArgs.length() < 2) {
parser.showError("Host not provided");
}
m_Host = parser.positionalArguments().at(1);
m_PredefinedPin = parser.value("pin");
if (!m_PredefinedPin.isEmpty() && m_PredefinedPin.length() != 4) {
parser.showError("PIN must be 4 digits");
}
}
QString PairCommandLineParser::getHost() const
{
return m_Host;
}
QString PairCommandLineParser::getPredefinedPin() const
{
return m_PredefinedPin;
}
StreamCommandLineParser::StreamCommandLineParser()
{
m_WindowModeMap = {
@@ -241,16 +310,23 @@ StreamCommandLineParser::StreamCommandLineParser()
m_AudioConfigMap = {
{"stereo", StreamingPreferences::AC_STEREO},
{"5.1-surround", StreamingPreferences::AC_51_SURROUND},
{"7.1-surround", StreamingPreferences::AC_71_SURROUND},
};
m_VideoCodecMap = {
{"auto", StreamingPreferences::VCC_AUTO},
{"H.264", StreamingPreferences::VCC_FORCE_H264},
{"HEVC", StreamingPreferences::VCC_FORCE_HEVC},
{"AV1", StreamingPreferences::VCC_FORCE_AV1},
};
m_VideoDecoderMap = {
{"auto", StreamingPreferences::VDS_AUTO},
{"software", StreamingPreferences::VDS_FORCE_HARDWARE},
{"hardware", StreamingPreferences::VDS_FORCE_SOFTWARE},
{"software", StreamingPreferences::VDS_FORCE_SOFTWARE},
{"hardware", StreamingPreferences::VDS_FORCE_HARDWARE},
};
m_CaptureSysKeysModeMap = {
{"never", StreamingPreferences::CSK_OFF},
{"fullscreen", StreamingPreferences::CSK_FULLSCREEN},
{"always", StreamingPreferences::CSK_ALWAYS},
};
}
@@ -280,14 +356,25 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
parser.addToggleOption("vsync", "V-Sync");
parser.addValueOption("fps", "FPS");
parser.addValueOption("bitrate", "bitrate in Kbps");
parser.addValueOption("packet-size", "video packet size");
parser.addChoiceOption("display-mode", "display mode", m_WindowModeMap.keys());
parser.addChoiceOption("audio-config", "audio config", m_AudioConfigMap.keys());
parser.addToggleOption("multi-controller", "multiple controller support");
parser.addToggleOption("quit-after", "quit app after session");
parser.addToggleOption("mouse-acceleration", "mouse acceleration");
parser.addToggleOption("absolute-mouse", "remote desktop optimized mouse control");
parser.addToggleOption("mouse-buttons-swap", "left and right mouse buttons swap");
parser.addToggleOption("touchscreen-trackpad", "touchscreen in trackpad mode");
parser.addToggleOption("game-optimization", "game optimizations");
parser.addToggleOption("audio-on-host", "audio on host PC");
parser.addToggleOption("frame-pacing", "frame pacing");
parser.addToggleOption("mute-on-focus-loss", "mute audio when Moonlight window loses focus");
parser.addToggleOption("background-gamepad", "background gamepad input");
parser.addToggleOption("reverse-scroll-direction", "inverted scroll direction");
parser.addToggleOption("swap-gamepad-buttons", "swap A/B and X/Y gamepad buttons (Nintendo-style)");
parser.addToggleOption("keep-awake", "prevent display sleep while streaming");
parser.addToggleOption("performance-overlay", "show performance overlay");
parser.addToggleOption("hdr", "HDR streaming");
parser.addChoiceOption("capture-system-keys", "capture system key combos", m_CaptureSysKeysModeMap.keys());
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
@@ -300,25 +387,21 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve display's width and height
QRegularExpression resolutionRexExp("^(720|1080|1440|4K|resolution)$");
QStringList resoOptions = parser.optionNames().filter(resolutionRexExp);
bool displaySet = resoOptions.length();
bool displaySet = !resoOptions.isEmpty();
if (displaySet) {
QString name = resoOptions.last();
if (name == "720") {
preferences->width = 1280;
preferences->height = 720;
displaySet = true;
} else if (name == "1080") {
preferences->width = 1920;
preferences->height = 1080;
displaySet = true;
} else if (name == "1440") {
preferences->width = 2560;
preferences->height = 1440;
displaySet = true;
} else if (name == "4K") {
preferences->width = 3840;
preferences->height = 2160;
displaySet = true;
} else if (name == "resolution") {
auto resolution = parser.getResolutionOptionValue(name);
preferences->width = resolution.first;
@@ -329,8 +412,8 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve --fps option
if (parser.isSet("fps")) {
preferences->fps = parser.getIntOption("fps");
if (!inRange(preferences->fps, 30, 120)) {
parser.showError("FPS must be in range: 30 - 120");
if (!inRange(preferences->fps, 30, 240)) {
parser.showError("FPS must be in range: 30 - 240");
}
}
@@ -345,6 +428,14 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
preferences->width, preferences->height, preferences->fps);
}
// Resolve --packet-size option
if (parser.isSet("packet-size")) {
preferences->packetSize = parser.getIntOption("packet-size");
if (preferences->packetSize < 1024) {
parser.showError("Packet size must be greater than 1024 bytes");
}
}
// Resolve --display option
if (parser.isSet("display-mode")) {
preferences->windowMode = mapValue(m_WindowModeMap, parser.getChoiceOptionValue("display-mode"));
@@ -364,8 +455,14 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve --quit-after and --no-quit-after options
preferences->quitAppAfter = parser.getToggleOptionValue("quit-after", preferences->quitAppAfter);
// Resolve --mouse-acceleration and --no-mouse-acceleration options
preferences->mouseAcceleration = parser.getToggleOptionValue("mouse-acceleration", preferences->mouseAcceleration);
// Resolve --absolute-mouse and --no-absolute-mouse options
preferences->absoluteMouseMode = parser.getToggleOptionValue("absolute-mouse", preferences->absoluteMouseMode);
// Resolve --mouse-buttons-swap and --no-mouse-buttons-swap options
preferences->swapMouseButtons = parser.getToggleOptionValue("mouse-buttons-swap", preferences->swapMouseButtons);
// Resolve --touchscreen-trackpad and --no-touchscreen-trackpad options
preferences->absoluteTouchMode = !parser.getToggleOptionValue("touchscreen-trackpad", !preferences->absoluteTouchMode);
// Resolve --game-optimization and --no-game-optimization options
preferences->gameOptimizations = parser.getToggleOptionValue("game-optimization", preferences->gameOptimizations);
@@ -376,6 +473,32 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve --frame-pacing and --no-frame-pacing options
preferences->framePacing = parser.getToggleOptionValue("frame-pacing", preferences->framePacing);
// Resolve --mute-on-focus-loss and --no-mute-on-focus-loss options
preferences->muteOnFocusLoss = parser.getToggleOptionValue("mute-on-focus-loss", preferences->muteOnFocusLoss);
// Resolve --background-gamepad and --no-background-gamepad options
preferences->backgroundGamepad = parser.getToggleOptionValue("background-gamepad", preferences->backgroundGamepad);
// Resolve --reverse-scroll-direction and --no-reverse-scroll-direction options
preferences->reverseScrollDirection = parser.getToggleOptionValue("reverse-scroll-direction", preferences->reverseScrollDirection);
// Resolve --swap-gamepad-buttons and --no-swap-gamepad-buttons options
preferences->swapFaceButtons = parser.getToggleOptionValue("swap-gamepad-buttons", preferences->swapFaceButtons);
// Resolve --keep-awake and --no-keep-awake options
preferences->keepAwake = parser.getToggleOptionValue("keep-awake", preferences->keepAwake);
// Resolve --performance-overlay and --no-performance-overlay options
preferences->showPerformanceOverlay = parser.getToggleOptionValue("performance-overlay", preferences->showPerformanceOverlay);
// Resolve --hdr and --no-hdr options
preferences->enableHdr = parser.getToggleOptionValue("hdr", preferences->enableHdr);
// Resolve --capture-system-keys option
if (parser.isSet("capture-system-keys")) {
preferences->captureSysKeysMode = mapValue(m_CaptureSysKeysModeMap, parser.getChoiceOptionValue("capture-system-keys"));
}
// Resolve --video-codec option
if (parser.isSet("video-codec")) {
preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec"));
@@ -412,3 +535,62 @@ QString StreamCommandLineParser::getAppName() const
{
return m_AppName;
}
ListCommandLineParser::ListCommandLineParser()
{
}
ListCommandLineParser::~ListCommandLineParser()
{
}
void ListCommandLineParser::parse(const QStringList &args)
{
CommandLineParser parser;
parser.setupCommonOptions();
parser.setApplicationDescription(
"\n"
"List the available apps on the given host."
);
parser.addPositionalArgument("list", "list available apps");
parser.addPositionalArgument("host", "Host computer name, UUID, or IP address", "<host>");
parser.addFlagOption("csv", "Print as CSV with additional information");
parser.addFlagOption("verbose", "Displays additional information");
if (!parser.parse(args)) {
parser.showError(parser.errorText());
}
parser.handleUnknownOptions();
m_PrintCSV = parser.isSet("csv");
m_Verbose = parser.isSet("verbose");
// This method will not return and terminates the process if --version or
// --help is specified
parser.handleHelpAndVersionOptions();
// Verify that host has been provided
auto posArgs = parser.positionalArguments();
if (posArgs.length() < 2) {
parser.showError("Host not provided");
}
m_Host = parser.positionalArguments().at(1);
}
QString ListCommandLineParser::getHost() const
{
return m_Host;
}
bool ListCommandLineParser::isPrintCSV() const
{
return m_PrintCSV;
}
bool ListCommandLineParser::isVerbose() const
{
return m_Verbose;
}
+37
View File
@@ -12,6 +12,8 @@ public:
NormalStartRequested,
StreamRequested,
QuitRequested,
PairRequested,
ListRequested,
};
GlobalCommandLineParser();
@@ -35,6 +37,22 @@ private:
QString m_Host;
};
class PairCommandLineParser
{
public:
PairCommandLineParser();
virtual ~PairCommandLineParser();
void parse(const QStringList &args);
QString getHost() const;
QString getPredefinedPin() const;
private:
QString m_Host;
QString m_PredefinedPin;
};
class StreamCommandLineParser
{
public:
@@ -53,4 +71,23 @@ private:
QMap<QString, StreamingPreferences::AudioConfig> m_AudioConfigMap;
QMap<QString, StreamingPreferences::VideoCodecConfig> m_VideoCodecMap;
QMap<QString, StreamingPreferences::VideoDecoderSelection> m_VideoDecoderMap;
QMap<QString, StreamingPreferences::CaptureSysKeysMode> m_CaptureSysKeysModeMap;
};
class ListCommandLineParser
{
public:
ListCommandLineParser();
virtual ~ListCommandLineParser();
void parse(const QStringList &args);
QString getHost() const;
bool isPrintCSV() const;
bool isVerbose() const;
private:
QString m_Host;
bool m_PrintCSV;
bool m_Verbose;
};
+208
View File
@@ -0,0 +1,208 @@
#include "listapps.h"
#include "backend/boxartmanager.h"
#include "backend/computermanager.h"
#include "backend/computerseeker.h"
#include <QCoreApplication>
#include <QTimer>
#define COMPUTER_SEEK_TIMEOUT 10000
#define APP_SEEK_TIMEOUT 10000
namespace CliListApps
{
enum State {
StateInit,
StateSeekComputer,
StateListApp,
StateSeekApp,
StateFailure,
};
class Event
{
public:
enum Type {
ComputerFound,
ComputerUpdated,
ComputerSeekTimedout,
Executed,
};
Event(Type type)
: type(type), computerManager(nullptr), computer(nullptr) {}
Type type;
ComputerManager *computerManager;
NvComputer *computer;
QString errorMessage;
};
class LauncherPrivate
{
Q_DECLARE_PUBLIC(Launcher)
public:
LauncherPrivate(Launcher *q) : q_ptr(q) {}
void handleEvent(Event event)
{
Q_Q(Launcher);
NvApp app;
switch (event.type) {
// Occurs when CLI main calls execute
case Event::Executed:
if (m_State == StateInit) {
m_State = StateSeekComputer;
m_ComputerManager = event.computerManager;
m_ComputerSeeker = new ComputerSeeker(m_ComputerManager, m_ComputerName, q);
q->connect(m_ComputerSeeker, &ComputerSeeker::computerFound,
q, &Launcher::onComputerFound);
q->connect(m_ComputerSeeker, &ComputerSeeker::errorTimeout,
q, &Launcher::onComputerSeekTimeout);
m_ComputerSeeker->start(COMPUTER_SEEK_TIMEOUT);
q->connect(m_ComputerManager, &ComputerManager::computerStateChanged,
q, &Launcher::onComputerUpdated);
m_BoxArtManager = new BoxArtManager(q);
if (m_Arguments.isVerbose()) {
fprintf(stdout, "Establishing connection to PC...\n");
}
}
break;
// Occurs when computer search timed out
case Event::ComputerSeekTimedout:
if (m_State == StateSeekComputer) {
fprintf(stderr, "%s\n", qPrintable(QString("Failed to connect to %1").arg(m_ComputerName)));
QCoreApplication::exit(-1);
}
break;
// Occurs when searched computer is found
case Event::ComputerFound:
if (m_State == StateSeekComputer) {
if (event.computer->pairState == NvComputer::PS_PAIRED) {
m_State = StateSeekApp;
m_Computer = event.computer;
m_TimeoutTimer->start(APP_SEEK_TIMEOUT);
if (m_Arguments.isVerbose()) {
fprintf(stdout, "Loading app list...\n");
}
} else {
m_State = StateFailure;
fprintf(stderr, "%s\n", qPrintable(QObject::tr("Computer %1 has not been paired. "
"Please open Moonlight to pair before retrieving games list.")
.arg(event.computer->name)));
QCoreApplication::exit(-1);
}
}
break;
// Occurs when a computer is updated
case Event::ComputerUpdated:
if (m_State == StateSeekApp) {
m_Arguments.isPrintCSV() ? printAppsCSV(m_Computer->appList) : printApps(m_Computer->appList);
QCoreApplication::exit(0);
}
break;
}
}
void printApps(QVector<NvApp> apps) {
for (int i = 0; i < apps.length(); i++) {
fprintf(stdout, "%s\n", qPrintable(apps[i].name));
}
}
void printAppsCSV(QVector<NvApp> apps) {
fprintf(stdout, "Name, ID, HDR Support, App Collection Game, Hidden, Direct Launch, Boxart URL\n");
for (int i = 0; i < apps.length(); i++) {
printAppCSV(apps[i]);
}
}
void printAppCSV(NvApp app) const
{
fprintf(stdout, "\"%s\",%d,%s,%s,%s,%s,\"%s\"\n", qPrintable(app.name),
app.id,
app.hdrSupported ? "true" : "false",
app.isAppCollectorGame ? "true" : "false",
app.hidden ? "true" : "false",
app.directLaunch ? "true" : "false",
qPrintable(m_BoxArtManager->loadBoxArt(m_Computer, app).toDisplayString()));
}
Launcher *q_ptr;
ComputerManager *m_ComputerManager;
QString m_ComputerName;
ComputerSeeker *m_ComputerSeeker;
BoxArtManager *m_BoxArtManager;
NvComputer *m_Computer;
State m_State;
QTimer *m_TimeoutTimer;
ListCommandLineParser m_Arguments;
};
Launcher::Launcher(QString computer, ListCommandLineParser arguments, QObject *parent)
: QObject(parent),
m_DPtr(new LauncherPrivate(this))
{
Q_D(Launcher);
d->m_ComputerName = computer;
d->m_State = StateInit;
d->m_TimeoutTimer = new QTimer(this);
d->m_TimeoutTimer->setSingleShot(true);
d->m_Arguments = arguments;
connect(d->m_TimeoutTimer, &QTimer::timeout,
this, &Launcher::onComputerSeekTimeout);
}
Launcher::~Launcher()
{
}
void Launcher::execute(ComputerManager *manager)
{
Q_D(Launcher);
Event event(Event::Executed);
event.computerManager = manager;
d->handleEvent(event);
}
bool Launcher::isExecuted() const
{
Q_D(const Launcher);
return d->m_State != StateInit;
}
void Launcher::onComputerFound(NvComputer *computer)
{
Q_D(Launcher);
Event event(Event::ComputerFound);
event.computer = computer;
d->handleEvent(event);
}
void Launcher::onComputerSeekTimeout()
{
Q_D(Launcher);
Event event(Event::ComputerSeekTimedout);
d->handleEvent(event);
}
void Launcher::onComputerUpdated(NvComputer *computer)
{
Q_D(Launcher);
Event event(Event::ComputerUpdated);
event.computer = computer;
d->handleEvent(event);
}
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "commandlineparser.h"
#include <QObject>
#include <QVariant>
class ComputerManager;
class NvComputer;
namespace CliListApps
{
class LauncherPrivate;
class Launcher : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE_D(m_DPtr, Launcher)
public:
explicit Launcher(QString computer, ListCommandLineParser arguments, QObject *parent = nullptr);
~Launcher();
Q_INVOKABLE void execute(ComputerManager *manager);
Q_INVOKABLE bool isExecuted() const;
private slots:
void onComputerFound(NvComputer *computer);
void onComputerUpdated(NvComputer *computer);
void onComputerSeekTimeout();
private:
QScopedPointer<LauncherPrivate> m_DPtr;
ListCommandLineParser m_Arguments;
};
}
+181
View File
@@ -0,0 +1,181 @@
#include "pair.h"
#include "backend/computermanager.h"
#include "backend/computerseeker.h"
#include <QCoreApplication>
#include <QTimer>
#define COMPUTER_SEEK_TIMEOUT 10000
namespace CliPair
{
enum State {
StateInit,
StateSeekComputer,
StatePairing,
StateFailure,
StateComplete,
};
class Event
{
public:
enum Type {
ComputerFound,
Executed,
PairingCompleted,
Timedout,
};
Event(Type type)
: type(type), computerManager(nullptr), computer(nullptr) {}
Type type;
ComputerManager *computerManager;
NvComputer *computer;
QString errorMessage;
};
class LauncherPrivate
{
Q_DECLARE_PUBLIC(Launcher)
public:
LauncherPrivate(Launcher *q) : q_ptr(q) {}
void handleEvent(Event event)
{
Q_Q(Launcher);
switch (event.type) {
// Occurs when CliPair becomes visible and the UI calls launcher's execute()
case Event::Executed:
if (m_State == StateInit) {
m_State = StateSeekComputer;
m_ComputerManager = event.computerManager;
q->connect(m_ComputerManager, &ComputerManager::pairingCompleted,
q, &Launcher::onPairingCompleted);
// If we weren't provided a predefined PIN, generate one now
if (m_PredefinedPin.isEmpty()) {
m_PredefinedPin = m_ComputerManager->generatePinString();
}
m_ComputerSeeker = new ComputerSeeker(m_ComputerManager, m_ComputerName, q);
q->connect(m_ComputerSeeker, &ComputerSeeker::computerFound,
q, &Launcher::onComputerFound);
q->connect(m_ComputerSeeker, &ComputerSeeker::errorTimeout,
q, &Launcher::onTimeout);
m_ComputerSeeker->start(COMPUTER_SEEK_TIMEOUT);
emit q->searchingComputer();
}
break;
// Occurs when searched computer is found
case Event::ComputerFound:
if (m_State == StateSeekComputer) {
if (event.computer->pairState == NvComputer::PS_PAIRED) {
m_State = StateFailure;
QString msg = QObject::tr("%1 is already paired").arg(event.computer->name);
emit q->failed(msg);
}
else {
Q_ASSERT(!m_PredefinedPin.isEmpty());
m_State = StatePairing;
m_ComputerManager->pairHost(event.computer, m_PredefinedPin);
emit q->pairing(event.computer->name, m_PredefinedPin);
}
}
break;
// Occurs when pairing operation completes
case Event::PairingCompleted:
if (m_State == StatePairing) {
if (event.errorMessage.isEmpty()) {
m_State = StateComplete;
emit q->success();
}
else {
m_State = StateFailure;
emit q->failed(event.errorMessage);
}
}
break;
// Occurs when computer search timed out
case Event::Timedout:
if (m_State == StateSeekComputer) {
m_State = StateFailure;
emit q->failed(QObject::tr("Failed to connect to %1").arg(m_ComputerName));
}
break;
}
}
Launcher *q_ptr;
QString m_ComputerName;
QString m_PredefinedPin;
ComputerManager *m_ComputerManager;
ComputerSeeker *m_ComputerSeeker;
NvComputer *m_Computer;
State m_State;
QTimer *m_TimeoutTimer;
};
Launcher::Launcher(QString computer, QString predefinedPin, QObject *parent)
: QObject(parent),
m_DPtr(new LauncherPrivate(this))
{
Q_D(Launcher);
d->m_ComputerName = computer;
d->m_PredefinedPin = predefinedPin;
d->m_State = StateInit;
d->m_TimeoutTimer = new QTimer(this);
d->m_TimeoutTimer->setSingleShot(true);
connect(d->m_TimeoutTimer, &QTimer::timeout,
this, &Launcher::onTimeout);
}
Launcher::~Launcher()
{
}
void Launcher::execute(ComputerManager *manager)
{
Q_D(Launcher);
Event event(Event::Executed);
event.computerManager = manager;
d->handleEvent(event);
}
bool Launcher::isExecuted() const
{
Q_D(const Launcher);
return d->m_State != StateInit;
}
void Launcher::onComputerFound(NvComputer *computer)
{
Q_D(Launcher);
Event event(Event::ComputerFound);
event.computer = computer;
d->handleEvent(event);
}
void Launcher::onTimeout()
{
Q_D(Launcher);
Event event(Event::Timedout);
d->handleEvent(event);
}
void Launcher::onPairingCompleted(NvComputer* computer, QString error)
{
Q_D(Launcher);
Event event(Event::PairingCompleted);
event.computer = computer;
event.errorMessage = error;
d->handleEvent(event);
}
}
+44
View File
@@ -0,0 +1,44 @@
#pragma once
#include <QObject>
#include <QVariant>
class ComputerManager;
class NvComputer;
class Session;
class StreamingPreferences;
namespace CliPair
{
class Event;
class LauncherPrivate;
class Launcher : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE_D(m_DPtr, Launcher)
public:
explicit Launcher(QString computer, QString predefinedPin,
QObject *parent = nullptr);
~Launcher();
Q_INVOKABLE void execute(ComputerManager *manager);
Q_INVOKABLE bool isExecuted() const;
signals:
void searchingComputer();
void pairing(QString pcName, QString pin);
void failed(QString text);
void success();
private slots:
void onComputerFound(NvComputer *computer);
void onPairingCompleted(NvComputer *computer, QString error);
void onTimeout();
private:
QScopedPointer<LauncherPrivate> m_DPtr;
};
}
+4 -4
View File
@@ -73,7 +73,7 @@ public:
case Event::ComputerSeekTimedout:
if (m_State == StateSeekComputer) {
m_State = StateFailure;
emit q->failed(QString("Failed to connect to %1").arg(m_ComputerName));
emit q->failed(QObject::tr("Failed to connect to %1").arg(m_ComputerName));
}
break;
// Occurs when searched computer is found
@@ -85,8 +85,8 @@ public:
m_ComputerManager->quitRunningApp(event.computer);
} else {
m_State = StateFailure;
QString msg = QString("Computer %1 has not been paired. "
"Please open Moonlight to pair before streaming.")
QString msg = QObject::tr("Computer %1 has not been paired. "
"Please open Moonlight to pair before streaming.")
.arg(event.computer->name);
emit q->failed(msg);
}
@@ -99,7 +99,7 @@ public:
QCoreApplication::exit(0);
} else {
m_State = StateFailure;
emit q->failed(QString("Quitting app failed, reason: %1").arg(event.errorMessage));
emit q->failed(QObject::tr("Quitting app failed, reason: %1").arg(event.errorMessage));
}
}
break;
+7 -7
View File
@@ -86,8 +86,8 @@ public:
emit q->searchingApp();
} else {
m_State = StateFailure;
QString msg = QString("Computer %1 has not been paired. "
"Please open Moonlight to pair before streaming.")
QString msg = QObject::tr("Computer %1 has not been paired. "
"Please open Moonlight to pair before streaming.")
.arg(event.computer->name);
emit q->failed(msg);
}
@@ -118,23 +118,23 @@ public:
}
break;
// Occurs when the previous app quit has been completed, handles quitting errors if any
// happended. ComputerUpdated event's handler handles session start when previous app has
// happened. ComputerUpdated event's handler handles session start when previous app has
// quit.
case Event::AppQuitCompleted:
if (m_State == StateSeekApp && !event.errorMessage.isEmpty()) {
m_State = StateFailure;
emit q->failed(QString("Quitting app failed, reason: %1").arg(event.errorMessage));
emit q->failed(QObject::tr("Quitting app failed, reason: %1").arg(event.errorMessage));
}
break;
// Occurs when computer or app search timed out
case Event::Timedout:
if (m_State == StateSeekComputer) {
m_State = StateFailure;
emit q->failed(QString("Failed to connect to %1").arg(m_ComputerName));
emit q->failed(QObject::tr("Failed to connect to %1").arg(m_ComputerName));
}
if (m_State == StateSeekApp) {
m_State = StateFailure;
emit q->failed(QString("Failed to find application %1").arg(m_AppName));
emit q->failed(QObject::tr("Failed to find application %1").arg(m_AppName));
}
break;
}
@@ -162,7 +162,7 @@ public:
QString getCurrentAppName() const
{
for (NvApp app : m_Computer->appList) {
for (const NvApp& app : m_Computer->appList) {
if (m_Computer->currentGameId == app.id) {
return app.name;
}
@@ -0,0 +1,40 @@
From 78261eb6e2fe728fa5d3843b5b8962b1ca559b7e Mon Sep 17 00:00:00 2001
From: David Rosca <nowrep@gmail.com>
Date: Sat, 16 Dec 2023 14:52:01 +0100
Subject: [PATCH] Vulkan: Don't try to reuse old swapchain
---
src/vulkan/swapchain.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/vulkan/swapchain.c b/src/vulkan/swapchain.c
index 0646e57c..c0b07ce4 100644
--- a/src/vulkan/swapchain.c
+++ b/src/vulkan/swapchain.c
@@ -612,13 +612,21 @@ static bool vk_sw_recreate(pl_swapchain sw, int w, int h)
}
#endif
+ {
+ pl_gpu_flush(gpu);
+ vk_wait_idle(vk);
+ for (int i = 0; i < vk->pool_graphics->num_queues; i++)
+ vk->QueueWaitIdle(vk->pool_graphics->queues[i]);
+ vk->DestroySwapchainKHR(vk->dev, p->swapchain, PL_VK_ALLOC);
+ }
+
// Calling `vkCreateSwapchainKHR` puts sinfo.oldSwapchain into a retired
// state whether the call succeeds or not, so we always need to garbage
// collect it afterwards - asynchronously as it may still be in use
- sinfo.oldSwapchain = p->swapchain;
+ /* sinfo.oldSwapchain = p->swapchain; */
p->swapchain = VK_NULL_HANDLE;
VkResult res = vk->CreateSwapchainKHR(vk->dev, &sinfo, PL_VK_ALLOC, &p->swapchain);
- vk_dev_callback(vk, VK_CB_FUNC(destroy_swapchain), vk, vk_wrap_handle(sinfo.oldSwapchain));
+ /* vk_dev_callback(vk, VK_CB_FUNC(destroy_swapchain), vk, vk_wrap_handle(sinfo.oldSwapchain)); */
PL_VK_ASSERT(res, "vk->CreateSwapchainKHR(...)");
// Get the new swapchain images
--
2.43.0
@@ -4,18 +4,19 @@
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>Moonlight</name>
<summary>Play games remotely from your NVIDIA GameStream-enabled PC</summary>
<summary>Stream games and other applications from another PC running Sunshine or GeForce Experience</summary>
<description>
<p>Moonlight can stream games and other applications from a PC with an NVIDIA GeForce GTX 600-series or higher GPU and GeForce Experience installed.</p>
<p>Moonlight can stream games and other applications from another PC with Sunshine or GeForce Experience software installed.</p>
<p>Features include:</p>
<ul>
<li>Streaming at up to 4K resolution</li>
<li>Support for up to 120 FPS streaming (high refresh rate monitor recommended)</li>
<li>Hardware accelerated video decoding with VAAPI, VDPAU, and NVDEC support</li>
<li>5.1 surround sound audio support</li>
<li>HEVC support for better video compression efficiency</li>
<li>Gamepad support with force feedback for up to 4 players</li>
<li>H.264, HEVC, and AV1 codec support</li>
<li>7.1 surround sound audio support</li>
<li>10-point multitouch support</li>
<li>Gamepad support with force feedback for up to 16 players</li>
<li>Support for both pointer capture (for games) and direct mouse control (for remote desktop)</li>
<li>Support for passing system-wide keyboard shortcuts like Alt+Tab to the host</li>
</ul>
</description>
@@ -33,6 +34,418 @@
</screenshots>
<releases>
<release version="6.0.0" date="2024-06-06">
<description>
<p>New features:</p>
<ul>
<li>HDR is now supported on Steam Deck and other HDR-capable Linux systems using a new Vulkan-based renderer</li>
<li>Vulkan Video decoding of H.264, HEVC, and AV1 is now supported using the new Vulkan renderer</li>
<li>Full E2E stream encryption is now supported when streaming from Sunshine v0.22 or later</li>
<li>Initiating a stream via the command-line will now automatically wake the target machine if it is sleeping</li>
<li>Error codes are now displayed in the connection termination dialog</li>
<li>Detailed PC state information is now available via the new "View Details" context menu option (similar to the Android client)</li>
<li>The performance overlay can now be configured to be shown by default when starting a stream</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>The selected bitrate is no longer silently adjusted by Moonlight based upon the video codec or HDR mode</li>
<li>The selected mouse mode when starting a stream no longer influences the acceleration curve when the mouse mode is toggled using the Ctrl+Alt+Shift+M key combo while streaming</li>
<li>Hardcoded fallback paths for VAAPI and VDPAU drivers are no longer used</li>
<li>Per-session keys (rikey and rikeyid values) are now automatically stripped from logs</li>
<li>Log messages will now be logged to stderr rather than stdout</li>
<li>EGL is now always used instead of GLX for loading OpenGL in X11 environments on non-x86 platforms</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Improved reliability of streaming during momentary drops of WiFi connections</li>
<li>Improved performance with high polling rate mice</li>
<li>Improved input latency when a gamepad is connected</li>
<li>Added missing command-line options to control HDR and AV1 codec usage</li>
<li>Fixed instant connection termination error when streaming over the Internet behind certain Carrier-Grade NAT devices</li>
<li>Fixed incorrect MTU detection when streaming over the Internet without a VPN</li>
<li>Fixed recovery of audio when no audio output device is present when the stream starts</li>
<li>Fixed merging of gamepad state when multi-controller mode is disabled</li>
<li>Fixed indefinitely resending mDNS queries when a host could not be resolved</li>
<li>Fixed inability to pair when the host is not using a RSA-2048 key</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="5.0.1" date="2023-11-02">
<description>
<p>Bugfixes:</p>
<ul>
<li>Fixed connection issue streaming from some hosts running GeForce Experience or Sunshine v0.20 and earlier</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="5.0.0" date="2023-10-18">
<description>
<p>New features:</p>
<ul>
<li>Custom FPS values</li>
<li>Streaming using the AV1 codec from Sunshine hosts</li>
<li>Horizontal scrolling with Sunshine hosts</li>
<li>Native multi-touch input with Sunshine hosts</li>
<li>Controller type information is passed to Sunshine for controller type autoselection</li>
<li>Extended features of PS4/PS5 controllers (touchpad, battery state, gyro/accelerometer motion, and RGB LED) are natively passed to Sunshine hosts</li>
<li>Support for up to 16 gamepads with Sunshine hosts</li>
<li>Frame pacing support on Wayland</li>
<li>Host-side processing latency is now displayed in the performance overlay with Sunshine hosts</li>
<li>Window title now includes the PC name when streaming</li>
<li>Alphabetical sorting of the PC list</li>
<li>Updated Play and Stop button design to improve contrast with app box art</li>
<li>The settings page automatically scrolls to the selected element when using keyboard or gamepad navigation</li>
<li>Pressing Share+PS buttons on PS4/PS5 controllers can be used to emulate a clickpad press</li>
<li>Improved audio quality when streaming with a high bitrate from remote hosts</li>
<li>Increased mouse polling rate</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>IPv6 addresses must be provided in URL-escaped form. Example: [2001:db8::1234:5678] or [2001:db8::1234:5678]:47989</li>
<li>Default bitrate logic has been adjusted to behave better with custom resolutions and frame rates</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Reduced the frequency of audio underruns (clicks and pops) by increasing audio buffer size</li>
<li>Fixed "Quitting App" message never dismissing in some cases</li>
<li>Fixed parsing IPv6 literals with port numbers</li>
<li>Fixed unnecessary WiFi activity causing stream disruptions</li>
<li>Fixed paired hosts being forgotten if Moonlight terminates while writing hosts to disk</li>
<li>Fixed freeze when closing the stream on Windows with some software that uses DX11 hooks</li>
<li>Fixed delayed PC wake when activating Wake-On-LAN feature</li>
<li>Fixed Wake-on-LAN when Sunshine is running on alternate ports</li>
<li>Fixed leak of /dev/dri fds when trying to initialize VAAPI decoder</li>
<li>Fixed support for the Applications/Menu key</li>
<li>Fixed automatic language detection for Simplified Chinese and Traditional Chinese</li>
<li>Fixed streaming from Sunshine when the client PC has multiple network interfaces or IPv6 privacy extensions enabled</li>
<li>Fixed small receive buffer causing video packet loss on some systems</li>
<li>Fixed theme overrides causing the UI to be unusable on some systems</li>
<li>Fixed tearing with V-Sync enabled on macOS and Linux when using the SDL renderer (software decoding and some hardware decoders)</li>
<li>Fixed stateful V4L2 hardware decoding using h264_v4l2m2m and hevc_v4l2m2m decoders</li>
<li>Fixed CVE-2023-42801</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.3.1" date="2022-11-03">
<description>
<p>Changes:</p>
<ul>
<li>Fixed crash during specific patterns of audio packet loss</li>
<li>Fixed detection of local streaming when using IPv6 addresses</li>
<li>Windowed mode streaming now starts maximized if the GUI window was maximized</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.3.0" date="2022-10-28">
<description>
<p>New features:</p>
<ul>
<li>Improved support for GeForce Experience 3.26</li>
<li>Improved image quality and performance when recovering from video packet loss using HEVC</li>
<li>Improved error concealment after audio packet loss</li>
<li>Improved UI performance when paired with many hosts or hosts with large numbers of apps</li>
<li>Pairing with Sunshine hosts is now supported even if the host is in a streaming session</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed streaming at resolutions below 720x480 with GeForce Experience 3.26</li>
<li>Fixed window position and size being lost when toggling between full-screen and windowed mode</li>
<li>Fixed initial window size not always respecting the stream aspect ratio</li>
<li>Fixed unexpected error when streaming at resolutions above 4096x4096 using Sunshine</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.2.1" date="2022-09-12">
<description>
<p>Bugfixes:</p>
<ul>
<li>Fixed streaming from hosts running Sunshine</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.2.0" date="2022-09-10">
<description>
<p>New features:</p>
<ul>
<li>Added support for pairing via the terminal</li>
<li>Added support for listing installed apps on a host via the terminal</li>
<li>Improved handling of V-Sync on Wayland systems to reduce latency</li>
<li>Improved performance using the legacy non-EGL VAAPI rendering code</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed native resolution detection on high DPI Wayland systems</li>
<li>Fixed audio crackling with SDL 2.24.0 on systems using PulseAudio</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.1.0" date="2022-05-23">
<description>
<p>New features:</p>
<ul>
<li>Overlays are now supported on the non-EGL X11 VAAPI renderer (requires RGBA subpicture support in the VAAPI driver)</li>
<li>Cursor lock can now be disabled when in full-screen mode</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>Moonlight can now reduce the client display resolution in full-screen mode if the current display mode doesn't have a high enough refresh rate for the selected stream frame rate</li>
<li>When choosing a new client display resolution in full-screen mode, Moonlight will pick a display mode with the closest aspect ratio to the selected stream resolution</li>
<li>Moonlight now defaults to borderless windowed mode on Wayland systems</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed missing toolbar buttons in certain languages</li>
<li>Fixed some text on the settings page not updating when the language is changed</li>
<li>Fixed a frame pacing bug that could cause excessive frame drops</li>
<li>Fixed the "keep display awake" setting not being saved when Moonlight restarts</li>
<li>Fixed black screen after unmaximizing the Moonlight window on some Linux systems</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="4.0.0" date="2022-04-02">
<description>
<p>New features:</p>
<ul>
<li>Added a new key combo for locking the mouse cursor to the window (Ctrl+Alt+Shift+L)</li>
<li>Added an option to avoid keeping the client display awake while streaming</li>
</ul>
<p>Behavior Changes:</p>
<ul>
<li>HDR streaming is now a separate option rather than being part of the Video Codec override dropdown</li>
<li>HDR streaming is no longer restricted to apps that are certified by NVIDIA as compatible with GameStream HDR. Some newer games may require an HDR display or EDID emulator dongle connected to your host PC for HDR options to be available.</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed loss of all audio if the active audio device is unplugged while streaming</li>
<li>Fixed the GUI being unresponsive after manually quitting when connection to the host is lost</li>
<li>Fixed a rare crash if a controller disconnects right as rumble is starting</li>
<li>Fixed text rendering on the overlay UI when using SDL_ttf 2.0.18 on Linux</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="3.2.0" date="2022-01-18">
<description>
<p>New features:</p>
<ul>
<li>Reduced CPU usage while streaming</li>
<li>Non-ASCII characters are now supported when pasting clipboard data to the host</li>
<li>Added support for zero-copy NVDEC rendering for Nvidia Wayland systems</li>
<li>Significantly improved performance with asynchronous decoders like V4L2M2M on Linux</li>
<li>Added support for color compression planes on newer Intel systems when using VAAPI decoding</li>
<li>Added support for copy-back rendering in non-default pixel formats (like the Raspberry Pi SAND format)</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed unexpected GUI input after using the gamepad quit combo</li>
<li>Updated included gamepad mappings</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="3.1.4" date="2021-06-25">
<description>
<p>Changes:</p>
<ul>
<li>Added network latency statistics to the performance overlay</li>
<li>Improved audio quality on unreliable connections (requires GeForce Experience 3.19 or later)</li>
<li>Reduced video frame drops on unreliable connections (requires GeForce Experience 3.22 or later)</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="3.1.3" date="2021-05-07">
<description>
<p>Changes:</p>
<ul>
<li>Fixed an issue that could cause excessive audio latency on some connections</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="3.1.2" date="2021-05-03">
<description>
<p>Changes:</p>
<ul>
<li>Improved connection reliability and performance with GeForce Experience 3.22</li>
<li>Added support for audio encryption with GeForce Experience 3.22</li>
<li>Added compatibility update checks for future versions of GeForce Experience</li>
<li>Fixed keyboard capture on X11</li>
<li>Updated community-contributed translations from Weblate</li>
</ul>
</description>
</release>
<release version="3.1.1" date="2021-04-09">
<description>
<p>Changes:</p>
<ul>
<li>Added support for streaming from GeForce Experience 3.22</li>
<li>Added support for AMF-encoded HEVC streams from servers like Sunshine and OpenStream</li>
<li>Added new community-contributed translations from Weblate</li>
<li>Fixed KMSDRM rendering with buffer modifiers on embedded devices</li>
</ul>
</description>
</release>
<release version="3.1.0" date="2021-03-14">
<description>
<p>New features:</p>
<ul>
<li>System keyboard shortcuts (Alt+Tab, Super key, Ctrl+Shift+Esc, etc.) can now be (optionally) captured in windowed mode</li>
<li>System keyboard shortcuts can now be captured under Wayland</li>
<li>Added support for typing the client's clipboard text on the host by pressing Ctrl+Alt+Shift+V</li>
<li>Added Ctrl+Alt+Shift+D key combo to minimize the streaming window</li>
<li>Added Ctrl+Alt+Shift+C key combo to show the local cursor while streaming in remote desktop mouse mode</li>
<li>Added Select+L1+R1+X gamepad button combo to toggle performance overlay</li>
<li>Added translations for Simplified Chinese and German</li>
<li>Added a language selector on the settings page</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Improved performance of loading the app grid</li>
<li>Fixed video scaling in High DPI mode on Wayland</li>
<li>Fixed window icons on Wayland</li>
<li>Fixed number pad enter key functionality in the UI</li>
</ul>
</description>
</release>
<release version="3.0.0" date="2021-01-17">
<description>
<p>New features:</p>
<ul>
<li>Added the ability to define a custom streaming resolution using the UI</li>
<li>Added the option to capture system key combinations (Alt+Tab, Ctrl+Shift+Esc, Win+Tab, etc) in fullscreen mode</li>
<li>Updated gamepad mappings are automatically downloaded each time Moonlight launches</li>
<li>The performance overlay is now supported for Linux clients using VAAPI and VDPAU hardware acceleration</li>
<li>Added the option to enable "Direct Launch" which immediately launches the specified game when clicking on a PC</li>
<li>Added the option to mute audio when the Moonlight window loses input focus</li>
<li>Added the option to toggle background gamepad input</li>
<li>Added the option to invert scroll direction</li>
<li>Added the option to swap gamepad button layout to Nintendo-style</li>
<li>Added the option to start the Moonlight UI in fullscreen mode</li>
<li>The failing TCP or UDP ports are now displayed when the connection fails</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed PS4 controllers not reading inputs during haptics in some games</li>
<li>Fixed some slow decoders causing the receive time value to increase rather than the decode time</li>
<li>Native resolution options now refresh each time the settings page is opened, rather than once per launch of Moonlight</li>
<li>Fixed no video or audio while streaming over Internet connections that drop packets with QoS tagging enabled</li>
<li>Improved connection testing accuracy for connections with low MTUs</li>
<li>Fixed inability to open an app's context menu with a gamepad</li>
</ul>
</description>
</release>
<release version="2.2.0" date="2020-09-10">
<description>
<p>New features:</p>
<ul>
<li>Added the ability to hide unwanted apps and games</li>
<li>Added a network test to determine if your Internet connection is blocking Moonlight</li>
<li>Added the option to swap mouse buttons</li>
<li>Added codec and resolution to the on-screen performance stats</li>
<li>Added a warning if the connection is too unstable to receive any complete video frames</li>
<li>Added a Discord link to the toolbar in settings</li>
<li>Enabled the new EGL renderer by default on Linux</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed streaming over networks that block QoS-tagged packets</li>
<li>Selecting a frame rate higher than 60 FPS no longer sets the host desktop to 720p</li>
<li>Right-side modifier keys no longer press the corresponding left-side keys too</li>
<li>Fixed mouse position never reaching the edge of the screen with certain desktop resolutions</li>
<li>Improved synchronization between host and client mouse cursor in remote desktop mouse mode</li>
<li>Cached box art is now deleted when the PC is removed from Moonlight</li>
<li>Fixed several CLI options not properly overriding GUI options</li>
<li>Updated included gamepad mappings</li>
<li>Updated to Qt 5.15.1</li>
</ul>
</description>
</release>
<release version="2.1.0" date="2020-05-17">
<description>
<p>New features:</p>
<ul>
<li>Remote desktop mode now allows interaction with the host without having to click to focus the Moonlight window first</li>
<li>Added a new EGL renderer for improved performance on Wayland and XWayland</li>
<li>Added the option to toggle between direct touchscreen mode and the old trackpad mode</li>
<li>Added the option to rename host PCs</li>
<li>Added the ability to scroll the settings page with the right analog stick</li>
<li>Various UI improvements</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Fixed unreliable mouse capture when the stream begins</li>
<li>Fixed cursor being trapped in full-screen mode even when the mouse wasn't captured</li>
<li>Fixed key presses not being sent to the host if the Super/Meta/Windows key is pressed</li>
<li>Updated included gamepad mappings</li>
</ul>
</description>
</release>
<release version="2.0.0" date="2020-04-28">
<description>
<p>New features:</p>
<ul>
<li>Remote desktop-optimized mouse mode which doesn't require capturing the mouse cursor</li>
<li>Touchscreen input now directly controls the mouse cursor</li>
<li>7.1 surround sound support</li>
</ul>
<p>Bugfixes:</p>
<ul>
<li>Improved performance on some lossy networks</li>
<li>Fixed disconnect delay when streaming from GeForce Experience 3.20.3.63</li>
<li>Fixed frame rate not exceeding 60 when streaming from GeForce Experience 3.20.3.63</li>
<li>Fixed parsing of command-line options when passing flags prior to the action</li>
<li>Fixed an issue that may cause excessive mDNS network traffic while Moonlight is running</li>
<li>Fixed hardware decoding on Intel GPUs running Mesa 20.0 and/or the Iris driver</li>
<li>Fixed hardware decoding on Comet Lake and later Intel GPUs using the iHD VA-API driver</li>
<li>Fixed hardware decoding on AMD Radeon GPUs with XWayland</li>
<li>Fixed a crash when using the iHD VA-API driver on Wayland</li>
<li>Fixed delay after exiting the stream on Wayland</li>
<li>Updated included gamepad mappings</li>
</ul>
</description>
</release>
<release version="1.2.0" date="2019-12-17">
<description>
<p>Bugfixes:</p>
<ul>
<li>Improved video encoding efficiency</li>
<li>Improved performance when streaming over a VPN</li>
<li>Fixed RTSP handshake error on certain networks</li>
<li>Fixed rumble not working on certain gamepads</li>
<li>Fixed pairing error when double-clicking on an unpaired PC</li>
<li>Updated included SDL gamepad mappings</li>
</ul>
</description>
</release>
<release version="1.1.1" date="2019-09-29">
<description>
<p>Bugfixes:</p>
<ul>
<li>Improved reliability of public IP address detection</li>
<li>Fixed connecting to a host PC with multiple network connections</li>
<li>Fixed a hang after exiting a full-screen stream with GNOME on Wayland</li>
<li>Fixed gamepad hotplugging</li>
<li>Updated to SDL 2.0.10</li>
<li>Updated to Qt 5.13.1</li>
</ul>
</description>
</release>
<release version="1.1.0" date="2019-08-05">
<description>
<p>New features:</p>
@@ -1,9 +1,9 @@
[Desktop Entry]
Name=Moonlight
Comment=Stream games from your NVIDIA GameStream-enabled PC
Comment=Stream games and other applications from another PC running Sunshine or GeForce Experience
Exec=moonlight
Icon=moonlight
Terminal=false
Type=Application
Categories=Qt;Game;
Keywords=nvidia;gamestream;stream;
Keywords=nvidia;gamestream;stream;sunshine;remote play;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+4
View File
@@ -5,6 +5,10 @@
# pairing data will be lost each reboot.
HOME=/usr/local/moonlight
# Enable Steam Controller detection in SDL
# https://github.com/moonlight-stream/moonlight-qt/issues/697
export SDL_ENABLE_STEAM_CONTROLLERS=1
# Renice PE_Single_CPU which seems to host A/V stuff
renice -10 -p $(pidof PE_Single_CPU)
+199 -105
View File
@@ -1,5 +1,6 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import AppModel 1.0
import ComputerManager 1.0
@@ -9,6 +10,8 @@ CenteredGridView {
property int computerIndex
property AppModel appModel : createModel()
property bool activated
property bool showHiddenGames
property bool showGames
id: appGrid
focus: true
@@ -38,6 +41,19 @@ CenteredGridView {
if (currentIndex == -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
currentIndex = 0
}
if (!showGames && !showHiddenGames) {
// Check if there's a direct launch app
var directLaunchAppIndex = model.getDirectLaunchAppIndex();
if (directLaunchAppIndex >= 0) {
// Start the direct launch app if nothing else is running
currentIndex = directLaunchAppIndex
currentItem.launchOrResumeSelectedApp(false)
// Set showGames so we will not loop when the stream ends
showGames = true
}
}
}
StackView.onDeactivating: {
@@ -48,7 +64,7 @@ CenteredGridView {
function createModel()
{
var model = Qt.createQmlObject('import AppModel 1.0; AppModel {}', parent, '')
model.initialize(ComputerManager, computerIndex)
model.initialize(ComputerManager, computerIndex, showHiddenGames)
return model
}
@@ -58,6 +74,12 @@ CenteredGridView {
width: 220; height: 287;
grid: appGrid
property alias appContextMenu: appContextMenuLoader.item
property alias appNameText: appNameTextLoader.item
// Dim the app if it's hidden
opacity: model.hidden ? 0.4 : 1.0
Image {
property bool isPlaceholder: false
@@ -67,9 +89,14 @@ CenteredGridView {
source: model.boxart
onSourceSizeChanged: {
if ((sourceSize.width == 130 && sourceSize.height == 180) || // GFE 2.0 placeholder image
(sourceSize.width == 628 && sourceSize.height == 888) || // GFE 3.0 placeholder image
(sourceSize.width == 200 && sourceSize.height == 266)) // Our no_app_image.png
// Nearly all of Nvidia's official box art does not match the dimensions of placeholder
// images, however the one known exception is Overcooked. Therefore, we only execute
// the image size checks if this is not an app collector game. We know the officially
// supported games all have box art, so this check is not required.
if (!model.isAppCollectorGame &&
((sourceSize.width == 130 && sourceSize.height == 180) || // GFE 2.0 placeholder image
(sourceSize.width == 628 && sourceSize.height == 888) || // GFE 3.0 placeholder image
(sourceSize.width == 200 && sourceSize.height == 266))) // Our no_app_image.png
{
isPlaceholder = true
}
@@ -86,95 +113,121 @@ CenteredGridView {
ToolTip.text: model.name
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: (parent.hovered || parent.highlighted) && (!appNameText.visible || appNameText.truncated)
ToolTip.visible: (parent.hovered || parent.highlighted) && (!appNameText || appNameText.truncated)
}
ToolButton {
id: resumeButton
anchors.horizontalCenterOffset: appIcon.isPlaceholder ? -47 : 0
anchors.verticalCenterOffset: appIcon.isPlaceholder ? -75 : -60
anchors.centerIn: appIcon
visible: model.running
implicitWidth: 125
implicitHeight: 125
Loader {
active: model.running
asynchronous: true
anchors.fill: appIcon
Image {
source: "qrc:/res/baseline-play_circle_filled_white-48px.svg"
anchors.centerIn: parent
sourceSize {
width: 75
height: 75
sourceComponent: Item {
RoundButton {
anchors.horizontalCenterOffset: appIcon.isPlaceholder ? -47 : 0
anchors.verticalCenterOffset: appIcon.isPlaceholder ? -75 : -60
anchors.centerIn: parent
implicitWidth: 85
implicitHeight: 85
Image {
source: "qrc:/res/play_arrow_FILL1_wght700_GRAD200_opsz48.svg"
anchors.centerIn: parent
sourceSize {
width: 75
height: 75
}
}
onClicked: {
launchOrResumeSelectedApp(true)
}
ToolTip.text: qsTr("Resume Game")
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
Material.background: "#D0808080"
}
RoundButton {
anchors.horizontalCenterOffset: appIcon.isPlaceholder ? 47 : 0
anchors.verticalCenterOffset: appIcon.isPlaceholder ? -75 : 60
anchors.centerIn: parent
implicitWidth: 85
implicitHeight: 85
Image {
source: "qrc:/res/stop_FILL1_wght700_GRAD200_opsz48.svg"
anchors.centerIn: parent
sourceSize {
width: 75
height: 75
}
}
onClicked: {
doQuitGame()
}
ToolTip.text: qsTr("Quit Game")
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
Material.background: "#D0808080"
}
}
onClicked: {
launchOrResumeSelectedApp()
}
ToolTip.text: "Resume Game"
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
}
ToolButton {
id: quitButton
anchors.horizontalCenterOffset: appIcon.isPlaceholder ? 47 : 0
anchors.verticalCenterOffset: appIcon.isPlaceholder ? -75 : 60
anchors.centerIn: appIcon
visible: model.running
implicitWidth: 125
implicitHeight: 125
Loader {
id: appNameTextLoader
active: appIcon.isPlaceholder
Image {
source: "qrc:/res/baseline-cancel-24px.svg"
anchors.centerIn: parent
sourceSize {
width: 75
height: 75
}
}
// This loader is not asynchronous to avoid noticeable differences
// in the time in which the text loads for each game.
onClicked: {
doQuitGame()
}
ToolTip.text: "Quit Game"
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
}
Label {
id: appNameText
visible: appIcon.isPlaceholder
text: model.name
width: appIcon.width
height: model.running ? 175 : appIcon.height
anchors.left: appIcon.left
anchors.right: appIcon.right
anchors.bottom: appIcon.bottom
font.pointSize: 22
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
elide: Text.ElideRight
sourceComponent: Label {
id: appNameText
text: model.name
font.pointSize: 22
leftPadding: 20
rightPadding: 20
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
elide: Text.ElideRight
}
}
function launchOrResumeSelectedApp()
function launchOrResumeSelectedApp(quitExistingApp)
{
var runningIndex = appModel.getRunningAppIndex()
if (runningIndex >= 0 && runningIndex !== index) {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = true
quitAppDialog.nextAppName = model.name
quitAppDialog.nextAppIndex = index
quitAppDialog.open()
var runningId = appModel.getRunningAppId()
if (runningId !== 0 && runningId !== model.appid) {
if (quitExistingApp) {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = true
quitAppDialog.nextAppName = model.name
quitAppDialog.nextAppIndex = index
quitAppDialog.open()
}
return
}
var component = Qt.createComponent("StreamSegue.qml")
var segue = component.createObject(stackView, {"appName": model.name, "session": appModel.createSessionForApp(index)})
var segue = component.createObject(stackView, {
"appName": model.name,
"session": appModel.createSessionForApp(index),
"isResume": runningId === model.appid
})
stackView.push(segue)
}
@@ -184,7 +237,26 @@ CenteredGridView {
// will handle starting the game and clicks on the box art will
// be ignored.
if (!model.running) {
launchOrResumeSelectedApp()
launchOrResumeSelectedApp(true)
}
}
onPressAndHold: {
// popup() ensures the menu appears under the mouse cursor
if (appContextMenu.popup) {
appContextMenu.popup()
}
else {
// Qt 5.9 doesn't have popup()
appContextMenu.open()
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton;
onClicked: {
parent.pressAndHold()
}
}
@@ -199,7 +271,10 @@ CenteredGridView {
}
}
Keys.onMenuPressed: {
Keys.onEnterPressed: {
// Open the app context menu if activated via the gamepad or keyboard
// for running games. If the game isn't running, the above onClicked
// method will handle the launch.
if (model.running) {
// This will be keyboard/gamepad driven so use
// open() instead of popup()
@@ -207,24 +282,59 @@ CenteredGridView {
}
}
Keys.onMenuPressed: {
// This will be keyboard/gamepad driven so use open() instead of popup()
appContextMenu.open()
}
function doQuitGame() {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = false
quitAppDialog.open()
}
NavigableMenu {
id: appContextMenu
NavigableMenuItem {
parentMenu: appContextMenu
text: model.running ? "Resume Game" : "Launch Game"
onTriggered: launchOrResumeSelectedApp()
}
NavigableMenuItem {
parentMenu: appContextMenu
text: "Quit Game"
onTriggered: doQuitGame()
visible: model.running
Loader {
id: appContextMenuLoader
asynchronous: true
sourceComponent: NavigableMenu {
id: appContextMenu
NavigableMenuItem {
parentMenu: appContextMenu
text: model.running ? qsTr("Resume Game") : qsTr("Launch Game")
onTriggered: launchOrResumeSelectedApp(true)
}
NavigableMenuItem {
parentMenu: appContextMenu
text: qsTr("Quit Game")
onTriggered: doQuitGame()
visible: model.running
}
NavigableMenuItem {
parentMenu: appContextMenu
checkable: true
checked: model.directLaunch
text: qsTr("Direct Launch")
onTriggered: appModel.setAppDirectLaunch(model.index, !model.directLaunch)
enabled: !model.hidden
ToolTip.text: qsTr("Launch this app immediately when the host is selected, bypassing the app selection grid.")
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
}
NavigableMenuItem {
parentMenu: appContextMenu
checkable: true
checked: model.hidden
text: qsTr("Hide Game")
onTriggered: appModel.setAppHidden(model.index, !model.hidden)
enabled: model.hidden || (!model.running && !model.directLaunch)
ToolTip.text: qsTr("Hide this game from the app grid. To access hidden games, right-click on the host and choose %1.").arg(qsTr("View All Apps"))
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
}
}
}
}
@@ -235,12 +345,12 @@ CenteredGridView {
property bool segueToStream : false
property string nextAppName: ""
property int nextAppIndex: 0
text:"Are you sure you want to quit " + appName +"? Any unsaved progress will be lost."
text:qsTr("Are you sure you want to quit %1? Any unsaved progress will be lost.").arg(appName)
standardButtons: Dialog.Yes | Dialog.No
function quitApp() {
var component = Qt.createComponent("QuitSegue.qml")
var params = {"appName": appName}
var params = {"appName": appName, "quitRunningAppFn": () => appModel.quitRunningApp()}
if (segueToStream) {
// Store the session and app name if we're going to stream after
// successfully quitting the old app.
@@ -253,26 +363,10 @@ CenteredGridView {
}
stackView.push(component.createObject(stackView, params))
// Trigger the quit after pushing the quit segue on screen
appModel.quitRunningApp()
}
onAccepted: quitApp()
}
ScrollBar.vertical: ScrollBar {
// Manually hide the scrollbar to prevent it from being drawn on top
// of the StreamSegue during the transition. It can sometimes get stuck
// there since we're not consistently pumping the event loop while
// starting the stream.
visible: activated
parent: appGrid.parent
anchors {
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
ScrollBar.vertical: ScrollBar {}
}
+15 -4
View File
@@ -2,12 +2,15 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import SdlGamepadKeyNavigation 1.0
import SystemProperties 1.0
// https://stackoverflow.com/questions/45029968/how-do-i-set-the-combobox-width-to-fit-the-largest-item
ComboBox {
property int textWidth
property int desiredWidth : leftPadding + textWidth + indicator.width + rightPadding
property int maximumWidth : parent.width
implicitWidth: leftPadding + textWidth + indicator.width + rightPadding
implicitWidth: desiredWidth < maximumWidth ? desiredWidth : maximumWidth
TextMetrics {
id: popupMetrics
@@ -17,9 +20,7 @@ ComboBox {
id: textMetrics
}
// We call this every time the options change (and init)
// so we can adjust the combo box width here too
onActivated: {
function recalculateWidth() {
textMetrics.font = font
popupMetrics.font = popup.font
textWidth = 0
@@ -31,9 +32,19 @@ ComboBox {
}
}
// We call this every time the options change (and init)
// so we can adjust the combo box width here too
onActivated: recalculateWidth()
popup.onAboutToShow: {
// Switch to normal navigation for combo boxes
SdlGamepadKeyNavigation.setUiNavMode(false)
// Override the popup color to improve contrast with the overridden
// Material 2 background color set in main.qml.
if (SystemProperties.usesMaterial3Theme) {
popup.background.color = "#424242"
}
}
popup.onAboutToHide: {
+2
View File
@@ -38,4 +38,6 @@ GridView {
updateMargins()
}
boundsBehavior: Flickable.OvershootBounds
}
+91
View File
@@ -0,0 +1,91 @@
import QtQuick 2.0
import QtQuick.Controls 2.2
import ComputerManager 1.0
import SdlGamepadKeyNavigation 1.0
Item {
function onSearchingComputer() {
stageLabel.text = qsTr("Establishing connection to PC...")
}
function onPairing(pcName, pin) {
stageLabel.text = qsTr("Pairing... Please enter '%1' on %2.").arg(pin).arg(pcName)
}
function onFailed(message) {
stageIndicator.visible = false
errorDialog.text = message
errorDialog.open()
}
function onSuccess(appName) {
stageIndicator.visible = false
pairCompleteDialog.open()
}
// Allow user to back out of pairing
Keys.onEscapePressed: {
Qt.quit()
}
Keys.onBackPressed: {
Qt.quit()
}
Keys.onCancelPressed: {
Qt.quit()
}
StackView.onActivated: {
if (!launcher.isExecuted()) {
toolBar.visible = false
// Normally this is enabled by PcView, but we will won't
// load PcView when streaming from the command-line.
SdlGamepadKeyNavigation.enable()
launcher.searchingComputer.connect(onSearchingComputer)
launcher.pairing.connect(onPairing)
launcher.failed.connect(onFailed)
launcher.success.connect(onSuccess)
launcher.execute(ComputerManager)
}
}
Row {
anchors.centerIn: parent
spacing: 5
id: stageIndicator
BusyIndicator {
id: stageSpinner
}
Label {
id: stageLabel
height: stageSpinner.height
font.pointSize: 20
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
ErrorMessageDialog {
id: errorDialog
onClosed: {
Qt.quit();
}
}
NavigableMessageDialog {
id: pairCompleteDialog
closePolicy: Popup.CloseOnEscape
text:qsTr("Pairing completed successfully")
standardButtons: Dialog.Ok
onClosed: {
Qt.quit()
}
}
}
+2 -2
View File
@@ -6,11 +6,11 @@ import Session 1.0
Item {
function onSearchingComputer() {
stageLabel.text = "Establishing connection to PC..."
stageLabel.text = qsTr("Establishing connection to PC...")
}
function onQuittingApp() {
stageLabel.text = "Quitting app..."
stageLabel.text = qsTr("Quitting app...")
}
function onFailure(message) {
+11 -6
View File
@@ -2,14 +2,15 @@ import QtQuick 2.0
import QtQuick.Controls 2.2
import ComputerManager 1.0
import SdlGamepadKeyNavigation 1.0
Item {
function onSearchingComputer() {
stageLabel.text = "Establishing connection to PC..."
stageLabel.text = qsTr("Establishing connection to PC...")
}
function onSearchingApp() {
stageLabel.text = "Loading app list..."
stageLabel.text = qsTr("Loading app list...")
}
function onSessionCreated(appName, session) {
@@ -25,6 +26,7 @@ Item {
function onLaunchFailed(message) {
errorDialog.text = message
errorDialog.open()
console.error(message)
}
function onAppQuitRequired(appName) {
@@ -35,6 +37,11 @@ Item {
StackView.onActivated: {
if (!launcher.isExecuted()) {
toolBar.visible = false
// Normally this is enabled by PcView, but we will won't
// load PcView when streaming from the command-line.
SdlGamepadKeyNavigation.enable()
launcher.searchingComputer.connect(onSearchingComputer)
launcher.searchingApp.connect(onSearchingApp)
launcher.sessionCreated.connect(onSessionCreated)
@@ -72,16 +79,14 @@ Item {
NavigableMessageDialog {
id: quitAppDialog
text:"Are you sure you want to quit " + appName +"? Any unsaved progress will be lost."
text:qsTr("Are you sure you want to quit %1? Any unsaved progress will be lost.").arg(appName)
standardButtons: Dialog.Yes | Dialog.No
property string appName : ""
function quitApp() {
var component = Qt.createComponent("QuitSegue.qml")
var params = {"appName": appName}
var params = {"appName": appName, "quitRunningAppFn": () => launcher.quitRunningApp()}
stackView.push(component.createObject(stackView, params))
// Trigger the quit after pushing the quit segue on screen
launcher.quitRunningApp()
}
onAccepted: quitApp()
+1 -1
View File
@@ -1,5 +1,5 @@
import QtQuick 2.0
Item {
objectName: "Gamepad Mapping"
objectName: qsTr("Gamepad Mapping")
}
+2 -1
View File
@@ -2,7 +2,8 @@ import QtQuick 2.0
import QtQuick.Controls 2.2
Dialog {
parent: overlay
// We should use Overlay.overlay here but that's not available in Qt 5.9 :(
parent: ApplicationWindow.contentItem
x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height - height) / 2)
+3
View File
@@ -21,4 +21,7 @@ ItemDelegate {
Keys.onReturnPressed: {
clicked()
}
Keys.onEnterPressed: {
clicked()
}
}
+8 -1
View File
@@ -3,6 +3,13 @@ import QtQuick.Controls 2.2
Menu {
onOpened: {
itemAt(0).forceActiveFocus(Qt.TabFocusReason)
// Give focus to the first visible and enabled menu item
for (var i = 0; i < count; i++) {
var item = itemAt(i)
if (item.visible && item.enabled) {
item.forceActiveFocus(Qt.TabFocusReason)
break
}
}
}
}
+4
View File
@@ -22,6 +22,10 @@ MenuItem {
triggered()
}
Keys.onEnterPressed: {
triggered()
}
Keys.onEscapePressed: {
parentMenu.close()
}
+13
View File
@@ -6,6 +6,8 @@ NavigableDialog {
id: dialog
property alias text: dialogLabel.dialogText
property alias showSpinner: dialogSpinner.visible
property alias imageSrc: dialogImage.source
property string helpText
property string helpUrl : "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"
@@ -19,7 +21,13 @@ NavigableDialog {
RowLayout {
spacing: 10
BusyIndicator {
id: dialogSpinner
visible: false
}
Image {
id: dialogImage
source: (standardButtons & Dialog.Yes) ?
"qrc:/res/baseline-help_outline-24px.svg" :
"qrc:/res/baseline-error_outline-24px.svg"
@@ -28,6 +36,7 @@ NavigableDialog {
width: 50
height: 50
}
visible: !showSpinner
}
Label {
@@ -47,6 +56,10 @@ NavigableDialog {
accept()
}
Keys.onEnterPressed: {
accept()
}
Keys.onEscapePressed: {
reject()
}
+6 -2
View File
@@ -1,5 +1,6 @@
import QtQuick 2.0
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ToolButton {
property string iconSource
@@ -20,13 +21,16 @@ ToolButton {
// This determines the size of the Material highlight. We increase it
// from the default because we use larger than normal icons for TV readability.
background.width: (parent.height - parent.anchors.bottomMargin - parent.anchors.topMargin) * 0.60
background.height: (parent.height - parent.anchors.bottomMargin - parent.anchors.topMargin) * 0.60
Layout.preferredHeight: parent.height
Keys.onReturnPressed: {
clicked()
}
Keys.onEnterPressed: {
clicked()
}
Keys.onRightPressed: {
nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocus)
}
+206 -60
View File
@@ -1,10 +1,12 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import ComputerModel 1.0
import ComputerManager 1.0
import StreamingPreferences 1.0
import SystemProperties 1.0
import SdlGamepadKeyNavigation 1.0
CenteredGridView {
@@ -16,7 +18,7 @@ CenteredGridView {
topMargin: 20
bottomMargin: 5
cellWidth: 310; cellHeight: 330;
objectName: "Computers"
objectName: qsTr("Computers")
Component.onCompleted: {
// Don't show any highlighted item until interacting with them.
@@ -25,6 +27,9 @@ CenteredGridView {
currentIndex = -1
}
// Note: Any initialization done here that is critical for streaming must
// also be done in CliStartStreamSegue.qml, since this code does not run
// for command-line initiated streams.
StackView.onActivated: {
// Setup signals on CM
ComputerManager.computerAddCompleted.connect(addComplete)
@@ -57,11 +62,18 @@ CenteredGridView {
}
}
function addComplete(success)
function addComplete(success, detectedPortBlocking)
{
if (!success) {
errorDialog.text = "Unable to connect to the specified PC."
errorDialog.helpText = "Click the Help button for possible solutions."
errorDialog.text = qsTr("Unable to connect to the specified PC.")
if (detectedPortBlocking) {
errorDialog.text += "\n\n" + qsTr("This PC's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network.")
}
else {
errorDialog.helpText = qsTr("Click the Help button for possible solutions.")
}
errorDialog.open()
}
}
@@ -71,6 +83,7 @@ CenteredGridView {
var model = Qt.createQmlObject('import ComputerModel 1.0; ComputerModel {}', parent, '')
model.initialize(ComputerManager)
model.pairingCompleted.connect(pairingComplete)
model.connectionTestCompleted.connect(testConnectionDialog.connectionTestComplete)
return model
}
@@ -87,8 +100,8 @@ CenteredGridView {
Label {
height: searchSpinner.height
elide: Label.ElideRight
text: StreamingPreferences.enableMdns ? "Searching for PCs with NVIDIA GameStream enabled..."
: "Automatic PC discovery is disabled. Add your PC manually."
text: StreamingPreferences.enableMdns ? qsTr("Searching for compatible hosts on your local network...")
: qsTr("Automatic PC discovery is disabled. Add your PC manually.")
font.pointSize: 20
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
@@ -101,10 +114,12 @@ CenteredGridView {
width: 300; height: 320;
grid: pcGrid
property alias pcContextMenu : pcContextMenuLoader.item
Image {
id: pcIcon
anchors.horizontalCenter: parent.horizontalCenter
source: "qrc:/res/ic_tv_white_48px.svg"
source: "qrc:/res/desktop_windows-48px.svg"
sourceSize {
width: 200
height: 200
@@ -116,12 +131,12 @@ CenteredGridView {
id: stateIcon
anchors.horizontalCenter: pcIcon.horizontalCenter
anchors.verticalCenter: pcIcon.verticalCenter
anchors.verticalCenterOffset: -10
anchors.verticalCenterOffset: !model.online ? -18 : -16
visible: !model.statusUnknown && (!model.online || !model.paired)
source: !model.online ? "qrc:/res/baseline-warning-24px.svg" : "qrc:/res/baseline-lock-24px.svg"
source: !model.online ? "qrc:/res/warning_FILL1_wght300_GRAD200_opsz24.svg" : "qrc:/res/baseline-lock-24px.svg"
sourceSize {
width: 75
height: 75
width: !model.online ? 75 : 70
height: !model.online ? 75 : 70
}
}
@@ -129,7 +144,7 @@ CenteredGridView {
id: statusUnknownSpinner
anchors.horizontalCenter: pcIcon.horizontalCenter
anchors.verticalCenter: pcIcon.verticalCenter
anchors.verticalCenterOffset: -10
anchors.verticalCenterOffset: -15
width: 75
height: 75
visible: model.statusUnknown
@@ -148,50 +163,92 @@ CenteredGridView {
elide: Text.ElideRight
}
NavigableMenu {
id: pcContextMenu
NavigableMenuItem {
parentMenu: pcContextMenu
text: "Delete PC"
onTriggered: {
deletePcDialog.pcIndex = index
// get confirmation first, actual closing is called from the dialog
deletePcDialog.open()
Loader {
id: pcContextMenuLoader
asynchronous: true
sourceComponent: NavigableMenu {
id: pcContextMenu
MenuItem {
text: qsTr("PC Status: %1").arg(model.online ? qsTr("Online") : qsTr("Offline"))
font.bold: true
enabled: false
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("View All Apps")
onTriggered: {
var component = Qt.createComponent("AppView.qml")
var appView = component.createObject(stackView, {"computerIndex": index, "objectName": model.name, "showHiddenGames": true})
stackView.push(appView)
}
visible: model.online && model.paired
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Wake PC")
onTriggered: computerModel.wakeComputer(index)
visible: !model.online && model.wakeable
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Test Network")
onTriggered: {
computerModel.testConnectionForComputer(index)
testConnectionDialog.open()
}
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Rename PC")
onTriggered: {
renamePcDialog.pcIndex = index
renamePcDialog.originalName = model.name
renamePcDialog.open()
}
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("Delete PC")
onTriggered: {
deletePcDialog.pcIndex = index
deletePcDialog.pcName = model.name
deletePcDialog.open()
}
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: qsTr("View Details")
onTriggered: {
showPcDetailsDialog.pcDetails = model.details
showPcDetailsDialog.open()
}
}
}
NavigableMenuItem {
parentMenu: pcContextMenu
text: "Wake PC"
onTriggered: computerModel.wakeComputer(index)
visible: !model.online && model.wakeable
}
}
onClicked: {
if (model.online) {
if (model.paired) {
if (!model.serverSupported) {
errorDialog.text = qsTr("The version of GeForce Experience on %1 is not supported by this build of Moonlight. You must update Moonlight to stream from %1.").arg(model.name)
errorDialog.helpText = ""
errorDialog.open()
}
else if (model.paired) {
// go to game view
var component = Qt.createComponent("AppView.qml")
var appView = component.createObject(stackView, {"computerIndex": index, "objectName": model.name})
stackView.push(appView)
}
else {
if (!model.busy) {
var pin = ("0000" + Math.floor(Math.random() * 10000)).slice(-4)
var pin = computerModel.generatePinString()
// Kick off pairing in the background
computerModel.pairComputer(index, pin)
// Kick off pairing in the background
computerModel.pairComputer(index, pin)
// Display the pairing dialog
pairDialog.pin = pin
pairDialog.open()
}
else {
// cannot pair while something is streaming or attempting to pair
errorDialog.text = "You cannot pair while a previous session is still running on the host PC. Quit any running games or reboot the host PC, then try pairing again."
errorDialog.helpText = ""
errorDialog.open()
}
// Display the pairing dialog
pairDialog.pin = pin
pairDialog.open()
}
} else if (!model.online) {
// Using open() here because it may be activated by keyboard
@@ -214,7 +271,7 @@ CenteredGridView {
anchors.fill: parent
acceptedButtons: Qt.RightButton;
onClicked: {
parent.onPressAndHold()
parent.pressAndHold()
}
}
@@ -223,6 +280,12 @@ CenteredGridView {
// the ItemDelegate and not where the mouse cursor is
pcContextMenu.open()
}
Keys.onDeletePressed: {
deletePcDialog.pcIndex = index
deletePcDialog.pcName = model.name
deletePcDialog.open()
}
}
ErrorMessageDialog {
@@ -235,9 +298,16 @@ CenteredGridView {
NavigableMessageDialog {
id: pairDialog
// Pairing dialog must be modal to prevent double-clicks from triggering
// pairing twice
modal: true
closePolicy: Popup.CloseOnEscape
// don't allow edits to the rest of the window while open
property string pin : "0000"
text:"Please enter " + pin + " on your GameStream PC. This dialog will close when pairing is completed."
text:qsTr("Please enter %1 on your host PC. This dialog will close when pairing is completed.").arg(pin)+"\n\n"+
qsTr("If your host PC is running Sunshine, navigate to the Sunshine web UI to enter the PIN.")
standardButtons: Dialog.Cancel
onRejected: {
// FIXME: We should interrupt pairing here
@@ -247,24 +317,100 @@ CenteredGridView {
NavigableMessageDialog {
id: deletePcDialog
// don't allow edits to the rest of the window while open
property int pcIndex : -1;
text:"Are you sure you want to remove this PC?"
property int pcIndex : -1
property string pcName : ""
text: qsTr("Are you sure you want to remove '%1'?").arg(pcName)
standardButtons: Dialog.Yes | Dialog.No
function deletePc() {
console.log("deleting PC pairing for PC at index: " + pcIndex)
computerModel.deleteComputer(pcIndex);
}
onAccepted: deletePc()
}
ScrollBar.vertical: ScrollBar {
parent: pcGrid.parent
anchors {
top: parent.top
right: parent.right
bottom: parent.bottom
onAccepted: {
computerModel.deleteComputer(pcIndex)
}
}
NavigableMessageDialog {
id: testConnectionDialog
closePolicy: Popup.CloseOnEscape
standardButtons: Dialog.Ok
onAboutToShow: {
testConnectionDialog.text = qsTr("Moonlight is testing your network connection to determine if any required ports are blocked.") + "\n\n" + qsTr("This may take a few seconds…")
showSpinner = true
}
function connectionTestComplete(result, blockedPorts)
{
if (result === -1) {
text = qsTr("The network test could not be performed because none of Moonlight's connection testing servers were reachable from this PC. Check your Internet connection or try again later.")
imageSrc = "qrc:/res/baseline-warning-24px.svg"
}
else if (result === 0) {
text = qsTr("This network does not appear to be blocking Moonlight. If you still have trouble connecting, check your PC's firewall settings.") + "\n\n" + qsTr("If you are trying to stream over the Internet, install the Moonlight Internet Hosting Tool on your gaming PC and run the included Internet Streaming Tester to check your gaming PC's Internet connection.")
imageSrc = "qrc:/res/baseline-check_circle_outline-24px.svg"
}
else {
text = qsTr("Your PC's current network connection seems to be blocking Moonlight. Streaming over the Internet may not work while connected to this network.") + "\n\n" + qsTr("The following network ports were blocked:") + "\n"
text += blockedPorts
imageSrc = "qrc:/res/baseline-error_outline-24px.svg"
}
// Stop showing the spinner and show the image instead
showSpinner = false
}
}
NavigableDialog {
id: renamePcDialog
property string label: qsTr("Enter the new name for this PC:")
property string originalName
property int pcIndex : -1;
standardButtons: Dialog.Ok | Dialog.Cancel
onOpened: {
// Force keyboard focus on the textbox so keyboard navigation works
editText.forceActiveFocus()
}
onClosed: {
editText.clear()
}
onAccepted: {
if (editText.text) {
computerModel.renameComputer(pcIndex, editText.text)
}
}
ColumnLayout {
Label {
text: renamePcDialog.label
font.bold: true
}
TextField {
id: editText
placeholderText: renamePcDialog.originalName
Layout.fillWidth: true
focus: true
Keys.onReturnPressed: {
renamePcDialog.accept()
}
Keys.onEnterPressed: {
renamePcDialog.accept()
}
}
}
}
NavigableMessageDialog {
id: showPcDetailsDialog
property string pcDetails : "";
text: showPcDetailsDialog.pcDetails
imageSrc: "qrc:/res/baseline-help_outline-24px.svg"
standardButtons: Dialog.Ok
}
ScrollBar.vertical: ScrollBar {}
}
+8 -1
View File
@@ -6,10 +6,11 @@ import Session 1.0
Item {
property string appName
property var quitRunningAppFn
property Session nextSession : null
property string nextAppName : ""
property string stageText : "Quitting " + appName + "..."
property string stageText : qsTr("Quitting %1...").arg(appName)
function quitAppCompleted(error)
{
@@ -17,6 +18,7 @@ Item {
if (error !== undefined) {
errorDialog.text = error
errorDialog.open()
console.error(error)
}
// If we're supposed to launch another game after this, do so now
@@ -37,6 +39,11 @@ Item {
// Connect the quit completion signal
ComputerManager.quitAppCompleted.connect(quitAppCompleted)
// Start the quit operation if requested
if (quitRunningAppFn) {
quitRunningAppFn()
}
}
StackView.onDeactivating: {
+1138 -258
View File
File diff suppressed because it is too large Load Diff
+48 -9
View File
@@ -8,19 +8,25 @@ import Session 1.0
Item {
property Session session
property string appName
property string stageText : "Starting " + appName + "..."
property string stageText : isResume ? qsTr("Resuming %1...").arg(appName) :
qsTr("Starting %1...").arg(appName)
property bool isResume : false
property bool quitAfter : false
function stageStarting(stage)
{
// Update the spinner text
stageText = "Starting " + stage + "..."
stageText = qsTr("Starting %1...").arg(stage)
}
function stageFailed(stage, errorCode)
function stageFailed(stage, errorCode, failingPorts)
{
// Display the error dialog after Session::exec() returns
streamSegueErrorDialog.text = "Starting " + stage + " failed: Error " + errorCode
streamSegueErrorDialog.text = qsTr("Starting %1 failed: Error %2").arg(stage).arg(errorCode)
if (failingPorts) {
streamSegueErrorDialog.text += "\n\n" + qsTr("Check your firewall and port forwarding rules for port(s): %1").arg(failingPorts)
}
}
function connectionStarted()
@@ -39,6 +45,7 @@ Item {
{
// Display the error dialog after Session::exec() returns
streamSegueErrorDialog.text = text
console.error(text)
}
function displayLaunchWarning(text)
@@ -50,6 +57,7 @@ Item {
toast.text = text
toast.timeout = 3000
toast.visible = true
console.warn(text)
}
function quitStarting()
@@ -62,8 +70,12 @@ Item {
window.visible = true
}
function sessionFinished()
function sessionFinished(portTestResult)
{
if (portTestResult !== 0 && portTestResult !== -1 && streamSegueErrorDialog.text) {
streamSegueErrorDialog.text += "\n\n" + qsTr("This PC's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network.")
}
// Enable GUI gamepad usage now
SdlGamepadKeyNavigation.enable()
@@ -95,6 +107,14 @@ Item {
}
}
function sessionReadyForDeletion()
{
// Garbage collect the Session object since it's pretty heavyweight
// and keeps other libraries (like SDL_TTF) around until it is deleted.
session = null
gc()
}
StackView.onDeactivating: {
// Show the toolbar again when popped off the stack
toolBar.visible = true
@@ -115,11 +135,25 @@ Item {
session.displayLaunchWarning.connect(displayLaunchWarning)
session.quitStarting.connect(quitStarting)
session.sessionFinished.connect(sessionFinished)
session.readyForDeletion.connect(sessionReadyForDeletion)
// Kick off the stream
spinnerTimer.start()
streamLoader.active = true
}
Timer {
id: spinnerTimer
// Display the spinner appearance a bit to allow us to reach
// the code in Session.exec() that pumps the event loop.
// If we display it immediately, it will briefly hang in the
// middle of the animation on Windows, which looks very
// obviously broken.
interval: 100
onTriggered: stageSpinner.running = true
}
Loader {
id: streamLoader
active: false
@@ -130,15 +164,19 @@ Item {
// in the hintText control itself to synchronize
// with Session.exec() which requires no concurrent
// gamepad usage.
hintText.text = SdlGamepadKeyNavigation.getConnectedGamepads() > 0 ?
"Tip: Press Start+Select+L1+R1 to disconnect your session" :
"Tip: Press Ctrl+Alt+Shift+Q to disconnect your session"
hintText.text = qsTr("Tip:") + " " + qsTr("Press %1 to disconnect your session").arg(SdlGamepadKeyNavigation.getConnectedGamepads() > 0 ?
qsTr("Start+Select+L1+R1") : qsTr("Ctrl+Alt+Shift+Q"))
// Stop GUI gamepad usage now
SdlGamepadKeyNavigation.disable()
// Garbage collect QML stuff before we start streaming,
// since we'll probably be streaming for a while and we
// won't be able to GC during the stream.
gc()
// Run the streaming session to completion
session.exec(Screen.virtualX, Screen.virtualY)
session.exec(Window.window)
}
sourceComponent: Item {}
@@ -150,6 +188,7 @@ Item {
BusyIndicator {
id: stageSpinner
running: false
}
Label {
+176 -32
View File
@@ -7,7 +7,7 @@ AppModel::AppModel(QObject *parent)
this, &AppModel::handleBoxArtLoaded);
}
void AppModel::initialize(ComputerManager* computerManager, int computerIndex)
void AppModel::initialize(ComputerManager* computerManager, int computerIndex, bool showHiddenGames)
{
m_ComputerManager = computerManager;
connect(m_ComputerManager, &ComputerManager::computerStateChanged,
@@ -15,29 +15,23 @@ void AppModel::initialize(ComputerManager* computerManager, int computerIndex)
Q_ASSERT(computerIndex < m_ComputerManager->getComputers().count());
m_Computer = m_ComputerManager->getComputers().at(computerIndex);
m_Apps = m_Computer->appList;
m_CurrentGameId = m_Computer->currentGameId;
m_ShowHiddenGames = showHiddenGames;
updateAppList(m_Computer->appList);
}
int AppModel::getRunningAppIndex()
int AppModel::getRunningAppId()
{
if (m_CurrentGameId != 0) {
for (int i = 0; i < m_Apps.count(); i++) {
if (m_Apps[i].id == m_CurrentGameId) {
return i;
}
}
}
return -1;
return m_CurrentGameId;
}
QString AppModel::getRunningAppName()
{
if (m_CurrentGameId != 0) {
for (int i = 0; i < m_Apps.count(); i++) {
if (m_Apps[i].id == m_CurrentGameId) {
return m_Apps[i].name;
for (int i = 0; i < m_AllApps.count(); i++) {
if (m_AllApps[i].id == m_CurrentGameId) {
return m_AllApps[i].name;
}
}
}
@@ -47,12 +41,23 @@ QString AppModel::getRunningAppName()
Session* AppModel::createSessionForApp(int appIndex)
{
Q_ASSERT(appIndex < m_Apps.count());
NvApp app = m_Apps.at(appIndex);
Q_ASSERT(appIndex < m_VisibleApps.count());
NvApp app = m_VisibleApps.at(appIndex);
return new Session(m_Computer, app);
}
int AppModel::getDirectLaunchAppIndex()
{
for (int i = 0; i < m_VisibleApps.count(); i++) {
if (m_VisibleApps[i].directLaunch) {
return i;
}
}
return -1;
}
int AppModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
@@ -60,7 +65,7 @@ int AppModel::rowCount(const QModelIndex &parent) const
if (parent.isValid())
return 0;
return m_Apps.count();
return m_VisibleApps.count();
}
QVariant AppModel::data(const QModelIndex &index, int role) const
@@ -68,8 +73,8 @@ QVariant AppModel::data(const QModelIndex &index, int role) const
if (!index.isValid())
return QVariant();
Q_ASSERT(index.row() < m_Apps.count());
NvApp app = m_Apps.at(index.row());
Q_ASSERT(index.row() < m_VisibleApps.count());
NvApp app = m_VisibleApps.at(index.row());
switch (role)
{
@@ -80,6 +85,14 @@ QVariant AppModel::data(const QModelIndex &index, int role) const
case BoxArtRole:
// FIXME: const-correctness
return const_cast<BoxArtManager&>(m_BoxArtManager).loadBoxArt(m_Computer, app);
case HiddenRole:
return app.hidden;
case AppIdRole:
return app.id;
case DirectLaunchRole:
return app.directLaunch;
case AppCollectorGameRole:
return app.isAppCollectorGame;
default:
return QVariant();
}
@@ -92,6 +105,10 @@ QHash<int, QByteArray> AppModel::roleNames() const
names[NameRole] = "name";
names[RunningRole] = "running";
names[BoxArtRole] = "boxart";
names[HiddenRole] = "hidden";
names[AppIdRole] = "appid";
names[DirectLaunchRole] = "directLaunch";
names[AppCollectorGameRole] = "appCollectorGame";
return names;
}
@@ -101,6 +118,138 @@ void AppModel::quitRunningApp()
m_ComputerManager->quitRunningApp(m_Computer);
}
bool AppModel::isAppCurrentlyVisible(const NvApp& app)
{
for (const NvApp& visibleApp : m_VisibleApps) {
if (app.id == visibleApp.id) {
return true;
}
}
return false;
}
QVector<NvApp> AppModel::getVisibleApps(const QVector<NvApp>& appList)
{
QVector<NvApp> visibleApps;
for (const NvApp& app : appList) {
// Don't immediately hide games that were previously visible. This
// allows users to easily uncheck the "Hide App" checkbox if they
// check it by mistake.
if (m_ShowHiddenGames || !app.hidden || isAppCurrentlyVisible(app)) {
visibleApps.append(app);
}
}
return visibleApps;
}
void AppModel::updateAppList(QVector<NvApp> newList)
{
m_AllApps = newList;
QVector<NvApp> newVisibleList = getVisibleApps(newList);
// Process removals and updates first
for (int i = 0; i < m_VisibleApps.count(); i++) {
const NvApp& existingApp = m_VisibleApps.at(i);
bool found = false;
for (const NvApp& newApp : newVisibleList) {
if (existingApp.id == newApp.id) {
// If the data changed, update it in our list
if (existingApp != newApp) {
m_VisibleApps.replace(i, newApp);
emit dataChanged(createIndex(i, 0), createIndex(i, 0));
}
found = true;
break;
}
}
if (!found) {
beginRemoveRows(QModelIndex(), i, i);
m_VisibleApps.removeAt(i);
endRemoveRows();
i--;
}
}
// Process additions now
for (const NvApp& newApp : newVisibleList) {
int insertionIndex = m_VisibleApps.size();
bool found = false;
for (int i = 0; i < m_VisibleApps.count(); i++) {
const NvApp& existingApp = m_VisibleApps.at(i);
if (existingApp.id == newApp.id) {
found = true;
break;
}
else if (existingApp.name.toLower() > newApp.name.toLower()) {
insertionIndex = i;
break;
}
}
if (!found) {
beginInsertRows(QModelIndex(), insertionIndex, insertionIndex);
m_VisibleApps.insert(insertionIndex, newApp);
endInsertRows();
}
}
Q_ASSERT(newVisibleList == m_VisibleApps);
}
void AppModel::setAppHidden(int appIndex, bool hidden)
{
Q_ASSERT(appIndex < m_VisibleApps.count());
int appId = m_VisibleApps.at(appIndex).id;
{
QWriteLocker lock(&m_Computer->lock);
for (NvApp& app : m_Computer->appList) {
if (app.id == appId) {
app.hidden = hidden;
break;
}
}
}
m_ComputerManager->clientSideAttributeUpdated(m_Computer);
}
void AppModel::setAppDirectLaunch(int appIndex, bool directLaunch)
{
Q_ASSERT(appIndex < m_VisibleApps.count());
int appId = m_VisibleApps.at(appIndex).id;
{
QWriteLocker lock(&m_Computer->lock);
for (NvApp& app : m_Computer->appList) {
if (directLaunch) {
// We must clear direct launch from all other apps
// to set it on the new app.
app.directLaunch = app.id == appId;
}
else if (app.id == appId) {
// If we're clearing direct launch, we're done once we
// find our matching app ID.
app.directLaunch = false;
break;
}
}
}
m_ComputerManager->clientSideAttributeUpdated(m_Computer);
}
void AppModel::handleComputerStateChanged(NvComputer* computer)
{
// Ignore updates for computers that aren't ours
@@ -119,20 +268,15 @@ void AppModel::handleComputerStateChanged(NvComputer* computer)
// First, process additions/removals from the app list. This
// is required because the new game may now be running, so
// we can't check that first.
if (computer->appList != m_Apps) {
// Just reset the whole thing if the list changes
beginResetModel();
m_Apps = computer->appList;
m_CurrentGameId = computer->currentGameId;
endResetModel();
return;
if (computer->appList != m_AllApps) {
updateAppList(computer->appList);
}
// Finally, process changes to the active app
if (computer->currentGameId != m_CurrentGameId) {
// First, invalidate the running state of newly running game
for (int i = 0; i < m_Apps.count(); i++) {
if (m_Apps[i].id == computer->currentGameId) {
for (int i = 0; i < m_VisibleApps.count(); i++) {
if (m_VisibleApps[i].id == computer->currentGameId) {
emit dataChanged(createIndex(i, 0),
createIndex(i, 0),
QVector<int>() << RunningRole);
@@ -142,8 +286,8 @@ void AppModel::handleComputerStateChanged(NvComputer* computer)
// Next, invalidate the running state of the old game (if it exists)
if (m_CurrentGameId != 0) {
for (int i = 0; i < m_Apps.count(); i++) {
if (m_Apps[i].id == m_CurrentGameId) {
for (int i = 0; i < m_VisibleApps.count(); i++) {
if (m_VisibleApps[i].id == m_CurrentGameId) {
emit dataChanged(createIndex(i, 0),
createIndex(i, 0),
QVector<int>() << RunningRole);
@@ -161,7 +305,7 @@ void AppModel::handleBoxArtLoaded(NvComputer* computer, NvApp app, QUrl /* image
{
Q_ASSERT(computer == m_Computer);
int index = m_Apps.indexOf(app);
int index = m_VisibleApps.indexOf(app);
// Make sure we're not delivering a callback to an app that's already been removed
if (index >= 0) {
+21 -4
View File
@@ -14,23 +14,33 @@ class AppModel : public QAbstractListModel
{
NameRole = Qt::UserRole,
RunningRole,
BoxArtRole
BoxArtRole,
HiddenRole,
AppIdRole,
DirectLaunchRole,
AppCollectorGameRole,
};
public:
explicit AppModel(QObject *parent = nullptr);
// Must be called before any QAbstractListModel functions
Q_INVOKABLE void initialize(ComputerManager* computerManager, int computerIndex);
Q_INVOKABLE void initialize(ComputerManager* computerManager, int computerIndex, bool showHiddenGames);
Q_INVOKABLE Session* createSessionForApp(int appIndex);
Q_INVOKABLE int getRunningAppIndex();
Q_INVOKABLE int getDirectLaunchAppIndex();
Q_INVOKABLE int getRunningAppId();
Q_INVOKABLE QString getRunningAppName();
Q_INVOKABLE void quitRunningApp();
Q_INVOKABLE void setAppHidden(int appIndex, bool hidden);
Q_INVOKABLE void setAppDirectLaunch(int appIndex, bool directLaunch);
QVariant data(const QModelIndex &index, int role) const override;
int rowCount(const QModelIndex &parent) const override;
@@ -46,9 +56,16 @@ signals:
void computerLost();
private:
void updateAppList(QVector<NvApp> newList);
QVector<NvApp> getVisibleApps(const QVector<NvApp>& appList);
bool isAppCurrentlyVisible(const NvApp& app);
NvComputer* m_Computer;
BoxArtManager m_BoxArtManager;
ComputerManager* m_ComputerManager;
QVector<NvApp> m_Apps;
QVector<NvApp> m_VisibleApps, m_AllApps;
int m_CurrentGameId;
bool m_ShowHiddenGames;
};
+96 -11
View File
@@ -40,6 +40,48 @@ QVariant ComputerModel::data(const QModelIndex& index, int role) const
return !computer->macAddress.isEmpty();
case StatusUnknownRole:
return computer->state == NvComputer::CS_UNKNOWN;
case ServerSupportedRole:
return computer->isSupportedServerVersion;
case DetailsRole: {
QString state, pairState;
switch (computer->state) {
case NvComputer::CS_ONLINE:
state = tr("Online");
break;
case NvComputer::CS_OFFLINE:
state = tr("Offline");
break;
default:
state = tr("Unknown");
break;
}
switch (computer->pairState) {
case NvComputer::PS_PAIRED:
pairState = tr("Paired");
break;
case NvComputer::PS_NOT_PAIRED:
pairState = tr("Unpaired");
break;
default:
pairState = tr("Unknown");
break;
}
return tr("Name: %1").arg(computer->name) + '\n' +
tr("Status: %1").arg(state) + '\n' +
tr("Active Address: %1").arg(computer->activeAddress.toString()) + '\n' +
tr("UUID: %1").arg(computer->uuid) + '\n' +
tr("Local Address: %1").arg(computer->localAddress.toString()) + '\n' +
tr("Remote Address: %1").arg(computer->remoteAddress.toString()) + '\n' +
tr("IPv6 Address: %1").arg(computer->ipv6Address.toString()) + '\n' +
tr("Manual Address: %1").arg(computer->manualAddress.toString()) + '\n' +
tr("MAC Address: %1").arg(computer->macAddress.isEmpty() ? tr("Unknown") : QString(computer->macAddress.toHex(':'))) + '\n' +
tr("Pair State: %1").arg(pairState) + '\n' +
tr("Running Game ID: %1").arg(computer->state == NvComputer::CS_ONLINE ? QString::number(computer->currentGameId) : tr("Unknown")) + '\n' +
tr("HTTPS Port: %1").arg(computer->state == NvComputer::CS_ONLINE ? QString::number(computer->activeHttpsPort) : tr("Unknown"));
}
default:
return QVariant();
}
@@ -66,6 +108,8 @@ QHash<int, QByteArray> ComputerModel::roleNames() const
names[BusyRole] = "busy";
names[WakeableRole] = "wakeable";
names[StatusUnknownRole] = "statusUnknown";
names[ServerSupportedRole] = "serverSupported";
names[DetailsRole] = "details";
return names;
}
@@ -128,6 +172,47 @@ void ComputerModel::wakeComputer(int computerIndex)
QThreadPool::globalInstance()->start(wakeTask);
}
void ComputerModel::renameComputer(int computerIndex, QString name)
{
Q_ASSERT(computerIndex < m_Computers.count());
m_ComputerManager->renameHost(m_Computers[computerIndex], name);
}
QString ComputerModel::generatePinString()
{
return m_ComputerManager->generatePinString();
}
class DeferredTestConnectionTask : public QObject, public QRunnable
{
Q_OBJECT
public:
void run()
{
unsigned int portTestResult = LiTestClientConnectivity("qt.conntest.moonlight-stream.org", 443, ML_PORT_FLAG_ALL);
if (portTestResult == ML_TEST_RESULT_INCONCLUSIVE) {
emit connectionTestCompleted(-1, QString());
}
else {
char blockedPorts[512];
LiStringifyPortFlags(portTestResult, "\n", blockedPorts, sizeof(blockedPorts));
emit connectionTestCompleted(portTestResult, QString(blockedPorts));
}
}
signals:
void connectionTestCompleted(int result, QString blockedPorts);
};
void ComputerModel::testConnectionForComputer(int)
{
DeferredTestConnectionTask* testConnectionTask = new DeferredTestConnectionTask();
QObject::connect(testConnectionTask, &DeferredTestConnectionTask::connectionTestCompleted,
this, &ComputerModel::connectionTestCompleted);
QThreadPool::globalInstance()->start(testConnectionTask);
}
void ComputerModel::pairComputer(int computerIndex, QString pin)
{
Q_ASSERT(computerIndex < m_Computers.count());
@@ -142,19 +227,19 @@ void ComputerModel::handlePairingCompleted(NvComputer*, QString error)
void ComputerModel::handleComputerStateChanged(NvComputer* computer)
{
// If this is an existing computer, we can report the data changed
int index = m_Computers.indexOf(computer);
if (index >= 0) {
// Let the view know that this specific computer changed
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
QVector<NvComputer*> newComputerList = m_ComputerManager->getComputers();
// Reset the model if the structural layout of the list has changed
if (m_Computers != newComputerList) {
beginResetModel();
m_Computers = newComputerList;
endResetModel();
}
else {
// This is a new PC which may be inserted at an arbitrary point
// in our computer list (since it comes from CM's QMap). Reload
// the whole model state to ensure it stays consistent.
beginResetModel();
m_Computers = m_ComputerManager->getComputers();
endResetModel();
// Let the view know that this specific computer changed
int index = m_Computers.indexOf(computer);
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
}
}
#include "computermodel.moc"
+10 -1
View File
@@ -14,7 +14,9 @@ class ComputerModel : public QAbstractListModel
PairedRole,
BusyRole,
WakeableRole,
StatusUnknownRole
StatusUnknownRole,
ServerSupportedRole,
DetailsRole
};
public:
@@ -31,14 +33,21 @@ public:
Q_INVOKABLE void deleteComputer(int computerIndex);
Q_INVOKABLE QString generatePinString();
Q_INVOKABLE void pairComputer(int computerIndex, QString pin);
Q_INVOKABLE void testConnectionForComputer(int computerIndex);
Q_INVOKABLE void wakeComputer(int computerIndex);
Q_INVOKABLE void renameComputer(int computerIndex, QString name);
Q_INVOKABLE Session* createSessionForCurrentGame(int computerIndex);
signals:
void pairingCompleted(QVariant error);
void connectionTestCompleted(int result, QString blockedPorts);
private slots:
void handleComputerStateChanged(NvComputer* computer);
+159 -66
View File
@@ -2,6 +2,7 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2
import QtQuick.Controls.Material 2.2
import ComputerManager 1.0
import AutoUpdateChecker 1.0
@@ -12,12 +13,71 @@ import SdlGamepadKeyNavigation 1.0
ApplicationWindow {
property bool pollingActive: false
// Set by SettingsView to force the back operation to pop all
// pages except the initial view. This is required when doing
// a retranslate() because AppView breaks for some reason.
property bool clearOnBack: false
id: window
visible: true
width: 1280
height: 600
visibility: StreamingPreferences.startWindowed ? "Windowed" : "Maximized"
Component.onCompleted: {
// Override the background color to Material 2 colors for Qt 6.5+
// in order to improve contrast between GFE's placeholder box art
// and the background of the app grid.
if (SystemProperties.usesMaterial3Theme) {
Material.background = "#303030"
}
// Show the window according to the user's preferences
if (SystemProperties.hasDesktopEnvironment) {
if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_MAXIMIZED) {
window.showMaximized()
}
else if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_FULLSCREEN) {
window.showFullScreen()
}
else {
window.show()
}
} else {
window.showFullScreen()
}
// Display any modal dialogs for configuration warnings
if (SystemProperties.isWow64) {
wow64Dialog.open()
}
else if (!SystemProperties.hasHardwareAcceleration) {
if (SystemProperties.isRunningXWayland) {
xWaylandDialog.open()
}
else {
noHwDecoderDialog.open()
}
}
if (SystemProperties.unmappedGamepads) {
unmappedGamepadDialog.unmappedGamepads = SystemProperties.unmappedGamepads
unmappedGamepadDialog.open()
}
}
// This configures the maximum width of the singleton attached QML ToolTip. If left unconstrained,
// it will never insert a line break and just extend on forever.
ToolTip.toolTip.contentWidth: ToolTip.toolTip.implicitContentWidth < 400 ? ToolTip.toolTip.implicitContentWidth : 400
function goBack() {
if (clearOnBack) {
// Pop all items except the first one
stackView.pop(null)
clearOnBack = false
}
else {
stackView.pop()
}
}
StackView {
id: stackView
@@ -34,7 +94,7 @@ ApplicationWindow {
Keys.onEscapePressed: {
if (depth > 1) {
stackView.pop()
goBack()
}
else {
quitConfirmationDialog.open()
@@ -43,7 +103,7 @@ ApplicationWindow {
Keys.onBackPressed: {
if (depth > 1) {
stackView.pop()
goBack()
}
else {
quitConfirmationDialog.open()
@@ -118,45 +178,20 @@ ApplicationWindow {
}
}
property bool initialized: false
// BUG: Using onAfterSynchronizing: here causes very strange
// failures on Linux. Many shaders fail to compile and we
// eventually segfault deep inside the Qt OpenGL code.
onAfterRendering: {
// We use this callback to trigger dialog display because
// it only happens once the window is fully constructed.
// Doing it earlier can lead to the dialog appearing behind
// the window or otherwise without input focus.
if (!initialized) {
// Set initialized before calling anything else, because
// pumping the event loop can cause us to get another
// onAfterRendering call and potentially reenter this code.
initialized = true;
if (SystemProperties.isWow64) {
wow64Dialog.open()
}
else if (!SystemProperties.hasHardwareAcceleration) {
if (SystemProperties.isRunningXWayland) {
xWaylandDialog.open()
}
else {
noHwDecoderDialog.open()
}
}
if (SystemProperties.unmappedGamepads) {
unmappedGamepadDialog.unmappedGamepads = SystemProperties.unmappedGamepads
unmappedGamepadDialog.open()
}
}
// Workaround for lack of instanceof in Qt 5.9.
//
// Based on https://stackoverflow.com/questions/13923794/how-to-do-a-is-a-typeof-or-instanceof-in-qml
function qmltypeof(obj, className) { // QtObject, string -> bool
// className plus "(" is the class instance without modification
// className plus "_QML" is the class instance with user-defined properties
var str = obj.toString();
return str.startsWith(className + "(") || str.startsWith(className + "_QML");
}
function navigateTo(url, objectName)
function navigateTo(url, objectType)
{
var existingItem = stackView.find(function(item, index) {
return item.objectName === objectName
return qmltypeof(item, objectType)
})
if (existingItem !== null) {
@@ -175,8 +210,19 @@ ApplicationWindow {
anchors.topMargin: 5
anchors.bottomMargin: 5
Label {
id: titleLabel
visible: toolBar.width > 700
anchors.fill: parent
text: stackView.currentItem.objectName
font.pointSize: 20
elide: Label.ElideRight
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
}
RowLayout {
spacing: 20
spacing: 10
anchors.leftMargin: 10
anchors.rightMargin: 10
anchors.fill: parent
@@ -187,33 +233,68 @@ ApplicationWindow {
iconSource: "qrc:/res/arrow_left.svg"
onClicked: stackView.pop()
onClicked: goBack()
Keys.onDownPressed: {
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
}
}
// This label will appear when the window gets too small and
// we need to ensure the toolbar controls don't collide
Label {
id: titleLabel
text: stackView.currentItem.objectName
font.pointSize: 15
id: titleRowLabel
font.pointSize: titleLabel.font.pointSize
elide: Label.ElideRight
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
Layout.fillWidth: true
// We need this label to always be visible so it can occupy
// the remaining space in the RowLayout. To "hide" it, we
// just set the text to empty string.
text: !titleLabel.visible ? stackView.currentItem.objectName : ""
}
Label {
id: versionLabel
visible: qmltypeof(stackView.currentItem, "SettingsView")
text: qsTr("Version %1").arg(SystemProperties.versionString)
font.pointSize: 12
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter
}
NavigableToolButton {
id: discordButton
visible: SystemProperties.hasBrowser &&
qmltypeof(stackView.currentItem, "SettingsView")
iconSource: "qrc:/res/discord.svg"
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.text: qsTr("Join our community on Discord")
// TODO need to make sure browser is brought to foreground.
onClicked: Qt.openUrlExternally("https://moonlight-stream.org/discord");
Keys.onDownPressed: {
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
}
}
NavigableToolButton {
id: addPcButton
visible: stackView.currentItem.objectName === "Computers"
visible: qmltypeof(stackView.currentItem, "PcView")
iconSource: "qrc:/res/ic_add_to_queue_white_48px.svg"
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.text: "Add PC manually" + (newPcShortcut.nativeText ? (" ("+newPcShortcut.nativeText+")") : "")
ToolTip.text: qsTr("Add PC manually") + (newPcShortcut.nativeText ? (" ("+newPcShortcut.nativeText+")") : "")
Shortcut {
id: newPcShortcut
@@ -239,17 +320,21 @@ ApplicationWindow {
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.visible: hovered || visible
// Invisible until we get a callback notifying us that
// an update is available
visible: false
onClicked: Qt.openUrlExternally(browserUrl);
onClicked: {
if (SystemProperties.hasBrowser) {
Qt.openUrlExternally(browserUrl);
}
}
function updateAvailable(version, url)
{
ToolTip.text = "Update available for Moonlight: Version " + version
ToolTip.text = qsTr("Update available for Moonlight: Version %1").arg(version)
updateButton.browserUrl = url
updateButton.visible = true
}
@@ -273,7 +358,7 @@ ApplicationWindow {
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.text: "Help" + (helpShortcut.nativeText ? (" ("+helpShortcut.nativeText+")") : "")
ToolTip.text: qsTr("Help") + (helpShortcut.nativeText ? (" ("+helpShortcut.nativeText+")") : "")
Shortcut {
id: helpShortcut
@@ -296,11 +381,11 @@ ApplicationWindow {
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.text: "Gamepad Mapper"
ToolTip.text: qsTr("Gamepad Mapper")
iconSource: "qrc:/res/ic_videogame_asset_white_48px.svg"
onClicked: navigateTo("qrc:/gui/GamepadMapper.qml", "Gamepad Mapping")
onClicked: navigateTo("qrc:/gui/GamepadMapper.qml", "GamepadMapper")
Keys.onDownPressed: {
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
@@ -312,7 +397,7 @@ ApplicationWindow {
iconSource: "qrc:/res/settings.svg"
onClicked: navigateTo("qrc:/gui/SettingsView.qml", "Settings")
onClicked: navigateTo("qrc:/gui/SettingsView.qml", "SettingsView")
Keys.onDownPressed: {
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
@@ -327,31 +412,31 @@ ApplicationWindow {
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.text: "Settings" + (settingsShortcut.nativeText ? (" ("+settingsShortcut.nativeText+")") : "")
ToolTip.text: qsTr("Settings") + (settingsShortcut.nativeText ? (" ("+settingsShortcut.nativeText+")") : "")
}
}
}
ErrorMessageDialog {
id: noHwDecoderDialog
text: "No functioning hardware accelerated H.264 video decoder was detected by Moonlight. " +
"Your streaming performance may be severely degraded in this configuration."
helpText: "Click the Help button for more information on solving this problem."
text: qsTr("No functioning hardware accelerated video decoder was detected by Moonlight. " +
"Your streaming performance may be severely degraded in this configuration.")
helpText: qsTr("Click the Help button for more information on solving this problem.")
helpUrl: "https://github.com/moonlight-stream/moonlight-docs/wiki/Fixing-Hardware-Decoding-Problems"
}
ErrorMessageDialog {
id: xWaylandDialog
text: "Hardware acceleration doesn't work on XWayland. Continuing on XWayland may result in poor streaming performance. " +
"Try running with QT_QPA_PLATFORM=wayland or switch to X11."
helpText: "Click the Help button for more information."
text: qsTr("Hardware acceleration doesn't work on XWayland. Continuing on XWayland may result in poor streaming performance. " +
"Try running with QT_QPA_PLATFORM=wayland or switch to X11.")
helpText: qsTr("Click the Help button for more information.")
helpUrl: "https://github.com/moonlight-stream/moonlight-docs/wiki/Fixing-Hardware-Decoding-Problems"
}
NavigableMessageDialog {
id: wow64Dialog
standardButtons: Dialog.Ok | Dialog.Cancel
text: "This PC is running a 64-bit version of Windows. Please download the x64 version of Moonlight for the best streaming performance."
text: qsTr("This version of Moonlight isn't optimized for your PC. Please download the '%1' version of Moonlight for the best streaming performance.").arg(SystemProperties.friendlyNativeArchName)
onAccepted: {
Qt.openUrlExternally("https://github.com/moonlight-stream/moonlight-qt/releases");
}
@@ -360,9 +445,9 @@ ApplicationWindow {
ErrorMessageDialog {
id: unmappedGamepadDialog
property string unmappedGamepads : ""
text: "Moonlight detected gamepads without a mapping:\n" + unmappedGamepads
text: qsTr("Moonlight detected gamepads without a mapping:") + "\n" + unmappedGamepads
helpTextSeparator: "\n\n"
helpText: "Click the Help button for information on how to map your gamepads."
helpText: qsTr("Click the Help button for information on how to map your gamepads.")
helpUrl: "https://github.com/moonlight-stream/moonlight-docs/wiki/Gamepad-Mapping"
}
@@ -370,7 +455,7 @@ ApplicationWindow {
NavigableMessageDialog {
id: quitConfirmationDialog
standardButtons: Dialog.Yes | Dialog.No
text: "Are you sure you want to quit?"
text: qsTr("Are you sure you want to quit?")
// For keyboard/gamepad navigation
onAccepted: Qt.quit()
}
@@ -400,7 +485,7 @@ ApplicationWindow {
NavigableDialog {
id: addPcDialog
property string label: "Enter the IP address of your GameStream PC:"
property string label: qsTr("Enter the IP address of your host PC:")
standardButtons: Dialog.Ok | Dialog.Cancel
@@ -409,9 +494,13 @@ ApplicationWindow {
editText.forceActiveFocus()
}
onClosed: {
editText.clear()
}
onAccepted: {
if (editText.text) {
ComputerManager.addNewHost(editText.text, false)
ComputerManager.addNewHostManually(editText.text.trim())
}
}
@@ -429,6 +518,10 @@ ApplicationWindow {
Keys.onReturnPressed: {
addPcDialog.accept()
}
Keys.onEnterPressed: {
addPcDialog.accept()
}
}
}
}
+47 -4
View File
@@ -8,13 +8,15 @@
#define AXIS_NAVIGATION_REPEAT_DELAY 150
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation()
: m_Enabled(false),
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation(StreamingPreferences* prefs)
: m_Prefs(prefs),
m_Enabled(false),
m_UiNavMode(false),
m_FirstPoll(false),
m_LastAxisNavigationEventTime(0)
{
m_PollingTimer = new QTimer(this);
connect(m_PollingTimer, SIGNAL(timeout()), this, SLOT(onPollingTimerFired()));
connect(m_PollingTimer, &QTimer::timeout, this, &SdlGamepadKeyNavigation::onPollingTimerFired);
}
SdlGamepadKeyNavigation::~SdlGamepadKeyNavigation()
@@ -61,6 +63,9 @@ void SdlGamepadKeyNavigation::enable()
}
}
// Flush events on the first poll
m_FirstPoll = true;
// Poll every 50 ms for a new joystick event
m_PollingTimer->start(50);
@@ -89,6 +94,16 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
{
SDL_Event event;
// Discard any pending button events on the first poll to avoid picking up
// stale input data from the stream session (like the quit combo).
if (m_FirstPoll) {
SDL_PumpEvents();
SDL_FlushEvent(SDL_CONTROLLERBUTTONDOWN);
SDL_FlushEvent(SDL_CONTROLLERBUTTONUP);
m_FirstPoll = false;
}
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
@@ -104,6 +119,24 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
event.type == SDL_CONTROLLERBUTTONDOWN ?
QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
// Swap face buttons if needed
if (m_Prefs->swapFaceButtons) {
switch (event.cbutton.button) {
case SDL_CONTROLLER_BUTTON_A:
event.cbutton.button = SDL_CONTROLLER_BUTTON_B;
break;
case SDL_CONTROLLER_BUTTON_B:
event.cbutton.button = SDL_CONTROLLER_BUTTON_A;
break;
case SDL_CONTROLLER_BUTTON_X:
event.cbutton.button = SDL_CONTROLLER_BUTTON_Y;
break;
case SDL_CONTROLLER_BUTTON_Y:
event.cbutton.button = SDL_CONTROLLER_BUTTON_X;
break;
}
}
switch (event.cbutton.button) {
case SDL_CONTROLLER_BUTTON_DPAD_UP:
if (m_UiNavMode) {
@@ -157,7 +190,17 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
case SDL_CONTROLLERDEVICEADDED:
SDL_GameController* gc = SDL_GameControllerOpen(event.cdevice.which);
if (gc != nullptr) {
m_Gamepads.append(gc);
// SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same
// gamepad in rare cases, because SDL doesn't fixup the device index in
// the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears
// before we've processed the add event.
if (!m_Gamepads.contains(gc)) {
m_Gamepads.append(gc);
}
else {
// We already have this game controller open
SDL_GameControllerClose(gc);
}
}
break;
}
+5 -1
View File
@@ -5,12 +5,14 @@
#include <SDL.h>
#include "settings/streamingpreferences.h"
class SdlGamepadKeyNavigation : public QObject
{
Q_OBJECT
public:
SdlGamepadKeyNavigation();
SdlGamepadKeyNavigation(StreamingPreferences* prefs);
~SdlGamepadKeyNavigation();
@@ -29,9 +31,11 @@ private slots:
void onPollingTimerFired();
private:
StreamingPreferences* m_Prefs;
QTimer* m_PollingTimer;
QList<SDL_GameController*> m_Gamepads;
bool m_Enabled;
bool m_UiNavMode;
bool m_FirstPoll;
Uint32 m_LastAxisNavigationEventTime;
};
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More