Initial commit
This commit is contained in:
commit
b3401b13ad
5 changed files with 218 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
wayland
|
||||||
4
Makefile
Normal file
4
Makefile
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
CFLAGS=-Wall -Wextra -Og -ggdb3
|
||||||
|
LIBS=-lwayland-client -lwayland-egl -lEGL -lOpenGL
|
||||||
|
wayland: wayland.c
|
||||||
|
gcc $(CFLAGS) $(LIBS) wayland.c -o wayland
|
||||||
0
gitignore
Normal file
0
gitignore
Normal file
6
notes.org
Normal file
6
notes.org
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
There are four ways (it would seem) to render pixels to a wayland surface:
|
||||||
|
|
||||||
|
1. *wl_shm* using shared memory, aka directly telling wayland the color of each pixel to draw using software rendering.
|
||||||
|
2. Using a *wl_shell_interface* to create a *wl_shell_surface*, then use the *wl_egl_* functions to draw pixels.
|
||||||
|
3. Using a *wl_surface* directly? Apparently not all compositors implement the *wl_shell_interface* protocol, and checking the source code from SDL's repository they do not even look for it.
|
||||||
|
4. Using extensions like *wl_egl_window_create* to hook a wayland window to a OGL rendering context. This link seems to agree with me: https://www.gfxstrand.net/faith/projects/wayland/wayland-android/
|
||||||
207
wayland.c
Normal file
207
wayland.c
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <wayland-egl.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct wl_compositor *compositor = NULL;
|
||||||
|
struct wl_registry *registry = NULL;
|
||||||
|
struct wl_shell *shell = NULL;
|
||||||
|
struct wl_surface *surface = NULL;
|
||||||
|
struct wl_shm *shm = NULL;
|
||||||
|
EGLBoolean errcode = 0;
|
||||||
|
|
||||||
|
void registry_handle_global(void *data, struct wl_registry *registry,
|
||||||
|
uint32_t name, const char *interface, uint32_t version)
|
||||||
|
{
|
||||||
|
printf("Wayland interface: '%s', version: %d, name: %d\n",
|
||||||
|
interface, version, name);
|
||||||
|
if (!strcmp(interface, wl_compositor_interface.name))
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Registering compositor...\n");
|
||||||
|
compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(interface, wl_shell_interface.name))
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Getting shell interface...\n");
|
||||||
|
shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void registry_handle_global_remove(void *data, struct wl_registry *registry,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
// This space deliberately left blank
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_registry_listener
|
||||||
|
registry_listener = {
|
||||||
|
.global = registry_handle_global,
|
||||||
|
.global_remove = registry_handle_global_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Starting platform layer...\n");
|
||||||
|
struct wl_display *display = wl_display_connect(NULL);
|
||||||
|
if (!display)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Cannot retrieve wayland display!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
registry = wl_display_get_registry(display);
|
||||||
|
if (!registry)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot retrieve wayland registry!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Linking registry listener...\n");
|
||||||
|
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||||
|
|
||||||
|
wl_display_dispatch(display);
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
|
surface = wl_compositor_create_surface(compositor);
|
||||||
|
if (!surface)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't create surface!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WL EGL initialization */
|
||||||
|
struct wl_egl_window *window = wl_egl_window_create(surface, 480, 460);
|
||||||
|
|
||||||
|
EGLDisplay egl_display = eglGetDisplay((EGLNativeDisplayType) display);
|
||||||
|
if (egl_display == EGL_NO_DISPLAY)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not retrieve EGL display from wayland display\n");
|
||||||
|
}
|
||||||
|
errcode = eglInitialize(egl_display, NULL, NULL);
|
||||||
|
switch (errcode)
|
||||||
|
{
|
||||||
|
case EGL_FALSE:
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
fprintf(stderr, "Could not initialize EGL display\n");
|
||||||
|
break;
|
||||||
|
case EGL_TRUE:
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_count;
|
||||||
|
errcode = eglGetConfigs(egl_display, NULL, 0, &config_count);
|
||||||
|
switch (errcode)
|
||||||
|
{
|
||||||
|
case EGL_FALSE:
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
case EGL_BAD_PARAMETER:
|
||||||
|
fprintf(stderr, "Could not retrieve EGL config number\n");
|
||||||
|
break;
|
||||||
|
case EGL_TRUE:
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLConfig *configs = calloc(config_count, sizeof(EGLConfig));
|
||||||
|
|
||||||
|
EGLint attr_list[] = {
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
int chosen_config_count;
|
||||||
|
|
||||||
|
errcode = eglChooseConfig(egl_display, attr_list, configs, config_count * sizeof(EGLConfig), &chosen_config_count);
|
||||||
|
switch (errcode)
|
||||||
|
{
|
||||||
|
case EGL_FALSE:
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
case EGL_BAD_PARAMETER:
|
||||||
|
fprintf(stderr, "Could not choose EGL config parameters\n");
|
||||||
|
break;
|
||||||
|
case EGL_TRUE:
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLSurface egl_surface = eglCreateWindowSurface(egl_display, configs[0], (EGLNativeWindowType)window, NULL);
|
||||||
|
|
||||||
|
switch ((intptr_t)egl_surface)
|
||||||
|
{
|
||||||
|
case (intptr_t)EGL_NO_SURFACE:
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
case EGL_BAD_CONFIG:
|
||||||
|
case EGL_BAD_NATIVE_WINDOW:
|
||||||
|
case EGL_BAD_ATTRIBUTE:
|
||||||
|
case EGL_BAD_ALLOC:
|
||||||
|
case EGL_BAD_MATCH:
|
||||||
|
fprintf(stderr, "Could not choose EGL config parameters\n");
|
||||||
|
break;
|
||||||
|
case EGL_TRUE:
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EGLint context_attribs[] = {
|
||||||
|
EGL_CONTEXT_MAJOR_VERSION, 3,
|
||||||
|
EGL_CONTEXT_MINOR_VERSION, 2,
|
||||||
|
EGL_CONTEXT_OPENGL_DEBUG, EGL_TRUE,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Change from OpenGL ES to regular OpenGL */
|
||||||
|
errcode = eglBindAPI(EGL_OPENGL_API);
|
||||||
|
switch (errcode)
|
||||||
|
{
|
||||||
|
case EGL_FALSE:
|
||||||
|
case EGL_BAD_PARAMETER:
|
||||||
|
fprintf(stderr, "Could not bind OpenGL API to EGL\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLContext egl_context = eglCreateContext(egl_display, configs[0], EGL_NO_CONTEXT, context_attribs);
|
||||||
|
|
||||||
|
errcode = eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
|
||||||
|
switch (errcode)
|
||||||
|
{
|
||||||
|
case EGL_BAD_CONTEXT:
|
||||||
|
case EGL_BAD_SURFACE:
|
||||||
|
case EGL_BAD_MATCH:
|
||||||
|
case EGL_BAD_NATIVE_WINDOW:
|
||||||
|
case EGL_BAD_CURRENT_SURFACE:
|
||||||
|
case EGL_BAD_ALLOC:
|
||||||
|
case EGL_CONTEXT_LOST:
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
fprintf(stderr, "Could not make EGL context current\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_region *region = wl_compositor_create_region(compositor);
|
||||||
|
wl_region_add(region, 0, 0, 480, 360);
|
||||||
|
wl_surface_set_opaque_region(surface, region);
|
||||||
|
|
||||||
|
// Main event loop
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
//wl_display_dispatch_pending(display);
|
||||||
|
fprintf(stdout, "Dispatching event...\n");
|
||||||
|
glClearColor(0.5, 0.3, 0.0, 1.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glFlush();
|
||||||
|
eglSwapBuffers(egl_display, egl_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_display_disconnect(display);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue