diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 76cfbd92..8e7a6402 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -87,8 +87,10 @@ sc_input_manager_init(struct sc_input_manager *im, } static void -send_keycode(struct sc_controller *controller, enum android_keycode keycode, +send_keycode(struct sc_input_manager *im, enum android_keycode keycode, enum sc_action action, const char *name) { + assert(im->controller); + // send DOWN event struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_INJECT_KEYCODE; @@ -99,100 +101,109 @@ send_keycode(struct sc_controller *controller, enum android_keycode keycode, msg.inject_keycode.metastate = 0; msg.inject_keycode.repeat = 0; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'inject %s'", name); } } static inline void -action_home(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_HOME, action, "HOME"); +action_home(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_HOME, action, "HOME"); } static inline void -action_back(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_BACK, action, "BACK"); +action_back(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_BACK, action, "BACK"); } static inline void -action_app_switch(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_APP_SWITCH, action, "APP_SWITCH"); +action_app_switch(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_APP_SWITCH, action, "APP_SWITCH"); } static inline void -action_power(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_POWER, action, "POWER"); +action_power(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_POWER, action, "POWER"); } static inline void -action_volume_up(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_VOLUME_UP, action, "VOLUME_UP"); +action_volume_up(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_VOLUME_UP, action, "VOLUME_UP"); } static inline void -action_volume_down(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_VOLUME_DOWN, action, "VOLUME_DOWN"); +action_volume_down(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_VOLUME_DOWN, action, "VOLUME_DOWN"); } static inline void -action_menu(struct sc_controller *controller, enum sc_action action) { - send_keycode(controller, AKEYCODE_MENU, action, "MENU"); +action_menu(struct sc_input_manager *im, enum sc_action action) { + send_keycode(im, AKEYCODE_MENU, action, "MENU"); } // turn the screen on if it was off, press BACK otherwise // If the screen is off, it is turned on only on ACTION_DOWN static void -press_back_or_turn_screen_on(struct sc_controller *controller, +press_back_or_turn_screen_on(struct sc_input_manager *im, enum sc_action action) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON; msg.back_or_screen_on.action = action == SC_ACTION_DOWN ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'press back or turn screen on'"); } } static void -expand_notification_panel(struct sc_controller *controller) { +expand_notification_panel(struct sc_input_manager *im) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'expand notification panel'"); } } static void -expand_settings_panel(struct sc_controller *controller) { +expand_settings_panel(struct sc_input_manager *im) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'expand settings panel'"); } } static void -collapse_panels(struct sc_controller *controller) { +collapse_panels(struct sc_input_manager *im) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_COLLAPSE_PANELS; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'collapse notification panel'"); } } static bool -get_device_clipboard(struct sc_controller *controller, - enum sc_copy_key copy_key) { +get_device_clipboard(struct sc_input_manager *im, enum sc_copy_key copy_key) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_GET_CLIPBOARD; msg.get_clipboard.copy_key = copy_key; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'get device clipboard'"); return false; } @@ -201,8 +212,10 @@ get_device_clipboard(struct sc_controller *controller, } static bool -set_device_clipboard(struct sc_controller *controller, bool paste, +set_device_clipboard(struct sc_input_manager *im, bool paste, uint64_t sequence) { + assert(im->controller); + char *text = SDL_GetClipboardText(); if (!text) { LOGW("Could not get clipboard text: %s", SDL_GetError()); @@ -222,7 +235,7 @@ set_device_clipboard(struct sc_controller *controller, bool paste, msg.set_clipboard.text = text_dup; msg.set_clipboard.paste = paste; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { free(text_dup); LOGW("Could not request 'set device clipboard'"); return false; @@ -232,19 +245,23 @@ set_device_clipboard(struct sc_controller *controller, bool paste, } static void -set_screen_power_mode(struct sc_controller *controller, +set_screen_power_mode(struct sc_input_manager *im, enum sc_screen_power_mode mode) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_SET_SCREEN_POWER_MODE; msg.set_screen_power_mode.mode = mode; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request 'set screen power mode'"); } } static void -switch_fps_counter_state(struct sc_fps_counter *fps_counter) { +switch_fps_counter_state(struct sc_input_manager *im) { + struct sc_fps_counter *fps_counter = &im->screen->fps_counter; + // the started state can only be written from the current thread, so there // is no ToCToU issue if (sc_fps_counter_is_started(fps_counter)) { @@ -256,7 +273,9 @@ switch_fps_counter_state(struct sc_fps_counter *fps_counter) { } static void -clipboard_paste(struct sc_controller *controller) { +clipboard_paste(struct sc_input_manager *im) { + assert(im->controller); + char *text = SDL_GetClipboardText(); if (!text) { LOGW("Could not get clipboard text: %s", SDL_GetError()); @@ -278,25 +297,28 @@ clipboard_paste(struct sc_controller *controller) { struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_INJECT_TEXT; msg.inject_text.text = text_dup; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { free(text_dup); LOGW("Could not request 'paste clipboard'"); } } static void -rotate_device(struct sc_controller *controller) { +rotate_device(struct sc_input_manager *im) { + assert(im->controller); + struct sc_control_msg msg; msg.type = SC_CONTROL_MSG_TYPE_ROTATE_DEVICE; - if (!sc_controller_push_msg(controller, &msg)) { + if (!sc_controller_push_msg(im->controller, &msg)) { LOGW("Could not request device rotation"); } } static void -apply_orientation_transform(struct sc_screen *screen, +apply_orientation_transform(struct sc_input_manager *im, enum sc_orientation transform) { + struct sc_screen *screen = im->screen; enum sc_orientation new_orientation = sc_orientation_apply(screen->orientation, transform); sc_screen_set_orientation(screen, new_orientation); @@ -364,7 +386,7 @@ static void sc_input_manager_process_key(struct sc_input_manager *im, const SDL_KeyboardEvent *event) { // controller is NULL if --no-control is requested - struct sc_controller *controller = im->controller; + bool control = im->controller; SDL_Keycode keycode = event->keysym.sym; uint16_t mod = event->keysym.mod; @@ -390,68 +412,68 @@ sc_input_manager_process_key(struct sc_input_manager *im, enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP; switch (keycode) { case SDLK_h: - if (controller && !shift && !repeat) { - action_home(controller, action); + if (control && !shift && !repeat) { + action_home(im, action); } return; case SDLK_b: // fall-through case SDLK_BACKSPACE: - if (controller && !shift && !repeat) { - action_back(controller, action); + if (control && !shift && !repeat) { + action_back(im, action); } return; case SDLK_s: - if (controller && !shift && !repeat) { - action_app_switch(controller, action); + if (control && !shift && !repeat) { + action_app_switch(im, action); } return; case SDLK_m: - if (controller && !shift && !repeat) { - action_menu(controller, action); + if (control && !shift && !repeat) { + action_menu(im, action); } return; case SDLK_p: - if (controller && !shift && !repeat) { - action_power(controller, action); + if (control && !shift && !repeat) { + action_power(im, action); } return; case SDLK_o: - if (controller && !repeat && down) { + if (control && !repeat && down) { enum sc_screen_power_mode mode = shift ? SC_SCREEN_POWER_MODE_NORMAL : SC_SCREEN_POWER_MODE_OFF; - set_screen_power_mode(controller, mode); + set_screen_power_mode(im, mode); } return; case SDLK_DOWN: if (shift) { if (!repeat & down) { - apply_orientation_transform(im->screen, + apply_orientation_transform(im, SC_ORIENTATION_FLIP_180); } - } else if (controller) { + } else if (control) { // forward repeated events - action_volume_down(controller, action); + action_volume_down(im, action); } return; case SDLK_UP: if (shift) { if (!repeat & down) { - apply_orientation_transform(im->screen, + apply_orientation_transform(im, SC_ORIENTATION_FLIP_180); } - } else if (controller) { + } else if (control) { // forward repeated events - action_volume_up(controller, action); + action_volume_up(im, action); } return; case SDLK_LEFT: if (!repeat && down) { if (shift) { - apply_orientation_transform(im->screen, + apply_orientation_transform(im, SC_ORIENTATION_FLIP_0); } else { - apply_orientation_transform(im->screen, + apply_orientation_transform(im, SC_ORIENTATION_270); } } @@ -459,34 +481,33 @@ sc_input_manager_process_key(struct sc_input_manager *im, case SDLK_RIGHT: if (!repeat && down) { if (shift) { - apply_orientation_transform(im->screen, + apply_orientation_transform(im, SC_ORIENTATION_FLIP_0); } else { - apply_orientation_transform(im->screen, + apply_orientation_transform(im, SC_ORIENTATION_90); } } return; case SDLK_c: - if (controller && !shift && !repeat && down) { - get_device_clipboard(controller, SC_COPY_KEY_COPY); + if (control && !shift && !repeat && down) { + get_device_clipboard(im, SC_COPY_KEY_COPY); } return; case SDLK_x: - if (controller && !shift && !repeat && down) { - get_device_clipboard(controller, SC_COPY_KEY_CUT); + if (control && !shift && !repeat && down) { + get_device_clipboard(im, SC_COPY_KEY_CUT); } return; case SDLK_v: - if (controller && !repeat && down) { + if (control && !repeat && down) { if (shift || im->legacy_paste) { // inject the text as input events - clipboard_paste(controller); + clipboard_paste(im); } else { // store the text in the device clipboard and paste, // without requesting an acknowledgment - set_device_clipboard(controller, true, - SC_SEQUENCE_INVALID); + set_device_clipboard(im, true, SC_SEQUENCE_INVALID); } } return; @@ -507,23 +528,23 @@ sc_input_manager_process_key(struct sc_input_manager *im, return; case SDLK_i: if (!shift && !repeat && down) { - switch_fps_counter_state(&im->screen->fps_counter); + switch_fps_counter_state(im); } return; case SDLK_n: - if (controller && !repeat && down) { + if (control && !repeat && down) { if (shift) { - collapse_panels(controller); + collapse_panels(im); } else if (im->key_repeat == 0) { - expand_notification_panel(controller); + expand_notification_panel(im); } else { - expand_settings_panel(controller); + expand_settings_panel(im); } } return; case SDLK_r: - if (controller && !shift && !repeat && down) { - rotate_device(controller); + if (control && !shift && !repeat && down) { + rotate_device(im); } return; } @@ -531,7 +552,7 @@ sc_input_manager_process_key(struct sc_input_manager *im, return; } - if (!controller) { + if (!control) { return; } @@ -540,7 +561,7 @@ sc_input_manager_process_key(struct sc_input_manager *im, if (im->clipboard_autosync && is_ctrl_v) { if (im->legacy_paste) { // inject the text as input events - clipboard_paste(controller); + clipboard_paste(im); return; } @@ -550,7 +571,7 @@ sc_input_manager_process_key(struct sc_input_manager *im, // Synchronize the computer clipboard to the device clipboard before // sending Ctrl+v, to allow seamless copy-paste. - bool ok = set_device_clipboard(controller, false, sequence); + bool ok = set_device_clipboard(im, false, sequence); if (!ok) { LOGW("Clipboard could not be synchronized, Ctrl+v not injected"); return; @@ -652,7 +673,7 @@ sc_input_manager_process_touch(struct sc_input_manager *im, static void sc_input_manager_process_mouse_button(struct sc_input_manager *im, const SDL_MouseButtonEvent *event) { - struct sc_controller *controller = im->controller; + bool control = im->controller; if (event->which == SDL_TOUCH_MOUSEID) { // simulated from touch events, so it's a duplicate @@ -661,27 +682,27 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im, bool down = event->type == SDL_MOUSEBUTTONDOWN; if (!im->forward_all_clicks) { - if (controller) { + if (control) { enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP; if (event->button == SDL_BUTTON_X1) { - action_app_switch(controller, action); + action_app_switch(im, action); return; } if (event->button == SDL_BUTTON_X2 && down) { if (event->clicks < 2) { - expand_notification_panel(controller); + expand_notification_panel(im); } else { - expand_settings_panel(controller); + expand_settings_panel(im); } return; } if (event->button == SDL_BUTTON_RIGHT) { - press_back_or_turn_screen_on(controller, action); + press_back_or_turn_screen_on(im, action); return; } if (event->button == SDL_BUTTON_MIDDLE) { - action_home(controller, action); + action_home(im, action); return; } } @@ -704,7 +725,7 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im, // otherwise, send the click event to the device } - if (!controller) { + if (!control) { return; }