project for a (works on my devices) demo

This commit is contained in:
beno
2026-03-13 02:28:59 +01:00
parent a00ae79ab5
commit dc39a56e91
36 changed files with 3892 additions and 61 deletions

View File

@@ -0,0 +1,83 @@
#include "application_context.h"
#include "window/window.h"
#include "../os/WAYLAND/wl_context.h"
#include "../os/EGL/egl_context.h"
#include "../os/EGL/GLES_3_1_compatibility.h"
#include <wayland-egl.h>
#include <stdlib.h>
#include <stdio.h>
application_context* application_context_malloc(){
application_context *app = malloc( sizeof( application_context));
return app;
}
application_context* application_context_new( const char *title){
wl_context *wl;
egl_context *egl;
gui_component *win;
application_context *app;
app = application_context_malloc();
/* get the builders and the display connection */
wl = wl_context_new();
app->w_context = wl;
fprintf(stderr, "created WL_CONTEXT\n");
/* builds the minimal for a running */
win = window_new(
title,
ui_dimensions_new(
wl_context_get(GLUT_SCREEN_WIDTH),
wl_context_get(GLUT_SCREEN_HEIGHT)
),
app
);
fprintf(stderr, "CREATED WINDOW\n");
/* ??? allocates the required struct for binding a buffer to the wl_surface of the window's toplevel */
app->win = win;
app->running = 1;
window_gui_enrichment *win_x = ( window_gui_enrichment* ) win->specialization;
win_x->egl_window = wl_egl_window_create( win->graphics->surface, win->graphics->dimensions->w, win->graphics->dimensions->h);
/* EGL_NO_SURFACE */
if (NULL == win_x->egl_window) {
fprintf(stderr, "Couldn't create EGL window\n");
exit(1);
}
/* gets the context for GLES2 graphics API */
egl = egl_context_new( wl->display);
app->e_context = egl;
win_x->egl_surface = eglCreateWindowSurface(
egl->display,
egl->config,
(EGLNativeWindowType) win_x->egl_window,
NULL
);
if( EGL_NO_SURFACE == win_x->egl_surface) {
fprintf(stderr, "Couldn't create EGL surface\n");
printEGLError();
exit(EXIT_FAILURE);
}
if( ! eglMakeCurrent(egl->display, win_x->egl_surface, win_x->egl_surface, egl->context)) {
fprintf(stderr, "Couldn't make EGL context current\n");
exit(EXIT_FAILURE);
}
GLES_3_1_compatibility_init();
return app;
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "../os/WAYLAND/wl_context.h"
#include "../os/EGL/egl_context.h"
#include "gui_component/gui_component.h"
typedef struct {
wl_context *w_context;
egl_context *e_context;
gui_component *win;
uint8_t running;
} application_context;
application_context* application_context_malloc();
application_context* application_context_new( const char *title);

View File

@@ -0,0 +1,87 @@
#include "gui_component.h"
#include "listeners/xdg_surface_listener.h"
#include <stdlib.h>
/*
listener to be bound on XDG surfaces
the only event declared by the xdg_surface is the "configure" one
indicates the hint for the client to update the arrangement of surfaces ( i.e. change of resolution )
*/
const struct xdg_surface_listener surface_listener = {
surface_configure
};
gui_component_graphics* gui_component_graphics_new(
ui_position *pos,
ui_dimensions *dim,
surface_builders *builders
){
gui_component_graphics *g = malloc( sizeof( gui_component_graphics));
g->dimensions = dim;
g->position = pos;
g->surface = wl_compositor_create_surface( builders->compositor);
g->xdg_surface = xdg_wm_base_get_xdg_surface( builders->xdg_wm_base, g->surface);
xdg_surface_add_listener( g->xdg_surface, &surface_listener, NULL);
return g;
}
gui_component* gui_component_new_begin(
gui_component *parent,
ui_position *pos,
ui_dimensions *dim,
void (*draw_callback) ( gui_component*, int),
void (*resize_callback) ( gui_component*, resize_event*),
void (*input_callback) ( gui_component*, resize_event*),
surface_builders *builders
){
gui_component* c = malloc( sizeof( gui_component));
c->specialization = NULL;
c->graphics = gui_component_graphics_new( pos, dim, builders);
c->draw_callback = draw_callback;
if( parent){
gui_component_add_child( parent, c);
}
c->children = gui_components_list_new();
return c;
}
void gui_component_new_end( gui_component* toComplete){
/*
must be called at the end of the configuration
*/
wl_surface_commit( toComplete->graphics->surface);
}
void gui_component_add_child( gui_component *parent, gui_component *child){
/* missing args */
if( ! parent || ! child){
}
/* components cannot be moved around at the moment, plug once and bye */
if( child->parent){
}
child->parent = parent;
gui_components_list_add( parent->children, child);
}
void child_draw( gui_component* child, void *extra){
int *casted = (int*) extra;
int deltaTime = *casted;
gui_component_draw( child, deltaTime);
}
void gui_component_draw( gui_component *c, int deltaTime){
c->draw_callback( c, deltaTime);
gui_components_list_foreach( c->children, child_draw, (void*) &deltaTime);
}

View File

@@ -0,0 +1,72 @@
#pragma once
#include "../../os/WAYLAND/wl_context.h"
#include "../../2d_structs.h"
#include "gui_components_list.h"
typedef struct {
int type;
} input_event;
typedef struct {
int w;
int h;
} resize_event;
typedef struct {
ui_dimensions *dimensions;
ui_position *position;
struct wl_surface *surface;
struct xdg_surface *xdg_surface;
}
gui_component_graphics;
typedef struct gui_component_raw {
void ( *draw_callback) ( struct gui_component_raw*, int);
void ( *resize_callback) ( struct gui_component_raw*, resize_event*);
void ( *input_callback) ( struct gui_component_raw*, resize_event*);
struct gui_component_raw *parent;
struct gui_components_list_raw *children;
gui_component_graphics *graphics;
void *specialization;
}
gui_component;
gui_component_graphics* gui_component_graphics_new(
ui_position *pos,
ui_dimensions *dim,
surface_builders *builders
);
/* called for initializing common configs */
gui_component* gui_component_new_begin(
gui_component *parent,
ui_position *pos,
ui_dimensions *dim,
void (*draw_callback) ( gui_component*, int),
void (*resize_callback) ( gui_component*, resize_event*),
void (*input_callback) ( gui_component*, resize_event*),
surface_builders *builders
);
/* must be called after specialized init for completing the configuration */
void gui_component_new_end( gui_component* toComplete);
void gui_component_add_child( gui_component *parent, gui_component *child);
void gui_component_draw( gui_component *c, int deltaTime);
void gui_component_input_event( gui_component *c, input_event *e);
void gui_component_resize_event( gui_component *c, resize_event *e);
/*
draw callback
input callback
resize callback
*/

View File

@@ -0,0 +1,28 @@
#include "gui_components_list.h"
#include <stdlib.h>
gui_components_list* gui_components_list_new(){
gui_components_list *l = malloc( sizeof( gui_components_list));
l->count = 0;
TAILQ_INIT(&( l->queue));
return l;
}
void gui_components_list_add( gui_components_list* list, gui_component *toAdd){
gui_components_list_entry *entry = malloc( sizeof( gui_components_list_entry));
entry->data = toAdd;
TAILQ_INSERT_TAIL( &(list->queue), entry, gui_components_list_entries);
list->count++;
}
void gui_components_list_foreach( gui_components_list* list, void ( *toRun) ( gui_component*, void*), void* extra){
gui_components_list_head *headp = &( list->queue);
gui_components_list_entry *current;
TAILQ_FOREACH( current, headp, gui_components_list_entries){
toRun( current->data, extra);
}
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include "gui_component.h"
#include <sys/queue.h>
/*
typedef struct AAA_RAW {
void *data;
TAILQ_ENTRY(AAA_RAW) AAAs; // Singly linked List
} AAA;
typedef TAILQ_HEAD(BBB_RAW, AAA_RAW) BBB;
typedef struct {
BBB queue;
int count;
} CCC;
*/
typedef struct gui_components_list_entry_raw {
struct gui_component_raw *data;
TAILQ_ENTRY(gui_components_list_entry_raw) gui_components_list_entries; /* Singly linked List. */
} gui_components_list_entry;
typedef TAILQ_HEAD(gui_components_list_head_raw, gui_components_list_entry_raw) gui_components_list_head;
typedef struct gui_components_list_raw {
gui_components_list_head queue;
int count;
}
gui_components_list;
gui_components_list* gui_components_list_new();
void gui_components_list_add( gui_components_list *list, struct gui_component_raw *toAdd);
void gui_components_list_foreach( gui_components_list *list, void (*toRun) ( struct gui_component_raw*, void*), void *extra);

View File

@@ -0,0 +1,16 @@
#include "xdg_surface_listener.h"
/******************************/
/********XDG surface **********/
/******************************/
/* listener bound to the various xdg_surfaces for listening to "configure" events
the client should rearrange its surfaces to accomodate the new state
the client should answer to (ACK) the event
*/
void surface_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial) {
(void) data;
xdg_surface_ack_configure(xdg_surface, serial);
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "../../../os/WAYLAND/xdg-shell.h"
void surface_configure(
void *data,
struct xdg_surface *xdg_surface,
uint32_t serial
);

View File

@@ -0,0 +1,7 @@
gui_component* panel_new(
gui_component *parent,
ui_position *pos,
ui_dimensions *dim
){
}

View File

@@ -0,0 +1,7 @@
#pragma once
gui_component* panel_new(
gui_component *parent,
ui_position *pos,
ui_dimensions *dim
);

View File

@@ -0,0 +1,62 @@
#include "xdg_toplevel_listener.h"
#include "../window.h"
#include "../../application_context.h"
#include <wayland-egl.h>
#include <stdlib.h>
#include <stdio.h>
/******************************/
/********XDG Toplevel**********/
/******************************/
/* listener bound to the toplevel surface
the toplevel may raise a "configure" event, which hints the client about reconfiguring its state
here we propagate the new width and height to the EGL window ( probably for readjusting buffers )
*/
void toplevel_configure(
void *data,
struct xdg_toplevel *xdg_toplevel,
int32_t width,
int32_t height,
struct wl_array *states
) {
(void) states;
gui_component *comp = data;
if( ! comp){
fprintf(stderr, "inconsistency during toplevel configure : no payload\n");
exit(EXIT_FAILURE);
}
window_gui_enrichment *win = (window_gui_enrichment*) comp->specialization;
if( ! win || win->xdg_toplevel != xdg_toplevel){
fprintf(stderr, "inconsistency during toplevel configure\n");
fprintf(stderr, "window->xdg_toplevel %p\nxdg_toplevel %p\n",
(void*) win->xdg_toplevel,
(void*) xdg_toplevel
);
exit(EXIT_FAILURE);
}
if(!width && !height) return;
if( comp->graphics->dimensions->w != width || comp->graphics->dimensions->h != height) {
comp->graphics->dimensions->w = width;
comp->graphics->dimensions->h = height;
wl_egl_window_resize(win->egl_window, width, height, 0, 0);
wl_surface_commit(comp->graphics->surface);
}
}
void toplevel_close( void *data, struct xdg_toplevel *xdg_toplevel) {
(void) xdg_toplevel;
application_context *app = data;
app->running = 0;
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "../../../os/WAYLAND/xdg-shell.h"
/******************************/
/********XDG Toplevel**********/
/******************************/
/* listener bound to the toplevel surface
the toplevel may raise a "configure" event, which hints the client about reconfiguring its state
here we propagate the new width and height to the EGL window ( probably for readjusting buffers )
*/
void toplevel_configure(
void *data,
struct xdg_toplevel *xdg_toplevel,
int32_t width,
int32_t height,
struct wl_array *states
);
void toplevel_close( void *data, struct xdg_toplevel *xdg_toplevel);

View File

@@ -0,0 +1,80 @@
#include "window.h"
#include "listeners/xdg_toplevel_listener.h"
#include "../../os/WAYLAND/xdg-shell.h"
#include <wayland-egl.h>
#include <GLES2/gl2.h>
#include <stdlib.h>
#include <stdio.h>
const struct xdg_toplevel_listener toplevel_listener = {
toplevel_configure,
toplevel_close
};
/******************************/
/************APIs**************/
/******************************/
window_gui_enrichment *window_gui_enrichment_new(
struct xdg_surface *xdg_surface,
const char *title,
application_context *ctx
){
window_gui_enrichment *win;
win->egl_window = NULL;
win->egl_surface = NULL;
win->ctx = ctx;
win->xdg_toplevel = xdg_surface_get_toplevel( xdg_surface);
xdg_toplevel_set_title( win->xdg_toplevel, title);
xdg_toplevel_add_listener( win->xdg_toplevel, &toplevel_listener, win);
return win;
}
void swapBuffers( application_context *app){
window_gui_enrichment *win = (window_gui_enrichment*) app->win->specialization;
wl_display_dispatch_pending(app->w_context->display);
eglSwapBuffers( app->e_context->display, win->egl_surface);
}
void draw_callback( gui_component* toDraw, int deltaTime){
glClearColor(1, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* should iterate on all the children */
window_gui_enrichment *win = toDraw->specialization;
swapBuffers( win->ctx);
}
gui_component* window_new(
const char *title,
ui_dimensions *dim,
application_context *app
){
void (*resize_callback) ( gui_component*, resize_event*) = 0;
void (*input_callback) ( gui_component*, resize_event*) = 0;
fprintf(stderr, "WINDOW NEW\n");
gui_component *c = gui_component_new_begin( NULL, ui_position_new(0, 0), dim, draw_callback, resize_callback, input_callback, app->w_context->builders );
fprintf(stderr, "WINDOW DID GUI_COMP_NEW\n");
window_gui_enrichment *spec = window_gui_enrichment_new( c->graphics->xdg_surface, title, app);
c->specialization = (void*) spec;
fprintf(stderr, "WINDOW DID ENRICHMENT NEW\n");
gui_component_new_end( c);
return c;
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include "../gui_component/gui_component.h"
#include "../application_context.h"
#include <EGL/egl.h>
#include "../../os/WAYLAND/wl_context.h"
#include "../../2d_structs.h"
#include "../../os/WAYLAND/xdg-shell.h"
typedef struct {
struct xdg_toplevel *xdg_toplevel;
struct wl_egl_window *egl_window;
EGLSurface *egl_surface;
application_context *ctx;
}
window_gui_enrichment;
window_gui_enrichment *window_gui_enrichment_new(
struct xdg_surface *xdg_surface,
const char *title,
application_context *ctx
);
/* the toplevel listener registration callback offers a void* arg for passing data inside the callback (our app state in this case, waiting for narrowing) */
gui_component* window_new(
const char *title,
ui_dimensions *dim,
application_context *ctx
);