Handle file drop from input_manager

A file is pushed (or an apk is installed) to the device on file drop.
This behavior is specific to the screen and its input_manager.
This commit is contained in:
Romain Vimont 2022-01-21 19:26:36 +01:00
parent ebef027c4f
commit 1ffe312369
5 changed files with 48 additions and 36 deletions

View file

@ -128,6 +128,7 @@ sc_input_manager_init(struct sc_input_manager *im,
assert(!params->control || (params->mp && params->mp->ops)); assert(!params->control || (params->mp && params->mp->ops));
im->controller = params->controller; im->controller = params->controller;
im->fp = params->fp;
im->screen = params->screen; im->screen = params->screen;
im->kp = params->kp; im->kp = params->kp;
im->mp = params->mp; im->mp = params->mp;
@ -834,6 +835,34 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
im->mp->ops->process_mouse_scroll(im->mp, &evt); im->mp->ops->process_mouse_scroll(im->mp, &evt);
} }
static bool
is_apk(const char *file) {
const char *ext = strrchr(file, '.');
return ext && !strcmp(ext, ".apk");
}
static void
sc_input_manager_process_file(struct sc_input_manager *im,
const SDL_DropEvent *event) {
char *file = strdup(event->file);
SDL_free(event->file);
if (!file) {
LOG_OOM();
return;
}
enum sc_file_pusher_action action;
if (is_apk(file)) {
action = SC_FILE_PUSHER_ACTION_INSTALL_APK;
} else {
action = SC_FILE_PUSHER_ACTION_PUSH_FILE;
}
bool ok = sc_file_pusher_request(im->fp, action, file);
if (!ok) {
free(file);
}
}
void void
sc_input_manager_handle_event(struct sc_input_manager *im, SDL_Event *event) { sc_input_manager_handle_event(struct sc_input_manager *im, SDL_Event *event) {
switch (event->type) { switch (event->type) {
@ -872,5 +901,11 @@ sc_input_manager_handle_event(struct sc_input_manager *im, SDL_Event *event) {
case SDL_FINGERUP: case SDL_FINGERUP:
sc_input_manager_process_touch(im, &event->tfinger); sc_input_manager_process_touch(im, &event->tfinger);
break; break;
case SDL_DROPFILE: {
if (!im->control) {
break;
}
sc_input_manager_process_file(im, &event->drop);
}
} }
} }

View file

@ -8,6 +8,7 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "controller.h" #include "controller.h"
#include "file_pusher.h"
#include "fps_counter.h" #include "fps_counter.h"
#include "options.h" #include "options.h"
#include "trait/key_processor.h" #include "trait/key_processor.h"
@ -15,6 +16,7 @@
struct sc_input_manager { struct sc_input_manager {
struct sc_controller *controller; struct sc_controller *controller;
struct sc_file_pusher *fp;
struct sc_screen *screen; struct sc_screen *screen;
struct sc_key_processor *kp; struct sc_key_processor *kp;
@ -44,6 +46,7 @@ struct sc_input_manager {
struct sc_input_manager_params { struct sc_input_manager_params {
struct sc_controller *controller; struct sc_controller *controller;
struct sc_file_pusher *fp;
struct sc_screen *screen; struct sc_screen *screen;
struct sc_key_processor *kp; struct sc_key_processor *kp;
struct sc_mouse_processor *mp; struct sc_mouse_processor *mp;

View file

@ -148,12 +148,6 @@ sdl_configure(bool display, bool disable_screensaver) {
} }
} }
static bool
is_apk(const char *file) {
const char *ext = strrchr(file, '.');
return ext && !strcmp(ext, ".apk");
}
enum event_result { enum event_result {
EVENT_RESULT_CONTINUE, EVENT_RESULT_CONTINUE,
EVENT_RESULT_STOPPED_BY_USER, EVENT_RESULT_STOPPED_BY_USER,
@ -161,8 +155,7 @@ enum event_result {
}; };
static enum event_result static enum event_result
handle_event(struct scrcpy *s, const struct scrcpy_options *options, handle_event(struct scrcpy *s, SDL_Event *event) {
SDL_Event *event) {
switch (event->type) { switch (event->type) {
case EVENT_STREAM_STOPPED: case EVENT_STREAM_STOPPED:
LOGD("Video stream stopped"); LOGD("Video stream stopped");
@ -170,42 +163,17 @@ handle_event(struct scrcpy *s, const struct scrcpy_options *options,
case SDL_QUIT: case SDL_QUIT:
LOGD("User requested to quit"); LOGD("User requested to quit");
return EVENT_RESULT_STOPPED_BY_USER; return EVENT_RESULT_STOPPED_BY_USER;
case SDL_DROPFILE: {
if (!options->control) {
break;
}
char *file = strdup(event->drop.file);
SDL_free(event->drop.file);
if (!file) {
LOGW("Could not strdup drop filename\n");
break;
}
enum sc_file_pusher_action action;
if (is_apk(file)) {
action = SC_FILE_PUSHER_ACTION_INSTALL_APK;
} else {
action = SC_FILE_PUSHER_ACTION_PUSH_FILE;
}
bool ok = sc_file_pusher_request(&s->file_pusher, action, file);
if (!ok) {
free(file);
}
goto end;
}
} }
sc_screen_handle_event(&s->screen, event); sc_screen_handle_event(&s->screen, event);
end:
return EVENT_RESULT_CONTINUE; return EVENT_RESULT_CONTINUE;
} }
static bool static bool
event_loop(struct scrcpy *s, const struct scrcpy_options *options) { event_loop(struct scrcpy *s) {
SDL_Event event; SDL_Event event;
while (SDL_WaitEvent(&event)) { while (SDL_WaitEvent(&event)) {
enum event_result result = handle_event(s, options, &event); enum event_result result = handle_event(s, &event);
switch (result) { switch (result) {
case EVENT_RESULT_STOPPED_BY_USER: case EVENT_RESULT_STOPPED_BY_USER:
return true; return true;
@ -409,11 +377,14 @@ scrcpy(struct scrcpy_options *options) {
const char *serial = s->server.params.serial; const char *serial = s->server.params.serial;
assert(serial); assert(serial);
struct sc_file_pusher *fp = NULL;
if (options->display && options->control) { if (options->display && options->control) {
if (!sc_file_pusher_init(&s->file_pusher, serial, if (!sc_file_pusher_init(&s->file_pusher, serial,
options->push_target)) { options->push_target)) {
goto end; goto end;
} }
fp = &s->file_pusher;
file_pusher_initialized = true; file_pusher_initialized = true;
} }
@ -578,6 +549,7 @@ aoa_hid_end:
struct sc_screen_params screen_params = { struct sc_screen_params screen_params = {
.controller = &s->controller, .controller = &s->controller,
.fp = fp,
.kp = kp, .kp = kp,
.mp = mp, .mp = mp,
.control = options->control, .control = options->control,
@ -627,7 +599,7 @@ aoa_hid_end:
} }
stream_started = true; stream_started = true;
ret = event_loop(s, options); ret = event_loop(s);
LOGD("quit..."); LOGD("quit...");
// Close the window immediately on closing, because screen_destroy() may // Close the window immediately on closing, because screen_destroy() may

View file

@ -485,6 +485,7 @@ sc_screen_init(struct sc_screen *screen,
struct sc_input_manager_params im_params = { struct sc_input_manager_params im_params = {
.controller = params->controller, .controller = params->controller,
.fp = params->fp,
.screen = screen, .screen = screen,
.kp = params->kp, .kp = params->kp,
.mp = params->mp, .mp = params->mp,

View file

@ -70,6 +70,7 @@ struct sc_screen {
struct sc_screen_params { struct sc_screen_params {
struct sc_controller *controller; struct sc_controller *controller;
struct sc_file_pusher *fp;
struct sc_key_processor *kp; struct sc_key_processor *kp;
struct sc_mouse_processor *mp; struct sc_mouse_processor *mp;