Skip to content

Commit

Permalink
Handle mouse events outside device screen
Browse files Browse the repository at this point in the history
Mouse events position were unsigned (so negative values could not be
handled properly).

To avoid issues with negative values, mouse events outside the device
screen were ignored (commit a7fe9ad).

But as a consequence, drag&drop were "broken" if the "drop" occurred
outside the device screen.

Instead, use signed 32-bits to store the position, and forward events
outside the device screen.

Fixes <#357>.
  • Loading branch information
rom1v committed Nov 27, 2018
1 parent 7830859 commit fefb981
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 40 deletions.
4 changes: 2 additions & 2 deletions app/src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ struct size {
};

struct point {
Uint16 x;
Uint16 y;
Sint32 x;
Sint32 y;
};

struct position {
Expand Down
16 changes: 8 additions & 8 deletions app/src/control_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#include "log.h"

static void write_position(Uint8 *buf, const struct position *position) {
buffer_write16be(&buf[0], position->point.x);
buffer_write16be(&buf[2], position->point.y);
buffer_write16be(&buf[4], position->screen_size.width);
buffer_write16be(&buf[6], position->screen_size.height);
buffer_write32be(&buf[0], position->point.x);
buffer_write32be(&buf[4], position->point.y);
buffer_write16be(&buf[8], position->screen_size.width);
buffer_write16be(&buf[10], position->screen_size.height);
}

int control_event_serialize(const struct control_event *event, unsigned char *buf) {
Expand All @@ -37,12 +37,12 @@ int control_event_serialize(const struct control_event *event, unsigned char *bu
buf[1] = event->mouse_event.action;
buffer_write32be(&buf[2], event->mouse_event.buttons);
write_position(&buf[6], &event->mouse_event.position);
return 14;
return 18;
case CONTROL_EVENT_TYPE_SCROLL:
write_position(&buf[1], &event->scroll_event.position);
buffer_write32be(&buf[9], (Uint32) event->scroll_event.hscroll);
buffer_write32be(&buf[13], (Uint32) event->scroll_event.vscroll);
return 17;
buffer_write32be(&buf[13], (Uint32) event->scroll_event.hscroll);
buffer_write32be(&buf[17], (Uint32) event->scroll_event.vscroll);
return 21;
case CONTROL_EVENT_TYPE_COMMAND:
buf[1] = event->command_event.action;
return 2;
Expand Down
45 changes: 17 additions & 28 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int
*y = (int) (*y / scale_y) - viewport.y;
}

static void get_mouse_point(struct screen *screen, int *x, int *y) {
SDL_GetMouseState(x, y);
convert_to_renderer_coordinates(screen->renderer, x, y);
static struct point get_mouse_point(struct screen *screen) {
int x;
int y;
SDL_GetMouseState(&x, &y);
convert_to_renderer_coordinates(screen->renderer, &x, &y);
return (struct point) {
.x = x,
.y = y,
};
}

static const int ACTION_DOWN = 1;
Expand Down Expand Up @@ -273,9 +279,6 @@ static SDL_bool is_outside_device_screen(struct input_manager *input_manager,

void input_manager_process_mouse_button(struct input_manager *input_manager,
const SDL_MouseButtonEvent *event) {
SDL_bool outside_device_screen = is_outside_device_screen(input_manager,
event->x,
event->y);
if (event->type == SDL_MOUSEBUTTONDOWN) {
if (event->button == SDL_BUTTON_RIGHT) {
press_back_or_turn_screen_on(input_manager->controller);
Expand All @@ -286,19 +289,18 @@ void input_manager_process_mouse_button(struct input_manager *input_manager,
return;
}
// double-click on black borders resize to fit the device screen
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2
&& outside_device_screen) {
screen_resize_to_fit(input_manager->screen);
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
SDL_bool outside= is_outside_device_screen(input_manager,
event->x,
event->y);
if (outside) {
screen_resize_to_fit(input_manager->screen);
}
return;
}
// otherwise, send the click event to the device
}

if (outside_device_screen) {
// ignore
return;
}

struct control_event control_event;
if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) {
if (!controller_push_event(input_manager->controller, &control_event)) {
Expand All @@ -309,22 +311,9 @@ void input_manager_process_mouse_button(struct input_manager *input_manager,

void input_manager_process_mouse_wheel(struct input_manager *input_manager,
const SDL_MouseWheelEvent *event) {
int x;
int y;
get_mouse_point(input_manager->screen, &x, &y);
if (is_outside_device_screen(input_manager, x, y)) {
// ignore
return;
}

SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000);

struct position position = {
.screen_size = input_manager->screen->frame_size,
.point = {
.x = (Uint16) x,
.y = (Uint16) y,
},
.point = get_mouse_point(input_manager->screen),
};
struct control_event control_event;
if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ private ControlEvent parseCommandControlEvent() {
}

private static Position readPosition(ByteBuffer buffer) {
int x = toUnsigned(buffer.getShort());
int y = toUnsigned(buffer.getShort());
int x = buffer.getInt();
int y = buffer.getInt();
int screenWidth = toUnsigned(buffer.getShort());
int screenHeight = toUnsigned(buffer.getShort());
return new Position(x, y, screenWidth, screenHeight);
Expand Down

0 comments on commit fefb981

Please sign in to comment.