Extract mouse capture
Factorize mouse capture for relative mouse mode to reduce code duplication between normal and OTG modes. PR #5322 <https://github.com/Genymobile/scrcpy/pull/5322>
This commit is contained in:
parent
65fc53eace
commit
281fcc7052
@ -23,6 +23,7 @@ src = [
|
|||||||
'src/frame_buffer.c',
|
'src/frame_buffer.c',
|
||||||
'src/input_manager.c',
|
'src/input_manager.c',
|
||||||
'src/keyboard_sdk.c',
|
'src/keyboard_sdk.c',
|
||||||
|
'src/mouse_capture.c',
|
||||||
'src/mouse_sdk.c',
|
'src/mouse_sdk.c',
|
||||||
'src/opengl.c',
|
'src/opengl.c',
|
||||||
'src/options.c',
|
'src/options.c',
|
||||||
|
120
app/src/mouse_capture.c
Normal file
120
app/src/mouse_capture.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#include "mouse_capture.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_mouse_capture_init(struct sc_mouse_capture *mc, SDL_Window *window) {
|
||||||
|
mc->window = window;
|
||||||
|
mc->mouse_capture_key_pressed = SDLK_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
sc_mouse_capture_is_capture_key(SDL_Keycode key) {
|
||||||
|
return key == SDLK_LALT || key == SDLK_LGUI || key == SDLK_RGUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_mouse_capture_handle_event(struct sc_mouse_capture *mc,
|
||||||
|
const SDL_Event *event) {
|
||||||
|
switch (event->type) {
|
||||||
|
case SDL_WINDOWEVENT:
|
||||||
|
if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||||
|
sc_mouse_capture_set_active(mc, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_KEYDOWN: {
|
||||||
|
SDL_Keycode key = event->key.keysym.sym;
|
||||||
|
if (sc_mouse_capture_is_capture_key(key)) {
|
||||||
|
if (!mc->mouse_capture_key_pressed) {
|
||||||
|
mc->mouse_capture_key_pressed = key;
|
||||||
|
} else {
|
||||||
|
// Another mouse capture key has been pressed, cancel
|
||||||
|
// mouse (un)capture
|
||||||
|
mc->mouse_capture_key_pressed = 0;
|
||||||
|
}
|
||||||
|
// Mouse capture keys are never forwarded to the device
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_KEYUP: {
|
||||||
|
SDL_Keycode key = event->key.keysym.sym;
|
||||||
|
SDL_Keycode cap = mc->mouse_capture_key_pressed;
|
||||||
|
mc->mouse_capture_key_pressed = 0;
|
||||||
|
if (sc_mouse_capture_is_capture_key(key)) {
|
||||||
|
if (key == cap) {
|
||||||
|
// A mouse capture key has been pressed then released:
|
||||||
|
// toggle the capture mouse mode
|
||||||
|
sc_mouse_capture_toggle(mc);
|
||||||
|
}
|
||||||
|
// Mouse capture keys are never forwarded to the device
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_MOUSEWHEEL:
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
if (!sc_mouse_capture_is_active(mc)) {
|
||||||
|
// The mouse will be captured on SDL_MOUSEBUTTONUP, so consume
|
||||||
|
// the event
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
if (!sc_mouse_capture_is_active(mc)) {
|
||||||
|
sc_mouse_capture_set_active(mc, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_FINGERMOTION:
|
||||||
|
case SDL_FINGERDOWN:
|
||||||
|
case SDL_FINGERUP:
|
||||||
|
// Touch events are not compatible with relative mode
|
||||||
|
// (coordinates are not relative), so consume the event
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_mouse_capture_set_active(struct sc_mouse_capture *mc, bool capture) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// Workaround for SDL bug on macOS:
|
||||||
|
// <https://github.com/libsdl-org/SDL/issues/5340>
|
||||||
|
if (capture) {
|
||||||
|
int mouse_x, mouse_y;
|
||||||
|
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||||
|
|
||||||
|
int x, y, w, h;
|
||||||
|
SDL_GetWindowPosition(window, &x, &y);
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
|
||||||
|
bool outside_window = mouse_x < x || mouse_x >= x + w
|
||||||
|
|| mouse_y < y || mouse_y >= y + h;
|
||||||
|
if (outside_window) {
|
||||||
|
SDL_WarpMouseInWindow(mc->window, w / 2, h / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void) mc;
|
||||||
|
#endif
|
||||||
|
if (SDL_SetRelativeMouseMode(capture)) {
|
||||||
|
LOGE("Could not set relative mouse mode to %s: %s",
|
||||||
|
capture ? "true" : "false", SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_mouse_capture_is_active(struct sc_mouse_capture *mc) {
|
||||||
|
(void) mc;
|
||||||
|
return SDL_GetRelativeMouseMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_mouse_capture_toggle(struct sc_mouse_capture *mc) {
|
||||||
|
bool new_value = !sc_mouse_capture_is_active(mc);
|
||||||
|
sc_mouse_capture_set_active(mc, new_value);
|
||||||
|
}
|
35
app/src/mouse_capture.h
Normal file
35
app/src/mouse_capture.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef SC_MOUSE_CAPTURE_H
|
||||||
|
#define SC_MOUSE_CAPTURE_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
struct sc_mouse_capture {
|
||||||
|
SDL_Window *window;
|
||||||
|
|
||||||
|
// To enable/disable mouse capture, a mouse capture key (LALT, LGUI or
|
||||||
|
// RGUI) must be pressed. This variable tracks the pressed capture key.
|
||||||
|
SDL_Keycode mouse_capture_key_pressed;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_mouse_capture_init(struct sc_mouse_capture *mc, SDL_Window *window);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_mouse_capture_set_active(struct sc_mouse_capture *mc, bool capture);
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_mouse_capture_is_active(struct sc_mouse_capture *mc);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_mouse_capture_toggle(struct sc_mouse_capture *mc);
|
||||||
|
|
||||||
|
// Return true if it consumed the event
|
||||||
|
bool
|
||||||
|
sc_mouse_capture_handle_event(struct sc_mouse_capture *mc,
|
||||||
|
const SDL_Event *event);
|
||||||
|
|
||||||
|
#endif
|
123
app/src/screen.c
123
app/src/screen.c
@ -162,47 +162,6 @@ sc_screen_is_relative_mode(struct sc_screen *screen) {
|
|||||||
return screen->im.mp && screen->im.mp->relative_mode;
|
return screen->im.mp && screen->im.mp->relative_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sc_screen_set_mouse_capture(struct sc_screen *screen, bool capture) {
|
|
||||||
#ifdef __APPLE__
|
|
||||||
// Workaround for SDL bug on macOS:
|
|
||||||
// <https://github.com/libsdl-org/SDL/issues/5340>
|
|
||||||
if (capture) {
|
|
||||||
int mouse_x, mouse_y;
|
|
||||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
|
||||||
|
|
||||||
int x, y, w, h;
|
|
||||||
SDL_GetWindowPosition(screen->window, &x, &y);
|
|
||||||
SDL_GetWindowSize(screen->window, &w, &h);
|
|
||||||
|
|
||||||
bool outside_window = mouse_x < x || mouse_x >= x + w
|
|
||||||
|| mouse_y < y || mouse_y >= y + h;
|
|
||||||
if (outside_window) {
|
|
||||||
SDL_WarpMouseInWindow(screen->window, w / 2, h / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void) screen;
|
|
||||||
#endif
|
|
||||||
if (SDL_SetRelativeMouseMode(capture)) {
|
|
||||||
LOGE("Could not set relative mouse mode to %s: %s",
|
|
||||||
capture ? "true" : "false", SDL_GetError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
sc_screen_get_mouse_capture(struct sc_screen *screen) {
|
|
||||||
(void) screen;
|
|
||||||
return SDL_GetRelativeMouseMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
sc_screen_toggle_mouse_capture(struct sc_screen *screen) {
|
|
||||||
(void) screen;
|
|
||||||
bool new_value = !sc_screen_get_mouse_capture(screen);
|
|
||||||
sc_screen_set_mouse_capture(screen, new_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_screen_update_content_rect(struct sc_screen *screen) {
|
sc_screen_update_content_rect(struct sc_screen *screen) {
|
||||||
assert(screen->video);
|
assert(screen->video);
|
||||||
@ -371,7 +330,6 @@ sc_screen_init(struct sc_screen *screen,
|
|||||||
screen->fullscreen = false;
|
screen->fullscreen = false;
|
||||||
screen->maximized = false;
|
screen->maximized = false;
|
||||||
screen->minimized = false;
|
screen->minimized = false;
|
||||||
screen->mouse_capture_key_pressed = 0;
|
|
||||||
screen->paused = false;
|
screen->paused = false;
|
||||||
screen->resume_frame = NULL;
|
screen->resume_frame = NULL;
|
||||||
screen->orientation = SC_ORIENTATION_0;
|
screen->orientation = SC_ORIENTATION_0;
|
||||||
@ -486,6 +444,9 @@ sc_screen_init(struct sc_screen *screen,
|
|||||||
|
|
||||||
sc_input_manager_init(&screen->im, &im_params);
|
sc_input_manager_init(&screen->im, &im_params);
|
||||||
|
|
||||||
|
// Initialize even if not used for simplicity
|
||||||
|
sc_mouse_capture_init(&screen->mc, screen->window);
|
||||||
|
|
||||||
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
||||||
if (screen->video) {
|
if (screen->video) {
|
||||||
SDL_AddEventWatch(event_watcher, screen);
|
SDL_AddEventWatch(event_watcher, screen);
|
||||||
@ -506,7 +467,7 @@ sc_screen_init(struct sc_screen *screen,
|
|||||||
|
|
||||||
if (!screen->video && sc_screen_is_relative_mode(screen)) {
|
if (!screen->video && sc_screen_is_relative_mode(screen)) {
|
||||||
// Capture mouse immediately if video mirroring is disabled
|
// Capture mouse immediately if video mirroring is disabled
|
||||||
sc_screen_set_mouse_capture(screen, true);
|
sc_mouse_capture_set_active(&screen->mc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -713,7 +674,7 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
|||||||
|
|
||||||
if (sc_screen_is_relative_mode(screen)) {
|
if (sc_screen_is_relative_mode(screen)) {
|
||||||
// Capture mouse on start
|
// Capture mouse on start
|
||||||
sc_screen_set_mouse_capture(screen, true);
|
sc_mouse_capture_set_active(&screen->mc, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,15 +798,8 @@ sc_screen_resize_to_pixel_perfect(struct sc_screen *screen) {
|
|||||||
content_size.height);
|
content_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
|
||||||
sc_screen_is_mouse_capture_key(SDL_Keycode key) {
|
|
||||||
return key == SDLK_LALT || key == SDLK_LGUI || key == SDLK_RGUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
||||||
bool relative_mode = sc_screen_is_relative_mode(screen);
|
|
||||||
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SC_EVENT_SCREEN_INIT_SIZE: {
|
case SC_EVENT_SCREEN_INIT_SIZE: {
|
||||||
// The initial size is passed via screen->frame_size
|
// The initial size is passed via screen->frame_size
|
||||||
@ -903,69 +857,14 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
|||||||
apply_pending_resize(screen);
|
apply_pending_resize(screen);
|
||||||
sc_screen_render(screen, true);
|
sc_screen_render(screen, true);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
||||||
if (relative_mode) {
|
|
||||||
sc_screen_set_mouse_capture(screen, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case SDL_KEYDOWN:
|
}
|
||||||
if (relative_mode) {
|
|
||||||
SDL_Keycode key = event->key.keysym.sym;
|
if (sc_screen_is_relative_mode(screen)
|
||||||
if (sc_screen_is_mouse_capture_key(key)) {
|
&& sc_mouse_capture_handle_event(&screen->mc, event)) {
|
||||||
if (!screen->mouse_capture_key_pressed) {
|
// The mouse capture handler consumed the event
|
||||||
screen->mouse_capture_key_pressed = key;
|
return true;
|
||||||
} else {
|
|
||||||
// Another mouse capture key has been pressed, cancel
|
|
||||||
// mouse (un)capture
|
|
||||||
screen->mouse_capture_key_pressed = 0;
|
|
||||||
}
|
|
||||||
// Mouse capture keys are never forwarded to the device
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_KEYUP:
|
|
||||||
if (relative_mode) {
|
|
||||||
SDL_Keycode key = event->key.keysym.sym;
|
|
||||||
SDL_Keycode cap = screen->mouse_capture_key_pressed;
|
|
||||||
screen->mouse_capture_key_pressed = 0;
|
|
||||||
if (sc_screen_is_mouse_capture_key(key)) {
|
|
||||||
if (key == cap) {
|
|
||||||
// A mouse capture key has been pressed then released:
|
|
||||||
// toggle the capture mouse mode
|
|
||||||
sc_screen_toggle_mouse_capture(screen);
|
|
||||||
}
|
|
||||||
// Mouse capture keys are never forwarded to the device
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_MOUSEWHEEL:
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
if (relative_mode && !sc_screen_get_mouse_capture(screen)) {
|
|
||||||
// Do not forward to input manager, the mouse will be captured
|
|
||||||
// on SDL_MOUSEBUTTONUP
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_FINGERMOTION:
|
|
||||||
case SDL_FINGERDOWN:
|
|
||||||
case SDL_FINGERUP:
|
|
||||||
if (relative_mode) {
|
|
||||||
// Touch events are not compatible with relative mode
|
|
||||||
// (coordinates are not relative)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
if (relative_mode && !sc_screen_get_mouse_capture(screen)) {
|
|
||||||
sc_screen_set_mouse_capture(screen, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_input_manager_handle_event(&screen->im, event);
|
sc_input_manager_handle_event(&screen->im, event);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "fps_counter.h"
|
#include "fps_counter.h"
|
||||||
#include "frame_buffer.h"
|
#include "frame_buffer.h"
|
||||||
#include "input_manager.h"
|
#include "input_manager.h"
|
||||||
|
#include "mouse_capture.h"
|
||||||
#include "opengl.h"
|
#include "opengl.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "trait/key_processor.h"
|
#include "trait/key_processor.h"
|
||||||
@ -30,6 +31,7 @@ struct sc_screen {
|
|||||||
|
|
||||||
struct sc_display display;
|
struct sc_display display;
|
||||||
struct sc_input_manager im;
|
struct sc_input_manager im;
|
||||||
|
struct sc_mouse_capture mc; // only used in mouse relative mode
|
||||||
struct sc_frame_buffer fb;
|
struct sc_frame_buffer fb;
|
||||||
struct sc_fps_counter fps_counter;
|
struct sc_fps_counter fps_counter;
|
||||||
|
|
||||||
@ -61,10 +63,6 @@ struct sc_screen {
|
|||||||
bool maximized;
|
bool maximized;
|
||||||
bool minimized;
|
bool minimized;
|
||||||
|
|
||||||
// To enable/disable mouse capture, a mouse capture key (LALT, LGUI or
|
|
||||||
// RGUI) must be pressed. This variable tracks the pressed capture key.
|
|
||||||
SDL_Keycode mouse_capture_key_pressed;
|
|
||||||
|
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
|
|
||||||
bool paused;
|
bool paused;
|
||||||
|
@ -4,47 +4,6 @@
|
|||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
static void
|
|
||||||
sc_screen_otg_set_mouse_capture(struct sc_screen_otg *screen, bool capture) {
|
|
||||||
#ifdef __APPLE__
|
|
||||||
// Workaround for SDL bug on macOS:
|
|
||||||
// <https://github.com/libsdl-org/SDL/issues/5340>
|
|
||||||
if (capture) {
|
|
||||||
int mouse_x, mouse_y;
|
|
||||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
|
||||||
|
|
||||||
int x, y, w, h;
|
|
||||||
SDL_GetWindowPosition(screen->window, &x, &y);
|
|
||||||
SDL_GetWindowSize(screen->window, &w, &h);
|
|
||||||
|
|
||||||
bool outside_window = mouse_x < x || mouse_x >= x + w
|
|
||||||
|| mouse_y < y || mouse_y >= y + h;
|
|
||||||
if (outside_window) {
|
|
||||||
SDL_WarpMouseInWindow(screen->window, w / 2, h / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void) screen;
|
|
||||||
#endif
|
|
||||||
if (SDL_SetRelativeMouseMode(capture)) {
|
|
||||||
LOGE("Could not set relative mouse mode to %s: %s",
|
|
||||||
capture ? "true" : "false", SDL_GetError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
sc_screen_otg_get_mouse_capture(struct sc_screen_otg *screen) {
|
|
||||||
(void) screen;
|
|
||||||
return SDL_GetRelativeMouseMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
sc_screen_otg_toggle_mouse_capture(struct sc_screen_otg *screen) {
|
|
||||||
(void) screen;
|
|
||||||
bool new_value = !sc_screen_otg_get_mouse_capture(screen);
|
|
||||||
sc_screen_otg_set_mouse_capture(screen, new_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_screen_otg_render(struct sc_screen_otg *screen) {
|
sc_screen_otg_render(struct sc_screen_otg *screen) {
|
||||||
SDL_RenderClear(screen->renderer);
|
SDL_RenderClear(screen->renderer);
|
||||||
@ -61,8 +20,6 @@ sc_screen_otg_init(struct sc_screen_otg *screen,
|
|||||||
screen->mouse = params->mouse;
|
screen->mouse = params->mouse;
|
||||||
screen->gamepad = params->gamepad;
|
screen->gamepad = params->gamepad;
|
||||||
|
|
||||||
screen->mouse_capture_key_pressed = 0;
|
|
||||||
|
|
||||||
const char *title = params->window_title;
|
const char *title = params->window_title;
|
||||||
assert(title);
|
assert(title);
|
||||||
|
|
||||||
@ -113,9 +70,11 @@ sc_screen_otg_init(struct sc_screen_otg *screen,
|
|||||||
LOGW("Could not load icon");
|
LOGW("Could not load icon");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc_mouse_capture_init(&screen->mc, screen->window);
|
||||||
|
|
||||||
if (screen->mouse) {
|
if (screen->mouse) {
|
||||||
// Capture mouse on start
|
// Capture mouse on start
|
||||||
sc_screen_otg_set_mouse_capture(screen, true);
|
sc_mouse_capture_set_active(&screen->mc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -137,11 +96,6 @@ sc_screen_otg_destroy(struct sc_screen_otg *screen) {
|
|||||||
SDL_DestroyWindow(screen->window);
|
SDL_DestroyWindow(screen->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
|
||||||
sc_screen_otg_is_mouse_capture_key(SDL_Keycode key) {
|
|
||||||
return key == SDLK_LALT || key == SDLK_LGUI || key == SDLK_RGUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_screen_otg_process_key(struct sc_screen_otg *screen,
|
sc_screen_otg_process_key(struct sc_screen_otg *screen,
|
||||||
const SDL_KeyboardEvent *event) {
|
const SDL_KeyboardEvent *event) {
|
||||||
@ -298,80 +252,46 @@ sc_screen_otg_process_gamepad_button(struct sc_screen_otg *screen,
|
|||||||
|
|
||||||
void
|
void
|
||||||
sc_screen_otg_handle_event(struct sc_screen_otg *screen, SDL_Event *event) {
|
sc_screen_otg_handle_event(struct sc_screen_otg *screen, SDL_Event *event) {
|
||||||
|
if (sc_mouse_capture_handle_event(&screen->mc, event)) {
|
||||||
|
// The mouse capture handler consumed the event
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
switch (event->window.event) {
|
switch (event->window.event) {
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
case SDL_WINDOWEVENT_EXPOSED:
|
||||||
sc_screen_otg_render(screen);
|
sc_screen_otg_render(screen);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
||||||
if (screen->mouse) {
|
|
||||||
sc_screen_otg_set_mouse_capture(screen, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
if (screen->mouse) {
|
|
||||||
SDL_Keycode key = event->key.keysym.sym;
|
|
||||||
if (sc_screen_otg_is_mouse_capture_key(key)) {
|
|
||||||
if (!screen->mouse_capture_key_pressed) {
|
|
||||||
screen->mouse_capture_key_pressed = key;
|
|
||||||
} else {
|
|
||||||
// Another mouse capture key has been pressed, cancel
|
|
||||||
// mouse (un)capture
|
|
||||||
screen->mouse_capture_key_pressed = 0;
|
|
||||||
}
|
|
||||||
// Mouse capture keys are never forwarded to the device
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (screen->keyboard) {
|
if (screen->keyboard) {
|
||||||
sc_screen_otg_process_key(screen, &event->key);
|
sc_screen_otg_process_key(screen, &event->key);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
if (screen->mouse) {
|
|
||||||
SDL_Keycode key = event->key.keysym.sym;
|
|
||||||
SDL_Keycode cap = screen->mouse_capture_key_pressed;
|
|
||||||
screen->mouse_capture_key_pressed = 0;
|
|
||||||
if (sc_screen_otg_is_mouse_capture_key(key)) {
|
|
||||||
if (key == cap) {
|
|
||||||
// A mouse capture key has been pressed then released:
|
|
||||||
// toggle the capture mouse mode
|
|
||||||
sc_screen_otg_toggle_mouse_capture(screen);
|
|
||||||
}
|
|
||||||
// Mouse capture keys are never forwarded to the device
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (screen->keyboard) {
|
if (screen->keyboard) {
|
||||||
sc_screen_otg_process_key(screen, &event->key);
|
sc_screen_otg_process_key(screen, &event->key);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
if (screen->mouse && sc_screen_otg_get_mouse_capture(screen)) {
|
if (screen->mouse) {
|
||||||
sc_screen_otg_process_mouse_motion(screen, &event->motion);
|
sc_screen_otg_process_mouse_motion(screen, &event->motion);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
if (screen->mouse && sc_screen_otg_get_mouse_capture(screen)) {
|
if (screen->mouse) {
|
||||||
sc_screen_otg_process_mouse_button(screen, &event->button);
|
sc_screen_otg_process_mouse_button(screen, &event->button);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
if (screen->mouse) {
|
if (screen->mouse) {
|
||||||
if (sc_screen_otg_get_mouse_capture(screen)) {
|
sc_screen_otg_process_mouse_button(screen, &event->button);
|
||||||
sc_screen_otg_process_mouse_button(screen, &event->button);
|
|
||||||
} else {
|
|
||||||
sc_screen_otg_set_mouse_capture(screen, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
if (screen->mouse && sc_screen_otg_get_mouse_capture(screen)) {
|
if (screen->mouse) {
|
||||||
sc_screen_otg_process_mouse_wheel(screen, &event->wheel);
|
sc_screen_otg_process_mouse_wheel(screen, &event->wheel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "keyboard_aoa.h"
|
#include "keyboard_aoa.h"
|
||||||
#include "mouse_aoa.h"
|
#include "mouse_aoa.h"
|
||||||
|
#include "mouse_capture.h"
|
||||||
#include "gamepad_aoa.h"
|
#include "gamepad_aoa.h"
|
||||||
|
|
||||||
struct sc_screen_otg {
|
struct sc_screen_otg {
|
||||||
@ -19,8 +20,7 @@ struct sc_screen_otg {
|
|||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
|
|
||||||
// See equivalent mechanism in screen.h
|
struct sc_mouse_capture mc;
|
||||||
SDL_Keycode mouse_capture_key_pressed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_screen_otg_params {
|
struct sc_screen_otg_params {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user