aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-07-13 00:25:25 +0100
committerHarry Jeffery <harry@exec64.co.uk>2019-07-13 00:25:25 +0100
commit5a1571d00dd1e73f906b1c83b7abe13aa0908e9a (patch)
tree77ff8548599ee1a1acf899795e5fba5162b73dca
parent96514247228548f2bf512e42fb072f965bd270f1 (diff)
downloadimv-5a1571d00dd1e73f906b1c83b7abe13aa0908e9a.tar.gz
Handle mouse input
-rw-r--r--src/imv.c25
-rw-r--r--src/window.c162
-rw-r--r--src/window.h4
3 files changed, 171 insertions, 20 deletions
diff --git a/src/imv.c b/src/imv.c
index 366de65..c6fe9f6 100644
--- a/src/imv.c
+++ b/src/imv.c
@@ -141,11 +141,6 @@ struct imv {
struct imv_image *current_image;
- struct {
- double x;
- double y;
- } last_cursor_position;
-
/* overlay font */
struct {
char *name;
@@ -454,6 +449,12 @@ static void event_handler(void *data, const struct imv_event *e)
case IMV_EVENT_KEYBOARD:
key_handler(imv, e->data.keyboard.scancode, e->data.keyboard. pressed);
break;
+ case IMV_EVENT_MOUSE_MOTION:
+ if (imv_window_get_mouse_button(imv->window, 1)) {
+ imv_viewport_move(imv->view, e->data.mouse_motion.dx,
+ e->data.mouse_motion.dy, imv->current_image);
+ }
+ break;
case IMV_EVENT_CUSTOM:
consume_internal_event(imv, e->data.custom);
break;
@@ -472,20 +473,6 @@ static void event_handler(void *data, const struct imv_event *e)
/* imv->last_cursor_position.y, -y);*/
/* }*/
-/* static void cursor_callback(GLFWwindow *window, double x, double y)*/
-/* {*/
-/* struct imv *imv = glfwGetWindowUserPointer(window);*/
-
-/* if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) {*/
-/* const double dx = x - imv->last_cursor_position.x;*/
-/* const double dy = y - imv->last_cursor_position.y;*/
-/* imv_viewport_move(imv->view, dx, dy, imv->current_image);*/
-/* }*/
-/* imv->last_cursor_position.x = x;*/
-/* imv->last_cursor_position.y = y;*/
-/* }*/
-
-
static void log_to_stderr(enum imv_log_level level, const char *text, void *data)
{
(void)data;
diff --git a/src/window.c b/src/window.c
index a4ac567..fd1986f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -40,6 +40,21 @@ struct imv_window {
int scale;
struct {
+ struct {
+ double last;
+ double current;
+ } x;
+ struct {
+ double last;
+ double current;
+ } y;
+ struct {
+ bool last;
+ bool current;
+ } mouse1;
+ } pointer;
+
+ struct {
struct imv_event *queue;
size_t len;
size_t cap;
@@ -138,6 +153,144 @@ static const struct wl_keyboard_listener keyboard_listener = {
.repeat_info = keyboard_repeat
};
+static void pointer_enter(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x,
+ wl_fixed_t surface_y)
+{
+ (void)pointer;
+ (void)serial;
+ (void)surface;
+
+ struct imv_window *window = data;
+ window->pointer.x.last = wl_fixed_to_double(surface_x);
+ window->pointer.y.last = wl_fixed_to_double(surface_y);
+ window->pointer.x.current = wl_fixed_to_double(surface_x);
+ window->pointer.y.current = wl_fixed_to_double(surface_y);
+}
+
+static void pointer_leave(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface)
+{
+ (void)data;
+ (void)pointer;
+ (void)serial;
+ (void)surface;
+}
+
+static void pointer_motion(void *data, struct wl_pointer *pointer,
+ uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
+{
+ (void)pointer;
+ (void)time;
+
+ struct imv_window *window = data;
+ window->pointer.x.current = wl_fixed_to_double(surface_x);
+ window->pointer.y.current = wl_fixed_to_double(surface_y);
+}
+
+static void pointer_button(void *data, struct wl_pointer *pointer,
+ uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
+{
+ (void)pointer;
+ (void)serial;
+ (void)time;
+
+ struct imv_window *window = data;
+ const uint32_t MOUSE1 = 0x110;
+ if (button == MOUSE1) {
+ window->pointer.mouse1.current = state;
+ }
+}
+
+static void pointer_axis(void *data, struct wl_pointer *pointer,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ (void)data;
+ (void)pointer;
+ (void)time;
+ (void)axis;
+ (void)value;
+}
+
+static void pointer_frame(void *data, struct wl_pointer *pointer)
+{
+ (void)pointer;
+
+ struct imv_window *window = data;
+
+ int dx = window->pointer.x.current - window->pointer.x.last;
+ int dy = window->pointer.y.current - window->pointer.y.last;
+ window->pointer.x.last = window->pointer.x.current;
+ window->pointer.y.last = window->pointer.y.current;
+ if (dx || dy) {
+ struct imv_event e = {
+ .type = IMV_EVENT_MOUSE_MOTION,
+ .data = {
+ .mouse_motion = {
+ .x = window->pointer.x.current,
+ .y = window->pointer.y.current,
+ .dx = dx,
+ .dy = dy,
+ }
+ }
+ };
+ imv_window_push_event(window, &e);
+ }
+
+ if (window->pointer.mouse1.current != window->pointer.mouse1.last) {
+ window->pointer.mouse1.last = window->pointer.mouse1.current;
+ struct imv_event e = {
+ .type = IMV_EVENT_MOUSE_BUTTON,
+ .data = {
+ .mouse_button = {
+ .button = 1,
+ .pressed = window->pointer.mouse1.current
+ }
+ }
+ };
+ imv_window_push_event(window, &e);
+ }
+
+}
+
+static void pointer_axis_source(void *data, struct wl_pointer *pointer,
+ uint32_t axis_source)
+{
+ (void)data;
+ (void)pointer;
+ (void)axis_source;
+}
+
+static void pointer_axis_stop(void *data, struct wl_pointer *pointer,
+ uint32_t time, uint32_t axis)
+{
+ (void)data;
+ (void)pointer;
+ (void)time;
+ (void)axis;
+}
+
+static void pointer_axis_discrete(void *data, struct wl_pointer *pointer,
+ uint32_t axis, int32_t discrete)
+{
+ (void)data;
+ (void)pointer;
+ (void)axis;
+ (void)discrete;
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ .enter = pointer_enter,
+ .leave = pointer_leave,
+ .motion = pointer_motion,
+ .button = pointer_button,
+ .axis = pointer_axis,
+ .frame = pointer_frame,
+ .axis_source = pointer_axis_source,
+ .axis_stop = pointer_axis_stop,
+ .axis_discrete = pointer_axis_discrete
+};
+
static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities)
{
(void)seat;
@@ -146,6 +299,7 @@ static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabil
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
if (!window->wl_pointer) {
window->wl_pointer = wl_seat_get_pointer(window->wl_seat);
+ wl_pointer_add_listener(window->wl_pointer, &pointer_listener, window);
}
} else {
if (window->wl_pointer) {
@@ -403,6 +557,14 @@ void imv_window_set_fullscreen(struct imv_window *window, bool fullscreen)
}
}
+bool imv_window_get_mouse_button(struct imv_window *window, int button)
+{
+ if (button == 1) {
+ return window->pointer.mouse1.last;
+ }
+ return false;
+}
+
void imv_window_present(struct imv_window *window)
{
eglSwapBuffers(window->egl_display, window->egl_surface);
diff --git a/src/window.h b/src/window.h
index 7c77aa1..d6e317e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -28,7 +28,7 @@ struct imv_event {
bool pressed;
} keyboard;
struct {
- int x, y, dx, dy;
+ double x, y, dx, dy;
} mouse_motion;
struct {
int button;
@@ -52,6 +52,8 @@ bool imv_window_is_fullscreen(struct imv_window *window);
void imv_window_set_fullscreen(struct imv_window *window, bool fullscreen);
+bool imv_window_get_mouse_button(struct imv_window *window, int button);
+
void imv_window_present(struct imv_window *window);
void imv_window_wait_for_event(struct imv_window *window, double timeout);