Compare commits
7 Commits
server_thr
...
server_thr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4ee797401 | ||
|
|
d7106d7009 | ||
|
|
9e6687e698 | ||
|
|
dc05033441 | ||
|
|
dc652f67ce | ||
|
|
55641ceb64 | ||
|
|
fb330cc603 |
@@ -43,11 +43,6 @@
|
||||
# define SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
||||
// <https://github.com/libsdl-org/SDL/commit/d7a318de563125e5bb465b1000d6bc9576fbc6fc>
|
||||
# define SCRCPY_SDL_HAS_HINT_TOUCH_MOUSE_EVENTS
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 8)
|
||||
// <https://hg.libsdl.org/SDL/rev/dfde5d3f9781>
|
||||
# define SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
#define EVENT_STREAM_STOPPED (SDL_USEREVENT + 1)
|
||||
#define EVENT_SERVER_CONNECTION_FAILED (SDL_USEREVENT + 2)
|
||||
#define EVENT_SERVER_CONNECTED (SDL_USEREVENT + 3)
|
||||
#define EVENT_SERVER_DISCONNECTED (SDL_USEREVENT + 4)
|
||||
|
||||
@@ -79,8 +79,29 @@ BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
static void
|
||||
sdl_set_hints(const char *render_driver) {
|
||||
// init SDL and set appropriate hints
|
||||
static bool
|
||||
sdl_init_and_configure(bool display, const char *render_driver,
|
||||
bool disable_screensaver) {
|
||||
uint32_t flags = display ? SDL_INIT_VIDEO : SDL_INIT_EVENTS;
|
||||
if (SDL_Init(flags)) {
|
||||
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
atexit(SDL_Quit);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Clean up properly on Ctrl+C on Windows
|
||||
bool ok = SetConsoleCtrlHandler(windows_ctrl_handler, TRUE);
|
||||
if (!ok) {
|
||||
LOGW("Could not set Ctrl+C handler");
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
if (!display) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (render_driver && !SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver)) {
|
||||
LOGW("Could not set render driver");
|
||||
@@ -98,15 +119,6 @@ sdl_set_hints(const char *render_driver) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SCRCPY_SDL_HAS_HINT_TOUCH_MOUSE_EVENTS
|
||||
// Disable synthetic mouse events from touch events
|
||||
// Touch events with id SDL_TOUCH_MOUSEID are ignored anyway, but it is
|
||||
// better not to generate them in the first place.
|
||||
if (!SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0")) {
|
||||
LOGW("Could not disable synthetic mouse events");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SCRCPY_SDL_HAS_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
|
||||
// Disable compositor bypassing on X11
|
||||
if (!SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")) {
|
||||
@@ -118,21 +130,6 @@ sdl_set_hints(const char *render_driver) {
|
||||
if (!SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0")) {
|
||||
LOGW("Could not disable minimize on focus loss");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sdl_configure(bool display, bool disable_screensaver) {
|
||||
#ifdef _WIN32
|
||||
// Clean up properly on Ctrl+C on Windows
|
||||
bool ok = SetConsoleCtrlHandler(windows_ctrl_handler, TRUE);
|
||||
if (!ok) {
|
||||
LOGW("Could not set Ctrl+C handler");
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
if (!display) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (disable_screensaver) {
|
||||
LOGD("Screensaver disabled");
|
||||
@@ -141,6 +138,8 @@ sdl_configure(bool display, bool disable_screensaver) {
|
||||
LOGD("Screensaver enabled");
|
||||
SDL_EnableScreenSaver();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -159,6 +158,10 @@ static enum event_result
|
||||
handle_event(struct scrcpy *s, const struct scrcpy_options *options,
|
||||
SDL_Event *event) {
|
||||
switch (event->type) {
|
||||
case EVENT_SERVER_DISCONNECTED:
|
||||
LOGD("Server disconnected");
|
||||
// Do nothing, will be managed by the "stream stopped" event
|
||||
break;
|
||||
case EVENT_STREAM_STOPPED:
|
||||
LOGD("Video stream stopped");
|
||||
return EVENT_RESULT_STOPPED_BY_EOS;
|
||||
@@ -221,6 +224,9 @@ static bool
|
||||
await_for_server(void) {
|
||||
SDL_Event event;
|
||||
while (SDL_WaitEvent(&event)) {
|
||||
// Should never receive disconnected event before connected
|
||||
assert(event.type != EVENT_SERVER_DISCONNECTED);
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
LOGD("User requested to quit");
|
||||
@@ -306,8 +312,7 @@ server_on_disconnected(struct server *server, void *userdata) {
|
||||
(void) server;
|
||||
(void) userdata;
|
||||
|
||||
LOGD("Server disconnected");
|
||||
// Do nothing, will be managed by the "stream stopped" event
|
||||
PUSH_EVENT(EVENT_SERVER_DISCONNECTED);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -315,14 +320,6 @@ scrcpy(struct scrcpy_options *options) {
|
||||
static struct scrcpy scrcpy;
|
||||
struct scrcpy *s = &scrcpy;
|
||||
|
||||
// Minimal SDL initialization
|
||||
if (SDL_Init(SDL_INIT_EVENTS)) {
|
||||
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
atexit(SDL_Quit);
|
||||
|
||||
bool ret = false;
|
||||
|
||||
bool server_started = false;
|
||||
@@ -339,6 +336,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||
bool controller_started = false;
|
||||
bool screen_initialized = false;
|
||||
|
||||
bool record = !!options->record_filename;
|
||||
struct server_params params = {
|
||||
.serial = options->serial,
|
||||
.log_level = options->log_level,
|
||||
@@ -367,24 +365,18 @@ scrcpy(struct scrcpy_options *options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO SDL_Init(SDL_INIT_EVENTS) before starting server
|
||||
if (!server_start(&s->server)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
server_started = true;
|
||||
|
||||
if (options->display) {
|
||||
sdl_set_hints(options->render_driver);
|
||||
}
|
||||
|
||||
// Initialize SDL video in addition if display is enabled
|
||||
if (options->display && SDL_Init(SDL_INIT_VIDEO)) {
|
||||
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||
if (!sdl_init_and_configure(options->display, options->render_driver,
|
||||
options->disable_screensaver)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
sdl_configure(options->display, options->disable_screensaver);
|
||||
|
||||
// Await for server without blocking Ctrl+C handling
|
||||
if (!await_for_server()) {
|
||||
goto end;
|
||||
@@ -411,7 +403,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||
}
|
||||
|
||||
struct recorder *rec = NULL;
|
||||
if (options->record_filename) {
|
||||
if (record) {
|
||||
if (!recorder_init(&s->recorder,
|
||||
options->record_filename,
|
||||
options->record_format,
|
||||
|
||||
@@ -352,8 +352,7 @@ connect_and_read_byte(uint16_t port) {
|
||||
}
|
||||
|
||||
static sc_socket
|
||||
connect_to_server(struct server *server, uint32_t attempts, sc_tick delay) {
|
||||
uint16_t port = server->local_port;
|
||||
connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) {
|
||||
do {
|
||||
LOGD("Remaining connection attempts: %d", (int) attempts);
|
||||
sc_socket socket = connect_and_read_byte(port);
|
||||
@@ -363,16 +362,7 @@ connect_to_server(struct server *server, uint32_t attempts, sc_tick delay) {
|
||||
}
|
||||
// TODO use mutex + condvar + bool stopped
|
||||
if (attempts) {
|
||||
sc_mutex_lock(&server->mutex);
|
||||
// Ignore timedwait return (spurious wake ups are harmless)
|
||||
sc_cond_timedwait(&server->stopped_cond, &server->mutex,
|
||||
sc_tick_now() + delay);
|
||||
bool stopped = server->stopped;
|
||||
sc_mutex_unlock(&server->mutex);
|
||||
if (stopped) {
|
||||
LOGI("Connection attempt stopped");
|
||||
break;
|
||||
}
|
||||
SDL_Delay(delay);
|
||||
}
|
||||
} while (--attempts > 0);
|
||||
return SC_INVALID_SOCKET;
|
||||
@@ -402,16 +392,7 @@ server_init(struct server *server, const struct server_params *params,
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = sc_cond_init(&server->stopped_cond);
|
||||
if (!ok) {
|
||||
sc_cond_destroy(&server->process_terminated_cond);
|
||||
sc_mutex_destroy(&server->mutex);
|
||||
server_params_destroy(&server->params);
|
||||
return false;
|
||||
}
|
||||
|
||||
server->process_terminated = false;
|
||||
server->stopped = false;
|
||||
server->connected = false;
|
||||
|
||||
server->server_socket = SC_INVALID_SOCKET;
|
||||
@@ -558,8 +539,9 @@ server_connect_to(struct server *server, struct server_info *info) {
|
||||
server->server_socket = SC_INVALID_SOCKET;
|
||||
} else {
|
||||
uint32_t attempts = 100;
|
||||
sc_tick delay = SC_TICK_FROM_MS(100);
|
||||
server->video_socket = connect_to_server(server, attempts, delay);
|
||||
uint32_t delay = 100; // ms
|
||||
server->video_socket =
|
||||
connect_to_server(server->local_port, attempts, delay);
|
||||
if (server->video_socket == SC_INVALID_SOCKET) {
|
||||
return false;
|
||||
}
|
||||
@@ -582,11 +564,6 @@ server_connect_to(struct server *server, struct server_info *info) {
|
||||
|
||||
void
|
||||
server_stop(struct server *server) {
|
||||
sc_mutex_lock(&server->mutex);
|
||||
server->stopped = true;
|
||||
sc_cond_signal(&server->stopped_cond);
|
||||
sc_mutex_unlock(&server->mutex);
|
||||
|
||||
if (server->server_socket != SC_INVALID_SOCKET) {
|
||||
if (!net_interrupt(server->server_socket)) {
|
||||
LOGW("Could not interrupt server socket");
|
||||
@@ -654,7 +631,6 @@ server_destroy(struct server *server) {
|
||||
}
|
||||
|
||||
server_params_destroy(&server->params);
|
||||
sc_cond_destroy(&server->stopped_cond);
|
||||
sc_cond_destroy(&server->process_terminated_cond);
|
||||
sc_mutex_destroy(&server->mutex);
|
||||
}
|
||||
|
||||
@@ -47,13 +47,9 @@ struct server {
|
||||
sc_thread thread;
|
||||
|
||||
sc_mutex mutex;
|
||||
|
||||
sc_cond process_terminated_cond;
|
||||
bool process_terminated;
|
||||
|
||||
sc_cond stopped_cond;
|
||||
bool stopped;
|
||||
|
||||
bool connected; // written by connect_thread
|
||||
struct server_info info; // initialized once connected
|
||||
|
||||
|
||||
Reference in New Issue
Block a user