262 Commits
v0.7 ... master

Author SHA1 Message Date
Cameron Gutman
1371ccc766 Version 0.10.27 2024-02-12 21:57:36 -06:00
Cameron Gutman
2e3643235f Update moonlight-common-c for full encryption support 2024-02-12 21:43:45 -06:00
Cameron Gutman
56a746b1ae Update README.md 2023-11-03 00:09:04 -05:00
Cameron Gutman
086d4d1152 Add deprecation notice 2023-11-03 00:08:34 -05:00
Cameron Gutman
85c112a978 Version 0.10.26 2023-11-02 23:57:45 -05:00
Cameron Gutman
81b3b2c2b4 Update moonlight-common-c with multi-homed host fix 2023-11-02 23:49:01 -05:00
Cameron Gutman
12d325ec2f Version 0.10.25 2023-10-19 00:35:20 -05:00
Cameron Gutman
300eef544c Update moonlight-common-c to pick up input batching and reliability fixes 2023-10-19 00:34:48 -05:00
Cameron Gutman
9f918ad0da Version 0.10.24 2023-10-10 18:31:45 -05:00
Cameron Gutman
c7134a48db Use int for buttonFlags 2023-10-10 18:31:18 -05:00
Cameron Gutman
b06b146824 Update moonlight-common-c 2023-10-10 18:18:56 -05:00
Cameron Gutman
4061330467 Version 0.10.23 2023-10-07 19:37:36 -05:00
Cameron Gutman
1f79d70b00 Update moonlight-common-c 2023-10-07 19:34:58 -05:00
Cameron Gutman
2427d4cef5 Fix normalization of touch coordinates 2023-09-17 15:56:50 -05:00
Cameron Gutman
f8bfbb5b7c Sync ca-bundle.crt 2023-09-16 02:22:38 -05:00
Cameron Gutman
9045844d00 Update Opus to v1.4 2023-09-16 01:57:56 -05:00
Cameron Gutman
babba295a9 Add native touch support 2023-09-16 01:57:56 -05:00
Cameron Gutman
dbe0a54469 Update moonlight-common-c 2023-09-16 01:57:56 -05:00
Cameron Gutman
6a4caeacac Try to fix AppVeyor CI 2023-09-16 01:50:29 -05:00
Cameron Gutman
72f4ee829f Update README.md 2023-09-03 18:05:50 -05:00
Cameron Gutman
61176368bb Add release build script 2022-11-06 22:10:50 -06:00
Cameron Gutman
f4eca63944 Fix garbled audio playing at the start of each stream after the first one 2022-11-06 21:44:33 -06:00
Cameron Gutman
13c22ea16f Fix last frame from previous session displaying when starting a new one 2022-11-06 21:42:58 -06:00
Cameron Gutman
11de8f49ff Fix mouse position glitches near the edges in absolute mode 2022-11-06 21:23:36 -06:00
Cameron Gutman
0eeaec548e Fix mysterious Y offset in input coordinates 2022-11-06 21:18:35 -06:00
Cameron Gutman
a191915b9d Improvements to haptic error handling
- Move gamepad index check to the JS side to simplify the code
- Handle gamepads that don't support haptics
2022-11-06 20:23:24 -06:00
utopiafallen
ce52398dc5 Validate controllers when handling rumble events from GameStream
Rumble events may be received for controllers that are no longer present or attached
so they should be dropped instead of being forwarded to JS for handling.
2022-11-06 19:58:35 -06:00
utopiafallen
dccd8ec7ef Fix black screen when starting game stream
Adding fullscreen class to the #listener seems to fix the game stream
getting stuck in a black screen. I suspect that #main-content isn't
recomputing its layout when #listener is resized.
2022-11-06 19:58:35 -06:00
utopiafallen
b55f604294 Restore overrideEscFullscreen permission
Otherwise, Esc breaks out of fullscreen instead of being sent to the streaming app.
2022-11-06 19:58:35 -06:00
utopiafallen
eb458c1ad2 Remove explicit fullscreen handling
Moonlight's fullscreen requests generally conflict with
what ChromeOS is trying to do automatically for the app, especially when
using tablet mode. Just remove it for now and let the OS handle
fullscreen.
2022-11-06 19:58:35 -06:00
bob
aaa1ca7079 Added controller rumble support.
Pepper SDK and NaCl in general is EOL for Chrome, although still supported for Chrome Apps.
This means that the Pepper Gamepad API was never updated with rumble support so in order
to add rumble support, rumble messages from Gamestream have to be forwarded to JavaScript
and handled with gamepad.vibrationActuator.playEffect().

Side note, Chrome limits the duration of playEffect to 5 seconds and requesting more than
that causes the vibration request to be rejected.
2022-11-06 19:58:35 -06:00
Cameron Gutman
ab3aac8d05 Update moonlight-common-c 2022-11-06 19:45:34 -06:00
Cameron Gutman
6c47627f85 Fix typo in error path 2022-10-31 18:15:36 -05:00
Cameron Gutman
07f9e7e576 Update moonlight-common-c 2022-10-31 18:15:23 -05:00
Cameron Gutman
f16299ebcc Fix passing GFE version to LiStartConnection() 2022-10-31 18:00:04 -05:00
Cameron Gutman
b2bee37fe2 Plumb RTSP session URL into LiStartConnection() 2022-10-31 17:54:09 -05:00
Cameron Gutman
fb2258fa34 Plumb moonlight-common-c log messages into the console 2022-10-31 17:34:01 -05:00
Cameron Gutman
56d9e75d2b Use the new LiRequestIdrFrame() API 2022-10-05 01:01:22 -05:00
Cameron Gutman
7ae0e0dd48 Version 0.10.21 2022-09-23 00:00:00 -05:00
Cameron Gutman
578ff79a88 Fix large frame header size for GFE 3.26 2022-09-22 23:59:32 -05:00
Cameron Gutman
ec90adfb42 Version 0.10.20 2022-09-11 23:58:45 -05:00
Cameron Gutman
22dd617d87 Fix mishandling of IDR frames with a SEI or AUD NAL 2022-09-11 23:58:08 -05:00
Cameron Gutman
74d97a04c2 Version 0.10.19 2022-09-05 19:12:07 -05:00
Cameron Gutman
f91787793e Fix handling of 3 byte Annex B start sequences 2022-09-05 19:10:44 -05:00
Cameron Gutman
661edf2466 Version 0.10.18 2022-07-04 18:31:17 -05:00
tomciaaa
765e104cb3 Make mouse locking optional (#518)
Co-authored-by: tomciaaa <tomciaaa@chromebook>
2022-07-04 18:30:08 -05:00
Cameron Gutman
6b053e4e71 Update README.md 2022-04-05 19:53:17 -05:00
Cameron Gutman
29a5663980 Version 0.10.17 2021-12-12 16:58:12 -06:00
Cameron Gutman
1bba410f69 Update moonlight-common-c to fix excessive scroll speed on newer GFE versions 2021-12-12 16:54:07 -06:00
Cameron Gutman
751c2f8d2e Version 0.10.16 2021-06-20 16:50:54 -05:00
Cameron Gutman
f0585f6c06 Update moonlight-common-c for audio fixes on old GFE versions 2021-06-20 16:50:18 -05:00
Cameron Gutman
97eb58d8b5 Version 0.10.15 2021-06-13 11:02:24 -05:00
Cameron Gutman
471c3d3259 Update moonlight-common-c with audio FEC fixes and optimizations 2021-06-13 11:01:19 -05:00
Cameron Gutman
584f9475e2 Version 0.10.14 2021-06-04 18:44:04 -05:00
Cameron Gutman
ccc1dfb426 Update moonlight-common-c with audio FEC support 2021-06-03 21:26:25 -05:00
Cameron Gutman
21876c6b8d Version 0.10.13 2021-05-16 20:52:09 -05:00
Cameron Gutman
19ef75e170 Update moonlight-common-c with streaming optimizations 2021-05-16 20:51:42 -05:00
Cameron Gutman
e20749927b Version 0.11.12 2021-04-29 18:18:43 -05:00
Cameron Gutman
f212c6e8ad Update moonlight-common-c with RTSP handshake retry logic 2021-04-29 18:18:17 -05:00
Cameron Gutman
fb31cb6bb5 Version 0.10.11 2021-04-27 18:23:38 -05:00
Cameron Gutman
72624335f1 Update moonlight-common-c with multi-FEC support 2021-04-27 18:23:03 -05:00
Cameron Gutman
09b10d81e8 Version 0.10.10 2021-04-23 19:43:59 -05:00
Cameron Gutman
04fbabc0f2 Enable audio encryption 2021-04-23 19:43:37 -05:00
Cameron Gutman
7f11ab3d84 Update moonlight-common-c 2021-04-18 19:17:07 -05:00
Cameron Gutman
000dc49ad9 Add AppVeyor badge and link to readme 2021-04-17 12:15:48 -05:00
Cameron Gutman
5d59723df8 Add AppVeyor CI 2021-04-17 12:09:50 -05:00
Cameron Gutman
abb977970c Version 0.10.9 2021-04-09 19:50:04 -05:00
Cameron Gutman
7da5e83864 Update moonlight-common-c with initial GFE 3.22 compatibility 2021-04-09 19:49:52 -05:00
Cameron Gutman
aa9b7652d9 Version 0.10.8 2021-01-09 20:09:41 -06:00
Cameron Gutman
6221f62c12 Update moonlight-common-c 2021-01-09 20:09:06 -06:00
Cameron Gutman
31f35b16fa Version 0.10.7 2020-10-28 21:38:22 -05:00
Cameron Gutman
569f670f9d Update moonlight-common-c with QoS fix 2020-10-28 21:28:38 -05:00
Cameron Gutman
f17dd82b09 Version 0.10.6 2020-09-06 17:15:44 -07:00
Cameron Gutman
0c3b45d7c2 Update moonlight-common-c to improve connection reliability 2020-09-06 17:15:12 -07:00
Cameron Gutman
f4d9265712 Add warning if no key frames can be received in 10 seconds 2020-08-29 21:15:05 -07:00
Cameron Gutman
e3274893b6 Version 0.10.5 2020-08-09 17:40:41 -07:00
Cameron Gutman
747f8b7f55 Update common-c to fix server log spam 2020-08-09 17:34:39 -07:00
Cameron Gutman
417950d7da Update common-c with client connectivity test and select() replacement 2020-07-27 00:08:58 -07:00
Cameron Gutman
f5788296ac Use getRandomValues() for PIN, key, and IV 2020-07-12 12:11:17 -07:00
Cameron Gutman
e83c9ccd10 Version 0.10.4 2020-07-11 15:43:04 -07:00
Cameron Gutman
232e3c57f3 Add a CA bundle for CURL 2020-07-11 15:40:50 -07:00
Cameron Gutman
fbc1e83ebe Reduce logging spam from CURL 2020-07-11 13:00:02 -07:00
Cameron Gutman
be7b87797b Fix validation of non-pinned trusted TLS certificates 2020-07-11 12:52:53 -07:00
Cameron Gutman
9255884af4 Update moonlight-common-c to fix QoS-related connection issues 2020-06-12 22:12:15 -07:00
Cameron Gutman
22e0d2f171 Update README 2020-05-27 19:58:32 -07:00
Cameron Gutman
cf9c112995 Version 0.10.3 2020-05-26 20:48:53 -07:00
Cameron Gutman
7acc19bd3e Update moonlight-common-c 2020-05-26 20:48:33 -07:00
Cameron Gutman
643cc6d128 Version 0.10.2 2020-05-01 21:35:22 -07:00
Cameron Gutman
8a962927ed Add a friendly error message when no video traffic is received 2020-05-01 21:34:25 -07:00
Cameron Gutman
7174ad265d Chrome -> ChromeOS 2020-04-30 21:20:15 -07:00
Cameron Gutman
2a34e15858 Version 0.10.1 2020-04-25 16:19:02 -07:00
Cameron Gutman
733d27ed9e Add special error text for the -1 launch error code 2020-04-25 16:16:52 -07:00
Cameron Gutman
227e1d7c62 Version 0.10.0 2020-04-22 19:48:10 -07:00
Cameron Gutman
66b435d9f9 Add a small touch deadzone for double clicking 2020-04-22 19:44:46 -07:00
Cameron Gutman
37cdf16834 Add direct touchscreen mouse support 2020-04-22 19:22:32 -07:00
Cameron Gutman
d9a09fe450 Version 0.9.14 2020-03-29 16:06:57 -07:00
Cameron Gutman
d76f932e85 Reduce ENet retransmission delay 2020-03-29 16:06:24 -07:00
Cameron Gutman
75d141d8a8 Version 0.9.13 2020-03-21 00:16:27 -07:00
Cameron Gutman
ae6e6f6400 Ignore autorepeat key events 2020-03-21 00:12:48 -07:00
Cameron Gutman
f1e789abe5 Change errorCode from long to int 2020-02-24 23:44:38 -08:00
Cameron Gutman
97df7bf58c Centralize Discord invite links 2020-01-18 10:55:11 -08:00
Cameron Gutman
12e5158b46 Version 0.9.12 2019-12-05 19:20:56 -08:00
Cameron Gutman
138f0ef40b Update common-c again with PMTUD fixes 2019-12-05 19:12:55 -08:00
Cameron Gutman
e05a0ef1eb Fix RTSP handshake error with broken PMTUD 2019-11-30 22:28:57 -06:00
Cameron Gutman
884ed26152 Fix auto-comment line breaks 2019-11-16 11:57:43 -08:00
Cameron Gutman
06ab7b8673 Add configuration for auto-comment bot 2019-11-09 15:06:05 -08:00
Cameron Gutman
3c3f207963 Add a friendly pairing error for being in game 2019-09-14 15:05:21 -07:00
Cameron Gutman
80d65e7b50 Version 0.9.11 2019-09-14 14:16:22 -07:00
Cameron Gutman
31f7ee835f Fix control stream connection error on multi-homed hosts 2019-09-14 14:12:16 -07:00
Cameron Gutman
dc1c515958 Version 0.9.10 2019-08-23 19:00:54 -07:00
Cameron Gutman
e56db8e6fe Update common-c for parallel STUN requests 2019-08-20 19:10:50 -07:00
Cameron Gutman
80eec4928c Version 0.9.9 2019-07-20 19:39:16 -07:00
Cameron Gutman
ce70b18bdb Implement OpenSSL locking callbacks 2019-07-20 19:33:21 -07:00
Cameron Gutman
7e65e6963a Update common-c for legacy servers 2019-07-07 11:00:07 -07:00
Cameron Gutman
7471853652 Generate SHA-256 client certificates instead of SHA-1 2019-07-05 21:50:48 -07:00
Cameron Gutman
9c2bfeb4e0 Version 0.9.8 2019-05-27 02:15:11 -07:00
Cameron Gutman
d072e0d142 Fix video on GFE 3.19 2019-05-27 02:14:59 -07:00
Cameron Gutman
b2418acf7c Version 0.9.7 2019-05-02 19:53:48 -07:00
Cameron Gutman
11d7b2125e Update moonlight-common-c for video optimizations and audio bandwidth reduction 2019-05-02 19:51:43 -07:00
Cameron Gutman
a3a2b4bdaa Version 0.9.6 2019-02-27 00:55:42 -08:00
Cameron Gutman
87f6f14af6 Add connection termination message for unexpected terminations 2019-02-27 00:55:27 -08:00
Cameron Gutman
b48cb3d069 Fix compiler flags 2019-02-27 00:33:52 -08:00
Cameron Gutman
9738b1bbc2 Add GfeVersion to start parameters 2019-02-27 00:08:57 -08:00
Cameron Gutman
3764f7dae4 Add high resolution scrolling support 2019-02-26 23:50:22 -08:00
Cameron Gutman
7d9229359a Version 0.9.5 2019-01-19 17:29:22 -08:00
Cameron Gutman
ab2865b71e Update common-c to fix IDR frame issues with GFE 3.17 2019-01-19 17:26:39 -08:00
Cameron Gutman
c3453ce2b8 Raise modifier keys on disconnect 2019-01-19 17:25:53 -08:00
Cameron Gutman
6729bb64f8 Version 0.9.4 2019-01-04 18:40:18 -08:00
Cameron Gutman
b993edae58 Enable strict bitrate limits for remote streaming 2019-01-04 18:39:05 -08:00
Cameron Gutman
ee803c6247 Switch to using stun.moonlight-stream.org for STUN 2019-01-04 18:12:47 -08:00
Cameron Gutman
6a6022cda7 Version 0.9.3 2018-12-24 18:56:56 -08:00
Cameron Gutman
f9438bec26 Update common-c with bitrate fix 2018-12-24 18:55:13 -08:00
Cameron Gutman
02edd06b63 Use shared UID for all Moonlight clients 2018-12-24 18:49:42 -08:00
Cameron Gutman
db49a33a0f Fix propagation of PPK after pairing via Add PC and a couple launch cosmetic issues 2018-12-24 18:39:22 -08:00
Cameron Gutman
d19bc0ca7d Fix adding PCs that are already paired 2018-12-24 18:13:31 -08:00
Cameron Gutman
0ddf07f4de Require cert pinning for HTTPS 2018-12-24 17:48:01 -08:00
Cameron Gutman
ecad4aa276 Sync pairing code with moonlight-embedded to fix MITM check during pairing 2018-12-24 01:03:32 -08:00
Cameron Gutman
065445d721 Update curl to 7.44.0 (latest webports version) 2018-12-24 00:13:44 -08:00
Cameron Gutman
bb452520fc Update readme to new URL 2018-12-03 21:45:15 -08:00
Cameron Gutman
6d60e02341 Version 0.9.2 2018-11-17 13:23:06 -08:00
Cameron Gutman
7f9c71805e Increase mouse polling rate to 5 ms to match PC 2018-11-17 13:18:35 -08:00
Cameron Gutman
e6f4247ae8 Batch mDNS discovery callbacks to every 500 ms 2018-11-17 13:17:55 -08:00
Cameron Gutman
9536c3f8c8 Save hosts when a new host is discovered via mDNS 2018-11-17 12:05:08 -08:00
Cameron Gutman
918b528648 Initialize the CURL library in a thread-safe way 2018-11-17 12:04:54 -08:00
Cameron Gutman
4613d4977c Add automatic detection of WAN IP address 2018-11-17 11:27:59 -08:00
Cameron Gutman
cb80160605 Update common-c for GFE 3.16 2018-11-17 11:14:56 -08:00
Cameron Gutman
fbd9319605 Update common-c 2018-11-03 17:30:11 -07:00
Cameron Gutman
a76c1ab6a1 Link to Moonlight Qt 2018-08-05 20:13:36 -07:00
Cameron Gutman
2f72f7e555 Version 0.9.1 2018-07-30 01:37:08 -07:00
Cameron Gutman
1d7b94ccaf Update to latest common-c 2018-07-30 01:36:31 -07:00
Cameron Gutman
3ce617a304 Merge pull request #487 from Jorys-Paulin/feature/github-bots
Added GitHub bots config files
2018-07-29 23:49:39 -07:00
Jorys Paulin
a8f55452f0 Added github bots config files 2018-07-30 08:28:53 +02:00
Cameron Gutman
754173543a Address broken error checking for launch requests and other minor issues 2018-06-12 21:23:24 -07:00
Cameron Gutman
1194556b9c Update readme with NaCl info 2018-06-12 19:49:02 -07:00
Cameron Gutman
7dc7df792a Merge pull request #464 from Jorys-Paulin/feature/github
GitHub integration
2018-06-12 19:45:11 -07:00
Cameron Gutman
ccfcfff9a4 Merge commit '8bbb522'
This is a partial merge of https://github.com/moonlight-stream/moonlight-chrome/pull/414
2018-06-12 19:41:29 -07:00
Cameron Gutman
e1dad1d65b Update common-c to fix a crash and other bugs 2018-06-12 19:37:30 -07:00
Cameron Gutman
75d43124ab Ensure the host PC exists before starting polling 2018-06-12 19:35:20 -07:00
Cameron Gutman
47cfbf3d9f Merge pull request #454 from Jorys-Paulin/develop
Changes and improvements
2018-06-12 19:33:29 -07:00
Jorys_Paulin
744ff01e64 Revert "Removed unused gameList and gameSelection ids"
This reverts commit 34b6004ad3.
2018-06-12 12:56:45 +02:00
Jorys_Paulin
5a30f4c983 Added "Running" title when hovering running game 2018-06-09 10:45:27 +02:00
Jorys_Paulin
50d21da453 Replaced border to outline to avoid content jumping 2018-06-09 10:37:36 +02:00
Jorys_Paulin
34b6004ad3 Removed unused gameList and gameSelection ids 2018-06-08 18:36:46 +02:00
Jorys_Paulin
9457304ad3 Added native classList to backgroundPoll 2018-06-05 18:36:38 +02:00
Jorys_Paulin
7c48586394 Added keyboard support on games list 2018-06-05 16:49:47 +02:00
Jorys_Paulin
84e1cb80e1 Removed Jquery from game list generation 2018-06-03 17:10:16 +02:00
Jorys_Paulin
0dfc4e6a61 Changed outline-color 2018-06-02 10:35:16 +02:00
Jorys_Paulin
617bd0b4ef Added PULL_REQUEST_TEMPLATE.md 2018-05-12 15:43:18 +02:00
Jorys_Paulin
092a9b0ef6 Added ISSUE_TEMPLATE.md 2018-05-12 11:27:21 +02:00
Jorys_Paulin
b15d2bb668 Added CONTRIBUTING.md 2018-05-12 11:12:28 +02:00
Jorys_Paulin
6074fd4b86 Added the "Contributor Covenant Code of Conduct" 2018-05-12 11:07:21 +02:00
Jorys Paulin
c48a1d8adc Fixed a duplication bug 2018-05-05 22:05:32 +02:00
Jorys_Paulin
7815f3fa5f Added graphic when gamelist empty 2018-05-05 21:51:50 +02:00
Jorys_Paulin
3234ffd4ea Added graphic when gamelist error 2018-05-05 16:52:25 +02:00
Jorys_Paulin
c15ddb8597 Added error when failed to get gamelist 2018-05-04 18:35:19 +02:00
Jorys_Paulin
d062346db2 Editied the album placeholder 2018-05-03 16:06:54 +02:00
Jorys_Paulin
29a105d016 Replaced error box art with new one + lazyload 2018-05-03 14:09:01 +02:00
Jorys_Paulin
8f5f383ead Simplifed options text 2018-05-02 10:44:26 +02:00
Jorys_Paulin
447ab4a74c Simplified the stylizeBoxArt function 2018-05-01 22:25:25 +02:00
Jorys_Paulin
492ee0dc61 Added message when gamelist empty 2018-05-01 09:50:51 +02:00
Cameron Gutman
248a4da331 Remove PEM_read* anti-pattern that only happens to work because we're using a global variable 2018-04-30 21:18:56 -07:00
Jorys_Paulin
78c32035f8 Added fade-in for images 2018-04-30 17:11:30 +02:00
Jorys_Paulin
fe06f6d8ff Fixed html identation 2018-04-24 12:46:45 +02:00
Jorys_Paulin
28a76fa965 Fixed indentation usign atom-beautify 2018-04-24 08:40:39 +02:00
Jorys_Paulin
49bdfcc33d Added placeholder while loading albums 2018-04-23 21:10:34 +02:00
Jorys_Paulin
28f0200c7f Lazy-load albums 2018-04-23 20:48:23 +02:00
Jorys_Paulin
1e5bd25291 Small changes to the UI 2018-04-23 20:41:27 +02:00
Cameron Gutman
7a54ad9fb1 Version 0.9.0 2018-03-28 01:53:56 -07:00
Cameron Gutman
80d9dc7c77 Remove usage of deleted function 2018-03-28 01:25:22 -07:00
Cameron Gutman
a069451888 Actually set the logMessage callback so logging works 2018-03-28 01:23:49 -07:00
Cameron Gutman
35720d0e8e Ensure revived hosts have a valid unique ID 2018-03-28 01:13:42 -07:00
Cameron Gutman
b186c42bf0 Hack around TLS v1.2 issue that causes machines to spuriously go offline 2018-03-28 01:02:45 -07:00
Cameron Gutman
ddd7310e38 Avoid racing reads from storage that could cause pairing data to be wiped 2018-03-28 00:33:41 -07:00
Cameron Gutman
6c457fe56d Rewrite box art loading to load directly from chrome.storage for a huge speed improvement 2018-03-28 00:32:51 -07:00
Cameron Gutman
4284394607 Display a message with the error when a connection stage fails 2018-03-27 23:14:22 -07:00
Paulin Jorys
8bbb522ced Added hardware acceleration setting 2018-02-26 21:32:31 +01:00
Cameron Gutman
5f6120012e Update common-c to fix audio dropouts 2018-02-19 01:39:00 -08:00
Cameron Gutman
2288714bce Version 0.8.2 2018-01-20 16:27:52 -08:00
Cameron Gutman
fdcd3d4747 Send attached gamepads at launch to fix L4D2 2018-01-20 15:08:36 -08:00
Cameron Gutman
17f006db03 Version 0.8.1 2018-01-10 00:59:01 -08:00
Cameron Gutman
053d2944d1 Update for new video decoder API changes 2017-11-18 17:42:55 -08:00
Cameron Gutman
490a95af0f Version 0.8.0 2017-11-12 22:23:04 -08:00
Cameron Gutman
8dcd65786e Merge pull request #348 from kevincharm/fix/macos-numpad
Handle numpad correctly for macOS client
2017-11-07 00:51:28 -08:00
Kevin Charm
0ad380ded0 detect numpad modifier and add appropriate offset to keycode 2017-11-07 16:02:03 +08:00
Cameron Gutman
3121b51d22 Send separate left and right VK codes for shift/alt/ctrl keys. Fixes #219 2017-11-06 22:57:21 -08:00
R. Aidan Campbell
178a5452d4 Merge pull request #337 from ryanomackey/master
feat(index.js): sort titles alphabetically
2017-10-22 13:09:33 -07:00
R. Aidan Campbell
331ec26530 Merge pull request #330 from moonlight-stream/nacl_logging
Nacl logging
2017-10-22 13:06:56 -07:00
R. Aidan Campbell
5328f2a9e9 ignoring visual studio generated directories 2017-10-22 13:05:05 -07:00
Cameron Gutman
19dc99b425 Update for GFE 3.10 2017-10-17 00:04:19 -07:00
Ryan Mackey
9527750205 feat(index.js): sort titles alphabetically 2017-10-16 22:53:54 -05:00
R. Aidan Campbell
7a6ed6da57 minor bugfixes in logging 2017-10-07 14:14:37 -07:00
R. Aidan Campbell
7e1dd5d30a Covered NaCl module loading with logging statements 2017-10-07 14:00:14 -07:00
Cameron Gutman
e0c4c01e44 Keep the display awake when streaming. Fixes #325 2017-10-04 19:19:56 -07:00
Cameron Gutman
3f244ff8e1 Fix default value of optimize games toggle 2017-09-08 21:03:55 -07:00
Cameron Gutman
63731def4a Update tooltip of remote audio checkbox and put it in a nav menu div 2017-09-05 21:14:36 -07:00
Cameron Gutman
9b4e7b661b Switch GFE optimizations from a menu to a toggle 2017-09-05 21:07:12 -07:00
GoonieG
f32a35607b Feature to enable Gamestream optimization or not (#309)
* Added new feature.  Menu option added (and helper code) to enable or disable Geforce Experience option to modify/optimize game settings or not.

* Revert manifest.json change
2017-09-05 21:06:44 -07:00
Cameron Gutman
f45a2c22d5 Merge pull request #308 from Jorys-Paulin/feature/roboto
Added Roboto font
2017-09-05 20:30:39 -07:00
Paulin Jorys
00e1511daf Added offline support 2017-09-05 18:43:51 +02:00
Paulin Jorys
7c29774fbb Added Roboto font 2017-09-05 18:27:35 +02:00
R. Aidan Campbell
3f7e3aa10b Merge pull request #276 from Jorys-Paulin/js-cleaning
A console update
2017-09-03 16:56:09 -07:00
Cameron Gutman
3157fb6923 Update to version 0.7.4 2017-09-03 11:42:31 -07:00
Cameron Gutman
fb5988ffec Update libcurl webports and dependencies for IPv6 support 2017-09-02 22:28:44 -07:00
Cameron Gutman
584d504273 Fix ability to update address of existing hosts via Add PC dialog 2017-09-02 21:26:28 -07:00
Cameron Gutman
498bff4b0b Update common-c submodule 2017-09-02 21:25:13 -07:00
Cameron Gutman
94df20bbee Improve performance of PC polling with many paired PCs 2017-09-02 20:30:18 -07:00
Cameron Gutman
f485c8ce49 Update icons 2017-08-23 23:04:22 -07:00
Cameron Gutman
b4ba33f72a Fix file mode on a bunch of files 2017-08-23 22:27:49 -07:00
Paulin Jorys
bdfc115a0a Added basic jsdoc for the messages.js file 2017-07-19 18:08:43 +02:00
Paulin Jorys
079126360d Quick-fix: changed ";" to "," 2017-07-12 11:31:06 +02:00
Paulin Jorys
d5db081e7d Added console errors for startGame() and stopGame() 2017-07-12 11:28:33 +02:00
Paulin Jorys
e1616df7b4 Fixed a git error 2017-07-11 16:25:18 +02:00
Paulin Jorys
7517e379c5 Merge branch 'js-cleaning' of https://github.com/Jorys-Paulin/moonlight-chrome into js-cleaning 2017-07-11 16:17:22 +02:00
Paulin Jorys
a34a0c492a Quick fix: Updated the remote audio storage log & launch app 2017-07-11 16:11:19 +02:00
Paulin Jorys
66da3a7c87 Quick fix: Updated the remote audio storage log 2017-07-11 16:03:34 +02:00
Paulin Jorys
12f0be4149 Quick-fix: snackback logging in the console 2017-07-11 13:53:04 +02:00
Paulin Jorys
6257594085 Inverted order for labels
From "function,filename" to "filename,function"
Added "[filename, function] to messages.js
2017-07-11 13:47:13 +02:00
Paulin Jorys
cfaa0efde4 Renamed "Moonlight GUI" to "index.js"
Changed utils.js:316 to be a 'backend' error
2017-07-11 13:28:22 +02:00
Paulin Jorys
1c0a575ccc Added back the host.toString() method to support text-file logs 2017-07-11 13:25:27 +02:00
Paulin Jorys
4108d696e4 Added better console logs 2017-07-11 13:20:01 +02:00
Cameron Gutman
2dfdf703fd Version 0.7.3 2017-06-24 17:18:49 -07:00
Cameron Gutman
d19ca54fda Merge pull request #246 from Jorys-Paulin/feature-a11y
Accessibility and keyboard support
2017-06-23 22:08:39 -07:00
Cameron Gutman
37387e151f Batch mouse movement events to reduce input lag with high polling rate mice 2017-06-23 16:43:10 -07:00
Paulin Jorys
2fc6b10cc9 Fixed lint errors 2017-06-23 16:12:30 +02:00
Cameron Gutman
59e3a104ba Update to latest moonlight-common-c 2017-06-11 15:52:03 -07:00
Cameron Gutman
2456ec603c Version 0.7.2 2017-06-08 21:57:27 -07:00
Cameron Gutman
cae6b4a566 Update moonlight-common-c with latest bugfixes 2017-06-08 21:50:00 -07:00
R. Aidan Campbell
326b7d6aed quick bitrate fix, thanks to Prax's mailed in patch 2017-05-29 18:20:31 -07:00
Paulin Jorys
d2a2542e5b go-back button now properly announced 2017-05-23 17:44:34 +02:00
Paulin Jorys
59e7adb32f Changed the back-button to be a mdl component 2017-05-23 17:42:29 +02:00
Paulin Jorys
8e601a9577 Added enter keyboard action for grids 2017-05-23 17:41:03 +02:00
Paulin Jorys
8689032369 Host grid accessible 2017-05-21 18:35:10 +02:00
Paulin Jorys
9cd90d5a8d Back button is now recognised 2017-05-21 18:28:22 +02:00
Paulin Jorys
850862c1d1 Quit app button now announces correctly 2017-05-21 18:26:03 +02:00
Paulin Jorys
053cd9a830 Made the game grid accessible 2017-05-21 18:22:28 +02:00
Cameron Gutman
38a7a058ab Only poll hosts in the background on the host display page 2017-05-13 23:14:15 -07:00
Cameron Gutman
7d978ca131 Prevent callbacks from many polling requests being queued for the same host 2017-05-13 23:12:55 -07:00
Cameron Gutman
c3d72f8c71 Correct default remote audio state 2017-05-13 22:50:02 -07:00
Cameron Gutman
fb85ea15da Correct default resolution to 720p 2017-05-13 22:15:44 -07:00
Cameron Gutman
3f0d2b9909 Update moonlight-common-c 2017-05-11 20:13:10 -07:00
Cameron Gutman
e4bec4133d Version 0.7.1 2017-05-07 23:11:29 -07:00
Cameron Gutman
c0d9ae87f2 Update common-c with critical FEC fixes 2017-05-07 23:10:31 -07:00
143 changed files with 6184 additions and 1838 deletions

7
.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,7 @@
# Contributing
Thanks for contributing to the Moonlight Project! Whether you're opening an issue or proposing a pull request, you are welcome to follow these instructions.
- Use proper English: it doesn't have to be complicated, just make it simple to understand for everyone
- Cleary expose your feature or problem: My features adds, my problem is...
- Include screenshots if possible
- When posting an issue, give us the logs (blank your private IP)

24
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,24 @@
# Read before posting an issue
If you have an issue, please consider the following before:
- Have you tried __updating__:
- Your operating system
- Geforce Experience (mention if in beta)
- Chrome to the latest version
- The Moonlight client
- Have you tried __pinging__ your host from the client?
- If streaming __over the internet__:
- Have you followed the [guide](https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide)?
- Have you opened all ports to they correct protocols (udp or tcp)
- Have you enabled __hardware acceleration__?
- Check under `chrome://settings/system` to enable it
- Check under `chrome://flags/#disable-accelerated-video-decode` for video hardware acceleration
- Check under `chrome://gpu` for:
- Video Decode: "Hardware accelerated"
- WebGL: "Hardware accelerated"
- WebGL2: "Hardware accelerated"
- Have you __enabled NaCL__?
- Check under `chrome://flags/#enable-nacl` to enable it
- Are you running Linux? if so, install Chrome from official ppa
If you still have problems, post them in the issues section with info, logs and screenshots if possible

10
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,10 @@
# Name of my pull request
Fixes #123
Changes proposed in this pull request:
- My change #1
- My change #2
- My change #3
@moonlight-stream

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!

8
.github/no-response.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
# ProBot No Response (https://probot.github.io/apps/no-response/)
daysUntilClose: 7
responseRequiredLabel: 'need more info'
closeComment: >
This issue has been automatically closed because there was no response to a
request for more information from the issue opener. Please leave a comment or
open a new issue if you have additional information related to this issue.

14
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
# ProBot Stale (https://probot.github.io/apps/stale/)
daysUntilStale: 90
daysUntilClose: 7
exemptLabels:
- accepted
- bug
- enhancement
- meta
staleLabel: stale
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs.
closeComment: false

8
.gitignore vendored
View File

@@ -41,4 +41,10 @@ dir.stamp
*.nexe *.nexe
*.pexe *.pexe
*.nmf *.nmf
*.bc *.bc
# Jetbrains IDEs
*.idea/
# Visual Studio
*.vs/

46
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at info@moonlight-stream.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -21,7 +21,8 @@ CHROME_ARGS += --allow-nacl-socket-api=localhost
LIBS = ppapi_gles2 ppapi ppapi_cpp pthread curl z ssl crypto nacl_io LIBS = ppapi_gles2 ppapi ppapi_cpp pthread curl z ssl crypto nacl_io
CFLAGS = -Wall $(COMMON_C_C_FLAGS) $(OPUS_C_FLAGS) CFLAGS += -Wall $(COMMON_C_C_FLAGS) $(OPUS_C_FLAGS)
CXXFLAGS += -Wall
SOURCES = \ SOURCES = \
$(OPUS_SOURCE) \ $(OPUS_SOURCE) \

View File

@@ -1,32 +1,24 @@
# Moonlight for Chrome # Moonlight for ChromeOS
[Moonlight for Chrome](http://moonlight-stream.com) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield, but built to run in the Chrome browser. [Moonlight for ChromeOS](https://moonlight-stream.org) is an open source client for NVIDIA GameStream and [Sunshine](https://github.com/LizardByte/Sunshine).
Moonlight for Chrome allows you to stream your full collection of games from your powerful desktop to another PC or laptop running Windows, Mac OS X, Linux, or Chrome OS. Moonlight for ChromeOS allows you to stream your full collection of games from your powerful desktop to another PC or laptop running ChromeOS.
Moonlight also has mobile versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [iOS](https://github.com/moonlight-stream/moonlight-ios). Moonlight also has mobile versions for [Android](https://github.com/moonlight-stream/moonlight-android) and [iOS/tvOS](https://github.com/moonlight-stream/moonlight-ios).
## Features Check out [the Moonlight wiki](https://github.com/moonlight-stream/moonlight-docs/wiki) for more detailed project information, setup guide, or troubleshooting steps.
* Streams Steam Big Picture and all of your games from your PC to your Chrome browser [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/w716mt9ulyww68c5/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-chrome/branch/master)
* Keyboard and mouse support
* Hardware-accelerated video decoding
* Full support for Xbox controllers and PlayStation controllers, and some other HID gamepads
* Use mDNS to scan for compatible GeForce Experience (GFE) machines on the network
## Features to come [![Moonlight for ChromeOS](https://moonlight-stream.org/images/chrome_webstore.png)](https://chrome.google.com/webstore/detail/moonlight-game-streaming/gemamigbbenahjlfnmlfdjhdnkpbkfjj)
* Gamepad mapping
* Improved UI
* Better error handling
## Installation ## Deprecation
* Download [GeForce Experience](http://www.geforce.com/geforce-experience) and install on your GameStream-compatible PC
* Install the [latest release](https://github.com/moonlight-stream/moonlight-chrome/releases)
## Requirements Moonlight for ChromeOS is a legacy client that depends on the [deprecated NaCl runtime](https://blog.chromium.org/2021/10/extending-chrome-app-support-on-chrome.html). It is receiving only basic bugfixes and little/no feature work.
* Chrome browser on Windows, Mac OS X, Linux, or Chrome OS
* [GameStream-compatible](http://shield.nvidia.com/play-pc-games/) computer with GTX 600+ series desktop or mobile GPU (for the PC from which you're streaming) For ChromeOS systems, we recommend migrating to the [Android](https://github.com/moonlight-stream/moonlight-android) app for additional features, functionality, and active support. Please reach out in the [GitHub tracker](https://github.com/moonlight-stream/moonlight-android/issues) if there are any functionality or performance regressions when moving to the Android client on ChromeOS systems.
* High-end wireless router (802.11n dual-band recommended) or wired network
For Windows, Mac, and Linux clients, we recommend running the [native PC port](https://github.com/moonlight-stream/moonlight-qt).
## Building ## Building
1. Install the Chrome Native Client SDK and download the current Pepper SDK 1. Install the Chrome Native Client SDK and download the current Pepper SDK
@@ -40,16 +32,3 @@ Moonlight also has mobile versions for [Android](https://github.com/moonlight-st
3. Click 'Load unpacked extension' and point it at your built moonlight-chrome repo 3. Click 'Load unpacked extension' and point it at your built moonlight-chrome repo
4. Run Moonlight from the extensions page 4. Run Moonlight from the extensions page
5. If making changes, make sure to click the Reload button on the Extensions page 5. If making changes, make sure to click the Reload button on the Extensions page
## Streaming
Simply type the hostname or IP into the textbox, pair, choose an app to run, then begin streaming. Once paired, the host will be remembered in a dropdown menu. To exit a stream, press Ctrl+Alt+Shift+Q. To remove focus from the stream, press Ctrl+Alt+Shift.
## Contribute
This project is being actively developed at [XDA Developers](http://forum.xda-developers.com/showthread.php?t=2505510)
1. Fork us
2. Write code
3. Send Pull Requests
Check out our [website](http://moonlight-stream.com) for project links and information.

26
appveyor.yml Normal file
View File

@@ -0,0 +1,26 @@
version: 0.0.0.{build}
clone_depth: 1
image: Previous Ubuntu2004
install:
- 'pushd $HOME'
- 'wget https://github.com/cgutman/nacl_sdk/archive/refs/heads/master.zip -O nacl_sdk.zip'
- 'unzip nacl_sdk.zip'
- 'cd nacl_sdk-master'
- 'source $HOME/venv2.7/bin/activate'
- './naclsdk update'
- 'export NACL_SDK_ROOT=$HOME/nacl_sdk-master/pepper_49'
- 'popd'
before_build:
- 'git submodule update --init --recursive'
build_script:
- './do-release.sh'
after_build:
- 'appveyor PushArtifact moonlight-chrome.zip'
deploy: off

View File

@@ -11,8 +11,8 @@
// at a time. // at a time.
static short s_CircularBuffer[CIRCULAR_BUFFER_SIZE][FRAME_SIZE * MAX_CHANNEL_COUNT]; static short s_CircularBuffer[CIRCULAR_BUFFER_SIZE][FRAME_SIZE * MAX_CHANNEL_COUNT];
static int s_ReadIndex = 0; static int s_ReadIndex;
static int s_WriteIndex = 0; static int s_WriteIndex;
static void AudioPlayerSampleCallback(void* samples, uint32_t buffer_size, void* data) { static void AudioPlayerSampleCallback(void* samples, uint32_t buffer_size, void* data) {
// It should only ask us for complete buffers // It should only ask us for complete buffers
@@ -34,8 +34,11 @@ static void AudioPlayerSampleCallback(void* samples, uint32_t buffer_size, void*
} }
} }
void MoonlightInstance::AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig) { int MoonlightInstance::AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags) {
int rc; int rc;
// Reset the ring buffer to empty
s_ReadIndex = s_WriteIndex = 0;
g_Instance->m_OpusDecoder = opus_multistream_decoder_create(opusConfig->sampleRate, g_Instance->m_OpusDecoder = opus_multistream_decoder_create(opusConfig->sampleRate,
opusConfig->channelCount, opusConfig->channelCount,
@@ -49,6 +52,8 @@ void MoonlightInstance::AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CON
// Start playback now // Start playback now
g_Instance->m_AudioPlayer.StartPlayback(); g_Instance->m_AudioPlayer.StartPlayback();
return 0;
} }
void MoonlightInstance::AudDecCleanup(void) { void MoonlightInstance::AudDecCleanup(void) {
@@ -83,8 +88,8 @@ void MoonlightInstance::AudDecDecodeAndPlaySample(char* sampleData, int sampleLe
} }
AUDIO_RENDERER_CALLBACKS MoonlightInstance::s_ArCallbacks = { AUDIO_RENDERER_CALLBACKS MoonlightInstance::s_ArCallbacks = {
MoonlightInstance::AudDecInit, .init = MoonlightInstance::AudDecInit,
MoonlightInstance::AudDecCleanup, .cleanup = MoonlightInstance::AudDecCleanup,
MoonlightInstance::AudDecDecodeAndPlaySample, .decodeAndPlaySample = MoonlightInstance::AudDecDecodeAndPlaySample,
CAPABILITY_DIRECT_SUBMIT .capabilities = CAPABILITY_DIRECT_SUBMIT
}; };

View File

@@ -24,18 +24,21 @@ COMMON_C_SOURCE := \
$(COMMON_C_DIR)/AudioStream.c \ $(COMMON_C_DIR)/AudioStream.c \
$(COMMON_C_DIR)/ByteBuffer.c \ $(COMMON_C_DIR)/ByteBuffer.c \
$(COMMON_C_DIR)/Connection.c \ $(COMMON_C_DIR)/Connection.c \
$(COMMON_C_DIR)/ConnectionTester.c \
$(COMMON_C_DIR)/ControlStream.c \ $(COMMON_C_DIR)/ControlStream.c \
$(COMMON_C_DIR)/FakeCallbacks.c \ $(COMMON_C_DIR)/FakeCallbacks.c \
$(COMMON_C_DIR)/InputStream.c \ $(COMMON_C_DIR)/InputStream.c \
$(COMMON_C_DIR)/LinkedBlockingQueue.c \ $(COMMON_C_DIR)/LinkedBlockingQueue.c \
$(COMMON_C_DIR)/Misc.c \ $(COMMON_C_DIR)/Misc.c \
$(COMMON_C_DIR)/Platform.c \ $(COMMON_C_DIR)/Platform.c \
$(COMMON_C_DIR)/PlatformCrypto.c \
$(COMMON_C_DIR)/PlatformSockets.c \ $(COMMON_C_DIR)/PlatformSockets.c \
$(COMMON_C_DIR)/RtpFecQueue.c \ $(COMMON_C_DIR)/RtpAudioQueue.c \
$(COMMON_C_DIR)/RtpReorderQueue.c \ $(COMMON_C_DIR)/RtpVideoQueue.c \
$(COMMON_C_DIR)/RtspConnection.c \ $(COMMON_C_DIR)/RtspConnection.c \
$(COMMON_C_DIR)/RtspParser.c \ $(COMMON_C_DIR)/RtspParser.c \
$(COMMON_C_DIR)/SdpGenerator.c \ $(COMMON_C_DIR)/SdpGenerator.c \
$(COMMON_C_DIR)/SimpleStun.c \
$(COMMON_C_DIR)/VideoDepacketizer.c \ $(COMMON_C_DIR)/VideoDepacketizer.c \
$(COMMON_C_DIR)/VideoStream.c \ $(COMMON_C_DIR)/VideoStream.c \
$(ENET_SOURCE) \ $(ENET_SOURCE) \

View File

@@ -10,8 +10,13 @@ void MoonlightInstance::ClStageStarting(int stage) {
g_Instance->PostMessage(response); g_Instance->PostMessage(response);
} }
void MoonlightInstance::ClStageFailed(int stage, long errorCode) { void MoonlightInstance::ClStageFailed(int stage, int errorCode) {
pp::Var response(std::string("Starting ") + std::string(LiGetStageName(stage)) + std::string("failed")); pp::Var response(
std::string("DialogMsg: ") +
std::string(LiGetStageName(stage)) +
std::string(" failed (error ") +
std::to_string(errorCode) +
std::string(")"));
g_Instance->PostMessage(response); g_Instance->PostMessage(response);
} }
@@ -20,7 +25,7 @@ void MoonlightInstance::ClConnectionStarted(void) {
g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::OnConnectionStarted)); g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::OnConnectionStarted));
} }
void MoonlightInstance::ClConnectionTerminated(long errorCode) { void MoonlightInstance::ClConnectionTerminated(int errorCode) {
// Teardown the connection // Teardown the connection
LiStopConnection(); LiStopConnection();
@@ -38,12 +43,23 @@ void MoonlightInstance::ClDisplayTransientMessage(const char* message) {
g_Instance->PostMessage(response); g_Instance->PostMessage(response);
} }
void MoonlightInstance::ClLogMessage(const char* format, ...) {
va_list va;
char message[1024];
va_start(va, format);
vsnprintf(message, sizeof(message), format, va);
va_end(va);
pp::Var response(std::string("LogMsg: ") + std::string(message));
g_Instance->PostMessage(response);
}
CONNECTION_LISTENER_CALLBACKS MoonlightInstance::s_ClCallbacks = { CONNECTION_LISTENER_CALLBACKS MoonlightInstance::s_ClCallbacks = {
MoonlightInstance::ClStageStarting, .stageStarting = MoonlightInstance::ClStageStarting,
NULL, .stageFailed = MoonlightInstance::ClStageFailed,
MoonlightInstance::ClStageFailed, .connectionStarted = MoonlightInstance::ClConnectionStarted,
MoonlightInstance::ClConnectionStarted, .connectionTerminated = MoonlightInstance::ClConnectionTerminated,
MoonlightInstance::ClConnectionTerminated, .logMessage = MoonlightInstance::ClLogMessage,
MoonlightInstance::ClDisplayMessage, .rumble = MoonlightInstance::ClControllerRumble,
MoonlightInstance::ClDisplayTransientMessage
}; };

16
do-release.sh Executable file
View File

@@ -0,0 +1,16 @@
fail()
{
echo "$1" 1>&2
exit 1
}
git diff-index --quiet HEAD -- || fail "Release builds must not have unstaged changes!"
rm moonlight-chrome.zip
make clean || fail "Clean failed"
make -j$(nproc) || fail "Build failed"
zip moonlight-chrome.zip -r . -i pnacl/Release/moonlight-chrome.* -i manifest.json -i index.html -i LICENSE || fail "Zip failed"
zip moonlight-chrome.zip -r icons || fail "Zip failed"
zip moonlight-chrome.zip -r static || fail "Zip failed"

View File

@@ -4,6 +4,8 @@
#include <Limelight.h> #include <Limelight.h>
#include <sstream>
static const unsigned short k_StandardGamepadButtonMapping[] = { static const unsigned short k_StandardGamepadButtonMapping[] = {
A_FLAG, B_FLAG, X_FLAG, Y_FLAG, A_FLAG, B_FLAG, X_FLAG, Y_FLAG,
LB_FLAG, RB_FLAG, LB_FLAG, RB_FLAG,
@@ -24,7 +26,10 @@ static short GetActiveGamepadMask(PP_GamepadsSampleData& gamepadData) {
for (unsigned int p = 0; p < gamepadData.length; p++) { for (unsigned int p = 0; p < gamepadData.length; p++) {
PP_GamepadSampleData& padData = gamepadData.items[p]; PP_GamepadSampleData& padData = gamepadData.items[p];
// See logic in getConnectedGamepadMask() (utils.js)
// These must stay in sync!
if (!padData.connected) { if (!padData.connected) {
// Not connected // Not connected
continue; continue;
@@ -81,7 +86,7 @@ void MoonlightInstance::PollGamepads() {
m_LastPadTimestamps[p] = padData.timestamp; m_LastPadTimestamps[p] = padData.timestamp;
short buttonFlags = 0; int buttonFlags = 0;
unsigned char leftTrigger = 0, rightTrigger = 0; unsigned char leftTrigger = 0, rightTrigger = 0;
short leftStickX = 0, leftStickY = 0; short leftStickX = 0, leftStickY = 0;
short rightStickX = 0, rightStickY = 0; short rightStickX = 0, rightStickY = 0;
@@ -124,3 +129,14 @@ void MoonlightInstance::PollGamepads() {
controllerIndex++; controllerIndex++;
} }
} }
void MoonlightInstance::ClControllerRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor)
{
const float weakMagnitude = static_cast<float>(highFreqMotor) / static_cast<float>(UINT16_MAX);
const float strongMagnitude = static_cast<float>(lowFreqMotor) / static_cast<float>(UINT16_MAX);
std::ostringstream ss;
ss << controllerNumber << "," << weakMagnitude << "," << strongMagnitude;
pp::Var response(std::string("controllerRumble: ") + ss.str());
g_Instance->PostMessage(response);
}

View File

@@ -5,15 +5,19 @@
#include <http.h> #include <http.h>
#include <errors.h> #include <errors.h>
#include <string.h> #include <string.h>
#include <sys/mount.h>
#include <mkcert.h> #include <mkcert.h>
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <curl/curl.h>
X509 *g_Cert; X509 *g_Cert;
EVP_PKEY *g_PrivateKey; EVP_PKEY *g_PrivateKey;
char *g_UniqueId; char *g_UniqueId;
char *g_CertHex; char *g_CertHex;
pthread_mutex_t *g_OSSLMutexes;
void MoonlightInstance::MakeCert(int32_t callbackId, pp::VarArray args) void MoonlightInstance::MakeCert(int32_t callbackId, pp::VarArray args)
{ {
@@ -62,7 +66,7 @@ void MoonlightInstance::LoadCert(const char* certStr, const char* keyStr)
BIO_free_all(bio); BIO_free_all(bio);
bio = BIO_new_mem_buf(_keyStr, -1); bio = BIO_new_mem_buf(_keyStr, -1);
if(PEM_read_bio_PrivateKey(bio, &g_PrivateKey, NULL, NULL) == NULL) { if (!(g_PrivateKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL))) {
PostMessage(pp::Var("Error loading private key into memory")); PostMessage(pp::Var("Error loading private key into memory"));
} }
BIO_free_all(bio); BIO_free_all(bio);
@@ -77,28 +81,67 @@ void MoonlightInstance::LoadCert(const char* certStr, const char* keyStr)
free(_keyStr); free(_keyStr);
} }
void MoonlightInstance::OSSLThreadLock(int mode, int n, const char *, int)
{
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&g_OSSLMutexes[n]);
}
else {
pthread_mutex_unlock(&g_OSSLMutexes[n]);
}
}
unsigned long MoonlightInstance::OSSLThreadId(void)
{
return (unsigned long)pthread_self();
}
void MoonlightInstance::NvHTTPInit(int32_t callbackId, pp::VarArray args) void MoonlightInstance::NvHTTPInit(int32_t callbackId, pp::VarArray args)
{ {
std::string _cert = args.Get(0).AsString(); std::string _cert = args.Get(0).AsString();
std::string _key = args.Get(1).AsString(); std::string _key = args.Get(1).AsString();
std::string _uniqueId = args.Get(2).AsString(); std::string _uniqueId = args.Get(2).AsString();
// Mount resource directory where CA bundle resides
mount("static/curl", "/curl", "httpfs", 0, "");
// This will initialize OpenSSL
curl_global_init(CURL_GLOBAL_DEFAULT);
LoadCert(_cert.c_str(), _key.c_str()); LoadCert(_cert.c_str(), _key.c_str());
g_UniqueId = strdup(_uniqueId.c_str()); g_UniqueId = strdup(_uniqueId.c_str());
g_OSSLMutexes = new pthread_mutex_t[CRYPTO_num_locks()];
for (int i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_init(&g_OSSLMutexes[i], NULL);
}
CRYPTO_set_id_callback(OSSLThreadId);
CRYPTO_set_locking_callback(OSSLThreadLock);
pp::VarDictionary ret; pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId)); ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("resolve")); ret.Set("type", pp::Var("resolve"));
ret.Set("ret", pp::Var("")); ret.Set("ret", pp::Var());
PostMessage(ret); PostMessage(ret);
} }
void MoonlightInstance::NvHTTPRequest(int32_t /*result*/, int32_t callbackId, std::string url, bool binaryResponse) void MoonlightInstance::NvHTTPRequest(int32_t /*result*/, int32_t callbackId, pp::VarArray args)
{ {
char* _url = strdup(url.c_str()); std::string url = args.Get(0).AsString();
std::string ppkstr = args.Get(1).AsString();
bool binaryResponse = args.Get(2).AsBool();
// For launch/resume requests, append the additional query parameters
if (url.find("/launch?") != std::string::npos || url.find("/resume?") != std::string::npos) {
url += LiGetLaunchUrlQueryParameters();
}
PostMessage(pp::Var(url.c_str()));
PHTTP_DATA data = http_create_data(); PHTTP_DATA data = http_create_data();
int err; int err;
if (data == NULL) { if (data == NULL) {
pp::VarDictionary ret; pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId)); ret.Set("callbackId", pp::Var(callbackId));
@@ -108,7 +151,7 @@ void MoonlightInstance::NvHTTPRequest(int32_t /*result*/, int32_t callbackId, st
goto clean_data; goto clean_data;
} }
err = http_request(_url , data); err = http_request(url.c_str(), ppkstr.empty() ? NULL : ppkstr.c_str(), data);
if (err) { if (err) {
pp::VarDictionary ret; pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId)); ret.Set("callbackId", pp::Var(callbackId));
@@ -144,5 +187,4 @@ void MoonlightInstance::NvHTTPRequest(int32_t /*result*/, int32_t callbackId, st
clean_data: clean_data:
http_free_data(data); http_free_data(data);
free(_url);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,174 +1,190 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1"> <meta http-equiv="Expires" content="-1">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Moonlight</title> <title>Moonlight</title>
<link rel="stylesheet" href="static/css/roboto.css"> <link rel="stylesheet" href="static/css/roboto.css">
<link rel="stylesheet" href="static/css/material.min.css"> <link rel="stylesheet" href="static/css/material.min.css">
<link rel="stylesheet" href="static/css/style.css"> <link rel="stylesheet" href="static/css/style.css">
<link rel="stylesheet" href="static/css/material-icons.css"> <link rel="stylesheet" href="static/css/material-icons.css">
</head> </head>
<body data-name="moonlight-chrome" data-tools="pnacl" data-configs="Debug Release" data-path="{tc}/{config}"> <body data-name="moonlight-chrome" data-tools="pnacl" data-configs="Debug Release" data-path="{tc}/{config}">
<div class="mdl-layout mdl-js-layout"> <div class="mdl-layout mdl-js-layout">
<header id="main-navigation" class="mdl-layout__header mdl-layout__header--transparent"> <header id="main-navigation" class="mdl-layout__header mdl-layout__header--transparent">
<div class="mdl-layout__header-row"> <div class="mdl-layout__header-row">
<span id='backIcon'><i class="material-icons">keyboard_arrow_left</i></span> <button id="backIcon" class="mdl-button mdl-js-button mdl-button--icon" role="link" aria-label="Host selection"><i class="material-icons">keyboard_arrow_left</i></button>
<!-- Title --> <!-- Title -->
<span class="mdl-layout-title">MOON<span>LIGHT</span></span> <span class="mdl-layout-title">MOON<span>LIGHT</span></span>
<!-- Add spacer, to align navigation to the right --> <!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div> <div class="mdl-layout-spacer"></div>
<!-- Navigation --> <!-- Navigation -->
<nav class="mdl-navigation"> <nav class="mdl-navigation">
<div class="nav-menu-parent">
<div class="nav-menu-parent"> <div id="resolutionMenu">
<div id="resolutionMenu"> <button id="selectResolution" data-value="1280:720" class="mdl-button mdl-js-button">
<button id="selectResolution" data-value="1920:1080" class="mdl-button mdl-js-button"> 720p
1080p
</button> </button>
</div> </div>
<ul class="resolutionMenu mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" <ul class="resolutionMenu mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="selectResolution">
for="selectResolution"> <li class="mdl-menu__item" data-value="1280:720">720p</li>
<li class="mdl-menu__item" data-value="1280:720">720p</li> <li class="mdl-menu__item" data-value="1920:1080">1080p</li>
<li class="mdl-menu__item" data-value="1920:1080">1080p</li> <li class="mdl-menu__item" data-value="3840:2160">4K</li>
<li class="mdl-menu__item" data-value="3840:2160">4K</li> </ul>
</ul>
<div id="resolutionTooltip" class="mdl-tooltip" for="resolutionMenu"> <div id="resolutionTooltip" class="mdl-tooltip" for="resolutionMenu">
Resolution Resolution
</div> </div>
</div> </div>
<div class="nav-menu-parent">
<div class="nav-menu-parent"> <div id="framerateMenu">
<div id="framerateMenu"> <button id="selectFramerate" data-value="60" class="mdl-button mdl-js-button">
<button id="selectFramerate" data-value="60" class="mdl-button mdl-js-button">
60 FPS 60 FPS
</button> </button>
</div> </div>
<ul class="framerateMenu mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" <ul class="framerateMenu mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="selectFramerate">
for="selectFramerate"> <li class="mdl-menu__item" data-value="30">30 FPS</li>
<li class="mdl-menu__item" data-value="30">30 FPS</li> <li class="mdl-menu__item" data-value="60">60 FPS</li>
<li class="mdl-menu__item" data-value="60">60 FPS</li> </ul>
</ul>
<div id="framerateTooltip" class="mdl-tooltip" for="framerateMenu"> <div id="framerateTooltip" class="mdl-tooltip" for="framerateMenu">
Framerate Framerate
</div> </div>
</div> </div>
<div class="nav-menu-parent"> <div class="nav-menu-parent">
<div id="bandwidthMenu"> <div id="bandwidthMenu">
<button id='bitrateField' class="mdl-button">10 Mbps</button> <button id="bitrateField" class="mdl-button">10 Mbps</button>
</div> </div>
<div class="bitrateMenu mdl-menu mdl-js-menu mdl-js-ripple-effect" for="bandwidthMenu"> <div class="bitrateMenu mdl-menu mdl-js-menu mdl-js-ripple-effect" for="bandwidthMenu">
<input id="bitrateSlider" class="mdl-slider mdl-js-slider" type="range" min="0" max="100" step="0.5" value="10"> <input id="bitrateSlider" class="mdl-slider mdl-js-slider" type="range" min="0" max="100" step="0.5" value="10">
</div> </div>
<div id="bandwidthTooltip" class="mdl-tooltip" for="bandwidthMenu"> <div id="bandwidthTooltip" class="mdl-tooltip" for="bandwidthMenu">
Bandwidth Bandwidth
</div> </div>
</div> </div>
<label id="externalAudioBtn" class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="remoteAudioEnabledSwitch"> <div class="nav-menu-parent">
<input type="checkbox" id="remoteAudioEnabledSwitch" class="mdl-icon-toggle__input" checked> <label id="externalAudioBtn" class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="remoteAudioEnabledSwitch">
<i class="mdl-icon-toggle__label material-icons">volume_up</i> <input type="checkbox" id="remoteAudioEnabledSwitch" class="mdl-icon-toggle__input">
</label> <i class="mdl-icon-toggle__label material-icons">volume_up</i>
<div id="externalAudioTooltip" class="mdl-tooltip" for="externalAudioBtn"> </label>
Remote audio is ON <div id="externalAudioTooltip" class="mdl-tooltip" for="externalAudioBtn">
</div> Play audio on the host
</div>
</div>
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="quitCurrentApp"> <div class="nav-menu-parent">
<label id="mouseLockBtn" class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="mouseLockEnabledSwitch">
<input type="checkbox" id="mouseLockEnabledSwitch" class="mdl-icon-toggle__input">
<i class="mdl-icon-toggle__label material-icons">mouse</i>
</label>
<div id="mouseLockTooltip" class="mdl-tooltip" for="mouseLockBtn">
Enable mouse locking (must disable to use tap-to-click on touchpads)
</div>
</div>
<div class="nav-menu-parent">
<label id="optimizeGamesBtn" class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="optimizeGamesSwitch">
<input type="checkbox" id="optimizeGamesSwitch" class="mdl-icon-toggle__input">
<i class="mdl-icon-toggle__label material-icons">timeline</i>
</label>
<div id="optimizeGamesTooltip" class="mdl-tooltip" for="optimizeGamesBtn">
Allow game optimisations
</div>
</div>
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="quitCurrentApp" aria-label="Quit current app">
<i class="material-icons">remove_circle_outline</i> <i class="material-icons">remove_circle_outline</i>
Quit Current App Quit Current App
</button> </button>
</nav> </nav>
</div> </div>
</header> </header>
<main id="main-content" class="mdl-layout__content"> <main id="main-content" class="mdl-layout__content">
<div id="host-grid"> <div id="host-grid">
<div class="page-title">Your PCs</div> <div class="add-host-card mdl-card mdl-shadow--4dp" id="addHostCell">
<div class="add-host-card mdl-card mdl-shadow--4dp" id='addHostCell'> <div class="mdl-card__title mdl-card--expand" id="addHostIcon" role="link" tabindex="0" aria-label="Add Host">
<div class="mdl-card__title mdl-card--expand" id="addHostIcon"> <h2 class="mdl-card__title-text">Add Host</h2>
<h2 class="mdl-card__title-text" >Add Host</h2> </div>
</div> </div>
</div> </div>
</div> <div id="game-grid"></div>
<div id="game-grid"> <div id="listener"></div>
<div class="page-title">Your Games</div> <!-- NaCl module placeholder. NaCl gets thrown into here -->
</div> <div id="loadingSpinner" class="mdl-progress mdl-js-progress mdl-progress__indeterminate">
<div id="listener"></div> <h5 id="loadingMessage"></h5>
<!-- NaCl module placeholder. NaCl gets thrown into here --> </div>
<div id="loadingSpinner" class="mdl-progress mdl-js-progress mdl-progress__indeterminate"> <div id="naclSpinner" class="mdl-progress mdl-js-progress mdl-progress__indeterminate">
<h5 id="loadingMessage"></h5> <h5 id="naclSpinnerMessage"></h5>
</div> </div>
<div id="naclSpinner" class="mdl-progress mdl-js-progress mdl-progress__indeterminate">
<h5 id="naclSpinnerMessage"></h5>
</div>
</main> </main>
</div> </div>
<script defer src="static/js/jquery-2.2.0.min.js"></script> <script defer src="static/js/jquery-2.2.0.min.js"></script>
<script defer src="static/js/material.min.js"></script> <script defer src="static/js/material.min.js"></script>
<script type="text/javascript" src="static/js/messages.js"></script> <script type="text/javascript" src="static/js/messages.js"></script>
<script type="text/javascript" src="static/js/common.js"></script> <script type="text/javascript" src="static/js/common.js"></script>
<script type="text/javascript" src="static/js/index.js"></script> <script type="text/javascript" src="static/js/index.js"></script>
<script type="text/javascript" src="static/js/utils.js"></script> <script type="text/javascript" src="static/js/utils.js"></script>
<script type="text/javascript" src="static/js/mdns-browser/dns.js"></script> <script type="text/javascript" src="static/js/mdns-browser/dns.js"></script>
<script type="text/javascript" src="static/js/mdns-browser/main.js"></script> <script type="text/javascript" src="static/js/mdns-browser/main.js"></script>
<dialog id="pairingDialog" class="mdl-dialog"> <dialog id="pairingDialog" class="mdl-dialog">
<h3 class="mdl-dialog__title">Pairing</h3> <h3 class="mdl-dialog__title">Pairing</h3>
<div class="mdl-dialog__content"> <div class="mdl-dialog__content">
<p id="pairingDialogText"> <p id="pairingDialogText">
Please enter the number XXXX on the GFE dialog on the computer. This dialog will be dismissed once complete Please enter the number XXXX on the GFE dialog on the computer. This dialog will be dismissed once complete
</p> </p>
</div> </div>
<div class="mdl-dialog__actions"> <div class="mdl-dialog__actions">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelPairingDialog">Cancel</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelPairingDialog">Cancel</button>
</div> </div>
</dialog> </dialog>
<dialog id="quitAppDialog" class="mdl-dialog"> <dialog id="quitAppDialog" class="mdl-dialog">
<h3 class="mdl-dialog__title">Quit Running App?</h3> <h3 class="mdl-dialog__title">Quit Running App?</h3>
<div class="mdl-dialog__content"> <div class="mdl-dialog__content">
<p id="quitAppDialogText"> <p id="quitAppDialogText">
Y is already running. Would you like to quit Y? Y is already running. Would you like to quit Y?
</p> </p>
</div> </div>
<div class="mdl-dialog__actions"> <div class="mdl-dialog__actions">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelQuitApp">No</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelQuitApp">No</button>
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="continueQuitApp">Yes</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="continueQuitApp">Yes</button>
</div> </div>
</dialog> </dialog>
<dialog id="deleteHostDialog" class="mdl-dialog"> <dialog id="deleteHostDialog" class="mdl-dialog">
<h3 class="mdl-dialog__title">Delete PC</h3> <h3 class="mdl-dialog__title">Delete PC</h3>
<div class="mdl-dialog__content"> <div class="mdl-dialog__content">
<p id="deleteHostDialogText"> <p id="deleteHostDialogText">
Are you sure you want to delete this host? Are you sure you want to delete this host?
</p> </p>
</div> </div>
<div class="mdl-dialog__actions"> <div class="mdl-dialog__actions">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelDeleteHost">No</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelDeleteHost">No</button>
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="continueDeleteHost">Yes</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="continueDeleteHost">Yes</button>
</div> </div>
</dialog> </dialog>
<dialog id="addHostDialog" class="mdl-dialog"> <dialog id="addHostDialog" class="mdl-dialog">
<h3 class="mdl-dialog__title">Add Host Manually</h3> <h3 class="mdl-dialog__title">Add Host Manually</h3>
<div class="mdl-dialog__content"> <div class="mdl-dialog__content">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="dialogInputHost"/> <input class="mdl-textfield__input" type="text" id="dialogInputHost" />
<label class="mdl-textfield__label" for="dialogInputHost">IP Address or Hostname of Geforce PC</label> <label class="mdl-textfield__label" for="dialogInputHost">IP Address or Hostname of GeForce PC</label>
</div> </div>
</div> </div>
<div class="mdl-dialog__actions"> <div class="mdl-dialog__actions">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelAddHost">Cancel</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="cancelAddHost">Cancel</button>
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="continueAddHost">Continue</button> <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" id="continueAddHost">Continue</button>
</div> </div>
</dialog> </dialog>
<div id="snackbar" class="mdl-snackbar mdl-js-snackbar"> <div id="snackbar" class="mdl-snackbar mdl-js-snackbar">
<div class="mdl-snackbar__text"></div> <div class="mdl-snackbar__text"></div>
<button id='snackButton' class="mdl-snackbar__action" type="button"></button> <!-- this button exists to suppress the snackbar warning. we're really using a toast. --> <button id="snackButton" class="mdl-snackbar__action" type="button"></button>
</div> <!-- this button exists to suppress the snackbar warning. we're really using a toast. -->
</div>
</body> </body>
</html> </html>

250
input.cpp
View File

@@ -1,13 +1,22 @@
#include "moonlight.hpp" #include "moonlight.hpp"
#include "ppapi/c/ppb_input_event.h" #include "ppapi/c/ppb_input_event.h"
#include "ppapi/cpp/mouse_cursor.h"
#include "ppapi/cpp/input_event.h" #include "ppapi/cpp/input_event.h"
#include <Limelight.h> #include <Limelight.h>
#include <math.h>
#define KEY_PREFIX 0x80 #define KEY_PREFIX 0x80
#define TOUCH_DEAD_ZONE_DELAY 0.250
#define TOUCH_DEAD_ZONE_RADIUS 50
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
static int ConvertPPButtonToLiButton(PP_InputEvent_MouseButton ppButton) { static int ConvertPPButtonToLiButton(PP_InputEvent_MouseButton ppButton) {
switch (ppButton) { switch (ppButton) {
case PP_INPUTEVENT_MOUSEBUTTON_LEFT: case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
@@ -21,12 +30,35 @@ static int ConvertPPButtonToLiButton(PP_InputEvent_MouseButton ppButton) {
} }
} }
void MoonlightInstance::LockMouseOrJustCaptureInput() {
if (m_MouseLockingFeatureEnabled) {
LockMouse(m_CallbackFactory.NewCallback(&MoonlightInstance::DidLockMouse));
}
else {
pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_NONE);
}
// Assume it worked until we get a callback telling us otherwise;
// if not locking mouse this just serves to tell us whether to capture input
m_MouseLocked = true;
}
void MoonlightInstance::UnlockMouseOrJustReleaseInput() {
if (m_MouseLockingFeatureEnabled) {
UnlockMouse();
} else {
pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_POINTER);
}
m_MouseLocked = false;
m_WaitingForAllModifiersUp = false;
}
void MoonlightInstance::DidLockMouse(int32_t result) { void MoonlightInstance::DidLockMouse(int32_t result) {
m_MouseLocked = (result == PP_OK); m_MouseLocked = (result == PP_OK);
if (m_MouseLocked) { if (m_MouseLocked) {
// Request an IDR frame to dump the frame queue that may have // Request an IDR frame to dump the frame queue that may have
// built up from the GL pipeline being stalled. // built up from the GL pipeline being stalled.
g_Instance->m_RequestIdrFrame = true; LiRequestIdrFrame();
} }
} }
@@ -51,15 +83,138 @@ static char GetModifierFlags(const pp::InputEvent& event) {
return flags; return flags;
} }
static uint32_t GetTranslatedKeyCode(const pp::KeyboardInputEvent& event) {
// For some reason, NaCl won't give us the real left and right
// VK codes for modifiers and instead gives us modifier flags
// to indicate whether the key is left or right. We have to
// convert these back to the original VK codes to before
// sending them to the PC.
switch (event.GetKeyCode()) {
// VK_SHIFT
case 0x10:
if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISLEFT) {
// VK_LSHIFT
return 0xA0;
}
else if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISRIGHT) {
// VK_RSHIFT
return 0xA1;
}
break;
// VK_CONTROL
case 0x11:
if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISLEFT) {
// VK_LCONTROL
return 0xA2;
}
else if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISRIGHT) {
// VK_RCONTROL
return 0xA3;
}
break;
// VK_MENU (Alt)
case 0x12:
if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISLEFT) {
// VK_LMENU
return 0xA4;
}
else if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISRIGHT) {
// VK_RMENU
return 0xA5;
}
break;
default:
break;
}
// We have to handle the ISKEYPAD modifier on macOS, and convert them
// to the correct numpad keycodes for Windows.
int32_t num = event.GetKeyCode() - 0x30;
if ((event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISKEYPAD) &&
num >= 0 && num <= 9) {
// Offset with numpad 0's virtual keycode
return num + 0x60;
}
return event.GetKeyCode();
}
void MoonlightInstance::ReportMouseMovement() {
if (m_MouseDeltaX != 0 || m_MouseDeltaY != 0) {
LiSendMouseMoveEvent(m_MouseDeltaX, m_MouseDeltaY);
m_MouseDeltaX = m_MouseDeltaY = 0;
} else if (m_MousePositionX != 0 || m_MousePositionY != 0) {
// Clamp the input coordinates to the plugin area
short x = MIN(MAX(m_MousePositionX, 0), m_PluginRect.width());
short y = MIN(MAX(m_MousePositionY, 0), m_PluginRect.height());
LiSendMousePositionEvent(x, y, m_PluginRect.width(), m_PluginRect.height());
m_MousePositionX = 0;
m_MousePositionY = 0;
}
if (m_AccumulatedTicks != 0) {
// We can have fractional ticks here, so multiply by WHEEL_DELTA
// to get actual scroll distance and use the high-res variant.
LiSendHighResScrollEvent(m_AccumulatedTicks * 120);
m_AccumulatedTicks = 0;
}
}
bool MoonlightInstance::TryHandleNativeTouchEvent(const pp::InputEvent& event) {
// Check if the host supports native pen/touch events
if (!(LiGetHostFeatureFlags() & LI_FF_PEN_TOUCH_EVENTS)) {
return false;
}
uint8_t eventType;
switch (event.GetType()) {
case PP_INPUTEVENT_TYPE_TOUCHSTART:
eventType = LI_TOUCH_EVENT_DOWN;
break;
case PP_INPUTEVENT_TYPE_TOUCHMOVE:
eventType = LI_TOUCH_EVENT_MOVE;
break;
case PP_INPUTEVENT_TYPE_TOUCHEND:
eventType = LI_TOUCH_EVENT_UP;
break;
case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
eventType = LI_TOUCH_EVENT_CANCEL;
break;
default:
// Not a touch event
return false;
}
pp::TouchInputEvent touchEvent(event);
uint32_t count = touchEvent.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
for (uint32_t i = 0; i < count; i++) {
pp::TouchPoint touchPoint = touchEvent.GetTouchByIndex(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, i);
pp::FloatPoint touchPos = touchPoint.position();
LiSendTouchEvent(eventType, touchPoint.id(),
MIN(MAX(touchPos.x(), 0), m_PluginRect.width()) / m_PluginRect.width(),
MIN(MAX(touchPos.y(), 0), m_PluginRect.height()) / m_PluginRect.height(),
touchPoint.pressure(),
0.0f, 0.0f,
touchPoint.rotation_angle());
}
return true;
}
bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) { bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
// If the host can handle native touch events, send them natively
if (TryHandleNativeTouchEvent(event)) {
return true;
}
switch (event.GetType()) { switch (event.GetType()) {
case PP_INPUTEVENT_TYPE_MOUSEDOWN: { case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
// Lock the mouse cursor when the user clicks on the stream // Lock the mouse cursor when the user clicks on the stream
if (!m_MouseLocked) { if (!m_MouseLocked) {
LockMouse(m_CallbackFactory.NewCallback(&MoonlightInstance::DidLockMouse)); LockMouseOrJustCaptureInput();
// Assume it worked until we get a callback telling us otherwise
m_MouseLocked = true;
return true; return true;
} }
@@ -73,11 +228,23 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
if (!m_MouseLocked) { if (!m_MouseLocked) {
return false; return false;
} }
pp::MouseInputEvent mouseEvent(event); pp::MouseInputEvent mouseEvent(event);
pp::Point posDelta = mouseEvent.GetMovement(); pp::Point posDelta = mouseEvent.GetMovement();
pp::Point position = mouseEvent.GetPosition();
// Wait to report mouse movement until the next input polling window
// to allow batching to occur which reduces overall input lag.
if (m_MouseLocked) {
if (m_MouseLockingFeatureEnabled) {
m_MouseDeltaX += posDelta.x();
m_MouseDeltaY += posDelta.y();
} else {
m_MousePositionX = position.x();
m_MousePositionY = position.y();
}
}
LiSendMouseMoveEvent(posDelta.x(), posDelta.y());
return true; return true;
} }
@@ -93,8 +260,6 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
} }
case PP_INPUTEVENT_TYPE_WHEEL: { case PP_INPUTEVENT_TYPE_WHEEL: {
signed char fullTicks;
if (!m_MouseLocked) { if (!m_MouseLocked) {
return false; return false;
} }
@@ -103,15 +268,6 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
// Accumulate the current tick value // Accumulate the current tick value
m_AccumulatedTicks += wheelEvent.GetTicks().y(); m_AccumulatedTicks += wheelEvent.GetTicks().y();
// Compute the number of full ticks
fullTicks = (signed char) m_AccumulatedTicks;
// Send a scroll event if we've completed a full tick
if (fullTicks != 0) {
LiSendScrollEvent(fullTicks);
m_AccumulatedTicks -= fullTicks;
}
return true; return true;
} }
@@ -122,9 +278,10 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
pp::KeyboardInputEvent keyboardEvent(event); pp::KeyboardInputEvent keyboardEvent(event);
char modifiers = GetModifierFlags(event); char modifiers = GetModifierFlags(event);
uint32_t keyCode = GetTranslatedKeyCode(keyboardEvent);
if (modifiers == (MODIFIER_ALT | MODIFIER_CTRL | MODIFIER_SHIFT)) { if (modifiers == (MODIFIER_ALT | MODIFIER_CTRL | MODIFIER_SHIFT)) {
if (keyboardEvent.GetKeyCode() == 0x51) { // Q key if (keyCode == 0x51) { // Q key
// Terminate the connection // Terminate the connection
StopConnection(); StopConnection();
return true; return true;
@@ -135,33 +292,74 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
} }
} }
LiSendKeyboardEvent(KEY_PREFIX << 8 | keyboardEvent.GetKeyCode(), if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
return true;
}
LiSendKeyboardEvent(KEY_PREFIX << 8 | keyCode,
KEY_ACTION_DOWN, modifiers); KEY_ACTION_DOWN, modifiers);
return true; return true;
} }
case PP_INPUTEVENT_TYPE_KEYUP: { case PP_INPUTEVENT_TYPE_KEYUP: {
if (!m_MouseLocked) { if (!m_MouseLocked) {
return false; return false;
} }
pp::KeyboardInputEvent keyboardEvent(event); pp::KeyboardInputEvent keyboardEvent(event);
char modifiers = GetModifierFlags(event); char modifiers = GetModifierFlags(event);
uint32_t keyCode = GetTranslatedKeyCode(keyboardEvent);
// Check if all modifiers are up now // Check if all modifiers are up now
if (m_WaitingForAllModifiersUp && modifiers == 0) { if (m_WaitingForAllModifiersUp && modifiers == 0) {
UnlockMouse(); UnlockMouseOrJustReleaseInput();
m_MouseLocked = false;
m_WaitingForAllModifiersUp = false;
} }
LiSendKeyboardEvent(KEY_PREFIX << 8 | keyboardEvent.GetKeyCode(), LiSendKeyboardEvent(KEY_PREFIX << 8 | keyCode,
KEY_ACTION_UP, modifiers); KEY_ACTION_UP, modifiers);
return true; return true;
} }
case PP_INPUTEVENT_TYPE_TOUCHMOVE:
case PP_INPUTEVENT_TYPE_TOUCHSTART: {
pp::TouchInputEvent touchEvent(event);
pp::FloatPoint touchPoint = touchEvent.GetTouchByIndex(PP_TOUCHLIST_TYPE_TARGETTOUCHES, 0).position();
// Create a small deadzone for touch downs to allow more precise double-clicks
if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHMOVE ||
event.GetTimeStamp() - m_LastTouchUpTime > TOUCH_DEAD_ZONE_DELAY ||
sqrt(pow(m_LastTouchUpPoint.x() - touchPoint.x(), 2) +
pow(m_LastTouchUpPoint.y() - touchPoint.y(), 2)) > TOUCH_DEAD_ZONE_RADIUS) {
// Scale the touch coordinates to the video rect
short x = MIN(MAX(touchPoint.x(), 0), m_PluginRect.width());
short y = MIN(MAX(touchPoint.y(), 0), m_PluginRect.height());
// Update the mouse position prior to sending the button down
LiSendMousePositionEvent(x, y, m_PluginRect.width(), m_PluginRect.height());
}
if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHSTART &&
touchEvent.GetTouchCount(PP_TOUCHLIST_TYPE_TARGETTOUCHES) == 1) {
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
}
return true;
}
case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
case PP_INPUTEVENT_TYPE_TOUCHEND: {
pp::TouchInputEvent touchEvent(event);
if (touchEvent.GetTouchCount(PP_TOUCHLIST_TYPE_TARGETTOUCHES) == 1) {
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
m_LastTouchUpTime = event.GetTimeStamp();
m_LastTouchUpPoint = touchEvent.GetTouchByIndex(PP_TOUCHLIST_TYPE_TARGETTOUCHES, 0).position();
}
return true;
}
default: { default: {
return false; return false;
} }
} }
} }

