Compare commits

...

536 Commits

Author SHA1 Message Date
Bogdan Seniuc
da47035525 Override default SDL audio ducking option 2024-12-20 15:46:19 -06:00
Cameron Gutman
db9a4ab7c2 Initialize block variables 2024-12-20 15:40:30 -06:00
Cameron Gutman
a528ce7e2a Roll back package metadata version to fix CI 2024-12-20 15:34:17 -06:00
Cameron Gutman
1e0714ce70 Fix reference cycle in HttpManager due to delegate retention
Fixes #654
2024-12-20 15:33:02 -06:00
Cameron Gutman
997525c71e Fix leaks during pairing
Ref: #654
2024-12-20 15:31:45 -06:00
Cameron Gutman
b88cf14b4e Fix leaks from getClientCertificate
Ref: #654
2024-12-20 15:31:12 -06:00
Cameron Gutman
1cfabac4b5 Disable certificate encryption to avoid legacy provider requirement
Closes #646
Fixes #660
2024-12-20 14:43:04 -06:00
Cameron Gutman
42518301f7 Update OpenSSL package 2024-12-20 14:18:15 -06:00
alexhaugland
022352c166
Upgrade OpenSSL so it works on visionOS (#635)
* Switch OpenSSL so it works on visionOS
* Fix cert generation to work with OpenSSL 3
* Update gitignore
2024-07-10 19:51:16 -05:00
Cameron Gutman
557765f2c0 Version 9.0.2 2024-02-25 16:46:42 -06:00
Cameron Gutman
c3ad7578fe Update moonlight-common-c to resolve build warning 2024-02-25 16:44:47 -06:00
Cameron Gutman
7df349ad7c Improve smooth scrolling precision 2024-02-25 16:25:56 -06:00
Marc Davis
855f48b455 mapped the Globe/Language key to Escape 2024-02-25 15:49:48 -06:00
Marc Davis
dd5d233993 yes 0x0D is the correct code for Enter according to Microsoft's documentation 2024-02-25 15:49:48 -06:00
Cameron Gutman
796f87713f Update moonlight-common-c with RTSP encryption and QoS improvements 2024-02-25 15:44:35 -06:00
Cameron Gutman
38259af3f1 Remove xcpretty in CI 2024-02-17 17:17:05 -06:00
Cameron Gutman
08279d825c Update AppVeyor images 2024-02-17 14:40:01 -06:00
Cameron Gutman
7465835808 Remove CPU core count check
Decryption seems fast enough for all reasonable bitrates even on dual-core devices.
2024-01-28 14:37:03 -06:00
Cameron Gutman
303303bf6b Update moonlight-common-c with finalized encryption changes 2024-01-19 19:18:21 -06:00
Cameron Gutman
9b28981b59 Opt in for video encryption on A10 and later SoCs 2024-01-15 15:21:56 -06:00
Cameron Gutman
5501d85762 Update moonlight-common-c with new encryption support 2024-01-15 15:11:32 -06:00
Cameron Gutman
cc799768ef Fix signing metadata for iOS 2023-12-29 23:36:40 -06:00
Cameron Gutman
ae1c290b79 Version 9.0.1 2023-12-29 22:33:58 -06:00
Cameron Gutman
62c6661267 Update moonlight-common-c for X-SS-Connect-Data support 2023-12-29 22:32:39 -06:00
Cameron Gutman
485c5e10db Update moonlight-common-c with fix for v4-mapped v6 addresses 2023-12-28 16:13:36 -06:00
Cameron Gutman
e69cd3dbbc Define __APPLE_USE_RFC_3542 at the project level for IPV6_PKTINFO
For some reason, the definition in unix.c is not working as expected.
2023-12-27 22:27:09 -06:00
Cameron Gutman
e05a6e4ec1 Update moonlight-common.xcodeproj to recommended build settings 2023-12-27 22:17:22 -06:00
Cameron Gutman
77485f2d8d Display error codes when the connection is terminated 2023-12-22 14:46:23 -06:00
Cameron Gutman
951289a802 Don't consume stylus events unless they're supported by the host
Fixes #595
2023-12-22 14:03:22 -06:00
Cameron Gutman
6f40922704 Version 9.0.0 2023-12-06 21:12:50 -06:00
Cameron Gutman
27ac6c0128 Set Game application category 2023-12-06 20:34:33 -06:00
Cameron Gutman
1f543325f8 Rewrite the OSC merging logic 2023-12-06 19:42:51 -06:00
Cameron Gutman
73d4199917 Implement immediate controller arrival and battery events 2023-12-06 19:12:04 -06:00
Cameron Gutman
e0808d6bfc Remove codec options that are not supported 2023-12-03 20:30:40 -06:00
Cameron Gutman
86919bd263 Enable reference frame invalidation for AV1 2023-12-03 20:21:41 -06:00
Cameron Gutman
401d9fbae7 Update moonlight-common-c with new bitrate logic 2023-12-03 20:21:12 -06:00
Cameron Gutman
bbc89011d4 Don't hardcode server signature length 2023-11-29 23:04:44 -06:00
Cameron Gutman
a2f470ddeb Raise toggleable keys upon dismissal of keyboard
Fixes #591
2023-11-29 21:16:09 -06:00
Cameron Gutman
b20079a165 Fix build warning on tvOS 2023-11-06 19:21:38 -06:00
Cameron Gutman
01b349d8d0 Check that a sequence header OBU was present in the IDR frame 2023-11-06 19:18:41 -06:00
Cameron Gutman
089b424f65 Rework CMVideoFormatDescription handling to fix several bugs
- Populate CMVideoFormatDescription with data parsed directly from sequence header OBU
- Recreate AV1 CMVideoFormatDescription for each IDR frame (same as H.264/HEVC) to fix HDR-SDR transitions
- Fixed leaking the format description on each IDR frame
2023-11-06 19:09:56 -06:00
Cameron Gutman
c51caba1ec Rebuild FFmpeg with AV1 CBS compiled in 2023-11-06 19:00:13 -06:00
Cameron Gutman
cb26398414 Download required platforms at build-time if not present 2023-11-04 03:44:25 -05:00
Cameron Gutman
8cd931cf50 Run tvOS builds on Big Sur until AppVeyor fixes Xcode on the Monterey image 2023-11-04 03:29:52 -05:00
Cameron Gutman
06fc3ec5dc Update CI to macOS Monterey image 2023-11-04 03:23:47 -05:00
Cameron Gutman
3ebcc86f0d Fix simulator builds and update to libopus v1.4
- Split library search paths into simulator and native targets
- Fixed incorrectly removed arm64 split from SDL simulator libraries
- Added simulator builds for opus libraries
2023-11-04 03:15:59 -05:00
Cameron Gutman
b81ea6b874 Write the AV1CodecConfigurationBox data into the CMFormatDescription extensions 2023-11-04 01:10:35 -05:00
Cameron Gutman
75a7b9e477 Add guards around AV1 checks 2023-11-04 01:08:56 -05:00
Cameron Gutman
ce25a66dc5 Bump SDL to 2.28.5 and add FFmpeg for AV1 parsing 2023-11-04 01:08:23 -05:00
Cameron Gutman
9366c763d6 Update moonlight-common-c with multi-homed host fix 2023-11-03 23:14:51 -05:00
Cameron Gutman
6974cda328 Extend codec configuration option for AV1 support 2023-11-03 23:13:44 -05:00
Cameron Gutman
0a59ce0ca9 Create a basic AV1 extension dictionary
We may also need the AV1CodecConfigurationBox though.
2023-10-20 17:11:02 -05:00
Cameron Gutman
628252ed28 Update moonlight-common-c 2023-10-20 17:04:15 -05:00
Cameron Gutman
2c76654841 Refactor decoder interface to pass decode unit into VideoDecoderRenderer 2023-10-20 17:04:06 -05:00
Cameron Gutman
f20d90791a Change AV1 bitrate multiplier to match HEVC 2023-10-15 15:37:45 -05:00
Cameron Gutman
2df60e571c Add support for H.264/HEVC bitstreams with multiple sets of parameter set NALUs 2023-10-13 23:39:26 -05:00
Cameron Gutman
0879bf0583 Update moonlight-common-c 2023-10-13 23:38:11 -05:00
Cameron Gutman
7c77a385cf Don't hit test against invisible controls
Fixes #568
2023-09-29 02:17:32 -05:00
Cameron Gutman
b9dbfdd82f Offset WoL ports when the host is using alternate ports 2023-09-29 01:52:47 -05:00
Cameron Gutman
5d9fa4d003 Revert "iPadOS External Display Fullscreen Support (#557)"
This breaks App Store Guidelines because we don't support all device orientations.

This reverts commit ff40bc105e1324de9c633131530767a0a8b070dc.
2023-09-29 01:35:23 -05:00
Cameron Gutman
40938d198f Sync bitrate logic with Moonlight Qt 2023-09-29 01:28:02 -05:00
Cameron Gutman
a46e7fa100 Link to a website we control rather than directly to Nvidia's knowledge base 2023-09-29 01:27:33 -05:00
Cameron Gutman
043bf735e8 Fix a few bugs in the new resolution options and remove dead code 2023-09-29 01:23:35 -05:00
Cameron Gutman
a342c294a1 Swap safe area and full resolution options to keep ascending order 2023-09-29 01:08:18 -05:00
goob47
f8a76e4584
Add support for full screen and safe area resolutions (#577)
Display full width x height in label below the resolution switcher
2023-09-29 01:03:47 -05:00
Cameron Gutman
d6ee43dab5 Fixups for keyboard toolbar feature 2023-09-29 00:50:35 -05:00
goob47
884deb9244
Add a toolbar above the on-screen keyboard with extra keys that are missing from iOS keyboard (#576)
* Add required images to assets

* Add toolbar above keyboard with more key options

* Fix tvOS errors
2023-09-29 00:49:35 -05:00
Cameron Gutman
514e415956 Add handling for Apple TV D-Pad
Fixes #569
2023-09-28 23:54:28 -05:00
Cameron Gutman
95dcbf6024 Add workaround for old Xcode version in AppVeyor 2023-09-28 23:37:36 -05:00
Cameron Gutman
9d0dc49fd2 Implement controller LED support 2023-09-27 08:52:26 -05:00
Cameron Gutman
7249854641 Rework gamepad handling
- Fix accelerometer axis direction
- Fix touchpad input coordinates
- Use physicalInputProfile instead of casting to specific GC classes
- Remove deprecated GCGamepad support
2023-09-27 07:12:36 -05:00
Cameron Gutman
11da9e0eea Add native Apple Pencil support using Sunshine protocol extensions 2023-09-27 05:54:17 -05:00
Cameron Gutman
4f9eb6ea04 Implement host processing time in stats overlay 2023-09-27 03:57:49 -05:00
Cameron Gutman
f883f5a2b5 Fix axis values for gyro input 2023-09-27 03:42:05 -05:00
Cameron Gutman
3fb328e238 Fix for old Xcode version in CI 2023-09-24 20:55:08 -04:00
empireslayer000
ff40bc105e
iPadOS External Display Fullscreen Support (#557) 2023-09-24 20:48:42 -04:00
Cameron Gutman
957ce6095e Basic AV1 plumbing 2023-09-18 21:24:12 -05:00
Cameron Gutman
d1c35144e1 Update moonlight-common-c 2023-09-18 21:20:45 -05:00
Cameron Gutman
65bf4ca6b1 Fix controller touch events being sent as normal touch events 2023-07-01 01:32:00 -05:00
Cameron Gutman
ef5c3d36d3 Implement controller motion sensor support
Axis values probably still need to be swapped around to match other platforms
2023-06-29 00:35:35 -05:00
Cameron Gutman
d48690b320 Implement controller touchpad support 2023-06-29 00:17:43 -05:00
Cameron Gutman
b279caa00b Fix touchpad button flag 2023-06-28 23:51:24 -05:00
Cameron Gutman
cc16186eed Implement extended gamepad buttons and controller metadata support 2023-06-28 23:46:39 -05:00
Cameron Gutman
20d0087bdc Plumb trigger rumble and motion sensor callbacks 2023-06-28 21:27:46 -05:00
Cameron Gutman
4f3f27287c Remove legacy GCGamepad profile 2023-03-05 22:49:06 -06:00
Cameron Gutman
9f7ebdc771 Version 8.5.0 2023-03-05 22:47:48 -06:00
Cameron Gutman
ba723816a1 Deregister GCMouse scroll callbacks 2023-03-05 19:45:29 -06:00
Cameron Gutman
c57e89a0bd Implement Start+Select+L1+R1 shortcut to quit
Fixes #548
2023-03-05 19:10:28 -06:00
Cameron Gutman
7ddf4e12ed Implement horizontal scrolling for Apple TV 2023-03-05 18:57:58 -06:00
Cameron Gutman
4f265cd09f Rebuild libopus without LTO and float approximations 2023-03-05 15:25:44 -06:00
Cameron Gutman
69081367e4 Update to libopus 1.3.1 2023-03-05 14:57:30 -06:00
Cameron Gutman
83fd8225e4 Add GameStream EOL link 2023-03-05 14:19:32 -06:00
Cameron Gutman
2c422c77fb Add Sunshine note to pairing dialog 2023-03-05 14:17:23 -06:00
Cameron Gutman
5c47cb8908 Update to OpenSSL 1.1.1t 2023-03-05 14:15:15 -06:00
Cameron Gutman
924e79d00f Update moonlight-common-c 2023-03-04 12:12:35 -06:00
Cameron Gutman
bdb7d08c57 Don't request IDR frame if the HDR metadata change was a no-op 2023-03-04 12:11:33 -06:00
Cameron Gutman
64803d9715 Tell the host if we want gamepads to persist after disconnection 2023-02-20 16:32:01 -06:00
oxkenshin
2462126963
Fix mouse speed too slow on iPad (#532)
* Fix mouse speed too slow on iPad

Fixes #491
2023-02-20 16:02:58 -06:00
Cameron Gutman
0e40e4795a Implement horizontal scrolling 2023-02-20 16:00:03 -06:00
Cameron Gutman
5c844d3d1f Pass SS_KBE_FLAG_NON_NORMALIZED when sending key events from characters 2023-02-03 00:01:18 -06:00
Cameron Gutman
6d7a8df54f Downgrade CI to Big Sur to fix missing tvOS targets 2023-02-02 23:57:18 -06:00
Cameron Gutman
9eae79f69c Add Sunshine references 2023-02-02 23:35:10 -06:00
Cameron Gutman
a04e1ebb3b Consolidate launch and resume handling for Sunshine 2023-02-02 23:13:59 -06:00
Cameron Gutman
dbb3087078 Don't suppress high refresh rates with Sunshine 2023-02-02 23:13:09 -06:00
Cameron Gutman
eefe8522c4 Plumb HDR metadata from Sunshine 2023-02-02 23:11:27 -06:00
Cameron Gutman
cf665ec774 Try to fix CI 2023-02-02 22:16:25 -06:00
Cameron Gutman
da4f41291e Fix handling of older IPv6 addresses 2023-02-02 22:12:45 -06:00
Cameron Gutman
9a03dd184a Fix infinite loop of retries when multiple hosts are not resolving 2023-02-02 21:56:26 -06:00
Cameron Gutman
4f03dd8c08 Implement support for alternate ports with Sunshine
Fixes #529
2023-02-02 21:54:52 -06:00
Yannick B
a2b15ed2ac Adding more Bitrate options to tvOS
Added bitrate value options of 70 and 80 Mbps in the Root.plist file specific to Moonlight TV.
2023-02-02 20:55:56 -06:00
Cameron Gutman
1c90ee607a Bump tvOS version too 2022-12-06 17:34:15 -06:00
Cameron Gutman
4f7b81335d Version 8.4.1 2022-12-06 17:25:13 -06:00
Cameron Gutman
eab25181e3 Update moonlight-common-c to fix streaming from Sunshine 2022-12-06 17:23:44 -06:00
Cameron Gutman
9b234bc867 Version 8.4.0 2022-12-04 17:34:00 -06:00
Cameron Gutman
c7badef9d7 Allow pairing with Sunshine hosts while streaming 2022-12-04 16:54:37 -06:00
Cameron Gutman
365f61b393 Fix undo menu appearing when opening the keyboard on iOS 16 2022-12-02 22:54:08 -06:00
Cameron Gutman
02e088ddb2 Fix suppression of right clicks when activating the keyboard 2022-12-02 22:03:42 -06:00
Cameron Gutman
be0c071fb5 Update moonlight-common-c 2022-12-02 20:41:40 -06:00
Felipe Cavalcanti
71b953cdd2 Fix black screen in HDR mode in newer AppleTV 4K Models 2022-12-02 20:39:29 -06:00
Cameron Gutman
3494962bc0 Version 8.3.1 2022-10-09 17:52:54 -05:00
Cameron Gutman
7c65bfcc77 Update moonlight-common-c for speculative RFI support 2022-10-09 17:34:17 -05:00
Cameron Gutman
bff3fd5f6c Version 8.3.0 2022-10-04 21:04:18 -05:00
Cameron Gutman
c8907b8ab8 Add special error text for ML_ERROR_FRAME_CONVERSION 2022-10-04 20:32:23 -05:00
Cameron Gutman
66f8b6f40c Update moonlight-common-c with additional GFE 3.26 fixes 2022-10-04 20:23:26 -05:00
Cameron Gutman
6eaf9274b8 Upgrade project to Xcode 14 defaults
This drops support for iOS 11 and below (which appears to have already happened on the App Store side anyway)
2022-10-04 20:22:37 -05:00
Cameron Gutman
dbc83234e9 Update moonlight-common-c 2022-10-03 23:10:56 -05:00
Cameron Gutman
054b3ae45e Enable RFI for HEVC only 2022-10-02 23:20:59 -05:00
Cameron Gutman
1f5ecdf1ea Default to HEVC enabled on iOS 2022-10-02 23:15:16 -05:00
Cameron Gutman
490abc320c Version 8.2.0 2022-09-28 18:17:51 -05:00
Cameron Gutman
f99381df81 Only enable RFI at resolutions at or below 1080p due to bugs 2022-09-28 17:59:18 -05:00
Cameron Gutman
842b6b3c76 Remove stale function definition 2022-09-28 17:57:44 -05:00
Cameron Gutman
f9a2eb022f Display HDR/SDR status in the performance overlay 2022-09-28 17:43:38 -05:00
Cameron Gutman
d896101ed2 Try to recover if the frame header parsing fails 2022-09-28 17:43:17 -05:00
Cameron Gutman
2ae79c5827 Rewrite buffer patching logic to avoid leaking if the first NALU has an unexpected offset 2022-09-28 17:42:48 -05:00
Cameron Gutman
c21f638399 Fix large frame header size for GFE 3.26 2022-09-23 00:03:46 -05:00
Cameron Gutman
6d94c8515e Fix mishandling of IDR frames with a SEI or AUD NAL 2022-09-12 00:05:55 -05:00
Cameron Gutman
65e40279ea Fix handling of 3 byte Annex B start sequences 2022-09-05 18:55:16 -05:00
Starlank
0bd81b8261 Added 1440p resolution option 2022-08-17 22:38:00 -05:00
Cameron Gutman
ac801e9bfb Re-enable the tvOS's HEVC option (defaulted to enabled)
Fixes #481
2022-08-01 20:01:41 -05:00
Cameron Gutman
6678488edc Implement ABXY swap for on-screen controls 2022-07-21 20:54:57 -05:00
Cameron Gutman
a80fa5cfbb Fix some minor issues with ABXY swap feature 2022-07-21 20:36:31 -05:00
IonBlade2K
b9e0b28adc
Add setting to swap A<->B and X<->Y buttons (#513)
* Added toggle for swapping A<->B and X<->Y buttons to enable proper button mapping for combined Joy-Cons in iOS16, where iOS level remapping is not supported and pushing Switch B (bottom face button) sends Xbox B (right face button) instead of Xbox A (bottom face button), etc.  Allows user to select between current behavior (button letter matches output) and muscle-memory behavior (face button pressed matches location of face button output)
2022-07-21 20:09:22 -05:00
Cameron Gutman
eb801b553f Use newer AppVeyor machine image 2022-05-18 00:39:24 -05:00
Cameron Gutman
9cc7972d11
Update README.md 2022-04-05 19:52:30 -05:00
Cameron Gutman
1b2a2ebddf Version 8.1.0 (iOS) 2022-03-27 15:57:18 -05:00
Cameron Gutman
3b0d80bce2 Fix crash during display layer reinitialization 2022-03-27 14:14:19 -05:00
Cameron Gutman
9ea5e2ec99 Fix CI build 2022-03-27 13:34:06 -05:00
Cameron Gutman
e79faba87d Ensure the HEVC selector is set appropriately upon startup 2022-03-27 13:29:51 -05:00
Cameron Gutman
11b180d1e3 Fix HDR selector state upon app restart 2022-03-27 13:25:04 -05:00
Cameron Gutman
54d1851c78 Add HDR toggle for iOS 2022-03-27 13:18:03 -05:00
Cameron Gutman
0d57bd1015 Version 8.0.0 2022-02-13 15:15:31 -06:00
Cameron Gutman
3a77bf3e65 Implement dynamic display mode changes for Apple TV 2022-02-13 14:27:17 -06:00
Cameron Gutman
d7673075b2 Build with iOS 15 SDK on the BigSur AppVeyor image 2022-02-12 20:07:25 -06:00
Cameron Gutman
6fb6b9bf38 Don't pace frame delivery if the display refresh rate has dropped 2022-02-12 19:14:06 -06:00
Cameron Gutman
6435afd229 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:05:58 -06:00
Cameron Gutman
bfdfdc3050 Enforce 256x256 minimum for streaming 2022-02-06 21:09:22 -06:00
Cameron Gutman
d12c103117 Additional custom resolution limits and warning text 2022-02-06 20:40:55 -06:00
Cameron Gutman
e3bce9cec3 Additional wording tweaks to frame pacing settings 2022-02-06 20:12:06 -06:00
Cameron Gutman
fc73663253 Improve custom resolution support 2022-02-06 19:49:04 -06:00
hbouhadji
b7ba94f77a ui fix resolutionSelector auto width 2022-02-06 19:07:11 -06:00
hbouhadji
29ba055024 dialog for custom resolution 2022-02-06 19:07:11 -06:00
hbouhadji
7f7770a42c Added support for native stream resolution 2022-02-06 19:06:58 -06:00
Cameron Gutman
77c6ca2993 Add scroll view to iPadOS settings 2022-02-06 18:48:17 -06:00
Cameron Gutman
edf449b708 Cap selected channel count at physical maximum 2022-02-06 18:00:14 -06:00
Cameron Gutman
72292dde94 Fix iOS build 2022-02-06 17:59:32 -06:00
Cameron Gutman
ff4f9e2bcb Tweak wording on surround options 2022-02-06 17:59:22 -06:00
Nitropud
701c83d79c Fix for: Surround sound audio on Apple TV #371
Added audio configuration option to the settings menu to allow users to select their speaker setup.
2022-02-06 17:52:06 -06:00
Cameron Gutman
87be7080cb Tweak frame pacing option text to be more clear 2022-02-06 17:35:53 -06:00
Cameron Gutman
736485616c Merge branch 'vsync' 2022-02-06 17:13:03 -06:00
Cameron Gutman
f21c58306e Preserve stream aspect ratio even when host resolution changes 2022-02-06 16:57:23 -06:00
Felipe Cavalcanti
7d6cb247b8 Add Frame Pacing feature 2022-02-02 13:37:07 -03:00
Cameron Gutman
bd582aa6c0 Switch to a pull-based renderer and render from CADisplayLink callback 2022-01-22 16:20:31 -06:00
Cameron Gutman
445c026ea9 Add xcschemes to .gitignore 2022-01-22 15:53:37 -06:00
Cameron Gutman
bd313d97cb Clean up new audio code 2022-01-22 15:49:52 -06:00
Cameron Gutman
5055a6db1d Fix SDL initialization on tvOS 2022-01-14 19:01:03 -06:00
Cameron Gutman
8391c766c7 Switch to SDL for audio output 2022-01-13 22:00:47 -06:00
Cameron Gutman
eccf517dc3 Fix scroll speed on recent GFE versions 2021-12-12 16:33:19 -06:00
Cameron Gutman
90d416ab34 Make GCMouse scroll direction consistent with UIPanGestureRecognizer 2021-12-12 16:28:21 -06:00
Cameron Gutman
283a5516d8 Fix erratic scroll movement when beginning a scroll gesture 2021-12-12 16:16:46 -06:00
Cameron Gutman
dee18fb5c2
Add building instructions 2021-10-16 14:18:04 -05:00
Cameron Gutman
c99ee24c65 Restore GCMouse scroll handling for tvOS 2021-10-15 22:32:32 -05:00
Cameron Gutman
76ef2ed432 Version 7.2.0 2021-10-12 19:27:46 -05:00
Cameron Gutman
92a2bbe28e Send Command key to host rather than treating it as Control
Fixes #464
2021-10-12 19:01:14 -05:00
Cameron Gutman
3dd0e8362a Xcode plist reorganization 2021-10-06 23:39:23 -05:00
Cameron Gutman
cea8ed485f Improve scrolling behavior for continuous scroll input 2021-10-06 23:28:29 -05:00
Cameron Gutman
505d248472 Improve scrolling behavior for discrete scroll input 2021-10-06 23:20:42 -05:00
Cameron Gutman
3722de4011 Fix navigation bar color when building with iOS 15 SDK 2021-10-05 22:28:41 -05:00
Cameron Gutman
3f530afca4 Add CADisableMinimumFrameDurationOnPhone for iPhone 120 Hz support 2021-10-05 21:43:54 -05:00
Cameron Gutman
d7cf8ced25 Go back to UIPanGestureRecognizer for all scroll events
GCMouse is broken in iPad 15 for mice with discrete scroll wheel events
2021-10-05 21:42:37 -05:00
Cameron Gutman
c930a4656a Switch to X1Kit fork with Xcode 13 fixes 2021-10-05 21:08:10 -05:00
Cameron Gutman
e80a4fd2b1 Add support for Unicode text input 2021-08-10 01:01:51 -05:00
Cameron Gutman
68e6690e55 Version 7.1.3 b2 2021-07-09 23:23:51 -05:00
Cameron Gutman
6c45a5c43a Actually update the moonlight-common-c submodule 2021-07-09 23:20:14 -05:00
Cameron Gutman
6490bb6d67 Version 7.1.3 2021-07-09 23:18:29 -05:00
Cameron Gutman
93bcd8615c Update moonlight-common-c to remove SEI NALs 2021-07-09 23:05:25 -05:00
Cameron Gutman
0fe84a7a1e Remove key frame detection logic
Moonlight-common-c already tells us whether a frame is an IDR or not
2021-07-09 17:43:36 -05:00
Cameron Gutman
7ed6b22cac Pass RTSP session URL to moonlight-common-c for dynamic ports 2021-07-02 17:31:45 -05:00
Cameron Gutman
295cf61727 Version 7.1.2 2021-06-20 17:14:00 -05:00
Cameron Gutman
c234c82e63 Update moonlight-common-c with performance improvements and legacy GFE compatibility 2021-06-20 16:48:40 -05:00
Cameron Gutman
e143dff76a Version 7.1.1 2021-06-04 18:54:51 -05:00
Cameron Gutman
d317cdc476 Update moonlight-common-c with audio FEC support 2021-06-03 21:19:01 -05:00
Cameron Gutman
b29259a330 Version 7.1.0 2021-05-19 22:20:53 -05:00
Cameron Gutman
f804d000f9 Update moonlight-common-c to avoid excessive ENet retransmissions when RTT variance is 0 2021-05-16 15:42:20 -05:00
Cameron Gutman
9baaa10417 Update moonlight-common-c with with more accurate RTTs and minRequiredFecPackets 2021-05-16 14:51:17 -05:00
Cameron Gutman
073873f681 Add network latency to stats overlay 2021-05-15 17:22:46 -05:00
Cameron Gutman
ab5a0a4470 Version 7.0.8 2021-05-06 23:57:36 -05:00
Cameron Gutman
fd1db224cb Update moonlight-common-c with audio latency fix 2021-05-06 23:56:38 -05:00
Cameron Gutman
2d8d176160 Disable reference frame invalidation on tvOS and always enable HEVC (for now)
Reference frame invalidation seems to trigger a renderer hang on tvOS 14.5 in my testing.
Since we don't have RFI to bias us toward H.264, let's use HEVC all the time now.

This may change again if the RFI issues are sorted out (perhaps we need to implement
blocking waits for invalidated frames?)
2021-05-06 23:56:08 -05:00
Cameron Gutman
a4035c18b5 Switch stream exit button to Play/Pause on Apple TV
It appears it's no longer possible to get a double-press for the Menu button on tvOS 14.5

Fixes #456
2021-05-06 23:42:52 -05:00
Cameron Gutman
05aedd5510 Version 7.0.7 2021-04-29 20:17:58 -05:00
Cameron Gutman
fd5426b7e8 Update moonlight-common-c with RTSP handshake retry logic 2021-04-29 18:47:24 -05:00
Cameron Gutman
651559727f Version 7.0.6 2021-04-27 18:41:23 -05:00
Cameron Gutman
76751dbee2 Update moonlight-common-c with multi-FEC support 2021-04-27 18:37:09 -05:00
Cameron Gutman
1c3d072b49 Add audio stream encryption 2021-04-23 19:07:27 -05:00
Cameron Gutman
d88321263f Update moonlight-common-c 2021-04-18 19:18:42 -05:00
Cameron Gutman
867777468f Version 7.0.5 2021-04-09 19:48:14 -05:00
Cameron Gutman
d52703c20e Update moonlight-common-c for initial GFE 3.22 compatibility 2021-04-09 19:37:27 -05:00
Cameron Gutman
3e90e2ebf2 Version 7.0.4 2021-04-03 13:22:09 -05:00
Cameron Gutman
16acd71f6a Disable system gestures on gamepad buttons while streaming 2021-04-03 12:54:08 -05:00
Cameron Gutman
4079af5d22 Update moonlight-common-c to pick up AMF HEVC parsing fix 2021-03-31 20:06:03 -05:00
Cameron Gutman
97f96bb116 Migrate to AppVeyor 2021-03-03 17:14:20 -06:00
Cameron Gutman
81b9a3e859 Migrate from travis-ci.org to travis-ci.com 2021-03-03 01:54:31 -06:00
Cameron Gutman
5da55d88c5 Update template to direct to troubleshooting page 2021-03-03 01:39:31 -06:00
Cameron Gutman
1fdbd84cd4 Add issue templates 2021-03-03 01:21:55 -06:00
Cameron Gutman
a66d6eb11b Version 7.0.3 2021-02-02 18:50:31 -06:00
Cameron Gutman
d92437cfc9 Update moonlight-common-c 2021-02-02 18:05:01 -06:00
Cameron Gutman
f719e080f9
Merge pull request #448 from ascagnel/tweak-tvos-icons
tweak tvOS icons
2021-02-02 18:00:48 -06:00
Cameron Gutman
b7740eaffd
Merge pull request #447 from mlostekk/fix/memLeaks
nil'ing observer references
2021-02-02 18:00:30 -06:00
Andrew Scagnelli
7b89d3813b tweaking gradient 2021-01-24 11:48:18 -05:00
Andrew Scagnelli
b51cd67327 tweak tvOS icons
add a gradient background so the app icon fits in a little better with
tvOS 14
2021-01-24 11:33:56 -05:00
Martin Mlostek
6e480a46a0
nil'ing observer references 2021-01-23 22:05:58 +01:00
Cameron Gutman
a3fe8e23f1 Enable some restricted key combos to pass through to the PC 2021-01-12 18:44:32 -06:00
Cameron Gutman
e76344812e Don't lock enhancement requests 2021-01-01 13:21:40 -06:00
Cameron Gutman
eed2b82230 Add configuration for GitHub lock bot 2021-01-01 13:08:42 -06:00
Cameron Gutman
ecd3427767 Add handling for above 4K resolutions 2020-12-24 13:33:54 -06:00
Cameron Gutman
311bf33e84 Add special error text for an unexpected early termination 2020-12-24 12:48:10 -06:00
Cameron Gutman
ea96bac31a Display failing ports when connection fails 2020-12-23 14:48:20 -06:00
Cameron Gutman
f09b2fd222 Use LiStringifyPortFlags() rather than coding it ourselves 2020-12-23 14:39:51 -06:00
Cameron Gutman
8b8bc2f818 Version 7.0.2 (iOS) 2020-12-18 17:10:29 -06:00
Cameron Gutman
949f088ef5 Fix dragging mouse on iOS 13
Fixes #440
2020-12-18 17:10:16 -06:00
Cameron Gutman
e29313d9b6 Version 7.0.1 (iOS) 2020-12-07 21:45:55 -06:00
Cameron Gutman
9e669d13fa Suppress all kbProductivity gesture recognizers 2020-12-07 21:10:30 -06:00
Cameron Gutman
015cfecdd6 Fix 3 finger taps causing the editing toolbar to appear 2020-12-07 20:54:24 -06:00
Cameron Gutman
c623d40600 Update moonlight-common-c submodule 2020-12-07 20:08:31 -06:00
Cameron Gutman
65293dab30 Fix race condition during PC detection 2020-12-06 00:56:16 -06:00
Cameron Gutman
f3635a515c Version 7.0.1 (tvOS) 2020-12-05 21:06:50 -06:00
Cameron Gutman
6b823e155a Don't emulate an OSC controller if absolute touch mode is enabled 2020-12-05 20:49:35 -06:00
Cameron Gutman
03f330ccff Fix keyboard input on tvOS
Fixes #434
2020-12-05 20:48:58 -06:00
Cameron Gutman
c301891ff5 Fix stats overlay being off by 1 FPS 2020-12-05 20:38:30 -06:00
Cameron Gutman
1ba1ad64ec Version 7.0.0 2020-11-28 22:32:01 -06:00
Cameron Gutman
1f24d28ddd Update quit tip text for Apple TV 2020-11-28 20:23:15 -06:00
Cameron Gutman
e9e03c74e2 Fix long pressing apps on tvOS 2020-11-28 20:16:26 -06:00
Cameron Gutman
0c6c3ccc83 Disable resizing the view for the keyboard size 2020-11-28 18:50:54 -06:00
Cameron Gutman
07b8e7fd50 Minor UI tweaks 2020-11-28 18:41:44 -06:00
Cameron Gutman
60a6582380 Fix conflicting touch action handling on UIAppView and UIComputerView 2020-11-14 17:03:22 -06:00
Cameron Gutman
f5e0443abb Hide shadows on hidden app tiles 2020-11-14 16:46:00 -06:00
Cameron Gutman
9b8a179f4a Perform the initial updateLoop iteration immediately after attaching the view 2020-11-14 16:42:17 -06:00
Cameron Gutman
78f2b8ac47 Enable right-click context menus on iPadOS 2020-11-14 15:57:16 -06:00
Cameron Gutman
dc9b5b7c96 Remove @available checks for < iOS 9.3 2020-11-14 15:27:49 -06:00
Cameron Gutman
313af5a7e7 Fix popover dialog not correctly anchoring to the UIComputerView on iPad
The view was being replaced after the UIAlertController was anchored to it
2020-11-14 15:15:46 -06:00
Cameron Gutman
bb885465f6
Merge pull request #429 from MichaelMKenny/ipad-alertcontroller-crash-fix
Fixed crash on iPad due to missing up UIAlertController popoverPresentation.
2020-11-14 14:58:54 -06:00
Michael Kenny
e258551008 Fixed crash on iPad when bringing up app long press menus, due to missing UIAlertController popoverPresentation. 2020-11-04 14:11:27 +10:30
Cameron Gutman
e402902d6e Fix tvOS build 2020-11-02 20:39:37 -06:00
Cameron Gutman
f55daf941c Add support for hiding apps 2020-11-02 20:39:24 -06:00
Cameron Gutman
a483c6ea41 Allow panning to the bottom of the screen when the keyboard appears 2020-11-02 18:41:38 -06:00
Cameron Gutman
3ad4d857e8 Replace home-rolled edge swipe gesture recognizer with UIScreenEdgePanGestureRecognizer 2020-11-01 21:18:06 -06:00
Cameron Gutman
6b1d34e4a9 StreamView must be multi-touch enabled for gestures to work 2020-11-01 20:50:25 -06:00
Cameron Gutman
bf36eaf661 Improve soft-keyboard handling 2020-11-01 20:47:14 -06:00
Cameron Gutman
e809afdd9e Implement zoom and pan in touchscreen mode 2020-11-01 20:22:01 -06:00
Cameron Gutman
0d75dd4efb Create stream view hierarchy programmatically 2020-11-01 20:00:39 -06:00
Cameron Gutman
b799978cac Remove old iOS 13.0 gesture recognizer hack 2020-11-01 17:53:21 -06:00
Cameron Gutman
42f29c44e6 Remove OSPortabilityDefs.h
The macOS support that used it has been removed for a while
2020-11-01 16:50:02 -06:00
Cameron Gutman
c3ba447372 Reorganize tvOS settings 2020-11-01 16:43:13 -06:00
Cameron Gutman
a358cdad3d Improve behavior of 2 finger scrolling in trackpad mode 2020-11-01 16:02:34 -06:00
Cameron Gutman
a1f09f117f Fix first tap in touch mode not registering 2020-11-01 14:43:55 -06:00
Cameron Gutman
7270554153 Scale dead zone areas by screen size 2020-11-01 14:36:43 -06:00
Cameron Gutman
8d127decb6 Shrink and deadzone the edge swipe region for touchscreen mode 2020-11-01 14:28:13 -06:00
Cameron Gutman
8ffee9e10f Minor video stats improvements 2020-11-01 14:09:05 -06:00
Cameron Gutman
0eac28a74f Fix stats overlay width decreasing each iteration 2020-11-01 13:45:24 -06:00
Cameron Gutman
5d94800e11 Update moonlight-common-c to disable QoS on IPv6 2020-11-01 13:27:40 -06:00
Cameron Gutman
44f713f5c9 Add a basic stats overlay 2020-11-01 13:27:10 -06:00
Cameron Gutman
2114e39237 Plumb touch mode and stats overlay preferences 2020-11-01 11:50:00 -06:00
Cameron Gutman
6fd8baee41 Implement AbsoluteTouchHandler 2020-11-01 11:07:42 -06:00
Cameron Gutman
63beaebe55 Stub AbsoluteTouchHandler 2020-11-01 10:30:39 -06:00
Cameron Gutman
17d4079a5a Refactor relative touch handling into a separate class 2020-11-01 10:19:32 -06:00
Cameron Gutman
b650119fe9
Merge pull request #426 from nauxliu/bump-max-bitrate
Bump max bitrate to 150Mbps to line up with android and qt version
2020-10-28 20:56:55 -05:00
Cameron Gutman
8b28606952 Update moonlight-common-c with QoS fix 2020-10-28 20:44:43 -05:00
Xiangxuan Liu
24258d6e17 Bump max bitrate to 150Mbps to line up with android and qt version 2020-10-28 01:04:34 +08:00
Cameron Gutman
3f1699258d Increase inactivity threshold to 60 seconds before killing the stream 2020-10-18 17:44:52 -05:00
Cameron Gutman
34f8696a5e Don't terminate the stream when resigning active on tvOS 2020-10-18 17:43:34 -05:00
Cameron Gutman
96e317fe31 Make Guide button emulation more granular by only enabling RB+Start or Start+Select based on physical buttons present 2020-10-18 17:37:18 -05:00
Cameron Gutman
ecad1bea38 Disable Guide button emulation on gamepads with physical Guide buttons 2020-10-18 15:04:09 -05:00
Cameron Gutman
e4534fd4af Version 6.1.1 2020-10-17 22:17:00 -05:00
Cameron Gutman
126735fa57 Update moonlight-common-c with MTU test 2020-10-17 21:52:31 -05:00
Cameron Gutman
9ff5fcb9d5 Fix off by one in rumble amplitude calculation 2020-10-17 21:25:10 -05:00
Cameron Gutman
8c66898765 Dynamically update haptic effects instead of creating new players all the time 2020-10-15 18:40:13 -05:00
Cameron Gutman
5faf1faf32 Add Guide button support on iOS 14 2020-10-15 17:55:53 -05:00
Cameron Gutman
7e704ee201 Trim the IP address string from the user 2020-10-06 21:57:22 -05:00
Cameron Gutman
c3ae83f902 Version 6.1.0 2020-09-18 22:41:03 -05:00
Cameron Gutman
95e16c5e2d Sort ITSAppUsesNonExemptEncryption 2020-09-18 21:54:05 -05:00
Cameron Gutman
fc08a7ee0e Set ITSAppUsesNonExemptEncryption=NO 2020-09-18 19:47:25 -05:00
Cameron Gutman
95e12f9853 Fix sorting of NSLocalNetworkUsageDescription 2020-09-18 19:18:51 -05:00
Cameron Gutman
88c18ad397 Don't use pointer lock if the mouse isn't compatible with GCMouse 2020-09-18 18:48:35 -05:00
Cameron Gutman
5043fadace Request pointer lock while streaming 2020-09-18 18:27:20 -05:00
Cameron Gutman
6fa5ef73f6 Add GCMouse support 2020-09-18 17:04:32 -05:00
Cameron Gutman
c0367f711b Disable legacy iOS 13.4 mouse support when a GCMouse is connected 2020-09-18 16:44:24 -05:00
Cameron Gutman
0a5499f369 Raise iOS deployment target to iOS 9.3 as required by Xcode 12 2020-09-18 16:29:46 -05:00
Cameron Gutman
26209f187e Update TravisCI to use Xcode 12 2020-09-18 15:30:21 -05:00
Cameron Gutman
e8c7eb67c6 Add rumble support on iOS 14 2020-09-17 20:32:41 -05:00
Cameron Gutman
2d24b0ec7b Fix mouse support on iOS 14 2020-09-17 18:59:18 -05:00
Cameron Gutman
dfec190b82 Version 6.0.1 2020-09-08 19:53:32 -07:00
Cameron Gutman
88f9423802 Update moonlight-common-c to improve connection reliability 2020-09-08 19:53:13 -07:00
Cameron Gutman
beeec54420 Version 6.0 2020-09-06 18:14:39 -07:00
Cameron Gutman
b7b7a88ef7 Display the prohibited address warning on failures too 2020-08-30 20:47:40 -07:00
Cameron Gutman
6bf643968b Display a loading spinner while adding a PC is in progress 2020-08-30 20:39:11 -07:00
Cameron Gutman
dbab07838d Only allow PCs on the same LAN to be added via the Add PC dialog
This is required to comply with App Store Guideline 4.2.7a.
2020-08-30 17:59:28 -07:00
Cameron Gutman
06a4ced692 Only impose app store restrictions on release builds 2020-08-30 16:43:56 -07:00
Cameron Gutman
fb9d778dab Purge mentions of Internet streaming for App Store Guideline 4.2.7a 2020-08-30 15:37:52 -07:00
Cameron Gutman
2a0b29a284 Revert "Add direct-to-desktop mode"
This reverts commit e445989ec73002d9210faf9cf4a881fe5aa49c20.
2020-08-30 15:30:58 -07:00
Cameron Gutman
bf437669fb Add warning if no key frames can be received in 10 seconds 2020-08-29 21:21:46 -07:00
Cameron Gutman
e445989ec7 Add direct-to-desktop mode 2020-08-12 22:26:56 -07:00
Cameron Gutman
0b712a1589 Add manual connection testing option 2020-08-12 22:20:15 -07:00
Cameron Gutman
1aa11df725 Fix simulator build for Apple silicon 2020-08-12 19:28:12 -07:00
Cameron Gutman
ff5e8d167d Add support for iOS 14 local network privacy changes 2020-08-12 18:34:49 -07:00
Cameron Gutman
286b19d360 Add automatic network testing on connection failure 2020-08-10 22:56:47 -07:00
Cameron Gutman
3ab0829db5 Update common-c to fix server-side log spam 2020-08-09 18:38:53 -07:00
Cameron Gutman
6f2041dfb6 Sync WoL ports with Android and Qt 2020-08-09 14:48:27 -07:00
Cameron Gutman
78600a4e06 Update common-c with client connectivity test and select() replacement 2020-07-27 00:23:00 -07:00
Cameron Gutman
e0bb48320f Avoid modulo bias for PIN generation 2020-07-12 11:40:31 -07:00
Cameron Gutman
46b9f84a31 Update moonlight-common-c to fix QoS-related connection issues 2020-06-12 22:10:41 -07:00
Cameron Gutman
abb4b5f9b9 Pad the SHA-1 hash for Gen5 and below servers 2020-06-09 01:13:30 -07:00
Cameron Gutman
a4f7861ccf Avoid using functions deprecated in OpenSSL 3.0 2020-06-09 00:56:58 -07:00
Cameron Gutman
39c03bc8a8 Attempt to fix Apple's concerns about cloud streaming 2020-06-05 16:03:38 -07:00
Cameron Gutman
059a943a3d Fix dragging with middle, X1, or X2 mouse buttons down 2020-05-31 12:40:54 -07:00
Cameron Gutman
3e2e4d13a9 Update moonlight-common-c 2020-05-29 19:17:37 -07:00
Cameron Gutman
4a537c1806 Fix tvOS build in Travis CI 2020-05-29 19:10:13 -07:00
Cameron Gutman
839f2018cb Update osx_image for Travis CI 2020-05-29 19:02:25 -07:00
Cameron Gutman
f9d1840941
Update README.md 2020-05-27 19:55:52 -07:00
Cameron Gutman
7747188363 Update README 2020-05-27 19:53:17 -07:00
Cameron Gutman
c43ed56751 Use a better workaround for the GFE 3.20.3 high FPS bug 2020-05-25 19:24:03 -07:00
Cameron Gutman
a3b01b3cd4 Revert "Disable SOPS for streams over 60 FPS for GFE 3.20.3"
This reverts commit fdaf7f92a13dafcb747cf83cd45e85322b7dda7e.
2020-05-25 18:58:15 -07:00
Cameron Gutman
96c2ac9be5 Version 5.0.2-2 (iOS) 2020-05-09 15:02:26 -07:00
Cameron Gutman
aee4e3bf3d Update moonlight-common-c 2020-05-09 15:00:41 -07:00
Cameron Gutman
d9cb55a17f Don't update the mouse position if it hasn't moved from the last location 2020-05-09 14:42:09 -07:00
Cameron Gutman
4c8ad13f3a Version 5.0.2 (iOS) 2020-05-01 19:48:49 -07:00
Cameron Gutman
99c160f8e5 Require iOS 13.4.1 to enable pointer interaction to avoid crashing on beta iOS 13.4 builds 2020-05-01 19:47:52 -07:00
Cameron Gutman
78e16b0e29 Fix crash on iOS 8 2020-05-01 19:43:21 -07:00
Cameron Gutman
fdc9e00c54 Add a friendly error message when no video traffic is received 2020-05-01 19:37:33 -07:00
Cameron Gutman
b16eaafd2c Allow continuous scroll type gestures. Fixes #408 2020-04-29 18:00:17 -07:00
Cameron Gutman
2ec6639351 Add special error text for the -1 launch error code 2020-04-25 16:29:47 -07:00
Cameron Gutman
f49a908dc0 Fix parsing rare GFE status code of 0xFFFFFFFF 2020-04-23 20:07:52 -07:00
Cameron Gutman
b3a666af8e Version 5.0.1 for iOS 2020-04-20 16:50:29 -07:00
Cameron Gutman
5abad38956 Revert "Refactor legacy UITextField-based keyboard support out of StreamView"
This refactoring breaks support for hardware keyboards on iOS 13.3
and below. The root cause of the breakage is not currently known.

This reverts commit 69d1ff15a1399d0afe43026dbca39cc14bff1022.
2020-04-20 16:31:21 -07:00
Cameron Gutman
7f034e0338 Version 4.0.2 for tvOS 2020-04-19 15:09:10 -07:00
Cameron Gutman
fb196f661c Reorder Info.plist 2020-04-19 14:57:56 -07:00
Cameron Gutman
3cca55703e Fix the LoadingFrameViewController not display on top of other content on tvOS
Also remove hacks that were put in place due to this bug previously.
2020-04-19 14:40:39 -07:00
Cameron Gutman
084018719a Version 5.0.0-2 for iOS 2020-04-18 17:25:16 -07:00
Cameron Gutman
4aca666df4 Fix race condition that could cause pairing state to be lost
If a mDNS response for a host happened during the period where we
had removed the host from discovery, it would be re-added by mDNS
without the pairing cert. Now we no longer completely remove the host
and instead just remember that it's paused.
2020-04-18 17:16:53 -07:00
Cameron Gutman
b833d3b3b7 Fix broken isEqual function for TemporaryApp and TemporaryHost 2020-04-18 17:05:36 -07:00
Cameron Gutman
cb94d7aad7 Version 5.0.0 for iOS 2020-04-18 15:26:44 -07:00
Cameron Gutman
b8631db5df Allow rediscovery of hosts after deletion without having to force quit the app 2020-04-18 15:03:52 -07:00
Cameron Gutman
bd5e0ecc40 Standardize mouse input scaling to avoid variance based on stream resolution 2020-04-18 14:44:57 -07:00
Cameron Gutman
10d2e1635b Only hide the cursor over the video region 2020-04-18 14:09:19 -07:00
Cameron Gutman
68e59aba74 Scale mouse input to fit the video region 2020-04-18 14:00:26 -07:00
Cameron Gutman
a4255f4cad Implement absolute mouse support on iOS 13.4
Fixes #402
2020-04-18 13:11:24 -07:00
Cameron Gutman
f12e2f16dc Add handling for cancelled touch events 2020-04-18 11:25:24 -07:00
Cameron Gutman
177ecdbe0b Enable pointer interaction on the PC and app grid items 2020-04-18 11:24:02 -07:00
Cameron Gutman
de05214728 Version 4.0.1 2020-04-17 12:46:46 -07:00
Cameron Gutman
b0149b2fe9
Merge pull request #405 from loki-47-6F-64/master
Don't send PIN to GFE
2020-04-17 12:40:29 -07:00
Loki
1366ede690 Don't send PIN to GFE 2020-04-17 14:45:46 +02:00
Cameron Gutman
fdaf7f92a1 Disable SOPS for streams over 60 FPS for GFE 3.20.3 2020-04-12 11:25:53 -07:00
Cameron Gutman
8efbe2670a Bump version to 4.0.0 2020-04-12 11:10:23 -07:00
Cameron Gutman
8bc66749c3 Update moonlight-common-c to avoid termination delay on GFE 3.20.3 2020-04-12 10:43:33 -07:00
Cameron Gutman
4ab71a3cc7 Allow Command key to function as Control 2020-04-11 11:17:25 -07:00
Cameron Gutman
55b2f39721 Adjust X1_MOUSE_SPEED_DIVISOR based on user testing 2020-04-11 11:04:00 -07:00
Cameron Gutman
e59f0764a2 Update tvOS target to Swift 5 2020-04-11 11:01:44 -07:00
Cameron Gutman
6194d80108 Upgrade to Swift 5 2020-04-08 20:11:10 -07:00
Cameron Gutman
5264fee655 Update to OpenSSL 1.1.1f
Built for targets: ios-sim-cross-i386 ios-sim-cross-x86_64 ios64-cross-arm64 ios64-cross-arm64e ios-cross-armv7s ios-cross-armv7 tvos-sim-cross-x86_64 tvos64-cross-arm64

https://github.com/keeshux/openssl-apple
2020-04-08 19:57:45 -07:00
Cameron Gutman
ab17c57c09 Update to latest upstream X1Kit with support for new X1 firmware 2020-04-08 18:47:08 -07:00
Cameron Gutman
c7a7fc3fbc Add 7.1 surround sound support 2020-04-03 17:46:04 -07:00
Cameron Gutman
f32d4f2886 Reduce retransmission delay on packet loss and enable QoS marking on ENet traffic 2020-03-29 22:22:03 -07:00
Cameron Gutman
8e4471fbc0 Slow X1 mouse input by 2x to make it more usable 2020-03-27 23:05:53 -07:00
Cameron Gutman
733b992912 Update to OpenSSL 1.1.1e 2020-03-27 21:24:32 -07:00
Cameron Gutman
6d03f4bc4c Add a settings option for enabling Citrix X1 support 2020-03-27 20:26:01 -07:00
Cameron Gutman
75ab28a2c3 Enhance physical keyboard support on iOS 13.4
Fixes #394
2020-03-25 18:24:04 -07:00
Cameron Gutman
69d1ff15a1 Refactor legacy UITextField-based keyboard support out of StreamView 2020-03-24 18:14:50 -07:00
Cameron Gutman
eceb23e1cd Allow Moonlight audio to mix with other audio 2020-03-21 16:35:07 -07:00
Cameron Gutman
ab5a9ba067 Use 10 ms audio samples on slow networks 2020-03-21 16:06:25 -07:00
Cameron Gutman
742bb7b516 Change errorCode from long to int 2020-02-25 00:00:00 -08:00
Cameron Gutman
65578b8a64 Fix tvOS build 2020-01-19 21:15:15 -08:00
Cameron Gutman
1246de3f18 Centralize Discord invite links 2020-01-18 10:54:22 -08:00
Cameron Gutman
5b5fdff6d8 Add support for Citrix X1 mice using X1Kit (untested) 2020-01-16 19:52:49 -08:00
Cameron Gutman
47aaa02d08 Version 3.3.0 (iOS) 2019-12-07 11:48:02 -08:00
Cameron Gutman
b71f06aa04 Change audio buffer duration back to 80 ms for now 2019-12-04 18:58:36 -08:00
Cameron Gutman
61c18c201c Prevent concurrent modification of host list 2019-12-03 20:02:16 -08:00
Cameron Gutman
32b7396070 Reduce buffering for 5 ms and 20 ms audio packets 2019-12-03 19:51:31 -08:00
Cameron Gutman
c327c5b1ec Force remote streaming mode when a VPN is connected 2019-12-01 20:55:20 -08:00
Cameron Gutman
44d4553031 Add support for arbitrary audio duration 2019-12-01 20:51:18 -08:00
Cameron Gutman
a2b8e3a8b8 Update common-c to fix RTSP handshake error when PMTUD is broken 2019-12-01 20:50:45 -08:00
Cameron Gutman
9e91627601 Fix auto-comment line breaks 2019-11-16 12:24:49 -08:00
Cameron Gutman
250f6618fd Plumb the presentation time from the server into the renderer 2019-11-11 18:42:11 -08:00
Cameron Gutman
ab5e253a59 Version 3.2.0 (iOS) 2019-11-11 18:41:40 -08:00
Cameron Gutman
12a64f8626 Don't emulate buttons when the controller already has them 2019-11-09 17:47:47 -08:00
Cameron Gutman
99fec8919e Add configuration for auto-comment bot 2019-11-09 15:03:16 -08:00
Cameron Gutman
52dcdd68c4 Fix concurrency issues accessing TemporaryHost fields that could be changed by other threads 2019-11-06 21:51:23 -08:00
Cameron Gutman
5a0e4bcc05 Fix UBSan undefined behavior warning
moonlight-ios/Limelight/Input/ControllerSupport.m:294:32: runtime error: 255 is outside the range of representable values of type 'char'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior moonlight-ios/Limelight/Input/ControllerSupport.m:294:32 in
2019-11-06 20:57:53 -08:00
Cameron Gutman
2577f581ba Revert "Don't navigate to a host that is known to be offline"
This reverts commit 95ce78bb00574ca0c12cc6ab3352e961e8258eac.
2019-11-05 20:30:17 -08:00
Cameron Gutman
1757359fbf Fix "server busy" pairing error dialog 2019-11-04 21:41:42 -08:00
Cameron Gutman
e89707e601 Don't send a STUN request when a VPN is connected 2019-11-04 21:28:53 -08:00
Cameron Gutman
c89de92e23 Fix tvOS build 2019-11-03 15:25:43 -08:00
Cameron Gutman
ee7df54842 Launch directly to the app grid if there is exactly one PC 2019-11-03 15:17:27 -08:00
Cameron Gutman
95ce78bb00 Don't navigate to a host that is known to be offline 2019-11-03 15:13:44 -08:00
Cameron Gutman
3c9314dff3 Disable both navbar buttons when disabling navigation 2019-11-03 15:13:13 -08:00
Cameron Gutman
c5e1bbf61b Set title immediately when a PC is tapped 2019-11-03 15:12:43 -08:00
Cameron Gutman
abe850cd72 Fix UI problems when a pairing error occurs in the background 2019-11-03 15:11:02 -08:00
Cameron Gutman
b0a3e163c4 Restart PC discovery when pairing fails 2019-11-03 14:43:12 -08:00
Cameron Gutman
2ae7fefc0c Prevent app grid from populating with empty cells during server info polling 2019-11-03 14:40:32 -08:00
Cameron Gutman
72af5d5217 Update initial PC state more quickly on launch 2019-11-03 14:26:13 -08:00
Cameron Gutman
d1eb7b45a2 Add quick action shortcuts to open paired PCs 2019-11-03 13:38:52 -08:00
Cameron Gutman
3b5652c3f5 Update moonlight-common-c submodule 2019-11-02 21:48:00 -07:00
Cameron Gutman
df50bb9583 Use blank gray launch screen to workaround inconsistent nav bar size 2019-11-02 18:22:09 -07:00
Cameron Gutman
18e2d67f6b Suppress home bar hiding when user is interacting 2019-11-02 15:17:52 -07:00
Cameron Gutman
9f19f5da27
Fix app store link 2019-10-28 18:41:38 -07:00
Cameron Gutman
005c3e4082
Update readme to include tvOS 2019-10-28 18:40:35 -07:00
Cameron Gutman
35b3c01582 Sync tvOS version numbering with iOS 2019-10-28 18:28:21 -07:00
Cameron Gutman
d8f55b57fa Fix Travis CI build with their updated Xcode 11 images 2019-10-22 00:40:39 -04:00
Cameron Gutman
5faa8a0b85 Hide the home bar when a gamepad is connected and no on-screen controls are visible
Fixes #386
2019-10-22 00:32:56 -04:00
Cameron Gutman
967ddd7d68 Refactor OSC handling 2019-10-22 00:16:20 -04:00
Cameron Gutman
26fac5b56e Fix asserts not catching the intended bugs (code analysis warning) 2019-10-21 17:53:18 -07:00
Cameron Gutman
75c1c85de9 Remove old IPA binaries
They don't work with recent GFE versions anyway
2019-10-21 17:41:47 -07:00
Cameron Gutman
653a72eaf8 Remove macOS port
We now have a proper native PC port (Moonlight Qt) and if we
wanted to bring the full iOS app over we can now use Catalyst.
2019-10-21 17:39:48 -07:00
Cameron Gutman
27d95ae0ba Update moonlight-common-c submodule 2019-10-21 17:23:50 -07:00
Cameron Gutman
7dca4c6c63 Fix incompatible pointer type warning 2019-10-21 17:05:03 -07:00
Cameron Gutman
12e7dd2181 Update moonlight-common-c submodule 2019-10-12 19:21:07 -07:00
Cameron Gutman
c9225d468a Change title of launch error dialog 2019-10-12 19:20:53 -07:00
Cameron Gutman
a824c23c59 Fix iOS build 2019-10-12 19:20:26 -07:00
Cameron Gutman
a9e01fc9a9 Fix pointer speed on tvOS 2019-10-12 18:23:28 -07:00
Cameron Gutman
fb2d58da6a Fix default resolution not taking effect on tvOS 2019-10-12 18:10:12 -07:00
Cameron Gutman
09ac6cc057 Clamp stream resolution and FPS to device capabilities 2019-10-12 18:07:47 -07:00
Cameron Gutman
1121a918d1 Improve description messages of error message dialogs 2019-10-12 16:41:32 -07:00
Cameron Gutman
565a8e56e6 Add NSError information to the HttpResponse on failure 2019-10-12 16:13:59 -07:00
Cameron Gutman
f8cc7bb77f Improve text for WoL alert 2019-10-12 16:03:35 -07:00
Cameron Gutman
55c52e1ee1 Require tvOS 12.0 due to navigation issues on tvOS 11.4 2019-10-10 02:20:33 -07:00
Diego Waxemberg
366a94d018 Removing manually specified signing certs
This will make signing for iOS and tvOS using the automatic signing possible. It complains if there is a manually specifed signing id.
2019-10-06 09:42:01 -04:00
Cameron Gutman
4e5264d5e9 Fix menu button recognizer not always working after returning from settings 2019-09-24 19:08:22 -07:00
Cameron Gutman
d98aba66a8 Add settings button for tvOS 2019-09-24 18:56:37 -07:00
Cameron Gutman
8ccbdc7923 Fix Start button not working on some MFi controllers on iOS 13 2019-09-24 18:13:56 -07:00
Cameron Gutman
769840d089 Immediately stop streaming when resigning active on tvOS 2019-09-24 17:37:35 -07:00
Cameron Gutman
33b050f84f Increase bitrate warning font size on tvOS 2019-09-24 17:36:26 -07:00
Cameron Gutman
d2bc7209f7 Use the same bundle identifier for tvOS 2019-09-24 06:06:35 -07:00
Cameron Gutman
d32d1aa09a Add tvOS UI screenshots 2019-09-23 21:33:26 -07:00
Cameron Gutman
7f6db298d0 Remove remove disallowed GCSupportedGameControllers value 2019-09-23 21:33:25 -07:00
Cameron Gutman
f9ff6a6004 Add tvOS launch image 2019-09-23 21:33:25 -07:00
Cameron Gutman
a6e6d0e491 Restore focus on the correct app after closing the stream 2019-09-23 21:33:24 -07:00
Cameron Gutman
6613976291 Increase icon resolution for tvOS 2019-09-23 21:33:24 -07:00
Cameron Gutman
6f8d898b77 Prevent box art from overlapping other tiles when focused 2019-09-23 21:33:24 -07:00
Cameron Gutman
d1cbfd9c44 Rewrite UIComputerView to use a pop-out effect on tvOS 2019-09-23 21:33:24 -07:00
Cameron Gutman
e6b1dd6b64 Rewrite UIAppView to avoid needing a custom hover pop-up effect on tvOS 2019-09-23 21:33:24 -07:00
Diego Waxemberg
15fe5a06c2 Bumping version for v3.0.0 build 3 2019-09-22 22:14:27 -07:00
Cameron Gutman
8d4c7bd705 Fix Steam app detection if GFE gives us a lower-case path 2019-09-22 10:31:23 -07:00
Cameron Gutman
b0d85abfa6 Increase audio circular buffer size to reduce glitching 2019-09-22 10:20:30 -07:00
Diego Waxemberg
4295017324 Bumping version for v3.0.0 build 2
Pulling in fix for assets
2019-09-21 23:26:09 -07:00
Cameron Gutman
d80d70215a Add App Store screenshots 2019-09-21 16:45:45 -07:00
Cameron Gutman
a46f905aa6 Fix case of Computer asset name 2019-09-21 14:32:12 -07:00
Diego Waxemberg
453c50d505 Bumping version for v3.0.0 2019-09-20 20:26:09 -07:00
Cameron Gutman
61c7d9f2b3 Disable bounce-back on the reveal view controller 2019-09-18 19:59:24 -07:00
Cameron Gutman
34707e7743 Update launch screen to match new UI 2019-09-18 19:45:27 -07:00
Cameron Gutman
9a9b9651a1 Address several iOS and tvOS compilation warnings 2019-09-15 15:46:23 -07:00
Cameron Gutman
d4576a8739 Suppress availability warning for overrideUserInterfaceStyle field 2019-09-15 15:29:29 -07:00
Cameron Gutman
87824c2650 Fix control stream connection error on multi-homed hosts 2019-09-14 14:14:26 -07:00
Cameron Gutman
283e735f90 Remove the successful quit dialog since it's redundant and annoying 2019-09-14 13:08:47 -07:00
Cameron Gutman
202f968b98 Rework app labels on iOS to reuse title UILabel and use correct size and insets 2019-09-14 12:59:40 -07:00
Cameron Gutman
62df1cd5ba Reduce minimum spacing to 15 to allow an extra column on iPhone SE 2019-09-14 12:47:21 -07:00
Cameron Gutman
f24c28c848 Switch back to text for navigation buttons 2019-09-14 12:46:50 -07:00
Cameron Gutman
8fb465d3ca Fix tvOS build warning 2019-09-14 12:28:37 -07:00
Cameron Gutman
29dff2320b Fix content insets for host and app scroll views 2019-09-14 12:28:21 -07:00
Cameron Gutman
a40b30016b Rewrite storyboards with Xcode 11 GM 2019-09-14 12:07:38 -07:00
Cameron Gutman
409b262a4f Add a hack as a possible workaround for #372 2019-09-14 11:49:09 -07:00
Cameron Gutman
73197e4378 Clean up and fix storyboards 2019-09-14 11:34:22 -07:00
Cameron Gutman
f51dbe4295 Fix some Xcode 11 warnings 2019-09-11 19:12:11 -07:00
Cameron Gutman
597aaa1bab Cleanup controller support code using the iOS 13 SDK directly 2019-09-11 18:44:37 -07:00
Cameron Gutman
b9656da8a5 Use Xcode 11 image for Travis CI 2019-09-11 18:27:45 -07:00
Cameron Gutman
422db1898c Improve manually added Steam app detection heuristic to prevent FPs on apps with "Steam" in the name 2019-09-08 18:56:18 -07:00
Cameron Gutman
56691791b8 Fix race condition that could cause safe area insets to be missing 2019-09-01 12:26:39 -07:00
Cameron Gutman
de2a5d3cd7 Fix overlays not being affected by button press and spinner eating touch events 2019-09-01 12:15:26 -07:00
Cameron Gutman
49fc10191c Fix transparent app grid background being incorrectly overridden 2019-08-31 20:19:03 -07:00
Cameron Gutman
bf8aaa8198 Refresh app icon when the running state changes on tvOS 2019-08-31 19:52:55 -07:00
Cameron Gutman
9a4cdc9c94 Replace updating overlay icon with spinner 2019-08-31 16:02:37 -07:00
Cameron Gutman
f6153fe818 Improve selection visibility on tvOS 2019-08-30 22:33:32 -07:00
Cameron Gutman
f2fa9e18ea Reorder tvOS settings and fix default bitrate for 1080p60 2019-08-30 21:51:10 -07:00
Cameron Gutman
aa013be6e6 Update settings config for tvOS 2019-08-30 21:44:12 -07:00
Cameron Gutman
7e21b131ac Redesign navigation bar on iOS 2019-08-30 21:15:11 -07:00
Cameron Gutman
97681f3a0d Increase size of PC icon 2019-08-30 20:00:00 -07:00
Cameron Gutman
e476cc407c Fix crash on pre-iOS 13 2019-08-30 19:55:49 -07:00
Cameron Gutman
f2e03bbf1f Always use dark mode on tvOS 2019-08-30 19:40:17 -07:00
Cameron Gutman
a6cef32c9a Increase size of PC icons on tvOS 2019-08-30 19:37:16 -07:00
Cameron Gutman
6d94897c21 Distinguish between offline and unknown hosts 2019-08-30 19:19:23 -07:00
Cameron Gutman
a065c78b5f Restyle UIComputerView to match other clients 2019-08-30 18:36:14 -07:00
Cameron Gutman
83479719a4 Fix styles on settings slideout on iOS 13 2019-08-30 17:16:56 -07:00
Cameron Gutman
fd4ede58ca Reduce the size of the audio circular buffer to reduce peak latency 2019-08-29 22:00:27 -07:00
Cameron Gutman
7ed5a9831f Fix settings slideout scrolling too far on iOS 13 2019-08-29 21:57:51 -07:00
Cameron Gutman
42b7fd35ce Fix surround sound audio playing back silence 2019-08-29 21:07:10 -07:00
Cameron Gutman
42c97eafaa Fix slightly offset titles 2019-08-29 20:34:51 -07:00
Cameron Gutman
5b82be0546 Rewrite UIAppView rendering to consolidate tvOS and iOS codepaths 2019-08-29 20:32:18 -07:00
Cameron Gutman
1529058f52 Increase font size for app names 2019-08-29 19:00:42 -07:00
Cameron Gutman
3dcca3a922 Allow click and drag via tvOS remote trackpad 2019-08-29 18:55:33 -07:00
Cameron Gutman
9b8f230c46 Prevent gesture recognizers from eating our touch events. Fixes #375 2019-08-28 21:51:52 -07:00
Cameron Gutman
7699d9e574 Implement 5.1 surround sound support. Fixes #371 2019-08-26 22:46:35 -07:00
Cameron Gutman
641e1c5066 Update common-c for parallel STUN requests 2019-08-20 19:08:25 -07:00
Cameron Gutman
617ef7c6a6 Update common-c to support STUN fallback 2019-08-07 23:15:33 -07:00
Cameron Gutman
c2620b8321 Fix tvOS build 2019-08-07 00:53:58 -07:00
Cameron Gutman
9e91d136bf
Add Travis CI badge to readme 2019-08-07 00:48:26 -07:00
Cameron Gutman
9960d2a2ff Add Travis CI support 2019-08-07 00:40:54 -07:00
Cameron Gutman
311e77e01a Remove unit test for the old Swift controller class 2019-08-07 00:06:54 -07:00
Cameron Gutman
c08df921da Update common-c to fix termination detection issue on GFE 3.19.0.107 2019-07-28 12:58:25 -04:00
Cameron Gutman
ba4e55aac4 Add on-screen connection status warning 2019-07-23 18:43:41 -04:00
Cameron Gutman
af16f03703 Stringify IPv6 addresses with scope IDs if present 2019-07-15 01:05:21 -07:00
Cameron Gutman
8189d54703 Remove forced population of host.address 2019-07-15 01:00:50 -07:00
Cameron Gutman
ac8514e3cb Update common-c for IPv6 optimizations 2019-07-15 00:16:54 -07:00
Cameron Gutman
8f4b8da3ce Handle IPv6-only servers 2019-07-14 22:55:41 -07:00
Cameron Gutman
8337b3e708 Add support for zero configuration IPv6 streaming 2019-07-14 19:17:17 -07:00
Cameron Gutman
cb527baead Generate SHA-256 client certificates instead of SHA-1 2019-07-05 22:20:55 -07:00
Cameron Gutman
ed10612e2c Allow pairing to complete in the background to allow users to type the PIN using remote desktop apps 2019-07-05 22:18:30 -07:00
Diego Waxemberg
7d3eaeef83 Creating a new 2.7.0 build 2019-06-05 20:22:31 -07:00
Cameron Gutman
dd5ecb37c4 Add support for Start and Select on iOS 13. Fixes #367 2019-06-05 19:54:56 -07:00
Cameron Gutman
636143ee97 Disable the 4K option for SoCs older than the A9 2019-06-05 18:59:40 -07:00
Cameron Gutman
28ff29bb96 Disable the HEVC toggle for devices that don't support HEVC 2019-06-05 18:41:30 -07:00
Cameron Gutman
a508c6d855 Remove default Steam app to address Apple App Review rejection 2019-06-04 18:37:52 -07:00
Diego Waxemberg
dbd6eabd24 Bumping app version for v2.7.0 2019-05-31 18:54:02 -07:00
Cameron Gutman
ad0a5935f7 Don't compile asserts into release builds 2019-05-31 14:46:20 -05:00
Cameron Gutman
dcd2dc97a6
Merge pull request #366 from MichaelMKenny/4K-120-bitrate-fix
Capped bitrate at 100Mbps.
2019-05-31 14:04:10 -05:00
Michael Kenny
f92544c7d2 Capped bitrate at 100Mbps.
Choosing 4K 120Hz was causing an assert/crash.
2019-05-31 15:04:20 +09:30
Cameron Gutman
797fa0f492 Add 4K resolution option. Fixes #364 2019-05-27 10:37:26 -07:00
Cameron Gutman
ff52adf4f8 Improve pairing messages 2019-05-27 10:27:10 -07:00
Cameron Gutman
8bb49ada11 Disable vibration for expedited review 2019-05-27 10:12:02 -07:00
Cameron Gutman
3f709b616b Fix video on GFE 3.19 2019-05-27 10:06:57 -07:00
546 changed files with 94876 additions and 46957 deletions

48
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,48 @@
---
name: Bug report
about: Follow the troubleshooting guide before reporting a bug
---
**READ ME FIRST!**
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.
**Steps to reproduce**
Any special steps that are required for the bug to appear.
**Screenshots**
If applicable, add screenshots to help explain your problem. If the issue is related to video glitching or poor quality, please include screenshots.
**Affected games**
List the games you've tried that exhibit the issue. To see if the issue is game-specific, try streaming Steam Big Picture with Moonlight and see if the issue persists there.
**Other Moonlight clients**
- Does the issue occur when using Moonlight on PC or Android?
**Moonlight settings (please complete the following information)**
- Have any settings been adjusted from defaults?
- 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?
- If gamepad input is not working, does it work if you use Moonlight's on-screen controls?
- 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
**Device details (please complete the following information)**
- iOS/tvOS version: [e.g. iOS 14.2]
- Device model: [e.g. iPhone 11 Pro]
**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]
- Antivirus and firewall software: [e.g. Windows Defender and Windows Firewall]
**Additional context**
Anything else you think may be relevant to the issue or special about your specific setup.

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

4
.github/auto-comment.yml vendored Normal file
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!

25
.github/lock.yml vendored Normal file
View File

@ -0,0 +1,25 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 60
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
skipCreatedBefore: false
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
exemptLabels:
- enhancement
# Label to add before locking, such as `outdated`. Set to `false` to disable
lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: >
This issue has been automatically locked since there has not been
any recent activity after it was closed. If you experience an issue
that looks similar to this one, please open a new issue with details
about your specific streaming setup.
# Don't lock PRs
only: issues

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
**/xcuserdata/
**/Moonlight.xcscmblueprint
**/xcschemes/*.xcscheme
.DS_Store
Build
DerivedData

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "moonlight-common/moonlight-common-c"]
path = moonlight-common/moonlight-common-c
url = https://github.com/moonlight-stream/moonlight-common-c.git
[submodule "X1Kit"]
path = X1Kit
url = https://github.com/cgutman/X1Kit.git

View File

@ -1,144 +0,0 @@
#!/bin/bash
set -e
source config.sh
# Number of CPUs (for make -j)
NCPU=`sysctl -n hw.ncpu`
if test x$NJOB = x; then
NJOB=$NCPU
fi
PLATFORMBASE=$(xcode-select -print-path)"/Platforms"
SCRIPT_DIR=$( (cd -P $(dirname $0) && pwd) )
DIST_DIR_BASE=${DIST_DIR_BASE:="$SCRIPT_DIR/dist"}
if [ ! -d opus ]
then
echo "opus source directory does not exist, run sync.sh"
fi
# PATH=${SCRIPT_DIR}/gas-preprocessor/:$PATH
for ARCH in $ARCHS
do
OPUS_DIR=opus-$ARCH
if [ ! -d $OPUS_DIR ]
then
echo "Directory $OPUS_DIR does not exist, run sync.sh"
exit 1
fi
echo "Compiling source for $ARCH in directory $OPUS_DIR"
echo "cd $OPUS_DIR"
cd $OPUS_DIR
DIST_DIR=$DIST_DIR_BASE-$ARCH
echo "mkdir -p $DIST_DIR"
mkdir -p $DIST_DIR
CFLAGS_ARCH=$ARCH
case $ARCH in
armv7)
EXTRA_FLAGS="--with-pic --enable-fixed-point"
EXTRA_CFLAGS="-mcpu=cortex-a8 -mfpu=neon -miphoneos-version-min=7.1"
PLATFORM="${PLATFORMBASE}/iPhoneOS.platform"
IOSSDK=iPhoneOS
;;
armv7s)
EXTRA_FLAGS="--with-pic --enable-fixed-point"
EXTRA_CFLAGS="-mcpu=cortex-a9 -mfpu=neon -miphoneos-version-min=7.1"
PLATFORM="${PLATFORMBASE}/iPhoneOS.platform"
IOSSDK=iPhoneOS
;;
aarch64)
CFLAGS_ARCH="arm64"
EXTRA_FLAGS="--with-pic --enable-fixed-point"
EXTRA_CFLAGS="-miphoneos-version-min=7.1"
PLATFORM="${PLATFORMBASE}/iPhoneOS.platform"
IOSSDK=iPhoneOS
;;
x86_64)
EXTRA_FLAGS="--with-pic"
EXTRA_CFLAGS="-miphoneos-version-min=7.1"
PLATFORM="${PLATFORMBASE}/iPhoneSimulator.platform"
IOSSDK=iPhoneSimulator
;;
i386)
EXTRA_FLAGS="--with-pic"
EXTRA_CFLAGS="-miphoneos-version-min=7.1"
PLATFORM="${PLATFORMBASE}/iPhoneSimulator.platform"
IOSSDK=iPhoneSimulator
;;
*)
echo "Unsupported architecture ${ARCH}"
exit 1
;;
esac
echo "Configuring opus for $ARCH..."
echo "./autogen.sh"
./autogen.sh
CFLAGS="-g -O2 -pipe -arch ${CFLAGS_ARCH} \
-isysroot ${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk \
-I${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk/usr/include \
${EXTRA_CFLAGS}"
LDFLAGS="-arch ${CFLAGS_ARCH} \
-isysroot ${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk \
-L${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk/usr/lib"
echo "CFLAGS=$CFLAGS"
echo "LDFLAGS=$LDFLAGS"
export CFLAGS
export LDFLAGS
export CXXCPP="/usr/bin/cpp"
export CPP="$CXXCPP"
export CXX="/usr/bin/gcc"
export CC="/usr/bin/gcc"
export LD="/usr/bin/ld"
export AR="/usr/bin/ar"
export AS="/usr/bin/ls"
export NM="/usr/bin/nm"
export RANLIB="/usr/bin/ranlib"
export STRIP="/usr/bin/strip"
echo "./configure \
--prefix=$DIST_DIR \
--host=${ARCH}-apple-darwin \
--with-sysroot=${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk \
--enable-static=yes \
--enable-shared=no \
--disable-doc \
${EXTRA_FLAGS}"
./configure \
--prefix=$DIST_DIR \
--host=${ARCH}-apple-darwin \
--with-sysroot=${PLATFORM}/Developer/SDKs/${IOSSDK}.sdk \
--enable-static=yes \
--enable-shared=no \
--disable-doc \
${EXTRA_FLAGS}
echo "Installing opus for $ARCH..."
echo "make clean"
make clean
echo "make -j$NJOB V=1"
make -j$NJOB V=1
echo "make install"
make install
echo "cd $SCRIPT_DIR"
cd $SCRIPT_DIR
if [ -d $DIST_DIR/bin ]
then
rm -rf $DIST_DIR/bin
fi
if [ -d $DIST_DIR/share ]
then
rm -rf $DIST_DIR/share
fi
done

View File

@ -1,51 +0,0 @@
#!/bin/bash
set -e
source config.sh
for ARCH in $ARCHS
do
if [ -d dist-$ARCH ]
then
MAIN_ARCH=$ARCH
fi
done
if [ -z "$MAIN_ARCH" ]
then
echo "Please compile an architecture"
exit 1
fi
OUTPUT_DIR="dist-uarch"
rm -rf $OUTPUT_DIR
mkdir -p $OUTPUT_DIR/lib $OUTPUT_DIR/include
for LIB in dist-$MAIN_ARCH/lib/*.a
do
LIB=`basename $LIB`
LIPO_CREATE=""
for ARCH in $ARCHS
do
LIPO_ARCH=$ARCH
if [ "$ARCH" = "aarch64" ];
then
LIPO_ARCH="arm64"
fi
if [ -d dist-$ARCH ]
then
LIPO_CREATE="$LIPO_CREATE-arch $LIPO_ARCH dist-$ARCH/lib/$LIB "
fi
done
OUTPUT="$OUTPUT_DIR/lib/$LIB"
echo "Creating: $OUTPUT"
xcrun -sdk iphoneos lipo -create $LIPO_CREATE -output $OUTPUT
xcrun -sdk iphoneos lipo -info $OUTPUT
done
echo "Copying headers from dist-$MAIN_ARCH..."
cp -R dist-$MAIN_ARCH/include/* $OUTPUT_DIR/include

View File

@ -1,36 +0,0 @@
#!/bin/bash
OPUS_DIR="opus"
IOSSDK_VER=8.1
ARCHS="armv7 armv7s aarch64 i386 x86_64"
remove_arch() {
OLD_ARCHS="$ARCHS"
NEW_ARCHS=""
REMOVAL="$1"
for ARCH in $OLD_ARCHS; do
if [ "$ARCH" != "$REMOVAL" ] ; then
NEW_ARCHS="$NEW_ARCHS $ARCH"
fi
done
ARCHS=$NEW_ARCHS
}
# armv7s is only supported in iOS 6.0+
CHECK=`echo $IOSSDK_VER '>= 6.0' | bc -l`
if [ "$CHECK" = "0" ] ; then
remove_arch "armv7s"
fi
# armv6 is not supported any more since iOS 6.0
CHECK=`echo $IOSSDK_VER '< 6.0' | bc -l`
if [ "$CHECK" = "0" ] ; then
remove_arch "armv6"
fi
echo 'Architectures to build:' $ARCHS

View File

@ -1,20 +0,0 @@
#!/bin/sh
set -e
source config.sh
SCRIPT_DIR=$( (cd -P $(dirname $0) && pwd) )
DIST_DIR_BASE=${DIST_DIR_BASE:="$SCRIPT_DIR/dist"}
cd opus
git checkout master
git pull origin master
cd ..
for ARCH in $ARCHS
do
OPUS_DIR=opus-$ARCH
echo "Syncing source for $ARCH to directory $OPUS_DIR"
rsync opus/ $OPUS_DIR/ --exclude '.*' -a --delete
done

View File

@ -1,104 +0,0 @@
#!/bin/bash
SYSROOT_iPHONE="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
SYSROOT_SIMULATOR="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk"
CC_IPHONE="xcrun -sdk iphoneos clang"
CC_SIMULATOR="xcrun -sdk iphonesimulator clang"
function build_one {
./configure \
--prefix=$PREFIX \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-armv5te \
--disable-armv6 \
--disable-doc \
--disable-everything \
--disable-debug \
--enable-decoder=h264 \
--enable-avresample \
--enable-cross-compile \
--sysroot=$SYSROOT \
--target-os=darwin \
--cc="$CC" \
--extra-cflags="$CFLAGS" \
--extra-ldflags="$LDFLAGS" \
--enable-pic \
$ADDI_FLAGS
make clean && make -j4 && make install
}
# armv7
function build_armv7 {
PREFIX="armv7"
SYSROOT=$SYSROOT_iPHONE
CC=$CC_IPHONE
CFLAGS="-arch armv7 -mfpu=neon -miphoneos-version-min=7.1 -fpic"
LDFLAGS="-arch armv7 -isysroot $SYSROOT_iPHONE -miphoneos-version-min=7.1"
ADDI_FLAGS="--arch=arm --cpu=cortex-a9"
build_one
}
# armv7s
function build_armv7s {
PREFIX="armv7s"
SYSROOT=$SYSROOT_iPHONE
CC=$CC_IPHONE
CFLAGS="-arch armv7s -mfpu=neon -miphoneos-version-min=7.1"
LDFLAGS="-arch armv7s -isysroot $SYSROOT_iPHONE -miphoneos-version-min=7.1"
ADDI_FLAGS="--arch=arm --cpu=cortex-a9"
build_one
}
# i386
function build_i386 {
PREFIX="i386"
SYSROOT=$SYSROOT_SIMULATOR
CC=$CC_SIMULATOR
CFLAGS="-arch i386"
LDFLAGS="-arch i386 -isysroot $SYSROOT_SIMULATOR -mios-simulator-version-min=7.1"
ADDI_FLAGS="--arch=i386 --cpu=i386 --disable-asm"
build_one
}
# create fat library
function build_universal {
cd armv7/lib
for file in *.a
do
cd ../..
xcrun -sdk iphoneos lipo -output universal/lib/$file -create \
-arch armv7 armv7/lib/$file \
-arch armv7s armv7s/lib/$file \
-arch i386 i386/lib/$file
echo "Universal $file created."
cd -
done
cd ../..
}
echo "FFmpeg directory?"
read SOURCE
cd $SOURCE
if [ "$1" = "clean" ]
then
rm -r armv7 armv7s i386 universal
make clean
exit 0
fi
mkdir armv7
mkdir armv7s
mkdir i386
mkdir -p universal/lib
build_armv7
build_armv7s
build_i386
build_universal
echo "Ouput files in $SOURCE/armv7 $SOURCE/armv7s $SOURCE/i386 $SOURCE/universal"

180
BuildScripts/build-libopus.sh Executable file
View File

@ -0,0 +1,180 @@
#!/bin/bash
# Builds libopus for iOS or tvOS.
#
# Copyright 2012 Mike Tigas <mike@tig.as>
#
# Based on work by Felix Schulze on 16.12.10.
# Copyright 2010 Felix Schulze. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
###########################################################################
# Choose your libopus version and your currently-installed iOS SDK version:
#
TARGET="AppleTV" # "iPhone"
VERSION="1.3.1"
SDKVERSION="16.1"
MINVERSIONDEF="-mtvos-version-min=12.0" # "-miphoneos-version-min=12.0"
###########################################################################
#
# Don't change anything under this line!
#
###########################################################################
# by default, we won't build for debugging purposes
if [ "${DEBUG}" == "true" ]; then
echo "Compiling for debugging ..."
OPT_CFLAGS="-O0 -fno-inline -g"
OPT_LDFLAGS=""
OPT_CONFIG_ARGS="--enable-assertions --disable-asm"
else
OPT_CFLAGS="-O3 -g"
OPT_LDFLAGS=""
OPT_CONFIG_ARGS=""
fi
# No need to change this since xcode build will only compile in the
# necessary bits from the libraries we create
ARCHS="x86_64 arm64"
DEVELOPER=`xcode-select -print-path`
#DEVELOPER="/Applications/Xcode.app/Contents/Developer"
cd "`dirname \"$0\"`"
REPOROOT=$(pwd)
# Where we'll end up storing things in the end
OUTPUTDIR="${REPOROOT}/dependencies"
mkdir -p ${OUTPUTDIR}/include
mkdir -p ${OUTPUTDIR}/lib
BUILDDIR="${REPOROOT}/build"
# where we will keep our sources and build from.
SRCDIR="${BUILDDIR}/src"
mkdir -p $SRCDIR
# where we will store intermediary builds
INTERDIR="${BUILDDIR}/built"
mkdir -p $INTERDIR
########################################
cd $SRCDIR
# Exit the script if an error happens
set -e
if [ ! -e "${SRCDIR}/opus-${VERSION}.tar.gz" ]; then
echo "Downloading opus-${VERSION}.tar.gz"
curl -LO http://downloads.xiph.org/releases/opus/opus-${VERSION}.tar.gz
fi
echo "Using opus-${VERSION}.tar.gz"
tar zxf opus-${VERSION}.tar.gz -C $SRCDIR
cd "${SRCDIR}/opus-${VERSION}"
set +e # don't bail out of bash script if ccache doesn't exist
CCACHE=`which ccache`
if [ $? == "0" ]; then
echo "Building with ccache: $CCACHE"
CCACHE="${CCACHE} "
else
echo "Building without ccache"
CCACHE=""
fi
set -e # back to regular "bail out on error" mode
export ORIGINALPATH=$PATH
for ARCH in ${ARCHS}
do
if [ "${ARCH}" == "i386" ] || [ "${ARCH}" == "x86_64" ]; then
PLATFORM="${TARGET}Simulator"
EXTRA_CFLAGS="-arch ${ARCH}"
EXTRA_CONFIG="--host=x86_64-apple-darwin"
else
PLATFORM="${TARGET}OS"
EXTRA_CFLAGS="-arch ${ARCH}"
EXTRA_CONFIG="--host=arm-apple-darwin"
fi
mkdir -p "${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk"
./configure --disable-shared --enable-static --with-pic --disable-extra-programs --disable-doc ${EXTRA_CONFIG} \
--prefix="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk" \
LDFLAGS="$LDFLAGS ${OPT_LDFLAGS} -fPIE ${MINVERSIONDEF} -L${OUTPUTDIR}/lib" \
CFLAGS="$CFLAGS ${EXTRA_CFLAGS} ${OPT_CFLAGS} -fPIE ${MINVERSIONDEF} -I${OUTPUTDIR}/include -isysroot ${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDKVERSION}.sdk" \
# Build the application and install it to the fake SDK intermediary dir
# we have set up. Make sure to clean up afterward because we will re-use
# this source tree to cross-compile other targets.
make -j$(nproc)
make install
make clean
done
########################################
echo "Build library..."
# These are the libs that comprise libopus.
OUTPUT_LIBS="libopus.a"
for OUTPUT_LIB in ${OUTPUT_LIBS}; do
INPUT_LIBS=""
for ARCH in ${ARCHS}; do
if [ "${ARCH}" == "i386" ] || [ "${ARCH}" == "x86_64" ];
then
PLATFORM="${TARGET}Simulator"
else
PLATFORM="${TARGET}OS"
fi
INPUT_ARCH_LIB="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/lib/${OUTPUT_LIB}"
if [ -e $INPUT_ARCH_LIB ]; then
INPUT_LIBS="${INPUT_LIBS} ${INPUT_ARCH_LIB}"
fi
done
# Combine the three architectures into a universal library.
if [ -n "$INPUT_LIBS" ]; then
lipo -create $INPUT_LIBS \
-output "${OUTPUTDIR}/lib/${OUTPUT_LIB}"
else
echo "$OUTPUT_LIB does not exist, skipping (are the dependencies installed?)"
fi
done
for ARCH in ${ARCHS}; do
if [ "${ARCH}" == "i386" ] || [ "${ARCH}" == "x86_64" ];
then
PLATFORM="${TARGET}Simulator"
else
PLATFORM="${TARGET}OS"
fi
cp -R ${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/include/* ${OUTPUTDIR}/include/
if [ $? == "0" ]; then
# We only need to copy the headers over once. (So break out of forloop
# once we get first success.)
break
fi
done
####################
echo "Building done."
echo "Cleaning up..."
rm -fr ${INTERDIR}
rm -fr "${SRCDIR}/opus-${VERSION}"
echo "Done."

View File

@ -1,124 +0,0 @@
#!/bin/bash
# Yay shell scripting! This script builds a static version of
# OpenSSL ${OPENSSL_VERSION} for iOS 7.0 that contains code for
# armv6, armv7, arm7s and i386.
#set -x
# Setup paths to stuff we need
OPENSSL_VERSION="1.0.1h"
DEVELOPER="/Applications/Xcode.app/Contents/Developer"
SDK_VERSION="7.1"
MIN_VERSION="7.1"
IPHONEOS_PLATFORM="${DEVELOPER}/Platforms/iPhoneOS.platform"
IPHONEOS_SDK="${IPHONEOS_PLATFORM}/Developer/SDKs/iPhoneOS.sdk"
IPHONEOS_GCC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
IPHONESIMULATOR_PLATFORM="${DEVELOPER}/Platforms/iPhoneSimulator.platform"
IPHONESIMULATOR_SDK="${IPHONESIMULATOR_PLATFORM}/Developer/SDKs/iPhoneSimulator.sdk"
IPHONESIMULATOR_GCC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
# Make sure things actually exist
if [ ! -d "$IPHONEOS_PLATFORM" ]; then
echo "Cannot find $IPHONEOS_PLATFORM"
exit 1
fi
if [ ! -d "$IPHONEOS_SDK" ]; then
echo "Cannot find $IPHONEOS_SDK"
exit 1
fi
if [ ! -x "$IPHONEOS_GCC" ]; then
echo "Cannot find $IPHONEOS_GCC"
exit 1
fi
if [ ! -d "$IPHONESIMULATOR_PLATFORM" ]; then
echo "Cannot find $IPHONESIMULATOR_PLATFORM"
exit 1
fi
if [ ! -d "$IPHONESIMULATOR_SDK" ]; then
echo "Cannot find $IPHONESIMULATOR_SDK"
exit 1
fi
if [ ! -x "$IPHONESIMULATOR_GCC" ]; then
echo "Cannot find $IPHONESIMULATOR_GCC"
exit 1
fi
# Clean up whatever was left from our previous build
rm -rf include lib
rm -rf /tmp/openssl-${OPENSSL_VERSION}-*
rm -rf /tmp/openssl-${OPENSSL_VERSION}-*.*-log
build()
{
TARGET=$1
ARCH=$2
GCC=$3
SDK=$4
EXTRA=$5
rm -rf "openssl-${OPENSSL_VERSION}"
tar xfz "openssl-${OPENSSL_VERSION}.tar.gz"
pushd .
cd "openssl-${OPENSSL_VERSION}"
./Configure ${TARGET} --openssldir="/tmp/openssl-${OPENSSL_VERSION}-${ARCH}" ${EXTRA} &> "/tmp/openssl-${OPENSSL_VERSION}-${ARCH}.log"
perl -i -pe 's|static volatile sig_atomic_t intr_signal|static volatile int intr_signal|' crypto/ui/ui_openssl.c
perl -i -pe "s|^CC= gcc|CC= ${GCC} -arch ${ARCH} -miphoneos-version-min=${MIN_VERSION}|g" Makefile
perl -i -pe "s|^CFLAG= (.*)|CFLAG= -isysroot ${SDK} \$1|g" Makefile
make &> "/tmp/openssl-${OPENSSL_VERSION}-${ARCH}.build-log"
make install &> "/tmp/openssl-${OPENSSL_VERSION}-${ARCH}.install-log"
popd
rm -rf "openssl-${OPENSSL_VERSION}"
}
mkdir openssl
cd openssl
if [ ! -e ${OPENSSL_VERSION}.tar.gz ]; then
echo "Downloading ${OPENSSL_VERSION}.tar.gz"
curl -O http://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
else
echo "Using ${OPENSSL_VERSION}.tar.gz"
fi
build "BSD-generic32" "armv7" "${IPHONEOS_GCC}" "${IPHONEOS_SDK}" ""
build "BSD-generic32" "armv7s" "${IPHONEOS_GCC}" "${IPHONEOS_SDK}" ""
build "BSD-generic64" "arm64" "${IPHONEOS_GCC}" "${IPHONEOS_SDK}" ""
build "BSD-generic32" "i386" "${IPHONESIMULATOR_GCC}" "${IPHONESIMULATOR_SDK}" ""
build "BSD-generic64" "x86_64" "${IPHONESIMULATOR_GCC}" "${IPHONESIMULATOR_SDK}" "-DOPENSSL_NO_ASM"
#
mkdir include
cp -r /tmp/openssl-${OPENSSL_VERSION}-i386/include/openssl include/
mkdir lib
lipo \
"/tmp/openssl-${OPENSSL_VERSION}-armv7/lib/libcrypto.a" \
"/tmp/openssl-${OPENSSL_VERSION}-armv7s/lib/libcrypto.a" \
"/tmp/openssl-${OPENSSL_VERSION}-arm64/lib/libcrypto.a" \
"/tmp/openssl-${OPENSSL_VERSION}-i386/lib/libcrypto.a" \
"/tmp/openssl-${OPENSSL_VERSION}-x86_64/lib/libcrypto.a" \
-create -output lib/libcrypto.a
lipo \
"/tmp/openssl-${OPENSSL_VERSION}-armv7/lib/libssl.a" \
"/tmp/openssl-${OPENSSL_VERSION}-armv7s/lib/libssl.a" \
"/tmp/openssl-${OPENSSL_VERSION}-arm64/lib/libssl.a" \
"/tmp/openssl-${OPENSSL_VERSION}-i386/lib/libssl.a" \
"/tmp/openssl-${OPENSSL_VERSION}-x86_64/lib/libssl.a" \
-create -output lib/libssl.a
rm -rf "/tmp/openssl-${OPENSSL_VERSION}-*"
rm -rf "/tmp/openssl-${OPENSSL_VERSION}-*.*-log"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,51 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="15A279b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="landscape" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<navigationController id="vV9-32-ww6">
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="y2P-aE-Haa">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<color key="barTintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</navigationBar>
<viewControllers>
<viewController id="l6V-ue-5Om">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="rEZ-vx-akr"/>
<viewControllerLayoutGuide type="bottom" id="gBD-cy-cth"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="6lF-fc-kpK">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
</view>
<navigationItem key="navigationItem" id="rW0-BH-s7l">
<barButtonItem key="leftBarButtonItem" enabled="NO" id="d9R-Zo-Uml">
<button key="customView" opaque="NO" contentMode="center" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="9JC-B5-BAE">
<rect key="frame" x="20" y="-1" width="109" height="46"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="Moonlight" image="Logo">
<color key="titleColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</state>
<variation key="widthClass=regular" preservesSuperviewLayoutMargins="NO"/>
</button>
</barButtonItem>
</navigationItem>
</viewController>
</viewControllers>
</navigationController>
<view contentMode="scaleToFill" id="VWy-YH-qYj">
<rect key="frame" x="0.0" y="0.0" width="896" height="414"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<point key="canvasLocation" x="33" y="187"/>
</view>
</objects>
<resources>
<image name="Logo" width="32" height="32"/>
</resources>
</document>

View File

@ -6,19 +6,13 @@
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
//
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
#else
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (readonly, strong) NSPersistentContainer *persistentContainer;
@property (strong, nonatomic) NSWindow *window;
#endif
@property (strong, nonatomic) NSString *pcUuidToLoad;
@property (strong, nonatomic) void (^shortcutCompletionHandler)(BOOL);
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;

View File

@ -18,19 +18,27 @@ static NSOperationQueue* mainQueue;
#if TARGET_OS_TV
static NSString* DB_NAME = @"Moonlight_tvOS.bin";
#elif TARGET_OS_IPHONE
static NSString* DB_NAME = @"Limelight_iOS.sqlite";
#else
static NSString* DB_NAME = @"moonlight_mac.sqlite";
static NSString* DB_NAME = @"Limelight_iOS.sqlite";
#endif
#if TARGET_OS_IPHONE
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#if !TARGET_OS_TV
UIApplicationShortcutItem* shortcut = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
if (shortcut != nil) {
_pcUuidToLoad = (NSString*)[shortcut.userInfo objectForKey:@"UUID"];
}
#endif
return YES;
}
#if !TARGET_OS_TV
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler {
_pcUuidToLoad = (NSString*)[shortcutItem.userInfo objectForKey:@"UUID"];
_shortcutCompletionHandler = completionHandler;
}
#endif
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
@ -58,17 +66,6 @@ static NSString* DB_NAME = @"moonlight_mac.sqlite";
// Saves changes in the application's managed object context before the application terminates.
[self saveContext];
}
#else
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
[self saveContext];
}
#endif
- (void)saveContext
{

View File

@ -9,7 +9,6 @@
#import "CryptoManager.h"
#import "mkcert.h"
#include <openssl/aes.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
@ -45,46 +44,47 @@ static NSData* p12 = nil;
}
- (NSData*) aesEncrypt:(NSData*)data withKey:(NSData*)key {
AES_KEY aesKey;
AES_set_encrypt_key([key bytes], 128, &aesKey);
int size = [self getEncryptSize:data];
unsigned char* buffer = malloc(size);
unsigned char* blockRoundedBuffer = calloc(1, size);
memcpy(blockRoundedBuffer, [data bytes], [data length]);
EVP_CIPHER_CTX* cipher;
int ciphertextLen;
cipher = EVP_CIPHER_CTX_new();
EVP_EncryptInit(cipher, EVP_aes_128_ecb(), [key bytes], NULL);
EVP_CIPHER_CTX_set_padding(cipher, 0);
NSMutableData* ciphertext = [NSMutableData dataWithLength:[data length]];
EVP_EncryptUpdate(cipher,
[ciphertext mutableBytes],
&ciphertextLen,
[data bytes],
(int)[data length]);
assert(ciphertextLen == [ciphertext length]);
EVP_CIPHER_CTX_free(cipher);
// AES_encrypt only encrypts the first 16 bytes so iterate the entire buffer
int blockOffset = 0;
while (blockOffset < size) {
AES_encrypt(blockRoundedBuffer + blockOffset, buffer + blockOffset, &aesKey);
blockOffset += 16;
}
NSData* encryptedData = [NSData dataWithBytes:buffer length:size];
free(buffer);
free(blockRoundedBuffer);
return encryptedData;
return ciphertext;
}
- (NSData*) aesDecrypt:(NSData*)data withKey:(NSData*)key {
AES_KEY aesKey;
AES_set_decrypt_key([key bytes], 128, &aesKey);
unsigned char* buffer = malloc([data length]);
// AES_decrypt only decrypts the first 16 bytes so iterate the entire buffer
int blockOffset = 0;
while (blockOffset < [data length]) {
AES_decrypt([data bytes] + blockOffset, buffer + blockOffset, &aesKey);
blockOffset += 16;
}
NSData* decryptedData = [NSData dataWithBytes:buffer length:[data length]];
free(buffer);
return decryptedData;
}
EVP_CIPHER_CTX* cipher;
int plaintextLen;
- (int) getEncryptSize:(NSData*)data {
// the size is the length of the data ceiling to the nearest 16 bytes
return (((int)[data length] + 15) / 16) * 16;
cipher = EVP_CIPHER_CTX_new();
EVP_DecryptInit(cipher, EVP_aes_128_ecb(), [key bytes], NULL);
EVP_CIPHER_CTX_set_padding(cipher, 0);
NSMutableData* plaintext = [NSMutableData dataWithLength:[data length]];
EVP_DecryptUpdate(cipher,
[plaintext mutableBytes],
&plaintextLen,
[data bytes],
(int)[data length]);
assert(plaintextLen == [plaintext length]);
EVP_CIPHER_CTX_free(cipher);
return plaintext;
}
+ (NSData*) pemToDer:(NSData*)pemCertBytes {
@ -96,6 +96,7 @@ static NSData* p12 = nil;
bio = BIO_new(BIO_s_mem());
i2d_X509_bio(bio, x509);
X509_free(x509);
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
@ -222,18 +223,34 @@ static NSData* p12 = nil;
+ (NSData *)getSignatureFromCert:(NSData *)cert {
BIO* bio = BIO_new_mem_buf([cert bytes], (int)[cert length]);
X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
BIO_free(bio);
if (!x509) {
Log(LOG_E, @"Unable to parse certificate in memory!");
return NULL;
}
return [NSData dataWithBytes:x509->signature->data length:x509->signature->length];
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
ASN1_BIT_STRING *asnSignature = x509->signature;
#elif (OPENSSL_VERSION_NUMBER < 0x10100000L)
ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, x509);
#else
const ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, x509);
#endif
NSData* sig = [NSData dataWithBytes:asnSignature->data length:asnSignature->length];
X509_free(x509);
return sig;
}
+ (NSData*)getKeyFromCertKeyPair:(CertKeyPair*)certKeyPair {
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, certKeyPair->pkey, NULL, NULL, 0, NULL, NULL);
PEM_write_bio_PrivateKey_traditional(bio, certKeyPair->pkey, NULL, NULL, 0, NULL, NULL);
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);

View File

@ -4,54 +4,88 @@
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/pkcs12.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include <OpenSSL/provider.h>
#include <OpenSSL/rsa.h>
#include <openssl/x509.h>
#include <OpenSSL/rand.h>
static const int NUM_BITS = 2048;
static const int SERIAL = 0;
static const int NUM_YEARS = 10;
static const int NUM_YEARS = 20;
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years);
int add_ext(X509 *cert, int nid, char *value);
void mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
X509* cert = X509_new();
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits);
// pk must be initialized on input
EVP_PKEY* pk = NULL;
EVP_PKEY_keygen(ctx, &pk);
EVP_PKEY_CTX_free(ctx);
X509_set_version(cert, 2);
ASN1_INTEGER_set(X509_get_serialNumber(cert), serial);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
X509_gmtime_adj(X509_get_notBefore(cert), 0);
X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * years);
#else
ASN1_TIME* before = ASN1_STRING_dup(X509_get0_notBefore(cert));
ASN1_TIME* after = ASN1_STRING_dup(X509_get0_notAfter(cert));
X509_gmtime_adj(before, 0);
X509_gmtime_adj(after, 60 * 60 * 24 * 365 * years);
X509_set1_notBefore(cert, before);
X509_set1_notAfter(cert, after);
ASN1_STRING_free(before);
ASN1_STRING_free(after);
#endif
X509_set_pubkey(cert, pk);
X509_NAME* name = X509_get_subject_name(cert);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
(const unsigned char*)"NVIDIA GameStream Client",
-1, -1, 0);
X509_set_issuer_name(cert, name);
X509_sign(cert, pk, EVP_sha256());
*x509p = cert;
*pkeyp = pk;
}
struct CertKeyPair generateCertKeyPair(void) {
BIO *bio_err;
X509 *x509 = NULL;
EVP_PKEY *pkey = NULL;
PKCS12 *p12 = NULL;
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
SSLeay_add_all_algorithms();
ERR_load_crypto_strings();
mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS);
p12 = PKCS12_create("limelight", "GameStream", pkey, x509, NULL, 0, 0, 0, 0, 0);
char* pass = "limelight";
p12 = PKCS12_create(pass,
"GameStream",
pkey,
x509,
NULL,
NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
-1, // disable certificate encryption
2048,
-1, // disable the automatic MAC
0);
// MAC it ourselves with SHA1 since iOS refuses to load anything else.
PKCS12_set_mac(p12, pass, -1, NULL, 0, 1, EVP_sha1());
if (p12 == NULL) {
printf("Error generating a valid PKCS12 certificate.\n");
}
// Debug Print statements
//RSA_print_fp(stdout, pkey->pkey.rsa, 0);
//X509_print_fp(stdout, x509);
//PEM_write_PUBKEY(stdout, pkey);
//PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
//PEM_write_X509(stdout, x509);
#ifndef OPENSSL_NO_ENGINE
ENGINE_cleanup();
#endif
CRYPTO_cleanup_all_ex_data();
CRYPTO_mem_leaks(bio_err);
BIO_free(bio_err);
return (CertKeyPair){x509, pkey, p12};
}
@ -61,92 +95,3 @@ void freeCertKeyPair(struct CertKeyPair certKeyPair) {
EVP_PKEY_free(certKeyPair.pkey);
PKCS12_free(certKeyPair.p12);
}
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
X509 *x;
EVP_PKEY *pk;
RSA *rsa;
X509_NAME *name = NULL;
if (*pkeyp == NULL) {
if ((pk=EVP_PKEY_new()) == NULL) {
return(0);
}
} else {
pk = *pkeyp;
}
if (*x509p == NULL) {
if ((x = X509_new()) == NULL) {
goto err;
}
} else {
x = *x509p;
}
rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);
if (!EVP_PKEY_assign_RSA(pk, rsa)) {
goto err;
}
X509_set_version(x, 2);
ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
X509_gmtime_adj(X509_get_notBefore(x), 0);
X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*365*years);
X509_set_pubkey(x, pk);
name = X509_get_subject_name(x);
/* This function creates and adds the entry, working out the
* correct string type and performing checks on its length.
*/
X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (unsigned char*)"NVIDIA GameStream Client", -1, -1, 0);
/* Its self signed so set the issuer name to be the same as the
* subject.
*/
X509_set_issuer_name(x, name);
/* Add various extensions: standard extensions */
add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");
add_ext(x, NID_subject_key_identifier, "hash");
if (!X509_sign(x, pk, EVP_sha1())) {
goto err;
}
*x509p = x;
*pkeyp = pk;
return(1);
err:
return(0);
}
/* Add extension using V3 code: we can set the config file as NULL
* because we wont reference any other sections.
*/
int add_ext(X509 *cert, int nid, char *value)
{
X509_EXTENSION *ex;
X509V3_CTX ctx;
/* This sets the 'context' of the extensions. */
/* No configuration database */
X509V3_set_ctx_nodb(&ctx);
/* Issuer and subject certs: both the target since it is self signed,
* no request and no CRL
*/
X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
if (!ex) {
return 0;
}
X509_add_ext(cert, ex, -1);
X509_EXTENSION_free(ex);
return 1;
}

View File

@ -17,13 +17,18 @@
framerate:(NSInteger)framerate
height:(NSInteger)height
width:(NSInteger)width
audioConfig:(NSInteger)audioConfig
onscreenControls:(NSInteger)onscreenControls
remote:(BOOL)streamingRemotely
optimizeGames:(BOOL)optimizeGames
multiController:(BOOL)multiController
swapABXYButtons:(BOOL)swapABXYButtons
audioOnPC:(BOOL)audioOnPC
useHevc:(BOOL)useHevc
enableHdr:(BOOL)enableHdr;
preferredCodec:(uint32_t)preferredCodec
useFramePacing:(BOOL)useFramePacing
enableHdr:(BOOL)enableHdr
btMouseSupport:(BOOL)btMouseSupport
absoluteTouchMode:(BOOL)absoluteTouchMode
statsOverlay:(BOOL)statsOverlay;
- (NSArray*) getHosts;
- (void) updateHost:(TemporaryHost*)host;

View File

@ -21,12 +21,11 @@
// HACK: Avoid calling [UIApplication delegate] off the UI thread to keep
// Main Thread Checker happy.
if ([NSThread isMainThread]) {
_appDelegate = (AppDelegate *)[[OSApplication sharedApplication] delegate];
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
else {
dispatch_sync(dispatch_get_main_queue(), ^{
self->_appDelegate = (AppDelegate *)[[OSApplication sharedApplication] delegate];
self->_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
});
}
@ -57,13 +56,18 @@
framerate:(NSInteger)framerate
height:(NSInteger)height
width:(NSInteger)width
audioConfig:(NSInteger)audioConfig
onscreenControls:(NSInteger)onscreenControls
remote:(BOOL)streamingRemotely
optimizeGames:(BOOL)optimizeGames
multiController:(BOOL)multiController
swapABXYButtons:(BOOL)swapABXYButtons
audioOnPC:(BOOL)audioOnPC
useHevc:(BOOL)useHevc
enableHdr:(BOOL)enableHdr {
preferredCodec:(uint32_t)preferredCodec
useFramePacing:(BOOL)useFramePacing
enableHdr:(BOOL)enableHdr
btMouseSupport:(BOOL)btMouseSupport
absoluteTouchMode:(BOOL)absoluteTouchMode
statsOverlay:(BOOL)statsOverlay {
[_managedObjectContext performBlockAndWait:^{
Settings* settingsToSave = [self retrieveSettings];
@ -71,13 +75,18 @@
settingsToSave.bitrate = [NSNumber numberWithInteger:bitrate];
settingsToSave.height = [NSNumber numberWithInteger:height];
settingsToSave.width = [NSNumber numberWithInteger:width];
settingsToSave.audioConfig = [NSNumber numberWithInteger:audioConfig];
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
settingsToSave.streamingRemotely = streamingRemotely;
settingsToSave.optimizeGames = optimizeGames;
settingsToSave.multiController = multiController;
settingsToSave.swapABXYButtons = swapABXYButtons;
settingsToSave.playAudioOnPC = audioOnPC;
settingsToSave.useHevc = useHevc;
settingsToSave.preferredCodec = preferredCodec;
settingsToSave.useFramePacing = useFramePacing;
settingsToSave.enableHdr = enableHdr;
settingsToSave.btMouseSupport = btMouseSupport;
settingsToSave.absoluteTouchMode = absoluteTouchMode;
settingsToSave.statsOverlay = statsOverlay;
[self saveData];
}];

View File

@ -13,7 +13,9 @@
@property (nullable, nonatomic, retain) NSString *id;
@property (nullable, nonatomic, retain) NSString *name;
@property (nullable, nonatomic, retain) NSString *installPath;
@property (nonatomic) BOOL hdrSupported;
@property (nonatomic) BOOL hidden;
@property (nullable, nonatomic, retain) TemporaryHost *host;
NS_ASSUME_NONNULL_BEGIN

View File

@ -16,6 +16,7 @@
self.id = app.id;
self.name = app.name;
self.hdrSupported = app.hdrSupported;
self.hidden = app.hidden;
self.host = tempHost;
return self;
@ -25,6 +26,7 @@
parent.id = self.id;
parent.name = self.name;
parent.hdrSupported = self.hdrSupported;
parent.hidden = self.hidden;
parent.host = host;
}
@ -41,7 +43,7 @@
return YES;
}
if (![object isKindOfClass:[App class]]) {
if (![object isKindOfClass:[self class]]) {
return NO;
}

View File

@ -11,23 +11,26 @@
@interface TemporaryHost : NSObject
@property (nonatomic) BOOL online;
@property (nonatomic) PairState pairState;
@property (nonatomic, nullable) NSString * activeAddress;
@property (nonatomic, nullable) NSString * currentGame;
@property (atomic) State state;
@property (atomic) PairState pairState;
@property (atomic, nullable, retain) NSString * activeAddress;
@property (atomic, nullable, retain) NSString * currentGame;
@property (atomic) unsigned short httpsPort;
@property (atomic) BOOL isNvidiaServerSoftware;
@property (nonatomic, nullable, retain) NSData *serverCert;
@property (nonatomic, nullable, retain) NSString *address;
@property (nonatomic, nullable, retain) NSString *externalAddress;
@property (nonatomic, nullable, retain) NSString *localAddress;
@property (nonatomic, nullable, retain) NSString *mac;
@property (nonatomic) int serverCodecModeSupport;
@property (atomic, nullable, retain) NSData *serverCert;
@property (atomic, nullable, retain) NSString *address;
@property (atomic, nullable, retain) NSString *externalAddress;
@property (atomic, nullable, retain) NSString *localAddress;
@property (atomic, nullable, retain) NSString *ipv6Address;
@property (atomic, nullable, retain) NSString *mac;
@property (atomic) int serverCodecModeSupport;
NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *uuid;
@property (nonatomic, retain) NSMutableSet *appList;
@property (atomic, retain) NSString *name;
@property (atomic, retain) NSString *uuid;
@property (atomic, retain) NSSet *appList;
- (id) initFromHost:(Host*)host;

View File

@ -16,6 +16,7 @@
self = [super init];
self.appList = [[NSMutableSet alloc] init];
self.currentGame = @"0";
self.state = StateUnknown;
return self;
}
@ -26,12 +27,18 @@
self.address = host.address;
self.externalAddress = host.externalAddress;
self.localAddress = host.localAddress;
self.ipv6Address = host.ipv6Address;
self.mac = host.mac;
self.name = host.name;
self.uuid = host.uuid;
self.serverCodecModeSupport = host.serverCodecModeSupport;
self.serverCert = host.serverCert;
// Older clients stored a non-URL-escaped IPv6 string. Try to detect that and fix it up.
if (![self.ipv6Address containsString:@"["]) {
self.ipv6Address = [Utils addressAndPortToAddressPortString:self.ipv6Address port:47989];
}
// Ensure we don't use a stale cached pair state if we haven't pinned the cert yet
self.pairState = host.serverCert ? [host.pairState intValue] : PairStateUnpaired;
@ -60,6 +67,9 @@
if (self.localAddress != nil) {
parentHost.localAddress = self.localAddress;
}
if (self.ipv6Address != nil) {
parentHost.ipv6Address = self.ipv6Address;
}
if (self.mac != nil) {
parentHost.mac = self.mac;
}
@ -85,7 +95,7 @@
return YES;
}
if (![object isKindOfClass:[Host class]]) {
if (![object isKindOfClass:[self class]]) {
return NO;
}

View File

@ -16,14 +16,24 @@
@property (nonatomic, retain) NSNumber * framerate;
@property (nonatomic, retain) NSNumber * height;
@property (nonatomic, retain) NSNumber * width;
@property (nonatomic, retain) NSNumber * audioConfig;
@property (nonatomic, retain) NSNumber * onscreenControls;
@property (nonatomic, retain) NSString * uniqueId;
@property (nonatomic) BOOL streamingRemotely;
@property (nonatomic) BOOL useHevc;
@property (nonatomic) enum {
CODEC_PREF_AUTO,
CODEC_PREF_H264,
CODEC_PREF_HEVC,
CODEC_PREF_AV1,
} preferredCodec;
@property (nonatomic) BOOL useFramePacing;
@property (nonatomic) BOOL multiController;
@property (nonatomic) BOOL swapABXYButtons;
@property (nonatomic) BOOL playAudioOnPC;
@property (nonatomic) BOOL optimizeGames;
@property (nonatomic) BOOL enableHdr;
@property (nonatomic) BOOL btMouseSupport;
@property (nonatomic) BOOL absoluteTouchMode;
@property (nonatomic) BOOL statsOverlay;
- (id) initFromSettings:(Settings*)settings;

View File

@ -17,26 +17,34 @@
self.parent = settings;
#if TARGET_OS_TV
NSInteger _bitrate = [[NSUserDefaults standardUserDefaults] integerForKey:@"bitrate"];
NSInteger _framerate = [[NSUserDefaults standardUserDefaults] integerForKey:@"framerate"];
if (_bitrate) {
self.bitrate = [NSNumber numberWithInteger:_bitrate];
} else {
self.bitrate = [NSNumber numberWithInteger:20000];
// Apply default values from our Root.plist
NSString* settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
NSDictionary* settingsData = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSArray* preferences = [settingsData objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary* defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for (NSDictionary* prefSpecification in preferences) {
NSString* key = [prefSpecification objectForKey:@"Key"];
if (key != nil) {
[defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
}
}
if (_framerate) {
self.framerate = [NSNumber numberWithInteger:_framerate];
} else {
self.framerate = [NSNumber numberWithInteger:60];
}
self.useHevc = [[NSUserDefaults standardUserDefaults] boolForKey:@"useHevc"] || NO;
self.playAudioOnPC = [[NSUserDefaults standardUserDefaults] boolForKey:@"audioOnPC"] || NO;
self.enableHdr = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableHdr"] || NO;
self.optimizeGames = [[NSUserDefaults standardUserDefaults] boolForKey:@"optimizeGames"] || YES;
self.multiController = [[NSUserDefaults standardUserDefaults] boolForKey:@"multipleControllers"] || YES;
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
self.bitrate = [NSNumber numberWithInteger:[[NSUserDefaults standardUserDefaults] integerForKey:@"bitrate"]];
assert([self.bitrate intValue] != 0);
self.framerate = [NSNumber numberWithInteger:[[NSUserDefaults standardUserDefaults] integerForKey:@"framerate"]];
assert([self.framerate intValue] != 0);
self.audioConfig = [NSNumber numberWithInteger:[[NSUserDefaults standardUserDefaults] integerForKey:@"audioConfig"]];
assert([self.audioConfig intValue] != 0);
self.preferredCodec = (typeof(self.preferredCodec))[[NSUserDefaults standardUserDefaults] integerForKey:@"preferredCodec"];
self.useFramePacing = [[NSUserDefaults standardUserDefaults] integerForKey:@"useFramePacing"] != 0;
self.playAudioOnPC = [[NSUserDefaults standardUserDefaults] boolForKey:@"audioOnPC"];
self.enableHdr = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableHdr"];
self.optimizeGames = [[NSUserDefaults standardUserDefaults] boolForKey:@"optimizeGames"];
self.multiController = [[NSUserDefaults standardUserDefaults] boolForKey:@"multipleControllers"];
self.swapABXYButtons = [[NSUserDefaults standardUserDefaults] boolForKey:@"swapABXYButtons"];
self.btMouseSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"btMouseSupport"];
self.statsOverlay = [[NSUserDefaults standardUserDefaults] boolForKey:@"statsOverlay"];
NSInteger _screenSize = [[NSUserDefaults standardUserDefaults] integerForKey:@"streamResolution"];
switch (_screenSize) {
@ -44,31 +52,41 @@
self.height = [NSNumber numberWithInteger:720];
self.width = [NSNumber numberWithInteger:1280];
break;
case 1:
self.height = [NSNumber numberWithInteger:1080];
self.width = [NSNumber numberWithInteger:1920];
break;
case 2:
self.height = [NSNumber numberWithInteger:2160];
self.width = [NSNumber numberWithInteger:3840];
break;
case 1:
default:
self.height = [NSNumber numberWithInteger:1080];
self.width = [NSNumber numberWithInteger:1920];
case 3:
self.height = [NSNumber numberWithInteger:1440];
self.width = [NSNumber numberWithInteger:2560];
break;
default:
abort();
}
self.onscreenControls = (NSInteger)OnScreenControlsLevelOff;
self.onscreenControls = [NSNumber numberWithInteger:OnScreenControlsLevelOff];
#else
self.bitrate = settings.bitrate;
self.framerate = settings.framerate;
self.height = settings.height;
self.width = settings.width;
self.useHevc = settings.useHevc;
self.audioConfig = settings.audioConfig;
self.preferredCodec = settings.preferredCodec;
self.useFramePacing = settings.useFramePacing;
self.playAudioOnPC = settings.playAudioOnPC;
self.enableHdr = settings.enableHdr;
self.optimizeGames = settings.optimizeGames;
self.multiController = settings.multiController;
self.swapABXYButtons = settings.swapABXYButtons;
self.onscreenControls = settings.onscreenControls;
self.btMouseSupport = settings.btMouseSupport;
self.absoluteTouchMode = settings.absoluteTouchMode;
self.statsOverlay = settings.statsOverlay;
#endif
self.uniqueId = settings.uniqueId;
self.streamingRemotely = settings.streamingRemotely;
return self;
}

View File

@ -1,23 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "limelight_computer_add_icon_1x.png"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "limelight_computer_add_icon_2x.png"
},
{
"idiom" : "universal",
"scale" : "3x",
"filename" : "limelight_computer_add_icon_3x.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -2,11 +2,11 @@
"images" : [
{
"idiom" : "universal",
"filename" : "add.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "logo.png",
"scale" : "2x"
},
{

View File

@ -0,0 +1,68 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœ]P[à ûÏ)r<>1}°cìÒº<C392>öcÛý¥AèZ!%q였°/ç"%Èè9oô&áz> _ž—/%qaä!ºyä<79>§T3ÐjqµîaÚ”t„,~ÖÚGHýôzQõ ®î:xgµ†I6Âß:gP(( hñ¯-1Îü5ç¶Žn3»!&úÖ"˜B-Õ¨~1@½ZÒ¹](¡¿d÷ë9ا-žt§å…aL
endstream
endobj
5 0 obj
183
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 150 150 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.16.0 (https://cairographics.org))
/CreationDate (D:20190922201812-07'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000587 00000 n
0000000369 00000 n
0000000297 00000 n
0000000015 00000 n
0000000275 00000 n
0000000652 00000 n
0000000768 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
820
%%EOF

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "AltIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,71 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœ][ƒ Eÿ³Šl )y¸Œ.¡ÃTû¡µûŸi€ Õa9×<07>ÑȺ±l.zÌ+|ÀTmñþ48a”ä_°äÑ&&ëSØ^8cYÕÍÅíl"‹«Æ5ºá<76>"{
ò<9¶<39>j<EFBFBD> ­7Ö!Db ×<>PÊbåÐjt¤øzÅÚœÔ:ƒº,'á½âýÒ‡ wRÁùÊ|µ8)w
-{GÍÑsµ™<C2B5>æ üÞG^’íosû»£MÅkäøà=h_
endstream
endobj
5 0 obj
214
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 0.3 /ca 0.3 >>
/a1 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 375 375 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.16.0 (https://cairographics.org))
/CreationDate (D:20190922201805-07'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000650 00000 n
0000000432 00000 n
0000000328 00000 n
0000000015 00000 n
0000000306 00000 n
0000000715 00000 n
0000000831 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
883
%%EOF

View File

@ -2,18 +2,16 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "limelight_computer_1x.png"
"filename" : "Computer.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "limelight_computer_2x.png"
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x",
"filename" : "limelight_computer_3x.png"
"scale" : "3x"
}
],
"info" : {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ControlIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "DeleteIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "doneIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

View File

@ -2,17 +2,15 @@
"images" : [
{
"idiom" : "universal",
"filename" : "pull-arrow-light-14x31@1x.png",
"filename" : "error.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "pull-arrow-light-28x61@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "pull-arrow-light-42x92@3x.png",
"scale" : "3x"
}
],

View File

@ -0,0 +1,68 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœUMA »ïý€¸<E282AC> ßð ÆD=ÈAý"L4š&[»µ€3ÉE<cJ´ àXÐŽŒå¤`¬‡8)-A:gúWo(ÜšÂVŠ:Õ !ª±n«bμú”?©ØB*žL¸ܶðÿUS3 tH
endstream
endobj
5 0 obj
110
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 150 150 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.16.0 (https://cairographics.org))
/CreationDate (D:20190922201819-07'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000514 00000 n
0000000296 00000 n
0000000224 00000 n
0000000015 00000 n
0000000202 00000 n
0000000579 00000 n
0000000695 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
747
%%EOF

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "EscapeIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "lock.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ShiftIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "TabIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "up_arrow.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,70 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœUŽQ
ƒ@ Dÿsй€1ÙÍF=†G(…êÇú¡½?-e`ƒÌ$
5Ö¼ZIqhоÓ—4qAî¨ó ÓsTdã¹dl>üØ<C3BC>H… {º‰n|KÏâé,Ë}°?‡ê5ôª™ÿ^øÐH;U$}
endstream
endobj
5 0 obj
114
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 75 75 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.16.0 (https://cairographics.org))
/CreationDate (D:20190830203401-07'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000516 00000 n
0000000300 00000 n
0000000228 00000 n
0000000015 00000 n
0000000206 00000 n
0000000581 00000 n
0000000697 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
749
%%EOF

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "WindowsIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,19 @@
//
// AbsoluteTouchHandler.h
// Moonlight
//
// Created by Cameron Gutman on 11/1/20.
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
//
#import "StreamView.h"
NS_ASSUME_NONNULL_BEGIN
@interface AbsoluteTouchHandler : UIResponder
-(id)initWithView:(StreamView*)view;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,120 @@
//
// AbsoluteTouchHandler.m
// Moonlight
//
// Created by Cameron Gutman on 11/1/20.
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
//
#import "AbsoluteTouchHandler.h"
#include <Limelight.h>
// How long the fingers must be stationary to start a right click
#define LONG_PRESS_ACTIVATION_DELAY 0.650f
// How far the finger can move before it cancels a right click
#define LONG_PRESS_ACTIVATION_DELTA 0.01f
// How long the double tap deadzone stays in effect between touch up and touch down
#define DOUBLE_TAP_DEAD_ZONE_DELAY 0.250f
// How far the finger can move before it can override the double tap deadzone
#define DOUBLE_TAP_DEAD_ZONE_DELTA 0.025f
@implementation AbsoluteTouchHandler {
StreamView* view;
NSTimer* longPressTimer;
UITouch* lastTouchDown;
CGPoint lastTouchDownLocation;
UITouch* lastTouchUp;
CGPoint lastTouchUpLocation;
}
- (id)initWithView:(StreamView*)view {
self = [self init];
self->view = view;
return self;
}
- (void)onLongPressStart:(NSTimer*)timer {
// Raise the left click and start a right click
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Ignore touch down events with more than one finger
if ([[event allTouches] count] > 1) {
return;
}
UITouch* touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:view];
// Don't reposition for finger down events within the deadzone. This makes double-clicking easier.
if (touch.timestamp - lastTouchUp.timestamp > DOUBLE_TAP_DEAD_ZONE_DELAY ||
sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchUpLocation.x / view.bounds.size.width), 2) +
pow((touchLocation.y / view.bounds.size.height) - (lastTouchUpLocation.y / view.bounds.size.height), 2)) > DOUBLE_TAP_DEAD_ZONE_DELTA) {
[view updateCursorLocation:touchLocation isMouse:NO];
}
// Press the left button down
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
// Start the long press timer
longPressTimer = [NSTimer scheduledTimerWithTimeInterval:LONG_PRESS_ACTIVATION_DELAY
target:self
selector:@selector(onLongPressStart:)
userInfo:nil
repeats:NO];
lastTouchDown = touch;
lastTouchDownLocation = touchLocation;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// Ignore touch move events with more than one finger
if ([[event allTouches] count] > 1) {
return;
}
UITouch* touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:view];
if (sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchDownLocation.x / view.bounds.size.width), 2) +
pow((touchLocation.y / view.bounds.size.height) - (lastTouchDownLocation.y / view.bounds.size.height), 2)) > LONG_PRESS_ACTIVATION_DELTA) {
// Moved too far since touch down. Cancel the long press timer.
[longPressTimer invalidate];
longPressTimer = nil;
}
[view updateCursorLocation:[[touches anyObject] locationInView:view] isMouse:NO];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Only fire this logic if all touches have ended
if ([[event allTouches] count] == [touches count]) {
// Cancel the long press timer
[longPressTimer invalidate];
longPressTimer = nil;
// Left button up on finger up
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
// Raise right button too in case we triggered a long press gesture
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
// Remember this last touch for touch-down deadzoning
lastTouchUp = [touches anyObject];
lastTouchUpLocation = [lastTouchUp locationInView:view];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
// Treat this as a normal touchesEnded event
[self touchesEnded:touches withEvent:event];
}
@end

View File

@ -6,21 +6,48 @@
// Copyright © 2019 Moonlight Game Streaming Project. All rights reserved.
//
#import "HapticContext.h"
@import GameController;
@import CoreHaptics;
@interface Controller : NSObject
typedef struct {
float lastX;
float lastY;
} controller_touch_context_t;
@property (nullable, nonatomic, retain) GCController* gamepad;
@property (nonatomic) int playerIndex;
@property (nonatomic) int lastButtonFlags;
@property (nonatomic) int emulatingButtonFlags;
@property (nonatomic) int supportedEmulationFlags;
@property (nonatomic) unsigned char lastLeftTrigger;
@property (nonatomic) unsigned char lastRightTrigger;
@property (nonatomic) short lastLeftStickX;
@property (nonatomic) short lastLeftStickY;
@property (nonatomic) short lastRightStickX;
@property (nonatomic) short lastRightStickY;
@property (nonatomic) unsigned short lowFreqMotor;
@property (nonatomic) unsigned short highFreqMotor;
@property (nonatomic) controller_touch_context_t primaryTouch;
@property (nonatomic) controller_touch_context_t secondaryTouch;
@property (nonatomic) HapticContext* _Nullable lowFreqMotor;
@property (nonatomic) HapticContext* _Nullable highFreqMotor;
@property (nonatomic) HapticContext* _Nullable leftTriggerMotor;
@property (nonatomic) HapticContext* _Nullable rightTriggerMotor;
@property (nonatomic) NSTimer* _Nullable accelTimer;
@property (nonatomic) GCAcceleration lastAccelSample;
@property (nonatomic) NSTimer* _Nullable gyroTimer;
@property (nonatomic) GCRotationRate lastGyroSample;
@property (nonatomic) NSTimer* _Nullable batteryTimer;
@property (nonatomic) GCDeviceBatteryState lastBatteryState;
@property (nonatomic) float lastBatteryLevel;
@property (nonatomic) BOOL reportedArrival;
@property (nonatomic) Controller* _Nullable mergedWithController;
@end

View File

@ -6,35 +6,34 @@
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
//
// Swift
#if !TARGET_OS_IPHONE
#import "Gamepad.h"
#endif
#import "StreamConfiguration.h"
#import "Controller.h"
@class OnScreenControls;
@protocol ControllerSupportDelegate <NSObject>
- (void) gamepadPresenceChanged;
- (void) mousePresenceChanged;
- (void) streamExitRequested;
@end
@interface ControllerSupport : NSObject
-(id) initWithConfig:(StreamConfiguration*)streamConfig;
-(id) initWithConfig:(StreamConfiguration*)streamConfig delegate:(id<ControllerSupportDelegate>)delegate;
-(void) connectionEstablished;
#if TARGET_OS_IPHONE
-(void) initAutoOnScreenControlMode:(OnScreenControls*)osc;
-(void) cleanup;
-(Controller*) getOscController;
#else
-(void) assignGamepad:(struct Gamepad_device *)gamepad;
-(void) removeGamepad:(struct Gamepad_device *)gamepad;
-(NSMutableDictionary*) getControllers;
#endif
-(void) updateLeftStick:(Controller*)controller x:(short)x y:(short)y;
-(void) updateRightStick:(Controller*)controller x:(short)x y:(short)y;
-(void) updateLeftTrigger:(Controller*)controller left:(char)left;
-(void) updateRightTrigger:(Controller*)controller right:(char)right;
-(void) updateTriggers:(Controller*)controller left:(char)left right:(char)right;
-(void) updateLeftTrigger:(Controller*)controller left:(unsigned char)left;
-(void) updateRightTrigger:(Controller*)controller right:(unsigned char)right;
-(void) updateTriggers:(Controller*)controller left:(unsigned char)left right:(unsigned char)right;
-(void) updateButtonFlags:(Controller*)controller flags:(int)flags;
-(void) setButtonFlag:(Controller*)controller flags:(int)flags;
@ -43,10 +42,12 @@
-(void) updateFinished:(Controller*)controller;
-(void) rumble:(unsigned short)controllerNumber lowFreqMotor:(unsigned short)lowFreqMotor highFreqMotor:(unsigned short)highFreqMotor;
-(void) rumbleTriggers:(uint16_t)controllerNumber leftTrigger:(uint16_t)leftTrigger rightTrigger:(uint16_t)rightTrigger;
-(void) setMotionEventState:(uint16_t)controllerNumber motionType:(uint8_t)motionType reportRateHz:(uint16_t)reportRateHz;
-(void) setControllerLed:(uint16_t)controllerNumber r:(uint8_t)r g:(uint8_t)g b:(uint8_t)b;
+(int) getConnectedGamepadMask:(StreamConfiguration*)streamConfig;
@property (nonatomic, strong) id connectObserver;
@property (nonatomic, strong) id disconnectObserver;
-(NSUInteger) getConnectedGamepadCount;
@end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
//
// HapticContext.h
// Moonlight
//
// Created by Cameron Gutman on 9/17/20.
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
//
@import CoreHaptics;
@import GameController;
@interface HapticContext : NSObject
-(void)setMotorAmplitude:(unsigned short)amplitude;
-(void)cleanup;
+(HapticContext*) createContextForHighFreqMotor:(GCController*)gamepad;
+(HapticContext*) createContextForLowFreqMotor:(GCController*)gamepad;
+(HapticContext*) createContextForLeftTrigger:(GCController*)gamepad;
+(HapticContext*) createContextForRightTrigger:(GCController*)gamepad;
@end

View File

@ -0,0 +1,170 @@
//
// HapticContext.m
// Moonlight
//
// Created by Cameron Gutman on 9/17/20.
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
//
#import "HapticContext.h"
@import CoreHaptics;
@import GameController;
@implementation HapticContext {
GCControllerPlayerIndex _playerIndex;
CHHapticEngine* _hapticEngine API_AVAILABLE(ios(13.0), tvos(14.0));
id<CHHapticPatternPlayer> _hapticPlayer API_AVAILABLE(ios(13.0), tvos(14.0));
BOOL _playing;
}
-(void)cleanup API_AVAILABLE(ios(14.0), tvos(14.0)) {
if (_hapticPlayer != nil) {
[_hapticPlayer cancelAndReturnError:nil];
_hapticPlayer = nil;
}
if (_hapticEngine != nil) {
[_hapticEngine stopWithCompletionHandler:nil];
_hapticEngine = nil;
}
}
-(void)setMotorAmplitude:(unsigned short)amplitude API_AVAILABLE(ios(14.0), tvos(14.0)) {
NSError* error;
// Check if the haptic engine died
if (_hapticEngine == nil) {
return;
}
// Stop the effect entirely if the amplitude is 0
if (amplitude == 0) {
if (_playing) {
[_hapticPlayer stopAtTime:0 error:&error];
_playing = NO;
}
return;
}
if (_hapticPlayer == nil) {
// We must initialize the intensity to 1.0f because the dynamic parameters are multiplied by this value before being applied
CHHapticEventParameter* intensityParameter = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f];
CHHapticEvent* hapticEvent = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObject:intensityParameter] relativeTime:0 duration:GCHapticDurationInfinite];
CHHapticPattern* hapticPattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:hapticEvent] parameters:[[NSArray alloc] init] error:&error];
if (error != nil) {
Log(LOG_W, @"Controller %d: Haptic pattern creation failed: %@", _playerIndex, error);
return;
}
_hapticPlayer = [_hapticEngine createPlayerWithPattern:hapticPattern error:&error];
if (error != nil) {
Log(LOG_W, @"Controller %d: Haptic player creation failed: %@", _playerIndex, error);
return;
}
}
CHHapticDynamicParameter* intensityParameter = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:amplitude / 65535.0f relativeTime:0];
[_hapticPlayer sendParameters:[NSArray arrayWithObject:intensityParameter] atTime:CHHapticTimeImmediate error:&error];
if (error != nil) {
Log(LOG_W, @"Controller %d: Haptic player parameter update failed: %@", _playerIndex, error);
return;
}
if (!_playing) {
[_hapticPlayer startAtTime:0 error:&error];
if (error != nil) {
_hapticPlayer = nil;
Log(LOG_W, @"Controller %d: Haptic playback start failed: %@", _playerIndex, error);
return;
}
_playing = YES;
}
}
-(id) initWithGamepad:(GCController*)gamepad locality:(GCHapticsLocality)locality API_AVAILABLE(ios(14.0), tvos(14.0)) {
if (gamepad.haptics == nil) {
Log(LOG_W, @"Controller %d does not support haptics", gamepad.playerIndex);
return nil;
}
if (![[gamepad.haptics supportedLocalities] containsObject:locality]) {
Log(LOG_W, @"Controller %d does not support haptic locality: %@", gamepad.playerIndex, locality);
return nil;
}
_playerIndex = gamepad.playerIndex;
_hapticEngine = [gamepad.haptics createEngineWithLocality:locality];
NSError* error;
[_hapticEngine startAndReturnError:&error];
if (error != nil) {
Log(LOG_W, @"Controller %d: Haptic engine failed to start: %@", gamepad.playerIndex, error);
return nil;
}
__weak typeof(self) weakSelf = self;
_hapticEngine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) {
HapticContext* me = weakSelf;
if (me == nil) {
return;
}
Log(LOG_W, @"Controller %d: Haptic engine stopped: %p", me->_playerIndex, stoppedReason);
me->_hapticPlayer = nil;
me->_hapticEngine = nil;
me->_playing = NO;
};
_hapticEngine.resetHandler = ^{
HapticContext* me = weakSelf;
if (me == nil) {
return;
}
Log(LOG_W, @"Controller %d: Haptic engine reset", me->_playerIndex);
me->_hapticPlayer = nil;
me->_playing = NO;
[me->_hapticEngine startAndReturnError:nil];
};
return self;
}
+(HapticContext*) createContextForHighFreqMotor:(GCController*)gamepad {
if (@available(iOS 14.0, tvOS 14.0, *)) {
return [[HapticContext alloc] initWithGamepad:gamepad locality:GCHapticsLocalityRightHandle];
}
else {
return nil;
}
}
+(HapticContext*) createContextForLowFreqMotor:(GCController*)gamepad {
if (@available(iOS 14.0, tvOS 14.0, *)) {
return [[HapticContext alloc] initWithGamepad:gamepad locality:GCHapticsLocalityLeftHandle];
}
else {
return nil;
}
}
+(HapticContext*) createContextForLeftTrigger:(GCController*)gamepad {
if (@available(iOS 14.0, tvOS 14.0, *)) {
return [[HapticContext alloc] initWithGamepad:gamepad locality:GCHapticsLocalityLeftTrigger];
}
else {
return nil;
}
}
+(HapticContext*) createContextForRightTrigger:(GCController*)gamepad {
if (@available(iOS 14.0, tvOS 14.0, *)) {
return [[HapticContext alloc] initWithGamepad:gamepad locality:GCHapticsLocalityRightTrigger];
}
else {
return nil;
}
}
@end

View File

@ -0,0 +1,18 @@
//
// KeyboardInputField.h
// Moonlight
//
// Created by Cameron Gutman on 12/2/22.
// Copyright © 2022 Moonlight Game Streaming Project. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface KeyboardInputField : UITextField
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,18 @@
//
// KeyboardInputField.m
// Moonlight
//
// Created by Cameron Gutman on 12/2/22.
// Copyright © 2022 Moonlight Game Streaming Project. All rights reserved.
//
#import "KeyboardInputField.h"
@implementation KeyboardInputField
- (UIEditingInteractionConfiguration) editingInteractionConfiguration {
// Suppress the Undo menu that appears with a 3 finger tap
return UIEditingInteractionConfigurationNone;
}
@end

View File

@ -16,6 +16,8 @@ struct KeyEvent {
u_char modifier;
};
+ (BOOL)sendKeyEventForPress:(UIPress*)press down:(BOOL)down API_AVAILABLE(ios(13.4));
+ (BOOL)sendKeyEvent:(UIKey*)key down:(BOOL)down API_AVAILABLE(ios(13.4));
+ (struct KeyEvent) translateKeyEvent:(unichar) inputChar withModifierFlags:(UIKeyModifierFlags)modifierFlags;
@end

View File

@ -11,6 +11,259 @@
@implementation KeyboardSupport
+ (BOOL)sendKeyEventForPress:(UIPress*)press down:(BOOL)down API_AVAILABLE(ios(13.4)) {
if (press.key != nil) {
return [KeyboardSupport sendKeyEvent:press.key down:down];
}
else {
short keyCode;
switch (press.type) {
case UIPressTypeUpArrow:
keyCode = 0x26;
break;
case UIPressTypeDownArrow:
keyCode = 0x28;
break;
case UIPressTypeLeftArrow:
keyCode = 0x25;
break;
case UIPressTypeRightArrow:
keyCode = 0x27;
break;
default:
// Unhandled press type
return NO;
}
LiSendKeyboardEvent(0x8000 | keyCode,
down ? KEY_ACTION_DOWN : KEY_ACTION_UP,
0);
return YES;
}
}
+ (BOOL)sendKeyEvent:(UIKey*)key down:(BOOL)down API_AVAILABLE(ios(13.4)) {
char modifierFlags = 0;
short keyCode = 0;
if (key.modifierFlags & UIKeyModifierShift) {
modifierFlags |= MODIFIER_SHIFT;
}
if (key.modifierFlags & UIKeyModifierAlternate) {
modifierFlags |= MODIFIER_ALT;
}
if (key.modifierFlags & UIKeyModifierControl) {
modifierFlags |= MODIFIER_CTRL;
}
if (key.modifierFlags & UIKeyModifierCommand) {
modifierFlags |= MODIFIER_META;
}
// This converts UIKeyboardHIDUsage values to Win32 VK_* values
// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
if (key.keyCode >= UIKeyboardHIDUsageKeyboardA &&
key.keyCode <= UIKeyboardHIDUsageKeyboardZ) {
keyCode = (key.keyCode - UIKeyboardHIDUsageKeyboardA) + 0x41;
}
else if (key.keyCode == UIKeyboardHIDUsageKeyboard0) {
// This key is at the beginning of the VK_ range but the end
// of the UIKeyboardHIDUsageKeyboard range.
keyCode = 0x30;
}
else if (key.keyCode >= UIKeyboardHIDUsageKeyboard1 &&
key.keyCode <= UIKeyboardHIDUsageKeyboard9) {
keyCode = (key.keyCode - UIKeyboardHIDUsageKeyboard1) + 0x31;
}
else if (key.keyCode == UIKeyboardHIDUsageKeypad0) {
// This key is at the beginning of the VK_ range but the end
// of the UIKeyboardHIDUsageKeypad range.
keyCode = 0x60;
}
else if (key.keyCode >= UIKeyboardHIDUsageKeypad1 &&
key.keyCode <= UIKeyboardHIDUsageKeypad9) {
keyCode = (key.keyCode - UIKeyboardHIDUsageKeypad1) + 0x61;
}
else if (key.keyCode >= UIKeyboardHIDUsageKeyboardF1 &&
key.keyCode <= UIKeyboardHIDUsageKeyboardF12) {
keyCode = (key.keyCode - UIKeyboardHIDUsageKeyboardF1) + 0x70;
}
else if (key.keyCode >= UIKeyboardHIDUsageKeyboardF13 &&
key.keyCode <= UIKeyboardHIDUsageKeyboardF24) {
keyCode = (key.keyCode - UIKeyboardHIDUsageKeyboardF13) + 0x7C;
}
else {
switch (key.keyCode) {
case UIKeyboardHIDUsageKeyboardReturnOrEnter:
keyCode = 0x0D;
break;
case UIKeyboardHIDUsageKeyboardEscape:
keyCode = 0x1B;
break;
case UIKeyboardHIDUsageKeyboardDeleteOrBackspace:
keyCode = 0x08;
break;
case UIKeyboardHIDUsageKeyboardTab:
keyCode = 0x09;
break;
case UIKeyboardHIDUsageKeyboardSpacebar:
keyCode = 0x20;
break;
case UIKeyboardHIDUsageKeyboardHyphen:
keyCode = 0xBD;
break;
case UIKeyboardHIDUsageKeyboardEqualSign:
keyCode = 0xBB;
break;
case UIKeyboardHIDUsageKeyboardOpenBracket:
keyCode = 0xDB;
break;
case UIKeyboardHIDUsageKeyboardCloseBracket:
keyCode = 0xDD;
break;
case UIKeyboardHIDUsageKeyboardBackslash:
keyCode = 0xDC;
break;
case UIKeyboardHIDUsageKeyboardSemicolon:
keyCode = 0xBA;
break;
case UIKeyboardHIDUsageKeyboardQuote:
keyCode = 0xDE;
break;
case UIKeyboardHIDUsageKeyboardGraveAccentAndTilde:
keyCode = 0xC0;
break;
case UIKeyboardHIDUsageKeyboardComma:
keyCode = 0xBC;
break;
case UIKeyboardHIDUsageKeyboardPeriod:
keyCode = 0xBE;
break;
case UIKeyboardHIDUsageKeyboardSlash:
keyCode = 0xBF;
break;
case UIKeyboardHIDUsageKeyboardCapsLock:
keyCode = 0x14;
break;
case UIKeyboardHIDUsageKeyboardPrintScreen:
keyCode = 0x2A;
break;
case UIKeyboardHIDUsageKeyboardScrollLock:
keyCode = 0x91;
break;
case UIKeyboardHIDUsageKeyboardPause:
keyCode = 0x13;
break;
case UIKeyboardHIDUsageKeyboardInsert:
keyCode = 0x2D;
break;
case UIKeyboardHIDUsageKeyboardHome:
keyCode = 0x24;
break;
case UIKeyboardHIDUsageKeyboardPageUp:
keyCode = 0x21;
break;
case UIKeyboardHIDUsageKeyboardDeleteForward:
keyCode = 0x2E;
break;
case UIKeyboardHIDUsageKeyboardEnd:
keyCode = 0x23;
break;
case UIKeyboardHIDUsageKeyboardPageDown:
keyCode = 0x22;
break;
case UIKeyboardHIDUsageKeyboardRightArrow:
keyCode = 0x27;
break;
case UIKeyboardHIDUsageKeyboardLeftArrow:
keyCode = 0x25;
break;
case UIKeyboardHIDUsageKeyboardDownArrow:
keyCode = 0x28;
break;
case UIKeyboardHIDUsageKeyboardUpArrow:
keyCode = 0x26;
break;
case UIKeyboardHIDUsageKeypadNumLock:
keyCode = 0x90;
break;
case UIKeyboardHIDUsageKeypadSlash:
keyCode = 0x6F;
break;
case UIKeyboardHIDUsageKeypadAsterisk:
keyCode = 0x6A;
break;
case UIKeyboardHIDUsageKeypadHyphen:
keyCode = 0x6D;
break;
case UIKeyboardHIDUsageKeypadPlus:
keyCode = 0x6B;
break;
case UIKeyboardHIDUsageKeypadEnter:
keyCode = 0x0D;
break;
case UIKeyboardHIDUsageKeypadPeriod:
keyCode = 0x6E;
break;
case UIKeyboardHIDUsageKeyboardNonUSBackslash:
keyCode = 0xE2;
break;
case UIKeyboardHIDUsageKeypadComma:
keyCode = 0x6C;
break;
case UIKeyboardHIDUsageKeyboardCancel:
keyCode = 0x03;
break;
case UIKeyboardHIDUsageKeyboardClear:
keyCode = 0x0C;
break;
case UIKeyboardHIDUsageKeyboardCrSelOrProps:
keyCode = 0xF7;
break;
case UIKeyboardHIDUsageKeyboardExSel:
keyCode = 0xF8;
break;
case UIKeyboardHIDUsageKeyboardLeftGUI:
keyCode = 0x5B;
break;
case UIKeyboardHIDUsageKeyboardLeftControl:
keyCode = 0xA2;
break;
case UIKeyboardHIDUsageKeyboardLeftShift:
keyCode = 0xA0;
break;
case UIKeyboardHIDUsageKeyboardLeftAlt:
keyCode = 0xA4;
break;
case UIKeyboardHIDUsageKeyboardRightGUI:
keyCode = 0x5C;
break;
case UIKeyboardHIDUsageKeyboardRightControl:
keyCode = 0xA3;
break;
case UIKeyboardHIDUsageKeyboardRightShift:
keyCode = 0xA1;
break;
case UIKeyboardHIDUsageKeyboardRightAlt:
keyCode = 0xA5;
break;
case 669: // This value corresponds to the "Globe" or "Language" key on most Apple branded iPad keyboards.
keyCode = 0x1B; // This value corresponds to "Escape", which is missing from most Apple branded iPad keyboards.
break;
default:
NSLog(@"Unhandled HID usage: %lu", (unsigned long)key.keyCode);
assert(0);
return false;
}
}
LiSendKeyboardEvent(0x8000 | keyCode,
down ? KEY_ACTION_DOWN : KEY_ACTION_UP,
modifierFlags);
return true;
}
+ (struct KeyEvent)translateKeyEvent:(unichar)inputChar withModifierFlags:(UIKeyModifierFlags)modifierFlags {
struct KeyEvent event;
event.keycode = 0;
@ -25,10 +278,12 @@
case UIKeyModifierControl:
[KeyboardSupport addControlModifier:&event];
break;
case UIKeyModifierCommand:
[KeyboardSupport addMetaModifier:&event];
break;
case UIKeyModifierAlternate:
[KeyboardSupport addAltModifier:&event];
break;
case UIKeyModifierCommand:
case UIKeyModifierNumericPad:
break;
}
@ -183,6 +438,11 @@
event->modifierKeycode = 0x11;
}
+ (void) addMetaModifier:(struct KeyEvent*)event {
event->modifier = MODIFIER_META;
event->modifierKeycode = 0x5B;
}
+ (void) addAltModifier:(struct KeyEvent*)event {
event->modifier = MODIFIER_ALT;
event->modifierKeycode = 0x12;

View File

@ -7,9 +7,9 @@
//
#import <Foundation/Foundation.h>
#import "StreamView.h"
@class ControllerSupport;
@class StreamConfiguration;
@interface OnScreenControls : NSObject
@ -25,12 +25,12 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) {
OnScreenControlsLevelAutoGCExtendedGamepadWithStickButtons
};
#if TARGET_OS_IPHONE
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)edgeDelegate;
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport streamConfig:(StreamConfiguration*)streamConfig;
- (BOOL) handleTouchDownEvent:(NSSet*)touches;
- (BOOL) handleTouchUpEvent:(NSSet*)touches;
- (BOOL) handleTouchMovedEvent:(NSSet*)touches;
- (void) setLevel:(OnScreenControlsLevel)level;
#endif
- (OnScreenControlsLevel) getLevel;
- (void) show;
@end

View File

@ -7,6 +7,7 @@
//
#import "OnScreenControls.h"
#import "StreamView.h"
#import "ControllerSupport.h"
#import "Controller.h"
#include "Limelight.h"
@ -35,7 +36,6 @@
CALayer* _l1Button;
CALayer* _l2Button;
CALayer* _l3Button;
CALayer* _edge;
UITouch* _aTouch;
UITouch* _bTouch;
@ -52,7 +52,6 @@
UITouch* _l1Touch;
UITouch* _l2Touch;
UITouch* _l3Touch;
UITouch* _edgeTouch;
NSDate* l3TouchStart;
NSDate* r3TouchStart;
@ -64,11 +63,12 @@
CGRect _controlArea;
UIView* _view;
OnScreenControlsLevel _level;
BOOL _visible;
ControllerSupport *_controllerSupport;
Controller *_controller;
id<EdgeDetectionDelegate> _edgeDelegate;
NSMutableArray* _deadTouches;
BOOL _swapABXY;
}
static const float EDGE_WIDTH = .05;
@ -112,15 +112,15 @@ static float L2_Y;
static float L3_X;
static float L3_Y;
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate {
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport streamConfig:(StreamConfiguration*)streamConfig {
self = [self init];
_view = view;
_controllerSupport = controllerSupport;
_controller = [controllerSupport getOscController];
_edgeDelegate = swipeDelegate;
_deadTouches = [[NSMutableArray alloc] init];
_swapABXY = streamConfig.swapABXYButtons;
_iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
_iPad = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
_controlArea = CGRectMake(0, 0, _view.frame.size.width, _view.frame.size.height);
if (_iPad)
{
@ -154,16 +154,28 @@ static float L3_Y;
_rightStickBackground = [CALayer layer];
_leftStick = [CALayer layer];
_rightStick = [CALayer layer];
_edge = [CALayer layer];
[self setupEdgeDetection];
return self;
}
- (void) show {
_visible = YES;
[self updateControls];
}
- (void) setLevel:(OnScreenControlsLevel)level {
_level = level;
[self updateControls];
// Only update controls if we're showing, otherwise
// show will do it for us.
if (_visible) {
[self updateControls];
}
}
- (OnScreenControlsLevel) getLevel {
return _level;
}
- (void) updateControls {
@ -237,11 +249,6 @@ static float L3_Y;
}
}
- (void) setupEdgeDetection {
_edge.frame = CGRectMake(0, 0, _view.frame.size.width * EDGE_WIDTH, _view.frame.size.height);
[_view.layer addSublayer:_edge];
}
// For GCExtendedGamepad controls we move start, select, L3, and R3 to the button
- (void) setupExtendedGamepadControls {
// Start with the default complex layout
@ -367,27 +374,33 @@ static float L3_Y;
}
- (void) drawButtons {
// create A button
UIImage* aButtonImage = [UIImage imageNamed:@"AButton"];
UIImage* bButtonImage = [UIImage imageNamed:@"BButton"];
UIImage* xButtonImage = [UIImage imageNamed:@"XButton"];
UIImage* yButtonImage = [UIImage imageNamed:@"YButton"];
CGRect aButtonFrame = CGRectMake(BUTTON_CENTER_X - aButtonImage.size.width / 2, BUTTON_CENTER_Y + BUTTON_DIST, aButtonImage.size.width, aButtonImage.size.height);
CGRect bButtonFrame = CGRectMake(BUTTON_CENTER_X + BUTTON_DIST, BUTTON_CENTER_Y - bButtonImage.size.height / 2, bButtonImage.size.width, bButtonImage.size.height);
CGRect xButtonFrame = CGRectMake(BUTTON_CENTER_X - BUTTON_DIST - xButtonImage.size.width, BUTTON_CENTER_Y - xButtonImage.size.height/ 2, xButtonImage.size.width, xButtonImage.size.height);
CGRect yButtonFrame = CGRectMake(BUTTON_CENTER_X - yButtonImage.size.width / 2, BUTTON_CENTER_Y - BUTTON_DIST - yButtonImage.size.height, yButtonImage.size.width, yButtonImage.size.height);
// create A button
_aButton.contents = (id) aButtonImage.CGImage;
_aButton.frame = CGRectMake(BUTTON_CENTER_X - aButtonImage.size.width / 2, BUTTON_CENTER_Y + BUTTON_DIST, aButtonImage.size.width, aButtonImage.size.height);
_aButton.frame = _swapABXY ? bButtonFrame : aButtonFrame;
[_view.layer addSublayer:_aButton];
// create B button
UIImage* bButtonImage = [UIImage imageNamed:@"BButton"];
_bButton.frame = CGRectMake(BUTTON_CENTER_X + BUTTON_DIST, BUTTON_CENTER_Y - bButtonImage.size.height / 2, bButtonImage.size.width, bButtonImage.size.height);
_bButton.frame = _swapABXY ? aButtonFrame : bButtonFrame;
_bButton.contents = (id) bButtonImage.CGImage;
[_view.layer addSublayer:_bButton];
// create X Button
UIImage* xButtonImage = [UIImage imageNamed:@"XButton"];
_xButton.frame = CGRectMake(BUTTON_CENTER_X - BUTTON_DIST - xButtonImage.size.width, BUTTON_CENTER_Y - xButtonImage.size.height/ 2, xButtonImage.size.width, xButtonImage.size.height);
_xButton.frame = _swapABXY ? yButtonFrame : xButtonFrame;
_xButton.contents = (id) xButtonImage.CGImage;
[_view.layer addSublayer:_xButton];
// create Y Button
UIImage* yButtonImage = [UIImage imageNamed:@"YButton"];
_yButton.frame = CGRectMake(BUTTON_CENTER_X - yButtonImage.size.width / 2, BUTTON_CENTER_Y - BUTTON_DIST - yButtonImage.size.height, yButtonImage.size.width, yButtonImage.size.height);
_yButton.frame = _swapABXY ? xButtonFrame : yButtonFrame;
_yButton.contents = (id) yButtonImage.CGImage;
[_view.layer addSublayer:_yButton];
@ -641,7 +654,7 @@ static float L3_Y;
if (updated) {
[_controllerSupport updateFinished:_controller];
}
return updated || buttonTouch;
return updated || buttonTouch;
}
- (BOOL)handleTouchDownEvent:touches {
@ -650,63 +663,63 @@ static float L3_Y;
for (UITouch* touch in touches) {
CGPoint touchLocation = [touch locationInView:_view];
if ([_aButton.presentationLayer hitTest:touchLocation]) {
if (_aButton.superlayer != nil && [_aButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:A_FLAG];
_aTouch = touch;
updated = true;
} else if ([_bButton.presentationLayer hitTest:touchLocation]) {
} else if (_bButton.superlayer != nil && [_bButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:B_FLAG];
_bTouch = touch;
updated = true;
} else if ([_xButton.presentationLayer hitTest:touchLocation]) {
} else if (_xButton.superlayer != nil && [_xButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:X_FLAG];
_xTouch = touch;
updated = true;
} else if ([_yButton.presentationLayer hitTest:touchLocation]) {
} else if (_yButton.superlayer != nil && [_yButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:Y_FLAG];
_yTouch = touch;
updated = true;
} else if ([_upButton.presentationLayer hitTest:touchLocation]) {
} else if (_upButton.superlayer != nil && [_upButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:UP_FLAG];
_dpadTouch = touch;
updated = true;
} else if ([_downButton.presentationLayer hitTest:touchLocation]) {
} else if (_downButton.superlayer != nil && [_downButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:DOWN_FLAG];
_dpadTouch = touch;
updated = true;
} else if ([_leftButton.presentationLayer hitTest:touchLocation]) {
} else if (_leftButton.superlayer != nil && [_leftButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:LEFT_FLAG];
_dpadTouch = touch;
updated = true;
} else if ([_rightButton.presentationLayer hitTest:touchLocation]) {
} else if (_rightButton.superlayer != nil && [_rightButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:RIGHT_FLAG];
_dpadTouch = touch;
updated = true;
} else if ([_startButton.presentationLayer hitTest:touchLocation]) {
} else if (_startButton.superlayer != nil && [_startButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:PLAY_FLAG];
_startTouch = touch;
updated = true;
} else if ([_selectButton.presentationLayer hitTest:touchLocation]) {
} else if (_selectButton.superlayer != nil && [_selectButton.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:BACK_FLAG];
_selectTouch = touch;
updated = true;
} else if ([_l1Button.presentationLayer hitTest:touchLocation]) {
} else if (_l1Button.superlayer != nil && [_l1Button.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:LB_FLAG];
_l1Touch = touch;
updated = true;
} else if ([_r1Button.presentationLayer hitTest:touchLocation]) {
} else if (_r1Button.superlayer != nil && [_r1Button.presentationLayer hitTest:touchLocation]) {
[_controllerSupport setButtonFlag:_controller flags:RB_FLAG];
_r1Touch = touch;
updated = true;
} else if ([_l2Button.presentationLayer hitTest:touchLocation]) {
} else if (_l2Button.superlayer != nil && [_l2Button.presentationLayer hitTest:touchLocation]) {
[_controllerSupport updateLeftTrigger:_controller left:0xFF];
_l2Touch = touch;
updated = true;
} else if ([_r2Button.presentationLayer hitTest:touchLocation]) {
} else if (_r2Button.superlayer != nil && [_r2Button.presentationLayer hitTest:touchLocation]) {
[_controllerSupport updateRightTrigger:_controller right:0xFF];
_r2Touch = touch;
updated = true;
} else if ([_l3Button.presentationLayer hitTest:touchLocation]) {
} else if (_l3Button.superlayer != nil && [_l3Button.presentationLayer hitTest:touchLocation]) {
if (l3Set) {
[_controllerSupport clearButtonFlag:_controller flags:LS_CLK_FLAG];
_l3Button.borderWidth = 0.0f;
@ -717,7 +730,7 @@ static float L3_Y;
l3Set = !l3Set;
_l3Touch = touch;
updated = true;
} else if ([_r3Button.presentationLayer hitTest:touchLocation]) {
} else if (_r3Button.superlayer != nil && [_r3Button.presentationLayer hitTest:touchLocation]) {
if (r3Set) {
[_controllerSupport clearButtonFlag:_controller flags:RS_CLK_FLAG];
_r3Button.borderWidth = 0.0f;
@ -728,7 +741,7 @@ static float L3_Y;
r3Set = !r3Set;
_r3Touch = touch;
updated = true;
} else if ([_leftStick.presentationLayer hitTest:touchLocation]) {
} else if (_leftStick.superlayer != nil && [_leftStick.presentationLayer hitTest:touchLocation]) {
if (l3TouchStart != nil) {
// Find elapsed time and convert to milliseconds
// Use (-) modifier to conversion since receiver is earlier than now
@ -740,7 +753,7 @@ static float L3_Y;
}
_lsTouch = touch;
stickTouch = true;
} else if ([_rightStick.presentationLayer hitTest:touchLocation]) {
} else if (_rightStick.superlayer != nil && [_rightStick.presentationLayer hitTest:touchLocation]) {
if (r3TouchStart != nil) {
// Find elapsed time and convert to milliseconds
// Use (-) modifier to conversion since receiver is earlier than now
@ -752,8 +765,6 @@ static float L3_Y;
}
_rsTouch = touch;
stickTouch = true;
} else if ([_edge.presentationLayer hitTest:touchLocation]) {
_edgeTouch = touch;
}
if (!updated && !stickTouch && [self isInDeadZone:touch]) {
[_deadTouches addObject:touch];
@ -837,11 +848,6 @@ static float L3_Y;
else if (touch == _r3Touch) {
_r3Touch = nil;
touched = true;
} else if (touch == _edgeTouch) {
_edgeTouch = nil;
if ([touch locationInView:_view].x >= _view.frame.size.width / 4) {
[_edgeDelegate edgeSwiped];
}
}
if ([_deadTouches containsObject:touch]) {
[_deadTouches removeObject:touch];

View File

@ -0,0 +1,19 @@
//
// RelativeTouchHandler.h
// Moonlight
//
// Created by Cameron Gutman on 11/1/20.
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
//
#import "StreamView.h"
NS_ASSUME_NONNULL_BEGIN
@interface RelativeTouchHandler : UIResponder
-(id)initWithView:(StreamView*)view;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,207 @@
//
// RelativeTouchHandler.m
// Moonlight
//
// Created by Cameron Gutman on 11/1/20.
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
//
#import "RelativeTouchHandler.h"
#include <Limelight.h>
static const int REFERENCE_WIDTH = 1280;
static const int REFERENCE_HEIGHT = 720;
@implementation RelativeTouchHandler {
CGPoint touchLocation, originalLocation;
BOOL touchMoved;
BOOL isDragging;
NSTimer* dragTimer;
NSUInteger peakTouchCount;
#if TARGET_OS_TV
UIGestureRecognizer* remotePressRecognizer;
UIGestureRecognizer* remoteLongPressRecognizer;
#endif
UIView* view;
}
- (id)initWithView:(StreamView*)view {
self = [self init];
self->view = view;
#if TARGET_OS_TV
remotePressRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(remoteButtonPressed:)];
remotePressRecognizer.allowedPressTypes = @[@(UIPressTypeSelect)];
remoteLongPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(remoteButtonLongPressed:)];
remoteLongPressRecognizer.allowedPressTypes = @[@(UIPressTypeSelect)];
[self->view addGestureRecognizer:remotePressRecognizer];
[self->view addGestureRecognizer:remoteLongPressRecognizer];
#endif
return self;
}
- (BOOL)isConfirmedMove:(CGPoint)currentPoint from:(CGPoint)originalPoint {
// Movements of greater than 5 pixels are considered confirmed
return hypotf(originalPoint.x - currentPoint.x, originalPoint.y - currentPoint.y) >= 5;
}
- (void)onDragStart:(NSTimer*)timer {
if (!touchMoved && !isDragging){
isDragging = true;
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
touchMoved = false;
peakTouchCount = [[event allTouches] count];
if ([[event allTouches] count] == 1) {
UITouch *touch = [[event allTouches] anyObject];
originalLocation = touchLocation = [touch locationInView:view];
if (!isDragging) {
dragTimer = [NSTimer scheduledTimerWithTimeInterval:0.650
target:self
selector:@selector(onDragStart:)
userInfo:nil
repeats:NO];
}
}
else if ([[event allTouches] count] == 2) {
CGPoint firstLocation = [[[[event allTouches] allObjects] objectAtIndex:0] locationInView:view];
CGPoint secondLocation = [[[[event allTouches] allObjects] objectAtIndex:1] locationInView:view];
originalLocation = touchLocation = CGPointMake((firstLocation.x + secondLocation.x) / 2, (firstLocation.y + secondLocation.y) / 2);
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if ([[event allTouches] count] == 1) {
UITouch *touch = [[event allTouches] anyObject];
CGPoint currentLocation = [touch locationInView:view];
if (touchLocation.x != currentLocation.x ||
touchLocation.y != currentLocation.y)
{
int deltaX = (currentLocation.x - touchLocation.x) * (REFERENCE_WIDTH / view.bounds.size.width);
int deltaY = (currentLocation.y - touchLocation.y) * (REFERENCE_HEIGHT / view.bounds.size.height);
if (deltaX != 0 || deltaY != 0) {
LiSendMouseMoveEvent(deltaX, deltaY);
touchLocation = currentLocation;
// If we've moved far enough to confirm this wasn't just human/machine error,
// mark it as such.
if ([self isConfirmedMove:touchLocation from:originalLocation]) {
touchMoved = true;
}
}
}
} else if ([[event allTouches] count] == 2) {
CGPoint firstLocation = [[[[event allTouches] allObjects] objectAtIndex:0] locationInView:view];
CGPoint secondLocation = [[[[event allTouches] allObjects] objectAtIndex:1] locationInView:view];
CGPoint avgLocation = CGPointMake((firstLocation.x + secondLocation.x) / 2, (firstLocation.y + secondLocation.y) / 2);
if (touchLocation.y != avgLocation.y) {
LiSendHighResScrollEvent((avgLocation.y - touchLocation.y) * 10);
}
// If we've moved far enough to confirm this wasn't just human/machine error,
// mark it as such.
if ([self isConfirmedMove:firstLocation from:originalLocation]) {
touchMoved = true;
}
touchLocation = avgLocation;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[dragTimer invalidate];
dragTimer = nil;
if (isDragging) {
isDragging = false;
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
} else if (!touchMoved) {
if (peakTouchCount == 2) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
Log(LOG_D, @"Sending right mouse button press");
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
// Wait 100 ms to simulate a real button press
usleep(100 * 1000);
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
});
} else if (peakTouchCount == 1) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
if (!self->isDragging){
Log(LOG_D, @"Sending left mouse button press");
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
// Wait 100 ms to simulate a real button press
usleep(100 * 1000);
}
self->isDragging = false;
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
});
}
}
// We we're moving from 2+ touches to 1. Synchronize the current position
// of the active finger so we don't jump unexpectedly on the next touchesMoved
// callback when finger 1 switches on us.
if ([[event allTouches] count] - [touches count] == 1) {
NSMutableSet *activeSet = [[NSMutableSet alloc] initWithCapacity:[[event allTouches] count]];
[activeSet unionSet:[event allTouches]];
[activeSet minusSet:touches];
touchLocation = [[activeSet anyObject] locationInView:view];
// Mark this touch as moved so we don't send a left mouse click if the user
// right clicks without moving their other finger.
touchMoved = true;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[dragTimer invalidate];
dragTimer = nil;
if (isDragging) {
isDragging = false;
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
}
peakTouchCount = 0;
}
#if TARGET_OS_TV
- (void)remoteButtonPressed:(id)sender {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
Log(LOG_D, @"Sending left mouse button press");
// Mark this as touchMoved to avoid a duplicate press on touch up
self->touchMoved = true;
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
// Wait 100 ms to simulate a real button press
usleep(100 * 1000);
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
});
}
- (void)remoteButtonLongPressed:(id)sender {
Log(LOG_D, @"Holding left mouse button");
isDragging = true;
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
}
#endif
@end

View File

@ -7,18 +7,31 @@
//
#import "ControllerSupport.h"
#import "OnScreenControls.h"
#import "Moonlight-Swift.h"
#import "StreamConfiguration.h"
@protocol EdgeDetectionDelegate <NSObject>
@protocol UserInteractionDelegate <NSObject>
- (void) edgeSwiped;
- (void) userInteractionBegan;
- (void) userInteractionEnded;
@end
@interface StreamView : OSView <UITextFieldDelegate>
#if TARGET_OS_TV
@interface StreamView : UIView <X1KitMouseDelegate, UITextFieldDelegate>
#else
@interface StreamView : UIView <X1KitMouseDelegate, UITextFieldDelegate, UIPointerInteractionDelegate>
#endif
@property (nonatomic, retain) IBOutlet UITextField* keyInputField;
- (void) setupStreamView:(ControllerSupport*)controllerSupport
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
config:(StreamConfiguration*)streamConfig;
- (void) showOnScreenControls;
- (OnScreenControlsLevel) getCurrentOscState;
- (void) setupOnScreenControls:(ControllerSupport*)controllerSupport swipeDelegate:(id<EdgeDetectionDelegate>)swipeDelegate;
- (void) setMouseDeltaFactors:(float)x y:(float)y;
#if !TARGET_OS_TV
- (void) updateCursorLocation:(CGPoint)location isMouse:(BOOL)isMouse;
#endif
@end

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@
<dict>
<key>CADisableMinimumFrameDuration</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
@ -19,24 +21,22 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.6.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>GCSupportedGameControllers</key>
<array>
<dict>
<key>ProfileName</key>
<string>ExtendedGamepad</string>
</dict>
<dict>
<key>ProfileName</key>
<string>Gamepad</string>
</dict>
</array>
<key>GCSupportsControllerUserInteraction</key>
<true/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>LSRequiresIPhoneOS</key>
@ -46,6 +46,18 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Bluetooth access allows Moonlight to connect to Citrix X1 mice.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Bluetooth access allows Moonlight to connect to Citrix X1 mice.</string>
<key>NSBonjourServices</key>
<array>
<string>_nvstream._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>Moonlight uses the local network to connect to your gaming PC for streaming.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>Launch Screen</string>
<key>UIMainStoryboardFile</key>

View File

@ -21,5 +21,4 @@
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "Logger.h"
#include "OSPortabilityDefs.h"
#endif

View File

@ -3,6 +3,6 @@
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>Moonlight v1.3.xcdatamodel</string>
<string>Moonlight v1.10.xcdatamodel</string>
</dict>
</plist>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22225" systemVersion="23A344" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="id" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
</entity>
<entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class">
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="ipv6Address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="serverCert" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="serverCodecModeSupport" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
</entity>
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
<attribute name="absoluteTouchMode" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="audioConfig" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="deviceGyroMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="preferredCodec" attributeType="Integer 32" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
</model>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14490.99" systemVersion="18F132" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="id" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
</entity>
<entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class">
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="ipv6Address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="serverCert" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="serverCodecModeSupport" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
</entity>
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="streamingRemotely" attributeType="Boolean" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="105"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="225"/>
</elements>
</model>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19E266" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="id" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
</entity>
<entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class">
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="ipv6Address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="serverCert" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="serverCodecModeSupport" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
</entity>
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="streamingRemotely" attributeType="Boolean" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="105"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="238"/>
</elements>
</model>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17192" systemVersion="19H2" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="id" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
</entity>
<entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class">
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="ipv6Address" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="serverCert" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="serverCodecModeSupport" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
</entity>
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
<attribute name="absoluteTouchMode" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="118"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="268"/>
</elements>
</model>

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