wayland: start getting rid of cairo in favor of pixman
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoI_xD 2026-04-08 14:18:13 -07:00
commit 6f6b08c0f5
4 changed files with 120 additions and 277 deletions

View file

@ -6,6 +6,7 @@
#ifndef __MW_LOWLEVEL_WAYLAND_H__ #ifndef __MW_LOWLEVEL_WAYLAND_H__
#define __MW_LOWLEVEL_WAYLAND_H__ #define __MW_LOWLEVEL_WAYLAND_H__
#include "pixman.h"
#include <Mw/MachDep.h> #include <Mw/MachDep.h>
#include <Mw/TypeDefs.h> #include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h> #include <Mw/LowLevel.h>
@ -34,7 +35,6 @@ struct _MwLLWayland;
typedef struct wayland_call_table { typedef struct wayland_call_table {
void* lib; void* lib;
void* xkb_lib; void* xkb_lib;
void* cairo_lib;
#if WAYLAND_LOAD_OPENGL #if WAYLAND_LOAD_OPENGL
#endif #endif
@ -66,64 +66,6 @@ typedef struct wayland_call_table {
xkb_layout_index_t (*xkb_state_key_get_layout)(struct xkb_state* state, xkb_keycode_t key); xkb_layout_index_t (*xkb_state_key_get_layout)(struct xkb_state* state, xkb_keycode_t key);
void (*xkb_keymap_unref)(struct xkb_keymap* keymap); void (*xkb_keymap_unref)(struct xkb_keymap* keymap);
void (*cairo_set_line_width)(cairo_t* cr,
double width);
void (*cairo_scale)(cairo_t* cr,
double sx,
double sy);
cairo_t* (*cairo_create)(cairo_surface_t* target);
void (*cairo_move_to)(cairo_t* cr,
double x,
double y);
void (*cairo_rectangle)(cairo_t* cr,
double x,
double y,
double width,
double height);
void (*cairo_new_path)(cairo_t* cr);
void (*cairo_set_line_cap)(cairo_t* cr,
cairo_line_cap_t line_cap);
void (*cairo_set_source_rgba)(cairo_t* cr,
double red,
double green,
double blue,
double alpha);
void (*cairo_set_source_rgb)(cairo_t* cr,
double red,
double green,
double blue);
void (*cairo_reset_clip)(cairo_t* cr);
unsigned char* (*cairo_image_surface_get_data)(cairo_surface_t* surface);
void (*cairo_line_to)(cairo_t* cr,
double x,
double y);
void (*cairo_surface_destroy)(cairo_surface_t* surface);
cairo_surface_t* (*cairo_image_surface_create_for_data)(unsigned char* data,
cairo_format_t format,
int width,
int height,
int stride);
cairo_surface_t* (*cairo_image_surface_create)(cairo_format_t format,
int width,
int height);
void (*cairo_destroy)(cairo_t* cr);
cairo_pattern_t* (*cairo_get_source)(cairo_t* cr);
void (*cairo_close_path)(cairo_t* cr);
void (*cairo_paint)(cairo_t* cr);
void (*cairo_surface_flush)(cairo_surface_t* surface);
void (*cairo_clip)(cairo_t* cr);
void (*cairo_surface_mark_dirty)(cairo_surface_t* surface);
void (*cairo_stroke)(cairo_t* cr);
void (*cairo_set_source_surface)(cairo_t* cr,
cairo_surface_t* surface,
double x,
double y);
void (*cairo_fill)(cairo_t* cr);
void (*cairo_pattern_set_filter)(cairo_pattern_t* pattern,
cairo_filter_t filter);
void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t);
} wayland_call_table_t; } wayland_call_table_t;
extern wayland_call_table_t wl_call_tbl; extern wayland_call_table_t wl_call_tbl;
@ -140,11 +82,7 @@ MwInline int wayland_load_funcs() {
printf("(libxkbcommon.so not found, cannot use Wayland backend.)\n"); printf("(libxkbcommon.so not found, cannot use Wayland backend.)\n");
return 1; return 1;
} }
wl_call_tbl.cairo_lib = MwDynamicOpen("libcairo.so");
if(!wl_call_tbl.cairo_lib) {
printf("(libcairo.so not found, cannot use Wayland backend.)\n");
return 1;
}
#define WAYLAND_FUNC(x) \ #define WAYLAND_FUNC(x) \
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.lib, #x); \ wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.lib, #x); \
if(!wl_call_tbl.x) { \ if(!wl_call_tbl.x) { \
@ -187,42 +125,6 @@ MwInline int wayland_load_funcs() {
XKB_FUNC(xkb_state_key_get_layout) XKB_FUNC(xkb_state_key_get_layout)
#undef XKB_FUNC #undef XKB_FUNC
#define CAIRO_FUNC(x) \
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.cairo_lib, #x); \
if(!wl_call_tbl.x) { \
printf("WARNING: Could use Wayland backend if " #x " was found. Do you have libcairo?\n"); \
return 1; \
};
CAIRO_FUNC(cairo_set_line_width);
CAIRO_FUNC(cairo_scale);
CAIRO_FUNC(cairo_create);
CAIRO_FUNC(cairo_move_to);
CAIRO_FUNC(cairo_rectangle);
CAIRO_FUNC(cairo_new_path);
CAIRO_FUNC(cairo_set_line_cap);
CAIRO_FUNC(cairo_set_antialias);
CAIRO_FUNC(cairo_set_source_rgba);
CAIRO_FUNC(cairo_set_source_rgb);
CAIRO_FUNC(cairo_reset_clip);
CAIRO_FUNC(cairo_image_surface_get_data);
CAIRO_FUNC(cairo_line_to);
CAIRO_FUNC(cairo_surface_destroy);
CAIRO_FUNC(cairo_image_surface_create_for_data);
CAIRO_FUNC(cairo_image_surface_create);
CAIRO_FUNC(cairo_destroy);
CAIRO_FUNC(cairo_get_source);
CAIRO_FUNC(cairo_close_path);
CAIRO_FUNC(cairo_paint);
CAIRO_FUNC(cairo_surface_flush);
CAIRO_FUNC(cairo_clip);
CAIRO_FUNC(cairo_surface_mark_dirty);
CAIRO_FUNC(cairo_stroke);
CAIRO_FUNC(cairo_set_source_surface);
CAIRO_FUNC(cairo_fill);
CAIRO_FUNC(cairo_pattern_set_filter);
#undef CAIRO_FUNC
return 0; return 0;
} }
@ -251,34 +153,6 @@ MwInline int wayland_load_funcs() {
#define xkb_keymap_key_get_syms_by_level wl_call_tbl.xkb_keymap_key_get_syms_by_level #define xkb_keymap_key_get_syms_by_level wl_call_tbl.xkb_keymap_key_get_syms_by_level
#define xkb_state_key_get_layout wl_call_tbl.xkb_state_key_get_layout #define xkb_state_key_get_layout wl_call_tbl.xkb_state_key_get_layout
#define cairo_set_line_width wl_call_tbl.cairo_set_line_width
#define cairo_scale wl_call_tbl.cairo_scale
#define cairo_create wl_call_tbl.cairo_create
#define cairo_move_to wl_call_tbl.cairo_move_to
#define cairo_rectangle wl_call_tbl.cairo_rectangle
#define cairo_new_path wl_call_tbl.cairo_new_path
#define cairo_set_line_cap wl_call_tbl.cairo_set_line_cap
#define cairo_set_antialias wl_call_tbl.cairo_set_antialias
#define cairo_set_source_rgba wl_call_tbl.cairo_set_source_rgba
#define cairo_set_source_rgb wl_call_tbl.cairo_set_source_rgb
#define cairo_reset_clip wl_call_tbl.cairo_reset_clip
#define cairo_image_surface_get_data wl_call_tbl.cairo_image_surface_get_data
#define cairo_line_to wl_call_tbl.cairo_line_to
#define cairo_surface_destroy wl_call_tbl.cairo_surface_destroy
#define cairo_image_surface_create_for_data wl_call_tbl.cairo_image_surface_create_for_data
#define cairo_image_surface_create wl_call_tbl.cairo_image_surface_create
#define cairo_destroy wl_call_tbl.cairo_destroy
#define cairo_get_source wl_call_tbl.cairo_get_source
#define cairo_close_path wl_call_tbl.cairo_close_path
#define cairo_paint wl_call_tbl.cairo_paint
#define cairo_surface_flush wl_call_tbl.cairo_surface_flush
#define cairo_clip wl_call_tbl.cairo_clip
#define cairo_surface_mark_dirty wl_call_tbl.cairo_surface_mark_dirty
#define cairo_stroke wl_call_tbl.cairo_stroke
#define cairo_set_source_surface wl_call_tbl.cairo_set_source_surface
#define cairo_fill wl_call_tbl.cairo_fill
#define cairo_pattern_set_filter wl_call_tbl.cairo_pattern_set_filter
#ifndef WL_PROTOCOLS_DEFINED #ifndef WL_PROTOCOLS_DEFINED
#define WL_PROTOCOLS_DEFINED #define WL_PROTOCOLS_DEFINED
#include "Wayland/wayland-core-protocol.h" #include "Wayland/wayland-core-protocol.h"
@ -347,12 +221,15 @@ struct _MwLLWaylandShmBuffer {
struct wl_surface* surface; struct wl_surface* surface;
struct wl_output* output; struct wl_output* output;
MwU8* buf; MwU32* buf;
MwU8* buf_back; MwU32* buf_back;
MwU64 buf_size; MwU64 buf_size;
int fd; int fd;
int fd_back; int fd_back;
MwBool setup; MwBool setup;
pixman_image_t* pixman_fb_front;
pixman_image_t* pixman_fb_back;
}; };
enum _MwLLWaylandType { enum _MwLLWaylandType {
@ -493,13 +370,6 @@ struct _MwLLWayland {
uint32_t last_time; uint32_t last_time;
MwBool moving; MwBool moving;
cairo_surface_t* front_cs;
cairo_surface_t* back_cs;
cairo_t* front_cairo;
cairo_t* back_cairo;
/* The cairo to actually use for draw operations. Typically is front_cairo, but MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo;
}; };
struct _MwLLWaylandColor { struct _MwLLWaylandColor {
@ -509,7 +379,7 @@ struct _MwLLWaylandColor {
struct _MwLLWaylandPixmap { struct _MwLLWaylandPixmap {
struct _MwLLCommonPixmap common; struct _MwLLCommonPixmap common;
cairo_surface_t* cs; pixman_image_t* img;
}; };
#endif #endif

View file

@ -38,6 +38,9 @@ if (grep(/^wayland$/, @backends)) {
add_cflags("-DWAYLAND_LOAD_OPENGL"); add_cflags("-DWAYLAND_LOAD_OPENGL");
} }
add_cflags("-I/usr/include/pixman-1");
add_libs("-lpixman-1");
scan_wayland_protocol_core(); scan_wayland_protocol_core();
scan_wayland_protocol("stable", "xdg-shell", ""); scan_wayland_protocol("stable", "xdg-shell", "");
scan_wayland_protocol("stable", "viewporter", ""); scan_wayland_protocol("stable", "viewporter", "");

View file

@ -4,6 +4,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "../../external/stb_ds.h" #include "../../external/stb_ds.h"
#include "pixman.h"
/* TODO: find out what FreeBSD and such wants us to include */ /* TODO: find out what FreeBSD and such wants us to include */
#ifdef __FreeBSD__ #ifdef __FreeBSD__
@ -1264,7 +1265,7 @@ static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
// Yes this is needed every time, it's how we fix weston. // Yes this is needed every time, it's how we fix weston.
wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
wl_surface_commit(buffer->surface); wl_surface_commit(buffer->surface);
} }
static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
@ -1272,7 +1273,7 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX";
char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXX"; char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXX";
buffer->buf_size = width * height * 4; buffer->buf_size = (width * height * 4) * sizeof(MwU32);
buffer->fd = mkstemp(temp_name); buffer->fd = mkstemp(temp_name);
buffer->fd_back = mkstemp(temp_name_back); buffer->fd_back = mkstemp(temp_name_back);
@ -1315,7 +1316,15 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3
} }
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;
pixman_color_t col = {0, 0, 0, 0xffff};
buffer->pixman_fb_front = pixman_image_create_bits(PIXMAN_a8b8g8r8,
width, height, buffer->buf, stride);
buffer->pixman_fb_back = pixman_image_create_bits(PIXMAN_a8b8g8r8,
width, height, buffer->buf_back, stride);
buffer->setup = MwTRUE;
} }
static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) { static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) {
@ -1328,15 +1337,15 @@ static void buffer_destroy(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);
pixman_image_unref(buffer->pixman_fb_front);
pixman_image_unref(buffer->pixman_fb_back);
buffer->setup = MwFALSE; buffer->setup = MwFALSE;
} }
static void framebuffer_setup(struct _MwLLWayland* wayland) { static void framebuffer_setup(struct _MwLLWayland* wayland) {
buffer_setup(&wayland->framebuffer, wayland->ww, wayland->wh); buffer_setup(&wayland->framebuffer, wayland->ww, wayland->wh);
wayland->front_cs = cairo_image_surface_create_for_data(wayland->framebuffer.buf_back, CAIRO_FORMAT_ARGB32, wayland->ww, wayland->wh, 4 * wayland->ww);
wayland->front_cairo = cairo_create(wayland->front_cs);
memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size);
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
wl_surface_commit(wayland->framebuffer.surface); wl_surface_commit(wayland->framebuffer.surface);
@ -1346,8 +1355,6 @@ static void framebuffer_setup(struct _MwLLWayland* wayland) {
}; };
static void framebuffer_destroy(struct _MwLLWayland* wayland) { static void framebuffer_destroy(struct _MwLLWayland* wayland) {
buffer_destroy(&wayland->framebuffer); buffer_destroy(&wayland->framebuffer);
cairo_destroy(wayland->front_cairo);
cairo_surface_destroy(wayland->front_cs);
}; };
static void backbuffer_setup(struct _MwLLWayland* wayland) { static void backbuffer_setup(struct _MwLLWayland* wayland) {
@ -1362,9 +1369,6 @@ static void backbuffer_setup(struct _MwLLWayland* wayland) {
} }
buffer_setup(&wayland->backbuffer, w, h); buffer_setup(&wayland->backbuffer, w, h);
wayland->back_cs = cairo_image_surface_create_for_data(wayland->backbuffer.buf_back, CAIRO_FORMAT_ARGB32, w, h, 4 * w);
wayland->back_cairo = cairo_create(wayland->back_cs);
memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size);
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
wl_surface_commit(wayland->backbuffer.surface); wl_surface_commit(wayland->backbuffer.surface);
@ -1373,8 +1377,6 @@ static void backbuffer_setup(struct _MwLLWayland* wayland) {
}; };
static void backbuffer_destroy(struct _MwLLWayland* wayland) { static void backbuffer_destroy(struct _MwLLWayland* wayland) {
buffer_destroy(&wayland->backbuffer); buffer_destroy(&wayland->backbuffer);
cairo_destroy(wayland->back_cairo);
cairo_surface_destroy(wayland->back_cs);
}; };
static void region_invalidate(MwLL handle) { static void region_invalidate(MwLL handle) {
@ -1751,15 +1753,6 @@ static void destroy_popup(MwLL r) {
r->wayland.configured = MwFALSE; r->wayland.configured = MwFALSE;
} }
static void clip(MwLL handle) {
MwLL parent = handle->wayland.parent;
if(parent && handle->wayland.type == MWLL_WAYLAND_SUBLEVEL) {
cairo_reset_clip(handle->wayland.front_cairo);
cairo_rectangle(handle->wayland.front_cairo, 0, 0, (parent->wayland.ww + handle->wayland.x), (parent->wayland.wh + handle->wayland.y));
cairo_clip(handle->wayland.front_cairo);
}
}
static void wl_logger(const char* fmt, va_list args) { static void wl_logger(const char* fmt, va_list args) {
vprintf(fmt, args); vprintf(fmt, args);
raise(SIGTRAP); raise(SIGTRAP);
@ -1966,7 +1959,7 @@ refresh:
static void MwLLBeginDrawImpl(MwLL handle) { static void MwLLBeginDrawImpl(MwLL handle) {
if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
handle->wayland.selected_cairo = handle->wayland.front_cairo; // handle->wayland.selected_cairo = handle->wayland.front_cairo;
return; return;
} }
@ -1974,34 +1967,34 @@ static void MwLLBeginDrawImpl(MwLL handle) {
int x; int x;
MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
cairo_set_line_width(handle->wayland.back_cairo, 4.0); // cairo_set_line_width(handle->wayland.back_cairo, 4.0);
for(x = 0; x < w; x++) { // for(x = 0; x < w; x++) {
float placeholder = (float)x / (float)w; // float placeholder = (float)x / (float)w;
cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25); // cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25);
cairo_move_to(handle->wayland.back_cairo, w - x, 0); // cairo_move_to(handle->wayland.back_cairo, w - x, 0);
cairo_line_to(handle->wayland.back_cairo, w - x, CSD_BORDER_FRAME_TOP); // cairo_line_to(handle->wayland.back_cairo, w - x, CSD_BORDER_FRAME_TOP);
cairo_stroke(handle->wayland.back_cairo); // cairo_stroke(handle->wayland.back_cairo);
cairo_move_to(handle->wayland.back_cairo, x, CSD_BORDER_FRAME_TOP); // cairo_move_to(handle->wayland.back_cairo, x, CSD_BORDER_FRAME_TOP);
cairo_line_to(handle->wayland.back_cairo, x, h); // cairo_line_to(handle->wayland.back_cairo, x, h);
cairo_stroke(handle->wayland.back_cairo); // cairo_stroke(handle->wayland.back_cairo);
} // }
cairo_set_source_rgba(handle->wayland.back_cairo, 1, 1, 1, 0.5); // cairo_set_source_rgba(handle->wayland.back_cairo, 1, 1, 1, 0.5);
cairo_move_to(handle->wayland.back_cairo, 0, 0); // cairo_move_to(handle->wayland.back_cairo, 0, 0);
cairo_line_to(handle->wayland.back_cairo, 0, h); // cairo_line_to(handle->wayland.back_cairo, 0, h);
cairo_stroke(handle->wayland.back_cairo); // cairo_stroke(handle->wayland.back_cairo);
cairo_move_to(handle->wayland.back_cairo, 0, 0); // cairo_move_to(handle->wayland.back_cairo, 0, 0);
cairo_line_to(handle->wayland.back_cairo, w, 0); // cairo_line_to(handle->wayland.back_cairo, w, 0);
cairo_stroke(handle->wayland.back_cairo); // cairo_stroke(handle->wayland.back_cairo);
cairo_set_source_rgba(handle->wayland.back_cairo, 0, 0, 0, 0.5); // cairo_set_source_rgba(handle->wayland.back_cairo, 0, 0, 0, 0.5);
cairo_move_to(handle->wayland.back_cairo, 0, h); // cairo_move_to(handle->wayland.back_cairo, 0, h);
cairo_line_to(handle->wayland.back_cairo, w, h); // cairo_line_to(handle->wayland.back_cairo, w, h);
cairo_stroke(handle->wayland.back_cairo); // cairo_stroke(handle->wayland.back_cairo);
cairo_move_to(handle->wayland.back_cairo, w, 0); // cairo_move_to(handle->wayland.back_cairo, w, 0);
cairo_line_to(handle->wayland.back_cairo, w, h); // cairo_line_to(handle->wayland.back_cairo, w, h);
cairo_stroke(handle->wayland.back_cairo); // cairo_stroke(handle->wayland.back_cairo);
if(strlen(handle->wayland.title) != 0) { if(strlen(handle->wayland.title) != 0) {
int y, x; int y, x;
@ -2017,7 +2010,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
memset(px, 0, tw * th * 4); memset(px, 0, tw * th * 4);
handle->wayland.selected_cairo = handle->wayland.back_cairo; // handle->wayland.selected_cairo = handle->wayland.back_cairo;
while(handle->wayland.title[i]) { while(handle->wayland.title[i]) {
int out; int out;
@ -2052,7 +2045,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
} }
update_buffer(handle, &handle->wayland.backbuffer); update_buffer(handle, &handle->wayland.backbuffer);
} }
handle->wayland.selected_cairo = handle->wayland.front_cairo; // handle->wayland.selected_cairo = handle->wayland.front_cairo;
} }
static void MwLLEndDrawImpl(MwLL handle) { static void MwLLEndDrawImpl(MwLL handle) {
@ -2065,44 +2058,43 @@ static void MwLLEndDrawImpl(MwLL handle) {
} }
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
int i; int i;
pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff};
pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * points_count);
pixman_image_t* image = pixman_image_create_solid_fill(&col);
memset(triangles, 0, sizeof(pixman_triangle_t) * points_count);
clip(handle); for(i = 0; i < points_count; i += 3) {
triangles[i].p1.x = pixman_double_to_fixed((double)points[i].x);
cairo_set_source_rgba(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); triangles[i].p1.y = pixman_double_to_fixed((double)points[i].y);
cairo_new_path(handle->wayland.front_cairo); triangles[i].p2.x = pixman_double_to_fixed((double)points[i + 1].x);
for(i = 0; i < points_count; i++) { triangles[i].p2.y = pixman_double_to_fixed((double)points[i + 1].y);
if(i == 0) { triangles[i].p3.x = pixman_double_to_fixed((double)points[i + 2].x);
cairo_move_to(handle->wayland.front_cairo, points[i].x, points[i].y); triangles[i].p3.y = pixman_double_to_fixed((double)points[i + 2].y);
} else {
cairo_line_to(handle->wayland.front_cairo, points[i].x, points[i].y);
}
} }
cairo_close_path(handle->wayland.front_cairo); pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb_back, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles);
cairo_fill(handle->wayland.front_cairo); pixman_image_unref(image);
handle->wayland.events_pending = 1; handle->wayland.events_pending = 1;
} }
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
int i; int i;
pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff};
pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * 3);
pixman_image_t* image = pixman_image_create_solid_fill(&col);
clip(handle); // for(i = 0; i < 3; i += 3) {
// triangles[i].p1.x = pixman_double_to_fixed((double)points[i].x);
// triangles[i].p1.y = pixman_double_to_fixed((double)points[i].y);
// triangles[i].p2.x = pixman_double_to_fixed((double)points[i + 1].x);
// triangles[i].p2.y = pixman_double_to_fixed((double)points[i + 1].y);
// triangles[i].p3.x = pixman_double_to_fixed((double)points[i].x);
// triangles[i].p3.y = pixman_double_to_fixed((double)points[i].y);
// }
cairo_set_antialias(handle->wayland.front_cairo, CAIRO_ANTIALIAS_NONE); pixman_image_unref(image);
cairo_set_line_cap(handle->wayland.front_cairo, CAIRO_LINE_CAP_SQUARE);
cairo_set_source_rgba(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
cairo_new_path(handle->wayland.front_cairo);
for(i = 0; i < 2; i++) {
if(i == 0) {
cairo_move_to(handle->wayland.front_cairo, points[i].x, points[i].y);
} else {
cairo_line_to(handle->wayland.front_cairo, points[i].x, points[i].y);
}
}
cairo_close_path(handle->wayland.front_cairo);
cairo_stroke(handle->wayland.front_cairo);
handle->wayland.events_pending = 1; handle->wayland.events_pending = 1;
} }
@ -2206,15 +2198,22 @@ static void MwLLSetTitleImpl(MwLL handle, const char* title) {
} }
static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) {
MwLLPixmap r = malloc(sizeof(*r)); MwLLPixmap r = malloc(sizeof(*r));
pixman_transform_t transform;
(void)handle; (void)handle;
int stride = width * 4;
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);
memcpy(r->common.raw, data, 4 * width * height); memcpy(r->common.raw, data, 4 * width * height);
r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); // pixman_transform_init_identity(&transform);
r->wayland.img = NULL;
// pixman_image_set_transform(r->wayland.img, &transform);
MwLLPixmapUpdate(r); MwLLPixmapUpdate(r);
@ -2224,54 +2223,33 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
static void MwLLPixmapUpdateImpl(MwLLPixmap r) { static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
int i; int i;
unsigned char* d; unsigned char* d;
if(r->wayland.img) {
cairo_surface_flush(r->wayland.cs); pixman_image_unref(r->wayland.img);
d = cairo_image_surface_get_data(r->wayland.cs);
for(i = 0; i < r->common.width * r->common.height * 4; i += 4) {
MwU32* p = (MwU32*)&d[i];
*p <<= 8;
*p |= r->common.raw[i + 3];
*p <<= 8;
*p |= r->common.raw[i + 0];
*p <<= 8;
*p |= r->common.raw[i + 1];
*p <<= 8;
*p |= r->common.raw[i + 2];
} }
cairo_surface_mark_dirty(r->wayland.cs); r->wayland.img = pixman_image_create_bits(PIXMAN_a8b8g8r8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4);
} }
static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
cairo_surface_destroy(pixmap->wayland.cs);
free(pixmap->common.raw); free(pixmap->common.raw);
free(pixmap); free(pixmap);
} }
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
cairo_t* c; int width, height;
cairo_surface_t* cs;
cairo_t* selected_cairo = handle->wayland.selected_cairo ? handle->wayland.selected_cairo : handle->wayland.front_cairo;
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height); width = pixman_image_get_width(pixmap->wayland.img);
c = cairo_create(cs); height = pixman_image_get_height(pixmap->wayland.img);
clip(handle); pixman_image_composite32(PIXMAN_OP_ATOP,
pixmap->wayland.img, /* src */
cairo_scale(c, (double)rect->width / pixmap->common.width, (double)rect->height / pixmap->common.height); NULL /* mask */,
handle->wayland.framebuffer.pixman_fb_back, /* dest */
cairo_set_source_surface(c, pixmap->wayland.cs, 0, 0); 0, 0, /* src_x, src_y */
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); 0, 0, /* mask_x, mask_y */
rect->x, rect->y, /* dest_x, dest_y */
cairo_paint(c); width, /* width */
height /* height */);
cairo_set_source_surface(selected_cairo, cs, rect->x, rect->y); return;
cairo_paint(selected_cairo);
cairo_destroy(c);
cairo_surface_destroy(cs);
MwLLForceRender(handle);
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
} }
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
@ -2579,16 +2557,12 @@ static int MwLLWaylandCallInitImpl(void) {
* - manually checking environment variables * - manually checking environment variables
*/ */
#ifdef __linux__ #ifdef __linux__
MwBool loadWayland; MwBool loadWayland = MwFALSE;
if(getenv("MILSKO_BACKEND")) { if(getenv("MILSKO_BACKEND")) {
loadWayland |= loadWayland =
(strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0); (strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0);
} } else if(getenv("WAYLAND_DISPLAY") && !loadWayland) {
if(getenv("XDG_SESSION_TYPE")) { loadWayland = (getenv("WAYLAND_DISPLAY") != NULL);
loadWayland |= (strcmp(getenv("XDG_SESSION_TYPE"), "wayland") == 0);
}
if(getenv("WAYLAND_DISPLAY")) {
loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL);
} }
if(loadWayland) { if(loadWayland) {

View file

@ -1278,14 +1278,10 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
static int MwLLX11CallInitImpl(void) { static int MwLLX11CallInitImpl(void) {
MwBool loadX11 = MwFALSE; MwBool loadX11 = MwFALSE;
if(getenv("MILSKO_BACKEND")) { if(getenv("MILSKO_BACKEND")) {
loadX11 |= loadX11 =
(strcmp(getenv("MILSKO_BACKEND"), "x11") == 0); (strcmp(getenv("MILSKO_BACKEND"), "x11") == 0);
} } else if(getenv("DISPLAY")) {
if(getenv("XDG_SESSION_TYPE")) { loadX11 = (getenv("DISPLAY") != NULL);
loadX11 |= (strcmp(getenv("XDG_SESSION_TYPE"), "x11") == 0);
}
if(getenv("DISPLAY")) {
loadX11 |= (getenv("DISPLAY") != NULL);
} }
if(!loadX11) { if(!loadX11) {