Compare commits
No commits in common. "503a259caab715b940fb461fa5b637a6c0fcad24" and "4fe57c6d96cfd560c2f37d47880acb1ac9ab5154" have entirely different histories.
503a259caa
...
4fe57c6d96
5 changed files with 102 additions and 294 deletions
|
|
@ -381,6 +381,7 @@ struct _MwLLWayland {
|
|||
struct zwp_relative_pointer_v1* relative_pointer;
|
||||
struct zwp_locked_pointer_v1* locked_pointer;
|
||||
MwBool pointer_constrained;
|
||||
MwBool valid;
|
||||
|
||||
#ifdef USE_DBUS
|
||||
MwLLDBusContext dbus;
|
||||
|
|
@ -395,7 +396,7 @@ struct _MwLLWayland {
|
|||
struct wl_data_device_manager* wl;
|
||||
struct zwp_primary_selection_device_manager_v1* zwp;
|
||||
} clipboard_manager;
|
||||
struct {
|
||||
union {
|
||||
struct wl_data_source* wl;
|
||||
struct zwp_primary_selection_source_v1* zwp;
|
||||
} clipboard_source;
|
||||
|
|
|
|||
|
|
@ -137,25 +137,13 @@ void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32
|
|||
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
|
||||
cairo_destroy(cairo->front_cairo);
|
||||
cairo_destroy(cairo->front_cairo_back);
|
||||
cairo_destroy(cairo->frontbuffer_cairo);
|
||||
cairo_surface_destroy(cairo->front_cs);
|
||||
cairo_surface_destroy(cairo->front_cs_back);
|
||||
cairo_surface_destroy(cairo->frontbuffer_cs);
|
||||
|
||||
/* set all to null so that cairo ignores future destroys */
|
||||
cairo->front_cairo = NULL;
|
||||
cairo->front_cairo_back = NULL;
|
||||
cairo->frontbuffer_cairo = NULL;
|
||||
cairo->front_cs = NULL;
|
||||
cairo->front_cs_back = NULL;
|
||||
cairo->frontbuffer_cs = NULL;
|
||||
cairo_destroy(cairo->frontbuffer_cairo);
|
||||
};
|
||||
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
|
||||
cairo_destroy(cairo->back_cairo);
|
||||
cairo_surface_destroy(cairo->back_cs);
|
||||
|
||||
cairo->back_cairo = NULL;
|
||||
cairo->back_cs = NULL;
|
||||
};
|
||||
|
||||
void MwLLCairoDestroy(struct _MwLLCairo handle) {
|
||||
|
|
@ -229,8 +217,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {}
|
|||
|
||||
static MwBool lmao = MwFALSE;
|
||||
static int MwLLPendingImpl(MwLL handle) {
|
||||
lmao = !lmao;
|
||||
return lmao;
|
||||
lmao = !lmao;
|
||||
return lmao;
|
||||
}
|
||||
static void MwLLNextEventImpl(MwLL handle) {
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
|
|
@ -274,10 +262,10 @@ static void MwLLRaiseImpl(MwLL handle) {}
|
|||
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
|
||||
static int MwLLCairoCallInitImpl(void) {
|
||||
if(cairo_load_funcs() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if(cairo_load_funcs() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include "call.c"
|
||||
CALL(Cairo);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
||||
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
|
||||
|
||||
MwLLCairoFrontDestroy(&wayland->cairo);
|
||||
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
|
||||
|
||||
memset(wayland->framebuffer.buf_back, 255, wayland->framebuffer.buf_size);
|
||||
|
|
@ -39,7 +38,6 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
|
|||
}
|
||||
MwLLWaylandBufferSetup(&wayland->backbuffer, w, h);
|
||||
|
||||
MwLLCairoBackDestroy(&wayland->cairo);
|
||||
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
|
||||
|
||||
memset(wayland->backbuffer.buf_back, 0, wayland->backbuffer.buf_size);
|
||||
|
|
@ -59,44 +57,40 @@ void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* wayland) {
|
|||
|
||||
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
|
||||
int stride = width * 4;
|
||||
int err;
|
||||
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXXXX";
|
||||
char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXXXX";
|
||||
|
||||
MwLLWaylandBufferDestroy(buffer);
|
||||
|
||||
buffer->buf_size = width * height * 4;
|
||||
|
||||
buffer->fd = mkstemp(temp_name);
|
||||
buffer->fd_back = mkstemp(temp_name_back);
|
||||
if(buffer->fd >= 65536) {
|
||||
MwDispatchError(-1, "Amount of allocated buffers has gone above 65536! Cannot continue.\n");
|
||||
goto fail;
|
||||
}
|
||||
if(buffer->fd == -1 || buffer->fd_back == -1) {
|
||||
printf("failure setting up wl_shm: could not create file. %s.\n", strerror(errno));
|
||||
goto fail;
|
||||
return;
|
||||
}
|
||||
|
||||
unlink(temp_name);
|
||||
unlink(temp_name_back);
|
||||
|
||||
/* posix_fallocate returns the error rather than setting errno */
|
||||
if((err = posix_fallocate(buffer->fd, 0, buffer->buf_size)) != 0) {
|
||||
printf("failure setting up wl_shm (front buf): could not fallocate %llu bytes. %s.\n", (unsigned long long)buffer->buf_size, strerror(err));
|
||||
goto fail;
|
||||
if(posix_fallocate(buffer->fd, 0, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm (front buf): could not fallocate. %s.\n", strerror(errno));
|
||||
close(buffer->fd);
|
||||
return;
|
||||
}
|
||||
if((err = posix_fallocate(buffer->fd_back, 0, buffer->buf_size)) != 0) {
|
||||
printf("failure setting up wl_shm (back buf): could not fallocate %llu bytes. %s.\n", (unsigned long long)buffer->buf_size, strerror(err));
|
||||
goto fail;
|
||||
if(posix_fallocate(buffer->fd_back, 0, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm (back buf): could not fallocate. %s.\n", strerror(errno));
|
||||
close(buffer->fd_back);
|
||||
return;
|
||||
}
|
||||
if(ftruncate(buffer->fd, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||
goto fail;
|
||||
close(buffer->fd);
|
||||
return;
|
||||
}
|
||||
if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||
goto fail;
|
||||
close(buffer->fd_back);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
||||
|
|
@ -116,13 +110,6 @@ void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, M
|
|||
buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
|
||||
buffer->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
|
||||
buffer->setup = MwTRUE;
|
||||
return;
|
||||
|
||||
fail:
|
||||
if(buffer->fd >= 0) close(buffer->fd);
|
||||
if(buffer->fd_back >= 0) close(buffer->fd_back);
|
||||
buffer->fd = -1;
|
||||
buffer->fd_back = -1;
|
||||
}
|
||||
|
||||
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
||||
|
|
@ -137,16 +124,7 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
|||
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
|
||||
close(buffer->fd);
|
||||
close(buffer->fd_back);
|
||||
|
||||
buffer->buf = NULL;
|
||||
buffer->buf_back = NULL;
|
||||
buffer->shm_buffer = NULL;
|
||||
buffer->shm_buffer_back = NULL;
|
||||
buffer->shm_pool = NULL;
|
||||
buffer->shm_pool_back = NULL;
|
||||
buffer->fd = -1;
|
||||
buffer->fd_back = -1;
|
||||
buffer->setup = MwFALSE;
|
||||
buffer->setup = MwFALSE;
|
||||
}
|
||||
|
||||
void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
|
||||
static void destroy_clipboard(MwLL self);
|
||||
static void destroy_zwp_clipboard(MwLL self);
|
||||
static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||
static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos);
|
||||
|
||||
/* Recursively dispatch a key event to a widget and its children */
|
||||
|
|
@ -133,9 +133,6 @@ static void wl_data_device_data_offer(void* data,
|
|||
|
||||
wl_data_offer_add_listener(offer, &offer_listener, data);
|
||||
|
||||
if(self->offer.wl && self->offer.wl != offer) {
|
||||
wl_data_offer_destroy(self->offer.wl);
|
||||
}
|
||||
self->offer.wl = offer;
|
||||
};
|
||||
|
||||
|
|
@ -323,9 +320,6 @@ static void zwp_primary_selection_device_v1_data_offer(void* data,
|
|||
wl_clipboard_device_context_t* self = data;
|
||||
(void)zwp_primary_selection_device_v1;
|
||||
|
||||
if(self->offer.zwp && self->offer.zwp != offer) {
|
||||
zwp_primary_selection_offer_v1_destroy(self->offer.zwp);
|
||||
}
|
||||
self->offer.zwp = offer;
|
||||
};
|
||||
|
||||
|
|
@ -497,15 +491,14 @@ static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLL
|
|||
|
||||
static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)data;
|
||||
destroy_clipboard((MwLL)wayland);
|
||||
if(wayland->clipboard_source.wl) {
|
||||
wl_data_source_destroy(wayland->clipboard_source.wl);
|
||||
wayland->clipboard_source.wl = NULL;
|
||||
}
|
||||
if(wayland->clipboard_manager.wl != NULL) {
|
||||
wl_data_device_manager_destroy(wayland->clipboard_manager.wl);
|
||||
wayland->clipboard_manager.wl = NULL;
|
||||
}
|
||||
if(wayland->clipboard_source.wl) {
|
||||
// wl_data_source_destroy(wayland->clipboard_source.wl);
|
||||
wayland->clipboard_source.wl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* zwp_primary_selection_device_manager_v1 setup function */
|
||||
|
|
@ -533,17 +526,8 @@ static wayland_protocol_t* zwp_primary_selection_device_manager_v1_setup(MwU32 n
|
|||
}
|
||||
|
||||
static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
destroy_zwp_clipboard((MwLL)wayland);
|
||||
if(wayland->clipboard_source.zwp) {
|
||||
zwp_primary_selection_source_v1_destroy(wayland->clipboard_source.zwp);
|
||||
wayland->clipboard_source.zwp = NULL;
|
||||
}
|
||||
if(wayland->clipboard_manager.zwp != NULL) {
|
||||
zwp_primary_selection_device_manager_v1_destroy(wayland->clipboard_manager.zwp);
|
||||
wayland->clipboard_manager.zwp = NULL;
|
||||
}
|
||||
wayland->supports_zwp = MwFALSE;
|
||||
}
|
||||
|
||||
/* zwp_primary_selection_device_manager_v1 setup function */
|
||||
|
|
@ -554,15 +538,8 @@ static wayland_protocol_t* zwp_pointer_constraints_v1_setup(MwU32 name, struct _
|
|||
}
|
||||
|
||||
static void zwp_pointer_constraints_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
if(wayland->locked_pointer) {
|
||||
zwp_locked_pointer_v1_destroy(wayland->locked_pointer);
|
||||
wayland->locked_pointer = NULL;
|
||||
}
|
||||
if(wayland->pointer_constraints) {
|
||||
zwp_pointer_constraints_v1_destroy(wayland->pointer_constraints);
|
||||
wayland->pointer_constraints = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct wl_surface* curSurface = NULL;
|
||||
|
|
@ -690,15 +667,8 @@ static wayland_protocol_t* zwp_relative_pointer_manager_v1_setup(MwU32 name, str
|
|||
}
|
||||
|
||||
static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
if(wayland->relative_pointer) {
|
||||
zwp_relative_pointer_v1_destroy(wayland->relative_pointer);
|
||||
wayland->relative_pointer = NULL;
|
||||
}
|
||||
if(wayland->relative_pointer_manager) {
|
||||
zwp_relative_pointer_manager_v1_destroy(wayland->relative_pointer_manager);
|
||||
wayland->relative_pointer_manager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* `wl_pointer.motion` callback */
|
||||
|
|
@ -948,16 +918,9 @@ static void keyboard_keymap(void* data,
|
|||
|
||||
struct xkb_state* xkb_state = xkb_state_new(xkb_keymap);
|
||||
|
||||
/* the compositor sends a new keymap whenever the layout changes */
|
||||
if(self->wayland.xkb_state) xkb_state_unref(self->wayland.xkb_state);
|
||||
if(self->wayland.xkb_keymap) xkb_keymap_unref(self->wayland.xkb_keymap);
|
||||
|
||||
self->wayland.xkb_keymap = xkb_keymap;
|
||||
self->wayland.xkb_state = xkb_state;
|
||||
} else {
|
||||
/* we don't read it, but the fd is still ours to close */
|
||||
close(fd);
|
||||
|
||||
self->wayland.xkb_keymap = self->wayland.parent->wayland.xkb_keymap;
|
||||
self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state;
|
||||
}
|
||||
|
|
@ -1196,31 +1159,6 @@ static void setup_clipboard(MwLL self, struct wl_seat* wl_seat) {
|
|||
device_ctx_wl->accepted_types[5] = "text/uri-list";
|
||||
};
|
||||
|
||||
static void destroy_zwp_clipboard(MwLL self) {
|
||||
int i;
|
||||
for(i = 0; i < arrlen(self->wayland.clipboard_devices_zwp); i++) {
|
||||
wl_clipboard_device_context_t* ctx = self->wayland.clipboard_devices_zwp[i];
|
||||
if(ctx->offer.zwp) zwp_primary_selection_offer_v1_destroy(ctx->offer.zwp);
|
||||
zwp_primary_selection_device_v1_destroy(ctx->device.zwp);
|
||||
free(ctx);
|
||||
}
|
||||
arrfree(self->wayland.clipboard_devices_zwp);
|
||||
}
|
||||
static void destroy_clipboard(MwLL self) {
|
||||
int i;
|
||||
for(i = 0; i < arrlen(self->wayland.clipboard_devices_wl); i++) {
|
||||
wl_clipboard_device_context_t* ctx = self->wayland.clipboard_devices_wl[i];
|
||||
if(ctx->offer.wl) wl_data_offer_destroy(ctx->offer.wl);
|
||||
if(wl_proxy_get_version((struct wl_proxy*)ctx->device.wl) >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION) {
|
||||
wl_data_device_release(ctx->device.wl);
|
||||
} else {
|
||||
wl_data_device_destroy(ctx->device.wl);
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
arrfree(self->wayland.clipboard_devices_wl);
|
||||
}
|
||||
|
||||
static void keyboard_repeat_info(void* data,
|
||||
struct wl_keyboard* wl_keyboard,
|
||||
int32_t rate,
|
||||
|
|
@ -1369,10 +1307,8 @@ static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_prot
|
|||
wayland->pointer_seat = NULL;
|
||||
}
|
||||
|
||||
if(data) {
|
||||
free(data->listener);
|
||||
free(data);
|
||||
}
|
||||
free(data->listener);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/* wl_output setup function */
|
||||
|
|
@ -1385,11 +1321,8 @@ static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll, MwU32 version) {
|
|||
}
|
||||
|
||||
static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
if(wayland->output) {
|
||||
wl_output_destroy(wayland->output);
|
||||
wayland->output = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* wl_compositor setup function */
|
||||
|
|
@ -1401,11 +1334,8 @@ static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland*
|
|||
}
|
||||
|
||||
static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
if(wayland->compositor) {
|
||||
wl_compositor_destroy(wayland->compositor);
|
||||
wayland->compositor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* wl_subcompositor setup function */
|
||||
|
|
@ -1421,10 +1351,13 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
|
|||
}
|
||||
|
||||
static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
/* The subcompositor lives in the toplevel/subsurface struct, which is already freed by the time this runs,
|
||||
* so destroy_toplevel()/destroy_subsurface() release it instead. */
|
||||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
wl_subcompositor_destroy(wayland->toplevel->scompositor);
|
||||
}
|
||||
if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
|
||||
wl_subcompositor_destroy(wayland->subsurface->subcompositor);
|
||||
}
|
||||
}
|
||||
|
||||
/* xdg_wm_base setup function */
|
||||
|
|
@ -1443,11 +1376,8 @@ static wayland_protocol_t* xdg_wm_base_setup(MwU32 name, struct _MwLLWayland* wa
|
|||
|
||||
static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
if(data) {
|
||||
xdg_wm_base_destroy(data->context);
|
||||
free(data->listener);
|
||||
free(data);
|
||||
}
|
||||
free(data->listener);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/* zxdg_decoration_manager_v1 setup function */
|
||||
|
|
@ -1457,8 +1387,8 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _
|
|||
(void)version;
|
||||
proto->listener = NULL;
|
||||
|
||||
ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1);
|
||||
ctx->decoration = NULL;
|
||||
ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1);
|
||||
;
|
||||
|
||||
proto->context = ctx;
|
||||
|
||||
|
|
@ -1466,15 +1396,8 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _
|
|||
}
|
||||
|
||||
static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
zxdg_decoration_manager_v1_context_t* ctx;
|
||||
(void)wayland;
|
||||
if(!data) return;
|
||||
|
||||
/* the toplevel decoration itself has to go before the xdg_toplevel, so destroy_toplevel() handles that */
|
||||
ctx = data->context;
|
||||
zxdg_decoration_manager_v1_destroy(ctx->manager);
|
||||
free(ctx);
|
||||
free(data);
|
||||
(void)data;
|
||||
}
|
||||
|
||||
/* wl_shm setup function */
|
||||
|
|
@ -1488,13 +1411,8 @@ static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland
|
|||
}
|
||||
|
||||
static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
if(wayland->framebuffer.shm) wl_shm_destroy(wayland->framebuffer.shm);
|
||||
if(wayland->backbuffer.shm) wl_shm_destroy(wayland->backbuffer.shm);
|
||||
if(wayland->cursor.shm) wl_shm_destroy(wayland->cursor.shm);
|
||||
wayland->framebuffer.shm = NULL;
|
||||
wayland->backbuffer.shm = NULL;
|
||||
wayland->cursor.shm = NULL;
|
||||
}
|
||||
|
||||
static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
||||
|
|
@ -1510,11 +1428,8 @@ static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct
|
|||
|
||||
static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
if(data) {
|
||||
xdg_toplevel_icon_manager_v1_destroy(data->context);
|
||||
free(data->listener);
|
||||
free(data);
|
||||
}
|
||||
free(data->listener);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
||||
|
|
@ -1528,14 +1443,7 @@ static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWay
|
|||
|
||||
static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
if(!data) return;
|
||||
|
||||
/* the destroy request only exists from version 3, before that the proxy is all there is to free */
|
||||
if(wl_proxy_get_version(data->context) >= ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION) {
|
||||
zwlr_layer_shell_v1_destroy(data->context);
|
||||
} else {
|
||||
wl_proxy_destroy(data->context);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
|
@ -1550,9 +1458,7 @@ static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayl
|
|||
|
||||
static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
if(!data) return;
|
||||
|
||||
wp_fifo_manager_v1_destroy(data->context);
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -342,14 +342,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
|
||||
/* Toplevel destroy function */
|
||||
static void destroy_toplevel(MwLL r) {
|
||||
/* The toplevel decoration must go before the xdg_toplevel. The manager itself is released in
|
||||
* zxdg_decoration_manager_v1_interface_destroy along with every other global. */
|
||||
if(WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1) != NULL) {
|
||||
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
|
||||
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context;
|
||||
if(dec->decoration) {
|
||||
zxdg_toplevel_decoration_v1_destroy(dec->decoration);
|
||||
dec->decoration = NULL;
|
||||
}
|
||||
zxdg_toplevel_decoration_v1_destroy(dec->decoration);
|
||||
zxdg_decoration_manager_v1_destroy(dec->manager);
|
||||
}
|
||||
|
||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||
|
|
@ -359,34 +355,19 @@ static void destroy_toplevel(MwLL r) {
|
|||
|
||||
xdg_surface_destroy(r->wayland.toplevel->xdg_surface);
|
||||
|
||||
xkb_state_unref(r->wayland.xkb_state);
|
||||
wl_compositor_destroy(r->wayland.compositor);
|
||||
|
||||
xkb_keymap_unref(r->wayland.xkb_keymap);
|
||||
|
||||
xkb_context_unref(r->wayland.xkb_context);
|
||||
xkb_state_unref(r->wayland.xkb_state);
|
||||
|
||||
r->wayland.xkb_state = NULL;
|
||||
r->wayland.xkb_keymap = NULL;
|
||||
r->wayland.xkb_context = NULL;
|
||||
xkb_context_unref(r->wayland.xkb_context);
|
||||
|
||||
/* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy,
|
||||
* after this function returns, so every widget type that binds a seat (toplevel, popup,
|
||||
* layer surface) releases them the same way instead of leaking or double-freeing them. */
|
||||
|
||||
/* framebuffer.surface has the wl_subsurface role, so that has to go first or the compositor raises defunct_role_object. */
|
||||
wl_subsurface_destroy(r->wayland.toplevel->ssurface);
|
||||
wl_subcompositor_destroy(r->wayland.toplevel->scompositor);
|
||||
|
||||
if(r->wayland.framebuffer.fifo) {
|
||||
wp_fifo_v1_destroy(r->wayland.framebuffer.fifo);
|
||||
r->wayland.framebuffer.fifo = NULL;
|
||||
}
|
||||
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
r->wayland.framebuffer.surface = NULL;
|
||||
|
||||
wl_surface_destroy(r->wayland.backbuffer.surface);
|
||||
r->wayland.backbuffer.surface = NULL;
|
||||
|
||||
free(r->wayland.toplevel);
|
||||
|
||||
|
|
@ -441,10 +422,6 @@ static void destroy_sublevel(MwLL r) {
|
|||
MwLLWaylandBackbufferDestroy(&r->wayland);
|
||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||
|
||||
/* xkb state is borrowed from the parent, so it is not ours to unref */
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
r->wayland.framebuffer.surface = NULL;
|
||||
|
||||
free(r->wayland.sublevel);
|
||||
|
||||
r->wayland.configured = MwFALSE;
|
||||
|
|
@ -505,14 +482,7 @@ static void destroy_subsurface(MwLL r) {
|
|||
MwLLWaylandBackbufferDestroy(&r->wayland);
|
||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||
|
||||
/* role object before the surface */
|
||||
wl_subsurface_destroy(r->wayland.subsurface->subsurface);
|
||||
wl_subcompositor_destroy(r->wayland.subsurface->subcompositor);
|
||||
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
r->wayland.framebuffer.surface = NULL;
|
||||
|
||||
free(r->wayland.subsurface);
|
||||
free(r->wayland.sublevel);
|
||||
|
||||
r->wayland.configured = MwFALSE;
|
||||
}
|
||||
|
|
@ -672,7 +642,8 @@ static void destroy_popup(MwLL r) {
|
|||
xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
|
||||
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
r->wayland.framebuffer.surface = NULL;
|
||||
|
||||
wl_registry_destroy(r->wayland.registry);
|
||||
|
||||
free(r->wayland.popup);
|
||||
|
||||
|
|
@ -776,27 +747,24 @@ static void setup_layer_surface(MwLL r, int x, int y, int width, int height) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Layer surface destroy function */
|
||||
/* Toplevel destroy function */
|
||||
static void destroy_layer_surface(MwLL r) {
|
||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||
|
||||
/* The role object has to go before the wl_surface, otherwise the compositor raises defunct_role_object. */
|
||||
zwlr_layer_surface_v1_destroy(r->wayland.layer_surface->surface);
|
||||
|
||||
free(r->wayland.layer_surface);
|
||||
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
|
||||
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context;
|
||||
zxdg_decoration_manager_v1_destroy(dec->manager);
|
||||
}
|
||||
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
r->wayland.framebuffer.surface = NULL;
|
||||
|
||||
xkb_state_unref(r->wayland.xkb_state);
|
||||
wl_compositor_destroy(r->wayland.compositor);
|
||||
|
||||
xkb_keymap_unref(r->wayland.xkb_keymap);
|
||||
|
||||
xkb_state_unref(r->wayland.xkb_state);
|
||||
|
||||
xkb_context_unref(r->wayland.xkb_context);
|
||||
|
||||
r->wayland.xkb_state = NULL;
|
||||
r->wayland.xkb_keymap = NULL;
|
||||
r->wayland.xkb_context = NULL;
|
||||
wl_registry_destroy(r->wayland.registry);
|
||||
|
||||
r->wayland.configured = MwFALSE;
|
||||
}
|
||||
|
|
@ -825,9 +793,6 @@ static void destroy_widget(MwLL handle) {
|
|||
case MwLL_WAYLAND_LAYER_SURFACE:
|
||||
destroy_layer_surface(handle);
|
||||
break;
|
||||
case MwLL_WAYLAND_SUBSURFACE:
|
||||
destroy_subsurface(handle);
|
||||
break;
|
||||
default:
|
||||
printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle);
|
||||
break;
|
||||
|
|
@ -840,22 +805,18 @@ static void destroy_widget(MwLL handle) {
|
|||
}
|
||||
|
||||
for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) {
|
||||
const char* key = handle->wayland.wl_protocol_setup_map[i].key;
|
||||
void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key);
|
||||
|
||||
/* Many setup functions keep what they bind in the MwLL and store a NULL context, so check
|
||||
* whether the global was bound at all rather than whether the context is NULL. */
|
||||
if(shgeti(handle->wayland.wl_protocol_map, key) != -1) {
|
||||
handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, shget(handle->wayland.wl_protocol_map, key));
|
||||
if(ctx != NULL) {
|
||||
handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx);
|
||||
}
|
||||
shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value);
|
||||
free(handle->wayland.wl_protocol_setup_map[i].value);
|
||||
}
|
||||
|
||||
shfree(handle->wayland.wl_protocol_map);
|
||||
shfree(handle->wayland.wl_protocol_setup_map);
|
||||
|
||||
wl_registry_destroy(handle->wayland.registry);
|
||||
handle->wayland.registry = NULL;
|
||||
|
||||
MwLLWaylandFlush(handle);
|
||||
}
|
||||
|
||||
|
|
@ -919,9 +880,6 @@ static void clip(MwLL handle) {
|
|||
cairo_clip(handle->wayland.cairo.front_cairo_back);
|
||||
}
|
||||
}
|
||||
|
||||
/* parentless handles skip the branch above (arrfree sets ws to NULL, so this is a no-op otherwise) */
|
||||
arrfree(ws);
|
||||
}
|
||||
|
||||
static void wl_logger(const char* fmt, va_list args) {
|
||||
|
|
@ -951,6 +909,7 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
|||
r->wayland.x = x;
|
||||
r->wayland.y = y;
|
||||
r->wayland.parent = parent;
|
||||
r->wayland.valid = MwTRUE;
|
||||
|
||||
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
||||
if(parent == NULL) {
|
||||
|
|
@ -990,9 +949,6 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
|||
}
|
||||
}
|
||||
|
||||
if(r->wayland.region) wl_region_destroy(r->wayland.region);
|
||||
if(r->wayland.o_region) wl_region_destroy(r->wayland.o_region);
|
||||
|
||||
r->wayland.region = wl_compositor_create_region(r->wayland.compositor);
|
||||
r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor);
|
||||
MwLLWaylandRegionSetup(r);
|
||||
|
|
@ -1134,9 +1090,6 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
MwLLWaylandFlush(handle);
|
||||
|
||||
MwLLDestroyCommon(handle);
|
||||
/* destroy_widget() roundtrips, which can still deliver events (keyboard leave etc.) to this handle;
|
||||
* MwLLDispatch skips a NULL handler table instead of reading the freed one */
|
||||
handle->common.handler = NULL;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000;
|
||||
|
|
@ -1150,36 +1103,25 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if(handle->wayland.cursor.setup) {
|
||||
if(handle->wayland.valid) {
|
||||
MwLLWaylandBufferDestroy(&handle->wayland.cursor);
|
||||
wl_surface_destroy(handle->wayland.cursor.surface);
|
||||
}
|
||||
wl_region_destroy(handle->wayland.region);
|
||||
wl_region_destroy(handle->wayland.o_region);
|
||||
wl_region_destroy(handle->wayland.region);
|
||||
|
||||
/* clipboard sources are released with their managers in destroy_widget */
|
||||
if(handle->wayland.icon != NULL) {
|
||||
if(handle->wayland.icon->setup) {
|
||||
if(handle->wayland.supports_zwp) {
|
||||
zwp_primary_selection_source_v1_destroy(handle->wayland.clipboard_source.zwp);
|
||||
} else {
|
||||
wl_data_source_destroy(handle->wayland.clipboard_source.wl);
|
||||
}
|
||||
if(handle->wayland.icon != NULL) {
|
||||
MwLLWaylandBufferDestroy(handle->wayland.icon);
|
||||
wl_surface_destroy(handle->wayland.icon->surface);
|
||||
}
|
||||
free(handle->wayland.icon);
|
||||
|
||||
destroy_widget(handle);
|
||||
} else {
|
||||
printf("widget invalid\n");
|
||||
}
|
||||
|
||||
destroy_widget(handle);
|
||||
|
||||
/* Only parentless handles connect (children borrow the parent's display), and children are
|
||||
* always freed before their parent, so nothing else is using it by now. */
|
||||
if(!handle->wayland.parent && handle->wayland.display) {
|
||||
wl_display_disconnect(handle->wayland.display);
|
||||
handle->wayland.display = NULL;
|
||||
}
|
||||
|
||||
if(handle->wayland.icon_pixmap) MwLLDestroyPixmap(handle->wayland.icon_pixmap);
|
||||
if(handle->wayland.snapshot) cairo_surface_destroy(handle->wayland.snapshot);
|
||||
free(handle->wayland.clipboard_buffer);
|
||||
arrfree(handle->wayland.currentlyHeldWidgets);
|
||||
|
||||
for(i = 0; i < arrlen(topmost_parent->wayland.currentlyHeldWidgets); i++) {
|
||||
if(topmost_parent->wayland.currentlyHeldWidgets[i] == handle) {
|
||||
arrdel(topmost_parent->wayland.currentlyHeldWidgets, i);
|
||||
|
|
@ -1192,6 +1134,13 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
||||
if(!handle->wayland.valid) {
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*w = 1;
|
||||
*h = 1;
|
||||
return;
|
||||
}
|
||||
*x = handle->wayland.x;
|
||||
*y = handle->wayland.y;
|
||||
*w = handle->wayland.ww;
|
||||
|
|
@ -1656,9 +1605,8 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
|||
if(handle->wayland.icon == NULL) {
|
||||
handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer));
|
||||
memset(handle->wayland.icon, 0, sizeof(struct _MwLLWaylandShmBuffer));
|
||||
handle->wayland.icon->shm = handle->wayland.framebuffer.shm;
|
||||
}
|
||||
/* wl_shm is rebound whenever the widget changes state, so don't hold on to an old one */
|
||||
handle->wayland.icon->shm = handle->wayland.framebuffer.shm;
|
||||
|
||||
if(handle->wayland.icon->setup) {
|
||||
MwLLWaylandBufferDestroy(handle->wayland.icon);
|
||||
|
|
@ -1671,17 +1619,11 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
|||
wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0);
|
||||
wl_surface_commit(handle->wayland.icon->surface);
|
||||
|
||||
/* RGBA -> BGRA, one pixel (4 bytes) at a time. The icon buffer is line x line, so rows
|
||||
* have to be placed with its stride rather than the pixmap's. */
|
||||
for(; i < size; i += 4) {
|
||||
int x = (i / 4) % pixmap->common.width;
|
||||
int y = (i / 4) / pixmap->common.width;
|
||||
unsigned char* dst = &handle->wayland.icon->buf_back[(y * line + x) * 4];
|
||||
|
||||
dst[0] = pixmap->common.raw[i + 2];
|
||||
dst[1] = pixmap->common.raw[i + 1];
|
||||
dst[2] = pixmap->common.raw[i + 0];
|
||||
dst[3] = 255;
|
||||
for(; i < size; i += 2) {
|
||||
handle->wayland.icon->buf_back[i] = pixmap->common.raw[i + 2];
|
||||
handle->wayland.icon->buf_back[i + 1] = pixmap->common.raw[i + 1];
|
||||
handle->wayland.icon->buf_back[i + 2] = pixmap->common.raw[i + 0];
|
||||
handle->wayland.icon->buf_back[i + 3] = 255;
|
||||
}
|
||||
|
||||
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, handle->wayland.icon);
|
||||
|
|
@ -1689,9 +1631,6 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
|||
xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1);
|
||||
|
||||
xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon);
|
||||
|
||||
/* the icon is immutable once set, destroying it doesn't unset it */
|
||||
xdg_toplevel_icon_v1_destroy(icon);
|
||||
}
|
||||
}
|
||||
if(!handle->wayland.has_decorations && handle->wayland.do_csd) {
|
||||
|
|
@ -1855,15 +1794,11 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
|
|||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
|
||||
if(toggle) {
|
||||
if(!topmost_parent->wayland.locked_pointer) {
|
||||
topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||
wl_surface_commit(topmost_parent->wayland.backbuffer.surface);
|
||||
}
|
||||
topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||
wl_surface_commit(topmost_parent->wayland.backbuffer.surface);
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
|
||||
if(!topmost_parent->wayland.relative_pointer) {
|
||||
topmost_parent->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, topmost_parent->wayland.pointer);
|
||||
zwp_relative_pointer_v1_add_listener(topmost_parent->wayland.relative_pointer, &MwLLWaylandRelativePointerListener, topmost_parent);
|
||||
}
|
||||
handle->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, topmost_parent->wayland.pointer);
|
||||
zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &MwLLWaylandRelativePointerListener, topmost_parent);
|
||||
} else {
|
||||
if(topmost_parent->wayland.locked_pointer) {
|
||||
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
|
||||
|
|
@ -1886,7 +1821,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
|
|||
if(handle->wayland.clipboard_buffer != NULL) {
|
||||
free(handle->wayland.clipboard_buffer);
|
||||
}
|
||||
handle->wayland.clipboard_buffer = malloc(strlen(text) + 1);
|
||||
handle->wayland.clipboard_buffer = malloc(strlen(text));
|
||||
strcpy(handle->wayland.clipboard_buffer, text);
|
||||
|
||||
if(clipboard_type == MwCLIPBOARD_PRIMARY) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue