mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-06-17 14:22:00 +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)
|
if (xml_search(data->memory, data->size, "GfeVersion", (char**) &server->serverInfo.serverInfoGfeVersion) != GS_OK)
|
||||||
goto cleanup;
|
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
|
// These fields are present on all version of GFE that this client supports
|
||||||
if (!strlen(currentGameText) || !strlen(pairedText) || !strlen(server->serverInfo.serverInfoAppVersion) || !strlen(stateText))
|
if (!strlen(currentGameText) || !strlen(pairedText) || !strlen(server->serverInfo.serverInfoAppVersion) || !strlen(stateText))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -641,6 +644,18 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b
|
|||||||
char* result = NULL;
|
char* result = NULL;
|
||||||
char uuid_str[37];
|
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)
|
if (config->height >= 2160 && !server->supports4K)
|
||||||
return GS_NOT_SUPPORTED_4K;
|
return GS_NOT_SUPPORTED_4K;
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ typedef struct _SERVER_DATA {
|
|||||||
int currentGame;
|
int currentGame;
|
||||||
int serverMajorVersion;
|
int serverMajorVersion;
|
||||||
char* gsVersion;
|
char* gsVersion;
|
||||||
|
PDISPLAY_MODE modes;
|
||||||
SERVER_INFORMATION serverInfo;
|
SERVER_INFORMATION serverInfo;
|
||||||
} SERVER_DATA, *PSERVER_DATA;
|
} SERVER_DATA, *PSERVER_DATA;
|
||||||
|
|
||||||
|
|||||||
@@ -27,5 +27,6 @@
|
|||||||
#define GS_IO_ERROR -5
|
#define GS_IO_ERROR -5
|
||||||
#define GS_NOT_SUPPORTED_4K -6
|
#define GS_NOT_SUPPORTED_4K -6
|
||||||
#define GS_UNSUPPORTED_VERSION -7
|
#define GS_UNSUPPORTED_VERSION -7
|
||||||
|
#define GS_NOT_SUPPORTED_MODE -8
|
||||||
|
|
||||||
const char* gs_error;
|
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) {
|
static void XMLCALL _xml_write_data(void *userData, const XML_Char *s, int len) {
|
||||||
struct xml_query *search = (struct xml_query*) userData;
|
struct xml_query *search = (struct xml_query*) userData;
|
||||||
if (search->start > 0) {
|
if (search->start > 0) {
|
||||||
@@ -141,3 +172,24 @@ int xml_applist(char* data, size_t len, PAPP_LIST *app_list) {
|
|||||||
|
|
||||||
return GS_OK;
|
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;
|
struct _APP_LIST *next;
|
||||||
} APP_LIST, *PAPP_LIST;
|
} 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_search(char* data, size_t len, char* node, char** result);
|
||||||
int xml_applist(char* data, size_t len, PAPP_LIST *app_list);
|
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 < 0) {
|
||||||
if (ret == GS_NOT_SUPPORTED_4K)
|
if (ret == GS_NOT_SUPPORTED_4K)
|
||||||
fprintf(stderr, "Server doesn't support 4K\n");
|
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
|
else
|
||||||
fprintf(stderr, "Errorcode starting app: %d\n", ret);
|
fprintf(stderr, "Errorcode starting app: %d\n", ret);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
Reference in New Issue
Block a user