View File

@@ -1,5 +1,6 @@
#include <sys/timeb.h> #include <sys/timeb.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdlib.h>
// This function is defined but not implemented by newlib // This function is defined but not implemented by newlib
int ftime(struct timeb *tp) { int ftime(struct timeb *tp) {
@@ -15,4 +16,11 @@ int ftime(struct timeb *tp) {
tp->dstflag = 0; tp->dstflag = 0;
return 0; return 0;
} }
// This function is required for libcurl to link but never
// called using by any of the APIs we use
unsigned alarm(unsigned seconds) {
abort();
return 0;
}

View File

@@ -27,3 +27,4 @@
#define GS_IO_ERROR -5 #define GS_IO_ERROR -5
#define GS_NOT_SUPPORTED_4K -6 #define GS_NOT_SUPPORTED_4K -6
#define GS_CERT_MISMATCH -100

View File

@@ -59,7 +59,7 @@ static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
return CURLE_OK; return CURLE_OK;
} }
int http_request(char* url, PHTTP_DATA data) { int http_request(const char* url, const char* ppkstr, PHTTP_DATA data) {
int ret; int ret;
CURL *curl; CURL *curl;
@@ -67,12 +67,7 @@ int http_request(char* url, PHTTP_DATA data) {
if (!curl) if (!curl)
return GS_FAILED; return GS_FAILED;
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_CAINFO, "/curl/ca-bundle.crt");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L);
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_curl); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_curl);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function); curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
@@ -80,11 +75,19 @@ int http_request(char* url, PHTTP_DATA data) {
curl_easy_setopt(curl, CURLOPT_MAXCONNECTS, 0L); curl_easy_setopt(curl, CURLOPT_MAXCONNECTS, 0L);
curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L); curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L);
curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L); curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
// Use the pinned certificate for HTTPS
if (ppkstr != NULL) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, ppkstr);
}
if (data->size > 0) { if (data->size > 0) {
free(data->memory); free(data->memory);
data->memory = malloc(1); data->memory = malloc(1);
@@ -97,8 +100,12 @@ int http_request(char* url, PHTTP_DATA data) {
} }
CURLcode res = curl_easy_perform(curl); CURLcode res = curl_easy_perform(curl);
printf("CURL: %s (PPK: '%s') -> %s\n", url, ppkstr ? ppkstr : "<NULL>", curl_easy_strerror(res));
if(res != CURLE_OK) { if (res == CURLE_SSL_PINNEDPUBKEYNOTMATCH) {
ret = GS_CERT_MISMATCH;
} else if (res != CURLE_OK) {
ret = GS_FAILED; ret = GS_FAILED;
} else if (data->memory == NULL) { } else if (data->memory == NULL) {
ret = GS_OUT_OF_MEMORY; ret = GS_OUT_OF_MEMORY;

View File

@@ -31,7 +31,7 @@ typedef struct _HTTP_DATA {
} HTTP_DATA, *PHTTP_DATA; } HTTP_DATA, *PHTTP_DATA;
PHTTP_DATA http_create_data(); PHTTP_DATA http_create_data();
int http_request(char* url, PHTTP_DATA data); int http_request(const char* url, const char* ppkstr, PHTTP_DATA data);
void http_free_data(PHTTP_DATA data); void http_free_data(PHTTP_DATA data);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -127,14 +127,8 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
* subject. * subject.
*/ */
X509_set_issuer_name(x, name); X509_set_issuer_name(x, name);
/* Add various extensions: standard extensions */ if (!X509_sign(x, pk, EVP_sha256())) {
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; goto err;
} }
@@ -144,30 +138,4 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
return(1); return(1);
err: err:
return(0); 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

@@ -54,11 +54,13 @@ static int xml_search(char* data, size_t len, char* node, char** result) {
startOffset = strstr(data, startTag); startOffset = strstr(data, startTag);
if (startOffset == NULL) { if (startOffset == NULL) {
free(data);
return GS_FAILED; return GS_FAILED;
} }
endOffset = strstr(data, endTag); endOffset = strstr(data, endTag);
if (endOffset == NULL) { if (endOffset == NULL) {
free(data);
return GS_FAILED; return GS_FAILED;
} }
@@ -67,6 +69,7 @@ static int xml_search(char* data, size_t len, char* node, char** result) {
*result = malloc(strlen(startOffset + strlen(startTag)) + 1); *result = malloc(strlen(startOffset + strlen(startTag)) + 1);
strcpy(*result, startOffset + strlen(startTag)); strcpy(*result, startOffset + strlen(startTag));
free(data);
return GS_OK; return GS_OK;
} }
@@ -126,115 +129,283 @@ cleanup:
return result; return result;
} }
int gs_pair(int serverMajorVersion, const char* address, const char* pin) { static bool verifySignature(const unsigned char *data, int dataLength, unsigned char *signature, int signatureLength, X509 *cert) {
int ret = GS_OK; EVP_PKEY* pubKey = X509_get_pubkey(cert);
char url[4096]; EVP_MD_CTX *mdctx = NULL;
mdctx = EVP_MD_CTX_create();
EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pubKey);
EVP_DigestVerifyUpdate(mdctx, data, dataLength);
int result = EVP_DigestVerifyFinal(mdctx, signature, signatureLength);
EVP_PKEY_free(pubKey);
EVP_MD_CTX_destroy(mdctx);
unsigned char salt_data[16]; return result > 0;
char salt_hex[33]; }
RAND_bytes(salt_data, 16);
bytes_to_hex(salt_data, salt_hex, 16); X509* get_cert(PHTTP_DATA data) {
char *pemcerthex;
sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", address, g_UniqueId, salt_hex, g_CertHex);
PHTTP_DATA data = http_create_data(); if (xml_search(data->memory, data->size, "plaincert", &pemcerthex) != GS_OK)
if (data == NULL) return NULL;
return GS_OUT_OF_MEMORY;
else if ((ret = http_request(url, data)) != GS_OK) // Convert cert from hex string to the PEM string and null terminate
goto cleanup; int hexstrlen = strlen(pemcerthex);
char *pemcert = malloc(hexstrlen / 2 + 1);
unsigned char salt_pin[20]; for (int count = 0; count < hexstrlen; count += 2) {
unsigned char aes_key_hash[32]; sscanf(&pemcerthex[count], "%2hhx", &pemcert[count / 2]);
AES_KEY enc_key, dec_key;
memcpy(salt_pin, salt_data, 16);
memcpy(salt_pin+16, pin, 4);
int hash_length = serverMajorVersion >= 7 ? 32 : 20;
if (serverMajorVersion >= 7)
SHA256(salt_pin, 20, aes_key_hash);
else
SHA1(salt_pin, 20, aes_key_hash);
AES_set_encrypt_key((unsigned char *)aes_key_hash, 128, &enc_key);
AES_set_decrypt_key((unsigned char *)aes_key_hash, 128, &dec_key);
unsigned char challenge_data[16];
unsigned char challenge_enc[16];
char challenge_hex[33];
RAND_bytes(challenge_data, 16);
AES_encrypt(challenge_data, challenge_enc, &enc_key);
bytes_to_hex(challenge_enc, challenge_hex, 16);
sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientchallenge=%s", address, g_UniqueId, challenge_hex);
if ((ret = http_request(url, data)) != GS_OK)
goto cleanup;
char *result;
if (xml_search(data->memory, data->size, "challengeresponse", &result) != GS_OK) {
ret = GS_INVALID;
goto cleanup;
} }
pemcert[hexstrlen / 2] = 0;
unsigned char challenge_response_data_enc[48]; free(pemcerthex);
unsigned char challenge_response_data[48];
for (int count = 0; count < strlen(result); count += 2) { // pemcert is referenced, but NOT copied!
sscanf(&result[count], "%2hhx", &challenge_response_data_enc[count / 2]); BIO* bio = BIO_new_mem_buf(pemcert, -1);
if (bio) {
X509* cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
BIO_free_all(bio);
free(pemcert);
return cert;
} }
free(result); else {
free(pemcert);
for (int i = 0; i < 48; i += 16) { return NULL;
AES_decrypt(&challenge_response_data_enc[i], &challenge_response_data[i], &dec_key);
} }
}
unsigned char client_secret_data[16];
RAND_bytes(client_secret_data, 16); static char* x509_to_curl_ppk_string(X509* x509) {
BIO* bio = BIO_new(BIO_s_mem());
unsigned char challenge_response[16 + 256 + 16];
unsigned char challenge_response_hash[32]; // Get x509 public key alone in DER format
unsigned char challenge_response_hash_enc[32]; EVP_PKEY* pubkey = X509_get_pubkey(x509);
char challenge_response_hex[65]; i2d_PUBKEY_bio(bio, pubkey);
memcpy(challenge_response, challenge_response_data + hash_length, 16); EVP_PKEY_free(pubkey);
memcpy(challenge_response + 16, g_Cert->signature->data, 256);
memcpy(challenge_response + 16 + 256, client_secret_data, 16); BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
if (serverMajorVersion >= 7)
SHA256(challenge_response, 16 + 256 + 16, challenge_response_hash); // SHA256 hash the resulting DER string
else unsigned char pubkeyhash[32];
SHA1(challenge_response, 16 + 256 + 16, challenge_response_hash); SHA256((unsigned char*)mem->data, mem->length, pubkeyhash);
BIO_free(bio);
for (int i = 0; i < 32; i += 16) {
AES_encrypt(&challenge_response_hash[i], &challenge_response_hash_enc[i], &enc_key); // Base64-encode the resulting SHA256 hash
} bio = BIO_new(BIO_s_mem());
bytes_to_hex(challenge_response_hash_enc, challenge_response_hex, 32); BIO* b64 = BIO_new(BIO_f_base64());
bio = BIO_push(b64, bio);
sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", address, g_UniqueId, challenge_response_hex); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
if ((ret = http_request(url, data)) != GS_OK) BIO_write(bio, pubkeyhash, sizeof(pubkeyhash));
goto cleanup; BIO_flush(bio);
if (xml_search(data->memory, data->size, "pairingsecret", &result) != GS_OK) { BIO_get_mem_ptr(bio, &mem);
ret = GS_INVALID;
goto cleanup; // Assemble the final curl PPK string
} const char* prefix = "sha256//";
char* ret = malloc(strlen(prefix) + mem->length + 1);
unsigned char *signature = NULL; memcpy(ret, prefix, strlen(prefix));
size_t s_len; memcpy(&ret[strlen(prefix)], mem->data, mem->length);
if (sign_it(client_secret_data, 16, &signature, &s_len, g_PrivateKey) != GS_OK) { ret[strlen(prefix) + mem->length] = 0;
gs_error = "Failed to sign data";
ret = GS_FAILED; BIO_free_all(bio);
goto cleanup;
}
unsigned char client_pairing_secret[16 + 256];
char client_pairing_secret_hex[(16 + 256) * 2 + 1];
memcpy(client_pairing_secret, client_secret_data, 16);
memcpy(client_pairing_secret + 16, signature, 256);
bytes_to_hex(client_pairing_secret, client_pairing_secret_hex, 16 + 256);
sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", address, g_UniqueId, client_pairing_secret_hex);
if ((ret = http_request(url, data)) != GS_OK)
goto cleanup;
cleanup:
http_free_data(data);
return ret; return ret;
}
int gs_unpair(const char* address) {
int ret = GS_OK;
char url[4096];
PHTTP_DATA data = http_create_data();
if (data == NULL)
return GS_OUT_OF_MEMORY;
snprintf(url, sizeof(url), "http://%s:47989/unpair?uniqueid=%s", address, g_UniqueId);
ret = http_request(url, NULL, data);
http_free_data(data);
return ret;
}
int gs_pair(int serverMajorVersion, const char* address, const char* pin, char** curl_ppk_string) {
int ret = GS_OK;
char* result = NULL;
X509* server_cert = NULL;
char url[4096];
unsigned char salt_data[16];
char salt_hex[33];
RAND_bytes(salt_data, 16);
bytes_to_hex(salt_data, salt_hex, 16);
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", address, g_UniqueId, salt_hex, g_CertHex);
PHTTP_DATA data = http_create_data();
if (data == NULL)
return GS_OUT_OF_MEMORY;
else if ((ret = http_request(url, NULL, data)) != GS_OK)
goto cleanup;
if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
goto cleanup;
if (strcmp(result, "1") != 0) {
ret = GS_FAILED;
goto cleanup;
}
free(result);
result = NULL;
server_cert = get_cert(data);
if (server_cert == NULL) {
ret = GS_FAILED;
goto cleanup;
}
unsigned char salt_pin[20];
unsigned char aes_key_hash[32];
AES_KEY enc_key, dec_key;
memcpy(salt_pin, salt_data, 16);
memcpy(salt_pin+16, pin, 4);
int hash_length = serverMajorVersion >= 7 ? 32 : 20;
if (serverMajorVersion >= 7)
SHA256(salt_pin, 20, aes_key_hash);
else
SHA1(salt_pin, 20, aes_key_hash);
AES_set_encrypt_key((unsigned char *)aes_key_hash, 128, &enc_key);
AES_set_decrypt_key((unsigned char *)aes_key_hash, 128, &dec_key);
unsigned char challenge_data[16];
unsigned char challenge_enc[16];
char challenge_hex[33];
RAND_bytes(challenge_data, 16);
AES_encrypt(challenge_data, challenge_enc, &enc_key);
bytes_to_hex(challenge_enc, challenge_hex, 16);
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientchallenge=%s", address, g_UniqueId, challenge_hex);
if ((ret = http_request(url, NULL, data)) != GS_OK)
goto cleanup;
free(result);
result = NULL;
if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
goto cleanup;
if (strcmp(result, "1") != 0) {
ret = GS_FAILED;
goto cleanup;
}
free(result);
result = NULL;
if (xml_search(data->memory, data->size, "challengeresponse", &result) != GS_OK) {
ret = GS_INVALID;
goto cleanup;
}
unsigned char challenge_response_data_enc[48];
unsigned char challenge_response_data[48];
for (int count = 0; count < strlen(result); count += 2) {
sscanf(&result[count], "%2hhx", &challenge_response_data_enc[count / 2]);
}
for (int i = 0; i < 48; i += 16) {
AES_decrypt(&challenge_response_data_enc[i], &challenge_response_data[i], &dec_key);
}
unsigned char client_secret_data[16];
RAND_bytes(client_secret_data, 16);
ASN1_BIT_STRING *asnSignature;
X509_get0_signature(&asnSignature, NULL, g_Cert);
unsigned char challenge_response[16 + 256 + 16];
unsigned char challenge_response_hash[32];
unsigned char challenge_response_hash_enc[32];
char challenge_response_hex[65];
memcpy(challenge_response, challenge_response_data + hash_length, 16);
memcpy(challenge_response + 16, asnSignature->data, 256);
memcpy(challenge_response + 16 + 256, client_secret_data, 16);
if (serverMajorVersion >= 7)
SHA256(challenge_response, 16 + 256 + 16, challenge_response_hash);
else
SHA1(challenge_response, 16 + 256 + 16, challenge_response_hash);
for (int i = 0; i < 32; i += 16) {
AES_encrypt(&challenge_response_hash[i], &challenge_response_hash_enc[i], &enc_key);
}
bytes_to_hex(challenge_response_hash_enc, challenge_response_hex, 32);
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", address, g_UniqueId, challenge_response_hex);
if ((ret = http_request(url, NULL, data)) != GS_OK)
goto cleanup;
free(result);
result = NULL;
if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
goto cleanup;
if (strcmp(result, "1") != 0) {
ret = GS_FAILED;
goto cleanup;
}
free(result);
result = NULL;
if (xml_search(data->memory, data->size, "pairingsecret", &result) != GS_OK) {
ret = GS_INVALID;
goto cleanup;
}
unsigned char pairing_secret[16 + 256];
for (int count = 0; count < strlen(result); count += 2) {
sscanf(&result[count], "%2hhx", &pairing_secret[count / 2]);
}
if (!verifySignature(pairing_secret, 16, pairing_secret+16, 256, server_cert)) {
ret = GS_FAILED;
goto cleanup;
}
unsigned char *signature = NULL;
size_t s_len;
if (sign_it(client_secret_data, 16, &signature, &s_len, g_PrivateKey) != GS_OK) {
ret = GS_FAILED;
goto cleanup;
}
unsigned char client_pairing_secret[16 + 256];
char client_pairing_secret_hex[(16 + 256) * 2 + 1];
memcpy(client_pairing_secret, client_secret_data, 16);
memcpy(client_pairing_secret + 16, signature, 256);
bytes_to_hex(client_pairing_secret, client_pairing_secret_hex, 16 + 256);
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", address, g_UniqueId, client_pairing_secret_hex);
if ((ret = http_request(url, NULL, data)) != GS_OK)
goto cleanup;
free(result);
result = NULL;
if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
goto cleanup;
if (strcmp(result, "1") != 0) {
ret = GS_FAILED;
goto cleanup;
}
*curl_ppk_string = x509_to_curl_ppk_string(server_cert);
cleanup:
if (ret != GS_OK)
gs_unpair(address);
if (result != NULL)
free(result);
if (server_cert != NULL)
X509_free(server_cert);
http_free_data(data);
return ret;
} }

View File

@@ -23,7 +23,7 @@
extern "C" { extern "C" {
#endif #endif
int gs_pair(int serverMajorVersion, const char* address, const char* pin); int gs_pair(int serverMajorVersion, const char* address, const char* pin, char** server_cert_der_string);
#ifdef __cplusplus #ifdef __cplusplus
} }

121
main.cpp
View File

@@ -10,20 +10,20 @@
#include "ppapi/cpp/input_event.h" #include "ppapi/cpp/input_event.h"
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
// Requests the NaCl module to connection to the server specified after the : // Requests the NaCl module to connection to the server specified after the :
#define MSG_START_REQUEST "startRequest" #define MSG_START_REQUEST "startRequest"
// Requests the NaCl module stop streaming // Requests the NaCl module stop streaming
#define MSG_STOP_REQUEST "stopRequest" #define MSG_STOP_REQUEST "stopRequest"
// Sent by the NaCl module when the stream has stopped whether user-requested or not // Sent by the NaCl module when the stream has stopped whether user-requested or not
#define MSG_STREAM_TERMINATED "streamTerminated" #define MSG_STREAM_TERMINATED "streamTerminated: "
#define MSG_OPENURL "openUrl" #define MSG_OPENURL "openUrl"
MoonlightInstance* g_Instance; MoonlightInstance* g_Instance;
MoonlightInstance::~MoonlightInstance() {}
class MoonlightModule : public pp::Module { class MoonlightModule : public pp::Module {
public: public:
MoonlightModule() : pp::Module() {} MoonlightModule() : pp::Module() {}
@@ -40,7 +40,7 @@ void MoonlightInstance::OnConnectionStarted(uint32_t unused) {
PostMessage(response); PostMessage(response);
// Start receiving input events // Start receiving input events
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_TOUCH);
// Filtering is suboptimal but it ensures that we can pass keyboard events // Filtering is suboptimal but it ensures that we can pass keyboard events
// to the browser when mouse lock is disabled. This is neccessary for Esc // to the browser when mouse lock is disabled. This is neccessary for Esc
@@ -53,13 +53,16 @@ void MoonlightInstance::OnConnectionStopped(uint32_t error) {
m_Running = false; m_Running = false;
// Stop receiving input events // Stop receiving input events
ClearInputEventRequest(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_KEYBOARD); ClearInputEventRequest(PP_INPUTEVENT_CLASS_MOUSE |
PP_INPUTEVENT_CLASS_WHEEL |
PP_INPUTEVENT_CLASS_KEYBOARD |
PP_INPUTEVENT_CLASS_TOUCH);
// Unlock the mouse // Unlock the mouse
UnlockMouse(); UnlockMouseOrJustReleaseInput();
// Notify the JS code that the stream has ended // Notify the JS code that the stream has ended
pp::Var response(MSG_STREAM_TERMINATED); pp::Var response(std::string(MSG_STREAM_TERMINATED) + std::to_string((int)error));
PostMessage(response); PostMessage(response);
} }
@@ -80,26 +83,35 @@ void* MoonlightInstance::StopThreadFunc(void* context) {
// not be invoked during LiStartConnection. // not be invoked during LiStartConnection.
pthread_join(g_Instance->m_ConnectionThread, NULL); pthread_join(g_Instance->m_ConnectionThread, NULL);
// Force raise all modifier keys to avoid leaving them down after disconnecting
LiSendKeyboardEvent(0xA0, KEY_ACTION_UP, 0);
LiSendKeyboardEvent(0xA1, KEY_ACTION_UP, 0);
LiSendKeyboardEvent(0xA2, KEY_ACTION_UP, 0);
LiSendKeyboardEvent(0xA3, KEY_ACTION_UP, 0);
LiSendKeyboardEvent(0xA4, KEY_ACTION_UP, 0);
LiSendKeyboardEvent(0xA5, KEY_ACTION_UP, 0);
// Not running anymore // Not running anymore
g_Instance->m_Running = false; g_Instance->m_Running = false;
// We also need to stop this thread after the connection thread, because it depends // We also need to stop this thread after the connection thread, because it depends
// on being initialized there. // on being initialized there.
pthread_join(g_Instance->m_GamepadThread, NULL); pthread_join(g_Instance->m_InputThread, NULL);
// Stop the connection // Stop the connection
LiStopConnection(); LiStopConnection();
return NULL; return NULL;
} }
void* MoonlightInstance::GamepadThreadFunc(void* context) { void* MoonlightInstance::InputThreadFunc(void* context) {
MoonlightInstance* me = (MoonlightInstance*)context; MoonlightInstance* me = (MoonlightInstance*)context;
while (me->m_Running) { while (me->m_Running) {
me->PollGamepads(); me->PollGamepads();
me->ReportMouseMovement();
// Poll every 10 ms // Poll every 5 ms
usleep(10 * 1000); usleep(5 * 1000);
} }
return NULL; return NULL;
@@ -117,16 +129,22 @@ void* MoonlightInstance::ConnectionThreadFunc(void* context) {
LiInitializeServerInformation(&serverInfo); LiInitializeServerInformation(&serverInfo);
serverInfo.address = me->m_Host.c_str(); serverInfo.address = me->m_Host.c_str();
serverInfo.serverInfoAppVersion = me->m_AppVersion.c_str(); serverInfo.serverInfoAppVersion = me->m_AppVersion.c_str();
serverInfo.serverInfoGfeVersion = me->m_GfeVersion.c_str();
serverInfo.rtspSessionUrl = me->m_RtspUrl.c_str();
serverInfo.serverCodecModeSupport = SCM_H264;
err = LiStartConnection(&serverInfo, err = LiStartConnection(&serverInfo,
&me->m_StreamConfig, &me->m_StreamConfig,
&MoonlightInstance::s_ClCallbacks, &MoonlightInstance::s_ClCallbacks,
&MoonlightInstance::s_DrCallbacks, &MoonlightInstance::s_DrCallbacks,
&MoonlightInstance::s_ArCallbacks, &MoonlightInstance::s_ArCallbacks,
NULL, 0,
NULL, 0); NULL, 0);
if (err != 0) { if (err != 0) {
// Notify the JS code that the stream has ended // Notify the JS code that the stream has ended
pp::Var response(MSG_STREAM_TERMINATED); // NB: We pass error code 0 here to avoid triggering a "Connection terminated"
// warning message.
pp::Var response(MSG_STREAM_TERMINATED + std::to_string(0));
me->PostMessage(response); me->PostMessage(response);
return NULL; return NULL;
} }
@@ -134,7 +152,7 @@ void* MoonlightInstance::ConnectionThreadFunc(void* context) {
// Set running state before starting connection-specific threads // Set running state before starting connection-specific threads
me->m_Running = true; me->m_Running = true;
pthread_create(&me->m_GamepadThread, NULL, MoonlightInstance::GamepadThreadFunc, me); pthread_create(&me->m_InputThread, NULL, MoonlightInstance::InputThreadFunc, me);
return NULL; return NULL;
} }
@@ -162,6 +180,8 @@ void MoonlightInstance::HandleMessage(const pp::Var& var_message) {
MakeCert(callbackId, params); MakeCert(callbackId, params);
} else if (strcmp(method.c_str(), "pair") == 0) { } else if (strcmp(method.c_str(), "pair") == 0) {
HandlePair(callbackId, params); HandlePair(callbackId, params);
} else if (strcmp(method.c_str(), "STUN") == 0) {
HandleSTUN(callbackId, params);
} else { } else {
pp::Var response("Unhandled message received: " + method); pp::Var response("Unhandled message received: " + method);
PostMessage(response); PostMessage(response);
@@ -182,7 +202,10 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
std::string bitrate = args.Get(4).AsString(); std::string bitrate = args.Get(4).AsString();
std::string rikey = args.Get(5).AsString(); std::string rikey = args.Get(5).AsString();
std::string rikeyid = args.Get(6).AsString(); std::string rikeyid = args.Get(6).AsString();
std::string appversion = args.Get(7).AsString(); std::string mouse_lock = args.Get(7).AsString();
std::string appversion = args.Get(8).AsString();
std::string gfeversion = args.Get(9).AsString();
std::string rtspurl = args.Get(10).AsString();
pp::Var response("Setting stream width to: " + width); pp::Var response("Setting stream width to: " + width);
PostMessage(response); PostMessage(response);
@@ -200,6 +223,12 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
PostMessage(response); PostMessage(response);
response = ("Setting appversion to: " + appversion); response = ("Setting appversion to: " + appversion);
PostMessage(response); PostMessage(response);
response = ("Setting gfeversion to: " + gfeversion);
PostMessage(response);
response = ("Setting mouse lock to: " + mouse_lock);
PostMessage(response);
response = ("Setting RTSP URL to: " + rtspurl);
PostMessage(response);
// Populate the stream configuration // Populate the stream configuration
LiInitializeStreamConfiguration(&m_StreamConfig); LiInitializeStreamConfiguration(&m_StreamConfig);
@@ -207,15 +236,15 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
m_StreamConfig.height = stoi(height); m_StreamConfig.height = stoi(height);
m_StreamConfig.fps = stoi(fps); m_StreamConfig.fps = stoi(fps);
m_StreamConfig.bitrate = stoi(bitrate); // kilobits per second m_StreamConfig.bitrate = stoi(bitrate); // kilobits per second
m_StreamConfig.streamingRemotely = 0;
m_StreamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO; m_StreamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO;
m_StreamConfig.streamingRemotely = STREAM_CFG_AUTO;
// The overhead of receiving a packet is much higher in NaCl because we must
// pass through various layers of abstraction on each recv() call. We're using a
// higher than normal default video packet size here to reduce CPU cycles wasted
// receiving packets. The possible cost is greater network losses.
m_StreamConfig.packetSize = 1392; m_StreamConfig.packetSize = 1392;
m_StreamConfig.supportedVideoFormats = VIDEO_FORMAT_H264;
// TODO: If/when video encryption is added, we'll probably want to
// limit that to devices that support AES instructions.
m_StreamConfig.encryptionFlags = ENCFLG_AUDIO;
// Load the rikey and rikeyid into the stream configuration // Load the rikey and rikeyid into the stream configuration
hexStringToBytes(rikey.c_str(), m_StreamConfig.remoteInputAesKey); hexStringToBytes(rikey.c_str(), m_StreamConfig.remoteInputAesKey);
int rikeyiv = htonl(stoi(rikeyid)); int rikeyiv = htonl(stoi(rikeyid));
@@ -224,6 +253,9 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
// Store the parameters from the start message // Store the parameters from the start message
m_Host = host; m_Host = host;
m_AppVersion = appversion; m_AppVersion = appversion;
m_GfeVersion = gfeversion;
m_RtspUrl = rtspurl;
m_MouseLockingFeatureEnabled = stoi(mouse_lock);
// Initialize the rendering surface before starting the connection // Initialize the rendering surface before starting the connection
if (InitializeRenderingSurface(m_StreamConfig.width, m_StreamConfig.height)) { if (InitializeRenderingSurface(m_StreamConfig.width, m_StreamConfig.height)) {
@@ -253,25 +285,54 @@ void MoonlightInstance::HandleStopStream(int32_t callbackId, pp::VarArray args)
} }
void MoonlightInstance::HandleOpenURL(int32_t callbackId, pp::VarArray args) { void MoonlightInstance::HandleOpenURL(int32_t callbackId, pp::VarArray args) {
std::string url = args.Get(0).AsString(); m_HttpThreadPool[m_HttpThreadPoolSequence++ % HTTP_HANDLER_THREADS]->message_loop().PostWork(
bool binaryResponse = args.Get(1).AsBool(); m_CallbackFactory.NewCallback(&MoonlightInstance::NvHTTPRequest, callbackId, args));
openHttpThread.message_loop().PostWork(m_CallbackFactory.NewCallback(&MoonlightInstance::NvHTTPRequest, callbackId, url, binaryResponse));
PostMessage(pp::Var (url.c_str()));
} }
void MoonlightInstance::HandlePair(int32_t callbackId, pp::VarArray args) { void MoonlightInstance::HandlePair(int32_t callbackId, pp::VarArray args) {
openHttpThread.message_loop().PostWork(m_CallbackFactory.NewCallback(&MoonlightInstance::PairCallback, callbackId, args)); m_HttpThreadPool[m_HttpThreadPoolSequence++ % HTTP_HANDLER_THREADS]->message_loop().PostWork(
m_CallbackFactory.NewCallback(&MoonlightInstance::PairCallback, callbackId, args));
} }
void MoonlightInstance::PairCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args) { void MoonlightInstance::PairCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args) {
int err = gs_pair(atoi(args.Get(0).AsString().c_str()), args.Get(1).AsString().c_str(), args.Get(2).AsString().c_str()); char* ppkstr;
int err = gs_pair(atoi(args.Get(0).AsString().c_str()), args.Get(1).AsString().c_str(), args.Get(2).AsString().c_str(), &ppkstr);
pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId));
if (err == 0) {
ret.Set("type", pp::Var("resolve"));
ret.Set("ret", pp::Var(ppkstr));
free(ppkstr);
}
else {
ret.Set("type", pp::Var("reject"));
ret.Set("ret", pp::Var(err));
}
PostMessage(ret);
}
void MoonlightInstance::HandleSTUN(int32_t callbackId, pp::VarArray args) {
m_HttpThreadPool[m_HttpThreadPoolSequence++ % HTTP_HANDLER_THREADS]->message_loop().PostWork(
m_CallbackFactory.NewCallback(&MoonlightInstance::STUNCallback, callbackId, args));
}
void MoonlightInstance::STUNCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args) {
unsigned int wanAddr;
char addrStr[128] = {};
pp::VarDictionary ret; pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId)); ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("resolve")); ret.Set("type", pp::Var("resolve"));
ret.Set("ret", pp::Var(err));
if (LiFindExternalAddressIP4("stun.moonlight-stream.org", 3478, &wanAddr) == 0) {
inet_ntop(AF_INET, &wanAddr, addrStr, sizeof(addrStr));
ret.Set("ret", pp::Var(addrStr));
} else {
ret.Set("ret", pp::Var());
}
PostMessage(ret); PostMessage(ret);
} }

View File

@@ -2,13 +2,13 @@
"manifest_version": 2, "manifest_version": 2,
"name": "Moonlight Game Streaming", "name": "Moonlight Game Streaming",
"short_name": "Moonlight", "short_name": "Moonlight",
"version": "0.7.0", "version": "0.10.27",
"description": "Open-source client for NVIDIA GameStream", "description": "Open-source client for NVIDIA GameStream",
"icons": { "icons": {
"128": "icons/icon128.png", "128": "icons/icon128.png",
"48": "icons/icon48.png", "48": "icons/icon48.png",
"32": "icons/icon32.png", "32": "icons/icon32.png",
"16": "icons/icon16.png" "16": "icons/icon16.png"
}, },
"app": { "app": {
"background": { "background": {
@@ -26,11 +26,12 @@
"pointerLock", "pointerLock",
"system.network", "system.network",
"fullscreen", "fullscreen",
"power",
"overrideEscFullscreen", { "overrideEscFullscreen", {
"socket": [ "socket": [
"tcp-connect", "tcp-connect",
"resolve-host", "resolve-host",
"udp-bind:*:*", "udp-bind:*:*",
"udp-send-to:*:*" "udp-send-to:*:*"
] } ] }
], ],

View File

@@ -38,6 +38,11 @@
#define DR_FLAG_FORCE_SW_DECODE 0x01 #define DR_FLAG_FORCE_SW_DECODE 0x01
// These will mostly be I/O bound so we'll create
// a bunch to allow more concurrent server requests
// since our HTTP request libary is synchronous.
#define HTTP_HANDLER_THREADS 8
struct Shader { struct Shader {
Shader() : program(0), texcoord_scale_location(0) {} Shader() : program(0), texcoord_scale_location(0) {}
~Shader() {} ~Shader() {}
@@ -53,13 +58,17 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
pp::MouseLock(this), pp::MouseLock(this),
m_HasNextPicture(false), m_HasNextPicture(false),
m_IsPainting(false), m_IsPainting(false),
m_RequestIdrFrame(false),
m_OpusDecoder(NULL), m_OpusDecoder(NULL),
m_CallbackFactory(this), m_CallbackFactory(this),
m_MouseLocked(false), m_MouseLocked(false),
m_WaitingForAllModifiersUp(false), m_WaitingForAllModifiersUp(false),
m_AccumulatedTicks(0), m_AccumulatedTicks(0),
openHttpThread(this) { m_MouseDeltaX(0),
m_MouseDeltaY(0),
m_MousePositionX(0),
m_MousePositionY(0),
m_LastTouchUpTime(0),
m_HttpThreadPoolSequence(0) {
// This function MUST be used otherwise sockets don't work (nacl_io_init() doesn't work!) // This function MUST be used otherwise sockets don't work (nacl_io_init() doesn't work!)
nacl_io_init_ppapi(pp_instance(), pp::Module::Get()->get_browser_interface()); nacl_io_init_ppapi(pp_instance(), pp::Module::Get()->get_browser_interface());
@@ -69,10 +78,18 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
m_GamepadApi = static_cast<const PPB_Gamepad*>(pp::Module::Get()->GetBrowserInterface(PPB_GAMEPAD_INTERFACE)); m_GamepadApi = static_cast<const PPB_Gamepad*>(pp::Module::Get()->GetBrowserInterface(PPB_GAMEPAD_INTERFACE));
openHttpThread.Start(); for (int i = 0; i < HTTP_HANDLER_THREADS; i++) {
m_HttpThreadPool[i] = new pp::SimpleThread(this);
m_HttpThreadPool[i]->Start();
}
} }
virtual ~MoonlightInstance(); virtual ~MoonlightInstance() {
for (int i = 0; i < HTTP_HANDLER_THREADS; i++) {
m_HttpThreadPool[i]->Join();
delete m_HttpThreadPool[i];
}
}
bool Init(uint32_t argc, const char* argn[], const char* argv[]); bool Init(uint32_t argc, const char* argn[], const char* argv[]);
@@ -82,14 +99,20 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
void HandleStartStream(int32_t callbackId, pp::VarArray args); void HandleStartStream(int32_t callbackId, pp::VarArray args);
void HandleStopStream(int32_t callbackId, pp::VarArray args); void HandleStopStream(int32_t callbackId, pp::VarArray args);
void HandleOpenURL(int32_t callbackId, pp::VarArray args); void HandleOpenURL(int32_t callbackId, pp::VarArray args);
void HandleSTUN(int32_t callbackId, pp::VarArray args);
void PairCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args); void PairCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args);
void STUNCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args);
bool TryHandleNativeTouchEvent(const pp::InputEvent& event);
bool HandleInputEvent(const pp::InputEvent& event); bool HandleInputEvent(const pp::InputEvent& event);
void ReportMouseMovement();
void PollGamepads(); void PollGamepads();
void MouseLockLost(); void MouseLockLost();
void DidLockMouse(int32_t result); void DidLockMouse(int32_t result);
void LockMouseOrJustCaptureInput();
void UnlockMouseOrJustReleaseInput();
void OnConnectionStopped(uint32_t unused); void OnConnectionStopped(uint32_t unused);
void OnConnectionStarted(uint32_t error); void OnConnectionStarted(uint32_t error);
@@ -105,15 +128,17 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
static void ProfilerPrintWarning(const char* message); static void ProfilerPrintWarning(const char* message);
static void* ConnectionThreadFunc(void* context); static void* ConnectionThreadFunc(void* context);
static void* GamepadThreadFunc(void* context); static void* InputThreadFunc(void* context);
static void* StopThreadFunc(void* context); static void* StopThreadFunc(void* context);
static void ClStageStarting(int stage); static void ClStageStarting(int stage);
static void ClStageFailed(int stage, long errorCode); static void ClStageFailed(int stage, int errorCode);
static void ClConnectionStarted(void); static void ClConnectionStarted(void);
static void ClConnectionTerminated(long errorCode); static void ClConnectionTerminated(int errorCode);
static void ClDisplayMessage(const char* message); static void ClDisplayMessage(const char* message);
static void ClDisplayTransientMessage(const char* message); static void ClDisplayTransientMessage(const char* message);
static void ClLogMessage(const char* format, ...);
static void ClControllerRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor);
static Shader CreateProgram(const char* vertexShader, const char* fragmentShader); static Shader CreateProgram(const char* vertexShader, const char* fragmentShader);
static void CreateShader(GLuint program, GLenum type, const char* source, int size); static void CreateShader(GLuint program, GLenum type, const char* source, int size);
@@ -124,20 +149,26 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
void PaintPicture(void); void PaintPicture(void);
bool InitializeRenderingSurface(int width, int height); bool InitializeRenderingSurface(int width, int height);
void DidChangeFocus(bool got_focus); void DidChangeFocus(bool got_focus);
void DidChangeView(const pp::View& view);
static void VidDecSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags); static int VidDecSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags);
static void VidDecCleanup(void); static void VidDecCleanup(void);
static int VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit); static int VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
static void AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig); static int AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags);
static void AudDecCleanup(void); static void AudDecCleanup(void);
static void AudDecDecodeAndPlaySample(char* sampleData, int sampleLength); static void AudDecDecodeAndPlaySample(char* sampleData, int sampleLength);
void MakeCert(int32_t callbackId, pp::VarArray args); void MakeCert(int32_t callbackId, pp::VarArray args);
void LoadCert(const char* certStr, const char* keyStr); void LoadCert(const char* certStr, const char* keyStr);
static void OSSLThreadLock(int mode, int n, const char *, int);
static unsigned long OSSLThreadId(void);
void NvHTTPInit(int32_t callbackId, pp::VarArray args); void NvHTTPInit(int32_t callbackId, pp::VarArray args);
void NvHTTPRequest(int32_t, int32_t callbackId, std::string url, bool binaryResponse); void NvHTTPRequest(int32_t, int32_t callbackId, pp::VarArray args);
public:
const PPB_Gamepad* m_GamepadApi;
private: private:
static CONNECTION_LISTENER_CALLBACKS s_ClCallbacks; static CONNECTION_LISTENER_CALLBACKS s_ClCallbacks;
@@ -146,11 +177,14 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
std::string m_Host; std::string m_Host;
std::string m_AppVersion; std::string m_AppVersion;
std::string m_GfeVersion;
std::string m_RtspUrl;
bool m_MouseLockingFeatureEnabled;
STREAM_CONFIGURATION m_StreamConfig; STREAM_CONFIGURATION m_StreamConfig;
bool m_Running; bool m_Running;
pthread_t m_ConnectionThread; pthread_t m_ConnectionThread;
pthread_t m_GamepadThread; pthread_t m_InputThread;
pp::Graphics3D m_Graphics3D; pp::Graphics3D m_Graphics3D;
pp::VideoDecoder* m_VideoDecoder; pp::VideoDecoder* m_VideoDecoder;
@@ -161,19 +195,24 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
bool m_HasNextPicture; bool m_HasNextPicture;
PP_VideoPicture m_CurrentPicture; PP_VideoPicture m_CurrentPicture;
bool m_IsPainting; bool m_IsPainting;
bool m_RequestIdrFrame;
pp::Rect m_PluginRect;
OpusMSDecoder* m_OpusDecoder; OpusMSDecoder* m_OpusDecoder;
pp::Audio m_AudioPlayer; pp::Audio m_AudioPlayer;
double m_LastPadTimestamps[4]; double m_LastPadTimestamps[4];
const PPB_Gamepad* m_GamepadApi;
pp::CompletionCallbackFactory<MoonlightInstance> m_CallbackFactory; pp::CompletionCallbackFactory<MoonlightInstance> m_CallbackFactory;
bool m_MouseLocked; bool m_MouseLocked;
bool m_WaitingForAllModifiersUp; bool m_WaitingForAllModifiersUp;
float m_AccumulatedTicks; float m_AccumulatedTicks;
int32_t m_MouseDeltaX, m_MouseDeltaY;
int32_t m_MousePositionX, m_MousePositionY;
PP_TimeTicks m_LastTouchUpTime;
pp::FloatPoint m_LastTouchUpPoint;
pp::SimpleThread openHttpThread; pp::SimpleThread* m_HttpThreadPool[HTTP_HANDLER_THREADS];
uint32_t m_HttpThreadPoolSequence;
}; };
extern MoonlightInstance* g_Instance; extern MoonlightInstance* g_Instance;

