From e57daa001cc74682cdb905d8e0c6c8c3a2c29372 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 10 Oct 2021 10:59:43 +0200 Subject: Initial commit, skeleton --- .gitignore | 5 +++++ LICENSE | 19 +++++++++++++++++++ README.md | 7 +++++++ include/mgl/glx.h | 15 +++++++++++++++ include/mgl/mgl.h | 29 +++++++++++++++++++++++++++++ include/mgl/window.h | 12 ++++++++++++ project.conf | 8 ++++++++ src/glx.c | 39 +++++++++++++++++++++++++++++++++++++++ src/mgl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/window.c | 13 +++++++++++++ tests/main.c | 6 ++++++ 11 files changed, 201 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 include/mgl/glx.h create mode 100644 include/mgl/mgl.h create mode 100644 include/mgl/window.h create mode 100644 project.conf create mode 100644 src/glx.c create mode 100644 src/mgl.c create mode 100644 src/window.c create mode 100644 tests/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..636c6b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c2e5149 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2021 dec05eba + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b96efe3 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Minimal Graphics Library + +# Dependencies +## Build +`xlib` +## Runtime +`libglvnd (libGLX.so, libOpenGL.so)` \ No newline at end of file diff --git a/include/mgl/glx.h b/include/mgl/glx.h new file mode 100644 index 0000000..dfb736d --- /dev/null +++ b/include/mgl/glx.h @@ -0,0 +1,15 @@ +#ifndef MGL_GLX_H +#define MGL_GLX_H + +typedef struct _XDisplay Display; +typedef struct __GLXFBConfigRec *GLXFBConfig; + +typedef struct { + void *handle; + GLXFBConfig* (*glXGetFBConfigs)(Display *dpy, int screen, int *nelements); +} mgl_glx; + +int mgl_glx_load(mgl_glx *self); +void mgl_glx_unload(mgl_glx *self); + +#endif /* MGL_GLX_H */ diff --git a/include/mgl/mgl.h b/include/mgl/mgl.h new file mode 100644 index 0000000..d896497 --- /dev/null +++ b/include/mgl/mgl.h @@ -0,0 +1,29 @@ +#ifndef MGL_MGL_H +#define MGL_MGL_H + +#include "glx.h" + +/* Display* on x11 */ +typedef void* mgl_connection; + +typedef struct { + mgl_connection connection; + mgl_glx glx; +} mgl_context; + +/* + Safe to call multiple times, but will only be initialized the first time called. + Returns non-0 value on failure. + Note: not thread safe. +*/ +int mgl_init(void); + +/* + Safe to call multiple times, but will only be deinitialized the last time called. + Note: not thread safe. +*/ +void mgl_deinit(void); + +mgl_context* mgl_get_context(void); + +#endif /* MGL_MGL_H */ diff --git a/include/mgl/window.h b/include/mgl/window.h new file mode 100644 index 0000000..bd29936 --- /dev/null +++ b/include/mgl/window.h @@ -0,0 +1,12 @@ +#ifndef MGL_WINDOW_H +#define MGL_WINDOW_H + +typedef struct { + int booba; +} mgl_window; + +void mgl_window_init(mgl_window *self); +void mgl_window_deinit(mgl_window *self); +void mgl_window_show(mgl_window *self); + +#endif /* MGL_WINDOW_H */ diff --git a/project.conf b/project.conf new file mode 100644 index 0000000..f9d0fdc --- /dev/null +++ b/project.conf @@ -0,0 +1,8 @@ +[package] +name = "mgl" +type = "static" +version = "0.1.0" +platforms = ["posix"] + +[dependencies] +x11 = ">=1" \ No newline at end of file diff --git a/src/glx.c b/src/glx.c new file mode 100644 index 0000000..4a5af9d --- /dev/null +++ b/src/glx.c @@ -0,0 +1,39 @@ +#include "../include/mgl/glx.h" +#include +#include +#include + +static void* dlsym_print_fail(void *handle, const char *name) { + dlerror(); + void *sym = dlsym(handle, name); + char *err_str = dlerror(); + + if(!sym) + fprintf(stderr, "dlsym(handle, \"%s\") failed, error: %s\n", name, err_str ? err_str : "(null)"); + + return sym; +} + +int mgl_glx_load(mgl_glx *self) { + const char *glx_path = "/usr/lib/libGLX.so.0"; + self->handle = dlopen(glx_path, RTLD_LAZY); + if(!self->handle) { + fprintf(stderr, "dlopen(\"%s\", RTLD_LAZY) failed\n", glx_path); + return -1; + } + + self->glXGetFBConfigs = (GLXFBConfig* (*)(Display*, int, int*))dlsym_print_fail(self->handle, "glXGetFBConfigs"); + if(!self->glXGetFBConfigs) { + mgl_glx_unload(self); + return -1; + } + + return 0; +} + +void mgl_glx_unload(mgl_glx *self) { + if(self->handle) { + dlclose(self->handle); + self->handle = NULL; + } +} diff --git a/src/mgl.c b/src/mgl.c new file mode 100644 index 0000000..a7221d0 --- /dev/null +++ b/src/mgl.c @@ -0,0 +1,48 @@ +#include "../include/mgl/mgl.h" +#include +#include + +static mgl_context context; +static int init_count = 0; +static XErrorHandler prev_xerror = NULL; + +static int ignore_xerror(Display *display, XErrorEvent *ee) { + (void)display; + (void)ee; + return 0; +} + +int mgl_init(void) { + ++init_count; + if(init_count == 1) { + context.connection = XOpenDisplay(NULL); + if(!context.connection) { + fprintf(stderr, "XOpenDisplay(NULL) failed\n"); + mgl_deinit(); + return -1; + } + + prev_xerror = XSetErrorHandler(ignore_xerror); + if(mgl_glx_load(&context.glx) != 0) { + mgl_deinit(); + return -1; + } + } + return 0; +} + +void mgl_deinit(void) { + if(init_count == 1) { + mgl_glx_unload(&context.glx); + XSetErrorHandler(prev_xerror); + XCloseDisplay(context.connection); + context.connection = NULL; + } + + if(init_count > 0) + --init_count; +} + +mgl_context* mgl_get_context(void) { + return &context; +} diff --git a/src/window.c b/src/window.c new file mode 100644 index 0000000..39855da --- /dev/null +++ b/src/window.c @@ -0,0 +1,13 @@ +#include "../include/mgl/window.h" + +void mgl_window_init(mgl_window *self) { + +} + +void mgl_window_deinit(mgl_window *self) { + +} + +void mgl_window_show(mgl_window *self) { + +} diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..ff1570b --- /dev/null +++ b/tests/main.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char **argv) { + printf("hello, world!\n"); + return 0; +} -- cgit v1.2.3