project for a (works on my devices) demo

This commit is contained in:
beno
2026-03-13 16:48:03 +01:00
parent 0c0b42fbd0
commit 7ca7ec5d61
38 changed files with 4797 additions and 62 deletions

300
sources/glut_backend.c Normal file
View File

@@ -0,0 +1,300 @@
/* for nanosleep */
#define _POSIX_C_SOURCE 199309L
#include <time.h> /*nanosleep*/
#include <stdlib.h> /*malloc*/
#include <stdio.h> /*fprintf*/
#include <string.h>
#include <EGL/egl.h> /*graphic context*/
#include <wayland-egl.h>
#include <wayland-client.h>
#include "../headers/backend_resources/xdg-shell.h"
#include "../headers/glut_backend.h"
#include <my_device_handler.h>
struct client_state {
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct xdg_wm_base *xdg_wm_base;
struct wl_surface *surface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *xdg_toplevel;
/**/
struct wl_egl_window *egl_window;
EGLDisplay egl_display;
EGLConfig egl_config;
EGLContext egl_context;
EGLSurface egl_surface;
int32_t width;
int32_t height;
uint8_t running;
};
static struct client_state state;
static void global_registry(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_compositor_interface.name)) {
state->compositor = wl_registry_bind(wl_registry, name,
&wl_compositor_interface, version);
} else if(!strcmp(interface, xdg_wm_base_interface.name)) {
state->xdg_wm_base = wl_registry_bind(wl_registry, name,
&xdg_wm_base_interface, version);
}
}
static void global_remove(void *data, struct wl_registry *wl_registry,
uint32_t name) {
(void) data;
(void) wl_registry;
(void) name;
}
static const struct wl_registry_listener registry_listener = {
global_registry,
global_remove
};
static void wm_ping(void *data, struct xdg_wm_base *xdg_wm_base,
uint32_t serial) {
(void) data;
xdg_wm_base_pong(xdg_wm_base, serial);
}
static const struct xdg_wm_base_listener wm_base_listener = {
wm_ping
};
static void surface_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial) {
(void) data;
xdg_surface_ack_configure(xdg_surface, serial);
}
static const struct xdg_surface_listener surface_listener = {
surface_configure
};
/******************************/
/********XDG Toplevel**********/
/******************************/
static void toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height, struct wl_array *states) {
struct client_state *state = data;
(void) xdg_toplevel;
(void) states;
if(!width && !height) return;
if(state->width != width || state->height != height) {
state->width = width;
state->height = height;
wl_egl_window_resize(state->egl_window, width, height, 0, 0);
wl_surface_commit(state->surface);
}
}
static void toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) {
(void) xdg_toplevel;
struct client_state *state = data;
state->running = 0;
}
static const struct xdg_toplevel_listener toplevel_listener = {
toplevel_configure,
toplevel_close
};
static void wayland_connect(struct client_state *state) {
state->display = wl_display_connect(NULL);
if(!state->display) {
fprintf(stderr, "Couldn't connect to wayland display\n");
exit(EXIT_FAILURE);
}
state->registry = wl_display_get_registry(state->display);
wl_registry_add_listener(state->registry, &registry_listener, state);
wl_display_roundtrip(state->display);
if(!state->compositor || !state->xdg_wm_base) {
fprintf(stderr, "Couldn't find compositor or xdg shell\n");
exit(EXIT_FAILURE);
}
xdg_wm_base_add_listener(state->xdg_wm_base, &wm_base_listener, NULL);
state->surface = wl_compositor_create_surface(state->compositor);
state->xdg_surface = xdg_wm_base_get_xdg_surface(state->xdg_wm_base,
state->surface);
xdg_surface_add_listener(state->xdg_surface, &surface_listener, NULL);
state->xdg_toplevel = xdg_surface_get_toplevel(state->xdg_surface);
xdg_toplevel_set_title(state->xdg_toplevel, "Hello World");
xdg_toplevel_add_listener(state->xdg_toplevel, &toplevel_listener, state);
wl_surface_commit(state->surface);
}
/**/
static void egl_init(struct client_state *state) {
EGLint major;
EGLint minor;
EGLint num_configs;
/*
replaced EGL_OPENGL_BIT with EGL_OPENGL_ES2_BIT
*/
EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
state->egl_window = wl_egl_window_create(state->surface, state->width,
state->height);
state->egl_display = eglGetDisplay((EGLNativeDisplayType) state->display);
if(state->display == EGL_NO_DISPLAY) {
fprintf(stderr, "Couldn't get EGL display\n");
exit(EXIT_FAILURE);
}
if(eglInitialize(state->egl_display, &major, &minor) != EGL_TRUE) {
fprintf(stderr, "Couldnt initialize EGL\n");
exit(EXIT_FAILURE);
}
if(eglChooseConfig(state->egl_display, attribs, &state->egl_config, 1,
&num_configs) != EGL_TRUE) {
fprintf(stderr, "CouldnÄt find matching EGL config\n");
exit(EXIT_FAILURE);
}
state->egl_surface = eglCreateWindowSurface(state->egl_display,
state->egl_config,
(EGLNativeWindowType) state->egl_window, NULL);
if(state->egl_surface == EGL_NO_SURFACE) {
fprintf(stderr, "Couldn't create EGL surface\n");
exit(EXIT_FAILURE);
}
/* added from
https://stackoverflow.com/questions/25843368/glgetstringgl-version-returns-opengl-es-cm-1-1-but-my-phone-supports-opengl
*/
const EGLint context_attrib_list[] = {
// request a context using Open GL ES 2.0
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
/*thanks to the dudes of stackoverflow for explaining how the attrib_list works*/
state->egl_context = eglCreateContext(state->egl_display, state->egl_config,
EGL_NO_CONTEXT, context_attrib_list);
if(state->egl_context == EGL_NO_CONTEXT) {
fprintf(stderr, "Couldn't create EGL context\n");
exit(EXIT_FAILURE);
}
if(!eglMakeCurrent(state->egl_display, state->egl_surface,
state->egl_surface, state->egl_context)) {
fprintf(stderr, "Couldn't make EGL context current\n");
exit(EXIT_FAILURE);
}
}
/* refer to demo_2_egl */
void init_implementation( char **paths, int count){
device_handler_init();
for( int i = 0; i < count; i++){
device_handler_add(paths[i]);
}
}
int create_window_implementation( const char *title){
state.running = 1;
wayland_connect(&state);
/*
*/
egl_init(&state);
}
void init_window_size_implementation( int width, int height){
state.width = width;
state.height = height;
}
/* BAD implementation : perpetual malloc and free */
void sleep_implementation(){
/* the second field should be the remainder, in case of premature ending */
struct timespec *millisecond = malloc( sizeof( struct timespec));
millisecond->tv_sec=0;
millisecond->tv_nsec=1e6;
nanosleep( millisecond, NULL); /*won't compensate any delay due to the loop body*/
free(millisecond);
}
void swap_buffers_implementation(){
/* should not be here (glued) */
wl_display_dispatch_pending(state.display);
eglSwapBuffers( state.egl_display, state.egl_surface);
}