diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index dbc9417..75f208b 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -1,4 +1,3 @@ -/* $Id$ */ /*! * @file Mw/LowLevel/Wayland.h * @brief Wayland Backend @@ -12,6 +11,7 @@ #include #include +#include #include #include #include @@ -44,7 +44,6 @@ struct _MwLLWaylandTopLevel { struct xkb_context* xkb_context; - MwBool running; MwBool compositor_created; MwBool xdg_wm_base_created; MwBool xdg_surface_created; @@ -79,14 +78,18 @@ struct _MwLLWayland { struct wl_shm* shm; struct wl_registry_listener registry_listener; + struct wl_pointer* pointer; + MwLL* subwidgets; - MwBool configured; - MwBool force_redraw; - MwBool egl_setup; - MwBool egl_do_resetup; - MwU32 x, y, ww, wh; - int z_index; + MwBool configured; + MwBool force_redraw; + MwBool egl_setup; + MwBool egl_do_resetup; + MwU32 x, y, ww, wh; + MwPoint cur_mouse_pos; + + int last_serial; MwLL parent; diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 53b4483..32f5c0b 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -1,12 +1,9 @@ -/* $Id$ */ - -// #include -#include #include #include #include #include +#include #include #include #include @@ -24,6 +21,9 @@ #include #include +/* TODO: find out what FreeBSD and such wants us to include */ +#include + PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; @@ -32,6 +32,16 @@ PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatus; +/* + callback todo: + void (*up)(MwLL handle, void* data); + void (*down)(MwLL handle, void* data); + void (*key)(MwLL handle, void* data); + void (*key_released)(MwLL handle, void* data); + void (*focus_in)(MwLL handle, void* data); + void (*focus_out)(MwLL handle, void* data); +*/ + #define WAYLAND_GET_INTERFACE(r, inter) shget(r.wl_protocol_map, inter##_interface.name) static void new_protocol(void* data, struct wl_registry* registry, @@ -54,9 +64,73 @@ static void protocol_removed(void* data, }; -static void wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {}; +static void pointer_enter(void* data, struct wl_pointer* wl_pointer, uint32_t serial, + struct wl_surface* surface, wl_fixed_t surface_x, + wl_fixed_t surface_y) {}; +static void pointer_leave(void* data, struct wl_pointer* wl_pointer, uint32_t serial, + struct wl_surface* surface) {}; +static void pointer_motion(void* data, struct wl_pointer* wl_pointer, uint32_t time, + wl_fixed_t surface_x, wl_fixed_t surface_y) { + MwLL self = data; + MwLLMouse p; + + self->wayland.cur_mouse_pos.x = wl_fixed_to_double(surface_x); + self->wayland.cur_mouse_pos.y = wl_fixed_to_double(surface_y); + p.point = self->wayland.cur_mouse_pos; + MwLLDispatch(self, move, &p); +}; +static void pointer_button(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { + MwLL self = data; + MwLLMouse p; + p.point = self->wayland.cur_mouse_pos; + if(p.point.x > self->wayland.x && p.point.x < self->wayland.x + self->wayland.ww && p.point.y > self->wayland.y && p.point.y < self->wayland.y + self->wayland.wh) { + switch(button) { + case BTN_LEFT: + p.button = MwLLMouseLeft; + break; + case BTN_MIDDLE: + p.button = MwLLMouseMiddle; + break; + case BTN_RIGHT: + p.button = MwLLMouseRight; + break; + } + switch(state) { + case WL_POINTER_BUTTON_STATE_PRESSED: + MwLLDispatch(self, down, &p); + break; + case WL_POINTER_BUTTON_STATE_RELEASED: + MwLLDispatch(self, up, &p); + break; + } + } +}; +static void pointer_axis(void* data, struct wl_pointer* wl_pointer, uint32_t time, + uint32_t axis, wl_fixed_t value) {}; + +struct wl_pointer_listener pointer_listener = { + .enter = pointer_enter, + .leave = pointer_leave, + .motion = pointer_motion, + .button = pointer_button, + .axis = pointer_axis, +}; + +static void + wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {}; static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat, - MwU32 capabilities) {}; + MwU32 capabilities) { + MwLL self = data; + if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) { + struct wl_keyboard* keyboard = wl_seat_get_keyboard(wl_seat); + // wl_keyboard_add_listener(keyboard, const struct wl_keyboard_listener* listener, data); + } + if(capabilities & WL_SEAT_CAPABILITY_POINTER && !self->wayland.pointer) { + self->wayland.pointer = wl_seat_get_pointer(wl_seat); + wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data); + return; + } +}; void xdg_wm_base_ping(void* data, struct xdg_wm_base* xdg_wm_base, @@ -66,15 +140,15 @@ void xdg_wm_base_ping(void* data, xdg_wm_base_pong(xdg_wm_base, serial); }; -static wayland_protocol_t* wl_seat_setup(MwU32 name, struct _MwLLWayland* wayland) { +static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll) { wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); proto->listener = malloc(sizeof(struct wl_seat_listener)); ((struct wl_seat_listener*)proto->listener)->name = wl_seat_name; ((struct wl_seat_listener*)proto->listener)->capabilities = wl_seat_capabilities; - proto->context = wl_registry_bind(wayland->registry, name, &wl_seat_interface, 1); - wl_seat_add_listener(proto->context, proto->listener, wayland); + proto->context = wl_registry_bind(ll->wayland.registry, name, &wl_seat_interface, 1); + wl_seat_add_listener(proto->context, proto->listener, ll); return proto; } @@ -347,9 +421,7 @@ static void decoration_configure( static void xdg_toplevel_close( void* data, struct xdg_toplevel* xdg_toplevel) { MwLL self = data; - - // Stop running if the user requests to close the toplevel - self->wayland.toplevel->running = MwFALSE; + MwLLDispatch(self, close, NULL); }; static void xdg_surface_configure( @@ -397,7 +469,7 @@ static int event_loop(MwLL handle) { if(errno != EINTR && errno != EAGAIN) { wl_display_cancel_read(wayland->display); - wayland->toplevel->running = MwFALSE; + MwLLDispatch(handle, close, NULL); return 0; } } @@ -446,8 +518,8 @@ static void setup_callbacks(struct _MwLLWayland* wayland) { WL_INTERFACE(wl_compositor); WL_INTERFACE(wl_subcompositor); + WL_INTERFACE(wl_seat); if(wayland->type == MWLL_WAYLAND_TOPLEVEL) { - WL_INTERFACE(wl_seat); WL_INTERFACE(xdg_wm_base); WL_INTERFACE(zxdg_decoration_manager_v1); WL_INTERFACE(wp_cursor_shape_manager_v1); @@ -627,7 +699,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->wayland.force_redraw = MwFALSE; r->wayland.subwidgets = NULL; - + r->wayland.pointer = NULL; if(parent == NULL) { setup_toplevel(r, x, y); } else { @@ -766,6 +838,8 @@ static void MwLLEndDrawImpl(MwLL handle) { h = parent->wayland.wh; } + recursive_draw(handle); + glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture); // glClear(GL_COLOR_BUFFER_BIT); // glClearColor(1.0, 0, 0, 1); @@ -822,7 +896,6 @@ static void MwLLNextEventImpl(MwLL handle) { MwBool render = handle->wayland.force_redraw; if(render) { - recursive_draw(handle); handle->wayland.force_redraw = MwFALSE; } } diff --git a/src/core.c b/src/core.c index 83de5c1..696ed42 100644 --- a/src/core.c +++ b/src/core.c @@ -14,6 +14,10 @@ static void lldrawhandler(MwLL handle, void* data) { MwDispatch(h, draw); if(h->draw_inject != NULL) h->draw_inject(h); MwDispatchUserHandler(h, MwNdrawHandler, NULL); + + if(handle->wayland.parent == NULL) { + MwLLEndDraw(handle); + } } static void lluphandler(MwLL handle, void* data) { @@ -332,7 +336,6 @@ void MwLoop(MwWidget handle) { while(MwPending(handle)) { if((v = MwStep(handle)) != 0) break; } - MwLLEndDraw(handle->lowlevel); if(v != 0) break; for(i = 0; i < arrlen(handle->tick_list); i++) {