summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build7
-rw-r--r--src/client.h34
-rw-r--r--src/egl.c122
-rw-r--r--src/egl.h17
-rw-r--r--src/log.c40
-rw-r--r--src/log.h9
-rw-r--r--src/main.c (renamed from src/client.c)74
7 files changed, 232 insertions, 71 deletions
diff --git a/meson.build b/meson.build
index 7474a4f..cdffbdd 100644
--- a/meson.build
+++ b/meson.build
@@ -15,6 +15,9 @@ project(
)
debug = get_option('buildtype').startswith('debug')
+if debug
+ add_project_arguments('-DDEBUG', language : 'c')
+endif
data_location = join_paths(
get_option('prefix'),
@@ -34,7 +37,9 @@ add_project_arguments(
)
sources = files(
- 'src/client.c',
+ 'src/main.c',
+ 'src/log.c',
+ 'src/egl.c',
'src/xdg-shell-protocol.c',
)
diff --git a/src/client.h b/src/client.h
new file mode 100644
index 0000000..04d78ac
--- /dev/null
+++ b/src/client.h
@@ -0,0 +1,34 @@
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "egl.h"
+
+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_seat *wl_seat;
+ struct xdg_wm_base *xdg_wm_base;
+ /* 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;
+ /* Keyboard state */
+ struct xkb_state *xkb_state;
+ struct xkb_context *xkb_context;
+ struct xkb_keymap *xkb_keymap;
+};
+
+#endif /* CLIENT_H */
diff --git a/src/egl.c b/src/egl.c
new file mode 100644
index 0000000..bd45413
--- /dev/null
+++ b/src/egl.c
@@ -0,0 +1,122 @@
+#include <assert.h>
+#include <string.h>
+#include <wayland-egl.h>
+#include "client.h"
+#include "log.h"
+
+static void egl_log_error();
+static const char *egl_error_string();
+
+void egl_create_window(struct client_state *state)
+{
+ state->egl.window = wl_egl_window_create(
+ state->wl_surface,
+ state->width,
+ state->height);
+
+ if (state->egl.window == EGL_NO_SURFACE) {
+ egl_log_error("Couldn't create EGL window");
+ }
+}
+
+void egl_create_context(struct client_state *state)
+{
+ struct egl *egl = &state->egl;
+ egl->display = eglGetDisplay(state->wl_display);
+ if (egl->display == EGL_NO_DISPLAY) {
+ egl_log_error("Couldn't get EGL display");
+ return;
+ }
+
+ if (!eglInitialize(egl->display, NULL, NULL)) {
+ egl_log_error("Couldn't initialise EGL");
+ return;
+ }
+
+ EGLBoolean result;
+ EGLConfig config;
+ EGLint num_configs;
+ static const EGLint config_attribs[] = {
+ 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_NONE
+ };
+
+ result = eglGetConfigs(egl->display, NULL, 0, &num_configs);
+ if ((result != EGL_TRUE) || (num_configs == 0)) {
+ egl_log_error("No EGL configs available");
+ return;
+ }
+
+ result = eglChooseConfig(egl->display, config_attribs, &config, 1, &num_configs);
+ if ((result != EGL_TRUE) || (num_configs != 1)) {
+ egl_log_error("Failed to choose EGL config");
+ return;
+ }
+
+ egl->surface = eglCreateWindowSurface(egl->display, config, egl->window, NULL);
+ if (egl->surface == EGL_NO_SURFACE) {
+ egl_log_error("Couldn't create EGL window surface");
+ return;
+ }
+
+ static const EGLint context_attribs[] = {
+ EGL_CONTEXT_MAJOR_VERSION, 2,
+ EGL_NONE
+ };
+
+ egl->context = eglCreateContext(egl->display, config, EGL_NO_CONTEXT, context_attribs);
+ if (egl->context == EGL_NO_CONTEXT) {
+ egl_log_error("Couldn't create EGL context");
+ return;
+ }
+
+ result = eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context);
+ if (!result) {
+ egl_log_error("Couldn't make EGL context current");
+ return;
+ }
+}
+
+void egl_log_error(const char *msg) {
+ log_error("%s: %s\n", msg, egl_error_string());
+}
+
+const char *egl_error_string() {
+ switch(eglGetError()) {
+ case EGL_SUCCESS:
+ return "EGL_SUCCESS";
+ case EGL_NOT_INITIALIZED:
+ return "EGL_NOT_INITIALIZED";
+ case EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL_BAD_ALLOC:
+ return "EGL_BAD_ALLOC";
+ case EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_CONTEXT:
+ return "EGL_BAD_CONTEXT";
+ case EGL_BAD_CONFIG:
+ return "EGL_BAD_CONFIG";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "EGL_BAD_CURRENT_SURFACE";
+ case EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL_BAD_SURFACE:
+ return "EGL_BAD_SURFACE";
+ case EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "EGL_BAD_NATIVE_WINDOW";
+ case EGL_CONTEXT_LOST:
+ return "EGL_CONTEXT_LOST";
+ }
+ return "Unknown EGL error";
+}
diff --git a/src/egl.h b/src/egl.h
new file mode 100644
index 0000000..f97bd22
--- /dev/null
+++ b/src/egl.h
@@ -0,0 +1,17 @@
+#ifndef EGL_H
+#define EGL_H
+
+#include <epoxy/egl.h>
+
+struct client_state;
+struct egl {
+ EGLNativeWindowType window;
+ EGLDisplay display;
+ EGLContext context;
+ EGLSurface surface;
+};
+
+void egl_create_window(struct client_state *state);
+void egl_create_context(struct client_state *state);
+
+#endif /* EGL_H */
diff --git a/src/log.c b/src/log.c
new file mode 100644
index 0000000..eb4d165
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+void log_error(const char *const fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "[ERROR]: ");
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+void log_warning(const char *const fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "[WARNING]: ");
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+void log_debug(const char *const fmt, ...)
+{
+#ifndef DEBUG
+ return;
+#endif
+ va_list args;
+ va_start(args, fmt);
+ printf("[DEBUG]: ");
+ vprintf(fmt, args);
+ va_end(args);
+}
+
+void log_info(const char *const fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ printf("[INFO]: ");
+ vprintf(fmt, args);
+ va_end(args);
+}
diff --git a/src/log.h b/src/log.h
new file mode 100644
index 0000000..e030bc9
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,9 @@
+#ifndef LOG_H
+#define LOG_H
+
+void log_error(const char *const fmt, ...);
+void log_warning(const char *const fmt, ...);
+void log_debug(const char *const fmt, ...);
+void log_info(const char *const fmt, ...);
+
+#endif /* LOG_H */
diff --git a/src/client.c b/src/main.c
index 0b2bdec..5991424 100644
--- a/src/client.c
+++ b/src/main.c
@@ -1,4 +1,3 @@
-#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <epoxy/egl.h>
#include <epoxy/gl.h>
@@ -14,6 +13,8 @@
#include <wayland-client.h>
#include <wayland-egl.h>
#include <xkbcommon/xkbcommon.h>
+#include "client.h"
+#include "egl.h"
#include "xdg-shell-client-protocol.h"
/* Shared memory support code */
@@ -64,30 +65,6 @@ allocate_shm_file(size_t size)
}
/* Wayland code */
-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_seat *wl_seat;
- struct xdg_wm_base *xdg_wm_base;
- /* 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;
- /* Keyboard state */
- struct xkb_state *xkb_state;
- struct xkb_context *xkb_context;
- struct xkb_keymap *xkb_keymap;
-};
static void
wl_buffer_release(void *data, struct wl_buffer *wl_buffer)
@@ -407,51 +384,8 @@ main(int argc, char *argv[])
wl_surface_commit(state.wl_surface);
-
- /* Setup EGL */
- EGLDisplay egl_dpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_KHR,
- state.wl_display, NULL);
- assert(egl_dpy != NULL);
- bool res = eglInitialize(egl_dpy, NULL, NULL);
- assert(res);
-
- const char *egl_extension_st = eglQueryString (egl_dpy, EGL_EXTENSIONS);
- assert (strstr (egl_extension_st, "EGL_KHR_create_context") != NULL);
-
- static const EGLint config_attribs[] = {
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_NONE
- };
- EGLConfig cfg;
- EGLint count;
-
- res = eglChooseConfig (egl_dpy, config_attribs, &cfg, 1, &count);
- assert (res);
-
- res = eglBindAPI (EGL_OPENGL_ES_API);
- assert (res);
-
- static const EGLint attribs[] = {
- EGL_CONTEXT_MAJOR_VERSION, 2,
- EGL_NONE
- };
- EGLContext core_ctx = eglCreateContext (egl_dpy,
- cfg,
- EGL_NO_CONTEXT,
- attribs);
- assert (core_ctx != EGL_NO_CONTEXT);
-
- struct wl_egl_window *egl_window = wl_egl_window_create(state.wl_surface, state.width, state.height);
- EGLSurface surface = eglCreatePlatformWindowSurfaceEXT(egl_dpy, cfg, egl_window, NULL);
- assert (surface != EGL_NO_SURFACE);
-
- res = eglMakeCurrent (egl_dpy, surface, surface, core_ctx);
- assert (res);
-
-
-
- /* */
+ egl_create_window(&state);
+ egl_create_context(&state);
struct wl_callback *cb = wl_surface_frame(state.wl_surface);
wl_callback_add_listener(cb, &wl_surface_frame_listener, &state);