Unfinished Wayland PR #1
2 changed files with 100 additions and 45 deletions
wayland: properly pump the events system, only drawing when necessary
commit
df43752fa7
|
|
@ -76,18 +76,25 @@ struct _MwLLWayland {
|
|||
struct wl_surface* surface;
|
||||
struct wl_shm* shm;
|
||||
struct wl_registry_listener registry_listener;
|
||||
struct wl_event_queue* event_queue;
|
||||
|
||||
struct wl_pointer* pointer;
|
||||
|
||||
MwLL* subwidgets;
|
||||
|
||||
MwBool configured;
|
||||
MwBool force_redraw;
|
||||
MwBool configured;
|
||||
MwBool force_redraw;
|
||||
|
||||
MwBool egl_setup;
|
||||
MwBool egl_do_resetup;
|
||||
MwBool has_set_xy;
|
||||
MwU32 x, y, ww, wh;
|
||||
MwPoint cur_mouse_pos;
|
||||
|
||||
struct timeval timer;
|
||||
|
||||
MwU64 cooldown_timer;
|
||||
MwU64 cooldown_timer_epoch;
|
||||
|
||||
MwLL parent;
|
||||
|
||||
GLuint fbo;
|
||||
|
|
@ -107,6 +114,7 @@ struct _MwLLWaylandColor {
|
|||
struct _MwLLWaylandPixmap {
|
||||
struct _MwLLCommonPixmap common;
|
||||
GLuint texture;
|
||||
MwBool texture_deleted;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
void (*focus_out)(MwLL handle, void* data);
|
||||
*/
|
||||
|
||||
static void timed_redraw(MwLL handle, MwU32 time, int cooldown, MwU64* cooldown_timer);
|
||||
|
||||
#define WAYLAND_GET_INTERFACE(r, inter) shget(r.wl_protocol_map, inter##_interface.name)
|
||||
|
||||
static void new_protocol(void* data, struct wl_registry* registry,
|
||||
|
|
@ -48,12 +50,12 @@ static void protocol_removed(void* data,
|
|||
|
||||
};
|
||||
|
||||
static void pointer_enter(void* data, struct wl_pointer* wl_pointer, uint32_t serial,
|
||||
static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 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,
|
||||
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
|
||||
struct wl_surface* surface) {};
|
||||
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, uint32_t time,
|
||||
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time,
|
||||
wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||
MwLL self = data;
|
||||
MwLLMouse p;
|
||||
|
|
@ -62,8 +64,10 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, uint32_t t
|
|||
self->wayland.cur_mouse_pos.y = wl_fixed_to_double(surface_y);
|
||||
p.point = self->wayland.cur_mouse_pos;
|
||||
MwLLDispatch(self, move, &p);
|
||||
|
||||
timed_redraw(self, time, 50, &self->wayland.cooldown_timer);
|
||||
};
|
||||
static void pointer_button(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
||||
static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) {
|
||||
MwLL self = data;
|
||||
MwLLMouse p;
|
||||
p.point = self->wayland.cur_mouse_pos;
|
||||
|
|
@ -88,9 +92,11 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, uint32_t s
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timed_redraw(self, time, 50, &self->wayland.cooldown_timer);
|
||||
};
|
||||
static void pointer_axis(void* data, struct wl_pointer* wl_pointer, uint32_t time,
|
||||
uint32_t axis, wl_fixed_t value) {};
|
||||
static void pointer_axis(void* data, struct wl_pointer* wl_pointer, MwU32 time,
|
||||
MwU32 axis, wl_fixed_t value) {};
|
||||
|
||||
struct wl_pointer_listener pointer_listener = {
|
||||
.enter = pointer_enter,
|
||||
|
|
@ -112,7 +118,6 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
|||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -258,9 +263,14 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
return MwFALSE;
|
||||
}
|
||||
|
||||
if(!eglMakeCurrent(display, surface, surface, context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
self->wayland.egl_display = display;
|
||||
self->wayland.egl_surface = surface;
|
||||
self->wayland.egl_context = context;
|
||||
|
||||
if(self->wayland.parent == NULL) {
|
||||
if(!eglMakeCurrent(self->wayland.egl_display, self->wayland.egl_surface, self->wayland.egl_surface, self->wayland.egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
|
@ -270,26 +280,21 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
self->wayland.egl_display = display;
|
||||
self->wayland.egl_surface = surface;
|
||||
self->wayland.egl_context = context;
|
||||
return MwTRUE;
|
||||
}
|
||||
|
||||
static void egl_resetup(MwLL handle) {
|
||||
int err;
|
||||
|
||||
if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
return;
|
||||
}
|
||||
// if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) {
|
||||
// printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
// return;
|
||||
// }
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, handle->wayland.ww, handle->wayland.wh, 0, -1, 1);
|
||||
glViewport(0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
|
||||
handle->wayland.egl_do_resetup = MwFALSE;
|
||||
}
|
||||
|
||||
static void recursive_draw(MwLL handle) {
|
||||
|
|
@ -302,16 +307,25 @@ static void recursive_draw(MwLL handle) {
|
|||
}
|
||||
}
|
||||
|
||||
static void recursive_resize(MwLL handle) {
|
||||
int i;
|
||||
if(handle->wayland.subwidgets != NULL) {
|
||||
for(i = 0; i < arrlen(handle->wayland.subwidgets); i++) {
|
||||
MwLLDispatch(handle->wayland.subwidgets[i], resize, NULL);
|
||||
recursive_resize(handle->wayland.subwidgets[i]);
|
||||
static void timed_redraw(MwLL handle, MwU32 time, int cooldown, MwU64* cooldown_timer) {
|
||||
if(handle->wayland.parent == NULL) {
|
||||
if(time >= (*cooldown_timer + cooldown)) {
|
||||
egl_resetup(handle);
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
// recursive_draw(handle);
|
||||
*cooldown_timer = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void timed_redraw_by_epoch(MwLL handle, int cooldown) {
|
||||
gettimeofday(&handle->wayland.timer, NULL);
|
||||
unsigned long long time =
|
||||
(unsigned long long)(handle->wayland.timer.tv_sec) * 1000 +
|
||||
(unsigned long long)(handle->wayland.timer.tv_usec) / 1000;
|
||||
timed_redraw(handle, time, cooldown, &handle->wayland.cooldown_timer_epoch);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_configure(void* data,
|
||||
struct xdg_toplevel* xdg_toplevel,
|
||||
MwI32 width, MwI32 height,
|
||||
|
|
@ -326,20 +340,17 @@ static void xdg_toplevel_configure(void* data,
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self->wayland.ww = width;
|
||||
self->wayland.wh = height;
|
||||
xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh);
|
||||
|
||||
MwLLSetWH(self, width, height);
|
||||
MwLLDispatch(self, resize, NULL);
|
||||
recursive_resize(self);
|
||||
|
||||
if(!self->wayland.egl_setup) {
|
||||
self->wayland.egl_setup = egl_setup(self, width, height);
|
||||
MwLLForceRender(self);
|
||||
} else {
|
||||
wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0);
|
||||
self->wayland.egl_do_resetup = MwTRUE;
|
||||
egl_resetup(self);
|
||||
}
|
||||
|
||||
|
|
@ -413,9 +424,13 @@ static int event_loop(MwLL handle) {
|
|||
if(wl_display_dispatch_pending(wayland->display) > 0) {
|
||||
}
|
||||
} else {
|
||||
/* Condition for no events being sent */
|
||||
if(wl_display_dispatch_pending(wayland->display) == 0) {
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
recursive_draw(handle);
|
||||
if(wayland->event_queue != NULL) {
|
||||
if(wl_display_roundtrip_queue(wayland->display, wayland->event_queue) < 0) {
|
||||
printf("error\n");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -444,8 +459,7 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
|||
#undef WL_INTERFACE
|
||||
|
||||
static void setup_toplevel(MwLL r, int x, int y) {
|
||||
int i;
|
||||
struct wl_region* region;
|
||||
int i;
|
||||
|
||||
r->wayland.type = MWLL_WAYLAND_TOPLEVEL;
|
||||
r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel));
|
||||
|
|
@ -517,6 +531,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
printf("zxdg null\n");
|
||||
}
|
||||
|
||||
r->wayland.event_queue = wl_display_create_queue(r->wayland.display);
|
||||
|
||||
MwLLForceRender(r);
|
||||
|
||||
// buffer_setup(&r->wayland);
|
||||
|
||||
// glGenBuffers(1, &vertex_buffer);
|
||||
|
|
@ -526,8 +544,8 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|||
struct wl_compositor* compositor = parent->wayland.compositor;
|
||||
struct wl_subcompositor* subcompositor = parent->wayland.subcompositor;
|
||||
struct wl_surface* parent_surface = parent->wayland.surface;
|
||||
MwLL topmost_parent = parent;
|
||||
struct wl_region* region;
|
||||
MwLL topmost_parent = parent;
|
||||
|
||||
while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
|
|
@ -572,7 +590,15 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|||
MwLLForceRender(r);
|
||||
};
|
||||
|
||||
r->wayland.event_queue = parent->wayland.event_queue;
|
||||
|
||||
arrpush(parent->wayland.subwidgets, r);
|
||||
|
||||
wl_surface_damage(parent->wayland.surface, 0, 0, parent->wayland.ww, parent->wayland.wh);
|
||||
|
||||
egl_resetup(topmost_parent);
|
||||
MwLLDispatch(topmost_parent, draw, NULL);
|
||||
recursive_draw(topmost_parent);
|
||||
}
|
||||
|
||||
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||
|
|
@ -599,6 +625,9 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|||
|
||||
r->wayland.parent = parent;
|
||||
|
||||
r->wayland.cooldown_timer = 0;
|
||||
r->wayland.has_set_xy = MwFALSE;
|
||||
|
||||
r->wayland.force_redraw = MwFALSE;
|
||||
r->wayland.subwidgets = NULL;
|
||||
r->wayland.pointer = NULL;
|
||||
|
|
@ -626,10 +655,20 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
|
|||
|
||||
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
||||
if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
MwLL topmost_parent = handle->wayland.parent;
|
||||
|
||||
while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
}
|
||||
|
||||
handle->wayland.x = x;
|
||||
handle->wayland.y = y;
|
||||
// wl_sublevel_set_position(handle->wayland.sublevel, x, y);
|
||||
MwLLForceRender(handle);
|
||||
if(handle->wayland.has_set_xy) {
|
||||
timed_redraw_by_epoch(topmost_parent, 25);
|
||||
recursive_draw(topmost_parent);
|
||||
} else if(x != 0 && y != 0) {
|
||||
handle->wayland.has_set_xy = MwTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -646,6 +685,13 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
|||
if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
} else {
|
||||
MwLL topmost_parent = handle->wayland.parent;
|
||||
|
||||
while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
}
|
||||
timed_redraw_by_epoch(topmost_parent, 25);
|
||||
recursive_draw(topmost_parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -692,6 +738,8 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
// glClearColor(1.0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static void MwLLEndDrawImpl(MwLL handle) {
|
||||
|
|
@ -711,8 +759,6 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
|||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
// glClearColor(1.0, 0, 0, 1);
|
||||
|
||||
wl_surface_damage(handle->wayland.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
|
||||
if(handle->wayland.parent == NULL) {
|
||||
if(!eglSwapBuffers(handle->wayland.egl_display, handle->wayland.egl_surface)) {
|
||||
printf("error swapping buffers! %0X\n", eglGetError());
|
||||
|
|
@ -745,7 +791,7 @@ static void MwLLFreeColorImpl(MwLLColor color) {
|
|||
static int MwLLPendingImpl(MwLL handle) {
|
||||
if(wl_display_dispatch_pending(handle->wayland.display) == 0) {
|
||||
}
|
||||
return event_loop(handle) || handle->wayland.force_redraw;
|
||||
return event_loop(handle);
|
||||
}
|
||||
|
||||
static void MwLLNextEventImpl(MwLL handle) {
|
||||
|
|
@ -815,16 +861,17 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
|||
glTexCoord2f(0.0f, 1);
|
||||
glVertex2f(x, y + rect->height);
|
||||
glEnd();
|
||||
glFinish();
|
||||
}
|
||||
|
||||
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
||||
}
|
||||
|
||||
static void MwLLForceRenderImpl(MwLL handle) {
|
||||
wl_surface_damage(handle->wayland.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
|
||||
wl_surface_commit(handle->wayland.surface);
|
||||
|
||||
if(handle->wayland.egl_setup) {
|
||||
timed_redraw_by_epoch(handle, 25);
|
||||
}
|
||||
handle->wayland.force_redraw = MwTRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue