Compare commits

...

13 commits

Author SHA1 Message Date
270c87bca2
care abt DESTDIR 2025-12-15 07:21:45 +09:00
dabe62d475
forgot 2025-12-15 07:10:23 +09:00
1e74356db7
method name consistency 2025-12-15 07:05:42 +09:00
bc998806ee
oops 2025-12-15 06:51:31 +09:00
cf4fdc531a
update color things 2025-12-15 06:48:40 +09:00
f9c0ec987e
improvement 2025-12-12 17:51:26 +09:00
0c8715ec9f
bugfix 2025-12-12 17:26:57 +09:00
363897df74
background pixmap 2025-12-11 01:37:13 +09:00
e57f3fd910
update 2025-12-11 00:50:50 +09:00
82f9330bef
add MwNfillArea 2025-12-10 13:26:19 +09:00
bbc27d680a
that is simply wrong 2025-12-10 12:57:40 +09:00
0c787264c6
fix some stuff 2025-12-10 11:15:52 +09:00
9a4c74ad93 Unfinished Wayland PR (#1)
moved from the github repo.

current progress:

<img width="389" alt="image.png" src="attachments/6a2cb365-7348-44b4-8fa7-9980df965a67">

Other notes:

- took the opportunity to remove MwLLSetBackground which I was told was deprecated
- Updated .gitignore to more accurately cover/remove example binaries
- Uses OpenGL as the backend.
- New LL function for swapping buffers, MwLLEndDraw
- [TODO] Uses weak linking for all libraries so that systems that don't support Wayland or even have it installed can launch without it.

Reviewed-on: https://gitea.nishi.boats/pyrite-dev/milsko/pulls/1
Co-authored-by: IoIxD <alphaproject217@gmail.com>
Co-committed-by: IoIxD <alphaproject217@gmail.com>
2025-12-09 20:11:01 -06:00
35 changed files with 6289 additions and 900 deletions

View file

@ -171,10 +171,10 @@ print(OUT "\n");
print(OUT "all: lib examples\n");
print(OUT "\n");
print(OUT "install: lib\n");
print(OUT " mkdir -p \$(PREFIX)/lib \$(PREFIX)/include\n");
print(OUT " -cp src/${library_prefix}Mw${library_suffix} \$(PREFIX)/lib/\n");
print(OUT " -cp src/libMw.a \$(PREFIX)/lib/\n");
print(OUT " cp -rf include \$(PREFIX)/\n");
print(OUT " mkdir -p \$(DESTDIR)\$(PREFIX)/lib \$(DESTDIR)\$(PREFIX)/include\n");
print(OUT " -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n");
print(OUT " -cp src/libMw.a \$(DESTDIR)\$(PREFIX)/lib/\n");
print(OUT " cp -rf include \$(DESTDIR)\$(PREFIX)/\n");
print(OUT "\n");
print(OUT "format:\n");
print(OUT

View file

@ -142,10 +142,10 @@ int main() {
NULL);
bgcolor = MwParseColor(window, MwGetText(window, MwNbackground));
MwGetColor(bgcolor, &br, &bg, &bb);
MwColorGet(bgcolor, &br, &bg, &bb);
fgcolor = MwParseColor(window, MwGetText(window, MwNforeground));
MwGetColor(fgcolor, &fr, &fg, &fb);
MwColorGet(fgcolor, &fr, &fg, &fb);
opengl = MwCreateWidget(MwOpenGLClass, "clock", window, 0, 0, 100, 100);

View file

@ -31,7 +31,7 @@ typedef uint16_t MwU16;
typedef int8_t MwI8;
typedef uint8_t MwU8;
#define OTHER_TYPES_DEFINED
#define MW_OTHER_TYPES_DEFINED
#elif __GNUC__ > 2
typedef long long MwI64;
typedef unsigned long long MwU64;
@ -48,15 +48,15 @@ typedef unsigned __int16 MwU16;
typedef __int8 MwI8;
typedef unsigned __int8 MwU8;
#define OTHER_TYPES_DEFINED
#define MW_OTHER_TYPES_DEFINED
#else
/* out of hope */
typedef long MwI64;
typedef unsigned long MwU64;
#endif
#ifdef OTHER_TYPES_DEFINED
#undef OTHER_TYPES_DEFINED
#ifdef MW_OTHER_TYPES_DEFINED
#undef MW_OTHER_TYPES_DEFINED
#else
typedef int MwI32;
typedef unsigned int MwU32;

View file

@ -21,6 +21,13 @@ extern "C" {
*/
MWDECL MwLLColor MwParseColor(MwWidget handle, const char* text);
/*!
* @brief Parses a color text
* @param text Color text
* @param rgb RGB
*/
MWDECL void MwParseColorNoAllocate(const char* text, MwRGB* rgb);
/*!
* @brief Lighten a color
* @param handle Widget
@ -105,7 +112,7 @@ MWDECL MwLLPixmap MwLoadImage(MwWidget handle, const char* path);
* @param green Pointer to green color
* @param blue Pointer to blue color
*/
MWDECL void MwGetColor(MwLLColor color, int* red, int* green, int* blue);
MWDECL void MwColorGet(MwLLColor color, int* red, int* green, int* blue);
/*!
* @brief Creates a pixmap from raw data
@ -118,14 +125,25 @@ MWDECL void MwGetColor(MwLLColor color, int* red, int* green, int* blue);
MWDECL MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height);
/*!
* @brief Creates a pixmap from raw data
* @param handle Widget
* @brief Updates a pixmap using raw data
* @param pixmap Pixmap to update
* @param rgb RGBA data
* @param width Width
* @param height Height
* @return Pixmap
*/
MWDECL void MwReloadRaw(MwWidget handle, unsigned char* rgb, int width, int height, MwLLPixmap pixmap);
MWDECL void MwPixmapReloadRaw(MwLLPixmap pixmap, unsigned char* rgb);
/*!
* @brief Gets the raw data of pixmap
* @param pixmap Pixmap
* @return RFBA data
*/
MWDECL unsigned char* MwPixmapGetRaw(MwLLPixmap pixmap);
/*!
* @brief Gets the size of pixmap
* @param pixmap Pixmap
* @param rect Size
*/
MWDECL void MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect);
/*!
* @brief Creates a pixmap from XPM data
@ -191,6 +209,13 @@ MWDECL int MwTextHeight(MwWidget handle, const char* text);
*/
MWDECL MwLLColor MwParseColorName(MwWidget handle, const char* color);
/*!
* @brief Parses a color name
* @param color Color name
* @param rgb RGB
*/
MWDECL void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb);
#ifdef __cplusplus
}
#endif

View file

@ -25,7 +25,8 @@ typedef void* MwLLPixmap;
enum MwLLBackends {
MwLLBackendX11 = 0,
MwLLBackendGDI
MwLLBackendGDI,
MwLLBackendWayland,
};
struct _MwLLCommon {
@ -46,6 +47,7 @@ struct _MwLLCommonPixmap {
int width;
int height;
unsigned char* raw;
void* user;
};
#ifdef _MILSKO
@ -55,6 +57,9 @@ struct _MwLLCommonPixmap {
#ifdef USE_GDI
#include <Mw/LowLevel/GDI.h>
#endif
#ifdef USE_WAYLAND
#include <Mw/LowLevel/Wayland.h>
#endif
union _MwLL {
struct _MwLLCommon common;
@ -64,6 +69,9 @@ union _MwLL {
#ifdef USE_GDI
struct _MwLLGDI gdi;
#endif
#ifdef USE_WAYLAND
struct _MwLLWayland wayland;
#endif
};
union _MwLLColor {
@ -74,6 +82,9 @@ union _MwLLColor {
#ifdef USE_GDI
struct _MwLLGDIColor gdi;
#endif
#ifdef USE_WAYLAND
struct _MwLLWaylandColor wayland;
#endif
};
union _MwLLPixmap {
@ -84,6 +95,9 @@ union _MwLLPixmap {
#ifdef USE_GDI
struct _MwLLGDIPixmap gdi;
#endif
#ifdef USE_WAYLAND
struct _MwLLWaylandPixmap wayland;
#endif
};
#endif
#include <Mw/TypeDefs.h>
@ -149,6 +163,8 @@ MWDECL void (*MwLLDestroy)(MwLL handle);
MWDECL void (*MwLLPolygon)(MwLL handle, MwPoint* points, int points_count, MwLLColor color);
MWDECL void (*MwLLLine)(MwLL handle, MwPoint* points, MwLLColor color);
MWDECL void (*MwLLBeginDraw)(MwLL handle);
MWDECL void (*MwLLEndDraw)(MwLL handle);
MWDECL MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b);
MWDECL void (*MwLLColorUpdate)(MwLL handle, MwLLColor c, int r, int g, int b);

View file

@ -0,0 +1,121 @@
/*!
* @file Mw/LowLevel/Wayland.h
* @brief Work in progress Wayland Backend
* @warning This is used internally.
* @warning This is disabled by default.
*/
#ifndef __MW_LOWLEVEL_WAYLAND_H__
#define __MW_LOWLEVEL_WAYLAND_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#include <wayland-client-protocol.h>
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
MWDECL int MwLLWaylandCallInit(void);
#ifndef WL_PROTOCOLS_DEFINED
#define WL_PROTOCOLS_DEFINED
#include "Wayland/xdg-shell-client-protocol.h"
#include "Wayland/xdg-decoration-client-protocol.h"
#include "Wayland/cursor-shape-client-protocol.h"
#endif
struct _MwLLWayland;
typedef struct wayland_protocol {
void* listener;
void* context;
} wayland_protocol_t;
typedef wayland_protocol_t*(wl_setup_func)(MwU32, struct _MwLLWayland*);
struct _MwLLWaylandTopLevel {
struct xdg_surface* xdg_surface;
struct xdg_toplevel* xdg_top_level;
struct xdg_toplevel_listener xdg_toplevel_listener;
struct xdg_surface_listener xdg_surface_listener;
struct xkb_context* xkb_context;
struct xkb_keymap* xkb_keymap;
struct xkb_state* xkb_state;
MwBool compositor_created;
MwBool xdg_wm_base_created;
MwBool xdg_surface_created;
};
struct _MwLLWayland {
struct _MwLLCommon common;
/* Pointer for data that's only loaded if the widget is a toplevel */
struct _MwLLWaylandTopLevel* toplevel;
enum {
MWLL_WAYLAND_TOPLEVEL = 0,
MWLL_WAYLAND_SUBLEVEL = 1, /* Sublevels are surfaces that have the toplevel as a parent. They could be implemented as subsurfaces if we ever switch away from OpenGL. Some parts of the code also call them subwidgets. */
} type;
/* Map of Wayland interfaces to their relevant setup functions. */
struct {
const char* key;
wl_setup_func* value;
}* wl_protocol_setup_map;
/* Map of Wayland interfaces to any information we keep about them once we've registered them. */
struct {
const char* key;
wayland_protocol_t* value;
}* wl_protocol_map;
struct wl_display* display;
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_subcompositor* subcompositor;
struct wl_surface* surface;
struct wl_registry_listener registry_listener;
struct wl_event_queue* event_queue;
EGLNativeWindowType egl_window_native;
EGLDisplay egl_display;
EGLContext egl_context;
EGLSurface egl_surface;
EGLConfig egl_config;
MwLL* sublevels; /* stb_ds managed array of any sublevels */
MwBool configured; /* Whether or not xdg_toplevel_configure has run once */
MwBool egl_setup; /* Whether or not EGL has been set up */
MwBool has_set_xy /* Whether or not MwSetXY has been called */;
int resize_counter; /* Counter that's for a hack in event_loop */
MwU32 x, y, ww, wh; /* Window position */
MwU32 lw, lh; /* Last known window position */
MwPoint cur_mouse_pos; /* Currently known mouse position */
struct timeval timer;
MwU64 cooldown_timer;
MwU64 cooldown_timer_epoch;
MwLL parent;
MwLL topmost_parent; /* The parent at the top of all the other parents. Usually a toplevel. */
};
struct _MwLLWaylandColor {
struct _MwLLCommonColor common;
};
struct _MwLLWaylandPixmap {
struct _MwLLCommonPixmap common;
GLuint texture;
MwBool texture_deleted;
};
#endif

View file

@ -0,0 +1 @@
*protocol.h

View file

@ -0,0 +1 @@
Folder for wayland-scanner to place any of its files.

View file

@ -13,6 +13,7 @@
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <sys/stat.h>
@ -43,6 +44,7 @@
#include <dlfcn.h>
#include <signal.h>
#include <dirent.h>
#include <fcntl.h>
#endif
#ifndef M_PI

View file

@ -31,6 +31,7 @@
#define MwNshowArrows "IshowArrows"
#define MwNpadding "Ipadding"
#define MwNborderWidth "IborderWidth"
#define MwNfillArea "IfillArea"
#define MwNtitle "Stitle"
#define MwNtext "Stext"
@ -44,6 +45,7 @@
#define MwNsizeHints "VsizeHints"
#define MwNfont "Vfont"
#define MwNboldFont "VboldFont"
#define MwNbackgroundPixmap "VbackgroundPixmap"
#define MwNactivateHandler "Cactivate" /* NULL/int* (MwListBox)/void* (MwTreeView) */
#define MwNresizeHandler "Cresize" /* NULL */

View file

@ -48,6 +48,7 @@
- MwNwidth
- MwNheight
- MwNborderWidth
- MwNbackgroundPixmap
Integer properties must be prefixed with I.
String properties must be prefixed with S.
@ -488,6 +489,7 @@
<property name="text" />
<property name="flat" />
<property name="padding" />
<property name="fillArea" />
</properties>
</widget>
<widget name="CheckBox">

View file

@ -26,6 +26,26 @@ if (grep(/^gdi$/, @backends)) {
$gl_libs = "-lopengl32 -lglu32";
}
if (grep(/^wayland$/, @backends)) {
add_cflags("-DUSE_WAYLAND");
new_object("src/backend/wayland.c");
if ($cross) {
add_libs("-lGL -lEGL -lwayland-egl -lwayland-client -lxkbcommon");
}
else {
add_libs("-lGL -lEGL");
add_cflags(`pkg-config --cflags wayland-egl wayland-client xkbcommon`);
add_libs(`pkg-config --libs wayland-egl wayland-client xkbcommon`);
}
scan_wayland_protocol("stable", "xdg-shell", "");
scan_wayland_protocol("stable", "tablet", "-v2");
scan_wayland_protocol("staging", "cursor-shape", "-v1");
scan_wayland_protocol("unstable", "xdg-decoration", "-unstable-v1");
$gl_libs = "-lGL -lGLU";
}
if (param_get("stb-image")) {
add_cflags("-DUSE_STB_IMAGE");
}
@ -34,7 +54,10 @@ if (param_get("stb-truetype")) {
}
if (param_get("freetype2")) {
add_cflags("-DUSE_FREETYPE2");
if (not($cross)) {
if ($cross) {
add_libs("-lfreetype");
}
else {
add_cflags(`pkg-config --cflags freetype2`);
add_libs(`pkg-config --libs freetype2`);
}

View file

@ -54,6 +54,38 @@ sub use_backend {
}
}
sub scan_wayland_protocol {
my $tier = $_[0];
my $proto = $_[1];
my $ver = $_[2];
my $proto_c = "src/backend/wayland-${proto}-protocol.c";
if (
system(
"wayland-scanner private-code /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml ${proto_c}"
) != 0
)
{
print(
"^ Error on getting private code for /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml\n"
);
}
else {
new_object($proto_c);
}
if (
system(
"wayland-scanner client-header /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml include/Mw/LowLevel/Wayland/${proto}-client-protocol.h"
)
)
{
print(
"^ Error on getting client header for /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml\n"
);
}
}
our %params = ();
sub param_set {

1
src/backend/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
wayland*protocol.c

View file

@ -8,8 +8,10 @@
MwLLCreate = MwLLCreateImpl; \
MwLLDestroy = MwLLDestroyImpl; \
\
MwLLPolygon = MwLLPolygonImpl; \
MwLLLine = MwLLLineImpl; \
MwLLPolygon = MwLLPolygonImpl; \
MwLLLine = MwLLLineImpl; \
MwLLBeginDraw = MwLLBeginDrawImpl; \
MwLLEndDraw = MwLLEndDrawImpl; \
\
MwLLAllocColor = MwLLAllocColorImpl; \
MwLLColorUpdate = MwLLColorUpdateImpl; \

View file

@ -280,6 +280,14 @@ static void MwLLDestroyImpl(MwLL handle) {
free(handle);
}
static void MwLLBeginDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLEndDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
POINT* p = malloc(sizeof(*p) * points_count);
HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0));

1150
src/backend/wayland.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -53,7 +53,7 @@ static void sync_move(MwLL handle, int x, int y) {
XSync(handle->x11.display, False);
if(!XPending(handle->x11.display)) continue;
XNextEvent(handle->x11.display, &ev);
if(ev.type == ReparentNotify && ev.xreparent.window == handle->x11.window && ev.xreparent.window != RootWindow(handle->x11.display, DefaultScreen(handle->x11.display))) {
if(ev.type == ReparentNotify && ev.xreparent.window == handle->x11.window) {
break;
} else {
arrput(queue, ev);
@ -259,6 +259,14 @@ static void MwLLDestroyImpl(MwLL handle) {
free(handle);
}
static void MwLLBeginDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLEndDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
int i;
XPoint* p = malloc(sizeof(*p) * points_count);
@ -572,9 +580,7 @@ static void MwLLSetTitleImpl(MwLL handle, const char* title) {
}
static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) {
MwLLPixmap r = malloc(sizeof(*r));
char* di = malloc(4 * width * height);
char* dm = malloc(4 * width * height);
MwLLPixmap r = malloc(sizeof(*r));
int evbase, erbase;
XWindowAttributes attr;
@ -595,8 +601,11 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
r->x11.use_xrender = XRenderQueryExtension(handle->x11.display, &evbase, &erbase) ? 1 : 0;
#endif
r->x11.image = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), r->x11.depth, ZPixmap, 0, di, width, height, 32, width * 4);
r->x11.mask = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), 1, ZPixmap, 0, dm, width, height, 32, width * 4);
r->x11.image = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), r->x11.depth, ZPixmap, 0, NULL, width, height, 32, 0);
r->x11.mask = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), 1, ZPixmap, 0, NULL, width, height, 32, 0);
r->x11.image->data = malloc(r->x11.image->bytes_per_line * height);
r->x11.mask->data = malloc(r->x11.mask->bytes_per_line * height);
MwLLPixmapUpdate(r);
return r;
@ -1012,7 +1021,7 @@ static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
XWindowAttributes xwa;
XGetWindowAttributes(handle->x11.display, handle->x11.window, &xwa);
XGetWindowAttributes(handle->x11.display, DefaultRootWindow(handle->x11.display), &xwa);
rect->x = rect->y = 0;
rect->width = xwa.width;
@ -1028,7 +1037,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
}
static int MwLLX11CallInitImpl(void) {
/* TODO: check properly */
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -6,11 +6,14 @@ static void lldrawhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
(void)data;
MwLLBeginDraw(handle);
h->bgcolor = NULL;
MwDispatch(h, draw);
if(h->draw_inject != NULL) h->draw_inject(h);
MwDispatchUserHandler(h, MwNdrawHandler, NULL);
MwLLEndDraw(handle);
}
static void lluphandler(MwLL handle, void* data) {
@ -303,7 +306,10 @@ int MwStep(MwWidget handle) {
arrfree(widgets);
handle->prop_event = 0;
if(handle->lowlevel != NULL && MwLLPending(handle->lowlevel)) MwLLNextEvent(handle->lowlevel);
if(handle->lowlevel != NULL && MwLLPending(handle->lowlevel))
MwLLNextEvent(handle->lowlevel);
handle->prop_event = 1;
clean_destroy_queue(handle);
@ -694,6 +700,9 @@ MwWidget MwGetParent(MwWidget handle) {
typedef int (*call_t)(void);
int MwLibraryInit(void) {
call_t calls[] = {
#ifdef USE_WAYLAND
MwLLWaylandCallInit,
#endif
#ifdef USE_X11
MwLLX11CallInit,
#endif

View file

@ -146,11 +146,11 @@ static void color_picker_image_update(color_picker_t* picker) {
picker->color_picker_pixmap = MwLoadRaw(
picker->parent, picker->color_picker_image_data, PICKER_SIZE, PICKER_SIZE);
} else {
MwReloadRaw(
picker->parent, picker->color_picker_image_data, PICKER_SIZE, PICKER_SIZE, picker->color_picker_pixmap);
MwPixmapReloadRaw(
picker->color_picker_pixmap, picker->color_picker_image_data);
}
MwVaApply(picker->color_picker_img, MwNpixmap, picker->color_picker_pixmap, NULL);
// printf("%d\n", n);
/* printf("%d\n", n); */
}
static void color_picker_click(MwWidget handle, void* user, void* call) {
@ -165,7 +165,7 @@ static void color_picker_click(MwWidget handle, void* user, void* call) {
(void)user;
(void)call;
// color_picker_image_update(picker);
/* color_picker_image_update(picker); */
i = ((mouse->point.y * PICKER_SIZE) + mouse->point.x) * 4;
@ -198,7 +198,7 @@ static void color_picker_on_change_value(MwWidget handle, void* user,
picker->value = ((double)value / 1024.);
picker->doUpdate = 1;
// color_picker_image_update(picker);
/* color_picker_image_update(picker); */
}
static void color_picker_tick(MwWidget handle, void* user,
@ -282,12 +282,12 @@ color_picker_t* color_picker_setup(MwWidget parent, int w, int h) {
MwVaCreateWidget(MwImageClass, "image", picker->parent, IMG_POS_X(w), IMG_POS_Y(h),
PICKER_SIZE, PICKER_SIZE, NULL);
// picker->color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4);
/* picker->color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4); */
picker->color_picker_pixmap = NULL;
picker->value = 0;
// color_picker_image_update(picker);
/* color_picker_image_update(picker); */
picker->doUpdate = 1;
MwAddUserHandler(picker->color_picker_img, MwNmouseDownHandler,
@ -299,7 +299,7 @@ color_picker_t* color_picker_setup(MwWidget parent, int w, int h) {
MwSetText(picker->color_display_text, MwNbackground, "#FFFFFF");
MwSetText(picker->color_display_text, MwNtext, "#FFFFFF");
// MwSetInteger(picker->color_display_text, Mwnali, MwALIGNMENT_CENTER);
/* MwSetInteger(picker->color_display_text, Mwnali, MwALIGNMENT_CENTER); */
MwAddUserHandler(picker->color_display_text, MwNactivateHandler,
color_display_text_change, picker);

View file

@ -37,28 +37,35 @@ static int hex(const char* txt, int len) {
return r;
}
MwLLColor MwParseColor(MwWidget handle, const char* text) {
int r;
int g;
int b;
void MwParseColorNoAllocate(const char* text, MwRGB* rgb) {
if(text[0] == '#' && strlen(text) == 4) {
r = hex(text + 1, 1);
g = hex(text + 2, 1);
b = hex(text + 3, 1);
rgb->red = hex(text + 1, 1);
rgb->green = hex(text + 2, 1);
rgb->blue = hex(text + 3, 1);
r |= r << 4;
g |= g << 4;
b |= b << 4;
rgb->red |= rgb->red << 4;
rgb->green |= rgb->green << 4;
rgb->blue |= rgb->blue << 4;
} else if(text[0] == '#' && strlen(text) == 7) {
r = hex(text + 1, 2);
g = hex(text + 3, 2);
b = hex(text + 5, 2);
rgb->red = hex(text + 1, 2);
rgb->green = hex(text + 3, 2);
rgb->blue = hex(text + 5, 2);
} else {
return MwParseColorName(handle, text);
MwParseColorNameNoAllocate(text, rgb);
return;
}
}
return MwLLAllocColor(handle->lowlevel, r, g, b);
MwLLColor MwParseColor(MwWidget handle, const char* text) {
MwRGB rgb;
rgb.red = 0;
rgb.green = 0;
rgb.blue = 0;
MwParseColorNoAllocate(text, &rgb);
return MwLLAllocColor(handle->lowlevel, rgb.red, rgb.green, rgb.blue);
}
MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b) {
@ -491,6 +498,7 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p4[2].y = rect->y + s * border;
}
MwLLPolygon(handle->lowlevel, p4, 3, col);
if(color != col) MwLLFreeColor(col);
MwLLFreeColor(lighter);
@ -648,45 +656,21 @@ MwLLPixmap MwLoadImage(MwWidget handle, const char* path) {
}
MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height) {
MwLLPixmap px;
unsigned char* out = malloc(width * height * 4);
int i;
MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor;
MwLLPixmap px = MwLLCreatePixmap(handle->lowlevel, rgb, width, height);
memset(out, 0, width * height * 4);
for(i = 0; i < width * height; i++) {
unsigned char* pin = &rgb[i * 4];
unsigned char* pout = &out[i * 4];
double a = pin[3];
a /= 255;
if(a != 0) {
pout[0] = pin[0] * a;
pout[1] = pin[1] * a;
pout[2] = pin[2] * a;
pout[0] += base->common.red * (1 - a);
pout[1] += base->common.green * (1 - a);
pout[2] += base->common.blue * (1 - a);
pout[3] = 255;
}
}
if(handle->bgcolor == NULL) MwLLFreeColor(base);
px = MwLLCreatePixmap(handle->lowlevel, out, width, height);
free(out);
px->common.user = handle;
MwPixmapReloadRaw(px, rgb);
return px;
}
void MwReloadRaw(MwWidget handle, unsigned char* rgb, int width, int height, MwLLPixmap px) {
void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) {
int i;
MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor;
MwWidget handle = px->common.user;
MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor;
memset(px->common.raw, 0, width * height * 4);
for(i = 0; i < width * height; i++) {
memset(px->common.raw, 0, px->common.width * px->common.height * 4);
for(i = 0; i < px->common.width * px->common.height; i++) {
unsigned char* pin = &rgb[i * 4];
unsigned char* pout = &px->common.raw[i * 4];
double a = pin[3];
@ -709,7 +693,16 @@ void MwReloadRaw(MwWidget handle, unsigned char* rgb, int width, int height, MwL
MwLLPixmapUpdate(px);
}
void MwGetColor(MwLLColor color, int* red, int* green, int* blue) {
unsigned char* MwPixmapGetRaw(MwLLPixmap pixmap) {
return pixmap->common.raw;
}
void MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect) {
rect->width = pixmap->common.width;
rect->height = pixmap->common.height;
}
void MwColorGet(MwLLColor color, int* red, int* green, int* blue) {
*red = color->common.red;
*green = color->common.green;
*blue = color->common.blue;

View file

@ -6,6 +6,9 @@ void (*MwLLDestroy)(MwLL handle);
void (*MwLLPolygon)(MwLL handle, MwPoint* points, int points_count, MwLLColor color);
void (*MwLLLine)(MwLL handle, MwPoint* points, MwLLColor color);
void (*MwLLBeginDraw)(MwLL handle);
void (*MwLLEndDraw)(MwLL handle);
MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b);
void (*MwLLColorUpdate)(MwLL handle, MwLLColor c, int r, int g, int b);
void (*MwLLFreeColor)(MwLLColor color);

View file

@ -292,6 +292,7 @@ static int ttf_MwTextHeight(MwWidget handle, int count) {
#endif
void MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
if(strlen(text) == 0) return;
#ifdef TTF
if(ttf_MwDrawText(handle, point, text, bold, align, color))
#endif

View file

@ -5,6 +5,7 @@ static int create(MwWidget handle) {
MwSetInteger(handle, MwNflat, 0);
MwSetInteger(handle, MwNpadding, 0);
MwSetInteger(handle, MwNfillArea, 1);
return 0;
}
@ -16,6 +17,7 @@ static void draw(MwWidget handle) {
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground));
const char* str = MwGetText(handle, MwNtext);
MwLLPixmap px = MwGetVoid(handle, MwNpixmap);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
if(str == NULL) str = "";
@ -33,6 +35,7 @@ static void draw(MwWidget handle) {
} else {
MwDrawWidgetBack(handle, &r, base, handle->pressed, 1);
}
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
if(MwGetInteger(handle, MwNflat) && !handle->pressed) {
r.x += MwDefaultBorderWidth(handle);
r.y += MwDefaultBorderWidth(handle);
@ -44,18 +47,23 @@ static void draw(MwWidget handle) {
int ow = r.width;
int oh = r.height;
double sw = (double)ow / px->common.width;
double sh = (double)oh / px->common.height;
if(MwGetInteger(handle, MwNfillArea)) {
double sw = (double)ow / px->common.width;
double sh = (double)oh / px->common.height;
if(sw < sh) {
r.width = px->common.width * sw;
r.height = px->common.height * sw;
if(sw < sh) {
r.width = px->common.width * sw;
r.height = px->common.height * sw;
} else {
r.width = px->common.width * sh;
r.height = px->common.height * sh;
}
r.width -= MwGetInteger(handle, MwNpadding) * 2;
r.height -= MwGetInteger(handle, MwNpadding) * 2;
} else {
r.width = px->common.width * sh;
r.height = px->common.height * sh;
r.width = px->common.width;
r.height = px->common.height;
}
r.width -= MwGetInteger(handle, MwNpadding) * 2;
r.height -= MwGetInteger(handle, MwNpadding) * 2;
r.x += (double)(ow - r.width) / 2;
r.y += (double)(oh - r.height) / 2;
@ -77,7 +85,7 @@ static void click(MwWidget handle) {
}
static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNtext) == 0 || strcmp(key, MwNpixmap) == 0 || strcmp(key, MwNflat) == 0 || strcmp(key, MwNpadding) == 0) MwForceRender(handle);
if(strcmp(key, MwNtext) == 0 || strcmp(key, MwNpixmap) == 0 || strcmp(key, MwNflat) == 0 || strcmp(key, MwNpadding) == 0 || strcmp(key, MwNfillArea) == 0) MwForceRender(handle);
}
MwClassRec MwButtonClassRec = {

View file

@ -9,8 +9,9 @@ static int create(MwWidget handle) {
}
static void draw(MwWidget handle) {
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0;
r.y = 0;
@ -18,6 +19,7 @@ static void draw(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight);
MwDrawWidgetBack(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0, MwTRUE);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
if(handle->pressed || MwGetInteger(handle, MwNchecked)) {
/* TODO: write check mark */
}

View file

@ -25,6 +25,7 @@ static void draw(MwWidget handle) {
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground));
const char* str = MwGetText(handle, MwNtext);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
if(str == NULL) str = "";
r.x = 0;
@ -33,6 +34,7 @@ static void draw(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight);
MwDrawWidgetBack(handle, &r, base, 1, 1);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
if(str != NULL) {
int w = MwTextWidth(handle, "M");
int h = MwTextHeight(handle, "M");

View file

@ -10,10 +10,11 @@ static int create(MwWidget handle) {
}
static void draw(MwWidget handle) {
MwRect fr;
MwRect rr;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
int inverted;
MwRect fr;
MwRect rr;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
int inverted;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
if(MwGetInteger(handle, MwNhasBorder)) {
inverted = MwGetInteger(handle, MwNinverted);
@ -36,6 +37,7 @@ static void draw(MwWidget handle) {
}
MwDrawRect(handle, &rr, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &rr, bgpx);
MwLLFreeColor(base);
}

View file

@ -14,7 +14,8 @@ static void draw(MwWidget handle) {
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground));
int align;
const char* str = MwGetText(handle, MwNtext);
const char* str = MwGetText(handle, MwNtext);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
if(str == NULL) str = "";
@ -24,6 +25,7 @@ static void draw(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
align = MwGetInteger(handle, MwNalignment);
if(align == MwALIGNMENT_CENTER) {

View file

@ -1,6 +1,12 @@
#include <Mw/Milsko.h>
#include <Mw/Widget/OpenGL.h>
#ifdef USE_WAYLAND
#include <stb_ds.h>
#include <pthread.h>
#include <sys/time.h>
#endif
#ifdef USE_GDI
typedef HGLRC(WINAPI* MWwglCreateContext)(HDC);
typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC);
@ -103,6 +109,12 @@ static int create(MwWidget handle) {
o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL, GL_TRUE);
}
#endif
#ifdef USE_WAYLAND
/* Wayland uses OpenGL as its backend so its already initialized */
if(handle->lowlevel->common.type == MwLLBackendWayland) {
}
#endif
handle->internal = r;
handle->lowlevel->common.copy_buffer = 0;
@ -133,6 +145,10 @@ static void destroy(MwWidget handle) {
MwDynamicClose(o->lib);
}
#endif
#ifdef USE_WAYLAND
/* Wayland uses OpenGL as its backend so its destroyed accordingly */
#endif
free(handle->internal);
}
@ -151,6 +167,10 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
o->glXMakeCurrent(handle->lowlevel->x11.display, handle->lowlevel->x11.window, o->gl);
}
#endif
#ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) {
}
#endif
}
static void mwOpenGLSwapBufferImpl(MwWidget handle) {
@ -168,6 +188,16 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) {
o->glXSwapBuffers(handle->lowlevel->x11.display, handle->lowlevel->x11.window);
}
#endif
#ifdef USE_WAYLAND
#define tp handle->lowlevel->wayland.topmost_parent->wayland
if(handle->lowlevel->common.type == MwLLBackendWayland) {
if(!eglSwapBuffers(
tp.egl_display, tp.egl_surface)) {
printf("Userland error: eglSwapBuffers, %0X\n", eglGetError());
}
}
#undef topmost_parent
#endif
}
static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) {
@ -184,6 +214,11 @@ static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) {
return o->glXGetProcAddress((const GLubyte*)name);
}
#endif
#ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) {
return eglGetProcAddress(name);
}
#endif
return NULL;
}

View file

@ -12,10 +12,11 @@ static int create(MwWidget handle) {
}
static void draw(MwWidget handle) {
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor fill = MwParseColor(handle, MwGetText(handle, MwNforeground));
double w;
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor fill = MwParseColor(handle, MwGetText(handle, MwNforeground));
double w;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0;
r.y = 0;
@ -26,6 +27,7 @@ static void draw(MwWidget handle) {
MwDrawRect(handle, &r, base);
w = MwGetInteger(handle, MwNvalue) - MwGetInteger(handle, MwNminValue);
w = w / (MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue));
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
r.x += MwDefaultBorderWidth(handle);
r.y += MwDefaultBorderWidth(handle);

View file

@ -11,8 +11,9 @@ static int create(MwWidget handle) {
}
static void draw(MwWidget handle) {
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0;
r.y = 0;
@ -20,6 +21,7 @@ static void draw(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0);
MwLLFreeColor(base);

View file

@ -65,7 +65,8 @@ static void draw(MwWidget handle) {
MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64);
scrollbar_t* scr = handle->internal;
int or ;
int uy, dy, ux, dx;
int uy, dy, ux, dx;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0;
r.y = 0;
@ -79,6 +80,7 @@ static void draw(MwWidget handle) {
dx = r.width - r.height;
MwDrawWidgetBack(handle, &r, dark, 1, MwTRUE);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
rt = r;

View file

@ -114,7 +114,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry**
if(tree->selected) {
r.x = p->x;
r.y = p->y - MwTextHeight(handle, "M") / 2;
r.width = MwGetInteger(handle, MwNwidth) - MwGetInteger(handle, MwNleftPadding) - shift; // MwTextWidth(handle, tree->label);
r.width = MwGetInteger(handle, MwNwidth) - MwGetInteger(handle, MwNleftPadding) - shift;
r.height = MwTextHeight(handle, "M");
MwDrawRect(handle, &r, text2);
}

View file

@ -5,15 +5,29 @@ open(OUT, ">", "src/color.c");
print(OUT "#include <Mw/Milsko.h>\n");
print(OUT "\n");
print(OUT "MwLLColor MwParseColorName(MwWidget handle, const char* color){\n");
print(OUT " MwRGB rgb;\n");
print(OUT " MwParseColorNameNoAllocate(color, &rgb);\n");
print(OUT
" return MwLLAllocColor(handle->lowlevel, rgb.red, rgb.green, rgb.blue);\n"
);
print(OUT "}\n");
print(OUT "\n");
print(OUT "void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb){\n");
while (my $l = <IN>) {
$l =~ s/\r?\n$//;
if ($l =~ /^[ \t]*([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+(.+)$/) {
print(OUT
" if(strcmp(color, \"$4\") == 0) return MwLLAllocColor(handle->lowlevel, $1, $2, $3);\n"
);
print(OUT " if(strcmp(color, \"$4\") == 0){\n");
print(OUT " rgb->red = $1;\n");
print(OUT " rgb->green = $2;\n");
print(OUT " rgb->green = $3;\n");
print(OUT " return;\n");
print(OUT " }\n");
}
}
print(OUT " return MwLLAllocColor(handle->lowlevel, 0, 0, 0);\n");
print(OUT " rgb->red = 0;\n");
print(OUT " rgb->green = 0;\n");
print(OUT " rgb->blue = 0;\n");
print(OUT "}\n");
close(OUT);