Compare commits

...

2 commits

Author SHA1 Message Date
Romain Vimont 7cd1e39766 Toggle "raw key events" via shortcut
The "raw key events" mode may need to be toggled while scrcpy is
running (e.g. to type text then play a game).

Remove the command-line argument and bind Ctrl+k to toggle the mode.
2018-08-15 21:07:50 +02:00
Romain Vimont 9de332bbe5 Add "raw key events" mode
Add a command-line option to enable "raw key events" mode
(-k,--raw-key-events).

This disable text inputs and forwards "text" key events (which are
not forwarded by default).

This is helpful for gaming:
<https://github.com/Genymobile/scrcpy/issues/87>
<https://github.com/Genymobile/scrcpy/issues/127>
2018-08-15 20:29:07 +02:00
6 changed files with 104 additions and 4 deletions

View file

@ -338,12 +338,15 @@ To run without installing:
| turn screen on | _Right-click²_ |
| paste computer clipboard to device | `Ctrl`+`v` |
| enable/disable FPS counter (on stdout) | `Ctrl`+`i` |
| toggle "raw key events" mode ([#87]) | `Ctrl`+`k` |
| install APK from computer | drag & drop APK file |
| push file to `/sdcard/` | drag & drop non-APK file |
_¹Double-click on black borders to remove them._
_²Right-click turns the screen on if it was off, presses BACK otherwise._
[#87]: https://github.com/Genymobile/scrcpy/issues/87
## Why _scrcpy_?

View file

@ -70,6 +70,83 @@ static enum android_metastate convert_meta_state(SDL_Keymod mod) {
return autocomplete_metastate(metastate);
}
// only used if raw_key_events is enabled
static SDL_bool convert_text_keycode(SDL_Keycode from, enum android_keycode *to) {
switch (from) {
MAP(SDLK_SPACE, AKEYCODE_SPACE);
MAP(SDLK_HASH, AKEYCODE_POUND);
MAP(SDLK_QUOTE, AKEYCODE_APOSTROPHE);
MAP(SDLK_ASTERISK, AKEYCODE_STAR);
MAP(SDLK_COMMA, AKEYCODE_COMMA);
MAP(SDLK_MINUS, AKEYCODE_MINUS);
MAP(SDLK_PERIOD, AKEYCODE_PERIOD);
MAP(SDLK_SLASH, AKEYCODE_SLASH);
MAP(SDLK_0, AKEYCODE_0);
MAP(SDLK_1, AKEYCODE_1);
MAP(SDLK_2, AKEYCODE_2);
MAP(SDLK_3, AKEYCODE_3);
MAP(SDLK_4, AKEYCODE_4);
MAP(SDLK_5, AKEYCODE_5);
MAP(SDLK_6, AKEYCODE_6);
MAP(SDLK_7, AKEYCODE_7);
MAP(SDLK_8, AKEYCODE_8);
MAP(SDLK_9, AKEYCODE_9);
MAP(SDLK_SEMICOLON, AKEYCODE_SEMICOLON);
MAP(SDLK_EQUALS, AKEYCODE_EQUALS);
MAP(SDLK_AT, AKEYCODE_AT);
MAP(SDLK_LEFTBRACKET, AKEYCODE_LEFT_BRACKET);
MAP(SDLK_BACKSLASH, AKEYCODE_BACKSLASH);
MAP(SDLK_RIGHTBRACKET, AKEYCODE_RIGHT_BRACKET);
MAP(SDLK_BACKQUOTE, AKEYCODE_GRAVE);
MAP(SDLK_a, AKEYCODE_A);
MAP(SDLK_b, AKEYCODE_B);
MAP(SDLK_c, AKEYCODE_C);
MAP(SDLK_d, AKEYCODE_D);
MAP(SDLK_e, AKEYCODE_E);
MAP(SDLK_f, AKEYCODE_F);
MAP(SDLK_g, AKEYCODE_G);
MAP(SDLK_h, AKEYCODE_H);
MAP(SDLK_i, AKEYCODE_I);
MAP(SDLK_j, AKEYCODE_J);
MAP(SDLK_k, AKEYCODE_K);
MAP(SDLK_l, AKEYCODE_L);
MAP(SDLK_m, AKEYCODE_M);
MAP(SDLK_n, AKEYCODE_N);
MAP(SDLK_o, AKEYCODE_O);
MAP(SDLK_p, AKEYCODE_P);
MAP(SDLK_q, AKEYCODE_Q);
MAP(SDLK_r, AKEYCODE_R);
MAP(SDLK_s, AKEYCODE_S);
MAP(SDLK_t, AKEYCODE_T);
MAP(SDLK_u, AKEYCODE_U);
MAP(SDLK_v, AKEYCODE_V);
MAP(SDLK_w, AKEYCODE_W);
MAP(SDLK_x, AKEYCODE_X);
MAP(SDLK_y, AKEYCODE_Y);
MAP(SDLK_z, AKEYCODE_Z);
MAP(SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER);
MAP(SDLK_KP_1, AKEYCODE_NUMPAD_1);
MAP(SDLK_KP_2, AKEYCODE_NUMPAD_2);
MAP(SDLK_KP_3, AKEYCODE_NUMPAD_3);
MAP(SDLK_KP_4, AKEYCODE_NUMPAD_4);
MAP(SDLK_KP_5, AKEYCODE_NUMPAD_5);
MAP(SDLK_KP_6, AKEYCODE_NUMPAD_6);
MAP(SDLK_KP_7, AKEYCODE_NUMPAD_7);
MAP(SDLK_KP_8, AKEYCODE_NUMPAD_8);
MAP(SDLK_KP_9, AKEYCODE_NUMPAD_9);
MAP(SDLK_KP_0, AKEYCODE_NUMPAD_0);
MAP(SDLK_KP_DIVIDE, AKEYCODE_NUMPAD_DIVIDE);
MAP(SDLK_KP_MULTIPLY, AKEYCODE_NUMPAD_MULTIPLY);
MAP(SDLK_KP_MINUS, AKEYCODE_NUMPAD_SUBTRACT);
MAP(SDLK_KP_PLUS, AKEYCODE_NUMPAD_ADD);
MAP(SDLK_KP_PERIOD, AKEYCODE_NUMPAD_DOT);
MAP(SDLK_KP_EQUALS, AKEYCODE_NUMPAD_EQUALS);
MAP(SDLK_KP_LEFTPAREN, AKEYCODE_NUMPAD_LEFT_PAREN);
MAP(SDLK_KP_RIGHTPAREN, AKEYCODE_NUMPAD_RIGHT_PAREN);
FAIL;
}
}
static SDL_bool convert_keycode(SDL_Keycode from, enum android_keycode *to) {
switch (from) {
MAP(SDLK_RETURN, AKEYCODE_ENTER);
@ -119,7 +196,8 @@ static enum android_motionevent_buttons convert_mouse_buttons(Uint32 state) {
}
SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
struct control_event *to) {
struct control_event *to,
SDL_bool raw_key_events) {
to->type = CONTROL_EVENT_TYPE_KEYCODE;
if (!convert_keycode_action(from->type, &to->keycode_event.action)) {
@ -127,7 +205,10 @@ SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
}
if (!convert_keycode(from->keysym.sym, &to->keycode_event.keycode)) {
return SDL_FALSE;
if (!raw_key_events ||
!convert_text_keycode(from->keysym.sym, &to->keycode_event.keycode)) {
return SDL_FALSE;
}
}
to->keycode_event.metastate = convert_meta_state(from->keysym.mod);

View file

@ -16,7 +16,9 @@ struct complete_mouse_wheel_event {
};
SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
struct control_event *to);
struct control_event *to,
SDL_bool raw_key_events);
SDL_bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
struct size screen_size,
struct control_event *to);

View file

@ -129,6 +129,10 @@ static void clipboard_paste(struct controller *controller) {
void input_manager_process_text_input(struct input_manager *input_manager,
const SDL_TextInputEvent *event) {
if (input_manager->raw_key_events) {
// we will forward the raw key events instead
return;
}
struct control_event control_event;
control_event.type = CONTROL_EVENT_TYPE_TEXT;
control_event.text_event.text = SDL_strdup(event->text);
@ -216,13 +220,21 @@ void input_manager_process_key(struct input_manager *input_manager,
switch_fps_counter_state(input_manager->frames);
}
return;
case SDLK_k:
if (!repeat && event->type == SDL_KEYDOWN) {
input_manager->raw_key_events ^= SDL_TRUE; // toggle
LOGI("Raw key events mode %s",
input_manager->raw_key_events ? "enabled" : "disabled");
}
return;
}
return;
}
struct control_event control_event;
if (input_key_from_sdl_to_android(event, &control_event)) {
SDL_bool raw_key_events = input_manager->raw_key_events;
if (input_key_from_sdl_to_android(event, &control_event, raw_key_events)) {
if (!controller_push_event(input_manager->controller, &control_event)) {
LOGW("Cannot send control event");
}

View file

@ -11,6 +11,7 @@ struct input_manager {
struct controller *controller;
struct frames *frames;
struct screen *screen;
SDL_bool raw_key_events;
};
void input_manager_process_text_input(struct input_manager *input_manager,

View file

@ -35,6 +35,7 @@ static struct input_manager input_manager = {
.controller = &controller,
.frames = &frames,
.screen = &screen,
.raw_key_events = SDL_FALSE,
};
#if defined(__APPLE__) || defined(__WINDOWS__)