diff options
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/meson.build | 16 | ||||
| -rw-r--r-- | gui/renderer_gles.c | 92 | ||||
| -rw-r--r-- | gui/surface_egl.c | 146 | ||||
| -rw-r--r-- | gui/window.c | 137 | ||||
| -rw-r--r-- | gui/window_xcb.c | 231 |
5 files changed, 0 insertions, 622 deletions
diff --git a/gui/meson.build b/gui/meson.build deleted file mode 100644 index b3486e7..0000000 --- a/gui/meson.build +++ /dev/null @@ -1,16 +0,0 @@ -gui_sources = files('window.c') -gui_deps = [] - -if os == 'linux' - gui_sources += ['window_xcb.c', 'surface_egl.c', 'renderer_gles.c'] - gui_deps += [ dependency('egl'), dependency('glesv2'), dependency('xcb') ] -endif - -gui_library = library( - 'RuimUI', - gui_sources, - include_directories: ruim_include, - dependencies: gui_deps, - link_with: internal_lib, - install: true, -) diff --git a/gui/renderer_gles.c b/gui/renderer_gles.c deleted file mode 100644 index d6e217a..0000000 --- a/gui/renderer_gles.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "gui/renderer.h" -#include "gui/window.h" -#include "internal/utils.h" - -#include <GLES2/gl2.h> -#include <GLES3/gl3.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> - -GLuint load_shader(const char *code, uint type) { - int success; - char infoLog[512]; - GLuint shader = glCreateShader(type); - - glShaderSource(shader, 1, &code, NULL); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - - if (!success) { - glGetShaderInfoLog(shader, 512, NULL, infoLog); - printf("Shader compilation failed: %s\n", infoLog); - } - - return shader; -} - -struct ruim_rendererGLES RuimSetupGLES(void) { - int success; - char infoLog[512]; - struct ruim_rendererGLES renderer; - float vertices[] = {-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f}; - - GLuint vertexShdr = - load_shader("#version 300 es\n" - "layout (location = 0) in vec3 aPos;\n" - "void main()\n" - "{\n" - "gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" - "}\0", - GL_VERTEX_SHADER); - - GLuint fragmentShdr = load_shader("#version 300 es\n" - "precision mediump float;\n" - "out vec4 FragColor;\n" - "void main()\n" - "{\n" - "FragColor = vec4(1.0, 0.5, 0.2, 1.0);\n" - "}\0", - GL_FRAGMENT_SHADER); - - glGenBuffers(1, &renderer.VBO); - glGenVertexArrays(1, &renderer.VAO); - - renderer.shaderProgram = glCreateProgram(); - glAttachShader(renderer.shaderProgram, vertexShdr); - glAttachShader(renderer.shaderProgram, fragmentShdr); - glLinkProgram(renderer.shaderProgram); - glGetProgramiv(renderer.shaderProgram, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(renderer.shaderProgram, 512, NULL, infoLog); - printf("Program linking failed: %s\n", infoLog); - } - - glDeleteShader(vertexShdr); - glDeleteShader(fragmentShdr); - - glBindVertexArray(renderer.VAO); - - glBindBuffer(GL_ARRAY_BUFFER, renderer.VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); - glEnableVertexAttribArray(0); - - glBindVertexArray(0); - - return renderer; -} - -void RuimResizeGLES(struct ruim_rendererGLES *renderer, int width, int height) { - glViewport(0, 0, width, height); -} - -void RuimRenderGLES(struct ruim_rendererGLES *renderer) { - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - glUseProgram(renderer->shaderProgram); - glBindVertexArray(renderer->VAO); - glDrawArrays(GL_TRIANGLES, 0, 3); -} diff --git a/gui/surface_egl.c b/gui/surface_egl.c deleted file mode 100644 index eea2ee5..0000000 --- a/gui/surface_egl.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "gui/renderer.h" -#include "gui/window.h" -#include "internal/utils.h" - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> - -/* Get human-readable EGL error string */ -const char *egl_error_string(EGLint error) { - switch (error) { - 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_CONFIG: - return "EGL_BAD_CONFIG"; - case EGL_BAD_CONTEXT: - return "EGL_BAD_CONTEXT"; - case EGL_BAD_CURRENT_SURFACE: - return "EGL_BAD_CURRENT_SURFACE"; - case EGL_BAD_DISPLAY: - return "EGL_BAD_DISPLAY"; - case EGL_BAD_MATCH: - return "EGL_BAD_MATCH"; - case EGL_BAD_NATIVE_PIXMAP: - return "EGL_BAD_NATIVE_PIXMAP"; - case EGL_BAD_NATIVE_WINDOW: - return "EGL_BAD_NATIVE_WINDOW"; - case EGL_BAD_PARAMETER: - return "EGL_BAD_PARAMETER"; - case EGL_BAD_SURFACE: - return "EGL_BAD_SURFACE"; - case EGL_CONTEXT_LOST: - return "EGL_CONTEXT_LOST"; - default: - return "UNKNOWN_EGL_ERROR"; - } -} - -/* Crash with EGL error information - * */ -void crash_egl(const char *expr, const char *file, int line) { - EGLint error = eglGetError(); - fprintf(stderr, "EGL Error at %s:%d\n", file, line); - fprintf(stderr, "Expression: %s\n", expr); - fprintf(stderr, "Error code: 0x%x (%s)\n", error, egl_error_string(error)); - abort(); -} - -/* Macro for checking EGL boolean returns (EGL_TRUE/EGL_FALSE) */ -#define assert_egl(expr) \ - do { \ - if (!(expr)) \ - crash_egl(#expr, __FILE__, __LINE__); \ - } while (0) - -void RuimInitEGL(RuimToplevel *toplevel) { - RuimSurfaceEGL ruimSurface; - EGLint version_major, version_minor; - EGLConfig config; - EGLint num_config; - struct toplevel_x11 *x11_toplevel = (struct toplevel_x11 *)toplevel->data; - struct backend_x11 *x11_backend = - (struct backend_x11 *)toplevel->backend->data; - EGLint constraints[] = { - EGL_SURFACE_TYPE, - EGL_WINDOW_BIT, - EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES3_BIT, - EGL_RED_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_ALPHA_SIZE, - 8, - EGL_DEPTH_SIZE, - 24, - EGL_NONE, - }; - - /* egl-contexts collect all state descriptions needed required for operation - */ - EGLint ctxattr[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, - 0, EGL_NONE}; - - const char *client_extensions = - eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - - if (!client_extensions) { - abort(); - } - if (!strstr(client_extensions, "EGL_EXT_platform_xcb")) { - abort(); - } - - ruimSurface.display = eglGetPlatformDisplay(EGL_PLATFORM_XCB_EXT, - x11_backend->connection, NULL); - - assert_egl(ruimSurface.display); - - assert_egl( - eglInitialize(ruimSurface.display, &version_major, &version_minor)); - ; - assert_egl(eglChooseConfig(ruimSurface.display, constraints, &config, 1, - &num_config)); - assert_egl(eglBindAPI(EGL_OPENGL_ES_API)); - - ruimSurface.surface = eglCreatePlatformWindowSurface( - ruimSurface.display, config, &x11_toplevel->window, NULL); - assert_egl(ruimSurface.surface); - - ruimSurface.context = - eglCreateContext(ruimSurface.display, config, EGL_NO_CONTEXT, ctxattr); - assert_egl(ruimSurface.context); - - assert_egl(eglMakeCurrent(ruimSurface.display, ruimSurface.surface, - ruimSurface.surface, ruimSurface.context)); - assert_egl(eglSwapInterval(ruimSurface.display, 1)); - - x11_backend->surface = ruimSurface; -} - -EGLBoolean RuimSwapEGL(RuimToplevel *toplevel) { - struct backend_x11 *x11_backend = - (struct backend_x11 *)toplevel->backend->data; - - return eglSwapBuffers(x11_backend->surface.display, - x11_backend->surface.surface); -} - -void RuimDeinitEGL(RuimSurfaceEGL *eglCtx) { - assert_egl(eglMakeCurrent(eglCtx->display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT)); - assert_egl(eglDestroyContext(eglCtx->display, eglCtx->context)); - assert_egl(eglDestroySurface(eglCtx->display, eglCtx->surface)); - assert_egl(eglTerminate(eglCtx->display)); -} diff --git a/gui/window.c b/gui/window.c deleted file mode 100644 index 66e8edb..0000000 --- a/gui/window.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "gui/window.h" -#include "gui/renderer.h" -#include "internal/utils.h" - -int RuimToplevelBackendInit(RuimToplevelBackend *backend) { - if (backend == NULL) { - crash_error("backend must be non-null"); - } - - if (backend->type == 0) { - /* TODO: select default one based on platform */ - backend->type = RUIM_TOPLEVEL_X11; - } - - switch (backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - return _init_xcb_backend(backend); - } break; -#endif - default: - printf("%d\n", backend->type); - crash_error("unrecognized backend type"); - } - - crash_error("unreachable"); - return -1; -} - -int RuimToplevelBackendDeinit(RuimToplevelBackend *backend) { - if (backend == NULL || backend->type == 0) { - crash_error("some crash"); - } - - switch (backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - return _deinit_xcb_backend(backend); - } break; -#endif - default: - crash_error("some crash"); - } - - return 0; -} - -int RuimToplevelCreate(RuimToplevel *toplevel, RuimToplevelType type) { - if (type && type != RUIM_TOPLEVEL_WINDOW) { - crash_error("TODO: toplevel must be a window"); - } - - if (toplevel->backend == NULL) { - crash_error("TODO: backend must be set"); - } - - switch (toplevel->backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - return _create_toplevel_xcb(toplevel); - } break; -#endif - default: - crash_error("unknown backend type"); - } - - return 0; -} - -int RuimToplevelDisplay(RuimToplevel *toplevel) { - if (toplevel == NULL) { - crash_error("toplevel must be non-null"); - } - - switch (toplevel->backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - return _display_toplevel_xcb(toplevel); - } break; -#endif - default: - crash_error("some crash"); - } - - return 0; -} - -int RuimToplevelPoll(RuimToplevel *toplevel, RuimToplevelEvent *event) { - switch (toplevel->backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - if (_poll_event_xcb(toplevel, event) != 0) { - crash_error("xcb connection error"); - } - } break; -#endif - default: - crash_error("unknown backend type"); - } - - if (event->type == RUIM_TOPLEVEL_EVENT_NOTHING) { - return 0; - } else { - return 1; - } -} - -int RuimToplevelWaitForEvent(RuimToplevel *toplevel) { - switch (toplevel->backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - return _wait_event_xcb(toplevel); - } break; -#endif - default: - crash_error("unknown backend type"); - } - - crash_error("unreachable"); - return -1; -} - -int RuimToplevelDestroy(RuimToplevel *toplevel) { - - switch (toplevel->backend->type) { -#ifdef RUIM_PLATFORM_LINUX - case RUIM_TOPLEVEL_X11: { - return _destroy_toplevel_xcb(toplevel); - } break; -#endif - default: - crash_error("unknown backend type"); - } - - crash_error("unreachable"); - return -1; -} diff --git a/gui/window_xcb.c b/gui/window_xcb.c deleted file mode 100644 index 61682ed..0000000 --- a/gui/window_xcb.c +++ /dev/null @@ -1,231 +0,0 @@ -#include "gui/types.h" -#include "gui/window.h" -#include "internal/utils.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <xcb/xcb.h> -#include <xcb/xproto.h> - -/* TODO(roberto): put the correct error values */ -static void _xcb_handle_error(int error) { - switch (error) { - case XCB_WINDOW: - crash_error("Invalid window error\n"); - case XCB_PIXMAP: - crash_error("Invalid pixmap error\n"); - case XCB_ATOM: - crash_error("Invalid atom error\n"); - case XCB_VALUE: - crash_error("Invalid value error\n"); - case XCB_MATCH: - crash_error("Match error (incompatible parameters)\n"); - case XCB_DRAWABLE: - crash_error("Invalid drawable error\n"); - case XCB_ACCESS: - crash_error("Access denied error\n"); - case XCB_ALLOC: - crash_error("Resource allocation error\n"); - default: - crash_error("Unknown error\n"); - } -} - -static xcb_atom_t _get_atom_xcb(xcb_connection_t *conn, const char *name) { - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t *reply; - xcb_atom_t atom; - - cookie = xcb_intern_atom(conn, 0, strlen(name), name); - reply = xcb_intern_atom_reply(conn, cookie, NULL); - - if (reply) { - atom = reply->atom; - free(reply); - return atom; - } - - return XCB_ATOM_NONE; -} - -int _init_xcb_backend(RuimToplevelBackend *backend) { - struct backend_x11 *x11; - xcb_screen_iterator_t iter; - int error = 0; - - x11 = (struct backend_x11 *)malloc(sizeof(struct backend_x11)); - x11->connection = xcb_connect(NULL, &x11->screen_num); - if ((error = xcb_connection_has_error(x11->connection)) != 0) { - return error; - } - - x11->poll.fd = xcb_get_file_descriptor(x11->connection); - x11->poll.events = POLLIN; - - x11->setup = xcb_get_setup(x11->connection); - iter = xcb_setup_roots_iterator(x11->setup); - x11->screen = iter.data; - - x11->wm_protocols = _get_atom_xcb(x11->connection, "WM_PROTOCOLS"); - x11->wm_delete_window = _get_atom_xcb(x11->connection, "WM_DELETE_WINDOW"); - - backend->data = (void *)x11; - - return 0; -} - -int _deinit_xcb_backend(RuimToplevelBackend *backend) { - struct backend_x11 *x11 = (struct backend_x11 *)backend->data; - xcb_disconnect(x11->connection); - - free(backend->data); - return 0; -} - -/* TODO: support more toplevel types */ -int _create_toplevel_xcb(RuimToplevel *toplevel) { - int error; - struct backend_x11 *x11_backend; - struct toplevel_x11 *x11_toplevel; - - x11_toplevel = (struct toplevel_x11 *)malloc(sizeof(struct toplevel_x11)); - x11_toplevel->event_values = (uint32_t *)malloc(sizeof(uint32_t) * 2); - x11_backend = (struct backend_x11 *)toplevel->backend->data; - if ((error = xcb_connection_has_error(x11_backend->connection)) != 0) { - return error; - } - - x11_toplevel->window = xcb_generate_id(x11_backend->connection); - x11_toplevel->event_mask = XCB_CW_EVENT_MASK; - x11_toplevel->event_values[0] = - XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_STRUCTURE_NOTIFY; - - xcb_create_window(x11_backend->connection, XCB_COPY_FROM_PARENT, - x11_toplevel->window, x11_backend->screen->root, 0, 0, 150, - 150, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, - x11_backend->screen->root_visual, x11_toplevel->event_mask, - x11_toplevel->event_values); - - xcb_change_property(x11_backend->connection, XCB_PROP_MODE_REPLACE, - x11_toplevel->window, x11_backend->wm_protocols, - XCB_ATOM_ATOM, 32, 1, &x11_backend->wm_delete_window); - - xcb_flush(x11_backend->connection); - - toplevel->data = (void *)x11_toplevel; - - return 0; -} - -int _display_toplevel_xcb(RuimToplevel *toplevel) { - struct backend_x11 *x11_backend = - (struct backend_x11 *)toplevel->backend->data; - struct toplevel_x11 *x11_toplevel = (struct toplevel_x11 *)toplevel->data; - - xcb_map_window(x11_backend->connection, x11_toplevel->window); - /* FIXME(roberto): decide where to flush the connection */ - return xcb_flush(x11_backend->connection) > 0; -} - -int _poll_event_xcb(RuimToplevel *toplevel, RuimToplevelEvent *event) { - struct backend_x11 *x11_backend = - (struct backend_x11 *)toplevel->backend->data; - xcb_generic_event_t *x11_event; - int error = 0; - /* FIXME(roberto): make it actually poll */ - /* FIXME(roberto): too laggy */ - x11_event = xcb_poll_for_event(x11_backend->connection); - - if (x11_event != NULL) { - switch (x11_event->response_type & ~0x80) { - case XCB_EXPOSE: { - RuimToplevelEventRedraw redraw; - xcb_configure_notify_event_t *cfg = - (xcb_configure_notify_event_t *)x11_event; - - event->type = RUIM_TOPLEVEL_EVENT_REDRAW; - redraw.width = cfg->width; - redraw.height = cfg->height; - redraw.x = cfg->x; - redraw.y = cfg->y; - - event->data.redraw = redraw; - } break; - case XCB_CLIENT_MESSAGE: { - xcb_client_message_event_t *cm = (xcb_client_message_event_t *)x11_event; - - if (cm->data.data32[0] == x11_backend->wm_delete_window) { - event->type = RUIM_TOPLEVEL_EVENT_QUIT; - } - } break; - case XCB_KEY_PRESS: { - xcb_key_press_event_t *key = (xcb_key_press_event_t *)x11_event; - - event->type = RUIM_TOPLEVEL_EVENT_KEYDOWN; - event->data.mouse.keycode = key->state; - event->data.mouse.x = key->event_x; - event->data.mouse.y = key->event_y; - } break; - case XCB_KEY_RELEASE: { - xcb_key_release_event_t *key = (xcb_key_press_event_t *)x11_event; - - event->type = RUIM_TOPLEVEL_EVENT_KEYUP; - event->data.mouse.keycode = key->state; - event->data.mouse.x = key->event_x; - event->data.mouse.y = key->event_y; - } break; - case XCB_BUTTON_PRESS: { - xcb_button_press_event_t *button = (xcb_button_press_event_t *)x11_event; - - event->type = RUIM_TOPLEVEL_EVENT_MOUSEDOWN; - event->data.mouse.keycode = button->state; - event->data.mouse.x = button->event_x; - event->data.mouse.y = button->event_y; - } break; - case XCB_BUTTON_RELEASE: { - xcb_button_release_event_t *button = - (xcb_button_press_event_t *)x11_event; - - event->type = RUIM_TOPLEVEL_EVENT_MOUSEUP; - event->data.mouse.keycode = button->state; - event->data.mouse.x = button->event_x; - event->data.mouse.y = button->event_y; - } break; - case XCB_CONFIGURE_NOTIFY: { - xcb_configure_notify_event_t *cfg = - (xcb_configure_notify_event_t *)x11_event; - - event->type = RUIM_TOPLEVEL_EVENT_WINDOW; - event->data.window.width = cfg->width; - event->data.window.height = cfg->height; - event->data.window.x = cfg->x; - event->data.window.y = cfg->y; - } break; - default: - break; - } - } else if ((error = xcb_connection_has_error(x11_backend->connection)) != 0) { - _xcb_handle_error(error); - return error; - } else { - event->type = RUIM_TOPLEVEL_EVENT_NOTHING; - } - - free(x11_event); - return 0; -} - -int _wait_event_xcb(RuimToplevel *toplevel) { - struct backend_x11 *backend = (struct backend_x11 *)toplevel->backend->data; - poll(&backend->poll, 1, 1); - - return 0; -} - -int _destroy_toplevel_xcb(RuimToplevel *toplevel) { - free(toplevel->data); - - return 0; -} |