mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-03-17 09:34:36 +01:00
Compare commits
9 Commits
disconnect
...
disconnect
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f237a4950 | ||
|
|
d36322c841 | ||
|
|
a7ff2ff6c7 | ||
|
|
2bdefc7663 | ||
|
|
9a079a716d | ||
|
|
cb6eee82cc | ||
|
|
ced45d0ec4 | ||
|
|
7958b297ec | ||
|
|
b4711a5904 |
@@ -1729,7 +1729,7 @@ parse_orientation(const char *s, enum sc_orientation *orientation) {
|
||||
return true;
|
||||
}
|
||||
LOGE("Unsupported orientation: %s (expected 0, 90, 180, 270, flip0, "
|
||||
"flip90, flip180 or flip270)", s);
|
||||
"flip90, flip180 or flip270)", optarg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
enum {
|
||||
SC_EVENT_NEW_FRAME = SDL_EVENT_USER,
|
||||
SC_EVENT_OPEN_WINDOW,
|
||||
SC_EVENT_RUN_ON_MAIN_THREAD,
|
||||
SC_EVENT_DEVICE_DISCONNECTED,
|
||||
SC_EVENT_SERVER_CONNECTION_FAILED,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "android/input.h"
|
||||
#include "android/keycodes.h"
|
||||
#include "events.h"
|
||||
#include "input_events.h"
|
||||
#include "screen.h"
|
||||
#include "shortcut_mod.h"
|
||||
@@ -47,8 +46,6 @@ sc_input_manager_init(struct sc_input_manager *im,
|
||||
im->key_repeat = 0;
|
||||
|
||||
im->next_sequence = 1; // 0 is reserved for SC_SEQUENCE_INVALID
|
||||
|
||||
im->disconnected = false;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -352,7 +349,7 @@ apply_orientation_transform(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_text_input(struct sc_input_manager *im,
|
||||
const SDL_TextInputEvent *event) {
|
||||
if (im->camera || !im->kp || im->screen->paused || im->disconnected) {
|
||||
if (im->camera || !im->kp || im->screen->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -420,7 +417,6 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
bool control = im->controller;
|
||||
bool paused = im->screen->paused;
|
||||
bool video = im->screen->video;
|
||||
bool disconnected = im->disconnected;
|
||||
|
||||
SDL_Keycode sdl_keycode = event->key;
|
||||
uint16_t mod = event->mod;
|
||||
@@ -437,7 +433,7 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
bool is_shortcut = sc_shortcut_mods_is_shortcut_mod(mods, mod)
|
||||
|| sc_shortcut_mods_is_shortcut_key(mods, sdl_keycode);
|
||||
|
||||
if (down && !repeat && !disconnected) {
|
||||
if (down && !repeat) {
|
||||
if (sdl_keycode == im->last_keycode && mod == im->last_mod) {
|
||||
++im->key_repeat;
|
||||
} else {
|
||||
@@ -514,12 +510,6 @@ sc_input_manager_process_key(struct sc_input_manager *im,
|
||||
return;
|
||||
}
|
||||
|
||||
if (disconnected) {
|
||||
// Only handle shortcuts that do not interact with the device (since
|
||||
// it is disconnected)
|
||||
return;
|
||||
}
|
||||
|
||||
// Flatten conditions to avoid additional indentation levels
|
||||
if (control) {
|
||||
// Controls for all sources
|
||||
@@ -728,7 +718,7 @@ sc_input_manager_get_position(struct sc_input_manager *im, int32_t x,
|
||||
static void
|
||||
sc_input_manager_process_mouse_motion(struct sc_input_manager *im,
|
||||
const SDL_MouseMotionEvent *event) {
|
||||
if (im->camera || !im->mp || im->screen->paused || im->disconnected) {
|
||||
if (im->camera || !im->mp || im->screen->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -767,7 +757,7 @@ sc_input_manager_process_mouse_motion(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_touch(struct sc_input_manager *im,
|
||||
const SDL_TouchFingerEvent *event) {
|
||||
if (im->camera || !im->mp || im->screen->paused || im->disconnected) {
|
||||
if (im->camera || !im->mp || im->screen->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -822,7 +812,7 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im,
|
||||
// some mouse events do not interact with the device, so process the event
|
||||
// even if control is disabled
|
||||
|
||||
if (im->camera || im->disconnected) {
|
||||
if (im->camera) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -993,7 +983,7 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
|
||||
const SDL_MouseWheelEvent *event) {
|
||||
if (im->camera || !im->kp || im->screen->paused || im->disconnected) {
|
||||
if (im->camera || !im->kp || im->screen->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1023,7 +1013,7 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
|
||||
const SDL_GamepadDeviceEvent *event) {
|
||||
// Handle device added or removed even if paused
|
||||
|
||||
if (im->camera || !im->gp || im->disconnected) {
|
||||
if (im->camera || !im->gp) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1068,7 +1058,7 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_gamepad_axis(struct sc_input_manager *im,
|
||||
const SDL_GamepadAxisEvent *event) {
|
||||
if (im->camera || !im->gp || im->screen->paused || im->disconnected) {
|
||||
if (im->camera || !im->gp || im->screen->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1088,7 +1078,7 @@ sc_input_manager_process_gamepad_axis(struct sc_input_manager *im,
|
||||
static void
|
||||
sc_input_manager_process_gamepad_button(struct sc_input_manager *im,
|
||||
const SDL_GamepadButtonEvent *event) {
|
||||
if (im->camera || !im->gp || im->screen->paused || im->disconnected) {
|
||||
if (im->camera || !im->gp || im->screen->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1114,7 +1104,7 @@ is_apk(const char *file) {
|
||||
static void
|
||||
sc_input_manager_process_file(struct sc_input_manager *im,
|
||||
const SDL_DropEvent *event) {
|
||||
if (im->camera || !im->controller || im->disconnected) {
|
||||
if (im->camera || !im->controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1137,16 +1127,6 @@ sc_input_manager_process_file(struct sc_input_manager *im,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sc_input_manager_on_device_disconnected(struct sc_input_manager *im) {
|
||||
im->disconnected = true;
|
||||
|
||||
struct sc_fps_counter *fps_counter = &im->screen->fps_counter;
|
||||
if (sc_fps_counter_is_started(fps_counter)) {
|
||||
sc_fps_counter_stop(fps_counter);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sc_input_manager_handle_event(struct sc_input_manager *im,
|
||||
const SDL_Event *event) {
|
||||
@@ -1187,8 +1167,5 @@ sc_input_manager_handle_event(struct sc_input_manager *im,
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
sc_input_manager_process_file(im, &event->drop);
|
||||
break;
|
||||
case SC_EVENT_DEVICE_DISCONNECTED:
|
||||
sc_input_manager_on_device_disconnected(im);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@ struct sc_input_manager {
|
||||
uint16_t last_mod;
|
||||
|
||||
uint64_t next_sequence; // used for request acknowledgements
|
||||
|
||||
bool disconnected;
|
||||
};
|
||||
|
||||
struct sc_input_manager_params {
|
||||
|
||||
@@ -205,23 +205,14 @@ sc_screen_render(struct sc_screen *screen, bool update_content_rect) {
|
||||
}
|
||||
|
||||
SDL_Renderer *renderer = screen->renderer;
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
sc_sdl_render_clear(renderer);
|
||||
|
||||
bool ok = false;
|
||||
SDL_Texture *texture = screen->tex.texture;
|
||||
if (!texture) {
|
||||
// Draw a dark 10x10 square in the top-right corner to distinguish a
|
||||
// black frame from the absence of a frame
|
||||
struct sc_size render_size = sc_sdl_get_render_output_size(renderer);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0x33, 0xff);
|
||||
SDL_FRect rect = {
|
||||
.x = render_size.width - 20,
|
||||
.y = 10,
|
||||
.w = 10,
|
||||
.h = 10,
|
||||
};
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
if (!screen->disconnected) {
|
||||
LOGW("No texture to render");
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -291,8 +282,11 @@ sc_screen_frame_sink_open(struct sc_frame_sink *sink,
|
||||
const AVCodecContext *ctx,
|
||||
const struct sc_stream_session *session) {
|
||||
assert(ctx->pix_fmt == AV_PIX_FMT_YUV420P);
|
||||
(void) ctx;
|
||||
(void) session;
|
||||
|
||||
struct sc_screen *screen = DOWNCAST(sink);
|
||||
(void) screen;
|
||||
|
||||
if (ctx->width <= 0 || ctx->width > 0xFFFF
|
||||
|| ctx->height <= 0 || ctx->height > 0xFFFF) {
|
||||
@@ -300,19 +294,6 @@ sc_screen_frame_sink_open(struct sc_frame_sink *sink,
|
||||
return false;
|
||||
}
|
||||
|
||||
// content_size can be written from this thread, because it is never read
|
||||
// from the main thread before handling SC_EVENT_OPEN_WINDOW (which acts as
|
||||
// a synchronization point) when video is enabled
|
||||
screen->frame_size.width = session->video.width;
|
||||
screen->frame_size.height = session->video.height;
|
||||
screen->content_size = get_oriented_size(screen->frame_size,
|
||||
screen->orientation);
|
||||
|
||||
bool ok = sc_push_event(SC_EVENT_OPEN_WINDOW);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
screen->open = true;
|
||||
#endif
|
||||
@@ -362,6 +343,7 @@ bool
|
||||
sc_screen_init(struct sc_screen *screen,
|
||||
const struct sc_screen_params *params) {
|
||||
screen->resize_pending = false;
|
||||
screen->has_frame = false;
|
||||
screen->window_shown = false;
|
||||
screen->paused = false;
|
||||
screen->resume_frame = NULL;
|
||||
@@ -741,14 +723,14 @@ sc_screen_set_orientation(struct sc_screen *screen,
|
||||
static bool
|
||||
sc_screen_apply_frame(struct sc_screen *screen) {
|
||||
assert(screen->video);
|
||||
assert(screen->window_shown);
|
||||
|
||||
sc_fps_counter_add_rendered_frame(&screen->fps_counter);
|
||||
|
||||
AVFrame *frame = screen->frame;
|
||||
struct sc_size new_frame_size = {frame->width, frame->height};
|
||||
|
||||
if (screen->frame_size.width != new_frame_size.width
|
||||
if (!screen->has_frame
|
||||
|| screen->frame_size.width != new_frame_size.width
|
||||
|| screen->frame_size.height != new_frame_size.height) {
|
||||
|
||||
// frame dimension changed
|
||||
@@ -756,8 +738,14 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
||||
|
||||
struct sc_size new_content_size =
|
||||
get_oriented_size(new_frame_size, screen->orientation);
|
||||
set_content_size(screen, new_content_size);
|
||||
sc_screen_update_content_rect(screen);
|
||||
if (screen->has_frame) {
|
||||
set_content_size(screen, new_content_size);
|
||||
sc_screen_update_content_rect(screen);
|
||||
} else {
|
||||
// This is the first frame
|
||||
screen->has_frame = true;
|
||||
screen->content_size = new_content_size;
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = sc_texture_set_from_frame(&screen->tex, frame);
|
||||
@@ -765,6 +753,17 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(screen->has_frame);
|
||||
if (!screen->window_shown) {
|
||||
// this is the very first frame, show the window
|
||||
sc_screen_show_initial_window(screen);
|
||||
|
||||
if (sc_screen_is_relative_mode(screen)) {
|
||||
// Capture mouse on start
|
||||
sc_mouse_capture_set_active(&screen->mc, true);
|
||||
}
|
||||
}
|
||||
|
||||
sc_screen_render(screen, false);
|
||||
return true;
|
||||
}
|
||||
@@ -907,16 +906,6 @@ sc_disconnect_on_timeout(struct sc_disconnect *d, void *userdata) {
|
||||
void
|
||||
sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
||||
switch (event->type) {
|
||||
case SC_EVENT_OPEN_WINDOW:
|
||||
sc_screen_show_initial_window(screen);
|
||||
|
||||
if (sc_screen_is_relative_mode(screen)) {
|
||||
// Capture mouse on start
|
||||
sc_mouse_capture_set_active(&screen->mc, true);
|
||||
}
|
||||
|
||||
sc_screen_render(screen, false);
|
||||
return;
|
||||
case SC_EVENT_NEW_FRAME: {
|
||||
bool ok = sc_screen_update_frame(screen);
|
||||
if (!ok) {
|
||||
@@ -959,8 +948,6 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
||||
return;
|
||||
}
|
||||
|
||||
sc_input_manager_handle_event(&screen->im, event);
|
||||
|
||||
sc_texture_reset(&screen->tex);
|
||||
sc_screen_render(screen, true);
|
||||
|
||||
@@ -1019,9 +1006,6 @@ sc_screen_handle_disconnection(struct sc_screen *screen) {
|
||||
sc_icon_destroy(icon_disconnected);
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
sc_screen_render(screen, true);
|
||||
break;
|
||||
case SC_EVENT_DISCONNECTED_TIMEOUT:
|
||||
LOGD("Closing after device disconnection");
|
||||
return;
|
||||
@@ -1029,8 +1013,6 @@ sc_screen_handle_disconnection(struct sc_screen *screen) {
|
||||
LOGD("User requested to quit");
|
||||
sc_screen_interrupt_disconnect(screen);
|
||||
return;
|
||||
default:
|
||||
sc_input_manager_handle_event(&screen->im, &event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ struct sc_screen {
|
||||
enum sc_orientation orientation;
|
||||
// rectangle of the content (excluding black borders)
|
||||
struct SDL_FRect rect;
|
||||
bool has_frame;
|
||||
bool window_shown;
|
||||
|
||||
AVFrame *frame;
|
||||
|
||||
@@ -93,4 +93,4 @@ Then just double-click on that file to run it.
|
||||
|
||||
To start scrcpy without opening a terminal, double-click `scrcpy-noconsole.vbs`
|
||||
(note that errors won't be shown). To pass arguments, edit (a copy of)
|
||||
`scrcpy-noconsole.vbs` and add the desired arguments.
|
||||
`scrcpy-noconsole.vbs` add and the desired arguments.
|
||||
|
||||
Reference in New Issue
Block a user