Remap event positions on rotated display
If the display is rotated, the position of clicks must be adapted.
@@ -442,6 +442,37 @@ 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;
+ case 3:
+ result.x = y;
+ result.y = w - x;
+ break;
+ default:
+ assert(!"Unreachable");
+ }
+ return result;
+}
+
static bool
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
struct control_msg *to) {
@@ -449,8 +480,8 @@ convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
to->inject_touch_event.action = AMOTION_EVENT_ACTION_MOVE;
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen->frame_size;
- to->inject_touch_event.position.point.x = from->x;
- to->inject_touch_event.position.point.y = from->y;
+ to->inject_touch_event.position.point =
+ rotate_position(screen, from->x, from->y);
to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
@@ -490,8 +521,9 @@ convert_touch(const SDL_TouchFingerEvent *from, struct screen *screen,
to->inject_touch_event.pointer_id = from->fingerId;
to->inject_touch_event.position.screen_size = frame_size;
// SDL touch event coordinates are normalized in the range [0; 1]
- to->inject_touch_event.position.point.x = from->x * frame_size.width;
- to->inject_touch_event.position.point.y = from->y * frame_size.height;
+ float x = from->x * frame_size.width;
+ float y = from->y * frame_size.height;
+ to->inject_touch_event.position.point = rotate_position(screen, x, y);
to->inject_touch_event.pressure = from->pressure;
to->inject_touch_event.buttons = 0;
return true;
@@ -526,8 +558,8 @@ convert_mouse_button(const SDL_MouseButtonEvent *from, struct screen *screen,
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen->frame_size;
- to->inject_touch_event.position.point.x = from->x;
- to->inject_touch_event.position.point.y = from->y;
+ to->inject_touch_event.position.point =
+ rotate_position(screen, from->x, from->y);
to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons =
convert_mouse_buttons(SDL_BUTTON(from->button));
