Compare commits
15 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 70c9d3a1f6 | |||
| f2afa16bfa | |||
| d3f2054bab | |||
| ba917c8b13 | |||
| 41a874432d | |||
| 709067c742 | |||
| 9960f7e7ef | |||
| 46c4e98506 | |||
| 94ace21566 | |||
| afb46f173a | |||
| c8e4d44e3e | |||
| 5462103815 | |||
| 3ce1cb88f6 | |||
| ec2c128c7c | |||
| 6f6b08c0f5 |
4 changed files with 254 additions and 312 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef __MW_LOWLEVEL_WAYLAND_H__
|
||||
#define __MW_LOWLEVEL_WAYLAND_H__
|
||||
|
||||
#include "pixman.h"
|
||||
#include <Mw/MachDep.h>
|
||||
#include <Mw/TypeDefs.h>
|
||||
#include <Mw/LowLevel.h>
|
||||
|
|
@ -34,7 +35,6 @@ struct _MwLLWayland;
|
|||
typedef struct wayland_call_table {
|
||||
void* lib;
|
||||
void* xkb_lib;
|
||||
void* cairo_lib;
|
||||
#if WAYLAND_LOAD_OPENGL
|
||||
#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);
|
||||
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;
|
||||
|
||||
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");
|
||||
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) \
|
||||
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.lib, #x); \
|
||||
if(!wl_call_tbl.x) { \
|
||||
|
|
@ -187,42 +125,6 @@ MwInline int wayland_load_funcs() {
|
|||
XKB_FUNC(xkb_state_key_get_layout)
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
@ -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_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
|
||||
#define WL_PROTOCOLS_DEFINED
|
||||
#include "Wayland/wayland-core-protocol.h"
|
||||
|
|
@ -342,17 +216,18 @@ struct _MwLLWaylandShmBuffer {
|
|||
struct wl_shm* shm;
|
||||
struct wl_shm_pool* shm_pool;
|
||||
struct wl_buffer* shm_buffer;
|
||||
struct wl_shm_pool* shm_pool_back;
|
||||
struct wl_buffer* shm_buffer_back;
|
||||
struct wl_surface* surface;
|
||||
struct wl_output* output;
|
||||
|
||||
MwU8* buf;
|
||||
MwU8* buf_back;
|
||||
MwU32* buf;
|
||||
MwU32* buf_back;
|
||||
MwU64 buf_size;
|
||||
int fd;
|
||||
int fd_back;
|
||||
MwBool setup;
|
||||
|
||||
// pixman_image_t* pixman_fb_front;
|
||||
pixman_image_t* pixman_fb;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
enum _MwLLWaylandType {
|
||||
|
|
@ -493,13 +368,6 @@ struct _MwLLWayland {
|
|||
uint32_t last_time;
|
||||
|
||||
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 {
|
||||
|
|
@ -509,7 +377,7 @@ struct _MwLLWaylandColor {
|
|||
struct _MwLLWaylandPixmap {
|
||||
struct _MwLLCommonPixmap common;
|
||||
|
||||
cairo_surface_t* cs;
|
||||
pixman_image_t* img;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ if (grep(/^wayland$/, @backends)) {
|
|||
add_cflags("-DWAYLAND_LOAD_OPENGL");
|
||||
}
|
||||
|
||||
add_cflags("-I/usr/include/pixman-1");
|
||||
add_libs("-lpixman-1");
|
||||
|
||||
scan_wayland_protocol_core();
|
||||
scan_wayland_protocol("stable", "xdg-shell", "");
|
||||
scan_wayland_protocol("stable", "viewporter", "");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include "../../external/stb_ds.h"
|
||||
#include "pixman.h"
|
||||
|
||||
/* TODO: find out what FreeBSD and such wants us to include */
|
||||
#ifdef __FreeBSD__
|
||||
|
|
@ -68,8 +69,6 @@ static void new_protocol(void* data, struct wl_registry* registry,
|
|||
/* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */
|
||||
} else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) {
|
||||
self->common.supports_transparency = MwTRUE;
|
||||
} else {
|
||||
// printf("unknown interface %s\n", interface);
|
||||
}
|
||||
|
||||
WAYLAND_EVENT_OP_END(self);
|
||||
|
|
@ -1262,8 +1261,10 @@ static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_proto
|
|||
static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
|
||||
(void)self;
|
||||
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
|
||||
// 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_commit(buffer->surface);
|
||||
}
|
||||
|
||||
|
|
@ -1272,10 +1273,9 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3
|
|||
char temp_name[] = "/tmp/milsko-wl-shm-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_back = mkstemp(temp_name_back);
|
||||
|
||||
unlink(temp_name);
|
||||
unlink(temp_name_back);
|
||||
|
|
@ -1285,36 +1285,28 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3
|
|||
close(buffer->fd);
|
||||
return;
|
||||
}
|
||||
if(posix_fallocate(buffer->fd_back, 0, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno));
|
||||
close(buffer->fd_back);
|
||||
return;
|
||||
}
|
||||
if(ftruncate(buffer->fd, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||
close(buffer->fd);
|
||||
return;
|
||||
}
|
||||
if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) {
|
||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||
close(buffer->fd_back);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
||||
buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0);
|
||||
buffer->buf_back = malloc(buffer->buf_size);
|
||||
|
||||
fsync(buffer->fd);
|
||||
fsync(buffer->fd_back);
|
||||
|
||||
if(!(buffer->shm_pool = wl_shm_create_pool(buffer->shm, buffer->fd, buffer->buf_size))) {
|
||||
printf("failure setting up wl_shm: could not create pool.\n");
|
||||
}
|
||||
if(!(buffer->shm_pool_back = wl_shm_create_pool(buffer->shm, buffer->fd_back, buffer->buf_size))) {
|
||||
printf("failure setting up wl_shm: could not create pool.\n");
|
||||
}
|
||||
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->pixman_fb = pixman_image_create_bits(PIXMAN_a8r8g8b8,
|
||||
width, height, buffer->buf_back, stride);
|
||||
|
||||
buffer->width = width;
|
||||
buffer->height = height;
|
||||
|
||||
buffer->setup = MwTRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1323,20 +1315,18 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) {
|
|||
return;
|
||||
}
|
||||
if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer);
|
||||
if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back);
|
||||
if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool);
|
||||
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
|
||||
munmap(buffer->buf, buffer->buf_size);
|
||||
free(buffer->buf_back);
|
||||
close(buffer->fd);
|
||||
close(buffer->fd_back);
|
||||
pixman_image_unref(buffer->pixman_fb);
|
||||
|
||||
buffer->setup = MwFALSE;
|
||||
}
|
||||
|
||||
static void framebuffer_setup(struct _MwLLWayland* wayland) {
|
||||
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);
|
||||
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
|
||||
wl_surface_commit(wayland->framebuffer.surface);
|
||||
|
|
@ -1346,8 +1336,6 @@ static void framebuffer_setup(struct _MwLLWayland* wayland) {
|
|||
};
|
||||
static void framebuffer_destroy(struct _MwLLWayland* wayland) {
|
||||
buffer_destroy(&wayland->framebuffer);
|
||||
cairo_destroy(wayland->front_cairo);
|
||||
cairo_surface_destroy(wayland->front_cs);
|
||||
};
|
||||
|
||||
static void backbuffer_setup(struct _MwLLWayland* wayland) {
|
||||
|
|
@ -1362,9 +1350,6 @@ static void backbuffer_setup(struct _MwLLWayland* wayland) {
|
|||
}
|
||||
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);
|
||||
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
|
||||
wl_surface_commit(wayland->backbuffer.surface);
|
||||
|
|
@ -1373,8 +1358,6 @@ static void backbuffer_setup(struct _MwLLWayland* wayland) {
|
|||
};
|
||||
static void backbuffer_destroy(struct _MwLLWayland* wayland) {
|
||||
buffer_destroy(&wayland->backbuffer);
|
||||
cairo_destroy(wayland->back_cairo);
|
||||
cairo_surface_destroy(wayland->back_cs);
|
||||
};
|
||||
|
||||
static void region_invalidate(MwLL handle) {
|
||||
|
|
@ -1751,15 +1734,6 @@ static void destroy_popup(MwLL r) {
|
|||
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) {
|
||||
vprintf(fmt, args);
|
||||
raise(SIGTRAP);
|
||||
|
|
@ -1866,7 +1840,6 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
pthread_mutex_unlock(&handle->wayland.eventsMutex);
|
||||
pthread_mutex_destroy(&handle->wayland.eventsMutex);
|
||||
|
||||
// framebuffer_destroy(&handle->wayland);
|
||||
buffer_destroy(&handle->wayland.cursor);
|
||||
wl_region_destroy(handle->wayland.region);
|
||||
|
||||
|
|
@ -1966,7 +1939,6 @@ refresh:
|
|||
|
||||
static void MwLLBeginDrawImpl(MwLL handle) {
|
||||
if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
handle->wayland.selected_cairo = handle->wayland.front_cairo;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1974,7 +1946,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|||
int x;
|
||||
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;
|
||||
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++) {
|
||||
float placeholder = (float)x / (float)w;
|
||||
cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25);
|
||||
|
|
@ -2001,7 +1973,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|||
cairo_stroke(handle->wayland.back_cairo);
|
||||
cairo_move_to(handle->wayland.back_cairo, w, 0);
|
||||
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) {
|
||||
int y, x;
|
||||
|
|
@ -2017,8 +1989,6 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|||
|
||||
memset(px, 0, tw * th * 4);
|
||||
|
||||
handle->wayland.selected_cairo = handle->wayland.back_cairo;
|
||||
|
||||
while(handle->wayland.title[i]) {
|
||||
int out;
|
||||
i += MwUTF8ToUTF32(handle->wayland.title + i, &out);
|
||||
|
|
@ -2052,7 +2022,6 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|||
}
|
||||
update_buffer(handle, &handle->wayland.backbuffer);
|
||||
}
|
||||
handle->wayland.selected_cairo = handle->wayland.front_cairo;
|
||||
}
|
||||
|
||||
static void MwLLEndDrawImpl(MwLL handle) {
|
||||
|
|
@ -2063,46 +2032,155 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
|||
update_buffer(handle, &handle->wayland.framebuffer);
|
||||
}
|
||||
}
|
||||
typedef struct pointf64 {
|
||||
double x;
|
||||
double y;
|
||||
} pointf64_t;
|
||||
|
||||
pixman_triangle_t* triangulate_polygon(pointf64_t* poly_points, int poly_points_count, int* tri_count_out) {
|
||||
pixman_triangle_t* tris;
|
||||
int* indices;
|
||||
double ax, ay, bx, by, cx, cy, cross;
|
||||
double px, py, d0x, d0y, d1x, d1y, d2x, d2y;
|
||||
double t, u;
|
||||
int n, i, j, prev, curr, next, count;
|
||||
MwBool ear_found, is_ear;
|
||||
|
||||
*tri_count_out = 0;
|
||||
|
||||
if(!poly_points || poly_points_count < 3) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = poly_points_count;
|
||||
indices = malloc(n * sizeof(int));
|
||||
if(!indices) {
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < n; i++) {
|
||||
indices[i] = i;
|
||||
}
|
||||
|
||||
tris = malloc((n - 2) * sizeof(pixman_triangle_t));
|
||||
if(!tris) {
|
||||
free(indices);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while(n > 2) {
|
||||
ear_found = MwFALSE;
|
||||
|
||||
for(i = 0; i < n; i++) {
|
||||
prev = (i + n - 1) % n;
|
||||
curr = i;
|
||||
next = (i + 1) % n;
|
||||
ax = (double)poly_points[indices[prev]].x;
|
||||
ay = (double)poly_points[indices[prev]].y;
|
||||
bx = (double)poly_points[indices[curr]].x;
|
||||
by = (double)poly_points[indices[curr]].y;
|
||||
cx = (double)poly_points[indices[next]].x;
|
||||
cy = (double)poly_points[indices[next]].y;
|
||||
|
||||
cross = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
|
||||
if(cross <= 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
is_ear = MwTRUE;
|
||||
for(j = 0; j < n; j++) {
|
||||
if(j == prev || j == curr || j == next) {
|
||||
continue;
|
||||
}
|
||||
|
||||
px = (double)poly_points[indices[j]].x;
|
||||
py = (double)poly_points[indices[j]].y;
|
||||
d0x = cx - ax;
|
||||
d0y = cy - ay;
|
||||
d1x = bx - ax;
|
||||
d1y = by - ay;
|
||||
d2x = px - ax;
|
||||
d2y = py - ay;
|
||||
t = (d0x * d2y - d0y * d2x) / (d0x * d1y - d0y * d1x + 1e-10);
|
||||
u = (d1x * d2y - d1y * d2x) / (d0x * d1y - d0y * d1x + 1e-10);
|
||||
if(t >= 0.0 && u >= 0.0 && (t + u) <= 1.0) {
|
||||
is_ear = MwFALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_ear) {
|
||||
pixman_triangle_t* tri;
|
||||
|
||||
tri = &tris[count++];
|
||||
tri->p1.x = pixman_double_to_fixed(poly_points[indices[prev]].x);
|
||||
tri->p1.y = pixman_double_to_fixed(poly_points[indices[prev]].y);
|
||||
tri->p2.x = pixman_double_to_fixed(poly_points[indices[curr]].x);
|
||||
tri->p2.y = pixman_double_to_fixed(poly_points[indices[curr]].y);
|
||||
tri->p3.x = pixman_double_to_fixed(poly_points[indices[next]].x);
|
||||
tri->p3.y = pixman_double_to_fixed(poly_points[indices[next]].y);
|
||||
|
||||
for(j = curr; j < n - 1; j++) {
|
||||
indices[j] = indices[j + 1];
|
||||
}
|
||||
|
||||
n--;
|
||||
ear_found = MwTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ear_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(indices);
|
||||
|
||||
if(count == 0) {
|
||||
free(tris);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(count < poly_points_count - 2) {
|
||||
pixman_triangle_t* shrunk;
|
||||
|
||||
shrunk = realloc(tris, count * sizeof(pixman_triangle_t));
|
||||
if(shrunk) {
|
||||
tris = shrunk;
|
||||
}
|
||||
}
|
||||
|
||||
*tri_count_out = count;
|
||||
return tris;
|
||||
}
|
||||
|
||||
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||
int i;
|
||||
|
||||
clip(handle);
|
||||
|
||||
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);
|
||||
int n, i;
|
||||
pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff};
|
||||
pixman_image_t* image = pixman_image_create_solid_fill(&col);
|
||||
pixman_triangle_t* triangles;
|
||||
pointf64_t* f64points = malloc(points_count * sizeof(pointf64_t));
|
||||
for(i = 0; i < points_count; 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);
|
||||
f64points[i].x = points[i].x;
|
||||
f64points[i].y = points[i].y;
|
||||
}
|
||||
}
|
||||
cairo_close_path(handle->wayland.front_cairo);
|
||||
triangles = triangulate_polygon(f64points, points_count, &n);
|
||||
|
||||
cairo_fill(handle->wayland.front_cairo);
|
||||
pixman_composite_triangles(PIXMAN_OP_OVER, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, n, triangles);
|
||||
|
||||
free(triangles);
|
||||
pixman_image_unref(image);
|
||||
|
||||
handle->wayland.events_pending = 1;
|
||||
}
|
||||
|
||||
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
||||
int i;
|
||||
pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff};
|
||||
pixman_image_t* image = pixman_image_create_solid_fill(&col);
|
||||
|
||||
clip(handle);
|
||||
|
||||
cairo_set_antialias(handle->wayland.front_cairo, CAIRO_ANTIALIAS_NONE);
|
||||
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);
|
||||
pixman_image_unref(image);
|
||||
|
||||
handle->wayland.events_pending = 1;
|
||||
}
|
||||
|
|
@ -2207,14 +2285,17 @@ 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));
|
||||
pixman_transform_t transform;
|
||||
|
||||
(void)handle;
|
||||
int stride = width * 4;
|
||||
|
||||
r->common.width = width;
|
||||
r->common.height = height;
|
||||
r->common.raw = malloc(4 * width * height);
|
||||
memcpy(r->common.raw, data, 4 * width * height);
|
||||
|
||||
r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
||||
r->wayland.img = NULL;
|
||||
|
||||
MwLLPixmapUpdate(r);
|
||||
|
||||
|
|
@ -2224,52 +2305,41 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
|
|||
static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
|
||||
int i;
|
||||
unsigned char* d;
|
||||
|
||||
cairo_surface_flush(r->wayland.cs);
|
||||
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];
|
||||
if(r->wayland.img) {
|
||||
pixman_image_unref(r->wayland.img);
|
||||
}
|
||||
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) {
|
||||
cairo_surface_destroy(pixmap->wayland.cs);
|
||||
free(pixmap->common.raw);
|
||||
free(pixmap);
|
||||
}
|
||||
|
||||
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||
cairo_t* c;
|
||||
cairo_surface_t* cs;
|
||||
cairo_t* selected_cairo = handle->wayland.selected_cairo ? handle->wayland.selected_cairo : handle->wayland.front_cairo;
|
||||
int width, height;
|
||||
pixman_transform_t transform;
|
||||
pixman_transform_t reverse;
|
||||
|
||||
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height);
|
||||
c = cairo_create(cs);
|
||||
pixman_transform_init_identity(&transform);
|
||||
|
||||
clip(handle);
|
||||
pixman_transform_scale(&transform, &reverse, pixman_double_to_fixed((double)pixmap->common.width / (double)rect->width), pixman_double_to_fixed((double)pixmap->common.height / (double)rect->height));
|
||||
|
||||
cairo_scale(c, (double)rect->width / pixmap->common.width, (double)rect->height / pixmap->common.height);
|
||||
pixman_image_set_transform(pixmap->wayland.img, &transform);
|
||||
|
||||
cairo_set_source_surface(c, pixmap->wayland.cs, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
|
||||
width = pixman_image_get_width(pixmap->wayland.img);
|
||||
height = pixman_image_get_height(pixmap->wayland.img);
|
||||
|
||||
cairo_paint(c);
|
||||
|
||||
cairo_set_source_surface(selected_cairo, cs, rect->x, rect->y);
|
||||
cairo_paint(selected_cairo);
|
||||
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
pixman_image_composite(PIXMAN_OP_OVER,
|
||||
pixmap->wayland.img, /* src */
|
||||
NULL /* mask */,
|
||||
handle->wayland.framebuffer.pixman_fb, /* dest */
|
||||
0, 0, /* src_x, src_y */
|
||||
0, 0, /* mask_x, mask_y */
|
||||
rect->x, rect->y, /* dest_x, dest_y */
|
||||
rect->width, rect->height /* height */);
|
||||
|
||||
/* this seems worthless but this actually makes it a bit more responsive */
|
||||
MwLLForceRender(handle);
|
||||
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
}
|
||||
|
|
@ -2293,21 +2363,22 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
|||
}
|
||||
handle->wayland.icon->surface = wl_compositor_create_surface(handle->wayland.compositor);
|
||||
|
||||
buffer_setup(handle->wayland.icon, pixmap->common.width, pixmap->common.height);
|
||||
|
||||
wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0);
|
||||
wl_surface_commit(handle->wayland.icon->surface);
|
||||
|
||||
buffer_setup(handle->wayland.icon, pixmap->common.width, pixmap->common.height);
|
||||
|
||||
for(; i < size; i += 2) {
|
||||
handle->wayland.icon->buf_back[i] = pixmap->common.raw[i + 2];
|
||||
handle->wayland.icon->buf_back[i + 1] = pixmap->common.raw[i + 1];
|
||||
handle->wayland.icon->buf_back[i + 2] = pixmap->common.raw[i + 0];
|
||||
MwU32* data = pixman_image_get_data(pixmap->wayland.img);
|
||||
handle->wayland.icon->buf_back[i] = data[i + 2];
|
||||
handle->wayland.icon->buf_back[i + 1] = data[i + 1];
|
||||
handle->wayland.icon->buf_back[i + 2] = data[i + 0];
|
||||
handle->wayland.icon->buf_back[i + 3] = 255;
|
||||
}
|
||||
|
||||
if(handle->wayland.configured) update_buffer(handle, handle->wayland.icon);
|
||||
|
||||
xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1);
|
||||
xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer, 1);
|
||||
|
||||
xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon);
|
||||
}
|
||||
|
|
@ -2331,13 +2402,14 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
|||
wl_surface_destroy(handle->wayland.cursor.surface);
|
||||
}
|
||||
buffer_setup(&handle->wayland.cursor, image->width, image->height);
|
||||
memset(handle->wayland.cursor.buf_back, 0, handle->wayland.cursor.buf_size);
|
||||
memset(handle->wayland.cursor.buf_back, 255, handle->wayland.cursor.buf_size);
|
||||
|
||||
xs = -mask->x + image->x;
|
||||
ys = mask->height + mask->y;
|
||||
ys = image->height + image->y - ys;
|
||||
|
||||
for(y = 0; y < mask->height; y++) {
|
||||
/* currently broken */
|
||||
/* for(y = 0; y < mask->height; y++) {
|
||||
unsigned int d = mask->data[y];
|
||||
for(x = mask->width - 1; x >= 0; x--) {
|
||||
int idx = ((y * image->width) + x) * 4;
|
||||
|
|
@ -2361,18 +2433,17 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
|||
handle->wayland.cursor.buf_back[idx] = px;
|
||||
handle->wayland.cursor.buf_back[idx + 1] = px;
|
||||
handle->wayland.cursor.buf_back[idx + 2] = px;
|
||||
handle->wayland.cursor.buf_back[idx + 3] = px;
|
||||
d = d >> 1;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
handle->wayland.cursor.surface = wl_compositor_create_surface(handle->wayland.compositor);
|
||||
wl_surface_attach(handle->wayland.cursor.surface, handle->wayland.cursor.shm_buffer, 0, 0);
|
||||
wl_surface_commit(handle->wayland.cursor.surface);
|
||||
update_buffer(handle, &handle->wayland.cursor);
|
||||
|
||||
/* If there's currently a pointer, set it up. (Otherwise, it'll be setup during the pointer enter event) */
|
||||
if(handle->wayland.pointer != NULL) {
|
||||
// wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0);
|
||||
wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2578,12 +2649,12 @@ static int MwLLWaylandCallInitImpl(void) {
|
|||
* - manually checking environment variables
|
||||
*/
|
||||
#ifdef __linux__
|
||||
MwBool loadWayland;
|
||||
MwBool loadWayland = MwFALSE;
|
||||
if(getenv("MILSKO_BACKEND")) {
|
||||
loadWayland |=
|
||||
loadWayland =
|
||||
(strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0);
|
||||
} else if(getenv("WAYLAND_DISPLAY")) {
|
||||
loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL);
|
||||
} else if(getenv("WAYLAND_DISPLAY") && !loadWayland) {
|
||||
loadWayland = (getenv("WAYLAND_DISPLAY") != NULL);
|
||||
}
|
||||
|
||||
if(loadWayland) {
|
||||
|
|
|
|||
|
|
@ -1278,10 +1278,10 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
|
|||
static int MwLLX11CallInitImpl(void) {
|
||||
MwBool loadX11 = MwFALSE;
|
||||
if(getenv("MILSKO_BACKEND")) {
|
||||
loadX11 |=
|
||||
loadX11 =
|
||||
(strcmp(getenv("MILSKO_BACKEND"), "x11") == 0);
|
||||
} else if(getenv("DISPLAY")) {
|
||||
loadX11 |= (getenv("DISPLAY") != NULL);
|
||||
loadX11 = (getenv("DISPLAY") != NULL);
|
||||
}
|
||||
|
||||
if(!loadX11) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue