Compare commits

...

12 Commits

Author SHA1 Message Date
IoIxD
8d4e845e7c wayland: MwLLGetScreenSize 2025-12-18 13:43:45 -07:00
IoIxD
aeaf0a4547 wayland: MwLLGetCursorCoordImpl 2025-12-18 13:16:16 -07:00
IoIxD
b366fc12a7 Merge branch 'master' of ssh://gitea.nishi.boats:2222/pyrite-dev/milsko 2025-12-18 13:15:20 -07:00
IoIxD
d8c08f80d6 wayland: cursor support 2025-12-18 13:15:03 -07:00
NishiOwO
bfa0a5811e fix 2025-12-19 04:38:29 +09:00
NishiOwO
19f52488b8 fancy things 2025-12-19 03:57:45 +09:00
IoIxD
c6e7421b31 wayland: key modifiers 2025-12-18 11:36:04 -07:00
IoIxD
e3b3363e42 Merge branch 'master' of ssh://gitea.nishi.boats:2222/pyrite-dev/milsko 2025-12-18 11:29:12 -07:00
IoIxD
a815998ace wayland: fix pointer 2025-12-18 11:26:51 -07:00
NishiOwO
75749697ba netbsd wants pthread. idk why 2025-12-19 03:01:12 +09:00
NishiOwO
c9c3a00ed3 unrelated changes 2025-12-19 02:55:30 +09:00
NishiOwO
012650f06f tiny change 2025-12-19 01:37:02 +09:00
8 changed files with 255 additions and 104 deletions

View File

@@ -58,6 +58,20 @@ struct _MwLLWaylandSublevel {
MwLL topmost_parent; /* The parent at the top of all the other parents. Usually a toplevel. */
};
/* Shared set of anything needed for a shm buffer. Used both for surface framebuffers, and cursors. */
struct _MwLLWaylandShmBuffer {
struct wl_shm* shm;
struct wl_shm_pool* shm_pool;
struct wl_buffer* shm_buffer;
struct wl_surface* surface;
struct wl_output* output;
MwU8* buf;
MwU64 buf_size;
int fd;
MwBool setup;
};
struct _MwLLWayland {
struct _MwLLCommon common;
@@ -88,9 +102,16 @@ struct _MwLLWayland {
struct wl_display* display;
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_surface* surface;
struct wl_registry_listener registry_listener;
/*struct wl_event_queue* event_queue;*/
struct wl_region* region;
struct wl_output* output;
struct wl_pointer* pointer;
MwU32 pointer_serial;
MwBool active; /* Whether or not the surface is the one being hovered over. */
MwU32 mod_state;
MwLL* sublevels; /* stb_ds managed array of any sublevels */
MwBool configured; /* Whether or not xdg_toplevel_configure has run once */
@@ -98,13 +119,10 @@ struct _MwLLWayland {
MwU32 x, y, ww, wh; /* Window position */
MwPoint cur_mouse_pos; /* Currently known mouse position */
struct wl_shm* shm;
struct wl_shm_pool* shm_pool;
struct wl_buffer* shm_buffer;
void* mapped_shm_buf;
MwU64 mapped_shm_buf_size;
int shm_fd;
MwBool shm_setup;
MwU32 mw, mh; /* Monitor width and height as advertised by wl_output.mode */
struct _MwLLWaylandShmBuffer framebuffer;
struct _MwLLWaylandShmBuffer cursor;
cairo_surface_t* cs;
cairo_t* cairo;

View File

@@ -9,6 +9,7 @@
#include <Mw/TypeDefs.h>
#include <Mw/Core.h>
#ifndef __gl_h_
#ifdef _WIN32
#include <windows.h>
#else
@@ -19,6 +20,7 @@
#ifndef GLAPIENTRY
#define GLAPIENTRY APIENTRY
#endif
#endif
#ifdef __cplusplus
extern "C" {

View File

@@ -526,6 +526,7 @@
<property name="pixmap" />
<property name="hasBorder" />
<property name="inverted" />
<property name="fillArea" />
</properties>
</widget>
<widget name="Label">

View File

@@ -2,5 +2,6 @@ add_incdir("-I/usr/X11R7/include -I/usr/pkg/include");
add_libdir(
"-L/usr/X11R7/lib -Wl,-R/usr/X11R7/lib -L/usr/pkg/lib -Wl,-R/usr/pkg/lib");
use_backend("x11");
add_libs("pthread");
1;

View File

@@ -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,7 +73,8 @@ 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;
p.point = self->wayland.cur_mouse_pos;
MwLLDispatch(self, move, &p);
/*timed_redraw(self, time, 50, &self->wayland.cooldown_timer);*/
@@ -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);
}
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;
buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
buffer->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) {

View File

@@ -693,7 +693,7 @@ static void force_render_all(MwWidget handle) {
for(i = 0; i < arrlen(handle->children); i++) {
force_render_all(handle->children[i]);
}
MwForceRender(handle);
if(handle->lowlevel != NULL) MwForceRender(handle);
}
void MwToggleDarkTheme(MwWidget handle, int toggle) {

View File

@@ -58,7 +58,6 @@ static void layout(MwWidget handle) {
} else {
wsz = sz * n / sum;
}
wsz -= Margin;
MwVaApply(handle->children[i],
horiz ? MwNx : MwNy, sk, /* this is what gets changed */

View File

@@ -5,6 +5,7 @@ static int create(MwWidget handle) {
MwSetInteger(handle, MwNhasBorder, 0);
MwSetInteger(handle, MwNinverted, 1);
MwSetInteger(handle, MwNfillArea, 1);
return 0;
}
@@ -23,6 +24,13 @@ static void draw(MwWidget handle) {
MwDrawRect(handle, &r, base);
if(px != NULL) {
if(!MwGetInteger(handle, MwNfillArea)) {
r.x = (r.width - px->common.width) / 2;
r.y = (r.height - px->common.height) / 2;
r.width = px->common.width;
r.height = px->common.height;
}
MwLLDrawPixmap(handle->lowlevel, &r, px);
}