merge conflict
This commit is contained in:
commit
9560c4fd92
20 changed files with 589 additions and 313 deletions
|
|
@ -104,7 +104,7 @@ static void wl_flush(MwLL handle) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Recursively dispatch a draw event to a widget and its children */
|
||||
/* Recursively dispatch a resize event to a widget and its children */
|
||||
static void recursive_dispatch_resize(MwLL handle) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(h) {
|
||||
|
|
@ -118,6 +118,20 @@ static void recursive_dispatch_resize(MwLL handle) {
|
|||
}
|
||||
};
|
||||
|
||||
/* Recursively dispatch a move event to a widget and its children */
|
||||
static void recursive_dispatch_move(MwLL handle, MwLLMouse* p) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
if(h) {
|
||||
int i;
|
||||
for(i = 0; i < arrlen(h->children); i++) {
|
||||
MwLLDispatch(h->children[i]->lowlevel, move, p);
|
||||
if(arrlen(h->children[i]->children) > 0) {
|
||||
recursive_dispatch_move(h->children[i]->lowlevel, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Recursively dispatch a key event to a widget and its children */
|
||||
static void recursive_dispatch_key(MwLL handle, int* k) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
|
|
@ -482,10 +496,13 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria
|
|||
/* `wl_pointer.leave` callback */
|
||||
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
|
||||
struct wl_surface* surface) {
|
||||
(void)data;
|
||||
MwLL self = data;
|
||||
(void)wl_pointer;
|
||||
(void)serial;
|
||||
(void)surface;
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
curSurface = NULL;
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
static void xdg_borderless_step(MwLL self, MwLLMouse p, MwU32 serial) {
|
||||
|
|
@ -514,6 +531,43 @@ static void xdg_borderless_step(MwLL self, MwLLMouse p, MwU32 serial) {
|
|||
|
||||
static MwLL currentlyHeldWidget = NULL;
|
||||
|
||||
static void relative_pointer_motion(void* data,
|
||||
struct zwp_relative_pointer_v1* pointer,
|
||||
uint32_t timeHi,
|
||||
uint32_t timeLo,
|
||||
wl_fixed_t dx,
|
||||
wl_fixed_t dy,
|
||||
wl_fixed_t dxUnaccel,
|
||||
wl_fixed_t dyUnaccel) {
|
||||
MwLL self = data;
|
||||
MwLLMouse p;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
p.point.x = wl_fixed_to_int(dxUnaccel);
|
||||
p.point.y = wl_fixed_to_int(dyUnaccel);
|
||||
|
||||
recursive_dispatch_move(self, &p);
|
||||
if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
}
|
||||
|
||||
struct zwp_relative_pointer_v1_listener relative_pointer_listener =
|
||||
{
|
||||
relative_pointer_motion};
|
||||
|
||||
/* zwp_primary_selection_device_manager_v1 setup function */
|
||||
static wayland_protocol_t* zwp_relative_pointer_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
||||
wayland->relative_pointer_manager = wl_registry_bind(wayland->registry, name, &zwp_relative_pointer_manager_v1_interface, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||
(void)wayland;
|
||||
(void)data;
|
||||
}
|
||||
|
||||
/* `wl_pointer.motion` callback */
|
||||
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time,
|
||||
wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||
|
|
@ -528,24 +582,13 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|||
|
||||
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
|
||||
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
|
||||
if(self->wayland.do_lock_pointer) {
|
||||
self->wayland.cur_mouse_pos.x -= topmost_parent->wayland.ww / 2.;
|
||||
self->wayland.cur_mouse_pos.y -= topmost_parent->wayland.wh / 2.;
|
||||
}
|
||||
p.point = self->wayland.cur_mouse_pos;
|
||||
p.point = self->wayland.cur_mouse_pos;
|
||||
MwLLDispatch(self, move, &p);
|
||||
|
||||
if(currentlyHeldWidget) {
|
||||
MwLLDispatch(currentlyHeldWidget, down, &p);
|
||||
}
|
||||
|
||||
if(self->wayland.do_lock_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);
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, wl_fixed_from_double(topmost_parent->wayland.ww / 2.), wl_fixed_from_double(topmost_parent->wayland.wh / 2.));
|
||||
wl_surface_commit(topmost_parent->wayland.backbuffer.surface);
|
||||
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
|
||||
}
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
};
|
||||
|
||||
|
|
@ -553,6 +596,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|||
static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) {
|
||||
MwLL self = data;
|
||||
MwLLMouse p;
|
||||
MwBool inArea = MwFALSE;
|
||||
|
||||
(void)wl_pointer;
|
||||
(void)serial;
|
||||
|
|
@ -562,10 +606,13 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
|
|||
|
||||
p.point = self->wayland.cur_mouse_pos;
|
||||
|
||||
// p.point.x > x && p.point.x < x + self->wayland.ww && p.point.y > y && p.point.y < y + self->wayland.wh
|
||||
if(
|
||||
self->wayland.framebuffer.surface == curSurface ||
|
||||
self->wayland.backbuffer.surface == curSurface) {
|
||||
if(self->wayland.framebuffer.surface) {
|
||||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
||||
}
|
||||
if(self->wayland.backbuffer.surface) {
|
||||
inArea |= self->wayland.backbuffer.surface == curSurface;
|
||||
}
|
||||
if(inArea) {
|
||||
int i;
|
||||
|
||||
switch(button) {
|
||||
|
|
@ -637,22 +684,24 @@ static void keyboard_keymap(void* data,
|
|||
(void)wl_keyboard;
|
||||
|
||||
if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
struct _MwLLWaylandTopLevel* wayland = self->wayland.toplevel;
|
||||
assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1);
|
||||
|
||||
char* map_shm = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
assert(map_shm != MAP_FAILED);
|
||||
|
||||
struct xkb_keymap* xkb_keymap = xkb_keymap_new_from_string(
|
||||
wayland->xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
self->wayland.xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
munmap(map_shm, size);
|
||||
close(fd);
|
||||
|
||||
struct xkb_state* xkb_state = xkb_state_new(xkb_keymap);
|
||||
|
||||
wayland->xkb_keymap = xkb_keymap;
|
||||
wayland->xkb_state = xkb_state;
|
||||
self->wayland.xkb_keymap = xkb_keymap;
|
||||
self->wayland.xkb_state = xkb_state;
|
||||
} else {
|
||||
self->wayland.xkb_keymap = self->wayland.parent->wayland.xkb_keymap;
|
||||
self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -700,37 +749,54 @@ static void keyboard_key(void* data,
|
|||
MwU32 time,
|
||||
MwU32 key,
|
||||
MwU32 state) {
|
||||
MwLL self = data;
|
||||
MwLL self = data;
|
||||
MwBool inArea;
|
||||
|
||||
(void)wl_keyboard;
|
||||
(void)serial;
|
||||
(void)time;
|
||||
|
||||
WAYLAND_EVENT_OP_START(self);
|
||||
|
||||
if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
struct _MwLLWaylandTopLevel* wayland = self->wayland.toplevel;
|
||||
xkb_layout_index_t layout;
|
||||
xkb_level_index_t level;
|
||||
const xkb_keysym_t* syms_out;
|
||||
MwU32 keycode = key + 8;
|
||||
MwU64 syms_num;
|
||||
int i;
|
||||
if(self->wayland.framebuffer.surface) {
|
||||
inArea |= self->wayland.framebuffer.surface == curSurface;
|
||||
}
|
||||
|
||||
if(!wayland->xkb_keymap) {
|
||||
if(self->wayland.backbuffer.surface) {
|
||||
inArea |= self->wayland.backbuffer.surface == curSurface;
|
||||
}
|
||||
if(inArea) {
|
||||
xkb_layout_index_t layout;
|
||||
MwU32 levels;
|
||||
xkb_level_index_t level;
|
||||
const xkb_keysym_t* syms_out;
|
||||
MwU32 keycode = key + 8;
|
||||
MwU64 syms_num;
|
||||
int i;
|
||||
|
||||
if(!self->wayland.xkb_keymap) {
|
||||
return;
|
||||
}
|
||||
|
||||
layout = xkb_state_key_get_layout(wayland->xkb_state, keycode);
|
||||
level =
|
||||
xkb_keymap_num_levels_for_key(wayland->xkb_keymap, keycode, layout) - 1;
|
||||
syms_num = xkb_keymap_key_get_syms_by_level(wayland->xkb_keymap, keycode, layout, level, &syms_out);
|
||||
layout = xkb_state_key_get_layout(self->wayland.xkb_state, keycode);
|
||||
levels =
|
||||
xkb_keymap_num_levels_for_key(self->wayland.xkb_keymap, keycode, layout);
|
||||
|
||||
if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) {
|
||||
level = 1;
|
||||
} else if(levels >= 1) {
|
||||
level = 0;
|
||||
}
|
||||
syms_num = xkb_keymap_key_get_syms_by_level(self->wayland.xkb_keymap, keycode, layout, level, &syms_out);
|
||||
if(syms_out == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < syms_num; i++) {
|
||||
int sym = syms_out[i];
|
||||
int key;
|
||||
int sym = syms_out[i];
|
||||
int key = -1;
|
||||
const char* name;
|
||||
|
||||
switch(sym) {
|
||||
case XKB_KEY_BackSpace:
|
||||
key = MwLLKeyBackSpace;
|
||||
|
|
@ -768,8 +834,11 @@ static void keyboard_key(void* data,
|
|||
key = MwLLKeyControl;
|
||||
break;
|
||||
default:
|
||||
key = sym;
|
||||
if(MwIsKeyUTF8(sym)) {
|
||||
key = sym;
|
||||
}
|
||||
}
|
||||
|
||||
if((self->wayland.mod_state & 4) == 4) {
|
||||
/* clipboard paste */
|
||||
if(key == 'V') {
|
||||
|
|
@ -785,10 +854,12 @@ static void keyboard_key(void* data,
|
|||
key |= MwLLAltMask;
|
||||
}
|
||||
|
||||
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
recursive_dispatch_key(self, &key);
|
||||
} else {
|
||||
recursive_dispatch_key_released(self, &key);
|
||||
if(key != -1) {
|
||||
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
MwLLDispatch(self, key, &key);
|
||||
} else {
|
||||
MwLLDispatch(self, key_released, &key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1139,11 +1210,10 @@ static void xdg_toplevel_configure(void* data,
|
|||
region_setup(self);
|
||||
MwLLDispatch(self, resize, NULL);
|
||||
|
||||
MwLLDispatch(self, draw, NULL);
|
||||
recursive_dispatch_resize(self);
|
||||
|
||||
if(self->wayland.pointer_constrained) {
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, wl_fixed_from_double(self->wayland.ww / 2.), wl_fixed_from_double(self->wayland.wh / 2.));
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
|
||||
wl_surface_commit(self->wayland.framebuffer.surface);
|
||||
}
|
||||
};
|
||||
|
|
@ -1165,6 +1235,8 @@ static void xdg_surface_configure(
|
|||
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
|
||||
MwLLDispatch(self, draw, NULL);
|
||||
|
||||
if(self->wayland.configured) {
|
||||
update_buffer(self, &self->wayland.framebuffer);
|
||||
update_buffer(self, &self->wayland.backbuffer);
|
||||
|
|
@ -1188,6 +1260,7 @@ static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_proto
|
|||
}
|
||||
|
||||
static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
|
||||
(void)self;
|
||||
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
|
||||
wl_surface_commit(buffer->surface);
|
||||
}
|
||||
|
|
@ -1247,10 +1320,10 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) {
|
|||
if(!buffer->setup) {
|
||||
return;
|
||||
}
|
||||
wl_buffer_destroy(buffer->shm_buffer);
|
||||
wl_buffer_destroy(buffer->shm_buffer_back);
|
||||
wl_shm_pool_destroy(buffer->shm_pool);
|
||||
wl_shm_pool_destroy(buffer->shm_pool_back);
|
||||
if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer);
|
||||
if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back);
|
||||
if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool);
|
||||
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
|
||||
close(buffer->fd);
|
||||
close(buffer->fd_back);
|
||||
buffer->setup = MwFALSE;
|
||||
|
|
@ -1383,14 +1456,14 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
|||
WL_INTERFACE(wl_data_device_manager);
|
||||
WL_INTERFACE(zwp_primary_selection_device_manager_v1);
|
||||
WL_INTERFACE(zwp_pointer_constraints_v1);
|
||||
WL_INTERFACE(zwp_relative_pointer_manager_v1);
|
||||
WL_INTERFACE(xdg_wm_base);
|
||||
if(wayland->type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
WL_INTERFACE(xdg_wm_base);
|
||||
WL_INTERFACE(wp_viewporter);
|
||||
WL_INTERFACE(zxdg_decoration_manager_v1);
|
||||
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
} else if(wayland->type == MWLL_WAYLAND_POPUP) {
|
||||
WL_INTERFACE(xdg_wm_base);
|
||||
} else {
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
}
|
||||
|
|
@ -1428,7 +1501,7 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
r->wayland.has_decorations = MwTRUE;
|
||||
}
|
||||
|
||||
r->wayland.toplevel->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
/* Create a wl_surface, a xdg_surface and a xdg_toplevel */
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
|
|
@ -1489,11 +1562,11 @@ static void destroy_toplevel(MwLL r) {
|
|||
|
||||
xdg_toplevel_destroy(r->wayland.toplevel->xdg_top_level);
|
||||
|
||||
xkb_keymap_unref(r->wayland.toplevel->xkb_keymap);
|
||||
xkb_keymap_unref(r->wayland.xkb_keymap);
|
||||
|
||||
xkb_state_unref(r->wayland.toplevel->xkb_state);
|
||||
xkb_state_unref(r->wayland.xkb_state);
|
||||
|
||||
xkb_context_unref(r->wayland.toplevel->xkb_context);
|
||||
xkb_context_unref(r->wayland.xkb_context);
|
||||
|
||||
free(r->wayland.toplevel);
|
||||
|
||||
|
|
@ -1521,6 +1594,12 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|||
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
|
||||
r->wayland.display = parent->wayland.display;
|
||||
|
||||
if(parent->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface;
|
||||
} else {
|
||||
r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface;
|
||||
}
|
||||
|
||||
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
|
||||
if(wl_display_roundtrip(r->wayland.display) == -1) {
|
||||
printf("roundtrip failed\n");
|
||||
|
|
@ -1530,10 +1609,6 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|||
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
|
||||
|
||||
if(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base))
|
||||
r->wayland.sublevel->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
||||
|
||||
r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.framebuffer.surface, parent_surface);
|
||||
|
||||
wl_subsurface_set_desync(r->wayland.sublevel->subsurface);
|
||||
|
|
@ -1543,6 +1618,9 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
|
|||
wl_subsurface_place_above(r->wayland.sublevel->subsurface, parent->wayland.framebuffer.surface);
|
||||
}
|
||||
|
||||
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
|
||||
r->wayland.xkb_state = parent->wayland.xkb_state;
|
||||
|
||||
r->wayland.configured = MwTRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1630,7 +1708,9 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
|||
r->wayland.popup->xdg_positioner,
|
||||
r->wayland.x, r->wayland.y, r->wayland.ww, r->wayland.wh);
|
||||
|
||||
xdg_surface = topmost_parent->wayland.toplevel->xdg_surface;
|
||||
xdg_surface = topmost_parent->wayland.toplevel->xdg_surface;
|
||||
r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap;
|
||||
r->wayland.xkb_state = topmost_parent->wayland.xkb_state;
|
||||
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
|
||||
|
|
@ -1847,19 +1927,24 @@ 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;
|
||||
goto refresh;
|
||||
if((w < 2 || h < 2)) {
|
||||
handle->wayland.ww = 2;
|
||||
handle->wayland.wh = 2;
|
||||
} else {
|
||||
handle->wayland.ww = w;
|
||||
handle->wayland.wh = h;
|
||||
}
|
||||
|
||||
handle->wayland.ww = w;
|
||||
handle->wayland.wh = h;
|
||||
|
||||
if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL && handle->wayland.configured) {
|
||||
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
}
|
||||
|
||||
if(handle->wayland.type == MWLL_WAYLAND_SUBLEVEL && handle->wayland.configured && !handle->wayland.dispatching_resize) {
|
||||
handle->wayland.dispatching_resize = MwTRUE;
|
||||
MwLLDispatch(handle, resize, NULL);
|
||||
handle->wayland.dispatching_resize = MwFALSE;
|
||||
}
|
||||
|
||||
if(handle->wayland.type == MWLL_WAYLAND_POPUP) {
|
||||
destroy_popup(handle);
|
||||
wl_flush(handle);
|
||||
|
|
@ -2098,9 +2183,7 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
if(handle->wayland.force_render) {
|
||||
// if(!handle->wayland.events_pending) {
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
// }
|
||||
if(handle->wayland.configured) update_buffer(handle, &handle->wayland.framebuffer);
|
||||
handle->wayland.force_render = 0;
|
||||
}
|
||||
|
|
@ -2287,7 +2370,7 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
|||
|
||||
/* 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);
|
||||
// wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2352,10 +2435,28 @@ static void MwLLFocusImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
|
||||
if(handle->wayland.pointer_constraints) {
|
||||
MwLL topmost_parent = handle;
|
||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
|
||||
if(toggle) {
|
||||
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);
|
||||
handle->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, handle->wayland.pointer);
|
||||
zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &relative_pointer_listener, topmost_parent);
|
||||
} else {
|
||||
if(topmost_parent->wayland.locked_pointer) {
|
||||
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
|
||||
topmost_parent->wayland.locked_pointer = NULL;
|
||||
}
|
||||
if(topmost_parent->wayland.relative_pointer) {
|
||||
zwp_relative_pointer_v1_destroy(topmost_parent->wayland.relative_pointer);
|
||||
topmost_parent->wayland.relative_pointer = NULL;
|
||||
}
|
||||
}
|
||||
handle->wayland.do_lock_pointer = toggle;
|
||||
} else {
|
||||
printf("[WARNING] MwLLGrabPointer not supported in Wayland session, zwp_pointer_constraints_v1 required.\n");
|
||||
printf("[WARNING] MwLLGrabPointer not supported in Wayland session, zwp_pointer_constraints_v1 and relative_pointer_manager_v1 are required.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2406,7 +2507,8 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
|||
}
|
||||
|
||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||
MwLLShow(handle, 0);
|
||||
(void)handle;
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
static void MwLLEndStateChangeImpl(MwLL handle) {
|
||||
|
|
@ -2439,9 +2541,8 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
|
|||
int i;
|
||||
for(i = 0; i < arrlen(w->children); i++) {
|
||||
if(w->children[i]->lowlevel->wayland.type == MWLL_WAYLAND_SUBLEVEL) {
|
||||
MwLL child = w->children[i]->lowlevel;
|
||||
child->wayland.sublevel->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(handle->wayland, xdg_wm_base)->context, handle->wayland.framebuffer.surface);
|
||||
MwLL child = w->children[i]->lowlevel;
|
||||
child->wayland.sublevel->xdg_surface = handle->wayland.popup->xdg_surface;
|
||||
wl_subsurface_destroy(child->wayland.sublevel->subsurface);
|
||||
wl_flush(handle);
|
||||
|
||||
|
|
@ -2466,8 +2567,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
|
|||
|
||||
handle->wayland.detatching = MwFALSE;
|
||||
}
|
||||
|
||||
MwLLShow(handle, 1);
|
||||
}
|
||||
|
||||
static int MwLLWaylandCallInitImpl(void) {
|
||||
|
|
|
|||
|
|
@ -558,8 +558,7 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
strcpy(str, s);
|
||||
}
|
||||
|
||||
/* HACK: this is bad, you can guess why */
|
||||
if(strlen(str) == 1) {
|
||||
if(MwIsKeyUTF8(sym)) {
|
||||
char s = str[0];
|
||||
|
||||
if(ev.xkey.state & (ShiftMask | LockMask) && !(ev.xkey.state & (ControlMask | Mod1Mask))) {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde
|
|||
MwRect r = *rect;
|
||||
int roundness = MwGetInteger(handle, MwNroundness);
|
||||
double div;
|
||||
if(rect->width <= 0 || rect->height <= 0){
|
||||
if(rect->width <= 0 || rect->height <= 0) {
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
65
src/string.c
65
src/string.c
|
|
@ -37,6 +37,7 @@ void MwStringTime(char* out, time_t t) {
|
|||
sprintf(out, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year);
|
||||
}
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
|
|
@ -49,3 +50,67 @@ void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) {
|
|||
|
||||
va_end(va);
|
||||
};
|
||||
=======
|
||||
|
||||
MWDECL MwBool MwIsKeyUTF8(MwU32 key) {
|
||||
unsigned char bytes[sizeof(MwU32)];
|
||||
memcpy(bytes, &key, sizeof(MwU32));
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < sizeof(MwU32); i++) {
|
||||
if(( // ASCII
|
||||
// use bytes[0] <= 0x7F to allow ASCII control characters
|
||||
bytes[0] == 0x09 ||
|
||||
bytes[0] == 0x0A ||
|
||||
bytes[0] == 0x0D ||
|
||||
(0x20 <= bytes[0] && bytes[0] <= 0x7E))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(( // non-overlong 2-byte
|
||||
(0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0xBF))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(( // excluding overlongs
|
||||
bytes[0] == 0xE0 &&
|
||||
(0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF)) ||
|
||||
( // straight 3-byte
|
||||
((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
|
||||
bytes[0] == 0xEE ||
|
||||
bytes[0] == 0xEF) &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF)) ||
|
||||
( // excluding surrogates
|
||||
bytes[0] == 0xED &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(( // planes 1-3
|
||||
bytes[0] == 0xF0 &&
|
||||
(0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
|
||||
(0x80 <= bytes[3] && bytes[3] <= 0xBF)) ||
|
||||
( // planes 4-15
|
||||
(0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
|
||||
(0x80 <= bytes[3] && bytes[3] <= 0xBF)) ||
|
||||
( // plane 16
|
||||
bytes[0] == 0xF4 &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
|
||||
(0x80 <= bytes[3] && bytes[3] <= 0xBF))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
>>>>>>> master
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ static int create(MwWidget handle) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle){
|
||||
static void destroy(MwWidget handle) {
|
||||
MwBox b = handle->internal;
|
||||
free(b);
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ static void layout(MwWidget handle) {
|
|||
static void draw(MwWidget handle) {
|
||||
MwRect r;
|
||||
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
|
||||
MwBox b = handle->internal;
|
||||
MwBox b = handle->internal;
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
|
|
@ -93,7 +93,7 @@ static void draw(MwWidget handle) {
|
|||
|
||||
MwLLFreeColor(base);
|
||||
|
||||
if(b->layout){
|
||||
if(b->layout) {
|
||||
layout(handle);
|
||||
|
||||
b->layout = 0;
|
||||
|
|
@ -101,8 +101,8 @@ static void draw(MwWidget handle) {
|
|||
}
|
||||
|
||||
static void prop_change(MwWidget handle, const char* key) {
|
||||
if(strcmp(key, MwNorientation) == 0){
|
||||
MwBox b = handle->internal;
|
||||
if(strcmp(key, MwNorientation) == 0) {
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
|
|
@ -112,8 +112,8 @@ static void prop_change(MwWidget handle, const char* key) {
|
|||
static void children_prop_change(MwWidget handle, MwWidget child, const char* key) {
|
||||
(void)child;
|
||||
|
||||
if(strcmp(key, MwNratio) == 0 || strcmp(key, MwNfixedSize) == 0){
|
||||
MwBox b = handle->internal;
|
||||
if(strcmp(key, MwNratio) == 0 || strcmp(key, MwNfixedSize) == 0) {
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
|
|
@ -121,14 +121,14 @@ static void children_prop_change(MwWidget handle, MwWidget child, const char* ke
|
|||
}
|
||||
|
||||
static void resize(MwWidget handle) {
|
||||
MwBox b = handle->internal;
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
|
||||
static void children_update(MwWidget handle) {
|
||||
MwBox b = handle->internal;
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ static int create(MwWidget handle) {
|
|||
if(!eglMakeCurrent(display, surface, surface, context)) {
|
||||
printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError());
|
||||
}
|
||||
eglSwapInterval(o->egl_display, 0);
|
||||
|
||||
o->egl_display = display;
|
||||
o->egl_surface = surface;
|
||||
|
|
@ -425,8 +426,6 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
|
|||
o->egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
}
|
||||
|
||||
eglSwapInterval(o->egl_display, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -450,6 +449,7 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) {
|
|||
#ifdef USE_WAYLAND
|
||||
if(handle->lowlevel->common.type == MwLLBackendWayland) {
|
||||
waylandopengl_t* o = handle->internal;
|
||||
eglSwapInterval(o->egl_display, 0);
|
||||
if(!eglSwapBuffers(o->egl_display, o->egl_surface)) {
|
||||
printf("ERROR: eglSwapBuffers, %0X\n", eglGetError());
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue