Add session input policy control stream support
This commit is contained in:
parent
6250fa29ee
commit
611a2e7f8f
3 changed files with 69 additions and 1 deletions
|
|
@ -83,6 +83,12 @@ typedef struct _QUEUED_ASYNC_CALLBACK {
|
||||||
uint8_t left[DS_EFFECT_PAYLOAD_SIZE];
|
uint8_t left[DS_EFFECT_PAYLOAD_SIZE];
|
||||||
uint8_t right[DS_EFFECT_PAYLOAD_SIZE];
|
uint8_t right[DS_EFFECT_PAYLOAD_SIZE];
|
||||||
} dsAdaptiveTrigger;
|
} dsAdaptiveTrigger;
|
||||||
|
struct {
|
||||||
|
uint8_t allowKeyboard;
|
||||||
|
uint8_t allowMouse;
|
||||||
|
uint8_t allowGamepad;
|
||||||
|
uint8_t reason;
|
||||||
|
} setInputPolicy;
|
||||||
} data;
|
} data;
|
||||||
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
||||||
} QUEUED_ASYNC_CALLBACK, *PQUEUED_ASYNC_CALLBACK;
|
} QUEUED_ASYNC_CALLBACK, *PQUEUED_ASYNC_CALLBACK;
|
||||||
|
|
@ -140,6 +146,7 @@ static PPLT_CRYPTO_CONTEXT decryptionCtx;
|
||||||
#define IDX_SET_MOTION_EVENT 10
|
#define IDX_SET_MOTION_EVENT 10
|
||||||
#define IDX_SET_RGB_LED 11
|
#define IDX_SET_RGB_LED 11
|
||||||
#define IDX_DS_ADAPTIVE_TRIGGERS 12
|
#define IDX_DS_ADAPTIVE_TRIGGERS 12
|
||||||
|
#define IDX_SET_INPUT_POLICY 13
|
||||||
|
|
||||||
#define CONTROL_STREAM_TIMEOUT_SEC 10
|
#define CONTROL_STREAM_TIMEOUT_SEC 10
|
||||||
#define CONTROL_STREAM_LINGER_TIMEOUT_SEC 2
|
#define CONTROL_STREAM_LINGER_TIMEOUT_SEC 2
|
||||||
|
|
@ -157,6 +164,7 @@ static const short packetTypesGen3[] = {
|
||||||
-1, // Rumble triggers (unused)
|
-1, // Rumble triggers (unused)
|
||||||
-1, // Set motion event (unused)
|
-1, // Set motion event (unused)
|
||||||
-1, // Set RGB LED (unused)
|
-1, // Set RGB LED (unused)
|
||||||
|
-1,
|
||||||
};
|
};
|
||||||
static const short packetTypesGen4[] = {
|
static const short packetTypesGen4[] = {
|
||||||
0x0606, // Request IDR frame
|
0x0606, // Request IDR frame
|
||||||
|
|
@ -171,6 +179,7 @@ static const short packetTypesGen4[] = {
|
||||||
-1, // Rumble triggers (unused)
|
-1, // Rumble triggers (unused)
|
||||||
-1, // Set motion event (unused)
|
-1, // Set motion event (unused)
|
||||||
-1, // Set RGB LED (unused)
|
-1, // Set RGB LED (unused)
|
||||||
|
-1,
|
||||||
};
|
};
|
||||||
static const short packetTypesGen5[] = {
|
static const short packetTypesGen5[] = {
|
||||||
0x0305, // Start A
|
0x0305, // Start A
|
||||||
|
|
@ -185,6 +194,7 @@ static const short packetTypesGen5[] = {
|
||||||
-1, // Rumble triggers (unused)
|
-1, // Rumble triggers (unused)
|
||||||
-1, // Set motion event (unused)
|
-1, // Set motion event (unused)
|
||||||
-1, // Set RGB LED (unused)
|
-1, // Set RGB LED (unused)
|
||||||
|
-1,
|
||||||
};
|
};
|
||||||
static const short packetTypesGen7[] = {
|
static const short packetTypesGen7[] = {
|
||||||
0x0305, // Start A
|
0x0305, // Start A
|
||||||
|
|
@ -199,6 +209,7 @@ static const short packetTypesGen7[] = {
|
||||||
-1, // Rumble triggers (unused)
|
-1, // Rumble triggers (unused)
|
||||||
-1, // Set motion event (unused)
|
-1, // Set motion event (unused)
|
||||||
-1, // Set RGB LED (unused)
|
-1, // Set RGB LED (unused)
|
||||||
|
-1,
|
||||||
};
|
};
|
||||||
static const short packetTypesGen7Enc[] = {
|
static const short packetTypesGen7Enc[] = {
|
||||||
0x0302, // Request IDR frame
|
0x0302, // Request IDR frame
|
||||||
|
|
@ -214,6 +225,7 @@ static const short packetTypesGen7Enc[] = {
|
||||||
0x5501, // Set motion event (Sunshine protocol extension)
|
0x5501, // Set motion event (Sunshine protocol extension)
|
||||||
0x5502, // Set RGB LED (Sunshine protocol extension)
|
0x5502, // Set RGB LED (Sunshine protocol extension)
|
||||||
0x5503, // Set Adaptive Triggers (Sunshine protocol extension)
|
0x5503, // Set Adaptive Triggers (Sunshine protocol extension)
|
||||||
|
0x5504,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char requestIdrFrameGen3[] = { 0, 0 };
|
static const char requestIdrFrameGen3[] = { 0, 0 };
|
||||||
|
|
@ -1010,6 +1022,12 @@ static void asyncCallbackThreadFunc(void* context) {
|
||||||
queuedCb->data.dsAdaptiveTrigger.left,
|
queuedCb->data.dsAdaptiveTrigger.left,
|
||||||
queuedCb->data.dsAdaptiveTrigger.right);
|
queuedCb->data.dsAdaptiveTrigger.right);
|
||||||
break;
|
break;
|
||||||
|
case IDX_SET_INPUT_POLICY:
|
||||||
|
ListenerCallbacks.setInputPolicy(queuedCb->data.setInputPolicy.allowKeyboard,
|
||||||
|
queuedCb->data.setInputPolicy.allowMouse,
|
||||||
|
queuedCb->data.setInputPolicy.allowGamepad,
|
||||||
|
queuedCb->data.setInputPolicy.reason);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Unhandled packet type from queueAsyncCallback()
|
// Unhandled packet type from queueAsyncCallback()
|
||||||
LC_ASSERT(false);
|
LC_ASSERT(false);
|
||||||
|
|
@ -1026,7 +1044,8 @@ static bool needsAsyncCallback(unsigned short packetType) {
|
||||||
packetType == packetTypes[IDX_SET_MOTION_EVENT] ||
|
packetType == packetTypes[IDX_SET_MOTION_EVENT] ||
|
||||||
packetType == packetTypes[IDX_SET_RGB_LED] ||
|
packetType == packetTypes[IDX_SET_RGB_LED] ||
|
||||||
packetType == packetTypes[IDX_HDR_INFO] ||
|
packetType == packetTypes[IDX_HDR_INFO] ||
|
||||||
packetType == packetTypes[IDX_DS_ADAPTIVE_TRIGGERS];
|
packetType == packetTypes[IDX_DS_ADAPTIVE_TRIGGERS] ||
|
||||||
|
packetType == packetTypes[IDX_SET_INPUT_POLICY];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void queueAsyncCallback(PNVCTL_ENET_PACKET_HEADER_V1 ctlHdr, int packetLength) {
|
static void queueAsyncCallback(PNVCTL_ENET_PACKET_HEADER_V1 ctlHdr, int packetLength) {
|
||||||
|
|
@ -1087,6 +1106,13 @@ static void queueAsyncCallback(PNVCTL_ENET_PACKET_HEADER_V1 ctlHdr, int packetLe
|
||||||
BbGetBytes(&bb, queuedCb->data.dsAdaptiveTrigger.right, DS_EFFECT_PAYLOAD_SIZE);
|
BbGetBytes(&bb, queuedCb->data.dsAdaptiveTrigger.right, DS_EFFECT_PAYLOAD_SIZE);
|
||||||
queuedCb->typeIndex = IDX_DS_ADAPTIVE_TRIGGERS;
|
queuedCb->typeIndex = IDX_DS_ADAPTIVE_TRIGGERS;
|
||||||
}
|
}
|
||||||
|
else if (ctlHdr->type == packetTypes[IDX_SET_INPUT_POLICY]) {
|
||||||
|
BbGet8(&bb, &queuedCb->data.setInputPolicy.allowKeyboard);
|
||||||
|
BbGet8(&bb, &queuedCb->data.setInputPolicy.allowMouse);
|
||||||
|
BbGet8(&bb, &queuedCb->data.setInputPolicy.allowGamepad);
|
||||||
|
BbGet8(&bb, &queuedCb->data.setInputPolicy.reason);
|
||||||
|
queuedCb->typeIndex = IDX_SET_INPUT_POLICY;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// Unhandled packet type from needsAsyncCallback()
|
// Unhandled packet type from needsAsyncCallback()
|
||||||
LC_ASSERT(false);
|
LC_ASSERT(false);
|
||||||
|
|
@ -1701,6 +1727,34 @@ int sendInputPacketOnControlStream(unsigned char* data, int length, uint8_t chan
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LiSendSessionInputPolicy(bool allowKeyboard, bool allowMouse, bool allowGamepad, uint8_t reason) {
|
||||||
|
struct {
|
||||||
|
uint8_t allowKeyboard;
|
||||||
|
uint8_t allowMouse;
|
||||||
|
uint8_t allowGamepad;
|
||||||
|
uint8_t reason;
|
||||||
|
} payload;
|
||||||
|
|
||||||
|
if (!IS_SUNSHINE() || AppVersionQuad[0] < 7) {
|
||||||
|
return LI_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client == NULL || peer == NULL || stopping) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.allowKeyboard = allowKeyboard ? 1 : 0;
|
||||||
|
payload.allowMouse = allowMouse ? 1 : 0;
|
||||||
|
payload.allowGamepad = allowGamepad ? 1 : 0;
|
||||||
|
payload.reason = reason;
|
||||||
|
|
||||||
|
if (sendMessageAndForget(0x5504, sizeof(payload), &payload, CTRL_CHANNEL_GENERIC, ENET_PACKET_FLAG_RELIABLE, false) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Called by the input stream to flush queued packets before a batching wait
|
// Called by the input stream to flush queued packets before a batching wait
|
||||||
void flushInputOnControlStream(void) {
|
void flushInputOnControlStream(void) {
|
||||||
if (AppVersionQuad[0] >= 5) {
|
if (AppVersionQuad[0] >= 5) {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ static void fakeClRumbleTriggers(uint16_t controllerNumber, uint16_t leftTrigger
|
||||||
static void fakeClSetMotionEventState(uint16_t controllerNumber, uint8_t motionType, uint16_t reportRateHz) {}
|
static void fakeClSetMotionEventState(uint16_t controllerNumber, uint8_t motionType, uint16_t reportRateHz) {}
|
||||||
static void fakeClSetAdaptiveTriggers(uint16_t controllerNumber, uint8_t eventFlags, uint8_t typeLeft, uint8_t typeRight, uint8_t *left, uint8_t *right) {};
|
static void fakeClSetAdaptiveTriggers(uint16_t controllerNumber, uint8_t eventFlags, uint8_t typeLeft, uint8_t typeRight, uint8_t *left, uint8_t *right) {};
|
||||||
static void fakeClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b) {}
|
static void fakeClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b) {}
|
||||||
|
static void fakeClSetInputPolicy(uint8_t allowKeyboard, uint8_t allowMouse, uint8_t allowGamepad, uint8_t reason) {}
|
||||||
|
|
||||||
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
||||||
.stageStarting = fakeClStageStarting,
|
.stageStarting = fakeClStageStarting,
|
||||||
|
|
@ -56,6 +57,7 @@ static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
||||||
.setMotionEventState = fakeClSetMotionEventState,
|
.setMotionEventState = fakeClSetMotionEventState,
|
||||||
.setControllerLED = fakeClSetControllerLED,
|
.setControllerLED = fakeClSetControllerLED,
|
||||||
.setAdaptiveTriggers = fakeClSetAdaptiveTriggers,
|
.setAdaptiveTriggers = fakeClSetAdaptiveTriggers,
|
||||||
|
.setInputPolicy = fakeClSetInputPolicy,
|
||||||
};
|
};
|
||||||
|
|
||||||
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
|
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
|
||||||
|
|
@ -146,5 +148,8 @@ void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_REND
|
||||||
if ((*clCallbacks)->setAdaptiveTriggers == NULL) {
|
if ((*clCallbacks)->setAdaptiveTriggers == NULL) {
|
||||||
(*clCallbacks)->setAdaptiveTriggers = fakeClSetAdaptiveTriggers;
|
(*clCallbacks)->setAdaptiveTriggers = fakeClSetAdaptiveTriggers;
|
||||||
}
|
}
|
||||||
|
if ((*clCallbacks)->setInputPolicy == NULL) {
|
||||||
|
(*clCallbacks)->setInputPolicy = fakeClSetInputPolicy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,8 @@ typedef void(*ConnListenerSetAdaptiveTriggers)(uint16_t controllerNumber, uint8_
|
||||||
// This callback is invoked to set a controller's RGB LED (if present).
|
// This callback is invoked to set a controller's RGB LED (if present).
|
||||||
typedef void(*ConnListenerSetControllerLED)(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b);
|
typedef void(*ConnListenerSetControllerLED)(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
typedef void(*ConnListenerSetInputPolicy)(uint8_t allowKeyboard, uint8_t allowMouse, uint8_t allowGamepad, uint8_t reason);
|
||||||
|
|
||||||
typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
||||||
ConnListenerStageStarting stageStarting;
|
ConnListenerStageStarting stageStarting;
|
||||||
ConnListenerStageComplete stageComplete;
|
ConnListenerStageComplete stageComplete;
|
||||||
|
|
@ -497,6 +499,7 @@ typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
||||||
ConnListenerSetMotionEventState setMotionEventState;
|
ConnListenerSetMotionEventState setMotionEventState;
|
||||||
ConnListenerSetControllerLED setControllerLED;
|
ConnListenerSetControllerLED setControllerLED;
|
||||||
ConnListenerSetAdaptiveTriggers setAdaptiveTriggers;
|
ConnListenerSetAdaptiveTriggers setAdaptiveTriggers;
|
||||||
|
ConnListenerSetInputPolicy setInputPolicy;
|
||||||
} CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS;
|
} CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS;
|
||||||
|
|
||||||
// Use this function to zero the connection callbacks when allocated on the stack or heap
|
// Use this function to zero the connection callbacks when allocated on the stack or heap
|
||||||
|
|
@ -837,6 +840,12 @@ int LiSendHighResScrollEvent(short scrollAmount);
|
||||||
int LiSendHScrollEvent(signed char scrollClicks);
|
int LiSendHScrollEvent(signed char scrollClicks);
|
||||||
int LiSendHighResHScrollEvent(short scrollAmount);
|
int LiSendHighResHScrollEvent(short scrollAmount);
|
||||||
|
|
||||||
|
#define LI_SESSION_INPUT_POLICY_REASON_STREAM_START 0x00
|
||||||
|
#define LI_SESSION_INPUT_POLICY_REASON_USER_TOGGLE 0x01
|
||||||
|
#define LI_SESSION_INPUT_POLICY_REASON_HOST_ACK 0x02
|
||||||
|
#define LI_SESSION_INPUT_POLICY_REASON_HOST_OVERRIDE 0x03
|
||||||
|
int LiSendSessionInputPolicy(bool allowKeyboard, bool allowMouse, bool allowGamepad, uint8_t reason);
|
||||||
|
|
||||||
// This function returns a time in microseconds with an implementation-defined epoch.
|
// This function returns a time in microseconds with an implementation-defined epoch.
|
||||||
// It should only ever be compared with the return value from a previous call to itself.
|
// It should only ever be compared with the return value from a previous call to itself.
|
||||||
uint64_t LiGetMicroseconds(void);
|
uint64_t LiGetMicroseconds(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue