project for a (works on my devices) demo
This commit is contained in:
63
SOURCES/graphics/2d_structs.c
Normal file
63
SOURCES/graphics/2d_structs.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "./2d_structs.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
ui_dimensions* ui_dimensions_malloc(){
|
||||
size_t d_size = sizeof( ui_dimensions);
|
||||
ui_dimensions *d = malloc(d_size);
|
||||
memset( d, 0, d_size);
|
||||
return d;
|
||||
}
|
||||
|
||||
ui_position* ui_position_malloc(){
|
||||
size_t p_size = sizeof( ui_position);
|
||||
ui_position *p = malloc(p_size);
|
||||
memset( p, 0, p_size);
|
||||
return p;
|
||||
}
|
||||
|
||||
ui_dimensions* ui_dimensions_new( uint16_t w, uint16_t h){
|
||||
size_t d_size = sizeof( ui_dimensions);
|
||||
ui_dimensions *d = malloc(d_size);
|
||||
d->w = w;
|
||||
d->h = h;
|
||||
return d;
|
||||
}
|
||||
|
||||
ui_position* ui_position_new( uint16_t x, uint16_t y){
|
||||
size_t p_size = sizeof( ui_position);
|
||||
ui_position *p = malloc(p_size);
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
return p;
|
||||
}
|
||||
|
||||
f_dimensions* f_dimensions_malloc(){
|
||||
size_t d_size = sizeof( f_dimensions);
|
||||
f_dimensions *d = malloc(d_size);
|
||||
memset( d, 0, d_size);
|
||||
return d;
|
||||
}
|
||||
|
||||
f_position* f_position_malloc(){
|
||||
size_t p_size = sizeof( f_position);
|
||||
f_position *p = malloc(p_size);
|
||||
memset( p, 0, p_size);
|
||||
return p;
|
||||
}
|
||||
|
||||
f_dimensions* f_dimensions_new( float w, float h){
|
||||
size_t d_size = sizeof( f_dimensions);
|
||||
f_dimensions *d = malloc(d_size);
|
||||
d->w = w;
|
||||
d->h = h;
|
||||
return d;
|
||||
}
|
||||
|
||||
f_position* f_position_new( float x, float y){
|
||||
size_t p_size = sizeof( f_position);
|
||||
f_position *p = malloc(p_size);
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
return p;
|
||||
}
|
||||
36
SOURCES/graphics/2d_structs.h
Normal file
36
SOURCES/graphics/2d_structs.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
} ui_dimensions;
|
||||
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} ui_position;
|
||||
|
||||
|
||||
ui_dimensions* ui_dimensions_malloc();
|
||||
ui_dimensions* ui_dimensions_new( uint16_t w, uint16_t h);
|
||||
|
||||
ui_position* ui_position_malloc();
|
||||
ui_position* ui_position_new( uint16_t x, uint16_t y);
|
||||
|
||||
typedef struct {
|
||||
float w;
|
||||
float h;
|
||||
} f_dimensions;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} f_position;
|
||||
|
||||
|
||||
f_dimensions* f_dimensions_malloc();
|
||||
f_dimensions*f_dimensions_new( float w, float h);
|
||||
|
||||
f_position* f_position_malloc();
|
||||
f_position* f_position_new( float x, float y);
|
||||
126
SOURCES/graphics/Makefile
Normal file
126
SOURCES/graphics/Makefile
Normal file
@@ -0,0 +1,126 @@
|
||||
include external.mk
|
||||
|
||||
GBD=${BD}graphics/
|
||||
GS=SOURCES/graphics/
|
||||
|
||||
REGISTRY_LISTENERS=${GBD}os/WAYLAND/registry_listeners/wl_output_listener.o ${GBD}os/WAYLAND/registry_listeners/xdg_wm_base_listener.o
|
||||
WAYLAND_OBJECTS=${GBD}os/WAYLAND/wl_context.o ${GBD}os/WAYLAND/xdg-shell.o ${REGISTRY_LISTENERS}
|
||||
|
||||
OS_GRAPHICS_OBJECTS=${GBD}2d_structs.o ${WAYLAND_OBJECTS} ${GBD}os/EGL/egl_context.o ${GBD}os/EGL/GLES_3_1_compatibility.o
|
||||
|
||||
|
||||
GUI_COMPONENT_OBJECTS=${GBD}library/gui_component/gui_component.o ${GBD}library/gui_component/gui_components_list.o ${GBD}library/gui_component/listeners/xdg_surface_listener.o
|
||||
WINDOW_OBJECTS=${GBD}library/window/window.o ${GBD}library/window/listeners/xdg_toplevel_listener.o
|
||||
LIBRARY_GRAPHICS_OBJECTS=${GUI_COMPONENT_OBJECTS} ${WINDOW_OBJECTS} ${GBD}library/application_context.o
|
||||
|
||||
export GRAPHICS_OBJECTS=${OS_GRAPHICS_OBJECTS} ${LIBRARY_GRAPHICS_OBJECTS}
|
||||
|
||||
|
||||
|
||||
${GBD}2d_structs.o : ${GS}2d_structs.c ${GS}2d_structs.h
|
||||
${COMPILER} \
|
||||
-o ${GBD}2d_structs.o \
|
||||
-c ${CFLAGS} ${GS}2d_structs.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}os/WAYLAND/wl_context.o : ${GS}os/WAYLAND/wl_context.c ${GS}os/WAYLAND/wl_context.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}os/WAYLAND/wl_context.o \
|
||||
-c ${CFLAGS} ${GS}os/WAYLAND/wl_context.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}os/WAYLAND/xdg-shell.o : ${GS}os/WAYLAND/xdg-shell.c ${GS}os/WAYLAND/xdg-shell.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}os/WAYLAND/xdg-shell.o \
|
||||
-c ${CFLAGS} ${GS}os/WAYLAND/xdg-shell.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}os/WAYLAND/registry_listeners/wl_output_listener.o : ${GS}os/WAYLAND/registry_listeners/wl_output_listener.c ${GS}os/WAYLAND/registry_listeners/wl_output_listener.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}os/WAYLAND/registry_listeners/wl_output_listener.o \
|
||||
-c ${CFLAGS} ${GS}os/WAYLAND/registry_listeners/wl_output_listener.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}os/WAYLAND/registry_listeners/xdg_wm_base_listener.o : ${GS}os/WAYLAND/registry_listeners/xdg_wm_base_listener.c ${GS}os/WAYLAND/registry_listeners/xdg_wm_base_listener.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}os/WAYLAND/registry_listeners/xdg_wm_base_listener.o \
|
||||
-c ${CFLAGS} ${GS}os/WAYLAND/registry_listeners/xdg_wm_base_listener.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
|
||||
${GBD}os/EGL/egl_context.o : ${GS}os/EGL/egl_context.c ${GS}os/EGL/egl_context.h
|
||||
${COMPILER} \
|
||||
${I_EGL} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}os/EGL/egl_context.o \
|
||||
-c ${CFLAGS} ${GS}os/EGL/egl_context.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}os/EGL/GLES_3_1_compatibility.o : ${GS}os/EGL/GLES_3_1_compatibility.c ${GS}os/EGL/GLES_3_1_compatibility.h
|
||||
${COMPILER} \
|
||||
${I_EGL} \
|
||||
-o ${GBD}os/EGL/GLES_3_1_compatibility.o \
|
||||
-c ${CFLAGS} ${GS}os/EGL/GLES_3_1_compatibility.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
${GBD}library/gui_component/gui_component.o : ${GS}library/gui_component/gui_component.c ${GS}library/gui_component/gui_component.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}library/gui_component/gui_component.o \
|
||||
-c ${CFLAGS} ${GS}library/gui_component/gui_component.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}library/gui_component/gui_components_list.o : ${GS}library/gui_component/gui_components_list.c ${GS}library/gui_component/gui_components_list.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}library/gui_component/gui_components_list.o \
|
||||
-c ${CFLAGS} ${GS}library/gui_component/gui_components_list.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}library/gui_component/listeners/xdg_surface_listener.o : ${GS}library/gui_component/listeners/xdg_surface_listener.c ${GS}library/gui_component/listeners/xdg_surface_listener.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}library/gui_component/listeners/xdg_surface_listener.o \
|
||||
-c ${CFLAGS} ${GS}library/gui_component/listeners/xdg_surface_listener.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
${GBD}library/window/window.o : ${GS}library/window/window.c ${GS}library/window/window.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
${I_EGL} \
|
||||
-o ${GBD}library/window/window.o \
|
||||
-c ${CFLAGS} ${GS}library/window/window.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
${GBD}library/window/listeners/xdg_toplevel_listener.o : ${GS}library/window/listeners/xdg_toplevel_listener.c ${GS}library/window/listeners/xdg_toplevel_listener.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${GBD}library/window/listeners/xdg_toplevel_listener.o \
|
||||
-c ${CFLAGS} ${GS}library/window/listeners/xdg_toplevel_listener.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
|
||||
|
||||
|
||||
# -I ./ è una porcata clamorosa
|
||||
${GBD}library/application_context.o : ${GS}library/application_context.c ${GS}library/application_context.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
${I_EGL} \
|
||||
-o ${GBD}library/application_context.o \
|
||||
-c ${CFLAGS} ${GS}library/application_context.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
83
SOURCES/graphics/library/application_context.c
Normal file
83
SOURCES/graphics/library/application_context.c
Normal 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;
|
||||
}
|
||||
18
SOURCES/graphics/library/application_context.h
Normal file
18
SOURCES/graphics/library/application_context.h
Normal 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);
|
||||
87
SOURCES/graphics/library/gui_component/gui_component.c
Normal file
87
SOURCES/graphics/library/gui_component/gui_component.c
Normal 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);
|
||||
}
|
||||
72
SOURCES/graphics/library/gui_component/gui_component.h
Normal file
72
SOURCES/graphics/library/gui_component/gui_component.h
Normal 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
|
||||
*/
|
||||
28
SOURCES/graphics/library/gui_component/gui_components_list.c
Normal file
28
SOURCES/graphics/library/gui_component/gui_components_list.c
Normal 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);
|
||||
}
|
||||
}
|
||||
41
SOURCES/graphics/library/gui_component/gui_components_list.h
Normal file
41
SOURCES/graphics/library/gui_component/gui_components_list.h
Normal 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);
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
7
SOURCES/graphics/library/panel/panel.c
Normal file
7
SOURCES/graphics/library/panel/panel.c
Normal file
@@ -0,0 +1,7 @@
|
||||
gui_component* panel_new(
|
||||
gui_component *parent,
|
||||
ui_position *pos,
|
||||
ui_dimensions *dim
|
||||
){
|
||||
|
||||
}
|
||||
7
SOURCES/graphics/library/panel/panel.h
Normal file
7
SOURCES/graphics/library/panel/panel.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
gui_component* panel_new(
|
||||
gui_component *parent,
|
||||
ui_position *pos,
|
||||
ui_dimensions *dim
|
||||
);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
80
SOURCES/graphics/library/window/window.c
Normal file
80
SOURCES/graphics/library/window/window.c
Normal 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;
|
||||
}
|
||||
32
SOURCES/graphics/library/window/window.h
Normal file
32
SOURCES/graphics/library/window/window.h
Normal 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
|
||||
);
|
||||
33
SOURCES/graphics/os/EGL/GLES_3_1_compatibility.c
Normal file
33
SOURCES/graphics/os/EGL/GLES_3_1_compatibility.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "GLES_3_1_compatibility.h"
|
||||
|
||||
/* fails at link time,
|
||||
resorting to eglGetProcAddress
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include <GLES2/gl2ext.h>
|
||||
*/
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOES;
|
||||
PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOES;
|
||||
PFNGLDRAWBUFFERSEXTPROC glDrawBuffersEXT;
|
||||
|
||||
void glGenVertexArrays( GLuint n, GLuint *arrays_ptr) {
|
||||
glGenVertexArraysOES( n, arrays_ptr);
|
||||
}
|
||||
|
||||
void glBindVertexArray( GLuint array_ptr) {
|
||||
glBindVertexArrayOES( array_ptr);
|
||||
}
|
||||
|
||||
/* https://registry.khronos.org/OpenGL/extensions/OES/OES_framebuffer_object.txt */
|
||||
void glDrawBuffers( GLsizei n,GLenum *buffers_ptr) {
|
||||
glDrawBuffersEXT( n, buffers_ptr);
|
||||
}
|
||||
|
||||
void GLES_3_1_compatibility_init(){
|
||||
glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
|
||||
glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
|
||||
glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)eglGetProcAddress("glDrawBuffersEXT");
|
||||
}
|
||||
36
SOURCES/graphics/os/EGL/GLES_3_1_compatibility.h
Normal file
36
SOURCES/graphics/os/EGL/GLES_3_1_compatibility.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
/* fails at link time,
|
||||
resorting to eglGetProcAddress
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
*/
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
/* aarch64-linux-gnu/include/math.h already defines it */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
/* GLES2 provides it as an extension */
|
||||
#ifndef GL_DEPTH24_STENCIL8
|
||||
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
|
||||
#endif
|
||||
|
||||
#ifndef GL_DEPTH_STENCIL_ATTACHMENT
|
||||
#define GL_DEPTH_STENCIL_ATTACHMENT GL_DEPTH_STENCIL_OES
|
||||
#endif
|
||||
|
||||
#ifndef GL_DRAW_FRAMEBUFFER
|
||||
#define GL_DRAW_FRAMEBUFFER GL_DRAW_BUFFER0_EXT
|
||||
#endif
|
||||
|
||||
void glGenVertexArrays( GLuint n, GLuint *arrays_ptr);
|
||||
|
||||
void glBindVertexArray( GLuint array_ptr);
|
||||
|
||||
void glDrawBuffers( GLsizei n,GLenum *buffers_ptr);
|
||||
|
||||
void GLES_3_1_compatibility_init();
|
||||
138
SOURCES/graphics/os/EGL/egl_context.c
Normal file
138
SOURCES/graphics/os/EGL/egl_context.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "egl_context.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void printEGLError(){
|
||||
EGLint errorCode = eglGetError();
|
||||
switch (errorCode){
|
||||
case EGL_SUCCESS:
|
||||
printf("EGL_SUCCESS : The last function succeeded without error.\n");
|
||||
break;
|
||||
case EGL_NOT_INITIALIZED:
|
||||
printf("EGL_NOT_INITIALIZED : EGL is not initialized, or could not be initialized, for the specified EGL display connection.\n");
|
||||
break;
|
||||
case EGL_BAD_ACCESS:
|
||||
printf("EGL_BAD_ACCESS : EGL cannot access a requested resource (for example a context is bound in another thread).\n");
|
||||
break;
|
||||
case EGL_BAD_ALLOC:
|
||||
printf("EGL_BAD_ALLOC : EGL failed to allocate resources for the requested operation.\n");
|
||||
break;
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
printf("EGL_BAD_ATTRIBUTE : An unrecognized attribute or attribute value was passed in the attribute list.\n");
|
||||
break;
|
||||
case EGL_BAD_CONTEXT:
|
||||
printf("EGL_BAD_CONTEXT : An EGLContext argument does not name a valid EGL rendering context.\n");
|
||||
break;
|
||||
case EGL_BAD_CONFIG:
|
||||
printf("EGL_BAD_CONFIG : An EGLConfig argument does not name a valid EGL frame buffer configuration.\n");
|
||||
break;
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
printf("EGL_BAD_CURRENT_SURFACE : The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid.\n");
|
||||
break;
|
||||
case EGL_BAD_DISPLAY:
|
||||
printf("EGL_BAD_DISPLAY : An EGLDisplay argument does not name a valid EGL display connection.\n");
|
||||
break;
|
||||
case EGL_BAD_SURFACE:
|
||||
printf("EGL_BAD_SURFACE : An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering.\n");
|
||||
break;
|
||||
case EGL_BAD_MATCH:
|
||||
printf("EGL_BAD_MATCH : Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface).\n");
|
||||
break;
|
||||
case EGL_BAD_PARAMETER:
|
||||
printf("EGL_BAD_PARAMETER : One or more argument values are invalid.\n");
|
||||
break;
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
printf("EGL_BAD_NATIVE_PIXMAP : A NativePixmapType argument does not refer to a valid native pixmap.\n");
|
||||
break;
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
printf("EGL_BAD_NATIVE_WINDOW : A NativeWindowType argument does not refer to a valid native window.\n");
|
||||
break;
|
||||
case EGL_CONTEXT_LOST:
|
||||
printf("EGL_CONTEXT_LOST : A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering.\n");
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN : wtf dude\n");
|
||||
}
|
||||
}
|
||||
|
||||
egl_context *egl_context_malloc() {
|
||||
return malloc( sizeof( egl_context));
|
||||
}
|
||||
|
||||
/*
|
||||
wl_display, wl_surface, w, h
|
||||
egl_window CREATE
|
||||
egl_display CREATE
|
||||
egl_config FIND
|
||||
|
||||
egl_surface CREATE
|
||||
|
||||
egl_context CREATE
|
||||
*/
|
||||
egl_context *egl_context_new( struct wl_display *display) {
|
||||
EGLint major;
|
||||
EGLint minor;
|
||||
EGLint num_configs;
|
||||
|
||||
EGLint lastEGLOp;
|
||||
/*
|
||||
replaced EGL_OPENGL_BIT with EGL_OPENGL_ES2_BIT
|
||||
*/
|
||||
EGLint attribs[] = {
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
egl_context *e = egl_context_malloc();
|
||||
|
||||
e->display = eglGetDisplay((EGLNativeDisplayType) display);
|
||||
|
||||
if(EGL_NO_DISPLAY == e->display) {
|
||||
fprintf(stderr, "Couldn't get EGL display\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if( EGL_TRUE != eglInitialize(e->display, &major, &minor)) {
|
||||
fprintf(stderr, "Couldnt initialize EGL\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/* null buffer for querying the count*/
|
||||
lastEGLOp = eglChooseConfig( e->display, attribs, NULL, 1, &num_configs);
|
||||
if( EGL_TRUE != lastEGLOp) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "found %d matching EGL configurations\n", num_configs);
|
||||
|
||||
EGLConfig *all_the_configs = malloc( num_configs * sizeof( EGLConfig));
|
||||
|
||||
/* was &e->config but broken */
|
||||
lastEGLOp = eglChooseConfig( e->display, attribs, all_the_configs, num_configs, &num_configs);
|
||||
if( EGL_TRUE != lastEGLOp) {
|
||||
fprintf(stderr, "CouldnÄt find matching EGL config\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
e->config = all_the_configs[0];
|
||||
|
||||
/* 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*/
|
||||
e->context = eglCreateContext(e->display, e->config, EGL_NO_CONTEXT, context_attrib_list);
|
||||
if( EGL_NO_CONTEXT == e->context) {
|
||||
fprintf(stderr, "Couldn't create EGL context\n");
|
||||
printEGLError();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
16
SOURCES/graphics/os/EGL/egl_context.h
Normal file
16
SOURCES/graphics/os/EGL/egl_context.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <wayland-client-core.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
typedef struct {
|
||||
EGLDisplay *display;
|
||||
EGLConfig *config;
|
||||
EGLContext *context;
|
||||
} egl_context;
|
||||
|
||||
void printEGLError();
|
||||
|
||||
egl_context* egl_context_malloc();
|
||||
|
||||
egl_context* egl_context_new( struct wl_display *display);
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "wl_output_listener.h"
|
||||
|
||||
// Callback for wl_output::mode events (resolutions)
|
||||
void output_mode(void *data, struct wl_output *output,
|
||||
uint32_t flags, int32_t width, int32_t height,
|
||||
int32_t refresh) {
|
||||
const char *mode_type = "";
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) mode_type = " (current)";
|
||||
if (flags & WL_OUTPUT_MODE_PREFERRED) mode_type = " (preferred)";
|
||||
|
||||
printf("Mode: %dx%d @ %.2f Hz%s\n",
|
||||
width, height, refresh / 1000.0, mode_type);
|
||||
}
|
||||
|
||||
// Callback for wl_output::geometry events (physical display info)
|
||||
void output_geometry(void *data, struct wl_output *output,
|
||||
int32_t x, int32_t y, int32_t physical_width,
|
||||
int32_t physical_height, int32_t subpixel,
|
||||
const char *make, const char *model,
|
||||
int32_t transform) {
|
||||
printf("Output: %s %s (physical size: %dx%d mm)\n", make, model,
|
||||
physical_width, physical_height);
|
||||
}
|
||||
|
||||
// Callback for wl_output::done events (end of output info)
|
||||
void output_done(void *data, struct wl_output *output) {}
|
||||
|
||||
// Callback for wl_output::scale events (HiDPI scaling)
|
||||
void output_scale(void *data, struct wl_output *output, int32_t scale) {}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Callback for wl_output::mode events (resolutions)
|
||||
void output_mode(
|
||||
void *data,
|
||||
struct wl_output *output,
|
||||
uint32_t flags,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t refresh
|
||||
);
|
||||
|
||||
// Callback for wl_output::geometry events (physical display info)
|
||||
void output_geometry(
|
||||
void *data,
|
||||
struct wl_output *output,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t physical_width,
|
||||
int32_t physical_height,
|
||||
int32_t subpixel,
|
||||
const char *make,
|
||||
const char *model,
|
||||
int32_t transform
|
||||
);
|
||||
|
||||
// Callback for wl_output::done events (end of output info)
|
||||
void output_done(
|
||||
void *data,
|
||||
struct wl_output *output
|
||||
);
|
||||
|
||||
// Callback for wl_output::scale events (HiDPI scaling)
|
||||
void output_scale(
|
||||
void *data,
|
||||
struct wl_output *output,
|
||||
int32_t scale
|
||||
);
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "xdg_wm_base_listener.h"
|
||||
|
||||
/*
|
||||
listener on the XDG wm_base "ping" event
|
||||
the client must respond fairly soon to the event with a "pong" request or the client may be deemed unresponsive
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../xdg-shell.h"
|
||||
|
||||
void wm_ping(
|
||||
void *data,
|
||||
struct xdg_wm_base *xdg_wm_base,
|
||||
uint32_t serial
|
||||
);
|
||||
139
SOURCES/graphics/os/WAYLAND/wl_context.c
Normal file
139
SOURCES/graphics/os/WAYLAND/wl_context.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "wl_context.h"
|
||||
|
||||
#include "registry_listeners/wl_output_listener.h"
|
||||
#include "registry_listeners/xdg_wm_base_listener.h"
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static const struct wl_output_listener output_listener = {
|
||||
.geometry = output_geometry,
|
||||
.mode = output_mode,
|
||||
.done = output_done,
|
||||
.scale = output_scale,
|
||||
};
|
||||
|
||||
static const struct xdg_wm_base_listener wm_base_listener = {
|
||||
wm_ping
|
||||
};
|
||||
|
||||
/***************************************/
|
||||
/***************************************/
|
||||
/**********REGISTRY CALLBACKS***********/
|
||||
/***************************************/
|
||||
/***************************************/
|
||||
|
||||
/*
|
||||
listener on the registry object's add events
|
||||
used for picking the singletons to COMPOSITOR, SUBCOMPOSITOR and XDG_WM_BASE
|
||||
*/
|
||||
void global_registry(
|
||||
void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name,
|
||||
const char *interface,
|
||||
uint32_t version
|
||||
) {
|
||||
surface_builders *builders = data;
|
||||
|
||||
printf("REGISTRY EVENT\nname: %s\nversion: %d\n", interface, version);
|
||||
|
||||
/*
|
||||
printf("%s\n%s\n%s\n\n", wl_compositor_interface.name, wl_subcompositor_interface.name, xdg_wm_base_interface.name);
|
||||
*/
|
||||
|
||||
if(!strcmp(interface, wl_compositor_interface.name)) {
|
||||
printf("FOUND COMP\n");
|
||||
builders->compositor = wl_registry_bind(
|
||||
wl_registry,
|
||||
name,
|
||||
&wl_compositor_interface,
|
||||
version
|
||||
);
|
||||
}
|
||||
else if(!strcmp(interface, wl_subcompositor_interface.name)){
|
||||
printf("FOUND SUBCOMP\n");
|
||||
builders->subcompositor = wl_registry_bind(
|
||||
wl_registry,
|
||||
name,
|
||||
&wl_subcompositor_interface,
|
||||
version
|
||||
);
|
||||
}
|
||||
else if(!strcmp(interface, xdg_wm_base_interface.name)) {
|
||||
printf("FOUND XDG\n");
|
||||
builders->xdg_wm_base = wl_registry_bind(
|
||||
wl_registry,
|
||||
name,
|
||||
&xdg_wm_base_interface,
|
||||
version
|
||||
);
|
||||
}
|
||||
|
||||
if (strcmp(interface, "wl_output") == 0) {
|
||||
printf("FOUND OUTPUT\n");
|
||||
builders->output = wl_registry_bind(
|
||||
wl_registry,
|
||||
name,
|
||||
&wl_output_interface,
|
||||
1
|
||||
);
|
||||
wl_output_add_listener( builders->output, &output_listener, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
listener on the registry object's remove events
|
||||
it is an error the body being unimplemented ( when an interface becomes unavailable it could mean that the physical device has been disconnected )
|
||||
*/
|
||||
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
|
||||
};
|
||||
|
||||
wl_context* wl_context_new() {
|
||||
wl_context *w = malloc( sizeof( wl_context));
|
||||
w->display = wl_display_connect(NULL);
|
||||
if(! w->display) {
|
||||
fprintf(stderr, "Couldn't connect to wayland display\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
w->builders = malloc( sizeof( surface_builders));
|
||||
w->registry = wl_display_get_registry( w->display);
|
||||
wl_registry_add_listener( w->registry, ®istry_listener, w->builders);
|
||||
wl_display_roundtrip( w->display);
|
||||
if( ! w->builders->compositor || ! w->builders->subcompositor || ! w->builders->xdg_wm_base) {
|
||||
fprintf(stderr, "Couldn't find compositor or xdg shell\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xdg_wm_base_add_listener(w->builders->xdg_wm_base, &wm_base_listener, NULL);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/* ALLOWS FOR QUERYING OF SOME ENVIRONMENT VARIABLE */
|
||||
int wl_context_get(int query){
|
||||
switch( query) {
|
||||
case GLUT_SCREEN_WIDTH :
|
||||
return 192;
|
||||
break;
|
||||
case GLUT_SCREEN_HEIGHT :
|
||||
return 108; /* 1156 */
|
||||
break;
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
55
SOURCES/graphics/os/WAYLAND/wl_context.h
Normal file
55
SOURCES/graphics/os/WAYLAND/wl_context.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include "../WAYLAND/xdg-shell.h"
|
||||
|
||||
typedef struct {
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_subcompositor *subcompositor;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct wl_output *output;
|
||||
} surface_builders;
|
||||
|
||||
typedef struct {
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
surface_builders *builders;
|
||||
} wl_context;
|
||||
|
||||
#define GLUT_SCREEN_WIDTH 0
|
||||
#define GLUT_SCREEN_HEIGHT 1
|
||||
|
||||
void global_registry(
|
||||
void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name,
|
||||
const char *interface,
|
||||
uint32_t version
|
||||
);
|
||||
|
||||
void global_remove(
|
||||
void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
the only event dispatched by the WM is the "ping" one
|
||||
emitted periodically to check if clients are still alive
|
||||
|
||||
calls
|
||||
xdg_wm_base_pong
|
||||
to inform the server that the client is alive and responsive
|
||||
*/
|
||||
void wm_ping(
|
||||
void *data,
|
||||
struct xdg_wm_base *xdg_wm_base,
|
||||
uint32_t serial);
|
||||
|
||||
|
||||
|
||||
/* connects to the default display and initializes basic wayland resources */
|
||||
wl_context* wl_context_new();
|
||||
|
||||
int wl_context_get( int query);
|
||||
183
SOURCES/graphics/os/WAYLAND/xdg-shell.c
Normal file
183
SOURCES/graphics/os/WAYLAND/xdg-shell.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2008-2013 Kristian Høgsberg
|
||||
* Copyright © 2013 Rafael Antognolli
|
||||
* Copyright © 2013 Jasper St. Pierre
|
||||
* Copyright © 2010-2013 Intel Corporation
|
||||
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||
* Copyright © 2015-2017 Red Hat Inc.
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface xdg_positioner_interface;
|
||||
extern const struct wl_interface xdg_surface_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *xdg_shell_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&xdg_popup_interface,
|
||||
&xdg_surface_interface,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_output_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||
{ "pong", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_events[] = {
|
||||
{ "ping", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||
"xdg_wm_base", 5,
|
||||
4, xdg_wm_base_requests,
|
||||
1, xdg_wm_base_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_positioner_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||
"xdg_positioner", 5,
|
||||
10, xdg_positioner_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_events[] = {
|
||||
{ "configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||
"xdg_surface", 5,
|
||||
5, xdg_surface_requests,
|
||||
1, xdg_surface_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||
{ "set_title", "s", xdg_shell_types + 0 },
|
||||
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||
{ "move", "ou", xdg_shell_types + 16 },
|
||||
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_events[] = {
|
||||
{ "configure", "iia", xdg_shell_types + 0 },
|
||||
{ "close", "", xdg_shell_types + 0 },
|
||||
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||
"xdg_toplevel", 5,
|
||||
14, xdg_toplevel_requests,
|
||||
4, xdg_toplevel_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "grab", "ou", xdg_shell_types + 22 },
|
||||
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_events[] = {
|
||||
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||
{ "popup_done", "", xdg_shell_types + 0 },
|
||||
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||
"xdg_popup", 5,
|
||||
3, xdg_popup_requests,
|
||||
3, xdg_popup_events,
|
||||
};
|
||||
|
||||
2280
SOURCES/graphics/os/WAYLAND/xdg-shell.h
Normal file
2280
SOURCES/graphics/os/WAYLAND/xdg-shell.h
Normal file
File diff suppressed because it is too large
Load Diff
14
SOURCES/main.c
Executable file
14
SOURCES/main.c
Executable file
@@ -0,0 +1,14 @@
|
||||
#include "graphics/library/application_context.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
application_context *app;
|
||||
|
||||
app = application_context_new( "Hello World");
|
||||
|
||||
fprintf(stderr, "ready to loop\n");
|
||||
while(1){
|
||||
gui_component_draw(app->win, 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user