Compare commits
1 Commits
issue15.2
...
supports_i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e272561d6 |
@@ -116,6 +116,9 @@ conf.set('DEFAULT_LOCK_VIDEO_ORIENTATION', '-1') # -1: unlocked
|
|||||||
# overridden by option --bit-rate
|
# overridden by option --bit-rate
|
||||||
conf.set('DEFAULT_BIT_RATE', '8000000') # 8Mbps
|
conf.set('DEFAULT_BIT_RATE', '8000000') # 8Mbps
|
||||||
|
|
||||||
|
# enable High DPI support
|
||||||
|
conf.set('HIDPI_SUPPORT', get_option('hidpi_support'))
|
||||||
|
|
||||||
# disable console on Windows
|
# disable console on Windows
|
||||||
conf.set('WINDOWS_NOCONSOLE', get_option('windows_noconsole'))
|
conf.set('WINDOWS_NOCONSOLE', get_option('windows_noconsole'))
|
||||||
|
|
||||||
|
|||||||
@@ -442,6 +442,36 @@ input_manager_process_key(struct input_manager *im,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct point
|
||||||
|
rotate_position(struct screen *screen, int32_t x, int32_t y) {
|
||||||
|
unsigned rotation = screen->rotation;
|
||||||
|
assert(rotation < 4);
|
||||||
|
|
||||||
|
int32_t w = screen->content_size.width;
|
||||||
|
int32_t h = screen->content_size.height;
|
||||||
|
struct point result;
|
||||||
|
switch (rotation) {
|
||||||
|
case 0:
|
||||||
|
result.x = x;
|
||||||
|
result.y = y;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result.x = h - y;
|
||||||
|
result.y = x;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result.x = w - x;
|
||||||
|
result.y = h - y;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(rotation == 3);
|
||||||
|
result.x = y;
|
||||||
|
result.y = w - x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
|
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
|
||||||
struct control_msg *to) {
|
struct control_msg *to) {
|
||||||
@@ -450,7 +480,7 @@ convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
|
|||||||
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
|
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
|
||||||
to->inject_touch_event.position.screen_size = screen->frame_size;
|
to->inject_touch_event.position.screen_size = screen->frame_size;
|
||||||
to->inject_touch_event.position.point =
|
to->inject_touch_event.position.point =
|
||||||
screen_convert_to_frame_coords(screen, from->x, from->y);
|
rotate_position(screen, from->x, from->y);
|
||||||
to->inject_touch_event.pressure = 1.f;
|
to->inject_touch_event.pressure = 1.f;
|
||||||
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
|
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
|
||||||
|
|
||||||
@@ -485,13 +515,14 @@ convert_touch(const SDL_TouchFingerEvent *from, struct screen *screen,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct size frame_size = screen->frame_size;
|
||||||
|
|
||||||
to->inject_touch_event.pointer_id = from->fingerId;
|
to->inject_touch_event.pointer_id = from->fingerId;
|
||||||
to->inject_touch_event.position.screen_size = screen->frame_size;
|
to->inject_touch_event.position.screen_size = frame_size;
|
||||||
// SDL touch event coordinates are normalized in the range [0; 1]
|
// SDL touch event coordinates are normalized in the range [0; 1]
|
||||||
float x = from->x * screen->content_size.width;
|
float x = from->x * frame_size.width;
|
||||||
float y = from->y * screen->content_size.height;
|
float y = from->y * frame_size.height;
|
||||||
to->inject_touch_event.position.point =
|
to->inject_touch_event.position.point = rotate_position(screen, x, y);
|
||||||
screen_convert_to_frame_coords(screen, x, y);
|
|
||||||
to->inject_touch_event.pressure = from->pressure;
|
to->inject_touch_event.pressure = from->pressure;
|
||||||
to->inject_touch_event.buttons = 0;
|
to->inject_touch_event.buttons = 0;
|
||||||
return true;
|
return true;
|
||||||
@@ -527,7 +558,7 @@ convert_mouse_button(const SDL_MouseButtonEvent *from, struct screen *screen,
|
|||||||
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
|
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
|
||||||
to->inject_touch_event.position.screen_size = screen->frame_size;
|
to->inject_touch_event.position.screen_size = screen->frame_size;
|
||||||
to->inject_touch_event.position.point =
|
to->inject_touch_event.position.point =
|
||||||
screen_convert_to_frame_coords(screen, from->x, from->y);
|
rotate_position(screen, from->x, from->y);
|
||||||
to->inject_touch_event.pressure = 1.f;
|
to->inject_touch_event.pressure = 1.f;
|
||||||
to->inject_touch_event.buttons =
|
to->inject_touch_event.buttons =
|
||||||
convert_mouse_buttons(SDL_BUTTON(from->button));
|
convert_mouse_buttons(SDL_BUTTON(from->button));
|
||||||
|
|||||||
@@ -109,10 +109,9 @@ static int
|
|||||||
event_watcher(void *data, SDL_Event *event) {
|
event_watcher(void *data, SDL_Event *event) {
|
||||||
(void) data;
|
(void) data;
|
||||||
if (event->type == SDL_WINDOWEVENT
|
if (event->type == SDL_WINDOWEVENT
|
||||||
&& event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
&& event->window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||||
// In practice, it seems to always be called from the same thread in
|
// called from another thread, not very safe, but it's a workaround!
|
||||||
// that specific case. Anyway, it's just a workaround.
|
screen_render(&screen);
|
||||||
screen_handle_window_event(&screen, &event->window);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -128,7 +127,6 @@ enum event_result {
|
|||||||
EVENT_RESULT_CONTINUE,
|
EVENT_RESULT_CONTINUE,
|
||||||
EVENT_RESULT_STOPPED_BY_USER,
|
EVENT_RESULT_STOPPED_BY_USER,
|
||||||
EVENT_RESULT_STOPPED_BY_EOS,
|
EVENT_RESULT_STOPPED_BY_EOS,
|
||||||
EVENT_RESULT_STOPPED_BY_ERROR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum event_result
|
static enum event_result
|
||||||
@@ -151,9 +149,7 @@ handle_event(SDL_Event *event, bool control) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
if (!screen_handle_window_event(&screen, &event->window)) {
|
screen_handle_window_event(&screen, &event->window);
|
||||||
return EVENT_RESULT_STOPPED_BY_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SDL_TEXTINPUT:
|
case SDL_TEXTINPUT:
|
||||||
if (!control) {
|
if (!control) {
|
||||||
@@ -225,9 +221,6 @@ event_loop(bool display, bool control) {
|
|||||||
case EVENT_RESULT_STOPPED_BY_EOS:
|
case EVENT_RESULT_STOPPED_BY_EOS:
|
||||||
LOGW("Device disconnected");
|
LOGW("Device disconnected");
|
||||||
return false;
|
return false;
|
||||||
case EVENT_RESULT_STOPPED_BY_ERROR:
|
|
||||||
LOGC("Stopping due to unrecoverable error");
|
|
||||||
return false;
|
|
||||||
case EVENT_RESULT_CONTINUE:
|
case EVENT_RESULT_CONTINUE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
124
app/src/screen.c
124
app/src/screen.c
@@ -113,13 +113,6 @@ get_optimal_size(struct size current_size, struct size content_size) {
|
|||||||
h = MIN(current_size.height, display_size.height);
|
h = MIN(current_size.height, display_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h == w * content_size.height / content_size.width
|
|
||||||
|| w == h * content_size.width / content_size.height) {
|
|
||||||
// The size is already optimal, if we ignore rounding errors due to
|
|
||||||
// integer window dimensions
|
|
||||||
return (struct size) {w, h};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keep_width = content_size.width * h > content_size.height * w;
|
bool keep_width = content_size.width * h > content_size.height * w;
|
||||||
if (keep_width) {
|
if (keep_width) {
|
||||||
// remove black borders on top and bottom
|
// remove black borders on top and bottom
|
||||||
@@ -217,9 +210,10 @@ screen_init_rendering(struct screen *screen, const char *window_title,
|
|||||||
|
|
||||||
struct size window_size =
|
struct size window_size =
|
||||||
get_initial_optimal_size(content_size, window_width, window_height);
|
get_initial_optimal_size(content_size, window_width, window_height);
|
||||||
uint32_t window_flags = SDL_WINDOW_HIDDEN
|
uint32_t window_flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||||
| SDL_WINDOW_RESIZABLE
|
#ifdef HIDPI_SUPPORT
|
||||||
| SDL_WINDOW_ALLOW_HIGHDPI;
|
window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
|
#endif
|
||||||
if (always_on_top) {
|
if (always_on_top) {
|
||||||
#ifdef SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
|
#ifdef SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
|
||||||
window_flags |= SDL_WINDOW_ALWAYS_ON_TOP;
|
window_flags |= SDL_WINDOW_ALWAYS_ON_TOP;
|
||||||
@@ -264,7 +258,7 @@ screen_init_rendering(struct screen *screen, const char *window_title,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// starts with "opengl"
|
// stats with "opengl"
|
||||||
screen->use_opengl = renderer_name && !strncmp(renderer_name, "opengl", 6);
|
screen->use_opengl = renderer_name && !strncmp(renderer_name, "opengl", 6);
|
||||||
if (screen->use_opengl) {
|
if (screen->use_opengl) {
|
||||||
struct sc_opengl *gl = &screen->gl;
|
struct sc_opengl *gl = &screen->gl;
|
||||||
@@ -309,11 +303,6 @@ screen_init_rendering(struct screen *screen, const char *window_title,
|
|||||||
|
|
||||||
screen->windowed_window_size = window_size;
|
screen->windowed_window_size = window_size;
|
||||||
|
|
||||||
struct scale_ratio *rw = &screen->scale.w;
|
|
||||||
struct scale_ratio *rh = &screen->scale.h;
|
|
||||||
SDL_GetWindowSize(screen->window, &rw->window, &rh->window);
|
|
||||||
SDL_GL_GetDrawableSize(screen->window, &rw->drawable, &rh->drawable);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,8 +491,7 @@ screen_resize_to_fit(struct screen *screen) {
|
|||||||
struct size optimal_size =
|
struct size optimal_size =
|
||||||
get_optimal_window_size(screen, screen->content_size);
|
get_optimal_window_size(screen, screen->content_size);
|
||||||
SDL_SetWindowSize(screen->window, optimal_size.width, optimal_size.height);
|
SDL_SetWindowSize(screen->window, optimal_size.width, optimal_size.height);
|
||||||
LOGD("Resized to optimal size: %ux%u", optimal_size.width,
|
LOGD("Resized to optimal size");
|
||||||
optimal_size.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -519,78 +507,14 @@ screen_resize_to_pixel_perfect(struct screen *screen) {
|
|||||||
|
|
||||||
struct size content_size = screen->content_size;
|
struct size content_size = screen->content_size;
|
||||||
SDL_SetWindowSize(screen->window, content_size.width, content_size.height);
|
SDL_SetWindowSize(screen->window, content_size.width, content_size.height);
|
||||||
LOGD("Resized to pixel-perfect: %ux%u", content_size.width,
|
LOGD("Resized to pixel-perfect");
|
||||||
content_size.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
screen_fix_hidpi(struct screen *screen) {
|
|
||||||
// If the scale ratio has changed, recreate the renderer to fix HiDPI issues
|
|
||||||
// <https://github.com/Genymobile/scrcpy/issues/15>
|
|
||||||
|
|
||||||
int ww, wh, dw, dh;
|
|
||||||
SDL_GetWindowSize(screen->window, &ww, &wh);
|
|
||||||
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
|
|
||||||
|
|
||||||
struct scale_ratio *rw = &screen->scale.w;
|
|
||||||
struct scale_ratio *rh = &screen->scale.h;
|
|
||||||
|
|
||||||
if (ww * rw->drawable == dw * rw->window &&
|
|
||||||
wh * rh->drawable == dh * rh->window) {
|
|
||||||
// same ratio, both horizontally and vertically, nothing to do
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the current scale
|
|
||||||
rw->window = ww;
|
|
||||||
rh->window = wh;
|
|
||||||
rw->drawable = dw;
|
|
||||||
rh->drawable = dh;
|
|
||||||
|
|
||||||
if (screen->texture) {
|
|
||||||
SDL_DestroyTexture(screen->texture);
|
|
||||||
}
|
|
||||||
if (screen->renderer) {
|
|
||||||
SDL_DestroyRenderer(screen->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
screen->renderer = SDL_CreateRenderer(screen->window, -1,
|
|
||||||
SDL_RENDERER_ACCELERATED);
|
|
||||||
if (!screen->renderer) {
|
|
||||||
LOGC("Could not create renderer: %s", SDL_GetError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct size content_size = screen->content_size;
|
|
||||||
if (SDL_RenderSetLogicalSize(screen->renderer, content_size.width,
|
|
||||||
content_size.height)) {
|
|
||||||
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
|
||||||
SDL_DestroyRenderer(screen->renderer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME this is wrong, we must update the last frame to the new texture,
|
|
||||||
// but we don't have it anymore!
|
|
||||||
screen->texture = create_texture(screen);
|
|
||||||
if (!screen->texture) {
|
|
||||||
LOGC("Could not create texture: %s", SDL_GetError());
|
|
||||||
SDL_DestroyRenderer(screen->renderer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGD("Renderer and texture reset");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
screen_handle_window_event(struct screen *screen,
|
screen_handle_window_event(struct screen *screen,
|
||||||
const SDL_WindowEvent *event) {
|
const SDL_WindowEvent *event) {
|
||||||
switch (event->event) {
|
switch (event->event) {
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
case SDL_WINDOWEVENT_EXPOSED:
|
||||||
if (!screen_fix_hidpi(screen)) {
|
|
||||||
// unrecoverable
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
screen_render(screen);
|
screen_render(screen);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
@@ -626,36 +550,4 @@ screen_handle_window_event(struct screen *screen,
|
|||||||
apply_windowed_size(screen);
|
apply_windowed_size(screen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct point
|
|
||||||
screen_convert_to_frame_coords(struct screen *screen, int32_t x, int32_t y) {
|
|
||||||
unsigned rotation = screen->rotation;
|
|
||||||
assert(rotation < 4);
|
|
||||||
|
|
||||||
int32_t w = screen->content_size.width;
|
|
||||||
int32_t h = screen->content_size.height;
|
|
||||||
struct point result;
|
|
||||||
switch (rotation) {
|
|
||||||
case 0:
|
|
||||||
result.x = x;
|
|
||||||
result.y = y;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result.x = h - y;
|
|
||||||
result.y = x;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result.x = w - x;
|
|
||||||
result.y = h - y;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(rotation == 3);
|
|
||||||
result.x = y;
|
|
||||||
result.y = w - x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,6 @@
|
|||||||
|
|
||||||
struct video_buffer;
|
struct video_buffer;
|
||||||
|
|
||||||
struct scale_ratio {
|
|
||||||
int window;
|
|
||||||
int drawable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct screen {
|
struct screen {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
@@ -38,11 +33,6 @@ struct screen {
|
|||||||
bool maximized;
|
bool maximized;
|
||||||
bool no_window;
|
bool no_window;
|
||||||
bool mipmaps;
|
bool mipmaps;
|
||||||
|
|
||||||
struct {
|
|
||||||
struct scale_ratio w;
|
|
||||||
struct scale_ratio h;
|
|
||||||
} scale;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCREEN_INITIALIZER { \
|
#define SCREEN_INITIALIZER { \
|
||||||
@@ -73,16 +63,6 @@ struct screen {
|
|||||||
.maximized = false, \
|
.maximized = false, \
|
||||||
.no_window = false, \
|
.no_window = false, \
|
||||||
.mipmaps = false, \
|
.mipmaps = false, \
|
||||||
.scale = { \
|
|
||||||
.w = { \
|
|
||||||
.window = 0, \
|
|
||||||
.drawable = 0, \
|
|
||||||
}, \
|
|
||||||
.h = { \
|
|
||||||
.window = 0, \
|
|
||||||
.drawable = 0, \
|
|
||||||
}, \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize default values
|
// initialize default values
|
||||||
@@ -131,13 +111,7 @@ void
|
|||||||
screen_set_rotation(struct screen *screen, unsigned rotation);
|
screen_set_rotation(struct screen *screen, unsigned rotation);
|
||||||
|
|
||||||
// react to window events
|
// react to window events
|
||||||
// return true on success, false on unrecoverable error
|
void
|
||||||
bool
|
|
||||||
screen_handle_window_event(struct screen *screen, const SDL_WindowEvent *event);
|
screen_handle_window_event(struct screen *screen, const SDL_WindowEvent *event);
|
||||||
|
|
||||||
// convert point from window coordinates to frame coordinates
|
|
||||||
// x and y are expressed in pixels
|
|
||||||
struct point
|
|
||||||
screen_convert_to_frame_coords(struct screen *screen, int32_t x, int32_t y);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ option('crossbuild_windows', type: 'boolean', value: false, description: 'Build
|
|||||||
option('windows_noconsole', type: 'boolean', value: false, description: 'Disable console on Windows (pass -mwindows flag)')
|
option('windows_noconsole', type: 'boolean', value: false, description: 'Disable console on Windows (pass -mwindows flag)')
|
||||||
option('prebuilt_server', type: 'string', description: 'Path of the prebuilt server')
|
option('prebuilt_server', type: 'string', description: 'Path of the prebuilt server')
|
||||||
option('portable', type: 'boolean', value: false, description: 'Use scrcpy-server from the same directory as the scrcpy executable')
|
option('portable', type: 'boolean', value: false, description: 'Use scrcpy-server from the same directory as the scrcpy executable')
|
||||||
|
option('hidpi_support', type: 'boolean', value: true, description: 'Enable High DPI support')
|
||||||
option('server_debugger', type: 'boolean', value: false, description: 'Run a server debugger and wait for a client to be attached')
|
option('server_debugger', type: 'boolean', value: false, description: 'Run a server debugger and wait for a client to be attached')
|
||||||
option('server_debugger_method', type: 'combo', choices: ['old', 'new'], value: 'new', description: 'Select the debugger method (Android < 9: "old", Android >= 9: "new")')
|
option('server_debugger_method', type: 'combo', choices: ['old', 'new'], value: 'new', description: 'Select the debugger method (Android < 9: "old", Android >= 9: "new")')
|
||||||
|
|||||||
@@ -136,12 +136,12 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static MediaCodec createCodec() throws IOException {
|
private static MediaCodec createCodec() throws IOException {
|
||||||
return MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
|
return MediaCodec.createEncoderByType("video/avc");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MediaFormat createFormat(int bitRate, int maxFps, int iFrameInterval) {
|
private static MediaFormat createFormat(int bitRate, int maxFps, int iFrameInterval) {
|
||||||
MediaFormat format = new MediaFormat();
|
MediaFormat format = new MediaFormat();
|
||||||
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
|
format.setString(MediaFormat.KEY_MIME, "video/avc");
|
||||||
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
||||||
// must be present to configure the encoder, but does not impact the actual frame rate, which is variable
|
// must be present to configure the encoder, but does not impact the actual frame rate, which is variable
|
||||||
format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);
|
format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ public final class InputManager {
|
|||||||
method.invoke(inputEvent, displayId);
|
method.invoke(inputEvent, displayId);
|
||||||
return true;
|
return true;
|
||||||
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||||
Ln.e("Cannot associate a display id to the input event", e);
|
// just a warning, it might happen on old devices
|
||||||
|
Ln.w("Cannot associate a display id to the input event");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user