2
opus

Submodule opus updated: f6f8487b76...82ac57d9f1

View File

@@ -55,6 +55,7 @@ OPUS_SOURCE := \
$(OPUS_DIR)/silk/lin2log.c \ $(OPUS_DIR)/silk/lin2log.c \
$(OPUS_DIR)/silk/log2lin.c \ $(OPUS_DIR)/silk/log2lin.c \
$(OPUS_DIR)/silk/LPC_analysis_filter.c \ $(OPUS_DIR)/silk/LPC_analysis_filter.c \
$(OPUS_DIR)/silk/LPC_fit.c \
$(OPUS_DIR)/silk/LPC_inv_pred_gain.c \ $(OPUS_DIR)/silk/LPC_inv_pred_gain.c \
$(OPUS_DIR)/silk/LP_variable_cutoff.c \ $(OPUS_DIR)/silk/LP_variable_cutoff.c \
$(OPUS_DIR)/silk/NLSF2A.c \ $(OPUS_DIR)/silk/NLSF2A.c \
@@ -114,14 +115,12 @@ OPUS_SOURCE := \
$(OPUS_DIR)/silk/fixed/LTP_scale_ctrl_FIX.c \ $(OPUS_DIR)/silk/fixed/LTP_scale_ctrl_FIX.c \
$(OPUS_DIR)/silk/fixed/noise_shape_analysis_FIX.c \ $(OPUS_DIR)/silk/fixed/noise_shape_analysis_FIX.c \
$(OPUS_DIR)/silk/fixed/pitch_analysis_core_FIX.c \ $(OPUS_DIR)/silk/fixed/pitch_analysis_core_FIX.c \
$(OPUS_DIR)/silk/fixed/prefilter_FIX.c \
$(OPUS_DIR)/silk/fixed/process_gains_FIX.c \ $(OPUS_DIR)/silk/fixed/process_gains_FIX.c \
$(OPUS_DIR)/silk/fixed/regularize_correlations_FIX.c \ $(OPUS_DIR)/silk/fixed/regularize_correlations_FIX.c \
$(OPUS_DIR)/silk/fixed/residual_energy16_FIX.c \ $(OPUS_DIR)/silk/fixed/residual_energy16_FIX.c \
$(OPUS_DIR)/silk/fixed/residual_energy_FIX.c \ $(OPUS_DIR)/silk/fixed/residual_energy_FIX.c \
$(OPUS_DIR)/silk/fixed/schur64_FIX.c \ $(OPUS_DIR)/silk/fixed/schur64_FIX.c \
$(OPUS_DIR)/silk/fixed/schur_FIX.c \ $(OPUS_DIR)/silk/fixed/schur_FIX.c \
$(OPUS_DIR)/silk/fixed/solve_LS_FIX.c \
$(OPUS_DIR)/silk/fixed/vector_ops_FIX.c \ $(OPUS_DIR)/silk/fixed/vector_ops_FIX.c \
$(OPUS_DIR)/silk/fixed/warped_autocorrelation_FIX.c \ $(OPUS_DIR)/silk/fixed/warped_autocorrelation_FIX.c \
$(OPUS_DIR)/src/analysis.c \ $(OPUS_DIR)/src/analysis.c \

134
ports/include/curl/curl.h Executable file → Normal file
View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -423,7 +423,9 @@ typedef enum {
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
CURLE_FTP_CANT_GET_HOST, /* 15 */ CURLE_FTP_CANT_GET_HOST, /* 15 */
CURLE_OBSOLETE16, /* 16 - NOT USED */ CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
[was obsoleted in August 2007 for 7.17.0,
reused in July 2014 for 7.38.0] */
CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
CURLE_PARTIAL_FILE, /* 18 */ CURLE_PARTIAL_FILE, /* 18 */
CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
@@ -519,13 +521,19 @@ typedef enum {
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
session will be queued */ session will be queued */
CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
match */
CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
the obsolete stuff removed! */ the obsolete stuff removed! */
/* Previously obsoletes error codes re-used in 7.24.0 */ /* Previously obsolete error code re-used in 7.38.0 */
#define CURLE_OBSOLETE16 CURLE_HTTP2
/* Previously obsolete error codes re-used in 7.24.0 */
#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED #define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT #define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
@@ -579,6 +587,16 @@ typedef enum {
make programs break */ make programs break */
#define CURLE_ALREADY_COMPLETE 99999 #define CURLE_ALREADY_COMPLETE 99999
/* Provide defines for really old option names */
#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
/* Since long deprecated options with no code in the lib that does anything
with them. */
#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
#endif /*!CURL_NO_OLDIES*/ #endif /*!CURL_NO_OLDIES*/
/* This prototype applies to all conversion callbacks */ /* This prototype applies to all conversion callbacks */
@@ -609,7 +627,8 @@ typedef enum {
* CURLAUTH_NONE - No HTTP authentication * CURLAUTH_NONE - No HTTP authentication
* CURLAUTH_BASIC - HTTP Basic authentication (default) * CURLAUTH_BASIC - HTTP Basic authentication (default)
* CURLAUTH_DIGEST - HTTP Digest authentication * CURLAUTH_DIGEST - HTTP Digest authentication
* CURLAUTH_GSSNEGOTIATE - HTTP GSS-Negotiate authentication * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication
* CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
* CURLAUTH_NTLM - HTTP NTLM authentication * CURLAUTH_NTLM - HTTP NTLM authentication
* CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
* CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
@@ -622,7 +641,9 @@ typedef enum {
#define CURLAUTH_NONE ((unsigned long)0) #define CURLAUTH_NONE ((unsigned long)0)
#define CURLAUTH_BASIC (((unsigned long)1)<<0) #define CURLAUTH_BASIC (((unsigned long)1)<<0)
#define CURLAUTH_DIGEST (((unsigned long)1)<<1) #define CURLAUTH_DIGEST (((unsigned long)1)<<1)
#define CURLAUTH_GSSNEGOTIATE (((unsigned long)1)<<2) #define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
#define CURLAUTH_NTLM (((unsigned long)1)<<3) #define CURLAUTH_NTLM (((unsigned long)1)<<3)
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) #define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) #define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
@@ -704,6 +725,10 @@ typedef enum {
servers, a user can this way allow the vulnerability back. */ servers, a user can this way allow the vulnerability back. */
#define CURLSSLOPT_ALLOW_BEAST (1<<0) #define CURLSSLOPT_ALLOW_BEAST (1<<0)
/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
SSL backends where such behavior is present. */
#define CURLSSLOPT_NO_REVOKE (1<<1)
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
the obsolete stuff removed! */ the obsolete stuff removed! */
@@ -785,6 +810,8 @@ typedef enum {
#define CURLPROTO_RTMPS (1<<23) #define CURLPROTO_RTMPS (1<<23)
#define CURLPROTO_RTMPTS (1<<24) #define CURLPROTO_RTMPTS (1<<24)
#define CURLPROTO_GOPHER (1<<25) #define CURLPROTO_GOPHER (1<<25)
#define CURLPROTO_SMB (1<<26)
#define CURLPROTO_SMBS (1<<27)
#define CURLPROTO_ALL (~0) /* enable everything */ #define CURLPROTO_ALL (~0) /* enable everything */
/* long may be 32 or 64 bits, but we should never depend on anything else /* long may be 32 or 64 bits, but we should never depend on anything else
@@ -820,10 +847,10 @@ typedef enum {
typedef enum { typedef enum {
/* This is the FILE * or void * the regular output should be written to. */ /* This is the FILE * or void * the regular output should be written to. */
CINIT(FILE, OBJECTPOINT, 1), CINIT(WRITEDATA, OBJECTPOINT, 1),
/* The full URL to get/put */ /* The full URL to get/put */
CINIT(URL, OBJECTPOINT, 2), CINIT(URL, OBJECTPOINT, 2),
/* Port number to connect to, if other than default. */ /* Port number to connect to, if other than default. */
CINIT(PORT, LONG, 3), CINIT(PORT, LONG, 3),
@@ -843,7 +870,7 @@ typedef enum {
/* not used */ /* not used */
/* Specified file stream to upload from (use as input): */ /* Specified file stream to upload from (use as input): */
CINIT(INFILE, OBJECTPOINT, 9), CINIT(READDATA, OBJECTPOINT, 9),
/* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
* bytes big. If this is not used, error messages go to stderr instead: */ * bytes big. If this is not used, error messages go to stderr instead: */
@@ -928,7 +955,7 @@ typedef enum {
/* send FILE * or void * to store headers to, if you use a callback it /* send FILE * or void * to store headers to, if you use a callback it
is simply passed to the callback unmodified */ is simply passed to the callback unmodified */
CINIT(WRITEHEADER, OBJECTPOINT, 29), CINIT(HEADERDATA, OBJECTPOINT, 29),
/* point to a file to read the initial cookies from, also enables /* point to a file to read the initial cookies from, also enables
"cookie awareness" */ "cookie awareness" */
@@ -961,13 +988,13 @@ typedef enum {
/* send linked-list of post-transfer QUOTE commands */ /* send linked-list of post-transfer QUOTE commands */
CINIT(POSTQUOTE, OBJECTPOINT, 39), CINIT(POSTQUOTE, OBJECTPOINT, 39),
CINIT(WRITEINFO, OBJECTPOINT, 40), /* DEPRECATED, do not use! */ CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
CINIT(VERBOSE, LONG, 41), /* talk a lot */ CINIT(VERBOSE, LONG, 41), /* talk a lot */
CINIT(HEADER, LONG, 42), /* throw the header out too */ CINIT(HEADER, LONG, 42), /* throw the header out too */
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */
CINIT(UPLOAD, LONG, 46), /* this is an upload */ CINIT(UPLOAD, LONG, 46), /* this is an upload */
CINIT(POST, LONG, 47), /* HTTP POST method */ CINIT(POST, LONG, 47), /* HTTP POST method */
CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */
@@ -1040,7 +1067,7 @@ typedef enum {
/* Max amount of cached alive connections */ /* Max amount of cached alive connections */
CINIT(MAXCONNECTS, LONG, 71), CINIT(MAXCONNECTS, LONG, 71),
CINIT(CLOSEPOLICY, LONG, 72), /* DEPRECATED, do not use! */ CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
/* 73 = OBSOLETE */ /* 73 = OBSOLETE */
@@ -1593,6 +1620,31 @@ typedef enum {
/* Pass in a bitmask of "header options" */ /* Pass in a bitmask of "header options" */
CINIT(HEADEROPT, LONG, 229), CINIT(HEADEROPT, LONG, 229),
/* The public key in DER form used to validate the peer public key
this option is used only if SSL_VERIFYPEER is true */
CINIT(PINNEDPUBLICKEY, OBJECTPOINT, 230),
/* Path to Unix domain socket */
CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
/* Set if we should verify the certificate status. */
CINIT(SSL_VERIFYSTATUS, LONG, 232),
/* Set if we should enable TLS false start. */
CINIT(SSL_FALSESTART, LONG, 233),
/* Do not squash dot-dot sequences */
CINIT(PATH_AS_IS, LONG, 234),
/* Proxy Service Name */
CINIT(PROXY_SERVICE_NAME, OBJECTPOINT, 235),
/* Service Name */
CINIT(SERVICE_NAME, OBJECTPOINT, 236),
/* Wait/don't wait for pipe/mutex to clarify */
CINIT(PIPEWAIT, LONG, 237),
CURLOPT_LASTENTRY /* the last unused */ CURLOPT_LASTENTRY /* the last unused */
} CURLoption; } CURLoption;
@@ -1629,13 +1681,10 @@ typedef enum {
option might be handy to force libcurl to use a specific IP version. */ option might be handy to force libcurl to use a specific IP version. */
#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP #define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
versions that your system allows */ versions that your system allows */
#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ #define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */
#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ #define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */
/* three convenient "aliases" that follow the name scheme better */ /* three convenient "aliases" that follow the name scheme better */
#define CURLOPT_WRITEDATA CURLOPT_FILE
#define CURLOPT_READDATA CURLOPT_INFILE
#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
/* These enums are for use with the CURLOPT_HTTP_VERSION option. */ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
@@ -1650,6 +1699,11 @@ enum {
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
}; };
/* Convenience definition simple because the name of the version is HTTP/2 and
not 2.0. The 2_0 version of the enum name was set while the version was
still planned to be 2.0 and we stick to it for compatibility. */
#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
/* /*
* Public API enums for RTSP requests * Public API enums for RTSP requests
*/ */
@@ -2013,12 +2067,13 @@ typedef enum {
CURLSSLBACKEND_OPENSSL = 1, CURLSSLBACKEND_OPENSSL = 1,
CURLSSLBACKEND_GNUTLS = 2, CURLSSLBACKEND_GNUTLS = 2,
CURLSSLBACKEND_NSS = 3, CURLSSLBACKEND_NSS = 3,
CURLSSLBACKEND_QSOSSL = 4, CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */
CURLSSLBACKEND_GSKIT = 5, CURLSSLBACKEND_GSKIT = 5,
CURLSSLBACKEND_POLARSSL = 6, CURLSSLBACKEND_POLARSSL = 6,
CURLSSLBACKEND_CYASSL = 7, CURLSSLBACKEND_CYASSL = 7,
CURLSSLBACKEND_SCHANNEL = 8, CURLSSLBACKEND_SCHANNEL = 8,
CURLSSLBACKEND_DARWINSSL = 9 CURLSSLBACKEND_DARWINSSL = 9,
CURLSSLBACKEND_AXTLS = 10
} curl_sslbackend; } curl_sslbackend;
/* Information about the SSL library used and the respective internal SSL /* Information about the SSL library used and the respective internal SSL
@@ -2219,23 +2274,30 @@ typedef struct {
} curl_version_info_data; } curl_version_info_data;
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ #define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ #define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ (deprecated) */
#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ #define CURL_VERSION_SSL (1<<2) /* SSL options are present */
#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ #define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ #define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ #define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported
#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ (deprecated) */
#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ #define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ #define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ #define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ #define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */
#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ #define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are
#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ supported */
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ #define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */ #define CURL_VERSION_CONV (1<<12) /* Character conversions supported */
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ #define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper
is suported */
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */
#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */
#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
/* /*
* NAME curl_version_info() * NAME curl_version_info()

0
ports/include/curl/curlbuild.h Executable file → Normal file
View File

0
ports/include/curl/curlrules.h Executable file → Normal file
View File

20
ports/include/curl/curlver.h Executable file → Normal file
View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -26,16 +26,16 @@
a script at release-time. This was made its own header file in 7.11.2 */ a script at release-time. This was made its own header file in 7.11.2 */
/* This is the global package copyright */ /* This is the global package copyright */
#define LIBCURL_COPYRIGHT "1996 - 2014 Daniel Stenberg, <daniel@haxx.se>." #define LIBCURL_COPYRIGHT "1996 - 2015 Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header /* This is the version number of the libcurl package from which this header
file origins: */ file origins: */
#define LIBCURL_VERSION "7.37.0" #define LIBCURL_VERSION "7.44.0"
/* The numeric version number is also available "in parts" by using these /* The numeric version number is also available "in parts" by using these
defines: */ defines: */
#define LIBCURL_VERSION_MAJOR 7 #define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 37 #define LIBCURL_VERSION_MINOR 44
#define LIBCURL_VERSION_PATCH 0 #define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier /* This is the numeric version of the libcurl version number, meant for easier
@@ -52,8 +52,12 @@
This 6-digit (24 bits) hexadecimal number does not show pre-release number, This 6-digit (24 bits) hexadecimal number does not show pre-release number,
and it is always a greater number in a more recent release. It makes and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work. comparisons with greater than and less than work.
Note: This define is the full hex number and _does not_ use the
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/ */
#define LIBCURL_VERSION_NUM 0x072500 #define LIBCURL_VERSION_NUM 0x072c00
/* /*
* This is the date and time when the full source package was created. The * This is the date and time when the full source package was created. The
@@ -64,6 +68,10 @@
* *
* "Mon Feb 12 11:35:33 UTC 2007" * "Mon Feb 12 11:35:33 UTC 2007"
*/ */
#define LIBCURL_TIMESTAMP "Wed May 21 05:58:26 UTC 2014" #define LIBCURL_TIMESTAMP "Wed Aug 12 06:10:30 UTC 2015"
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
#define CURL_AT_LEAST_VERSION(x,y,z) \
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
#endif /* __CURL_CURLVER_H */ #endif /* __CURL_CURLVER_H */

0
ports/include/curl/easy.h Executable file → Normal file
View File

9
ports/include/curl/mprintf.h Executable file → Normal file
View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -57,15 +57,8 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
# undef vaprintf # undef vaprintf
# define printf curl_mprintf # define printf curl_mprintf
# define fprintf curl_mfprintf # define fprintf curl_mfprintf
#ifdef CURLDEBUG
/* When built with CURLDEBUG we define away the sprintf functions since we
don't want internal code to be using them */
# define sprintf sprintf_was_used
# define vsprintf vsprintf_was_used
#else
# define sprintf curl_msprintf # define sprintf curl_msprintf
# define vsprintf curl_mvsprintf # define vsprintf curl_mvsprintf
#endif
# define snprintf curl_msnprintf # define snprintf curl_msnprintf
# define vprintf curl_mvprintf # define vprintf curl_mvprintf
# define vfprintf curl_mvfprintf # define vfprintf curl_mvfprintf

38
ports/include/curl/multi.h Executable file → Normal file
View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -74,6 +74,11 @@ typedef enum {
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM #define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
/* bitmask bits for CURLMOPT_PIPELINING */
#define CURLPIPE_NOTHING 0L
#define CURLPIPE_HTTP1 1L
#define CURLPIPE_MULTIPLEX 2L
typedef enum { typedef enum {
CURLMSG_NONE, /* first, not used */ CURLMSG_NONE, /* first, not used */
CURLMSG_DONE, /* This easy handle has completed. 'result' contains CURLMSG_DONE, /* This easy handle has completed. 'result' contains
@@ -365,6 +370,12 @@ typedef enum {
/* maximum number of open connections in total */ /* maximum number of open connections in total */
CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
/* This is the server push callback function pointer */
CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
/* This is the argument passed to the server push callback */
CINIT(PUSHDATA, OBJECTPOINT, 15),
CURLMOPT_LASTENTRY /* the last unused */ CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption; } CURLMoption;
@@ -392,6 +403,31 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
curl_socket_t sockfd, void *sockp); curl_socket_t sockfd, void *sockp);
/*
* Name: curl_push_callback
*
* Desc: This callback gets called when a new stream is being pushed by the
* server. It approves or denies the new stream.
*
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
*/
#define CURL_PUSH_OK 0
#define CURL_PUSH_DENY 1
struct curl_pushheaders; /* forward declaration only */
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
size_t num);
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
const char *name);
typedef int (*curl_push_callback)(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *userp);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif

0
ports/include/curl/stdcheaders.h Executable file → Normal file
View File

6
ports/include/curl/typecheck-gcc.h Executable file → Normal file
View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -270,6 +270,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
(option) == CURLOPT_DNS_LOCAL_IP4 || \ (option) == CURLOPT_DNS_LOCAL_IP4 || \
(option) == CURLOPT_DNS_LOCAL_IP6 || \ (option) == CURLOPT_DNS_LOCAL_IP6 || \
(option) == CURLOPT_LOGIN_OPTIONS || \ (option) == CURLOPT_LOGIN_OPTIONS || \
(option) == CURLOPT_PROXY_SERVICE_NAME || \
(option) == CURLOPT_SERVICE_NAME || \
0) 0)
/* evaluates to true if option takes a curl_write_callback argument */ /* evaluates to true if option takes a curl_write_callback argument */
@@ -291,7 +293,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
(option) == CURLOPT_SOCKOPTDATA || \ (option) == CURLOPT_SOCKOPTDATA || \
(option) == CURLOPT_OPENSOCKETDATA || \ (option) == CURLOPT_OPENSOCKETDATA || \
(option) == CURLOPT_PROGRESSDATA || \ (option) == CURLOPT_PROGRESSDATA || \
(option) == CURLOPT_WRITEHEADER || \ (option) == CURLOPT_HEADERDATA || \
(option) == CURLOPT_DEBUGDATA || \ (option) == CURLOPT_DEBUGDATA || \
(option) == CURLOPT_SSL_CTX_DATA || \ (option) == CURLOPT_SSL_CTX_DATA || \
(option) == CURLOPT_SEEKDATA || \ (option) == CURLOPT_SEEKDATA || \

0
ports/include/openssl/aes.h Executable file → Normal file
View File

0
ports/include/openssl/asn1.h Executable file → Normal file
View File

0
ports/include/openssl/asn1_mac.h Executable file → Normal file
View File

0
ports/include/openssl/asn1t.h Executable file → Normal file
View File

0
ports/include/openssl/bio.h Executable file → Normal file
View File

0
ports/include/openssl/blowfish.h Executable file → Normal file
View File

0
ports/include/openssl/bn.h Executable file → Normal file
View File

0
ports/include/openssl/buffer.h Executable file → Normal file
View File

0
ports/include/openssl/camellia.h Executable file → Normal file
View File

0
ports/include/openssl/cast.h Executable file → Normal file
View File

0
ports/include/openssl/cmac.h Executable file → Normal file
View File

0
ports/include/openssl/cms.h Executable file → Normal file
View File

0
ports/include/openssl/comp.h Executable file → Normal file
View File

0
ports/include/openssl/conf.h Executable file → Normal file
View File

0
ports/include/openssl/conf_api.h Executable file → Normal file
View File

0
ports/include/openssl/crypto.h Executable file → Normal file
View File

0
ports/include/openssl/des.h Executable file → Normal file
View File

0
ports/include/openssl/des_old.h Executable file → Normal file
View File

0
ports/include/openssl/dh.h Executable file → Normal file
View File

0
ports/include/openssl/dsa.h Executable file → Normal file
View File

0
ports/include/openssl/dso.h Executable file → Normal file
View File

0
ports/include/openssl/dtls1.h Executable file → Normal file
View File

0
ports/include/openssl/e_os2.h Executable file → Normal file
View File

0
ports/include/openssl/ebcdic.h Executable file → Normal file
View File

0
ports/include/openssl/ec.h Executable file → Normal file
View File

0
ports/include/openssl/ecdh.h Executable file → Normal file
View File

0
ports/include/openssl/ecdsa.h Executable file → Normal file
View File

0
ports/include/openssl/engine.h Executable file → Normal file
View File

0
ports/include/openssl/err.h Executable file → Normal file
View File

0
ports/include/openssl/evp.h Executable file → Normal file
View File

0
ports/include/openssl/hmac.h Executable file → Normal file
View File

0
ports/include/openssl/idea.h Executable file → Normal file
View File

0
ports/include/openssl/krb5_asn.h Executable file → Normal file
View File

0
ports/include/openssl/kssl.h Executable file → Normal file
View File

0
ports/include/openssl/lhash.h Executable file → Normal file
View File

0
ports/include/openssl/md4.h Executable file → Normal file
View File

0
ports/include/openssl/md5.h Executable file → Normal file
View File

0
ports/include/openssl/mdc2.h Executable file → Normal file
View File

0
ports/include/openssl/modes.h Executable file → Normal file
View File

0
ports/include/openssl/obj_mac.h Executable file → Normal file
View File

0
ports/include/openssl/objects.h Executable file → Normal file
View File

0
ports/include/openssl/ocsp.h Executable file → Normal file
View File

0
ports/include/openssl/opensslconf.h Executable file → Normal file
View File

0
ports/include/openssl/opensslv.h Executable file → Normal file
View File

0
ports/include/openssl/ossl_typ.h Executable file → Normal file
View File

0
ports/include/openssl/pem.h Executable file → Normal file
View File

0
ports/include/openssl/pem2.h Executable file → Normal file
View File

0
ports/include/openssl/pkcs12.h Executable file → Normal file
View File

0
ports/include/openssl/pkcs7.h Executable file → Normal file
View File

0
ports/include/openssl/pqueue.h Executable file → Normal file
View File

0
ports/include/openssl/rand.h Executable file → Normal file
View File

0
ports/include/openssl/rc2.h Executable file → Normal file
View File

0
ports/include/openssl/rc4.h Executable file → Normal file
View File

0
ports/include/openssl/ripemd.h Executable file → Normal file
View File

0
ports/include/openssl/rsa.h Executable file → Normal file
View File

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