mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-02-16 10:30:47 +00:00
Check display mode before streaming
This commit is contained in:
@@ -232,6 +232,9 @@ static int load_server_status(PSERVER_DATA server) {
|
||||
if (xml_search(data->memory, data->size, "GfeVersion", (char**) &server->serverInfo.serverInfoGfeVersion) != GS_OK)
|
||||
goto cleanup;
|
||||
|
||||
if (xml_modelist(data->memory, data->size, &server->modes) != GS_OK)
|
||||
goto cleanup;
|
||||
|
||||
// These fields are present on all version of GFE that this client supports
|
||||
if (!strlen(currentGameText) || !strlen(pairedText) || !strlen(server->serverInfo.serverInfoAppVersion) || !strlen(stateText))
|
||||
goto cleanup;
|
||||
@@ -641,6 +644,18 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b
|
||||
char* result = NULL;
|
||||
char uuid_str[37];
|
||||
|
||||
PDISPLAY_MODE mode = server->modes;
|
||||
bool correct_mode = false;
|
||||
while (mode != NULL) {
|
||||
if (mode->width == config->width && mode->height == config->height && mode->refresh == config->fps)
|
||||
correct_mode = true;
|
||||
|
||||
mode = mode->next;
|
||||
}
|
||||
|
||||
if (!correct_mode)
|
||||
return GS_NOT_SUPPORTED_MODE;
|
||||
|
||||
if (config->height >= 2160 && !server->supports4K)
|
||||
return GS_NOT_SUPPORTED_4K;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct _SERVER_DATA {
|
||||
int currentGame;
|
||||
int serverMajorVersion;
|
||||
char* gsVersion;
|
||||
PDISPLAY_MODE modes;
|
||||
SERVER_INFORMATION serverInfo;
|
||||
} SERVER_DATA, *PSERVER_DATA;
|
||||
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
#define GS_IO_ERROR -5
|
||||
#define GS_NOT_SUPPORTED_4K -6
|
||||
#define GS_UNSUPPORTED_VERSION -7
|
||||
#define GS_NOT_SUPPORTED_MODE -8
|
||||
|
||||
const char* gs_error;
|
||||
|
||||
@@ -79,6 +79,37 @@ static void XMLCALL _xml_end_applist_element(void *userData, const char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
static void XMLCALL _xml_start_mode_element(void *userData, const char *name, const char **atts) {
|
||||
struct xml_query *search = (struct xml_query*) userData;
|
||||
if (strcmp("DisplayMode", name) == 0) {
|
||||
PDISPLAY_MODE mode = calloc(1, sizeof(DISPLAY_MODE));
|
||||
if (mode != NULL) {
|
||||
mode->next = (PDISPLAY_MODE) search->data;
|
||||
search->data = mode;
|
||||
}
|
||||
} else if (search->data != NULL && (strcmp("Height", name) == 0 || strcmp("Width", name) == 0 || strcmp("RefreshRate", name) == 0)) {
|
||||
search->memory = malloc(1);
|
||||
search->size = 0;
|
||||
search->start = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void XMLCALL _xml_end_mode_element(void *userData, const char *name) {
|
||||
struct xml_query *search = (struct xml_query*) userData;
|
||||
if (search->data != NULL && search->start) {
|
||||
PDISPLAY_MODE mode = (PDISPLAY_MODE) search->data;
|
||||
if (strcmp("Width", name) == 0)
|
||||
mode->width = atoi(search->memory);
|
||||
else if (strcmp("Height", name) == 0)
|
||||
mode->height = atoi(search->memory);
|
||||
else if (strcmp("RefreshRate", name) == 0)
|
||||
mode->refresh = atoi(search->memory);
|
||||
|
||||
free(search->memory);
|
||||
search->start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void XMLCALL _xml_write_data(void *userData, const XML_Char *s, int len) {
|
||||
struct xml_query *search = (struct xml_query*) userData;
|
||||
if (search->start > 0) {
|
||||
@@ -141,3 +172,24 @@ int xml_applist(char* data, size_t len, PAPP_LIST *app_list) {
|
||||
|
||||
return GS_OK;
|
||||
}
|
||||
|
||||
int xml_modelist(char* data, size_t len, PDISPLAY_MODE *mode_list) {
|
||||
struct xml_query query = {0};
|
||||
query.memory = calloc(1, 1);
|
||||
XML_Parser parser = XML_ParserCreate("UTF-8");
|
||||
XML_SetUserData(parser, &query);
|
||||
XML_SetElementHandler(parser, _xml_start_mode_element, _xml_end_mode_element);
|
||||
XML_SetCharacterDataHandler(parser, _xml_write_data);
|
||||
if (! XML_Parse(parser, data, len, 1)) {
|
||||
int code = XML_GetErrorCode(parser);
|
||||
gs_error = XML_ErrorString(code);
|
||||
XML_ParserFree(parser);
|
||||
return GS_INVALID;
|
||||
}
|
||||
|
||||
XML_ParserFree(parser);
|
||||
*mode_list = (PDISPLAY_MODE) query.data;
|
||||
|
||||
return GS_OK;
|
||||
|
||||
}
|
||||
|
||||
@@ -26,5 +26,13 @@ typedef struct _APP_LIST {
|
||||
struct _APP_LIST *next;
|
||||
} APP_LIST, *PAPP_LIST;
|
||||
|
||||
typedef struct _DISPLAY_MODE {
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned int refresh;
|
||||
struct _DISPLAY_MODE *next;
|
||||
} DISPLAY_MODE, *PDISPLAY_MODE;
|
||||
|
||||
int xml_search(char* data, size_t len, char* node, char** result);
|
||||
int xml_applist(char* data, size_t len, PAPP_LIST *app_list);
|
||||
int xml_modelist(char* data, size_t len, PDISPLAY_MODE *mode_list);
|
||||
|
||||
@@ -88,6 +88,8 @@ static void stream(PSERVER_DATA server, PCONFIGURATION config, enum platform sys
|
||||
if (ret < 0) {
|
||||
if (ret == GS_NOT_SUPPORTED_4K)
|
||||
fprintf(stderr, "Server doesn't support 4K\n");
|
||||
else if (ret == GS_NOT_SUPPORTED_MODE)
|
||||
fprintf(stderr, "Server doesn't support %dx%d (%d fps)\n", config->stream.width, config->stream.height, config->stream.fps);
|
||||
else
|
||||
fprintf(stderr, "Errorcode starting app: %d\n", ret);
|
||||
exit(-1);
|
||||
|
||||
Reference in New Issue
Block a user