Unfinished Wayland PR #1
6 changed files with 310 additions and 119 deletions
wayland: give up on cairo and switch to OpenGL
commit
0adc98a2a2
|
|
@ -12,11 +12,14 @@
|
|||
#include <Mw/TypeDefs.h>
|
||||
#include <Mw/LowLevel.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>
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
MWDECL int MwLLWaylandCallInit(void);
|
||||
|
||||
#ifndef WL_PROTOCOLS_DEFINED
|
||||
|
|
@ -58,21 +61,6 @@ struct _MwLLWayland {
|
|||
MWLL_WAYLAND_SUBSURFACE = 1,
|
||||
} type;
|
||||
|
||||
struct wl_display* display;
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_subcompositor* subcompositor;
|
||||
struct wl_surface* surface;
|
||||
struct wl_shm* shm;
|
||||
struct wl_registry_listener registry_listener;
|
||||
|
||||
int mapped_buffer_size;
|
||||
|
||||
cairo_surface_t* cairo_surface;
|
||||
// cairo_t* cairo;
|
||||
|
||||
MwU8* mapped_buffer;
|
||||
|
||||
struct {
|
||||
const char* key;
|
||||
wl_setup_func* value;
|
||||
|
|
@ -83,9 +71,32 @@ struct _MwLLWayland {
|
|||
wayland_protocol_t* value;
|
||||
}* wl_protocol_map;
|
||||
|
||||
/*MwLL* subsurfaces;*/
|
||||
|
||||
struct wl_display* display;
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_subcompositor* subcompositor;
|
||||
struct wl_surface* surface;
|
||||
struct wl_shm* shm;
|
||||
struct wl_registry_listener registry_listener;
|
||||
// cairo_surface_t* cairo_surface;
|
||||
MwBool configured;
|
||||
MwBool force_redraw;
|
||||
MwBool do_clear;
|
||||
MwU32 x, y, ww, wh;
|
||||
|
||||
MwLL parent;
|
||||
|
||||
GLuint fbo;
|
||||
unsigned int fbo_texture;
|
||||
unsigned int rbo;
|
||||
|
||||
MwBool egl_setup;
|
||||
EGLNativeWindowType egl_window_native;
|
||||
EGLDisplay egl_display;
|
||||
EGLContext egl_context;
|
||||
EGLSurface egl_surface;
|
||||
};
|
||||
|
||||
struct _MwLLWaylandColor {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ if (grep(/^gdi$/, @backends)) {
|
|||
if (grep(/^wayland$/, @backends)) {
|
||||
add_cflags("-DUSE_WAYLAND");
|
||||
new_object("src/backend/wayland.c");
|
||||
add_libs("-lcairo -lwayland-client -lxkbcommon");
|
||||
add_libs("-lGL -lEGL -lwayland-egl -lwayland-client -lxkbcommon");
|
||||
|
||||
scan_wayland_protocol("stable", "xdg-shell","");
|
||||
scan_wayland_protocol("stable", "tablet","-v2");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* $Id$ */
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
|
@ -18,6 +19,17 @@
|
|||
#include "Mw/LowLevel.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <wayland-egl-core.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||
PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
|
||||
// PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
|
||||
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
|
||||
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
||||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatus;
|
||||
|
||||
#define WAYLAND_GET_INTERFACE(r, inter) shget(r.wl_protocol_map, inter##_interface.name)
|
||||
|
||||
|
|
@ -57,57 +69,8 @@ static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland
|
|||
wayland->shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1);
|
||||
return NULL;
|
||||
}
|
||||
static void buffer_setup(struct _MwLLWayland* wayland) {
|
||||
struct wl_shm_pool* pool;
|
||||
struct wl_buffer* buffer;
|
||||
int x, y;
|
||||
int stride = wayland->ww * 4;
|
||||
|
||||
int fd;
|
||||
MwU32 size = wayland->ww * wayland->wh * 4;
|
||||
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX";
|
||||
|
||||
fd = mkstemp(temp_name);
|
||||
|
||||
unlink(temp_name);
|
||||
|
||||
if(posix_fallocate(fd, 0, size) != 0) {
|
||||
printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno));
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
if(ftruncate(fd, size) != 0) {
|
||||
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
wayland->mapped_buffer = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
memset(wayland->mapped_buffer, 0xFF, size);
|
||||
// wayland->mapped_buffer_size = size;
|
||||
|
||||
wayland->cairo_surface = cairo_image_surface_create_for_data(wayland->mapped_buffer,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
wayland->ww,
|
||||
wayland->wh,
|
||||
stride);
|
||||
|
||||
fsync(fd);
|
||||
|
||||
if(!(pool = wl_shm_create_pool(wayland->shm, fd, size))) {
|
||||
printf("failure setting up wl_shm: could not create pool.\n");
|
||||
}
|
||||
|
||||
buffer = wl_shm_pool_create_buffer(pool, 0, wayland->ww, wayland->wh, stride, WL_SHM_FORMAT_ARGB8888);
|
||||
|
||||
if(wayland->configured) {
|
||||
wl_surface_attach(wayland->surface, buffer, 0, 0);
|
||||
wl_surface_commit(wayland->surface);
|
||||
}
|
||||
wl_buffer_destroy(buffer);
|
||||
wl_shm_pool_destroy(pool);
|
||||
close(fd);
|
||||
}
|
||||
// static void buffer_setup(struct _MwLLWayland* wayland) {
|
||||
// }
|
||||
|
||||
static wayland_protocol_t* wl_seat_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
||||
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
|
||||
|
|
@ -174,20 +137,171 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _
|
|||
return proto;
|
||||
}
|
||||
|
||||
static MwBool egl_setup(MwLL self, int width, int height) {
|
||||
int err;
|
||||
EGLint numConfigs;
|
||||
EGLint majorVersion;
|
||||
EGLint minorVersion;
|
||||
EGLContext context;
|
||||
EGLSurface surface;
|
||||
EGLConfig config;
|
||||
EGLint fbAttribs[] =
|
||||
{
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE};
|
||||
EGLint contextAttribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||
EGL_CONTEXT_MAJOR_VERSION, 1,
|
||||
EGL_CONTEXT_MINOR_VERSION, 1,
|
||||
EGL_NONE};
|
||||
|
||||
EGLDisplay display = eglGetDisplay(self->wayland.display);
|
||||
if(display == EGL_NO_DISPLAY) {
|
||||
printf("ERROR: eglGetDisplay, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
// Initialize EGL
|
||||
if(!eglInitialize(display, &majorVersion, &minorVersion)) {
|
||||
printf("ERROR: eglInitialize, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
// Get configs
|
||||
if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) || (numConfigs == 0)) {
|
||||
printf("ERROR: eglGetConfigs, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
// Choose config
|
||||
if((eglChooseConfig(display, fbAttribs, &config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
|
||||
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
self->wayland.egl_window_native =
|
||||
wl_egl_window_create(self->wayland.surface, width, height);
|
||||
if(self->wayland.egl_window_native == EGL_NO_SURFACE) {
|
||||
printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n");
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
// Create a surface
|
||||
surface = eglCreateWindowSurface(display, config, self->wayland.egl_window_native, NULL);
|
||||
if(surface == EGL_NO_SURFACE) {
|
||||
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
// Create a GL context
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if(context == EGL_NO_CONTEXT) {
|
||||
printf("ERROR: eglCreateContext, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
// Make the context current
|
||||
if(!eglMakeCurrent(display, surface, surface, context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)eglGetProcAddress("glGenFramebuffers");
|
||||
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)eglGetProcAddress("glFramebufferTexture2D");
|
||||
glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)eglGetProcAddress("glGenRenderbuffers");
|
||||
// glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)eglGetProcAddress("glRenderbufferStorage");
|
||||
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)eglGetProcAddress("glFramebufferRenderbuffer");
|
||||
glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)eglGetProcAddress("glBindRenderbuffer");
|
||||
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)eglGetProcAddress("glBindFramebuffer");
|
||||
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)eglGetProcAddress("glCheckFramebufferStatus");
|
||||
|
||||
glGenTextures(1, &self->wayland.fbo_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, self->wayland.fbo_texture);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glGenRenderbuffers(1, &self->wayland.rbo);
|
||||
// glBindRenderbuffer(GL_RENDERBUFFER, self->wayland.rbo));
|
||||
// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 768, 1024);
|
||||
// glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
glGenFramebuffers(1, &self->wayland.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, self->wayland.fbo);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->wayland.fbo_texture, 0);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self->wayland.rbo);
|
||||
|
||||
if((err = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
printf("Error binding framebuffer: %0X\n", err);
|
||||
return MwFALSE;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, 0);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, height, -13, -1, 1);
|
||||
|
||||
self->wayland.egl_display = display;
|
||||
self->wayland.egl_surface = surface;
|
||||
self->wayland.egl_context = context;
|
||||
printf("EGL success\n");
|
||||
return MwTRUE;
|
||||
}
|
||||
|
||||
static void xdg_toplevel_configure(void* data,
|
||||
struct xdg_toplevel* xdg_toplevel,
|
||||
MwI32 width, MwI32 height,
|
||||
struct wl_array* states) {
|
||||
MwLL self = data;
|
||||
MwLL self = data;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)eglGetProcAddress("glFramebufferTexture2D");
|
||||
|
||||
if(width != 0 && height != 0) {
|
||||
self->wayland.ww = width;
|
||||
self->wayland.wh = height;
|
||||
xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, self->wayland.x, self->wayland.y, self->wayland.ww, self->wayland.wh);
|
||||
if(width == 0 && height == 0) {
|
||||
width = self->wayland.ww;
|
||||
height = self->wayland.wh;
|
||||
}
|
||||
self->wayland.ww = width;
|
||||
self->wayland.wh = height;
|
||||
xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, self->wayland.x, self->wayland.y, self->wayland.ww, self->wayland.wh);
|
||||
|
||||
MwLLSetWH(self, width, height);
|
||||
MwLLDispatch(self, resize, NULL);
|
||||
};
|
||||
MwLLSetWH(self, width, height);
|
||||
MwLLDispatch(self, resize, NULL);
|
||||
|
||||
if(!self->wayland.egl_setup) {
|
||||
self->wayland.egl_setup = egl_setup(self, width, height);
|
||||
} else {
|
||||
wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, height, -13, -1, 1);
|
||||
self->wayland.do_clear = MwTRUE;
|
||||
|
||||
// glDeleteTextures(1, &self->wayland.fbo_texture);
|
||||
// glGenTextures(1, &self->wayland.fbo_texture);
|
||||
// glBindTexture(GL_TEXTURE_2D, self->wayland.fbo_texture);
|
||||
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
MwLLForceRender(self);
|
||||
|
||||
|
|
@ -335,7 +449,7 @@ static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
|||
printf("zxdg null\n");
|
||||
}
|
||||
|
||||
buffer_setup(&r->wayland);
|
||||
// buffer_setup(&r->wayland);
|
||||
|
||||
wl_surface_commit(r->wayland.surface);
|
||||
}
|
||||
|
|
@ -369,23 +483,34 @@ static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int h
|
|||
return;
|
||||
}
|
||||
|
||||
// arrpush(parent->wayland.subsurfaces, r);
|
||||
|
||||
r->wayland.configured = MwTRUE;
|
||||
|
||||
r->wayland.egl_context = parent->wayland.egl_context;
|
||||
r->wayland.egl_display = parent->wayland.egl_display;
|
||||
r->wayland.egl_surface = parent->wayland.egl_surface;
|
||||
r->wayland.fbo = parent->wayland.fbo;
|
||||
r->wayland.fbo_texture = parent->wayland.fbo_texture;
|
||||
r->wayland.rbo = parent->wayland.rbo;
|
||||
}
|
||||
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||
MwLL r;
|
||||
r = malloc(sizeof(*r));
|
||||
MwLLCreateCommon(r);
|
||||
|
||||
// r->common.copy_buffer = 1;
|
||||
r->common.type = MwLLBackendWayland;
|
||||
|
||||
if(width == 0) width = parent->wayland.ww;
|
||||
if(height == 0) height = parent->wayland.wh;
|
||||
if(width == 0) width = 1;
|
||||
if(height == 0) height = 1;
|
||||
|
||||
r->wayland.ww = width;
|
||||
r->wayland.wh = height;
|
||||
r->wayland.ww = width;
|
||||
r->wayland.wh = height;
|
||||
r->wayland.parent = parent;
|
||||
|
||||
r->common.success = MwTRUE;
|
||||
r->wayland.force_redraw = MwFALSE;
|
||||
r->wayland.do_clear = MwFALSE;
|
||||
r->common.success = MwTRUE;
|
||||
|
||||
if(parent == NULL) {
|
||||
setup_toplevel(r, x, y, width, height);
|
||||
|
|
@ -393,7 +518,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|||
setup_subsurface(parent, r, x, y, width, height);
|
||||
}
|
||||
|
||||
buffer_setup(&r->wayland);
|
||||
// buffer_setup(&r->wayland);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
@ -412,6 +537,13 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
|
|||
}
|
||||
|
||||
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
||||
|
||||
if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
handle->wayland.x = x;
|
||||
handle->wayland.y = y;
|
||||
wl_subsurface_set_position(handle->wayland.subsurface, x, y);
|
||||
MwLLForceRender(handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||
|
|
@ -421,45 +553,82 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
|||
if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, handle->wayland.x, handle->wayland.y, handle->wayland.ww, handle->wayland.wh);
|
||||
} else {
|
||||
// setup the buffer again with the new size.
|
||||
// buffer_setup(&handle->wayland);
|
||||
}
|
||||
}
|
||||
|
||||
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||
int i = 0;
|
||||
/*
|
||||
* TODO: this function sucks shit, ioi needs to make it not suck shit :)
|
||||
*/
|
||||
int i;
|
||||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)eglGetProcAddress("glBindFramebuffer");
|
||||
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)eglGetProcAddress("glBindRenderbuffer");
|
||||
int w, h;
|
||||
|
||||
cairo_t* cairo = cairo_create(handle->wayland.cairo_surface);
|
||||
cairo_set_source_rgb(cairo, color->common.red / 255., color->common.green / 255., color->common.blue / 255.);
|
||||
cairo_set_line_width(cairo, 0.1);
|
||||
cairo_set_fill_rule(cairo, CAIRO_FILL_RULE_EVEN_ODD);
|
||||
|
||||
cairo_new_path(cairo);
|
||||
for(; i < points_count; i++) {
|
||||
cairo_line_to(cairo, points[i].x, points[i].y);
|
||||
if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
w = handle->wayland.ww;
|
||||
h = handle->wayland.wh;
|
||||
} else {
|
||||
MwLL parent = handle->wayland.parent;
|
||||
while(parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
parent = parent->wayland.parent;
|
||||
}
|
||||
w = parent->wayland.ww;
|
||||
h = parent->wayland.wh;
|
||||
}
|
||||
cairo_close_path(cairo);
|
||||
|
||||
// cairo_paint(cairo);
|
||||
cairo_stroke_preserve(cairo);
|
||||
cairo_fill(cairo);
|
||||
cairo_destroy(cairo);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, handle->wayland.fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(i = 0; i < points_count; i++) {
|
||||
glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0);
|
||||
glVertex2f(
|
||||
(handle->wayland.x + points[i].x),
|
||||
(handle->wayland.y + points[i].y));
|
||||
|
||||
if((i % 3) == 0 && i != 0) {
|
||||
glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0);
|
||||
glVertex2f(
|
||||
(handle->wayland.x + points[i].x),
|
||||
(handle->wayland.y + points[i].y));
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glFinish();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 1);
|
||||
glVertex2f(0, 0);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(w, 0);
|
||||
glTexCoord2f(1, 0.0f);
|
||||
glVertex2f(w, h);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(0, h);
|
||||
glEnd();
|
||||
glFinish();
|
||||
|
||||
if(!eglSwapBuffers(handle->wayland.egl_display, handle->wayland.egl_surface)) {
|
||||
printf("error swapping buffers! %0X\n", eglGetError());
|
||||
} else {
|
||||
wl_surface_commit(handle->wayland.surface);
|
||||
}
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
handle->wayland.do_clear = MwFALSE;
|
||||
}
|
||||
|
||||
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
||||
MwPoint p1 = points[0];
|
||||
MwPoint p2 = points[1];
|
||||
int i;
|
||||
|
||||
cairo_t* cairo = cairo_create(handle->wayland.cairo_surface);
|
||||
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_line_width(cairo, 1);
|
||||
cairo_set_source_rgb(cairo, color->common.red / 255., color->common.green / 255., color->common.blue / 255.);
|
||||
cairo_paint(cairo);
|
||||
|
||||
cairo_move_to(cairo, p1.x, p1.y);
|
||||
cairo_line_to(cairo, p2.x, p2.y);
|
||||
cairo_fill(cairo);
|
||||
cairo_destroy(cairo);
|
||||
//
|
||||
}
|
||||
|
||||
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
|
||||
|
|
@ -536,9 +705,7 @@ static int MwLLPendingImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
static void MwLLNextEventImpl(MwLL handle) {
|
||||
MwBool render;
|
||||
|
||||
render = handle->wayland.force_redraw;
|
||||
MwBool render = handle->wayland.force_redraw;
|
||||
|
||||
if(render) {
|
||||
int x, y;
|
||||
|
|
@ -580,9 +747,16 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
|||
}
|
||||
|
||||
static void MwLLForceRenderImpl(MwLL handle) {
|
||||
// event_loop(handle);
|
||||
wl_surface_damage(handle->wayland.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
|
||||
if(handle->wayland.egl_setup) {
|
||||
if(!eglSwapBuffers(handle->wayland.egl_display, handle->wayland.egl_surface)) {
|
||||
printf("error swapping buffers! %0X\n", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
wl_surface_commit(handle->wayland.surface);
|
||||
|
||||
handle->wayland.force_redraw = MwTRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ static XVisualInfo* get_visual_info(Display* display) {
|
|||
}
|
||||
|
||||
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||
printf("%d %d\n", width, height);
|
||||
MwLL r;
|
||||
Window p;
|
||||
XVisualInfo* xvi;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
#include "../external/stb_ds.h"
|
||||
#include "Mw/LowLevel.h"
|
||||
|
||||
static void lldrawhandler(MwLL handle, void* data) {
|
||||
MwWidget h = (MwWidget)handle->common.user;
|
||||
|
|
@ -295,6 +297,7 @@ int MwStep(MwWidget handle) {
|
|||
arrfree(widgets);
|
||||
|
||||
handle->prop_event = 0;
|
||||
|
||||
if(handle->lowlevel != NULL && MwLLPending(handle->lowlevel))
|
||||
MwLLNextEvent(handle->lowlevel);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* $Id$ */
|
||||
#include "Mw/LowLevel.h"
|
||||
#include <Mw/Milsko.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
@ -485,6 +486,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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue