### Initialize and Start a Moonlight Stream Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/README.md Demonstrates the setup of video, audio, and connection callbacks followed by the initiation of a stream connection. ```c #include "Limelight.h" #include // Video decoder callbacks int onVideoSetup(int videoFormat, int width, int height, int fps, void* ctx, int flags) { printf("Video: %d×%d @%dfps format=%d\n", width, height, fps, videoFormat); return 0; // success } void onVideoSubmit(PDECODE_UNIT du) { printf("Frame %d: %d bytes\n", du->frameNumber, du->fullLength); // Decode and render the frame... } // Audio decoder callbacks int onAudioInit(int audioConfig, const POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* ctx, int flags) { printf("Audio: %d channels, %d Hz\n", opusConfig->channelCount, opusConfig->sampleRate); return 0; // success } void onAudioPlay(char* sampleData, int sampleLength) { // Decode Opus and play... } // Connection callbacks void onConnected(void) { printf("Connected!\n"); } void onTerminated(int code) { printf("Disconnected: %d\n", code); } void onStageFailed(int stage, int code) { printf("Connection failed at %s: %d\n", LiGetStageName(stage), code); } int main() { // Configure stream STREAM_CONFIGURATION streamConfig; LiInitializeStreamConfiguration(&streamConfig); streamConfig.width = 1920; streamConfig.height = 1080; streamConfig.fps = 60; streamConfig.bitrate = 10000; streamConfig.packetSize = 1024; streamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO; streamConfig.supportedVideoFormats = VIDEO_FORMAT_H264 | VIDEO_FORMAT_H265; // Server info SERVER_INFORMATION server; LiInitializeServerInformation(&server); server.address = "192.168.1.50"; // Callbacks DECODER_RENDERER_CALLBACKS drCallbacks; LiInitializeVideoCallbacks(&drCallbacks); drCallbacks.setup = onVideoSetup; drCallbacks.submitDecodeUnit = onVideoSubmit; AUDIO_RENDERER_CALLBACKS arCallbacks; LiInitializeAudioCallbacks(&arCallbacks); arCallbacks.init = onAudioInit; arCallbacks.decodeAndPlaySample = onAudioPlay; CONNECTION_LISTENER_CALLBACKS clCallbacks; LiInitializeConnectionCallbacks(&clCallbacks); clCallbacks.connectionStarted = onConnected; clCallbacks.connectionTerminated = onTerminated; clCallbacks.stageFailed = onStageFailed; // Start stream int ret = LiStartConnection(&server, &streamConfig, &clCallbacks, &drCallbacks, &arCallbacks, NULL, 0, NULL, 0); if (ret != 0) { printf("Failed to start stream: %d\n", ret); return 1; } // Run event loop (in production, handle input and shutdown) // ... keep connection alive ... LiStopConnection(); return 0; } ``` -------------------------------- ### Initiate a GameStream connection with LiStartConnection Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Defines the signature for starting a connection and provides a complete example of initializing configuration and server structures. ```c int LiStartConnection( PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks, PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, void* renderContext, int drFlags, void* audioContext, int arFlags ); ``` ```c STREAM_CONFIGURATION config; LiInitializeStreamConfiguration(&config); config.width = 1920; config.height = 1080; config.fps = 60; config.bitrate = 10000; config.packetSize = 1024; config.audioConfiguration = AUDIO_CONFIGURATION_STEREO; config.supportedVideoFormats = VIDEO_FORMAT_H264 | VIDEO_FORMAT_H265; SERVER_INFORMATION server; LiInitializeServerInformation(&server); server.address = "192.168.1.50"; server.serverInfoAppVersion = "2021.12.1"; server.serverCodecModeSupport = SCM_H264 | SCM_HEVC; int ret = LiStartConnection(&server, &config, NULL, NULL, NULL, NULL, 0, NULL, 0); if (ret != 0) { printf("Connection failed: %d\n", ret); } ``` -------------------------------- ### LiWaitForNextVideoFrame Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Demonstrates a blocking loop to retrieve and process video frames. ```c VIDEO_FRAME_HANDLE handle; PDECODE_UNIT decodeUnit; while (LiWaitForNextVideoFrame(&handle, &decodeUnit)) { int status = decodeFrame(decodeUnit); LiCompleteVideoFrame(handle, status); } ``` -------------------------------- ### LiCompleteVideoFrame Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Demonstrates how to use LiCompleteVideoFrame after attempting to decode a frame retrieved from the library. ```c VIDEO_FRAME_HANDLE handle; PDECODE_UNIT decodeUnit; if (LiWaitForNextVideoFrame(&handle, &decodeUnit)) { int status = decodeFrame(decodeUnit); if (status < 0) { printf("Decode failed, requesting IDR\n"); LiCompleteVideoFrame(handle, DR_NEED_IDR); } else { LiCompleteVideoFrame(handle, DR_OK); } } ``` -------------------------------- ### Invoke LiSendControllerArrivalEvent Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Example usage of the arrival event function for a PlayStation-style controller. ```c LiSendControllerArrivalEvent( 0, // controllerNumber 0x0001, // activeGamepadMask (controller 0 present) LI_CTYPE_PS, // PlayStation-style controller (A_FLAG | B_FLAG | X_FLAG | Y_FLAG), // supportedButtonFlags LI_CCAP_ANALOG_TRIGGERS | LI_CCAP_RUMBLE // capabilities ); ``` -------------------------------- ### Configure Stream and Connection Callbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Initialize stream configuration, server details, and renderer callbacks before starting a connection with LiStartConnection. ```c #include "Limelight.h" STREAM_CONFIGURATION config; LiInitializeStreamConfiguration(&config); // 1080p, 60 FPS, 10 Mbps bitrate for local LAN config.width = 1920; config.height = 1080; config.fps = 60; config.bitrate = 10000; config.packetSize = 1024; config.streamingRemotely = STREAM_CFG_AUTO; // Audio: Stereo config.audioConfiguration = AUDIO_CONFIGURATION_STEREO; // Video: H.264 and HEVC config.supportedVideoFormats = VIDEO_FORMAT_H264 | VIDEO_FORMAT_H265; // Colors: Rec. 709 (HD), limited range config.colorSpace = COLORSPACE_REC_709; config.colorRange = COLOR_RANGE_LIMITED; // Encryption: Encrypt both audio and video config.encryptionFlags = ENCFLG_AUDIO | ENCFLG_VIDEO; // No display refresh rate optimization config.clientRefreshRateX100 = 0; SERVER_INFORMATION server; LiInitializeServerInformation(&server); server.address = "192.168.1.50"; server.serverInfoAppVersion = "2021.12.1"; server.serverCodecModeSupport = SCM_H264 | SCM_HEVC; DECODER_RENDERER_CALLBACKS drCallbacks; LiInitializeVideoCallbacks(&drCallbacks); drCallbacks.setup = videoSetupCallback; drCallbacks.start = videoStartCallback; drCallbacks.stop = videoStopCallback; drCallbacks.cleanup = videoCleanupCallback; drCallbacks.submitDecodeUnit = videoSubmitCallback; drCallbacks.capabilities = CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC | CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC; AUDIO_RENDERER_CALLBACKS arCallbacks; LiInitializeAudioCallbacks(&arCallbacks); arCallbacks.init = audioInitCallback; arCallbacks.start = audioStartCallback; arCallbacks.stop = audioStopCallback; arCallbacks.cleanup = audioCleanupCallback; arCallbacks.decodeAndPlaySample = audioDecodeCallback; CONNECTION_LISTENER_CALLBACKS clCallbacks; LiInitializeConnectionCallbacks(&clCallbacks); clCallbacks.connectionStarted = onConnected; clCallbacks.connectionTerminated = onDisconnected; clCallbacks.stageFailed = onStageFailed; int ret = LiStartConnection(&server, &config, &clCallbacks, &drCallbacks, &arCallbacks, NULL, 0, NULL, 0); if (ret != 0) { printf("Connection failed: %d\n", ret); } ``` -------------------------------- ### Usage Example for LiGetStageName Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Demonstrates logging a stage failure by converting the stage integer to a human-readable string. ```c void onStageFailed(int stage, int errorCode) { printf("Stage failed: %s (error: %d)\n", LiGetStageName(stage), errorCode); } ``` -------------------------------- ### Test Moonlight Port Connectivity Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connectivity-testing.md Example demonstrating how to test all standard Moonlight ports and handle the returned bitmask of failed ports. ```c // Test all standard Moonlight ports unsigned int failedPorts = LiTestClientConnectivity("test.moonlight-stream.org", 443, ML_PORT_FLAG_ALL); if (failedPorts == 0) { printf("All ports passed!\n"); } else if (failedPorts == ML_TEST_RESULT_INCONCLUSIVE) { printf("Test error - couldn't reach test server\n"); } else { printf("Failed ports: 0x%X\n", failedPorts); char portNames[256]; LiStringifyPortFlags(failedPorts, ", ", portNames, sizeof(portNames)); printf("Failed: %s\n", portNames); } ``` -------------------------------- ### LiPeekNextVideoFrame Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Checks frame properties before committing to the decode process. ```c PDECODE_UNIT nextFrame; if (LiPeekNextVideoFrame(&nextFrame)) { if (nextFrame->frameType == FRAME_TYPE_IDR) { printf("Next frame is an IDR frame\n"); } // Now actually retrieve and decode it VIDEO_FRAME_HANDLE handle; LiPollNextVideoFrame(&handle, &nextFrame); int status = decodeFrame(nextFrame); LiCompleteVideoFrame(handle, status); } ``` -------------------------------- ### LiPollNextVideoFrame Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Shows how to poll for frames within a game loop without blocking execution. ```c void gameLoopTick() { VIDEO_FRAME_HANDLE handle; PDECODE_UNIT decodeUnit; if (LiPollNextVideoFrame(&handle, &decodeUnit)) { int status = decodeFrame(decodeUnit); LiCompleteVideoFrame(handle, status); } // Continue with other game logic } ``` -------------------------------- ### Complete Pull-Based Decoder Loop Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md A full implementation example showing the decoder thread loop and stream management for pull-based rendering. ```c #include "Limelight.h" #include #include #include static pthread_t decoderThread; static volatile bool stopDecoder = false; int myVideoSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags) { printf("Setting up video: %dx%d, format=%d\n", width, height, videoFormat); return 0; // Success } void myVideoStart(void) { printf("Starting video decoder\n"); } void myVideoStop(void) { printf("Stopping video decoder\n"); } void myVideoCleanup(void) { printf("Cleaning up video decoder\n"); } // This runs in a dedicated decoder thread void* decoderThreadProc(void* arg) { VIDEO_FRAME_HANDLE handle; PDECODE_UNIT decodeUnit; printf("Decoder thread started\n"); while (!stopDecoder && LiWaitForNextVideoFrame(&handle, &decodeUnit)) { printf("Got frame %d (%s), size=%d bytes\n", decodeUnit->frameNumber, decodeUnit->frameType == FRAME_TYPE_IDR ? "IDR" : "P", decodeUnit->fullLength); // Decode the frame int decodeStatus = decodeVideoFrame(decodeUnit); // Report completion if (decodeStatus != 0) { printf("Decode failed, requesting IDR\n"); LiCompleteVideoFrame(handle, DR_NEED_IDR); } else { LiCompleteVideoFrame(handle, DR_OK); } } printf("Decoder thread exiting\n"); return NULL; } int startPullBasedStream() { STREAM_CONFIGURATION streamConfig; LiInitializeStreamConfiguration(&streamConfig); streamConfig.width = 1920; streamConfig.height = 1080; streamConfig.fps = 60; streamConfig.bitrate = 10000; streamConfig.packetSize = 1024; streamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO; streamConfig.supportedVideoFormats = VIDEO_FORMAT_H264; SERVER_INFORMATION server; LiInitializeServerInformation(&server); server.address = "192.168.1.50"; DECODER_RENDERER_CALLBACKS drCallbacks; LiInitializeVideoCallbacks(&drCallbacks); drCallbacks.setup = myVideoSetup; drCallbacks.start = myVideoStart; drCallbacks.stop = myVideoStop; drCallbacks.cleanup = myVideoCleanup; // Note: submitDecodeUnit is NOT set for pull-based rendering stopDecoder = false; if (pthread_create(&decoderThread, NULL, decoderThreadProc, NULL) != 0) { return -1; } int ret = LiStartConnection(&server, &streamConfig, NULL, &drCallbacks, NULL, NULL, CAPABILITY_PULL_RENDERER, NULL, 0); if (ret != 0) { stopDecoder = true; LiWakeWaitForVideoFrame(); pthread_join(decoderThread, NULL); } return ret; } void stopPullBasedStream() { stopDecoder = true; LiWakeWaitForVideoFrame(); pthread_join(decoderThread, NULL); LiStopConnection(); } ``` -------------------------------- ### Sending Pen Input Events Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Example of initiating a pen down event with specific tilt and pressure parameters. ```c // Pen down with tilt LiSendPenEvent( LI_TOUCH_EVENT_DOWN, // eventType LI_TOOL_TYPE_PEN, // toolType 0, // penButtons (no buttons pressed) 0.5, 0.5, // x, y 0.9, // pressureOrDistance 0.02, 0.02, // contactAreaMajor, contactAreaMinor 45, // rotation 30 // tilt (30 degrees from vertical) ); ``` -------------------------------- ### LiSendControllerEvent Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Demonstrates sending a gamepad event with the A button pressed and the left stick moved. ```c // A button pressed, left stick moved LiSendControllerEvent( A_FLAG, // buttonFlags 0x00, // leftTrigger (unpressed) 0xFF, // rightTrigger (pressed) 16384, // leftStickX (right) 0, // leftStickY (center) 0, // rightStickX (center) 0 // rightStickY (center) ); ``` -------------------------------- ### LiSendMultiControllerEvent Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Signals the presence of controllers 0 and 1 using an active gamepad mask. ```c // Signal that controllers 0 and 1 are present activeGamepadMask = (1 << 0) | (1 << 1); // 0x0003 LiSendMultiControllerEvent(0, activeGamepadMask, 0, 0, 0, 0, 0, 0, 0); ``` -------------------------------- ### Handle Video Decoder Status Codes in C Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/errors.md Examples demonstrating how to return DR_OK and DR_NEED_IDR status codes from a video submission callback. ```c int myVideoSubmit(PDECODE_UNIT decodeUnit) { if (decodeVideoFrame(decodeUnit) == 0) { return DR_OK; // Success } else { return DR_NEED_IDR; // Request keyframe on error } } ``` ```c int myVideoSubmit(PDECODE_UNIT decodeUnit) { if (isCorrupted(decodeUnit)) { printf("Corrupted frame, requesting IDR\n"); return DR_NEED_IDR; } return DR_OK; } ``` -------------------------------- ### Initialize Minimum Stream Configuration Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/README.md Sets up a basic stream configuration with standard resolution, framerate, and stereo audio. ```c STREAM_CONFIGURATION config; LiInitializeStreamConfiguration(&config); config.width = 1920; config.height = 1080; config.fps = 60; config.bitrate = 10000; config.packetSize = 1024; config.audioConfiguration = AUDIO_CONFIGURATION_STEREO; config.supportedVideoFormats = VIDEO_FORMAT_H264; ``` -------------------------------- ### Get Millisecond Timestamp Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves a millisecond-precision timestamp for relative time comparisons. ```c uint64_t LiGetMillis(void); ``` ```c uint64_t start = LiGetMillis(); // ... wait for something ... if (LiGetMillis() - start > 5000) { printf("Timeout: waited more than 5 seconds\n"); } ``` -------------------------------- ### Get Microsecond Timestamp Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves a microsecond-precision timestamp for relative time comparisons. ```c uint64_t LiGetMicroseconds(void); ``` ```c uint64_t start = LiGetMicroseconds(); // ... do work ... uint64_t elapsed = LiGetMicroseconds() - start; printf("Elapsed: %lu microseconds\n", elapsed); ``` -------------------------------- ### Initialize Connection Callbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all callback function pointers and event handlers for safe initialization. ```c CONNECTION_LISTENER_CALLBACKS callbacks; LiInitializeConnectionCallbacks(&callbacks); callbacks.connectionStarted = myOnConnectionStarted; ``` -------------------------------- ### Get Host Feature Flags Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves a bitmask of supported feature flags from the host. ```c uint32_t LiGetHostFeatureFlags(void); ``` -------------------------------- ### Get RTP Video Statistics Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves read-only statistics for the RTP video stream. ```c const RTP_VIDEO_STATS* LiGetRTPVideoStats(void); ``` ```c typedef struct _RTP_VIDEO_STATS { uint32_t packetCountVideo; // total video packets received uint32_t packetCountFec; // total FEC packets received uint32_t packetCountFecRecovered; // packets recovered using FEC uint32_t packetCountFecFailed; // FEC recovery attempts that failed uint32_t packetCountOOS; // out-of-sequence packets uint32_t packetCountInvalid; // corrupted or invalid packets uint32_t packetCountFecInvalid; // invalid FEC packets } RTP_VIDEO_STATS; ``` ```c const RTP_VIDEO_STATS* stats = LiGetRTPVideoStats(); if (stats && stats->packetCountFecFailed > 0) { printf("Video: %u packets, %u/%u FEC recovered\n", stats->packetCountVideo, stats->packetCountFecRecovered, stats->packetCountFecFailed); } ``` -------------------------------- ### Get RTP Audio Statistics Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves read-only statistics for the RTP audio stream. ```c const RTP_AUDIO_STATS* LiGetRTPAudioStats(void); ``` ```c typedef struct _RTP_AUDIO_STATS { uint32_t packetCountAudio; // total audio packets received uint32_t packetCountFec; // total FEC packets received uint32_t packetCountFecRecovered; // packets recovered using FEC uint32_t packetCountFecFailed; // FEC recovery attempts that failed uint32_t packetCountOOS; // out-of-sequence packets uint32_t packetCountInvalid; // corrupted or invalid packets uint32_t packetCountFecInvalid; // invalid FEC packets } RTP_AUDIO_STATS; ``` ```c const RTP_AUDIO_STATS* stats = LiGetRTPAudioStats(); if (stats) { printf("Audio packets: %u, FEC recovered: %u, FEC failed: %u\n", stats->packetCountAudio, stats->packetCountFecRecovered, stats->packetCountFecFailed); } ``` -------------------------------- ### LiGetLaunchUrlQueryParameters Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Retrieves the query parameters required for the launch URL to enable Sunshine-specific functionality. ```APIDOC ## const char* LiGetLaunchUrlQueryParameters() ### Description Retrieves the launch URL query parameters as a string. These parameters should be appended to the /launch or /resume endpoint. ### Returns - **const char*** - A string containing the query parameters. ``` -------------------------------- ### Initialize Video Callbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all video decoder callback function pointers for safe initialization. ```c DECODER_RENDERER_CALLBACKS callbacks; LiInitializeVideoCallbacks(&callbacks); callbacks.setup = myVideoSetup; callbacks.submitDecodeUnit = myVideoSubmit; ``` -------------------------------- ### LiWakeWaitForVideoFrame Usage Example Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Interrupts a blocking wait during shutdown or to force a decoder thread to return. ```c // From shutdown handler or another thread void shutdown() { LiWakeWaitForVideoFrame(); // The decoder thread will return from LiWaitForNextVideoFrame() with false } ``` -------------------------------- ### Initialize Audio Callbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all audio decoder callback function pointers for safe initialization. ```c AUDIO_RENDERER_CALLBACKS callbacks; LiInitializeAudioCallbacks(&callbacks); callbacks.init = myAudioInit; callbacks.decodeAndPlaySample = myAudioDecode; ``` -------------------------------- ### LiInitializeAudioCallbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all audio decoder callback function pointers for safe initialization. ```APIDOC ## LiInitializeAudioCallbacks ### Description Zeros all audio decoder callback function pointers for safe initialization. ### Signature `void LiInitializeAudioCallbacks(PAUDIO_RENDERER_CALLBACKS arCallbacks);` ### Parameters - **arCallbacks** (PAUDIO_RENDERER_CALLBACKS) - Required - Pointer to audio renderer callbacks struct to zero ### Returns None. ``` -------------------------------- ### LiInitializeVideoCallbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all video decoder callback function pointers for safe initialization. ```APIDOC ## LiInitializeVideoCallbacks ### Description Zeros all video decoder callback function pointers for safe initialization. ### Signature `void LiInitializeVideoCallbacks(PDECODER_RENDERER_CALLBACKS drCallbacks);` ### Parameters - **drCallbacks** (PDECODER_RENDERER_CALLBACKS) - Required - Pointer to decoder renderer callbacks struct to zero ### Returns None. ``` -------------------------------- ### Initialize Server Information Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all fields in a server information structure for safe initialization on the stack or heap. ```c SERVER_INFORMATION server; LiInitializeServerInformation(&server); server.address = "192.168.1.50"; ``` -------------------------------- ### LiInitializeServerInformation Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all fields in a server information structure for safe initialization on the stack or heap. ```APIDOC ## LiInitializeServerInformation ### Description Zeros all fields in a server information structure for safe initialization on the stack or heap. ### Signature `void LiInitializeServerInformation(PSERVER_INFORMATION serverInfo);` ### Parameters - **serverInfo** (PSERVER_INFORMATION) - Required - Pointer to server information struct to zero ### Returns None. ``` -------------------------------- ### Get Pending Audio Frames Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves the count of queued audio frames. Only relevant when CAPABILITY_DIRECT_SUBMIT is not set. ```c int LiGetPendingAudioFrames(void); ``` ```c int pendingFrames = LiGetPendingAudioFrames(); ``` -------------------------------- ### Configure Include Directories and Definitions Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/CMakeLists.txt Sets public and private include paths and global compile definitions. ```cmake target_include_directories(moonlight-common-c SYSTEM PUBLIC src) target_include_directories(moonlight-common-c SYSTEM PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/nanors ${CMAKE_CURRENT_SOURCE_DIR}/nanors/deps ${CMAKE_CURRENT_SOURCE_DIR}/nanors/deps/obl ) target_compile_definitions(moonlight-common-c PRIVATE HAS_SOCKLEN_T) ``` -------------------------------- ### Get Protocol from Port Index Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connectivity-testing.md Determines the transport protocol (TCP or UDP) for a given port index constant. ```c int LiGetProtocolFromPortFlagIndex(int portFlagIndex); ``` ```c int protocol = LiGetProtocolFromPortFlagIndex(ML_PORT_INDEX_TCP_47984); if (protocol == IPPROTO_TCP) { printf("Port 47984 is TCP\n"); } ``` -------------------------------- ### Configure Server Application Version Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Set the application version from the server info response. ```c server.serverInfoAppVersion = "2021.12.1"; // From tag ``` -------------------------------- ### Configure Custom Audio Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Define a custom audio configuration using the MAKE_AUDIO_CONFIGURATION macro. ```c // Custom: 4 channels with specific channel mask config.audioConfiguration = MAKE_AUDIO_CONFIGURATION(4, 0x0F); ``` -------------------------------- ### Check Host Feature Flags Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Demonstrates how to check for specific input support using the bitmask returned by LiGetHostFeatureFlags. ```c uint32_t flags = LiGetHostFeatureFlags(); if (flags & LI_FF_PEN_TOUCH_EVENTS) { printf("Host supports pen/touch input\n"); } if (flags & LI_FF_CONTROLLER_TOUCH_EVENTS) { printf("Host supports controller touchpad input\n"); } ``` -------------------------------- ### Get Pending Audio Duration Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves the buffered audio duration in milliseconds. This is preferred over frame counts as it is agnostic to frame duration. ```c int LiGetPendingAudioDuration(void); ``` ```c int pendingMs = LiGetPendingAudioDuration(); if (pendingMs > 500) { printf("Audio buffer: %d ms\n", pendingMs); } ``` -------------------------------- ### Configure Predefined Audio Formats Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Set the audio configuration using predefined constants for stereo or surround sound. ```c // Stereo audio (2 channels, default) config.audioConfiguration = AUDIO_CONFIGURATION_STEREO; // 5.1 surround (6 channels) if supported by host config.audioConfiguration = AUDIO_CONFIGURATION_51_SURROUND; // 7.1 surround (8 channels) if supported by host config.audioConfiguration = AUDIO_CONFIGURATION_71_SURROUND; ``` -------------------------------- ### Get Port Number from Port Index Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connectivity-testing.md Retrieves the actual port number in host byte order for a specific port index constant. ```c unsigned short LiGetPortFromPortFlagIndex(int portFlagIndex); ``` ```c unsigned short port = LiGetPortFromPortFlagIndex(ML_PORT_INDEX_UDP_47998); printf("Video port: %u\n", port); // Output: "Video port: 47998" ``` -------------------------------- ### LiInitializeConnectionCallbacks Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all callback function pointers and event handlers for safe initialization. ```APIDOC ## LiInitializeConnectionCallbacks ### Description Zeros all callback function pointers and event handlers for safe initialization. ### Signature `void LiInitializeConnectionCallbacks(PCONNECTION_LISTENER_CALLBACKS clCallbacks);` ### Parameters - **clCallbacks** (PCONNECTION_LISTENER_CALLBACKS) - Required - Pointer to connection listener callbacks struct to zero ### Returns None. ``` -------------------------------- ### Get Port Flags from Termination Error Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connectivity-testing.md Maps a connection termination error code to the relevant port flags. Useful for diagnosing connectivity issues that occur after a connection has been established. ```c unsigned int LiGetPortFlagsFromTerminationErrorCode(int errorCode); ``` ```c void onConnectionTerminated(int errorCode) { printf("Connection terminated: error=%d\n", errorCode); unsigned int ports = LiGetPortFlagsFromTerminationErrorCode(errorCode); if (ports != 0) { unsigned int failed = LiTestClientConnectivity("test.moonlight-stream.org", 443, ports); if (failed != 0) { char portNames[256]; LiStringifyPortFlags(failed, ", ", portNames, sizeof(portNames)); printf("Likely blocked ports: %s\n", portNames); } } } ``` -------------------------------- ### Get Port Flags from Connection Stage Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connectivity-testing.md Retrieves a bitmask of ports associated with a specific connection stage. Use this to isolate testing to ports relevant to a failed initialization stage. ```c unsigned int LiGetPortFlagsFromStage(int stage); ``` ```c void onStageFailed(int stage, int errorCode) { printf("Stage %s failed\n", LiGetStageName(stage)); unsigned int ports = LiGetPortFlagsFromStage(stage); if (ports != 0) { printf("Testing ports involved in this stage...\n"); unsigned int failed = LiTestClientConnectivity("test.moonlight-stream.org", 443, ports); if (failed != 0) { char portNames[256]; LiStringifyPortFlags(failed, ", ", portNames, sizeof(portNames)); printf("Blocked ports: %s\n", portNames); } } } ``` -------------------------------- ### Build Library and Link Dependencies Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/CMakeLists.txt Creates the library target and links the required enet dependency. ```cmake if (NOT DEFINED BUILD_SHARED_LIBS) set(BUILD_SHARED_LIBS ON) set(BUILD_SHARED_LIBS_OVERRIDE ON) endif() add_library(moonlight-common-c ${SRC_LIST}) if (BUILD_SHARED_LIBS_OVERRIDE) unset(BUILD_SHARED_LIBS) unset(BUILD_SHARED_LIBS_OVERRIDE) endif() target_link_libraries(moonlight-common-c PRIVATE enet) ``` -------------------------------- ### LiStartConnection Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Initiates a connection to the server with pull-based rendering enabled by passing the CAPABILITY_PULL_RENDERER flag. ```APIDOC ## LiStartConnection ### Description Starts a connection to a streaming server. To enable pull-based rendering, the `drFlags` parameter must include `CAPABILITY_PULL_RENDERER`. ### Signature int LiStartConnection(PSERVER_INFORMATION server, PSTREAM_CONFIGURATION streamConfig, void* audioContext, PDECODER_RENDERER_CALLBACKS drCallbacks, void* videoContext, void* inputContext, int drFlags, char* remoteAddress, int remotePort); ### Parameters - **drFlags** (int) - Required - Set to `CAPABILITY_PULL_RENDERER` to enable pull-based rendering mode. - **drCallbacks** (PDECODER_RENDERER_CALLBACKS) - Required - Structure containing setup, start, stop, and cleanup callbacks. Note: `submitDecodeUnit` must not be provided in pull-based mode. ``` -------------------------------- ### Retrieve Launch URL Query Parameters Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Use this function to obtain parameters required for Sunshine-specific launch or resume endpoints. ```c const char* launchParams = LiGetLaunchUrlQueryParameters(); // Append to /launch or /resume endpoint // e.g., "https://host/apps/launch?app=...&launchParams=[result]" ``` -------------------------------- ### LiStartConnection Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/API_INDEX.md Establishes a streaming connection using the provided server information, stream configuration, and callback structures. ```APIDOC ## LiStartConnection ### Description Establishes a streaming connection. ### Signature `int LiStartConnection(PSERVER_INFORMATION, PSTREAM_CONFIGURATION, PCONNECTION_LISTENER_CALLBACKS, PDECODER_RENDERER_CALLBACKS, PAUDIO_RENDERER_CALLBACKS, void*, int, void*, int)` ### Returns int ``` -------------------------------- ### Configure CMake Project and Options Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/CMakeLists.txt Sets the minimum CMake version, project language, and user-configurable build options. ```cmake cmake_minimum_required(VERSION 3.1...4.0) project(moonlight-common-c LANGUAGES C) string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) option(USE_MBEDTLS "Use MbedTLS instead of OpenSSL" OFF) option(CODE_ANALYSIS "Run code analysis during compilation" OFF) SET(CMAKE_C_STANDARD 11) ``` -------------------------------- ### Configure Server Address Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Set the server address using an IP, hostname, or external URL. ```c server.address = "192.168.1.50"; // IP address server.address = "gamepc.local"; // Hostname/mDNS server.address = "example.com"; // External hostname for remote ``` -------------------------------- ### Configure Cryptography Backend Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/CMakeLists.txt Selects between MbedTLS and OpenSSL based on the USE_MBEDTLS option. ```cmake if (USE_MBEDTLS) target_compile_definitions(moonlight-common-c PRIVATE USE_MBEDTLS) find_package(MbedTLS QUIET) if (MBEDTLS_FOUND) target_link_libraries(moonlight-common-c PRIVATE ${MBEDCRYPTO_LIBRARY}) target_include_directories(moonlight-common-c SYSTEM PRIVATE ${MBEDTLS_INCLUDE_DIRS}) else() # For sub project added via CMake target_link_libraries(moonlight-common-c PRIVATE mbedcrypto) endif() else() find_package(OpenSSL 1.0.2 REQUIRED) target_link_libraries(moonlight-common-c PRIVATE ${OPENSSL_CRYPTO_LIBRARY}) target_include_directories(moonlight-common-c SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR}) endif() ``` -------------------------------- ### Extract Audio Configuration Details Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Retrieve channel count and mask from an existing audio configuration. ```c int channels = CHANNEL_COUNT_FROM_AUDIO_CONFIGURATION(config.audioConfiguration); int mask = CHANNEL_MASK_FROM_AUDIO_CONFIGURATION(config.audioConfiguration); ``` -------------------------------- ### Initialize Stream Configuration Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all fields in a stream configuration structure for safe initialization on the stack or heap. ```c STREAM_CONFIGURATION config; LiInitializeStreamConfiguration(&config); // Now safe to configure individual fields ``` -------------------------------- ### Configure Arbitrary Audio Duration Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Enable support for variable audio packet durations. ```c arCallbacks.capabilities = CAPABILITY_SUPPORTS_ARBITRARY_AUDIO_DURATION; ``` -------------------------------- ### Sending Multi-Touch Events Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Demonstrates a touch interaction sequence from down to move and finally up. Verify host support using LiGetHostFeatureFlags() with the LI_FF_PEN_TOUCH_EVENTS flag before calling. ```c // Single touch at center with full pressure LiSendTouchEvent( LI_TOUCH_EVENT_DOWN, // eventType 42, // pointerId (unique for this touch) 0.5, // x (center) 0.5, // y (center) 1.0, // pressureOrDistance (full pressure) 0.05, // contactAreaMajor 0.05, // contactAreaMinor LI_ROT_UNKNOWN // rotation ); // Move the same touch LiSendTouchEvent(LI_TOUCH_EVENT_MOVE, 42, 0.55, 0.55, 1.0, 0.05, 0.05, LI_ROT_UNKNOWN); // Release the touch LiSendTouchEvent(LI_TOUCH_EVENT_UP, 42, 0.55, 0.55, 0.0, 0.0, 0.0, LI_ROT_UNKNOWN); ``` -------------------------------- ### Enable Pull-Based Rendering Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/pull-based-rendering.md Set the CAPABILITY_PULL_RENDERER flag during connection initialization to enable pull-based mode. ```c DECODER_RENDERER_CALLBACKS drCallbacks; LiInitializeVideoCallbacks(&drCallbacks); drCallbacks.setup = myVideoSetup; drCallbacks.cleanup = myVideoCleanup; drCallbacks.start = myVideoStart; drCallbacks.stop = myVideoStop; int drFlags = CAPABILITY_PULL_RENDERER; LiStartConnection(&server, &streamConfig, NULL, &drCallbacks, NULL, NULL, drFlags, NULL, 0); ``` -------------------------------- ### Configure Pull Renderer Capability Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Enable demand-driven frame delivery for custom decoding threads. ```c int drFlags = CAPABILITY_PULL_RENDERER; LiStartConnection(&server, &config, NULL, &drCallbacks, NULL, NULL, drFlags, NULL, 0); ``` -------------------------------- ### Configure Direct Submit Capability Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Enable non-blocking frame submission directly to the callback. ```c // In callbacks struct drCallbacks.capabilities = CAPABILITY_DIRECT_SUBMIT; // Or in drFlags parameter int drFlags = CAPABILITY_DIRECT_SUBMIT; ``` -------------------------------- ### LiSendControllerTouchEvent Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Sends touchpad input for a game controller. ```APIDOC ## LiSendControllerTouchEvent ### Description Sends touchpad input for a game controller. Ensure the host supports controller touch events by checking the LI_FF_CONTROLLER_TOUCH_EVENTS flag via LiGetHostFeatureFlags(). ### Signature int LiSendControllerTouchEvent(uint8_t controllerNumber, uint8_t eventType, uint32_t pointerId, float x, float y, float pressure); ### Parameters - **controllerNumber** (uint8_t) - Required - Zero-based controller index - **eventType** (uint8_t) - Required - Touch event type - **pointerId** (uint32_t) - Required - Unique identifier for this touch - **x** (float) - Required - Normalized X coordinate (0.0-1.0) - **y** (float) - Required - Normalized Y coordinate (0.0-1.0) - **pressure** (float) - Required - Pressure (0.0-1.0) ### Returns 0 on success; LI_ERR_UNSUPPORTED if host doesn't support controller touch events. ``` -------------------------------- ### LiStartConnection Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Initiates a new GameStream streaming connection to a remote host. ```APIDOC ## LiStartConnection ### Description Initiates a new GameStream streaming connection to a remote host. ### Signature int LiStartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks, PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, void* renderContext, int drFlags, void* audioContext, int arFlags); ### Parameters - **serverInfo** (PSERVER_INFORMATION) - Required - Server connection details including address and codec capabilities - **streamConfig** (PSTREAM_CONFIGURATION) - Required - Stream quality and format parameters (resolution, bitrate, FPS, audio config) - **clCallbacks** (PCONNECTION_LISTENER_CALLBACKS) - Optional - Callbacks for connection lifecycle events, error reporting, and input feedback - **drCallbacks** (PDECODER_RENDERER_CALLBACKS) - Optional - Callbacks for video frame delivery and decoder lifecycle - **arCallbacks** (PAUDIO_RENDERER_CALLBACKS) - Optional - Callbacks for audio sample delivery and decoder lifecycle - **renderContext** (void*) - Optional - Opaque context pointer passed to video decoder callbacks - **drFlags** (int) - Optional - Video renderer capability flags - **audioContext** (void*) - Optional - Opaque context pointer passed to audio decoder callbacks - **arFlags** (int) - Optional - Audio renderer capability flags ### Returns 0 on successful stream negotiation and start; non-zero error code on failure. ``` -------------------------------- ### LiSendTouchEvent Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/API_INDEX.md Queues a touch event for the streaming session. ```APIDOC ## int LiSendTouchEvent(uint8_t type, uint32_t id, float x, float y, float pressure, float majAxis, float minAxis, uint16_t rotation) ### Description Queues a touch event to be sent to the host. ### Signature `int LiSendTouchEvent(uint8_t type, uint32_t id, float x, float y, float pressure, float majAxis, float minAxis, uint16_t rotation)` ``` -------------------------------- ### Configure Server Codec Support Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Define supported codecs based on the server info response. ```c server.serverCodecModeSupport = SCM_H264 | SCM_HEVC | SCM_HEVC_MAIN10; ``` -------------------------------- ### Check feature support before calling input functions Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/errors.md Use LiGetHostFeatureFlags to verify support for touch or pen events before invoking advanced input functions to avoid LI_ERR_UNSUPPORTED errors. ```c if (LiGetHostFeatureFlags() & LI_FF_PEN_TOUCH_EVENTS) { LiSendTouchEvent(...); // Safe to call } else { // Fall back to mouse events LiSendMousePositionEvent(...); } ``` -------------------------------- ### Input Handling Functions Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/README.md Functions for sending touch and mouse input events to the host. ```APIDOC ## LiSendTouchEvent / LiSendMousePositionEvent ### Description Functions to transmit input events to the streaming host. Use LiGetHostFeatureFlags to determine if touch events are supported before sending. ### Signatures - `void LiSendTouchEvent(int type, int pointerId, float x, float y, float pressure, float tiltX, float tiltY, int rotation)` - `void LiSendMousePositionEvent(int x, int y, int screenWidth, int screenHeight)` ``` -------------------------------- ### LiInitializeStreamConfiguration Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/connection-control.md Zeros all fields in a stream configuration structure for safe initialization on the stack or heap. ```APIDOC ## LiInitializeStreamConfiguration ### Description Zeros all fields in a stream configuration structure for safe initialization on the stack or heap. ### Signature `void LiInitializeStreamConfiguration(PSTREAM_CONFIGURATION streamConfig);` ### Parameters - **streamConfig** (PSTREAM_CONFIGURATION) - Required - Pointer to stream configuration struct to zero ### Returns None. ``` -------------------------------- ### Check for System Clock Support Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/CMakeLists.txt Verifies availability of clock_gettime and specific clock types on non-Windows/non-Apple platforms. ```cmake if (NOT(MSVC OR APPLE)) include(CheckLibraryExists) CHECK_LIBRARY_EXISTS(rt clock_gettime "" HAVE_CLOCK_GETTIME) if (NOT HAVE_CLOCK_GETTIME) set(CMAKE_EXTRA_INCLUDE_FILES time.h) CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME) SET(CMAKE_EXTRA_INCLUDE_FILES) endif() foreach(clock CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW) message(STATUS "Testing whether ${clock} can be used") CHECK_CXX_SOURCE_COMPILES( "#define _POSIX_C_SOURCE 200112L #include int main () { struct timespec ts[1]; clock_gettime (${clock}, ts); return 0; }" HAVE_${clock}) if(HAVE_${clock}) message(STATUS "Testing whether ${clock} can be used -- Success") else() message(STATUS "Testing whether ${clock} can be used -- Failed") endif() endforeach() endif() ``` -------------------------------- ### LiSendControllerArrivalEvent Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Notifies the host of a new controller with its capabilities. ```APIDOC ## LiSendControllerArrivalEvent ### Description Notifies the host of a new controller with its capabilities. ### Signature int LiSendControllerArrivalEvent(uint8_t controllerNumber, uint16_t activeGamepadMask, uint8_t type, uint32_t supportedButtonFlags, uint16_t capabilities); ### Parameters - **controllerNumber** (uint8_t) - Required - Zero-based controller index - **activeGamepadMask** (uint16_t) - Required - Bitmask of present controllers - **type** (uint8_t) - Required - Controller type: LI_CTYPE_XBOX, LI_CTYPE_PS, LI_CTYPE_NINTENDO, LI_CTYPE_UNKNOWN - **supportedButtonFlags** (uint32_t) - Required - Bitmask of supported button flags - **capabilities** (uint16_t) - Required - Feature capabilities bitmask (LI_CCAP_*) ### Returns 0 on success; LI_ERR_UNSUPPORTED if not supported by host (falls back to LiSendMultiControllerEvent). ### Example LiSendControllerArrivalEvent(0, 0x0001, LI_CTYPE_PS, (A_FLAG | B_FLAG | X_FLAG | Y_FLAG), LI_CCAP_ANALOG_TRIGGERS | LI_CCAP_RUMBLE); ``` -------------------------------- ### Queue Keyboard Event with LiSendKeyboardEvent Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Queues a keyboard event using Win32 Virtual Key codes interpreted as US English layout. ```c int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers); ``` ```c // Send Ctrl+C LiSendKeyboardEvent(0x43, KEY_ACTION_DOWN, MODIFIER_CTRL); // C key down LiSendKeyboardEvent(0x43, KEY_ACTION_UP, MODIFIER_CTRL); // C key up ``` -------------------------------- ### LiSendTouchEvent Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/input-events.md Sends multi-touch input events to Sunshine hosts. Requires checking for the LI_FF_PEN_TOUCH_EVENTS flag via LiGetHostFeatureFlags() before use. ```APIDOC ## LiSendTouchEvent ### Description Sends multi-touch input to Sunshine hosts. ### Signature int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, float pressureOrDistance, float contactAreaMajor, float contactAreaMinor, uint16_t rotation); ### Parameters - **eventType** (uint8_t) - Required - Touch event type (e.g., LI_TOUCH_EVENT_DOWN, LI_TOUCH_EVENT_UP, LI_TOUCH_EVENT_MOVE) - **pointerId** (uint32_t) - Required - Opaque unique identifier for this touch interaction - **x** (float) - Required - Normalized X coordinate (0.0 to 1.0) - **y** (float) - Required - Normalized Y coordinate (0.0 to 1.0) - **pressureOrDistance** (float) - Required - Pressure (0.0-1.0) or distance (1.0=far, 0.0=touching) - **contactAreaMajor** (float) - Required - Contact ellipse major axis (normalized) - **contactAreaMinor** (float) - Required - Contact ellipse minor axis (normalized) - **rotation** (uint16_t) - Required - Rotation in degrees (0-360) ### Returns 0 on success; LI_ERR_UNSUPPORTED if host doesn't support touch events. ``` -------------------------------- ### Check Host HDR Mode with LiGetCurrentHostDisplayHdrMode Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Retrieves the current HDR state from the host. Use this to synchronize local display settings with the host's HDR status. ```c bool LiGetCurrentHostDisplayHdrMode(void); ``` ```c if (LiGetCurrentHostDisplayHdrMode()) { printf("Host is in HDR mode\n"); enableLocalHdr(); } else { printf("Host is in SDR mode\n"); disableLocalHdr(); } ``` -------------------------------- ### Configure GFE Version Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/configuration.md Set the GFE version for GFE-specific hosts. ```c server.serverInfoGfeVersion = "3.21.0"; // From tag, if present ``` -------------------------------- ### Define STREAM_CONFIGURATION structure Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/types.md Used by LiStartConnection() to define streaming session parameters. Initialize using LiInitializeStreamConfiguration(). ```c typedef struct _STREAM_CONFIGURATION { int width; int height; int fps; int bitrate; int packetSize; int streamingRemotely; int audioConfiguration; int supportedVideoFormats; int clientRefreshRateX100; int colorSpace; int colorRange; int encryptionFlags; char remoteInputAesKey[16]; char remoteInputAesIv[16]; } STREAM_CONFIGURATION, *PSTREAM_CONFIGURATION; ``` -------------------------------- ### LiGetCurrentHostDisplayHdrMode Source: https://github.com/moonlight-stream/moonlight-common-c/blob/master/_autodocs/api-reference/streaming-status.md Returns the current HDR mode state on the host PC, allowing the client to synchronize its local display mode. ```APIDOC ## bool LiGetCurrentHostDisplayHdrMode(void) ### Description Returns the current HDR mode state on the host PC. This is useful for updating the local display mode to match the host. ### Returns - **bool** - true if HDR is enabled on the host; false otherwise. ### Example ```c if (LiGetCurrentHostDisplayHdrMode()) { printf("Host is in HDR mode\n"); enableLocalHdr(); } else { printf("Host is in SDR mode\n"); disableLocalHdr(); } ``` ```