diff --git a/src/gfx.h b/src/gfx.h index 4d34611..4ca8189 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -95,6 +95,11 @@ typedef struct { struct wl_buffer *buffer; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; + struct wl_seat *seat; + struct wl_pointer *pointer; + + int mouse_x, mouse_y; + int mouse_left_down, mouse_right_down; } _opengl_gfx_context_wayland; typedef struct { @@ -607,6 +612,54 @@ static void _metal_gfx_update_buffer(_metal_gfx_context *cx, memcpy(buffer_contents, data, len); } #elif __linux__ +#include + +static void _wayland_pointer_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t x, wl_fixed_t y) { + fprintf(stderr, "pointer enter: %d, %d\n", x, y); +} +static void _wayland_pointer_leave(void *data, struct wl_pointer *pointer, + uint32_t serial, + struct wl_surface *surface) { + fprintf(stderr, "pointer leave\n"); +} +static void _wayland_pointer_button(void *data, struct wl_pointer *pointer, + uint32_t serial, uint32_t time, + uint32_t button, uint32_t state) { + _opengl_gfx_context_wayland *cx = data; + + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { + if (button == BTN_LEFT) { + cx->mouse_left_down = true; + } else if (button == BTN_RIGHT) { + cx->mouse_right_down = true; + } + } else if (state == WL_POINTER_BUTTON_STATE_RELEASED) { + if (button == BTN_LEFT) { + cx->mouse_left_down = false; + } else if (button == BTN_RIGHT) { + cx->mouse_right_down = false; + } + } +} +static void _wayland_pointer_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, + wl_fixed_t value) {} +static void _wayland_pointer_motion(void *data, struct wl_pointer *pointer, + uint32_t time, wl_fixed_t x, wl_fixed_t y) { + _opengl_gfx_context_wayland *cx = data; + cx->mouse_x = wl_fixed_to_int(x); + cx->mouse_y = wl_fixed_to_int(y); +} + +static const struct wl_pointer_listener pointer_listener = { + .enter = _wayland_pointer_enter, + .leave = _wayland_pointer_leave, + .motion = _wayland_pointer_motion, + .button = _wayland_pointer_button, + .axis = _wayland_pointer_axis, +}; static void _wayland_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, @@ -659,6 +712,8 @@ static void _wayland_registry_handle_global(void *data, } else if (strcmp(interface, "xdg_wm_base") == 0) { d->wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); + } else if (strcmp(interface, "wl_seat") == 0) { + d->seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); } } @@ -685,9 +740,11 @@ _opengl_gfx_init_context_wayland(uint32_t width, uint32_t height) { // wait for all the globals to be registered wl_display_roundtrip(cx.display); - xdg_wm_base_add_listener(cx.wm_base, &xdg_wm_base_listener, &cx); + cx.pointer = wl_seat_get_pointer(cx.seat); + wl_pointer_add_listener(cx.pointer, &pointer_listener, &cx); + cx.surface = wl_compositor_create_surface(cx.compositor); cx.xdg_surface = xdg_wm_base_get_xdg_surface(cx.wm_base, cx.surface); xdg_surface_add_listener(cx.xdg_surface, &xdg_surface_listener, &cx); @@ -705,12 +762,14 @@ _opengl_gfx_init_context_wayland(uint32_t width, uint32_t height) { ftruncate(fd, size); uint8_t *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - data[0] = 255; + for (int i = 0; i < size; ++i) { + data[i] = 255; + } cx.shared_memory_pool = wl_shm_create_pool(cx.shared_memory, fd, size); cx.buffer = wl_shm_pool_create_buffer(cx.shared_memory_pool, 0, width, height, - width * 4, WL_SHM_FORMAT_XRGB8888); + width * 4, WL_SHM_FORMAT_ARGB8888); wl_surface_attach(cx.surface, cx.buffer, 0, 0); wl_surface_commit(cx.surface);