|
|
|
|
@@ -17,10 +17,13 @@
|
|
|
|
|
#include <linux/input-event-codes.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Setup the wl_shm buffer with the saved width/height */
|
|
|
|
|
static void buffer_setup(struct _MwLLWayland* wayland);
|
|
|
|
|
/* Destroy the wl_shm buffer */
|
|
|
|
|
static void buffer_destroy(struct _MwLLWayland* handle);
|
|
|
|
|
/* Setup the framebuffer with the saved width/height */
|
|
|
|
|
static void framebuffer_setup(struct _MwLLWayland* wayland);
|
|
|
|
|
/* Destroy the framebuffer */
|
|
|
|
|
static void framebuffer_destroy(struct _MwLLWayland* handle);
|
|
|
|
|
|
|
|
|
|
static void region_setup(MwLL handle);
|
|
|
|
|
static void region_invalidate(MwLL handle);
|
|
|
|
|
|
|
|
|
|
/* Get the registered interface from r, or NULL if it doesn't currently have it. */
|
|
|
|
|
#define WAYLAND_GET_INTERFACE(handle, inter) shget(handle.wl_protocol_map, inter##_interface.name)
|
|
|
|
|
@@ -50,11 +53,17 @@ static void protocol_removed(void* data,
|
|
|
|
|
/* `wl_pointer.enter` callback */
|
|
|
|
|
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) {};
|
|
|
|
|
wl_fixed_t surface_y) {
|
|
|
|
|
MwLL self = data;
|
|
|
|
|
self->wayland.pointer_serial = serial;
|
|
|
|
|
|
|
|
|
|
wl_pointer_set_cursor(wl_pointer, serial, self->wayland.cursor.surface, 0, 0);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* `wl_pointer.leave` callback */
|
|
|
|
|
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
|
|
|
|
|
struct wl_surface* surface) {};
|
|
|
|
|
struct wl_surface* surface) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* `wl_pointer.motion` callback */
|
|
|
|
|
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time,
|
|
|
|
|
@@ -64,6 +73,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
@@ -112,28 +122,6 @@ struct wl_pointer_listener pointer_listener = {
|
|
|
|
|
.axis = pointer_axis,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Recursively dispatch the key event to `handle` and its children */
|
|
|
|
|
static void recursive_key(MwLL handle, void* ud) {
|
|
|
|
|
int i;
|
|
|
|
|
if(handle->wayland.sublevels != NULL) {
|
|
|
|
|
for(i = 0; i < arrlen(handle->wayland.sublevels); i++) {
|
|
|
|
|
MwLLDispatch(handle->wayland.sublevels[i], key, ud);
|
|
|
|
|
recursive_key(handle->wayland.sublevels[i], ud);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recursively dispatch the key_released event to `handle` and its children */
|
|
|
|
|
static void recursive_key_released(MwLL handle, void* ud) {
|
|
|
|
|
int i;
|
|
|
|
|
if(handle->wayland.sublevels != NULL) {
|
|
|
|
|
for(i = 0; i < arrlen(handle->wayland.sublevels); i++) {
|
|
|
|
|
MwLLDispatch(handle->wayland.sublevels[i], key_released, ud);
|
|
|
|
|
recursive_key(handle->wayland.sublevels[i], ud);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* `wl_keyboard.keymap` callback */
|
|
|
|
|
static void keyboard_keymap(void* data,
|
|
|
|
|
struct wl_keyboard* wl_keyboard,
|
|
|
|
|
@@ -253,12 +241,16 @@ static void keyboard_key(void* data,
|
|
|
|
|
default:
|
|
|
|
|
key = sym;
|
|
|
|
|
}
|
|
|
|
|
if((self->wayland.mod_state & 4) == 4) {
|
|
|
|
|
key |= MwLLControlMask;
|
|
|
|
|
}
|
|
|
|
|
if((self->wayland.mod_state & 8) == 8) {
|
|
|
|
|
key |= MwLLAltMask;
|
|
|
|
|
}
|
|
|
|
|
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
|
|
|
|
MwLLDispatch(self, key, &key);
|
|
|
|
|
recursive_key(self, &key);
|
|
|
|
|
} else {
|
|
|
|
|
MwLLDispatch(self, key_released, &key);
|
|
|
|
|
recursive_key_released(self, &key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -271,7 +263,13 @@ static void keyboard_modifiers(void* data,
|
|
|
|
|
MwU32 mods_depressed,
|
|
|
|
|
MwU32 mods_latched,
|
|
|
|
|
MwU32 mods_locked,
|
|
|
|
|
MwU32 group) {};
|
|
|
|
|
MwU32 group) {
|
|
|
|
|
MwLL self = data;
|
|
|
|
|
|
|
|
|
|
self->wayland.mod_state = 0;
|
|
|
|
|
self->wayland.mod_state |= mods_depressed;
|
|
|
|
|
self->wayland.mod_state |= mods_locked;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct wl_keyboard_listener keyboard_listener = {
|
|
|
|
|
.keymap = keyboard_keymap,
|
|
|
|
|
@@ -294,11 +292,37 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
|
|
|
|
wl_keyboard_add_listener(keyboard, &keyboard_listener, data);
|
|
|
|
|
}
|
|
|
|
|
if(capabilities & WL_SEAT_CAPABILITY_POINTER) {
|
|
|
|
|
struct wl_pointer* pointer = wl_seat_get_pointer(wl_seat);
|
|
|
|
|
wl_pointer_add_listener(pointer, &pointer_listener, data);
|
|
|
|
|
self->wayland.pointer = wl_seat_get_pointer(wl_seat);
|
|
|
|
|
wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void output_geometry(void* data,
|
|
|
|
|
struct wl_output* wl_output,
|
|
|
|
|
int32_t x,
|
|
|
|
|
int32_t y,
|
|
|
|
|
int32_t physical_width,
|
|
|
|
|
int32_t physical_height,
|
|
|
|
|
int32_t subpixel,
|
|
|
|
|
const char* make,
|
|
|
|
|
const char* model,
|
|
|
|
|
int32_t transform) {};
|
|
|
|
|
static void output_mode(void* data,
|
|
|
|
|
struct wl_output* wl_output,
|
|
|
|
|
uint32_t flags,
|
|
|
|
|
int32_t width,
|
|
|
|
|
int32_t height,
|
|
|
|
|
int32_t refresh) {
|
|
|
|
|
MwLL self = data;
|
|
|
|
|
self->wayland.mw = width;
|
|
|
|
|
self->wayland.mh = height;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct wl_output_listener output_listener = {
|
|
|
|
|
.geometry = output_geometry,
|
|
|
|
|
.mode = output_mode,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* `xdg_wm_base.ping` callback */
|
|
|
|
|
void xdg_wm_base_ping(void* data,
|
|
|
|
|
struct xdg_wm_base* xdg_wm_base,
|
|
|
|
|
@@ -320,6 +344,14 @@ static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll) {
|
|
|
|
|
return proto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wl_output setup function */
|
|
|
|
|
static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll) {
|
|
|
|
|
ll->wayland.output = wl_registry_bind(ll->wayland.registry, name, &wl_output_interface, 1);
|
|
|
|
|
wl_output_add_listener(ll->wayland.output, &output_listener, ll);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wl_compositor setup function */
|
|
|
|
|
static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
|
|
|
|
wayland->compositor = wl_registry_bind(wayland->registry, name, &wl_compositor_interface, 1);
|
|
|
|
|
@@ -383,6 +415,7 @@ static void xdg_toplevel_configure(void* data,
|
|
|
|
|
MwI32 width, MwI32 height,
|
|
|
|
|
struct wl_array* states) {
|
|
|
|
|
MwLL self = data;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if(width == 0 || height == 0) {
|
|
|
|
|
width = self->wayland.ww;
|
|
|
|
|
@@ -393,16 +426,23 @@ static void xdg_toplevel_configure(void* data,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
region_invalidate(self);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
buffer_destroy(&self->wayland);
|
|
|
|
|
buffer_setup(&self->wayland);
|
|
|
|
|
framebuffer_destroy(&self->wayland);
|
|
|
|
|
framebuffer_setup(&self->wayland);
|
|
|
|
|
region_setup(self);
|
|
|
|
|
|
|
|
|
|
MwLLDispatch(self, resize, NULL);
|
|
|
|
|
MwLLDispatch(self, draw, NULL);
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < arrlen(self->wayland.sublevels); i++) {
|
|
|
|
|
MwLL handle = self->wayland.sublevels[i];
|
|
|
|
|
region_setup(handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*if(!self->wayland.egl_setup) {
|
|
|
|
|
self->wayland.egl_setup = egl_setup(self, self->wayland.x, self->wayland.y, width, height);
|
|
|
|
|
} else {
|
|
|
|
|
@@ -434,7 +474,7 @@ static void xdg_surface_configure(
|
|
|
|
|
xdg_surface_ack_configure(xdg_surface, serial);
|
|
|
|
|
|
|
|
|
|
if(self->wayland.configured) {
|
|
|
|
|
wl_surface_commit(self->wayland.surface);
|
|
|
|
|
wl_surface_commit(self->wayland.framebuffer.surface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self->wayland.configured = MwTRUE;
|
|
|
|
|
@@ -443,76 +483,94 @@ static void xdg_surface_configure(
|
|
|
|
|
/* wl_shm setup function */
|
|
|
|
|
static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
|
|
|
|
|
|
|
|
|
wayland->shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1);
|
|
|
|
|
wayland->framebuffer.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1);
|
|
|
|
|
wayland->cursor.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void update_buffer(MwLL handle) {
|
|
|
|
|
fsync(handle->wayland.shm_fd);
|
|
|
|
|
static void update_framebuffer(struct _MwLLWayland* wayland) {
|
|
|
|
|
struct _MwLLWaylandShmBuffer* buffer = &wayland->framebuffer;
|
|
|
|
|
fsync(buffer->fd);
|
|
|
|
|
|
|
|
|
|
if(handle->wayland.configured) {
|
|
|
|
|
wl_surface_attach(handle->wayland.surface, handle->wayland.shm_buffer, 0, 0);
|
|
|
|
|
wl_surface_commit(handle->wayland.surface);
|
|
|
|
|
if(wayland->configured && buffer->setup) {
|
|
|
|
|
wl_surface_attach(wayland->framebuffer.surface, buffer->shm_buffer, wayland->x, wayland->y);
|
|
|
|
|
wl_surface_commit(wayland->framebuffer.surface);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void buffer_setup(struct _MwLLWayland* wayland) {
|
|
|
|
|
static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
|
|
|
|
|
int x, y;
|
|
|
|
|
int stride = wayland->ww * 4;
|
|
|
|
|
int stride = width * 4;
|
|
|
|
|
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX";
|
|
|
|
|
|
|
|
|
|
wayland->mapped_shm_buf_size = wayland->ww * wayland->wh * 4;
|
|
|
|
|
buffer->buf_size = width * height * 4;
|
|
|
|
|
|
|
|
|
|
wayland->shm_fd = mkstemp(temp_name);
|
|
|
|
|
buffer->fd = mkstemp(temp_name);
|
|
|
|
|
|
|
|
|
|
unlink(temp_name);
|
|
|
|
|
|
|
|
|
|
if(posix_fallocate(wayland->shm_fd, 0, wayland->mapped_shm_buf_size) != 0) {
|
|
|
|
|
if(posix_fallocate(buffer->fd, 0, buffer->buf_size) != 0) {
|
|
|
|
|
printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno));
|
|
|
|
|
close(wayland->shm_fd);
|
|
|
|
|
close(buffer->fd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(ftruncate(wayland->shm_fd, wayland->mapped_shm_buf_size) != 0) {
|
|
|
|
|
if(ftruncate(buffer->fd, buffer->buf_size) != 0) {
|
|
|
|
|
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
|
|
|
|
close(wayland->shm_fd);
|
|
|
|
|
close(buffer->fd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wayland->mapped_shm_buf = mmap(NULL, wayland->mapped_shm_buf_size, PROT_WRITE, MAP_SHARED, wayland->shm_fd, 0);
|
|
|
|
|
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
|
|
|
|
|
|
|
|
|
fsync(wayland->shm_fd);
|
|
|
|
|
fsync(buffer->fd);
|
|
|
|
|
|
|
|
|
|
if(!(wayland->shm_pool = wl_shm_create_pool(wayland->shm, wayland->shm_fd, wayland->mapped_shm_buf_size))) {
|
|
|
|
|
if(!(buffer->shm_pool = wl_shm_create_pool(buffer->shm, buffer->fd, buffer->buf_size))) {
|
|
|
|
|
printf("failure setting up wl_shm: could not create pool.\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wayland->shm_buffer = wl_shm_pool_create_buffer(wayland->shm_pool, 0, wayland->ww, wayland->wh, stride, WL_SHM_FORMAT_ARGB8888);
|
|
|
|
|
|
|
|
|
|
if(wayland->configured) {
|
|
|
|
|
wl_surface_attach(wayland->surface, wayland->shm_buffer, 0, 0);
|
|
|
|
|
wl_surface_commit(wayland->surface);
|
|
|
|
|
buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
|
|
|
|
|
buffer->setup = MwTRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wayland->cs = cairo_image_surface_create_for_data(wayland->mapped_shm_buf, CAIRO_FORMAT_ARGB32, wayland->ww, wayland->wh, 4 * wayland->ww);
|
|
|
|
|
wayland->cairo = cairo_create(wayland->cs);
|
|
|
|
|
|
|
|
|
|
memset(wayland->mapped_shm_buf, 255, wayland->mapped_shm_buf_size);
|
|
|
|
|
update_buffer((MwLL)wayland);
|
|
|
|
|
wayland->shm_setup = MwTRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void buffer_destroy(struct _MwLLWayland* wayland) {
|
|
|
|
|
if(!wayland->shm_setup) {
|
|
|
|
|
static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) {
|
|
|
|
|
if(!buffer->setup) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
wl_buffer_destroy(buffer->shm_buffer);
|
|
|
|
|
wl_shm_pool_destroy(buffer->shm_pool);
|
|
|
|
|
close(buffer->fd);
|
|
|
|
|
buffer->setup = MwFALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void framebuffer_setup(struct _MwLLWayland* wayland) {
|
|
|
|
|
buffer_setup(&wayland->framebuffer, wayland->ww, wayland->wh);
|
|
|
|
|
|
|
|
|
|
wayland->cs = cairo_image_surface_create_for_data(wayland->framebuffer.buf, CAIRO_FORMAT_ARGB32, wayland->ww, wayland->wh, 4 * wayland->ww);
|
|
|
|
|
wayland->cairo = cairo_create(wayland->cs);
|
|
|
|
|
|
|
|
|
|
memset(wayland->framebuffer.buf, 255, wayland->framebuffer.buf_size);
|
|
|
|
|
update_framebuffer(wayland);
|
|
|
|
|
};
|
|
|
|
|
static void framebuffer_destroy(struct _MwLLWayland* wayland) {
|
|
|
|
|
buffer_destroy(&wayland->framebuffer);
|
|
|
|
|
cairo_destroy(wayland->cairo);
|
|
|
|
|
cairo_surface_destroy(wayland->cs);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
wl_buffer_destroy(wayland->shm_buffer);
|
|
|
|
|
// munmap(wayland->mapped_shm_buf, wayland->mapped_shm_buf_size);
|
|
|
|
|
wl_shm_pool_destroy(wayland->shm_pool);
|
|
|
|
|
close(wayland->shm_fd);
|
|
|
|
|
static void region_invalidate(MwLL handle) {
|
|
|
|
|
if(!handle->wayland.configured) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
wl_region_subtract(handle->wayland.region, handle->wayland.x, handle->wayland.y, handle->wayland.ww, handle->wayland.wh);
|
|
|
|
|
}
|
|
|
|
|
static void region_setup(MwLL handle) {
|
|
|
|
|
if(!handle->wayland.configured) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
wl_region_add(handle->wayland.region, handle->wayland.x, handle->wayland.y, handle->wayland.ww, handle->wayland.wh);
|
|
|
|
|
wl_surface_set_input_region(handle->wayland.framebuffer.surface, handle->wayland.region);
|
|
|
|
|
wl_surface_set_opaque_region(handle->wayland.framebuffer.surface, handle->wayland.region);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Standard Wayland event loop. */
|
|
|
|
|
@@ -558,7 +616,7 @@ static int event_loop(MwLL handle) {
|
|
|
|
|
if(!poll(&fd, 1, timeout)) {
|
|
|
|
|
wl_display_cancel_read(handle->wayland.display);
|
|
|
|
|
/* In this case, we need to commit the surface for any animations, etc. */
|
|
|
|
|
wl_surface_commit(handle->wayland.surface);
|
|
|
|
|
wl_surface_commit(handle->wayland.framebuffer.surface);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -587,6 +645,7 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
|
|
|
|
WL_INTERFACE(wl_shm);
|
|
|
|
|
WL_INTERFACE(wl_compositor);
|
|
|
|
|
WL_INTERFACE(wl_seat);
|
|
|
|
|
WL_INTERFACE(wl_output);
|
|
|
|
|
if(wayland->type == MWLL_WAYLAND_TOPLEVEL) {
|
|
|
|
|
WL_INTERFACE(xdg_wm_base);
|
|
|
|
|
WL_INTERFACE(zxdg_decoration_manager_v1);
|
|
|
|
|
@@ -614,6 +673,8 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r->wayland.framebuffer.surface = NULL;
|
|
|
|
|
|
|
|
|
|
/* Do a roundtrip to ensure all interfaces are setup. */
|
|
|
|
|
r->wayland.registry = wl_display_get_registry(r->wayland.display);
|
|
|
|
|
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
|
|
|
|
|
@@ -626,9 +687,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|
|
|
|
r->wayland.toplevel->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
|
|
|
|
|
|
|
|
/* Create a wl_surface, a xdg_surface and a xdg_toplevel */
|
|
|
|
|
r->wayland.surface = wl_compositor_create_surface(r->wayland.compositor);
|
|
|
|
|
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
|
|
|
|
|
|
|
|
|
r->wayland.toplevel->xdg_surface =
|
|
|
|
|
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.surface);
|
|
|
|
|
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
|
|
|
|
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
|
|
|
|
|
|
|
|
|
/* setup mandatory listeners */
|
|
|
|
|
@@ -645,7 +707,7 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|
|
|
|
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
|
|
|
|
|
|
|
|
|
/* Perform the initial commit and wait for the first configure event */
|
|
|
|
|
wl_surface_commit(r->wayland.surface);
|
|
|
|
|
wl_surface_commit(r->wayland.framebuffer.surface);
|
|
|
|
|
event_loop(r);
|
|
|
|
|
|
|
|
|
|
/* setup decorations if we can */
|
|
|
|
|
@@ -669,7 +731,7 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|
|
|
|
/* Sublevel setup function */
|
|
|
|
|
static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|
|
|
|
struct wl_compositor* compositor = parent->wayland.compositor;
|
|
|
|
|
struct wl_surface* parent_surface = parent->wayland.surface;
|
|
|
|
|
struct wl_surface* parent_surface = parent->wayland.framebuffer.surface;
|
|
|
|
|
|
|
|
|
|
r->wayland.sublevel = malloc(sizeof(struct _MwLLWaylandSublevel));
|
|
|
|
|
|
|
|
|
|
@@ -677,7 +739,7 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|
|
|
|
|
|
|
|
|
r->wayland.display = parent->wayland.display;
|
|
|
|
|
|
|
|
|
|
r->wayland.surface = wl_compositor_create_surface(compositor);
|
|
|
|
|
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
|
|
|
|
|
|
|
|
|
|
setup_callbacks(&r->wayland);
|
|
|
|
|
|
|
|
|
|
@@ -693,7 +755,7 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.surface, parent_surface);
|
|
|
|
|
r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.framebuffer.surface, parent_surface);
|
|
|
|
|
|
|
|
|
|
wl_subsurface_set_position(r->wayland.sublevel->subsurface, x, y);
|
|
|
|
|
|
|
|
|
|
@@ -703,6 +765,7 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|
|
|
|
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|
|
|
|
MwLL r;
|
|
|
|
|
r = malloc(sizeof(*r));
|
|
|
|
|
memset(r, 0, sizeof(*r));
|
|
|
|
|
MwLLCreateCommon(r);
|
|
|
|
|
|
|
|
|
|
r->common.type = MwLLBackendWayland;
|
|
|
|
|
@@ -730,7 +793,10 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|
|
|
|
setup_sublevel(parent, r, x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer_setup(&r->wayland);
|
|
|
|
|
framebuffer_setup(&r->wayland);
|
|
|
|
|
|
|
|
|
|
r->wayland.region = wl_compositor_create_region(r->wayland.compositor);
|
|
|
|
|
region_setup(r);
|
|
|
|
|
|
|
|
|
|
MwLLForceRender(r);
|
|
|
|
|
|
|
|
|
|
@@ -740,7 +806,9 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|
|
|
|
static void MwLLDestroyImpl(MwLL handle) {
|
|
|
|
|
MwLLDestroyCommon(handle);
|
|
|
|
|
|
|
|
|
|
buffer_destroy(&handle->wayland);
|
|
|
|
|
buffer_destroy(&handle->wayland.framebuffer);
|
|
|
|
|
buffer_destroy(&handle->wayland.cursor);
|
|
|
|
|
wl_region_destroy(handle->wayland.region);
|
|
|
|
|
|
|
|
|
|
free(handle);
|
|
|
|
|
}
|
|
|
|
|
@@ -754,25 +822,23 @@ 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) {
|
|
|
|
|
region_invalidate(handle);
|
|
|
|
|
handle->wayland.x = x;
|
|
|
|
|
handle->wayland.y = y;
|
|
|
|
|
/*if(handle->wayland.has_set_xy) {
|
|
|
|
|
timed_redraw_by_epoch(handle->wayland.topmost_parent, 25);
|
|
|
|
|
} else if(x != 0 && y != 0) {
|
|
|
|
|
handle->wayland.has_set_xy = MwTRUE;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
wl_subsurface_set_position(handle->wayland.sublevel->subsurface, x, y);
|
|
|
|
|
region_setup(handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MwLLDispatch(handle, draw, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
|
|
|
|
region_invalidate(handle);
|
|
|
|
|
/* Prevent an integer underflow when the w/h is too low */
|
|
|
|
|
if((w < 10 || h < 10)) {
|
|
|
|
|
handle->wayland.ww = 10;
|
|
|
|
|
handle->wayland.wh = 10;
|
|
|
|
|
return;
|
|
|
|
|
goto refresh;
|
|
|
|
|
}
|
|
|
|
|
handle->wayland.ww = w;
|
|
|
|
|
handle->wayland.wh = h;
|
|
|
|
|
@@ -780,8 +846,12 @@ 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);
|
|
|
|
|
}
|
|
|
|
|
buffer_destroy(&handle->wayland);
|
|
|
|
|
buffer_setup(&handle->wayland);
|
|
|
|
|
|
|
|
|
|
refresh:
|
|
|
|
|
region_setup(handle);
|
|
|
|
|
|
|
|
|
|
framebuffer_destroy(&handle->wayland);
|
|
|
|
|
framebuffer_setup(&handle->wayland);
|
|
|
|
|
MwLLDispatch(handle, draw, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -822,7 +892,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLEndDrawImpl(MwLL handle) {
|
|
|
|
|
update_buffer(handle);
|
|
|
|
|
update_framebuffer(&handle->wayland);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
|
|
|
|
|
@@ -922,7 +992,7 @@ 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_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
if(handle->wayland.egl_setup) {
|
|
|
|
|
@@ -932,6 +1002,53 @@ static void MwLLForceRenderImpl(MwLL handle) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
if(handle->wayland.cursor.setup) {
|
|
|
|
|
buffer_destroy(&handle->wayland.cursor);
|
|
|
|
|
wl_surface_destroy(handle->wayland.cursor.surface);
|
|
|
|
|
}
|
|
|
|
|
buffer_setup(&handle->wayland.cursor, image->width, image->height);
|
|
|
|
|
memset(handle->wayland.cursor.buf, 0, handle->wayland.cursor.buf_size);
|
|
|
|
|
|
|
|
|
|
for(y = 0; y < mask->height; y++) {
|
|
|
|
|
unsigned int d = mask->data[y];
|
|
|
|
|
for(x = mask->width - 1; x >= 0; x--) {
|
|
|
|
|
int px = 0;
|
|
|
|
|
int idx = ((y * mask->width) + x) * 4;
|
|
|
|
|
|
|
|
|
|
if(d & 1) {
|
|
|
|
|
handle->wayland.cursor.buf[idx + 3] = 255;
|
|
|
|
|
};
|
|
|
|
|
d = d >> 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for(y = 0; y < image->height; y++) {
|
|
|
|
|
unsigned int d = image->data[y];
|
|
|
|
|
for(x = image->width - 1; x >= 0; x--) {
|
|
|
|
|
int px = 0;
|
|
|
|
|
int idx = ((y * image->width) + x) * 4;
|
|
|
|
|
|
|
|
|
|
if(d & 1) {
|
|
|
|
|
px = 255;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
handle->wayland.cursor.buf[idx] = px;
|
|
|
|
|
handle->wayland.cursor.buf[idx + 1] = px;
|
|
|
|
|
handle->wayland.cursor.buf[idx + 2] = px;
|
|
|
|
|
d = d >> 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handle->wayland.cursor.surface = wl_compositor_create_surface(handle->wayland.compositor);
|
|
|
|
|
|
|
|
|
|
wl_surface_attach(handle->wayland.cursor.surface, handle->wayland.cursor.shm_buffer, 0, 0);
|
|
|
|
|
wl_surface_commit(handle->wayland.cursor.surface);
|
|
|
|
|
|
|
|
|
|
/* If there's currently a pointer, set it up. (Otherwise, it'll be setup during the pointer enter event) */
|
|
|
|
|
if(handle->wayland.pointer != NULL) {
|
|
|
|
|
wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
|
|
|
|
|
@@ -985,9 +1102,14 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
|
|
|
|
*point = handle->wayland.cur_mouse_pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
|
|
|
|
rect->x = 0;
|
|
|
|
|
rect->y = 0;
|
|
|
|
|
rect->width = handle->wayland.mw;
|
|
|
|
|
rect->height = handle->wayland.mh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
|
|
|
|
|