Compare commits
16 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ff4d72582a | |||
| b59ddffce6 | |||
| bbbd248051 | |||
| 0c9aaf26db | |||
| 6541419007 | |||
| 503a259caa | |||
| 37b1f86fa9 | |||
| f3cb2fe15a | |||
| 4061112460 | |||
| 4fe57c6d96 | |||
| 11aa9e860e | |||
| a74814f27b | |||
| a61c199d5e | |||
| a6202258b7 | |||
| eb8b945995 | |||
| 56d4d0377c |
25 changed files with 31008 additions and 12160 deletions
|
|
@ -1,3 +1,8 @@
|
||||||
|
========================= 2.0b ========================
|
||||||
|
- Fixed scrollbar bug where it can freeze entire toolkit
|
||||||
|
- Fixed scroller bug where it bar could appear "empty"
|
||||||
|
- Added function specific to Wayland backend (MwLLWaylandSetToolWindowType) that changes what type a created layer surface is when using MwLLMakeToolWindow
|
||||||
|
|
||||||
========================= 2.0a ========================
|
========================= 2.0a ========================
|
||||||
- Fixed a bug where key_released was not fired in GDI backend
|
- Fixed a bug where key_released was not fired in GDI backend
|
||||||
- Fixed examples
|
- Fixed examples
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Greetings - Welcome to the Milsko GUI Toolkit (Version 2.0a)
|
Greetings - Welcome to the Milsko GUI Toolkit (Version 2.0b)
|
||||||
|
|
||||||
This document contains a brief summary of the contents of this source
|
This document contains a brief summary of the contents of this source
|
||||||
distributions and building instructions for Milsko GUI Toolkit.
|
distributions and building instructions for Milsko GUI Toolkit.
|
||||||
|
|
|
||||||
7
configure
vendored
7
configure
vendored
|
|
@ -36,6 +36,7 @@ our $executable_suffix = "";
|
||||||
our @library_targets = ();
|
our @library_targets = ();
|
||||||
our @examples_targets = ();
|
our @examples_targets = ();
|
||||||
our %examples_libs = ();
|
our %examples_libs = ();
|
||||||
|
our %examples_all = ();
|
||||||
|
|
||||||
our $cross = 0;
|
our $cross = 0;
|
||||||
our $host = "";
|
our $host = "";
|
||||||
|
|
@ -331,11 +332,13 @@ if (param_get("examples")) {
|
||||||
|
|
||||||
if (param_get("shared")) {
|
if (param_get("shared")) {
|
||||||
print(OUT
|
print(OUT
|
||||||
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n"
|
"${l}: ${s}${object_suffix} ${add} src/${library_prefix}Mw${library_suffix}\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print(OUT "${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n");
|
print(OUT
|
||||||
|
"${l}: ${s}${object_suffix} ${add} src/${library_prefix}Mw.a\n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (grep(/^cocoa$/, @backends)) {
|
if (grep(/^cocoa$/, @backends)) {
|
||||||
print(OUT
|
print(OUT
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
| Language | Repo | Version | Notes |
|
| Language | Repo | Version | Notes |
|
||||||
| -------- | --------------------------------------------------------------------- | ------- | -------------- |
|
| -------- | --------------------------------------------------------------------- | ------- | -------------- |
|
||||||
| Node.js | [milsko-node](https://forgejo.nishi.boats/pyrite-dev/milsko-node) | 1.4 | Auto-generated |
|
| Node.js | [milsko-node](https://forgejo.nishi.boats/pyrite-dev/milsko-node) | 1.4 | Auto-generated |
|
||||||
| C++ | [mwcxx](https://forgejo.nishi.boats/pyrite-dev/mwcxx) | 2.0a | Auto-generated |
|
| C++ | [mwcxx](https://forgejo.nishi.boats/pyrite-dev/mwcxx) | 2.0b | Auto-generated |
|
||||||
| Python | [milsko-py](https://forgejo.nishi.boats/pyrite-dev/milsko-py) | 2.0a | Auto-generated |
|
| Python | [milsko-py](https://forgejo.nishi.boats/pyrite-dev/milsko-py) | 2.0b | Auto-generated |
|
||||||
| Pascal | [milsko-pascal](https://forgejo.nishi.boats/pyrite-dev/milsko-pascal) | 2.0a | Auto-generated |
|
| Pascal | [milsko-pascal](https://forgejo.nishi.boats/pyrite-dev/milsko-pascal) | 2.0b | Auto-generated |
|
||||||
|
|
||||||
# Inactive Bindings
|
# Inactive Bindings
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ int main() {
|
||||||
f = frame("Separator", -PaddingContent, -PaddingContent, MwSeparatorClass, NULL);
|
f = frame("Separator", -PaddingContent, -PaddingContent, MwSeparatorClass, NULL);
|
||||||
|
|
||||||
f = frame("SubWindow", -PaddingContent, -PaddingContent, MwViewportClass,
|
f = frame("SubWindow", -PaddingContent, -PaddingContent, MwViewportClass,
|
||||||
MwNcolumnSpan, 2,
|
MwNcolumnSpan, 3,
|
||||||
NULL);
|
NULL);
|
||||||
w = child(f);
|
w = child(f);
|
||||||
MwViewportSetSize(w, 512, 512);
|
MwViewportSetSize(w, 512, 512);
|
||||||
|
|
@ -352,7 +352,9 @@ int main() {
|
||||||
MwNtitle, "Sub window 2",
|
MwNtitle, "Sub window 2",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass, NULL);
|
f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass,
|
||||||
|
MwNcolumnSpan, 2,
|
||||||
|
NULL);
|
||||||
w = child(f);
|
w = child(f);
|
||||||
MwSetString(MwTabAdd(w, "ABC"), MwNbackground, "#f00");
|
MwSetString(MwTabAdd(w, "ABC"), MwNbackground, "#f00");
|
||||||
MwSetString(MwTabAdd(w, "DEF"), MwNbackground, "#0f0");
|
MwSetString(MwTabAdd(w, "DEF"), MwNbackground, "#0f0");
|
||||||
|
|
@ -364,7 +366,14 @@ int main() {
|
||||||
v = MwTreeViewAdd(w, v, NULL, "def");
|
v = MwTreeViewAdd(w, v, NULL, "def");
|
||||||
v = MwTreeViewAdd(w, v, NULL, "ghi");
|
v = MwTreeViewAdd(w, v, NULL, "ghi");
|
||||||
|
|
||||||
f = frame("Viewport", -PaddingContent, -PaddingContent, MwViewportClass, NULL);
|
f = frame("Text", -PaddingContent, -PaddingContent, MwViewportClass,
|
||||||
|
MwNcolumnSpan, 2,
|
||||||
|
NULL);
|
||||||
|
w = child(f);
|
||||||
|
|
||||||
|
f = frame("Viewport", -PaddingContent, -PaddingContent, MwViewportClass,
|
||||||
|
MwNcolumnSpan, 2,
|
||||||
|
NULL);
|
||||||
w = child(f);
|
w = child(f);
|
||||||
MwViewportSetSize(w, 256, 256);
|
MwViewportSetSize(w, 256, 256);
|
||||||
MwVaCreateWidget(MwButtonClass, "btn", MwViewportGetViewport(w), 64, 64, 128, 128,
|
MwVaCreateWidget(MwButtonClass, "btn", MwViewportGetViewport(w), 64, 64, 128, 128,
|
||||||
|
|
@ -382,6 +391,4 @@ int main() {
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
MwLoop(window);
|
MwLoop(window);
|
||||||
|
|
||||||
MwDestroyPixmap(px);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,6 @@ struct _MwLLWayland {
|
||||||
struct zwp_relative_pointer_v1* relative_pointer;
|
struct zwp_relative_pointer_v1* relative_pointer;
|
||||||
struct zwp_locked_pointer_v1* locked_pointer;
|
struct zwp_locked_pointer_v1* locked_pointer;
|
||||||
MwBool pointer_constrained;
|
MwBool pointer_constrained;
|
||||||
MwBool valid;
|
|
||||||
|
|
||||||
#ifdef USE_DBUS
|
#ifdef USE_DBUS
|
||||||
MwLLDBusContext dbus;
|
MwLLDBusContext dbus;
|
||||||
|
|
@ -396,7 +395,7 @@ struct _MwLLWayland {
|
||||||
struct wl_data_device_manager* wl;
|
struct wl_data_device_manager* wl;
|
||||||
struct zwp_primary_selection_device_manager_v1* zwp;
|
struct zwp_primary_selection_device_manager_v1* zwp;
|
||||||
} clipboard_manager;
|
} clipboard_manager;
|
||||||
union {
|
struct {
|
||||||
struct wl_data_source* wl;
|
struct wl_data_source* wl;
|
||||||
struct zwp_primary_selection_source_v1* zwp;
|
struct zwp_primary_selection_source_v1* zwp;
|
||||||
} clipboard_source;
|
} clipboard_source;
|
||||||
|
|
@ -464,6 +463,8 @@ struct _MwLLWayland {
|
||||||
MwBool accepts_dnd;
|
MwBool accepts_dnd;
|
||||||
|
|
||||||
MwBool shown;
|
MwBool shown;
|
||||||
|
|
||||||
|
enum zwlr_layer_shell_v1_layer layer_surface_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwLLWaylandColor {
|
struct _MwLLWaylandColor {
|
||||||
|
|
@ -526,4 +527,13 @@ typedef struct zxdg_decoration_manager_v1_context {
|
||||||
|
|
||||||
extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener;
|
extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* function for setting the layer surface type used when creating a tool window
|
||||||
|
* (assuming layer surfaces are used).
|
||||||
|
*
|
||||||
|
* NOTE: Must be called after MwLLMakeToolWindow, as that function sets the type to
|
||||||
|
* the default of ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY.
|
||||||
|
*/
|
||||||
|
MWDECL void MWAPI MwLLWaylandSetToolWindowType(MwLL handle, enum zwlr_layer_shell_v1_layer type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@ struct _MwMenu {
|
||||||
MwMenu* sub;
|
MwMenu* sub;
|
||||||
void* opaque;
|
void* opaque;
|
||||||
int cleaned;
|
int cleaned;
|
||||||
|
int bold;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwEntry {
|
struct _MwEntry {
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@
|
||||||
/*!
|
/*!
|
||||||
* @brief Patchlevel of version, if patchlevel_alphabet is a or bigger, this value is calculated by `patchlevel_alphabet - 'a' + 1`. Otherwise 0
|
* @brief Patchlevel of version, if patchlevel_alphabet is a or bigger, this value is calculated by `patchlevel_alphabet - 'a' + 1`. Otherwise 0
|
||||||
*/
|
*/
|
||||||
#define MwPATCH 1
|
#define MwPATCH 2
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Version in string
|
* @brief Version in string
|
||||||
*/
|
*/
|
||||||
#define MwVERSION "2.0a"
|
#define MwVERSION "2.0b"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Version in string
|
* @brief Version in string
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,8 @@ new_example("examples/basic/subwindow");
|
||||||
new_example("examples/basic/tab");
|
new_example("examples/basic/tab");
|
||||||
new_example("examples/basic/document");
|
new_example("examples/basic/document");
|
||||||
|
|
||||||
|
#new_example("examples/doom/mwdoom", "", 1);
|
||||||
|
|
||||||
if (param_get("opengl")) {
|
if (param_get("opengl")) {
|
||||||
new_example("examples/gldemos/boing", $gl_libs);
|
new_example("examples/gldemos/boing", $gl_libs);
|
||||||
new_example("examples/gldemos/clock", $gl_libs);
|
new_example("examples/gldemos/clock", $gl_libs);
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,12 @@ sub add_libs {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub new_example {
|
sub new_example {
|
||||||
if (@_ == 2) {
|
if (@_ >= 2) {
|
||||||
$examples_libs{"$_[0]${executable_suffix}"} = $_[1];
|
$examples_libs{"$_[0]${executable_suffix}"} = $_[1];
|
||||||
}
|
}
|
||||||
|
if (@_ >= 3) {
|
||||||
|
$examples_all{"$_[0]${executable_suffix}"} = $_[2];
|
||||||
|
}
|
||||||
push(@examples_targets, "${_[0]}${executable_suffix}");
|
push(@examples_targets, "${_[0]}${executable_suffix}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -137,13 +137,25 @@ void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32
|
||||||
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
|
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
|
||||||
cairo_destroy(cairo->front_cairo);
|
cairo_destroy(cairo->front_cairo);
|
||||||
cairo_destroy(cairo->front_cairo_back);
|
cairo_destroy(cairo->front_cairo_back);
|
||||||
cairo_surface_destroy(cairo->front_cs);
|
|
||||||
cairo_surface_destroy(cairo->frontbuffer_cs);
|
|
||||||
cairo_destroy(cairo->frontbuffer_cairo);
|
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;
|
||||||
};
|
};
|
||||||
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
|
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
|
||||||
cairo_destroy(cairo->back_cairo);
|
cairo_destroy(cairo->back_cairo);
|
||||||
cairo_surface_destroy(cairo->back_cs);
|
cairo_surface_destroy(cairo->back_cs);
|
||||||
|
|
||||||
|
cairo->back_cairo = NULL;
|
||||||
|
cairo->back_cs = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
void MwLLCairoDestroy(struct _MwLLCairo handle) {
|
void MwLLCairoDestroy(struct _MwLLCairo handle) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
||||||
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
|
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
|
||||||
|
|
||||||
|
MwLLCairoFrontDestroy(&wayland->cairo);
|
||||||
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
|
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
|
||||||
|
|
||||||
memset(wayland->framebuffer.buf_back, 255, wayland->framebuffer.buf_size);
|
memset(wayland->framebuffer.buf_back, 255, wayland->framebuffer.buf_size);
|
||||||
|
|
@ -38,6 +39,7 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
|
||||||
}
|
}
|
||||||
MwLLWaylandBufferSetup(&wayland->backbuffer, w, h);
|
MwLLWaylandBufferSetup(&wayland->backbuffer, w, h);
|
||||||
|
|
||||||
|
MwLLCairoBackDestroy(&wayland->cairo);
|
||||||
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
|
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
|
||||||
|
|
||||||
memset(wayland->backbuffer.buf_back, 0, wayland->backbuffer.buf_size);
|
memset(wayland->backbuffer.buf_back, 0, wayland->backbuffer.buf_size);
|
||||||
|
|
@ -57,40 +59,44 @@ void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* wayland) {
|
||||||
|
|
||||||
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
|
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
|
||||||
int stride = width * 4;
|
int stride = width * 4;
|
||||||
|
int err;
|
||||||
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXXXX";
|
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXXXX";
|
||||||
char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXXXX";
|
char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXXXX";
|
||||||
|
|
||||||
|
MwLLWaylandBufferDestroy(buffer);
|
||||||
|
|
||||||
buffer->buf_size = width * height * 4;
|
buffer->buf_size = width * height * 4;
|
||||||
|
|
||||||
buffer->fd = mkstemp(temp_name);
|
buffer->fd = mkstemp(temp_name);
|
||||||
buffer->fd_back = mkstemp(temp_name_back);
|
buffer->fd_back = mkstemp(temp_name_back);
|
||||||
if(buffer->fd >= 65536) {
|
if(buffer->fd >= 65536) {
|
||||||
MwDispatchError(-1, "Amount of allocated buffers has gone above 65536! Cannot continue.\n");
|
MwDispatchError(-1, "Amount of allocated buffers has gone above 65536! Cannot continue.\n");
|
||||||
return;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink(temp_name);
|
unlink(temp_name);
|
||||||
unlink(temp_name_back);
|
unlink(temp_name_back);
|
||||||
|
|
||||||
if(posix_fallocate(buffer->fd, 0, buffer->buf_size) != 0) {
|
/* posix_fallocate returns the error rather than setting errno */
|
||||||
printf("failure setting up wl_shm (front buf): could not fallocate. %s.\n", strerror(errno));
|
if((err = posix_fallocate(buffer->fd, 0, buffer->buf_size)) != 0) {
|
||||||
close(buffer->fd);
|
printf("failure setting up wl_shm (front buf): could not fallocate %llu bytes. %s.\n", (unsigned long long)buffer->buf_size, strerror(err));
|
||||||
return;
|
goto fail;
|
||||||
}
|
}
|
||||||
if(posix_fallocate(buffer->fd_back, 0, buffer->buf_size) != 0) {
|
if((err = 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));
|
printf("failure setting up wl_shm (back buf): could not fallocate %llu bytes. %s.\n", (unsigned long long)buffer->buf_size, strerror(err));
|
||||||
close(buffer->fd_back);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if(ftruncate(buffer->fd, buffer->buf_size) != 0) {
|
if(ftruncate(buffer->fd, buffer->buf_size) != 0) {
|
||||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||||
close(buffer->fd);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) {
|
if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) {
|
||||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||||
close(buffer->fd_back);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
||||||
|
|
@ -110,6 +116,13 @@ 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 = 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->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
|
||||||
buffer->setup = MwTRUE;
|
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) {
|
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
||||||
|
|
@ -124,6 +137,15 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
||||||
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
|
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
|
||||||
close(buffer->fd);
|
close(buffer->fd);
|
||||||
close(buffer->fd_back);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat);
|
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 setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
||||||
|
|
||||||
static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat);
|
static void destroy_clipboard(MwLL self);
|
||||||
static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
|
static void destroy_zwp_clipboard(MwLL self);
|
||||||
static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos);
|
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 */
|
/* Recursively dispatch a key event to a widget and its children */
|
||||||
|
|
@ -133,6 +133,9 @@ static void wl_data_device_data_offer(void* data,
|
||||||
|
|
||||||
wl_data_offer_add_listener(offer, &offer_listener, 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;
|
self->offer.wl = offer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -320,6 +323,9 @@ static void zwp_primary_selection_device_v1_data_offer(void* data,
|
||||||
wl_clipboard_device_context_t* self = data;
|
wl_clipboard_device_context_t* self = data;
|
||||||
(void)zwp_primary_selection_device_v1;
|
(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;
|
self->offer.zwp = offer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -491,14 +497,15 @@ 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) {
|
static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)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) {
|
if(wayland->clipboard_manager.wl != NULL) {
|
||||||
wl_data_device_manager_destroy(wayland->clipboard_manager.wl);
|
wl_data_device_manager_destroy(wayland->clipboard_manager.wl);
|
||||||
wayland->clipboard_manager.wl = NULL;
|
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 */
|
/* zwp_primary_selection_device_manager_v1 setup function */
|
||||||
|
|
@ -526,8 +533,17 @@ 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) {
|
static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
|
||||||
(void)data;
|
(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 */
|
/* zwp_primary_selection_device_manager_v1 setup function */
|
||||||
|
|
@ -538,8 +554,15 @@ 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) {
|
static void zwp_pointer_constraints_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
|
||||||
(void)data;
|
(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;
|
static struct wl_surface* curSurface = NULL;
|
||||||
|
|
@ -667,8 +690,15 @@ 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) {
|
static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
|
||||||
(void)data;
|
(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 */
|
/* `wl_pointer.motion` callback */
|
||||||
|
|
@ -706,8 +736,10 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
||||||
|
|
||||||
for(i = 0; i < arrlen(currentlyHeldWidgets); i++) {
|
for(i = 0; i < arrlen(currentlyHeldWidgets); i++) {
|
||||||
MwLL new_topmost = currentlyHeldWidgets[i];
|
MwLL new_topmost = currentlyHeldWidgets[i];
|
||||||
p.point = topmost_parent->wayland.cur_mouse_pos;
|
/* the position is relative to the surface the pointer is on (ours), so only widgets below
|
||||||
while(new_topmost->wayland.parent) {
|
* us are offset from it. going further would also subtract e.g. a popup's position */
|
||||||
|
p.point = self->wayland.cur_mouse_pos;
|
||||||
|
while(new_topmost != self && new_topmost->wayland.parent) {
|
||||||
p.point.x -= new_topmost->wayland.x;
|
p.point.x -= new_topmost->wayland.x;
|
||||||
p.point.y -= new_topmost->wayland.y;
|
p.point.y -= new_topmost->wayland.y;
|
||||||
new_topmost = new_topmost->wayland.parent;
|
new_topmost = new_topmost->wayland.parent;
|
||||||
|
|
@ -732,8 +764,9 @@ static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwP
|
||||||
while(topmost_parent->wayland.parent) {
|
while(topmost_parent->wayland.parent) {
|
||||||
topmost_parent = topmost_parent->wayland.parent;
|
topmost_parent = topmost_parent->wayland.parent;
|
||||||
if(topmost_parent) {
|
if(topmost_parent) {
|
||||||
/* if the topmost parent is a popup/subwindow then its x/y is irrelevant to us. */
|
/* if the topmost parent is a popup/subwindow/layer surface then its x/y is irrelevant to us,
|
||||||
if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP && topmost_parent->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
* it's the window's position on screen and pointer coordinates are relative to the window. */
|
||||||
|
if(topmost_parent->wayland.type == MwLL_WAYLAND_SUBLEVEL || topmost_parent->wayland.type == MwLL_WAYLAND_SUBSURFACE) {
|
||||||
absolute_pos.x += topmost_parent->wayland.x;
|
absolute_pos.x += topmost_parent->wayland.x;
|
||||||
absolute_pos.y += topmost_parent->wayland.y;
|
absolute_pos.y += topmost_parent->wayland.y;
|
||||||
}
|
}
|
||||||
|
|
@ -918,9 +951,16 @@ static void keyboard_keymap(void* data,
|
||||||
|
|
||||||
struct xkb_state* xkb_state = xkb_state_new(xkb_keymap);
|
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_keymap = xkb_keymap;
|
||||||
self->wayland.xkb_state = xkb_state;
|
self->wayland.xkb_state = xkb_state;
|
||||||
} else {
|
} 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_keymap = self->wayland.parent->wayland.xkb_keymap;
|
||||||
self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state;
|
self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state;
|
||||||
}
|
}
|
||||||
|
|
@ -1014,21 +1054,24 @@ static void keyboard_key(void* data,
|
||||||
MwU64 syms_num;
|
MwU64 syms_num;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(!self->wayland.xkb_keymap) {
|
struct xkb_keymap* xkb_keymap = topmost_parent->wayland.xkb_keymap;
|
||||||
|
struct xkb_state* xkb_state = topmost_parent->wayland.xkb_state;
|
||||||
|
|
||||||
|
if(!xkb_keymap || !xkb_state) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout = xkb_state_key_get_layout(self->wayland.xkb_state, keycode);
|
layout = xkb_state_key_get_layout(xkb_state, keycode);
|
||||||
levels =
|
levels =
|
||||||
xkb_keymap_num_levels_for_key(self->wayland.xkb_keymap, keycode, layout);
|
xkb_keymap_num_levels_for_key(xkb_keymap, keycode, layout);
|
||||||
|
|
||||||
if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) {
|
if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) {
|
||||||
level = 1;
|
level = 1;
|
||||||
} else if(levels >= 1) {
|
} else if(levels >= 1) {
|
||||||
level = 0;
|
level = 0;
|
||||||
}
|
}
|
||||||
syms_num = xkb_keymap_key_get_syms_by_level(self->wayland.xkb_keymap, keycode, layout, level, &syms_out);
|
syms_num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, layout, level, &syms_out);
|
||||||
if(syms_out == NULL) {
|
if(syms_out == NULL) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -1159,6 +1202,31 @@ static void setup_clipboard(MwLL self, struct wl_seat* wl_seat) {
|
||||||
device_ctx_wl->accepted_types[5] = "text/uri-list";
|
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,
|
static void keyboard_repeat_info(void* data,
|
||||||
struct wl_keyboard* wl_keyboard,
|
struct wl_keyboard* wl_keyboard,
|
||||||
int32_t rate,
|
int32_t rate,
|
||||||
|
|
@ -1307,9 +1375,11 @@ static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_prot
|
||||||
wayland->pointer_seat = NULL;
|
wayland->pointer_seat = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(data) {
|
||||||
free(data->listener);
|
free(data->listener);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* wl_output setup function */
|
/* wl_output setup function */
|
||||||
static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll, MwU32 version) {
|
static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll, MwU32 version) {
|
||||||
|
|
@ -1321,8 +1391,11 @@ 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) {
|
static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
if(wayland->output) {
|
||||||
|
wl_output_destroy(wayland->output);
|
||||||
|
wayland->output = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wl_compositor setup function */
|
/* wl_compositor setup function */
|
||||||
|
|
@ -1334,8 +1407,11 @@ static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland*
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
if(wayland->compositor) {
|
||||||
|
wl_compositor_destroy(wayland->compositor);
|
||||||
|
wayland->compositor = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wl_subcompositor setup function */
|
/* wl_subcompositor setup function */
|
||||||
|
|
@ -1351,13 +1427,10 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
|
(void)wayland;
|
||||||
(void)data;
|
(void)data;
|
||||||
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
|
/* The subcompositor lives in the toplevel/subsurface struct, which is already freed by the time this runs,
|
||||||
wl_subcompositor_destroy(wayland->toplevel->scompositor);
|
* so destroy_toplevel()/destroy_subsurface() release it instead. */
|
||||||
}
|
|
||||||
if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
|
|
||||||
wl_subcompositor_destroy(wayland->subsurface->subcompositor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xdg_wm_base setup function */
|
/* xdg_wm_base setup function */
|
||||||
|
|
@ -1376,9 +1449,12 @@ 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) {
|
static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
(void)wayland;
|
||||||
|
if(data) {
|
||||||
|
xdg_wm_base_destroy(data->context);
|
||||||
free(data->listener);
|
free(data->listener);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* zxdg_decoration_manager_v1 setup function */
|
/* zxdg_decoration_manager_v1 setup function */
|
||||||
static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
||||||
|
|
@ -1388,7 +1464,7 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _
|
||||||
proto->listener = NULL;
|
proto->listener = NULL;
|
||||||
|
|
||||||
ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1);
|
ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1);
|
||||||
;
|
ctx->decoration = NULL;
|
||||||
|
|
||||||
proto->context = ctx;
|
proto->context = ctx;
|
||||||
|
|
||||||
|
|
@ -1396,8 +1472,15 @@ 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) {
|
static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
|
zxdg_decoration_manager_v1_context_t* ctx;
|
||||||
(void)wayland;
|
(void)wayland;
|
||||||
(void)data;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wl_shm setup function */
|
/* wl_shm setup function */
|
||||||
|
|
@ -1411,8 +1494,13 @@ 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) {
|
static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
|
||||||
(void)data;
|
(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) {
|
static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
||||||
|
|
@ -1428,9 +1516,12 @@ 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) {
|
static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
(void)wayland;
|
||||||
|
if(data) {
|
||||||
|
xdg_toplevel_icon_manager_v1_destroy(data->context);
|
||||||
free(data->listener);
|
free(data->listener);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
|
||||||
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
|
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
|
||||||
|
|
@ -1443,7 +1534,14 @@ 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) {
|
static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
(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);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1458,7 +1556,9 @@ 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) {
|
static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
|
||||||
(void)wayland;
|
(void)wayland;
|
||||||
|
if(!data) return;
|
||||||
|
|
||||||
|
wp_fifo_manager_v1_destroy(data->context);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -342,10 +342,14 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
||||||
|
|
||||||
/* Toplevel destroy function */
|
/* Toplevel destroy function */
|
||||||
static void destroy_toplevel(MwLL r) {
|
static void destroy_toplevel(MwLL r) {
|
||||||
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
|
/* 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) {
|
||||||
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context;
|
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);
|
zxdg_toplevel_decoration_v1_destroy(dec->decoration);
|
||||||
zxdg_decoration_manager_v1_destroy(dec->manager);
|
dec->decoration = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||||
|
|
@ -355,19 +359,34 @@ static void destroy_toplevel(MwLL r) {
|
||||||
|
|
||||||
xdg_surface_destroy(r->wayland.toplevel->xdg_surface);
|
xdg_surface_destroy(r->wayland.toplevel->xdg_surface);
|
||||||
|
|
||||||
wl_compositor_destroy(r->wayland.compositor);
|
xkb_state_unref(r->wayland.xkb_state);
|
||||||
|
|
||||||
xkb_keymap_unref(r->wayland.xkb_keymap);
|
xkb_keymap_unref(r->wayland.xkb_keymap);
|
||||||
|
|
||||||
xkb_state_unref(r->wayland.xkb_state);
|
|
||||||
|
|
||||||
xkb_context_unref(r->wayland.xkb_context);
|
xkb_context_unref(r->wayland.xkb_context);
|
||||||
|
|
||||||
|
r->wayland.xkb_state = NULL;
|
||||||
|
r->wayland.xkb_keymap = NULL;
|
||||||
|
r->wayland.xkb_context = NULL;
|
||||||
|
|
||||||
/* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy,
|
/* 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,
|
* 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. */
|
* 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);
|
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);
|
free(r->wayland.toplevel);
|
||||||
|
|
||||||
|
|
@ -422,6 +441,10 @@ static void destroy_sublevel(MwLL r) {
|
||||||
MwLLWaylandBackbufferDestroy(&r->wayland);
|
MwLLWaylandBackbufferDestroy(&r->wayland);
|
||||||
MwLLWaylandFramebufferDestroy(&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);
|
free(r->wayland.sublevel);
|
||||||
|
|
||||||
r->wayland.configured = MwFALSE;
|
r->wayland.configured = MwFALSE;
|
||||||
|
|
@ -482,7 +505,14 @@ static void destroy_subsurface(MwLL r) {
|
||||||
MwLLWaylandBackbufferDestroy(&r->wayland);
|
MwLLWaylandBackbufferDestroy(&r->wayland);
|
||||||
MwLLWaylandFramebufferDestroy(&r->wayland);
|
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||||
|
|
||||||
free(r->wayland.sublevel);
|
/* 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);
|
||||||
|
|
||||||
r->wayland.configured = MwFALSE;
|
r->wayland.configured = MwFALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -586,15 +616,20 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
||||||
r->wayland.popup->xdg_positioner = xdg_wm_base_create_positioner(r->wayland.popup->xdg_wm_base);
|
r->wayland.popup->xdg_positioner = xdg_wm_base_create_positioner(r->wayland.popup->xdg_wm_base);
|
||||||
|
|
||||||
xdg_positioner_set_size(r->wayland.popup->xdg_positioner, r->wayland.ww, r->wayland.wh);
|
xdg_positioner_set_size(r->wayland.popup->xdg_positioner, r->wayland.ww, r->wayland.wh);
|
||||||
|
/* the anchor rect is relative to the parent surface, so a layer surface's position on screen doesn't apply */
|
||||||
xdg_positioner_set_anchor_rect(
|
xdg_positioner_set_anchor_rect(
|
||||||
r->wayland.popup->xdg_positioner,
|
r->wayland.popup->xdg_positioner,
|
||||||
topmost_parent->wayland.x, topmost_parent->wayland.y, r->wayland.ww, r->wayland.wh);
|
topmost_parent->wayland.type == MwLL_WAYLAND_LAYER_SURFACE ? 0 : topmost_parent->wayland.x,
|
||||||
|
topmost_parent->wayland.type == MwLL_WAYLAND_LAYER_SURFACE ? 0 : topmost_parent->wayland.y,
|
||||||
|
r->wayland.ww, r->wayland.wh);
|
||||||
xdg_positioner_set_offset(
|
xdg_positioner_set_offset(
|
||||||
r->wayland.popup->xdg_positioner,
|
r->wayland.popup->xdg_positioner,
|
||||||
r->wayland.x, r->wayland.y);
|
r->wayland.x, r->wayland.y);
|
||||||
|
|
||||||
xdg_positioner_set_anchor(r->wayland.popup->xdg_positioner, XDG_POSITIONER_ANCHOR_NONE);
|
xdg_positioner_set_anchor(r->wayland.popup->xdg_positioner, XDG_POSITIONER_ANCHOR_NONE);
|
||||||
xdg_positioner_set_gravity(r->wayland.popup->xdg_positioner, XDG_POSITIONER_GRAVITY_NONE);
|
xdg_positioner_set_gravity(r->wayland.popup->xdg_positioner, XDG_POSITIONER_GRAVITY_NONE);
|
||||||
|
/* we can't see where we are on screen, so let the compositor keep the popup on it */
|
||||||
|
xdg_positioner_set_constraint_adjustment(r->wayland.popup->xdg_positioner, XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
|
||||||
|
|
||||||
r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap;
|
r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap;
|
||||||
r->wayland.xkb_state = topmost_parent->wayland.xkb_state;
|
r->wayland.xkb_state = topmost_parent->wayland.xkb_state;
|
||||||
|
|
@ -642,8 +677,7 @@ static void destroy_popup(MwLL r) {
|
||||||
xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
|
xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
|
||||||
|
|
||||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||||
|
r->wayland.framebuffer.surface = NULL;
|
||||||
wl_registry_destroy(r->wayland.registry);
|
|
||||||
|
|
||||||
free(r->wayland.popup);
|
free(r->wayland.popup);
|
||||||
|
|
||||||
|
|
@ -725,7 +759,7 @@ static void setup_layer_surface(MwLL r, int x, int y, int width, int height) {
|
||||||
|
|
||||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||||
|
|
||||||
r->wayland.layer_surface->surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, r->wayland.framebuffer.surface, NULL, ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "milsko-surfaces");
|
r->wayland.layer_surface->surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, r->wayland.framebuffer.surface, NULL, r->wayland.layer_surface_type, "milsko-surfaces");
|
||||||
|
|
||||||
zwlr_layer_surface_v1_set_size(r->wayland.layer_surface->surface, width, height);
|
zwlr_layer_surface_v1_set_size(r->wayland.layer_surface->surface, width, height);
|
||||||
zwlr_layer_surface_v1_set_margin(r->wayland.layer_surface->surface,
|
zwlr_layer_surface_v1_set_margin(r->wayland.layer_surface->surface,
|
||||||
|
|
@ -747,24 +781,27 @@ static void setup_layer_surface(MwLL r, int x, int y, int width, int height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Toplevel destroy function */
|
/* Layer surface destroy function */
|
||||||
static void destroy_layer_surface(MwLL r) {
|
static void destroy_layer_surface(MwLL r) {
|
||||||
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
|
MwLLWaylandFramebufferDestroy(&r->wayland);
|
||||||
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context;
|
|
||||||
zxdg_decoration_manager_v1_destroy(dec->manager);
|
/* 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);
|
||||||
|
|
||||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||||
|
r->wayland.framebuffer.surface = NULL;
|
||||||
wl_compositor_destroy(r->wayland.compositor);
|
|
||||||
|
|
||||||
xkb_keymap_unref(r->wayland.xkb_keymap);
|
|
||||||
|
|
||||||
xkb_state_unref(r->wayland.xkb_state);
|
xkb_state_unref(r->wayland.xkb_state);
|
||||||
|
|
||||||
|
xkb_keymap_unref(r->wayland.xkb_keymap);
|
||||||
|
|
||||||
xkb_context_unref(r->wayland.xkb_context);
|
xkb_context_unref(r->wayland.xkb_context);
|
||||||
|
|
||||||
wl_registry_destroy(r->wayland.registry);
|
r->wayland.xkb_state = NULL;
|
||||||
|
r->wayland.xkb_keymap = NULL;
|
||||||
|
r->wayland.xkb_context = NULL;
|
||||||
|
|
||||||
r->wayland.configured = MwFALSE;
|
r->wayland.configured = MwFALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -793,6 +830,9 @@ static void destroy_widget(MwLL handle) {
|
||||||
case MwLL_WAYLAND_LAYER_SURFACE:
|
case MwLL_WAYLAND_LAYER_SURFACE:
|
||||||
destroy_layer_surface(handle);
|
destroy_layer_surface(handle);
|
||||||
break;
|
break;
|
||||||
|
case MwLL_WAYLAND_SUBSURFACE:
|
||||||
|
destroy_subsurface(handle);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle);
|
printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle);
|
||||||
break;
|
break;
|
||||||
|
|
@ -805,18 +845,22 @@ static void destroy_widget(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) {
|
for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) {
|
||||||
void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key);
|
const char* key = handle->wayland.wl_protocol_setup_map[i].key;
|
||||||
|
|
||||||
if(ctx != NULL) {
|
/* Many setup functions keep what they bind in the MwLL and store a NULL context, so check
|
||||||
handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx);
|
* 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));
|
||||||
}
|
}
|
||||||
shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value);
|
|
||||||
free(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_map);
|
||||||
shfree(handle->wayland.wl_protocol_setup_map);
|
shfree(handle->wayland.wl_protocol_setup_map);
|
||||||
|
|
||||||
|
wl_registry_destroy(handle->wayland.registry);
|
||||||
|
handle->wayland.registry = NULL;
|
||||||
|
|
||||||
MwLLWaylandFlush(handle);
|
MwLLWaylandFlush(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -880,6 +924,9 @@ static void clip(MwLL handle) {
|
||||||
cairo_clip(handle->wayland.cairo.front_cairo_back);
|
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) {
|
static void wl_logger(const char* fmt, va_list args) {
|
||||||
|
|
@ -909,7 +956,6 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
|
||||||
r->wayland.x = x;
|
r->wayland.x = x;
|
||||||
r->wayland.y = y;
|
r->wayland.y = y;
|
||||||
r->wayland.parent = parent;
|
r->wayland.parent = parent;
|
||||||
r->wayland.valid = MwTRUE;
|
|
||||||
|
|
||||||
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
if(ty == MwLL_WAYLAND_UNKNOWN) {
|
||||||
if(parent == NULL) {
|
if(parent == NULL) {
|
||||||
|
|
@ -949,6 +995,9 @@ 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.region = wl_compositor_create_region(r->wayland.compositor);
|
||||||
r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor);
|
r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor);
|
||||||
MwLLWaylandRegionSetup(r);
|
MwLLWaylandRegionSetup(r);
|
||||||
|
|
@ -1090,6 +1139,9 @@ static void MwLLDestroyImpl(MwLL handle) {
|
||||||
MwLLWaylandFlush(handle);
|
MwLLWaylandFlush(handle);
|
||||||
|
|
||||||
MwLLDestroyCommon(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_sec = 0;
|
||||||
tv.tv_usec = 1000;
|
tv.tv_usec = 1000;
|
||||||
|
|
@ -1103,25 +1155,36 @@ static void MwLLDestroyImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(handle->wayland.valid) {
|
if(handle->wayland.cursor.setup) {
|
||||||
MwLLWaylandBufferDestroy(&handle->wayland.cursor);
|
MwLLWaylandBufferDestroy(&handle->wayland.cursor);
|
||||||
wl_region_destroy(handle->wayland.region);
|
wl_surface_destroy(handle->wayland.cursor.surface);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
wl_region_destroy(handle->wayland.region);
|
||||||
|
wl_region_destroy(handle->wayland.o_region);
|
||||||
|
|
||||||
|
/* clipboard sources are released with their managers in destroy_widget */
|
||||||
if(handle->wayland.icon != NULL) {
|
if(handle->wayland.icon != NULL) {
|
||||||
|
if(handle->wayland.icon->setup) {
|
||||||
MwLLWaylandBufferDestroy(handle->wayland.icon);
|
MwLLWaylandBufferDestroy(handle->wayland.icon);
|
||||||
wl_surface_destroy(handle->wayland.icon->surface);
|
wl_surface_destroy(handle->wayland.icon->surface);
|
||||||
}
|
}
|
||||||
|
free(handle->wayland.icon);
|
||||||
|
}
|
||||||
|
|
||||||
destroy_widget(handle);
|
destroy_widget(handle);
|
||||||
} else {
|
|
||||||
printf("widget invalid\n");
|
/* 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++) {
|
for(i = 0; i < arrlen(topmost_parent->wayland.currentlyHeldWidgets); i++) {
|
||||||
if(topmost_parent->wayland.currentlyHeldWidgets[i] == handle) {
|
if(topmost_parent->wayland.currentlyHeldWidgets[i] == handle) {
|
||||||
arrdel(topmost_parent->wayland.currentlyHeldWidgets, i);
|
arrdel(topmost_parent->wayland.currentlyHeldWidgets, i);
|
||||||
|
|
@ -1134,13 +1197,6 @@ static void MwLLDestroyImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
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;
|
*x = handle->wayland.x;
|
||||||
*y = handle->wayland.y;
|
*y = handle->wayland.y;
|
||||||
*w = handle->wayland.ww;
|
*w = handle->wayland.ww;
|
||||||
|
|
@ -1605,8 +1661,9 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
||||||
if(handle->wayland.icon == NULL) {
|
if(handle->wayland.icon == NULL) {
|
||||||
handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer));
|
handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer));
|
||||||
memset(handle->wayland.icon, 0, 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) {
|
if(handle->wayland.icon->setup) {
|
||||||
MwLLWaylandBufferDestroy(handle->wayland.icon);
|
MwLLWaylandBufferDestroy(handle->wayland.icon);
|
||||||
|
|
@ -1619,11 +1676,17 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
||||||
wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0);
|
wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0);
|
||||||
wl_surface_commit(handle->wayland.icon->surface);
|
wl_surface_commit(handle->wayland.icon->surface);
|
||||||
|
|
||||||
for(; i < size; i += 2) {
|
/* RGBA -> BGRA, one pixel (4 bytes) at a time. The icon buffer is line x line, so rows
|
||||||
handle->wayland.icon->buf_back[i] = pixmap->common.raw[i + 2];
|
* have to be placed with its stride rather than the pixmap's. */
|
||||||
handle->wayland.icon->buf_back[i + 1] = pixmap->common.raw[i + 1];
|
for(; i < size; i += 4) {
|
||||||
handle->wayland.icon->buf_back[i + 2] = pixmap->common.raw[i + 0];
|
int x = (i / 4) % pixmap->common.width;
|
||||||
handle->wayland.icon->buf_back[i + 3] = 255;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, handle->wayland.icon);
|
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, handle->wayland.icon);
|
||||||
|
|
@ -1631,6 +1694,9 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
||||||
xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1);
|
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);
|
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) {
|
if(!handle->wayland.has_decorations && handle->wayland.do_csd) {
|
||||||
|
|
@ -1711,7 +1777,13 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
|
|
||||||
while(p != NULL) {
|
while(p != NULL) {
|
||||||
if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
/* a layer surface's x/y is its position on screen, which like a toplevel's isn't part of the offset */
|
||||||
|
if(p->wayland.type == MwLL_WAYLAND_POPUP) {
|
||||||
|
/* a popup's x/y is already relative to the topmost surface, so anything above it is counted already */
|
||||||
|
x += p->wayland.x;
|
||||||
|
y += p->wayland.y;
|
||||||
|
break;
|
||||||
|
} else if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL && p->wayland.type != MwLL_WAYLAND_LAYER_SURFACE) {
|
||||||
x += p->wayland.x;
|
x += p->wayland.x;
|
||||||
y += p->wayland.y;
|
y += p->wayland.y;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1794,11 +1866,15 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
|
||||||
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
|
||||||
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
|
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
|
||||||
if(toggle) {
|
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);
|
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);
|
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);
|
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, topmost_parent->wayland.pointer);
|
if(!topmost_parent->wayland.relative_pointer) {
|
||||||
zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &MwLLWaylandRelativePointerListener, topmost_parent);
|
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);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(topmost_parent->wayland.locked_pointer) {
|
if(topmost_parent->wayland.locked_pointer) {
|
||||||
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
|
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
|
||||||
|
|
@ -1821,7 +1897,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
|
||||||
if(handle->wayland.clipboard_buffer != NULL) {
|
if(handle->wayland.clipboard_buffer != NULL) {
|
||||||
free(handle->wayland.clipboard_buffer);
|
free(handle->wayland.clipboard_buffer);
|
||||||
}
|
}
|
||||||
handle->wayland.clipboard_buffer = malloc(strlen(text));
|
handle->wayland.clipboard_buffer = malloc(strlen(text) + 1);
|
||||||
strcpy(handle->wayland.clipboard_buffer, text);
|
strcpy(handle->wayland.clipboard_buffer, text);
|
||||||
|
|
||||||
if(clipboard_type == MwCLIPBOARD_PRIMARY) {
|
if(clipboard_type == MwCLIPBOARD_PRIMARY) {
|
||||||
|
|
@ -1873,9 +1949,15 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
|
||||||
handle->wayland.type_to_be = MwLL_WAYLAND_POPUP;
|
handle->wayland.type_to_be = MwLL_WAYLAND_POPUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle->wayland.layer_surface_type = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
|
||||||
|
|
||||||
handle->wayland.changing = MwTRUE;
|
handle->wayland.changing = MwTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWDECL void MWAPI MwLLWaylandSetToolWindowType(MwLL handle, enum zwlr_layer_shell_v1_layer type) {
|
||||||
|
handle->wayland.layer_surface_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
||||||
MwLL topmost_parent = handle;
|
MwLL topmost_parent = handle;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,8 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
|
||||||
h->lowlevel = NULL;
|
h->lowlevel = NULL;
|
||||||
}
|
}
|
||||||
h->widget_class = widget_class;
|
h->widget_class = widget_class;
|
||||||
|
h->mouse_point.x = 0;
|
||||||
|
h->mouse_point.y = 0;
|
||||||
h->pressed = 0;
|
h->pressed = 0;
|
||||||
h->close = 0;
|
h->close = 0;
|
||||||
h->destroy_queue = NULL;
|
h->destroy_queue = NULL;
|
||||||
|
|
@ -751,7 +753,7 @@ void MwSetString(MwWidget handle, const char* key, const char* value) {
|
||||||
|
|
||||||
void MwSetPointer(MwWidget handle, const char* key, void* value) {
|
void MwSetPointer(MwWidget handle, const char* key, void* value) {
|
||||||
if(IsFirstVisible(handle) && strcmp(key, MwNiconPixmap) == 0) {
|
if(IsFirstVisible(handle) && strcmp(key, MwNiconPixmap) == 0) {
|
||||||
MwLLSetIcon(handle->lowlevel, value);
|
MwLLSetIcon(handle->lowlevel, ((MwPixmap)value)->lowlevel);
|
||||||
} else if(strcmp(key, MwNsizeHints) == 0) {
|
} else if(strcmp(key, MwNsizeHints) == 0) {
|
||||||
MwSizeHints* sz = value;
|
MwSizeHints* sz = value;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3017,6 +3017,7 @@ unsigned char MwBoldMonospaceTTFData[] = {
|
||||||
0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x16, 0xe7, 0x6b,
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x16, 0xe7, 0x6b,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xe1, 0xa9, 0xde, 0x3f, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0xe1, 0xa9, 0xde, 0x3f, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xe5, 0x4d, 0x1e, 0x99};
|
0xe5, 0x4d, 0x1e, 0x99
|
||||||
|
};
|
||||||
unsigned int MwBoldMonospaceTTFDataSize = 36184;
|
unsigned int MwBoldMonospaceTTFDataSize = 36184;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
15207
src/text/font/boldttf.c
15207
src/text/font/boldttf.c
File diff suppressed because it is too large
Load diff
|
|
@ -3017,6 +3017,7 @@ unsigned char MwMonospaceTTFData[] = {
|
||||||
0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x16, 0xe7, 0x6b,
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x16, 0xe7, 0x6b,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xe1, 0xa9, 0xde, 0x41, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0xe1, 0xa9, 0xde, 0x41, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xe5, 0x4d, 0x1e, 0x76};
|
0xe5, 0x4d, 0x1e, 0x76
|
||||||
|
};
|
||||||
unsigned int MwMonospaceTTFDataSize = 36184;
|
unsigned int MwMonospaceTTFDataSize = 36184;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
15202
src/text/font/ttf.c
15202
src/text/font/ttf.c
File diff suppressed because it is too large
Load diff
|
|
@ -248,6 +248,7 @@ static MwMenu mwMenuAddImpl(MwWidget handle, MwMenu menu, const char* name) {
|
||||||
new->wsub = NULL;
|
new->wsub = NULL;
|
||||||
new->keep = 0;
|
new->keep = 0;
|
||||||
new->cleaned = 0;
|
new->cleaned = 0;
|
||||||
|
new->bold = 0;
|
||||||
|
|
||||||
arrput(m->sub, new);
|
arrput(m->sub, new);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ static int calc_length(MwWidget handle) {
|
||||||
int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue);
|
int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue);
|
||||||
int area = MwGetInteger(handle, MwNareaShown);
|
int area = MwGetInteger(handle, MwNareaShown);
|
||||||
if(area > len) area = len;
|
if(area > len) area = len;
|
||||||
|
if(len == 0) return max;
|
||||||
|
|
||||||
return (int)(max * (double)area / len);
|
return (int)(max * (double)area / len);
|
||||||
}
|
}
|
||||||
|
|
@ -35,6 +36,7 @@ static int calc_position(MwWidget handle) {
|
||||||
int max = MwScrollBarGetVisibleLength(handle);
|
int max = MwScrollBarGetVisibleLength(handle);
|
||||||
int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue);
|
int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue);
|
||||||
int val = MwGetInteger(handle, MwNvalue);
|
int val = MwGetInteger(handle, MwNvalue);
|
||||||
|
if(len == 0) return 0;
|
||||||
|
|
||||||
return (int)((max - calc_length(handle)) * (double)val / len);
|
return (int)((max - calc_length(handle)) * (double)val / len);
|
||||||
}
|
}
|
||||||
|
|
@ -49,9 +51,11 @@ static void add_value(MwWidget handle, int mul) {
|
||||||
if(val < min) val = min;
|
if(val < min) val = min;
|
||||||
if(val > max) val = max;
|
if(val > max) val = max;
|
||||||
|
|
||||||
|
if(MwGetInteger(handle, MwNvalue) != val) {
|
||||||
MwSetInteger(handle, MwNvalue, val);
|
MwSetInteger(handle, MwNvalue, val);
|
||||||
MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
|
MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void draw(MwWidget handle) {
|
static void draw(MwWidget handle) {
|
||||||
MwRect r = {0}, rt = {0}, rbar = {0};
|
MwRect r = {0}, rt = {0}, rbar = {0};
|
||||||
|
|
@ -85,7 +89,7 @@ static void draw(MwWidget handle) {
|
||||||
rt.y = r.y;
|
rt.y = r.y;
|
||||||
if(MwGetInteger(handle, MwNshowArrows)) {
|
if(MwGetInteger(handle, MwNshowArrows)) {
|
||||||
MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.y <= uy) ? 1 : 0, MwNORTH);
|
MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.y <= uy) ? 1 : 0, MwNORTH);
|
||||||
if(handle->pressed && scr->point.y <= uy) {
|
if(handle->pressed && scr->point.y < uy) {
|
||||||
add_value(handle, -1);
|
add_value(handle, -1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -110,7 +114,7 @@ static void draw(MwWidget handle) {
|
||||||
rt.x = r.x;
|
rt.x = r.x;
|
||||||
if(MwGetInteger(handle, MwNshowArrows)) {
|
if(MwGetInteger(handle, MwNshowArrows)) {
|
||||||
MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.x <= ux) ? 1 : 0, MwWEST);
|
MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.x <= ux) ? 1 : 0, MwWEST);
|
||||||
if(handle->pressed && scr->point.x <= ux) {
|
if(handle->pressed && scr->point.x < ux) {
|
||||||
add_value(handle, -1);
|
add_value(handle, -1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -223,6 +227,7 @@ static void mouse_down(MwWidget handle, void* ptr) {
|
||||||
static void prop_change(MwWidget handle, const char* key) {
|
static void prop_change(MwWidget handle, const char* key) {
|
||||||
if(strcmp(key, MwNminValue) == 0 || strcmp(key, MwNvalue) == 0 || strcmp(key, MwNmaxValue) == 0) {
|
if(strcmp(key, MwNminValue) == 0 || strcmp(key, MwNvalue) == 0 || strcmp(key, MwNmaxValue) == 0) {
|
||||||
if(MwGetInteger(handle, MwNvalue) > MwGetInteger(handle, MwNmaxValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNmaxValue));
|
if(MwGetInteger(handle, MwNvalue) > MwGetInteger(handle, MwNmaxValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNmaxValue));
|
||||||
|
if(MwGetInteger(handle, MwNvalue) < MwGetInteger(handle, MwNminValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNminValue));
|
||||||
MwForceRender(handle);
|
MwForceRender(handle);
|
||||||
}
|
}
|
||||||
if(strcmp(key, MwNshowArrows) == 0 || strcmp(key, MwNareaShown) == 0) {
|
if(strcmp(key, MwNshowArrows) == 0 || strcmp(key, MwNareaShown) == 0) {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,8 @@ static void draw(MwWidget handle) {
|
||||||
|
|
||||||
p.y += 2 + 1;
|
p.y += 2 + 1;
|
||||||
} else {
|
} else {
|
||||||
int tw = MwTextWidth(handle, NULL, menu->sub[i]->name);
|
MwFLFont font = MwFLBuildFont(menu->sub[i]->wsub != NULL ? MwFLFlagBold : 0);
|
||||||
|
int tw = MwTextWidth(handle, font, menu->sub[i]->name);
|
||||||
int th = MwTextHeight(handle, NULL, menu->sub[i]->name);
|
int th = MwTextHeight(handle, NULL, menu->sub[i]->name);
|
||||||
|
|
||||||
if(menu->sub[i]->wsub != NULL) {
|
if(menu->sub[i]->wsub != NULL) {
|
||||||
|
|
@ -71,7 +72,7 @@ static void draw(MwWidget handle) {
|
||||||
p.x = 5 + tw / 2 + MwGetInteger(handle, MwNleftPadding);
|
p.x = 5 + tw / 2 + MwGetInteger(handle, MwNleftPadding);
|
||||||
|
|
||||||
p.y += th / 2;
|
p.y += th / 2;
|
||||||
MwDrawText(handle, MwFLBuildFont(menu->sub[i]->wsub != NULL ? MwFLFlagBold : 0), &p, menu->sub[i]->name, MwALIGNMENT_CENTER, text);
|
MwDrawText(handle, font, &p, menu->sub[i]->name, MwALIGNMENT_CENTER, text);
|
||||||
|
|
||||||
if(arrlen(menu->sub[i]->sub) > 0) {
|
if(arrlen(menu->sub[i]->sub) > 0) {
|
||||||
MwRect tr;
|
MwRect tr;
|
||||||
|
|
@ -182,6 +183,11 @@ static void mwSubMenuAppearImpl(MwWidget handle, MwMenu menu, MwPoint* point, in
|
||||||
MwLLMakeToolWindow(handle->lowlevel);
|
MwLLMakeToolWindow(handle->lowlevel);
|
||||||
MwLLDetach(handle->lowlevel, &p);
|
MwLLDetach(handle->lowlevel, &p);
|
||||||
|
|
||||||
|
MwVaApply(handle,
|
||||||
|
MwNwidth, sz.width,
|
||||||
|
MwNheight, sz.height,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if(handle->lowlevel->common.coordinate_type == MwCOORDINATE_GLOBAL) {
|
if(handle->lowlevel->common.coordinate_type == MwCOORDINATE_GLOBAL) {
|
||||||
if(MwGetInteger(handle, MwNy) + sz.height > rc.height) {
|
if(MwGetInteger(handle, MwNy) + sz.height > rc.height) {
|
||||||
MwVaApply(handle,
|
MwVaApply(handle,
|
||||||
|
|
@ -208,7 +214,7 @@ static void mwSubMenuGetSizeImpl(MwWidget handle, MwMenu menu, MwRect* rect) {
|
||||||
if(strcmp(menu->sub[i]->name, "----") == 0) {
|
if(strcmp(menu->sub[i]->name, "----") == 0) {
|
||||||
rect->height += 2 + 2;
|
rect->height += 2 + 2;
|
||||||
} else {
|
} else {
|
||||||
int tw = MwTextWidth(handle, NULL, menu->sub[i]->name);
|
int tw = MwTextWidth(handle, MwFLBuildFont(arrlen(menu->sub[i]->sub) > 0 ? MwFLFlagBold : 0), menu->sub[i]->name);
|
||||||
rect->height += MwTextHeight(handle, NULL, menu->sub[i]->name) + 3;
|
rect->height += MwTextHeight(handle, NULL, menu->sub[i]->name) + 3;
|
||||||
if(tw > rect->width) {
|
if(tw > rect->width) {
|
||||||
rect->width = tw;
|
rect->width = tw;
|
||||||
|
|
|
||||||
12
tools/ttf.sh
12
tools/ttf.sh
|
|
@ -1,11 +1,13 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
for out in src/font/ttf.c src/font/boldttf.c; do
|
for out in src/text/font/ttf.c src/text/font/boldttf.c src/text/font/monottf.c src/text/font/boldmonottf.c; do
|
||||||
echo '#include <Mw/Milsko.h>' > $out
|
echo '#include <Mw/Milsko.h>' > $out
|
||||||
echo '' >> $out
|
echo '' >> $out
|
||||||
echo '#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2)' >> $out
|
echo '#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)' >> $out
|
||||||
done
|
done
|
||||||
xxd -n MwTTFData -i resource/font/IBMPlexMono.ttf | sed s/_len/Size/ >> src/font/ttf.c
|
xxd -n MwMonospaceTTFData -i resource/font/IBMPlexMono-Regular.ttf | sed s/_len/Size/ >> src/text/font/monottf.c
|
||||||
xxd -n MwBoldTTFData -i resource/font/IBMPlexMono-Bold.ttf | sed s/_len/Size/ >> src/font/boldttf.c
|
xxd -n MwBoldMonospaceTTFData -i resource/font/IBMPlexMono-Bold.ttf | sed s/_len/Size/ >> src/text/font/boldmonottf.c
|
||||||
for out in src/font/ttf.c src/font/boldttf.c; do
|
xxd -n MwTTFData -i resource/font/OpenSans-Regular.ttf | sed s/_len/Size/ >> src/text/font/ttf.c
|
||||||
|
xxd -n MwBoldTTFData -i resource/font/OpenSans-Bold.ttf | sed s/_len/Size/ >> src/text/font/boldttf.c
|
||||||
|
for out in src/text/font/ttf.c src/text/font/boldttf.c src/text/font/monottf.c src/text/font/boldmonottf.c; do
|
||||||
echo '#endif' >> $out
|
echo '#endif' >> $out
|
||||||
done
|
done
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue