summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build2
-rw-r--r--src/background.c (renamed from src/png.c)8
-rw-r--r--src/background.h (renamed from src/png.h)0
-rw-r--r--src/client.h67
-rw-r--r--src/egl.c32
-rw-r--r--src/egl.h9
-rw-r--r--src/gl.c31
-rw-r--r--src/main.c294
8 files changed, 277 insertions, 166 deletions
diff --git a/meson.build b/meson.build
index 5439ee2..7f1439e 100644
--- a/meson.build
+++ b/meson.build
@@ -45,10 +45,10 @@ add_project_arguments(
sources = files(
'src/main.c',
+ 'src/background.c',
'src/egl.c',
'src/gl.c',
'src/log.c',
- 'src/png.c',
'src/xdg-shell-protocol.c',
)
diff --git a/src/png.c b/src/background.c
index af96c8f..68beb5e 100644
--- a/src/png.c
+++ b/src/background.c
@@ -4,7 +4,7 @@
#include <png.h>
#include "client.h"
#include "log.h"
-#include "png.h"
+#include "background.h"
#define HEADER_BYTES 8
@@ -85,7 +85,7 @@ void load_background(struct client_state *state, const char *filename)
free(row_pointers);
fclose(fp);
- state->background_image.width = width;
- state->background_image.height = height;
- state->background_image.buffer = buffer;
+ state->window.background_image.width = width;
+ state->window.background_image.height = height;
+ state->window.background_image.buffer = buffer;
}
diff --git a/src/png.h b/src/background.h
index 68b432a..68b432a 100644
--- a/src/png.h
+++ b/src/background.h
diff --git a/src/client.h b/src/client.h
index 32670af..4814fdb 100644
--- a/src/client.h
+++ b/src/client.h
@@ -6,38 +6,65 @@
#include "egl.h"
#include "gl.h"
+struct surface {
+ struct egl egl;
+ struct gl gl;
+ struct wl_surface *wl_surface;
+ int32_t width;
+ int32_t height;
+ bool redraw;
+};
+
+struct image {
+ uint8_t *buffer;
+ uint32_t width;
+ uint32_t height;
+};
+
+struct color {
+ float r;
+ float g;
+ float b;
+ float a;
+};
+
struct client_state {
/* Globals */
struct wl_display *wl_display;
struct wl_registry *wl_registry;
- struct wl_shm *wl_shm;
struct wl_compositor *wl_compositor;
+ struct wl_subcompositor *wl_subcompositor;
struct wl_seat *wl_seat;
+ struct wl_output *wl_output;
struct xdg_wm_base *xdg_wm_base;
+
+ uint32_t wl_display_name;
+ uint32_t wl_registry_name;
+ uint32_t wl_compositor_name;
+ uint32_t wl_subcompositor_name;
+ uint32_t wl_seat_name;
+ uint32_t wl_output_name;
+ uint32_t xdg_wm_base_name;
+
/* Objects */
- struct wl_surface *wl_surface;
struct wl_keyboard *wl_keyboard;
- struct xdg_surface *xdg_surface;
- struct xdg_toplevel *xdg_toplevel;
+
/* State */
- float offset;
- uint32_t last_frame;
- int width;
- int height;
bool closed;
- struct egl egl;
- struct gl gl;
struct {
- uint8_t *buffer;
- uint32_t width;
- uint32_t height;
- } background_image;
- struct color {
- float r;
- float g;
- float b;
- float a;
- } background_color;
+ struct surface surface;
+ struct xdg_surface *xdg_surface;
+ struct xdg_toplevel *xdg_toplevel;
+ struct image background_image;
+ struct color background_color;
+ struct {
+ struct surface surface;
+ struct wl_subsurface *wl_subsurface;
+ struct image image;
+ } entry;
+ uint32_t scale;
+ } window;
+
/* Keyboard state */
struct xkb_state *xkb_state;
struct xkb_context *xkb_context;
diff --git a/src/egl.c b/src/egl.c
index 363ecb8..2e6b7a7 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -1,28 +1,26 @@
#include <assert.h>
#include <string.h>
#include <wayland-egl.h>
-#include "client.h"
+#include "egl.h"
#include "log.h"
-static void egl_log_error();
static const char *egl_error_string();
-void egl_create_window(struct client_state *state)
+void egl_create_window(struct egl *egl, struct wl_surface *wl_surface, uint32_t width, uint32_t height)
{
- state->egl.window = wl_egl_window_create(
- state->wl_surface,
- state->width,
- state->height);
+ egl->window = wl_egl_window_create(
+ wl_surface,
+ width,
+ height);
- if (state->egl.window == EGL_NO_SURFACE) {
+ if (egl->window == EGL_NO_SURFACE) {
egl_log_error("Couldn't create EGL window");
}
}
-void egl_create_context(struct client_state *state)
+void egl_create_context(struct egl *egl, struct wl_display *wl_display)
{
- struct egl *egl = &state->egl;
- egl->display = eglGetDisplay(state->wl_display);
+ egl->display = eglGetDisplay(wl_display);
if (egl->display == EGL_NO_DISPLAY) {
egl_log_error("Couldn't get EGL display");
return;
@@ -85,6 +83,18 @@ void egl_log_error(const char *msg) {
log_error("%s: %s\n", msg, egl_error_string());
}
+void egl_make_current(struct egl *egl) {
+ bool result = eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context);
+ if (!result) {
+ egl_log_error("Couldn't make EGL context current");
+ return;
+ }
+}
+
+void egl_swap_buffers(struct egl *egl) {
+ eglSwapBuffers(egl->display, egl->surface);
+}
+
const char *egl_error_string() {
switch(eglGetError()) {
case EGL_SUCCESS:
diff --git a/src/egl.h b/src/egl.h
index f97bd22..a1856b2 100644
--- a/src/egl.h
+++ b/src/egl.h
@@ -1,9 +1,9 @@
#ifndef EGL_H
#define EGL_H
+#include <wayland-egl.h>
#include <epoxy/egl.h>
-struct client_state;
struct egl {
EGLNativeWindowType window;
EGLDisplay display;
@@ -11,7 +11,10 @@ struct egl {
EGLSurface surface;
};
-void egl_create_window(struct client_state *state);
-void egl_create_context(struct client_state *state);
+void egl_create_window(struct egl *egl, struct wl_surface *wl_surface, uint32_t width, uint32_t height);
+void egl_create_context(struct egl *egl, struct wl_display *wl_display);
+void egl_log_error(const char *msg);
+void egl_make_current(struct egl *egl);
+void egl_swap_buffers(struct egl *egl);
#endif /* EGL_H */
diff --git a/src/gl.c b/src/gl.c
index 8187438..f9ff059 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -14,11 +14,11 @@ static GLuint create_shader_program(const char *vert, const char *frag);
void gl_initialise(struct client_state *state)
{
- if (state->background_image.buffer == NULL) {
+ if (state->window.background_image.buffer == NULL) {
return;
}
- struct gl *gl = &state->gl;
+ struct gl *gl = &state->window.surface.gl;
/* Compile and link the shader programs */
gl->shader = create_shader_program(
@@ -71,8 +71,8 @@ void gl_initialise(struct client_state *state)
/* Create the texture we'll draw to */
glGenTextures(1, &gl->texture);
glBindTexture(GL_TEXTURE_2D, gl->texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, state->background_image.width, state->background_image.height, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, (GLvoid *)state->background_image.buffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, state->window.background_image.width, state->window.background_image.height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, (GLvoid *)state->window.background_image.buffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -86,26 +86,25 @@ void gl_initialise(struct client_state *state)
void gl_draw(struct client_state *state)
{
glClearColor(
- state->background_color.r,
- state->background_color.g,
- state->background_color.b,
- state->background_color.a
+ state->window.background_color.r,
+ state->window.background_color.g,
+ state->window.background_color.b,
+ state->window.background_color.a
);
glClear(GL_COLOR_BUFFER_BIT);
- if (state->background_image.buffer == NULL) {
+ if (state->window.background_image.buffer == NULL) {
return;
}
double scale = max(
- (double)state->width / state->background_image.width,
- (double)state->height / state->background_image.height
+ (double)state->window.surface.width / state->window.background_image.width,
+ (double)state->window.surface.height / state->window.background_image.height
);
- uint32_t width = (uint32_t)(scale * state->background_image.width);
- uint32_t height = (uint32_t)(scale * state->background_image.height);
- int32_t x = -((int32_t)width - (int32_t)state->width) / 2;
- int32_t y = -((int32_t)height - (int32_t)state->height) / 2;
- printf("%d, %d\n", x, y);
+ uint32_t width = (uint32_t)(scale * state->window.background_image.width);
+ uint32_t height = (uint32_t)(scale * state->window.background_image.height);
+ int32_t x = -((int32_t)width - (int32_t)state->window.surface.width) / 2;
+ int32_t y = -((int32_t)height - (int32_t)state->window.surface.height) / 2;
glViewport(x, y, width, height);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
diff --git a/src/main.c b/src/main.c
index 07a4fbd..cacc82e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -10,18 +10,26 @@
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client.h>
+#include <wctype.h>
#include <xkbcommon/xkbcommon.h>
+#include <locale.h>
#include "client.h"
#include "egl.h"
#include "gl.h"
-#include "png.h"
+#include "background.h"
#include "xdg-shell-client-protocol.h"
-void draw_frame(struct client_state *state)
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+static void wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time);
+static const struct wl_callback_listener wl_surface_frame_listener = {
+ .done = wl_surface_frame_done,
+};
+
+void draw_frame(struct surface *surface)
{
- gl_draw(state);
- eglSwapBuffers(state->egl.display, state->egl.surface);
- wl_surface_damage_buffer(state->wl_surface, 0, 0, 50, 50);
+ printf("DRAW\n");
+ surface->redraw = true;
}
static void
@@ -35,11 +43,24 @@ xdg_toplevel_configure(void *data,
return;
}
- if (width != state->width || height != state->height) {
- state->width = width;
- state->height = height;
- wl_egl_window_resize(state->egl.window, width, height, 0, 0);
- draw_frame(state);
+ int32_t scaled_width = width * state->window.scale;
+ int32_t scaled_height = height * state->window.scale;
+
+ if (scaled_width != state->window.surface.width || scaled_height != state->window.surface.height) {
+ state->window.surface.width = scaled_width;
+ state->window.surface.height = scaled_height;
+ wl_egl_window_resize(state->window.surface.egl.window, scaled_width, scaled_height, 0, 0);
+
+ printf("%d, %d\n",
+ (width - state->window.entry.surface.width / state->window.scale) / 2,
+ (height - state->window.entry.surface.height / state->window.scale) / 2
+ );
+ wl_subsurface_set_position(state->window.entry.wl_subsurface,
+ (width - state->window.entry.surface.width / state->window.scale) / 2,
+ (height - state->window.entry.surface.height / state->window.scale) / 2
+ );
+ wl_surface_commit(state->window.entry.surface.wl_surface);
+ draw_frame(&state->window.surface);
}
}
@@ -94,19 +115,6 @@ wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, struct wl_surface *surface,
struct wl_array *keys)
{
- struct client_state *client_state = data;
- fprintf(stderr, "keyboard enter; keys pressed are:\n");
- uint32_t *key;
- wl_array_for_each(key, keys) {
- char buf[128];
- xkb_keysym_t sym = xkb_state_key_get_one_sym(
- client_state->xkb_state, *key + 8);
- xkb_keysym_get_name(sym, buf, sizeof(buf));
- fprintf(stderr, "sym: %-12s (%d), ", buf, sym);
- xkb_state_key_get_utf8(client_state->xkb_state,
- *key + 8, buf, sizeof(buf));
- fprintf(stderr, "utf8: '%s'\n", buf);
- }
}
static void
@@ -116,17 +124,15 @@ wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard,
struct client_state *client_state = data;
char buf[128];
uint32_t keycode = key + 8;
- xkb_keysym_t sym = xkb_state_key_get_one_sym(
- client_state->xkb_state, keycode);
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(client_state->xkb_state, keycode);
xkb_keysym_get_name(sym, buf, sizeof(buf));
- const char *action =
- state == WL_KEYBOARD_KEY_STATE_PRESSED ? "press" : "release";
- fprintf(stderr, "key %s: sym: %-12s (%d), ", action, buf, sym);
- xkb_state_key_get_utf8(client_state->xkb_state, keycode,
- buf, sizeof(buf));
- fprintf(stderr, "utf8: '%s'\n", buf);
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- draw_frame(client_state);
+ int len = xkb_state_key_get_utf8(client_state->xkb_state, keycode, buf, sizeof(buf));
+ wchar_t ch;
+ mbtowc(&ch, buf, sizeof(buf));
+ if (len > 0 && iswprint(ch)) {
+ fprintf(stderr, "%s\n", buf);
+ }
}
}
@@ -134,7 +140,6 @@ static void
wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, struct wl_surface *surface)
{
- fprintf(stderr, "keyboard leave\n");
}
static void
@@ -152,7 +157,6 @@ static void
wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
int32_t rate, int32_t delay)
{
- /* Left as an exercise for the reader */
}
static const struct wl_keyboard_listener wl_keyboard_listener = {
@@ -184,7 +188,7 @@ wl_seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
static void
wl_seat_name(void *data, struct wl_seat *wl_seat, const char *name)
{
- fprintf(stderr, "seat name: %s\n", name);
+ fprintf(stderr, "seat name: %s\n", name);
}
static const struct wl_seat_listener wl_seat_listener = {
@@ -202,64 +206,88 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
.ping = xdg_wm_base_ping,
};
-static const struct wl_callback_listener wl_surface_frame_listener;
-
static void
wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time)
{
/* Destroy this callback */
wl_callback_destroy(cb);
+ fprintf(stderr, "callback\n");
/* Request another frame */
struct client_state *state = data;
- cb = wl_surface_frame(state->wl_surface);
+ cb = wl_surface_frame(state->window.surface.wl_surface);
wl_callback_add_listener(cb, &wl_surface_frame_listener, state);
- /* Update scroll amount at 24 pixels per second */
- if (state->last_frame != 0) {
- int elapsed = time - state->last_frame;
- state->offset += elapsed / 1000.0 * 24;
- }
-
/* Submit a frame for this event */
- wl_surface_commit(state->wl_surface);
+ wl_surface_commit(state->window.surface.wl_surface);
+}
- state->last_frame = time;
+static void output_geometry(void *data, struct wl_output *wl_output,
+ int32_t x, int32_t y, int32_t physical_width, int32_t physical_height,
+ int32_t subpixel, const char *make, const char *model, int32_t transform)
+{
+ /* Deliberately left blank */
}
-static const struct wl_callback_listener wl_surface_frame_listener = {
- .done = wl_surface_frame_done,
+static void output_mode(void *data, struct wl_output *wl_output,
+ uint32_t flags, int32_t width, int32_t height, int32_t refresh)
+{
+ /* Deliberately left blank */
+}
+
+static void output_scale(void *data, struct wl_output *wl_output, int32_t factor)
+{
+ struct client_state *state = data;
+ state->window.scale = MAX(factor, (int32_t)state->window.scale);
+ wl_surface_set_buffer_scale(state->window.surface.wl_surface, state->window.scale);
+ wl_surface_set_buffer_scale(state->window.entry.surface.wl_surface, state->window.scale);
+}
+
+static void output_done(void *data, struct wl_output *wl_output)
+{
+ /* TODO */
+}
+
+static const struct wl_output_listener wl_output_listener = {
+ .geometry = output_geometry,
+ .mode = output_mode,
+ .done = output_done,
+ .scale = output_scale,
};
-static void
-registry_global(void *data, struct wl_registry *wl_registry,
- uint32_t name, const char *interface, uint32_t version)
+static void registry_global(void *data, struct wl_registry *wl_registry,
+ uint32_t name, const char *interface, uint32_t version)
{
- struct client_state *state = data;
- if (strcmp(interface, wl_shm_interface.name) == 0) {
- state->wl_shm = wl_registry_bind(
- wl_registry, name, &wl_shm_interface, 1);
- } else if (strcmp(interface, wl_compositor_interface.name) == 0) {
- state->wl_compositor = wl_registry_bind(
- wl_registry, name, &wl_compositor_interface, 4);
- } else if (strcmp(interface, wl_seat_interface.name) == 0) {
- state->wl_seat = wl_registry_bind(
- wl_registry, name, &wl_seat_interface, 7);
- wl_seat_add_listener(state->wl_seat,
- &wl_seat_listener, state);
- } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
- state->xdg_wm_base = wl_registry_bind(
- wl_registry, name, &xdg_wm_base_interface, 1);
- xdg_wm_base_add_listener(state->xdg_wm_base,
- &xdg_wm_base_listener, state);
- }
+ struct client_state *state = data;
+ //fprintf(stderr, "%s\n", interface);
+ if (strcmp(interface, wl_compositor_interface.name) == 0) {
+ state->wl_compositor = wl_registry_bind(
+ wl_registry, name, &wl_compositor_interface, 4);
+ } else if (strcmp(interface, wl_subcompositor_interface.name) == 0) {
+ state->wl_subcompositor = wl_registry_bind(
+ wl_registry, name, &wl_subcompositor_interface, 1);
+ } else if (strcmp(interface, wl_seat_interface.name) == 0) {
+ state->wl_seat = wl_registry_bind(
+ wl_registry, name, &wl_seat_interface, 7);
+ wl_seat_add_listener(state->wl_seat,
+ &wl_seat_listener, state);
+ } else if (strcmp(interface, wl_output_interface.name) == 0) {
+ state->wl_output = wl_registry_bind(
+ wl_registry, name, &wl_output_interface, 3);
+ wl_output_add_listener(state->wl_output,
+ &wl_output_listener, state);
+ } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
+ state->xdg_wm_base = wl_registry_bind(
+ wl_registry, name, &xdg_wm_base_interface, 1);
+ xdg_wm_base_add_listener(state->xdg_wm_base,
+ &xdg_wm_base_listener, state);
+ }
}
-static void
-registry_global_remove(void *data,
- struct wl_registry *wl_registry, uint32_t name)
+static void registry_global_remove(void *data, struct wl_registry *wl_registry,
+ uint32_t name)
{
- /* This space deliberately left blank */
+ /* Deliberately left blank */
}
static const struct wl_registry_listener wl_registry_listener = {
@@ -267,44 +295,88 @@ static const struct wl_registry_listener wl_registry_listener = {
.global_remove = registry_global_remove,
};
+static void surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output)
+{
+ fprintf(stderr, "enter\n");
+}
+
+static void surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output)
+{
+ fprintf(stderr, "leave\n");
+}
+
+static const struct wl_surface_listener wl_surface_listener = {
+ .enter = surface_enter,
+ .leave = surface_leave
+};
+
int main(int argc, char *argv[])
{
- struct client_state state = { 0 };
- load_background(&state, "Night-1800.png");
- state.background_color = (struct color){ 0.2, 0.8, 0.8, 1.0 };
- state.width = 640;
- state.height = 480;
- state.wl_display = wl_display_connect(NULL);
- state.wl_registry = wl_display_get_registry(state.wl_display);
- state.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
- wl_registry_add_listener(state.wl_registry, &wl_registry_listener, &state);
- wl_display_roundtrip(state.wl_display);
-
- state.wl_surface = wl_compositor_create_surface(state.wl_compositor);
- state.xdg_surface = xdg_wm_base_get_xdg_surface(
- state.xdg_wm_base, state.wl_surface);
- xdg_surface_add_listener(state.xdg_surface, &xdg_surface_listener, &state);
- state.xdg_toplevel = xdg_surface_get_toplevel(state.xdg_surface);
- xdg_toplevel_add_listener(state.xdg_toplevel,
- &xdg_toplevel_listener, &state);
- xdg_toplevel_set_title(state.xdg_toplevel, "Greetd mini wayland greeter");
-
- wl_surface_commit(state.wl_surface);
-
- egl_create_window(&state);
- egl_create_context(&state);
- gl_initialise(&state);
-
- struct wl_callback *cb = wl_surface_frame(state.wl_surface);
- wl_callback_add_listener(cb, &wl_surface_frame_listener, &state);
-
- wl_display_roundtrip(state.wl_display);
- draw_frame(&state);
- while (!state.closed) {
- wl_display_dispatch(state.wl_display);
- }
-
- wl_display_disconnect(state.wl_display);
-
- return 0;
+ setlocale(LC_ALL, "");
+ struct client_state state = { 0 };
+ load_background(&state, "Night-1800.png");
+ state.window.background_color = (struct color){ 0.2, 0.8, 0.8, 1.0 };
+ state.window.surface.width = 640;
+ state.window.surface.height = 480;
+ state.window.entry.surface.width = 80;
+ state.window.entry.surface.height = 40;
+ state.wl_display = wl_display_connect(NULL);
+ state.wl_registry = wl_display_get_registry(state.wl_display);
+ state.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ wl_registry_add_listener(state.wl_registry, &wl_registry_listener, &state);
+ wl_display_roundtrip(state.wl_display);
+
+ state.window.surface.wl_surface = wl_compositor_create_surface(state.wl_compositor);
+ state.window.scale = 1;
+ wl_surface_add_listener(state.window.surface.wl_surface, &wl_surface_listener, &state);
+ state.window.xdg_surface = xdg_wm_base_get_xdg_surface(state.xdg_wm_base, state.window.surface.wl_surface);
+ xdg_surface_add_listener(state.window.xdg_surface, &xdg_surface_listener, &state);
+ state.window.xdg_toplevel = xdg_surface_get_toplevel(state.window.xdg_surface);
+ xdg_toplevel_add_listener(state.window.xdg_toplevel,
+ &xdg_toplevel_listener, &state);
+ xdg_toplevel_set_title(state.window.xdg_toplevel, "Greetd mini wayland greeter");
+ wl_surface_commit(state.window.surface.wl_surface);
+
+ state.window.entry.surface.wl_surface = wl_compositor_create_surface(state.wl_compositor);
+ state.window.entry.wl_subsurface = wl_subcompositor_get_subsurface(state.wl_subcompositor, state.window.entry.surface.wl_surface, state.window.surface.wl_surface);
+ wl_subsurface_set_desync(state.window.entry.wl_subsurface);
+ wl_surface_commit(state.window.entry.surface.wl_surface);
+
+
+ struct surface *surface = &state.window.surface;
+ egl_create_window(&surface->egl, surface->wl_surface, surface->width, surface->height);
+ egl_create_context(&surface->egl, state.wl_display);
+ gl_initialise(&state);
+
+ surface = &state.window.entry.surface;
+ egl_create_window(&surface->egl, surface->wl_surface, surface->width, surface->height);
+ egl_create_context(&surface->egl, state.wl_display);
+
+
+ wl_display_roundtrip(state.wl_display);
+ egl_make_current(&state.window.surface.egl);
+ eglSwapBuffers(state.window.surface.egl.display, state.window.surface.egl.surface);
+ egl_make_current(&state.window.entry.surface.egl);
+ eglSwapBuffers(state.window.entry.surface.egl.display, state.window.entry.surface.egl.surface);
+ draw_frame(&state.window.surface);
+ while (wl_display_dispatch(state.wl_display) != -1) {
+ if (state.closed) {
+ break;
+ }
+ if (state.window.surface.redraw) {
+ egl_make_current(&state.window.surface.egl);
+ gl_draw(&state);
+ egl_swap_buffers(&state.window.surface.egl);
+ state.window.surface.redraw = false;
+ }
+ if (state.window.entry.surface.redraw) {
+ egl_make_current(&state.window.entry.surface.egl);
+ egl_swap_buffers(&state.window.entry.surface.egl);
+ state.window.entry.surface.redraw = false;
+ }
+ }
+
+ wl_display_disconnect(state.wl_display);
+
+ return 0;
}