better alpha blending
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit

This commit is contained in:
Nishi 2026-09-26 18:32:30 +09:00
commit 0320cd64eb
21 changed files with 170 additions and 87 deletions

View file

@ -184,6 +184,12 @@ MWDECL unsigned char* MWAPI MwPixmapGetRaw(MwLLPixmap pixmap);
*/ */
MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect); MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect);
/*!
* @brief Destroys the pixmap
* @param pixmap Pixmap
*/
MWDECL void MWAPI MwDestroyPixmap(MwLLPixmap pixmap);
/*! /*!
* @brief Creates a pixmap from XPM data * @brief Creates a pixmap from XPM data
* @param handle Widget * @param handle Widget

View file

@ -34,7 +34,7 @@ enum MwLLBackends {
}; };
struct _MwLLCommon { struct _MwLLCommon {
void* user; void* internal;
int copy_buffer; int copy_buffer;
int type; int type;
int coordinate_type; int coordinate_type;
@ -58,7 +58,8 @@ struct _MwLLCommonPixmap {
int width; int width;
int height; int height;
unsigned char* raw; unsigned char* raw;
void* user; unsigned char* before_blend;
void* internal;
}; };
#ifdef USE_DBUS #ifdef USE_DBUS

View file

@ -99,11 +99,14 @@ struct _MwWidget {
int prop_event; int prop_event;
int held; int held;
void* internal; void* internal;
void* opaque; void* opaque;
void* user; void* user;
void (*draw_inject)(MwWidget handle); MwHandler draw_inject;
void (*destroy_inject)(MwWidget handle); MwHandler destroy_inject;
MwHandlerProp prop_inject_pixmap; /* this is for pixmap; do not use */
MwLLPixmap* pixmaps;
MwIntegerKeyValue* integer; MwIntegerKeyValue* integer;
MwTextKeyValue* text; MwTextKeyValue* text;

View file

@ -46,10 +46,12 @@ MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data,
if(width >= INT16_MAX) width = INT16_MAX; if(width >= INT16_MAX) width = INT16_MAX;
if(height >= INT16_MAX) height = INT16_MAX; if(height >= INT16_MAX) height = INT16_MAX;
r->common.width = width; r->common.width = width;
r->common.height = height; r->common.height = height;
r->common.raw = malloc(4 * width * height); r->common.raw = malloc(4 * width * height);
r->common.before_blend = malloc(4 * width * height);
memcpy(r->common.raw, data, 4 * width * height); memcpy(r->common.raw, data, 4 * width * height);
memcpy(r->common.before_blend, data, 4 * width * height);
r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
@ -80,6 +82,7 @@ void MwLLCairoPixmapUpdate(MwLLPixmap r) {
void MwLLCairoDestroyPixmap(MwLLPixmap pixmap) { void MwLLCairoDestroyPixmap(MwLLPixmap pixmap) {
cairo_surface_destroy(pixmap->wayland.cs); cairo_surface_destroy(pixmap->wayland.cs);
free(pixmap->common.before_blend);
free(pixmap->common.raw); free(pixmap->common.raw);
free(pixmap); free(pixmap);
} }

View file

@ -64,7 +64,7 @@ static inline NSPoint localPointFlip(NSPoint point, NSView* view) {
/* Recursively dispatch a key event to a widget and its children */ /* Recursively dispatch a key event to a widget and its children */
static void recursive_dispatch_key(MwLL handle, int* k) { static void recursive_dispatch_key(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
MwLLDispatch(handle, key, k); MwLLDispatch(handle, key, k);
if(h) { if(h) {
int i; int i;
@ -78,7 +78,7 @@ static void recursive_dispatch_key(MwLL handle, int* k) {
}; };
/* Recursively dispatch a key released event to a widget and its children */ /* Recursively dispatch a key released event to a widget and its children */
static void recursive_dispatch_key_released(MwLL handle, int* k) { static void recursive_dispatch_key_released(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
MwLLDispatch(handle, key_released, k); MwLLDispatch(handle, key_released, k);
if(h) { if(h) {
int i; int i;
@ -637,7 +637,7 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) {
[topmost_parent->cocoa.real->view setNeedsDisplay:true]; [topmost_parent->cocoa.real->view setNeedsDisplay:true];
MwLLDispatch(topmost_parent, draw, NULL); MwLLDispatch(topmost_parent, draw, NULL);
h = (MwWidget)topmost_parent->common.user; h = (MwWidget)topmost_parent->common.intenral;
if(h) { if(h) {
int i; int i;
for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {

View file

@ -665,6 +665,14 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
memcpy(r->common.raw, data, 4 * width * height); memcpy(r->common.raw, data, 4 * width * height);
r->common.before_blend = malloc(width * height * 4);
if(!r->common.before_blend) {
printf("Out Of Memory\n");
return NULL;
}
memcpy(r->common.before_blend, data, 4 * width * height);
r->common.width = width; r->common.width = width;
r->common.height = height; r->common.height = height;
@ -740,6 +748,7 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
} }
static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
free(pixmap->common.before_blend);
free(pixmap->common.raw); free(pixmap->common.raw);
DeleteObject(pixmap->gdi.hMask); DeleteObject(pixmap->gdi.hMask);
DeleteObject(pixmap->gdi.hMask2); DeleteObject(pixmap->gdi.hMask2);

View file

@ -23,7 +23,7 @@ static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwP
/* Recursively dispatch a key event to a widget and its children */ /* Recursively dispatch a key event to a widget and its children */
static void recursive_dispatch_key(MwLL handle, int* k) { static void recursive_dispatch_key(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
MwLLDispatch(handle, key, k); MwLLDispatch(handle, key, k);
if(h) { if(h) {
int i; int i;
@ -37,7 +37,7 @@ static void recursive_dispatch_key(MwLL handle, int* k) {
}; };
/* Recursively dispatch a key released event to a widget and its children */ /* Recursively dispatch a key released event to a widget and its children */
static void recursive_dispatch_key_released(MwLL handle, int* k) { static void recursive_dispatch_key_released(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
MwLLDispatch(handle, key_released, k); MwLLDispatch(handle, key_released, k);
if(h) { if(h) {
int i; int i;
@ -52,7 +52,7 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) {
/* Recursively dispatch a move event to a widget and its children */ /* Recursively dispatch a move event to a widget and its children */
static void recursive_dispatch_move(MwLL handle, MwMouse* p) { static void recursive_dispatch_move(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
if(h) { if(h) {
int i; int i;
for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {
@ -165,8 +165,8 @@ static void wl_data_device_leave(void* data,
static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx) { static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx) {
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) { if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) {
return MwTRUE; return MwTRUE;
} else if(self->common.user) { } else if(self->common.intenral) {
MwWidget w = self->common.user; MwWidget w = self->common.intenral;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -190,8 +190,8 @@ static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx
static void clipboard_dispatch(MwLL self, char* buf) { static void clipboard_dispatch(MwLL self, char* buf) {
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) { if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) {
MwLLDispatch(self, drag_and_drop, buf); MwLLDispatch(self, drag_and_drop, buf);
} else if(self->common.user) { } else if(self->common.intenral) {
MwWidget w = self->common.user; MwWidget w = self->common.intenral;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -722,7 +722,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
}; };
static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) { static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
MwLLDispatch(handle, down, p); MwLLDispatch(handle, down, p);
if(h) { if(h) {
int i; int i;
@ -735,7 +735,7 @@ static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) {
} }
}; };
static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) { static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
MwLLDispatch(handle, up, p); MwLLDispatch(handle, up, p);
if(h) { if(h) {
int i; int i;
@ -793,8 +793,8 @@ static void mouse_dispatch(MwLL self, MwMouse p, MwU32 state) {
break; break;
} }
if(self->common.user) { if(self->common.intenral) {
MwWidget w = self->common.user; MwWidget w = self->common.intenral;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -963,8 +963,8 @@ static void keyboard_leave(void* data,
}; };
void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down) { void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down) {
if(self->common.user) { if(self->common.intenral) {
MwWidget w = self->common.user; MwWidget w = self->common.intenral;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {

View file

@ -14,8 +14,8 @@ MwBool MwWaylandVulkan = MwFALSE;
MwBool MwWaylandCairoOnly = MwFALSE; MwBool MwWaylandCairoOnly = MwFALSE;
void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) { void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) {
if(handle->common.user) { if(handle->common.intenral) {
MwWidget w = handle->common.user; MwWidget w = handle->common.intenral;
int i; int i;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -30,7 +30,7 @@ static int event_loop(MwLL handle);
/* Recursively dispatch a resize 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) { static void recursive_dispatch_resize(MwLL handle) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.intenral;
if(h) { if(h) {
int i; int i;
for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {
@ -45,7 +45,7 @@ static void recursive_dispatch_resize(MwLL handle) {
static void recursive_render(MwLL handle) { static void recursive_render(MwLL handle) {
int i; int i;
for(i = 0; i < arrlen(((MwWidget)handle->common.user)->children); i++) recursive_render(((MwWidget)handle->common.user)->children[i]->lowlevel); for(i = 0; i < arrlen(((MwWidget)handle->common.intenral)->children); i++) recursive_render(((MwWidget)handle->common.intenral)->children[i]->lowlevel);
MwLLForceRender(handle); MwLLForceRender(handle);
} }
@ -512,7 +512,7 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup));
if(parent) { if(parent) {
MwWidget p = parent->common.user; MwWidget p = parent->common.intenral;
while(topmost_parent->wayland.parent) { while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent; topmost_parent = topmost_parent->wayland.parent;
} }
@ -1944,11 +1944,11 @@ static void MwLLRaiseImpl(MwLL handle) {
MwLL topmost_parent = handle; MwLL topmost_parent = handle;
int children_num; int children_num;
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
children_num = arrlen(((MwWidget)topmost_parent->common.user)->children); children_num = arrlen(((MwWidget)topmost_parent->common.intenral)->children);
if(children_num > 1) { if(children_num > 1) {
printf("%d\n", children_num); printf("%d\n", children_num);
MwWidget last_child = ((MwWidget)topmost_parent->common.user)->children[children_num - 1]; MwWidget last_child = ((MwWidget)topmost_parent->common.intenral)->children[children_num - 1];
wl_subsurface_place_above(handle->wayland.sublevel->subsurface, last_child->lowlevel->wayland.framebuffer.surface); wl_subsurface_place_above(handle->wayland.sublevel->subsurface, last_child->lowlevel->wayland.framebuffer.surface);
} }
}*/ }*/

View file

@ -1097,6 +1097,9 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
r->common.raw = malloc(4 * width * height); r->common.raw = malloc(4 * width * height);
memcpy(r->common.raw, data, 4 * width * height); memcpy(r->common.raw, data, 4 * width * height);
r->common.before_blend = malloc(4 * width * height);
memcpy(r->common.before_blend, data, 4 * width * height);
XGetWindowAttributes(handle->x11.display, handle->x11.window, &attr); XGetWindowAttributes(handle->x11.display, handle->x11.window, &attr);
r->common.width = width; r->common.width = width;
@ -1152,6 +1155,7 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
} }
static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
free(pixmap->common.before_blend);
free(pixmap->common.raw); free(pixmap->common.raw);
XDestroyImage(pixmap->x11.image); XDestroyImage(pixmap->x11.image);
XDestroyImage(pixmap->x11.mask); XDestroyImage(pixmap->x11.mask);

View file

@ -30,11 +30,17 @@
} \ } \
} }
#define PROP(handle, key) \
{ \
MwDispatch3((handle), prop_change, (key)); \
if((handle)->prop_inject_pixmap != NULL) handle->prop_inject_pixmap((handle), (key)); \
}
static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early); static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early);
static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop); static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop);
static void lldrawhandler(MwLL handle, void* data) { static void lldrawhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
#ifdef PERIODIC #ifdef PERIODIC
MwWidget top; MwWidget top;
#endif #endif
@ -67,7 +73,7 @@ static void lldrawhandler(MwLL handle, void* data) {
} }
static void lluphandler(MwLL handle, void* data) { static void lluphandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwMouse* p = data; MwMouse* p = data;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -82,7 +88,7 @@ static void lluphandler(MwLL handle, void* data) {
} }
static void lldownhandler(MwLL handle, void* data) { static void lldownhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwMouse* p = data; MwMouse* p = data;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -96,7 +102,7 @@ static void lldownhandler(MwLL handle, void* data) {
} }
static void llresizehandler(MwLL handle, void* data) { static void llresizehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
#ifdef RESIZE_ON_TICK #ifdef RESIZE_ON_TICK
MwWidget top; MwWidget top;
#endif #endif
@ -129,7 +135,7 @@ static void llresizehandler(MwLL handle, void* data) {
} }
static void llclosehandler(MwLL handle, void* data) { static void llclosehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
(void)data; (void)data;
@ -147,7 +153,7 @@ static void llclosehandler(MwLL handle, void* data) {
} }
static void llmovehandler(MwLL handle, void* data) { static void llmovehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwPoint* p = data; MwPoint* p = data;
h->mouse_point.x = p->x; h->mouse_point.x = p->x;
@ -158,7 +164,7 @@ static void llmovehandler(MwLL handle, void* data) {
} }
static void llkeyhandler(MwLL handle, void* data) { static void llkeyhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int key = *(int*)data; int key = *(int*)data;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -168,7 +174,7 @@ static void llkeyhandler(MwLL handle, void* data) {
} }
static void llkeyrelhandler(MwLL handle, void* data) { static void llkeyrelhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -176,7 +182,7 @@ static void llkeyrelhandler(MwLL handle, void* data) {
} }
static void llfocusinhandler(MwLL handle, void* data) { static void llfocusinhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -184,7 +190,7 @@ static void llfocusinhandler(MwLL handle, void* data) {
} }
static void llfocusouthandler(MwLL handle, void* data) { static void llfocusouthandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -192,7 +198,7 @@ static void llfocusouthandler(MwLL handle, void* data) {
} }
static void llclipboardhandler(MwLL handle, void* data) { static void llclipboardhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -201,7 +207,7 @@ static void llclipboardhandler(MwLL handle, void* data) {
} }
static void lldraganddrophandler(MwLL handle, void* data) { static void lldraganddrophandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
@ -222,7 +228,7 @@ static void lldraganddrophandler(MwLL handle, void* data) {
#define IsFirstVisible(handle) ((handle)->widget_class != NULL && ((handle)->parent == NULL || (handle)->parent->widget_class == NULL)) #define IsFirstVisible(handle) ((handle)->widget_class != NULL && ((handle)->parent == NULL || (handle)->parent->widget_class == NULL))
static void lldarkthemehandler(MwLL handle, void* data) { static void lldarkthemehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int* ptr = data; int* ptr = data;
int s; int s;
@ -260,16 +266,18 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
} else { } else {
h->lowlevel = NULL; h->lowlevel = NULL;
} }
h->widget_class = widget_class; h->widget_class = widget_class;
h->pressed = 0; h->pressed = 0;
h->close = 0; h->close = 0;
h->destroy_queue = NULL; h->destroy_queue = NULL;
h->prop_event = 1; h->prop_event = 1;
h->draw_inject = NULL; h->draw_inject = NULL;
h->destroy_inject = NULL; h->destroy_inject = NULL;
h->tick_list = NULL; h->prop_inject_pixmap = NULL;
h->destroyed = 0; h->pixmaps = NULL;
h->bgcolor = NULL; h->tick_list = NULL;
h->destroyed = 0;
h->bgcolor = NULL;
h->berserk = 0; h->berserk = 0;
h->last_tick = MwTimeGetTick(); h->last_tick = MwTimeGetTick();
@ -288,7 +296,7 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
if(parent == NULL) h->top_step = 1; if(parent == NULL) h->top_step = 1;
if(h->lowlevel != NULL) { if(h->lowlevel != NULL) {
h->lowlevel->common.user = h; h->lowlevel->common.internal = h;
h->lowlevel->common.handler->draw = lldrawhandler; h->lowlevel->common.handler->draw = lldrawhandler;
h->lowlevel->common.handler->up = lluphandler; h->lowlevel->common.handler->up = lluphandler;
h->lowlevel->common.handler->down = lldownhandler; h->lowlevel->common.handler->down = lldownhandler;
@ -456,6 +464,9 @@ void MwFreeWidget(MwWidget handle) {
arrfree(handle->destroy_queue); arrfree(handle->destroy_queue);
arrfree(handle->tick_list); arrfree(handle->tick_list);
while(arrlen(handle->pixmaps) > 0) MwDestroyPixmap(handle->pixmaps[0]);
arrfree(handle->pixmaps);
arrfree(handle->draw_queue); arrfree(handle->draw_queue);
arrfree(handle->resize_queue); arrfree(handle->resize_queue);
@ -628,6 +639,20 @@ static void force_render_all(MwWidget handle) {
if(handle->lowlevel != NULL) MwForceRender(handle); if(handle->lowlevel != NULL) MwForceRender(handle);
} }
static void notify_all_bgfg_prop(MwWidget handle) {
int i;
for(i = 0; i < arrlen(handle->children); i++) {
notify_all_bgfg_prop(handle->children[i]);
}
PROP(handle, MwNbackground);
PROP(handle, MwNforeground);
PROP(handle, MwNsubBackground);
PROP(handle, MwNsubForeground);
MwForceRender(handle);
}
void MwSetInteger(MwWidget handle, const char* key, int n) { void MwSetInteger(MwWidget handle, const char* key, int n) {
int xy; int xy;
int wh = 0; int wh = 0;
@ -653,7 +678,7 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
arrfree(keys); arrfree(keys);
MwDispatch3(handle, prop_change, key); PROP(handle, key);
} }
if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL && handle->parent->prop_event) {
@ -663,7 +688,7 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
if(strcmp(key, MwNforceInverted) == 0) { if(strcmp(key, MwNforceInverted) == 0) {
MwForceRender(handle); MwForceRender(handle);
} }
if(strcmp(key, MwNmodernLook) == 0 || strcmp(key, MwNdarkTheme) == 0 || strcmp(key, MwNbitmapFont) == 0) { if(strcmp(key, MwNmodernLook) == 0 || strcmp(key, MwNbitmapFont) == 0) {
force_render_all(handle); force_render_all(handle);
} }
@ -677,6 +702,8 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
} }
if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n); if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n);
notify_all_bgfg_prop(handle);
} }
if(strcmp(key, MwNacceptsDnD) == 0 && n) { if(strcmp(key, MwNacceptsDnD) == 0 && n) {
@ -706,7 +733,7 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
arrfree(keys); arrfree(keys);
MwDispatch3(handle, prop_change, key); PROP(handle, key);
} }
if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL && handle->parent->prop_event) {
@ -738,7 +765,7 @@ void MwSetVoid(MwWidget handle, const char* key, void* value) {
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
arrfree(keys); arrfree(keys);
MwDispatch3(handle, prop_change, key); PROP(handle, key);
} }
if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL && handle->parent->prop_event) {
@ -918,8 +945,8 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early)
if(x != MwDEFAULT && y != MwDEFAULT) { if(x != MwDEFAULT && y != MwDEFAULT) {
MwLLSetXY(handle->lowlevel, x, y); MwLLSetXY(handle->lowlevel, x, y);
if(handle->prop_event) { if(handle->prop_event) {
MwDispatch3(handle, prop_change, MwNx); PROP(handle, MwNx);
MwDispatch3(handle, prop_change, MwNy); PROP(handle, MwNy);
} }
} else { } else {
if(x != MwDEFAULT) { if(x != MwDEFAULT) {
@ -931,8 +958,8 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early)
if(w != MwDEFAULT && h != MwDEFAULT) { if(w != MwDEFAULT && h != MwDEFAULT) {
MwLLSetWH(handle->lowlevel, w, h); MwLLSetWH(handle->lowlevel, w, h);
if(handle->prop_event) { if(handle->prop_event) {
MwDispatch3(handle, prop_change, MwNwidth); PROP(handle, MwNwidth);
MwDispatch3(handle, prop_change, MwNheight); PROP(handle, MwNheight);
} }
} else { } else {
if(w != MwDEFAULT) { if(w != MwDEFAULT) {
@ -947,7 +974,7 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early)
if(handle->prop_event) { if(handle->prop_event) {
for(i = 0; keys[i] != NULL; i++) { for(i = 0; keys[i] != NULL; i++) {
MwDispatch3(handle, prop_change, keys[i]); PROP(handle, keys[i]);
} }
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);

View file

@ -220,7 +220,7 @@ static void MWAPI color_picker_tick(MwWidget handle, void* user,
} }
static void color_picker_destroy(color_picker_t* picker) { static void color_picker_destroy(color_picker_t* picker) {
MwLLDestroyPixmap(picker->color_picker_pixmap); MwDestroyPixmap(picker->color_picker_pixmap);
free(picker); free(picker);
} }

View file

@ -43,12 +43,12 @@ static void destroy(MwWidget handle) {
for(i = 0; i < arrlen(fc->entries); i++) MwDirectoryFreeEntry(fc->entries[i]); for(i = 0; i < arrlen(fc->entries); i++) MwDirectoryFreeEntry(fc->entries[i]);
arrfree(fc->entries); arrfree(fc->entries);
MwLLDestroyPixmap(fc->dir); MwDestroyPixmap(fc->dir);
MwLLDestroyPixmap(fc->file); MwDestroyPixmap(fc->file);
MwLLDestroyPixmap(fc->back); MwDestroyPixmap(fc->back);
MwLLDestroyPixmap(fc->forward); MwDestroyPixmap(fc->forward);
MwLLDestroyPixmap(fc->up); MwDestroyPixmap(fc->up);
MwLLDestroyPixmap(fc->computer); MwDestroyPixmap(fc->computer);
free(handle->opaque); free(handle->opaque);
} }

View file

@ -21,7 +21,7 @@ static void spawn_button(MwWidget handle, int x, int y, int id, const char* text
static void messagebox_destroy_inject(MwWidget handle) { static void messagebox_destroy_inject(MwWidget handle) {
void* px; void* px;
if((px = MwGetVoid(handle, MwNpixmap)) != NULL) MwLLDestroyPixmap(px); if((px = MwGetVoid(handle, MwNpixmap)) != NULL) MwDestroyPixmap(px);
} }
static void MWAPI messagebox_close(MwWidget handle, void* user, void* call) { static void MWAPI messagebox_close(MwWidget handle, void* user, void* call) {

View file

@ -953,29 +953,43 @@ MwLLPixmap MwLoadImage(MwWidget handle, const char* path) {
return px; return px;
} }
static void pixmap_prop(MwWidget handle, const char* prop) {
if(strcmp(prop, MwNbackground) == 0 || strcmp(prop, MwNsubBackground) == 0) {
int i;
for(i = 0; i < arrlen(handle->pixmaps); i++) MwPixmapReloadRaw(handle->pixmaps[i], NULL);
}
}
MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height) { MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height) {
MwLLPixmap px = MwLLCreatePixmap(handle->lowlevel, rgb, width, height); MwLLPixmap px = MwLLCreatePixmap(handle->lowlevel, rgb, width, height);
px->common.user = handle; px->common.internal = handle;
MwPixmapReloadRaw(px, rgb); MwPixmapReloadRaw(px, rgb);
handle->prop_inject_pixmap = pixmap_prop;
arrput(handle->pixmaps, px);
return px; return px;
} }
void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) { void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) {
int i; int i;
MwWidget handle = px->common.user; MwWidget handle = px->common.internal;
MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor; MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor;
if(rgb != NULL) memcpy(px->common.before_blend, rgb, px->common.width * px->common.height * 4);
memset(px->common.raw, 0, px->common.width * px->common.height * 4); memset(px->common.raw, 0, px->common.width * px->common.height * 4);
for(i = 0; i < px->common.width * px->common.height; i++) { for(i = 0; i < px->common.width * px->common.height; i++) {
unsigned char* pin = &rgb[i * 4]; unsigned char* pin = &px->common.before_blend[i * 4];
unsigned char* pout = &px->common.raw[i * 4]; unsigned char* pout = &px->common.raw[i * 4];
double a = pin[3]; double a = pin[3];
a /= 255; a /= 255;
if(a != 0) { if(a != 0) {
#if 1 #if 0
a = 1; a = 1;
#endif #endif
pout[0] = (unsigned char)(pin[0] * a); pout[0] = (unsigned char)(pin[0] * a);
@ -1003,6 +1017,22 @@ void MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect) {
rect->height = pixmap->common.height; rect->height = pixmap->common.height;
} }
void MwDestroyPixmap(MwLLPixmap pixmap) {
int i;
MwWidget handle = pixmap->common.internal;
for(i = 0; i < arrlen(handle->pixmaps); i++) {
if(handle->pixmaps[i] == pixmap) {
arrdel(handle->pixmaps, i);
break;
}
}
if(arrlen(handle->pixmaps) == 0) handle->prop_inject_pixmap = NULL;
MwLLDestroyPixmap(pixmap);
}
void MwColorGet(MwLLColor color, int* red, int* green, int* blue) { void MwColorGet(MwLLColor color, int* red, int* green, int* blue) {
*red = color->common.red; *red = color->common.red;
*green = color->common.green; *green = color->common.green;

View file

@ -93,7 +93,7 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
return 0; return 0;

View file

@ -103,7 +103,7 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
DeleteObject(hbm); DeleteObject(hbm);

View file

@ -80,7 +80,7 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
return 0; return 0;

View file

@ -330,7 +330,7 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
} }

View file

@ -191,7 +191,7 @@ static void draw(MwWidget handle) {
r2.x = (r.width - r2.width) / 2; r2.x = (r.width - r2.width) / 2;
r2.y = r2.y + gh * 2; r2.y = r2.y + gh * 2;
MwLLDrawPixmap(handle->lowlevel, &r2, px); MwLLDrawPixmap(handle->lowlevel, &r2, px);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
px = blit(handle, months[MwGetInteger(handle, MwNmonth)], cb, ct, gh); px = blit(handle, months[MwGetInteger(handle, MwNmonth)], cb, ct, gh);
r2 = r3; r2 = r3;
@ -200,7 +200,7 @@ static void draw(MwWidget handle) {
r2.x = (r.width - r2.width) / 2; r2.x = (r.width - r2.width) / 2;
r2.y = r2.y + h - gh * 2 - r2.height; r2.y = r2.y + h - gh * 2 - r2.height;
MwLLDrawPixmap(handle->lowlevel, &r2, px); MwLLDrawPixmap(handle->lowlevel, &r2, px);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
MwStringPrintIntoBuffer(buf, 5, "%d", MwGetInteger(handle, MwNyear)); MwStringPrintIntoBuffer(buf, 5, "%d", MwGetInteger(handle, MwNyear));
@ -211,7 +211,7 @@ static void draw(MwWidget handle) {
r2.x = (r.width - r2.width) / 2; r2.x = (r.width - r2.width) / 2;
r2.y = r2.y + h + gh * 6; r2.y = r2.y + h + gh * 6;
MwLLDrawPixmap(handle->lowlevel, &r2, px); MwLLDrawPixmap(handle->lowlevel, &r2, px);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
MwLLFreeColor(cf); MwLLFreeColor(cf);
MwLLFreeColor(ct); MwLLFreeColor(ct);

View file

@ -309,7 +309,7 @@ static void draw_seven_segment(MwWidget handle) {
free(raw); free(raw);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
} }
static void draw_normal(MwWidget handle) { static void draw_normal(MwWidget handle) {

View file

@ -617,7 +617,7 @@ static void frontbuffer_resize(MwWidget handle) {
free(o->frontbuffer_data); free(o->frontbuffer_data);
} }
if(o->frontbuffer) { if(o->frontbuffer) {
MwLLDestroyPixmap(o->frontbuffer); MwDestroyPixmap(o->frontbuffer);
} }
if(o->gbm_surface) { if(o->gbm_surface) {
o->gbm_surface_destroy(o->gbm_surface); o->gbm_surface_destroy(o->gbm_surface);