wl-graphics-demo

wl-graphics-demo.git
git clone git://git.lenczewski.org/wl-graphics-demo.git
Log | Files | Refs | README

wl-egl.c (5466B)


      1 #include <wayland-client.h>
      2 #include "xdg-shell.h"
      3 
      4 #include <wayland-egl.h>
      5 #include <EGL/egl.h>
      6 
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 
     11 struct wl_display *display;
     12 struct wl_compositor *compositor;
     13 struct xdg_wm_base *wm_base;
     14 EGLDisplay egl_display;
     15 char running;
     16 
     17 #define DEFAULT_WIDTH 256
     18 #define DEFAULT_HEIGHT 256
     19 
     20 struct window {
     21 	EGLContext egl_context;
     22 	struct wl_surface *surface;
     23 	struct xdg_surface *xdg_surface;
     24 	struct xdg_toplevel *xdg_toplevel;
     25 	struct wl_egl_window *egl_window;
     26 	EGLSurface egl_surface;
     27 };
     28 
     29 static void
     30 wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial)
     31 {
     32 	xdg_wm_base_pong(wm_base, serial);
     33 }
     34 
     35 static const struct xdg_wm_base_listener xdg_wm_base_listener = {
     36 	.ping = wm_base_ping,
     37 };
     38 
     39 static void
     40 registry_add_global(void *data, struct wl_registry *registry, uint32_t name, char const *interface, uint32_t version)
     41 {
     42 	if (!strcmp(interface, wl_compositor_interface.name)) {
     43 		compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 6);
     44 	} else if (!strcmp(interface, xdg_wm_base_interface.name)) {
     45 		wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 6);
     46 		xdg_wm_base_add_listener(wm_base, &xdg_wm_base_listener, NULL);
     47 	}
     48 }
     49 
     50 static void
     51 registry_remove_global(void *data, struct wl_registry *registry, uint32_t name)
     52 {
     53 }
     54 
     55 static const struct wl_registry_listener registry_listener = {
     56 	.global = registry_add_global,
     57 	.global_remove = registry_remove_global,
     58 };
     59 
     60 static void
     61 xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial)
     62 {
     63 	xdg_surface_ack_configure(xdg_surface, serial);
     64 }
     65 
     66 static const struct xdg_surface_listener xdg_surface_listener = {
     67 	.configure = xdg_surface_configure,
     68 };
     69 
     70 static void
     71 xdg_toplevel_configure(void *data, struct xdg_toplevel *toplevel,
     72 		       int32_t width, int32_t height, struct wl_array *states)
     73 {
     74 	fprintf(stderr, "xdg_toplevel_configure: width: %d, height: %d\n", width, height);
     75 
     76 	struct window *window = data;
     77 
     78 	wl_egl_window_resize(window->egl_window,
     79 			     width ? width : DEFAULT_WIDTH,
     80 			     height ? height : DEFAULT_HEIGHT,
     81 			     0, 0);
     82 
     83 	fprintf(stderr, "Created egl_window\n");
     84 }
     85 
     86 static void
     87 xdg_toplevel_close(void *data, struct xdg_toplevel *toplevel)
     88 {
     89 	running = 0;
     90 
     91 	fprintf(stderr, "Closing egl_window\n");
     92 }
     93 
     94 static void
     95 xdg_toplevel_configure_bounds(void *data, struct xdg_toplevel *toplevel,
     96 			      int32_t width, int32_t height)
     97 {
     98 	fprintf(stderr, "xdg_toplevel_configure_bounds: width: %d, height: %d\n", width, height);
     99 
    100 	struct window *window = data;
    101 
    102 	wl_egl_window_resize(window->egl_window, width, height, 0, 0);
    103 
    104 	fprintf(stderr, "Resized egl_window\n");
    105 }
    106 
    107 static void
    108 xdg_toplevel_wm_capabilities(void *data, struct xdg_toplevel *toplevel,
    109 			     struct wl_array *caps)
    110 {
    111 }
    112 
    113 static const struct xdg_toplevel_listener xdg_toplevel_listener = {
    114 	.configure = xdg_toplevel_configure,
    115 	.close = xdg_toplevel_close,
    116 	.configure_bounds = xdg_toplevel_configure_bounds,
    117 	.wm_capabilities = xdg_toplevel_wm_capabilities,
    118 };
    119 
    120 void
    121 create_egl_window(struct window *window)
    122 {
    123 	EGLint major, minor;
    124 	eglInitialize(egl_display, &major, &minor);
    125 
    126 	fprintf(stderr, "EGL version: %d.%d\n", major, minor);
    127 
    128 	eglBindAPI(EGL_OPENGL_API);
    129 
    130 	EGLint attrs[] = {
    131 		EGL_RED_SIZE, 8,
    132 		EGL_GREEN_SIZE, 8,
    133 		EGL_BLUE_SIZE, 8,
    134 		EGL_ALPHA_SIZE, 8,
    135 		EGL_NONE,
    136 	};
    137 
    138 	EGLConfig config;
    139 	EGLint num_config;
    140 	eglChooseConfig(egl_display, attrs, &config, 1, &num_config);
    141 
    142 	window->egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, NULL);
    143 
    144 	window->surface = wl_compositor_create_surface(compositor);
    145 	window->egl_window = wl_egl_window_create(window->surface, DEFAULT_WIDTH, DEFAULT_HEIGHT);
    146 
    147 	window->xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, window->surface);
    148 	xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, NULL);
    149 
    150 	window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface);
    151 	xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener, window);
    152 
    153 	xdg_toplevel_set_title(window->xdg_toplevel, "wl-egl-example");
    154 
    155 	wl_surface_commit(window->surface);
    156 	wl_display_roundtrip(display);
    157 
    158 	window->egl_surface = eglCreateWindowSurface(egl_display, config, window->egl_window, NULL);
    159 	if (window->egl_surface == EGL_NO_SURFACE) {
    160 		fprintf(stderr, "Failed to create surface!\n");
    161 		exit(EXIT_FAILURE);
    162 	}
    163 
    164 	eglMakeCurrent(egl_display, window->egl_surface, window->egl_surface, window->egl_context);
    165 }
    166 
    167 void
    168 destroy_egl_window(struct window *window)
    169 {
    170 	eglDestroySurface(egl_display, window->egl_surface);
    171 	wl_egl_window_destroy(window->egl_window);
    172 	xdg_toplevel_destroy(window->xdg_toplevel);
    173 	xdg_surface_destroy(window->xdg_surface);
    174 	wl_surface_destroy(window->surface);
    175 	eglDestroyContext(egl_display, window->egl_context);
    176 }
    177 
    178 void
    179 draw(struct window *window)
    180 {
    181 	eglSwapBuffers(egl_display, window->egl_surface);
    182 }
    183 
    184 int
    185 main(void)
    186 {
    187 	fprintf(stderr, "Hello, World!\n");
    188 
    189 	display = wl_display_connect(NULL);
    190 
    191 	struct wl_registry *registry = wl_display_get_registry(display);
    192 	wl_registry_add_listener(registry, &registry_listener, NULL);
    193 	wl_display_roundtrip(display);
    194 
    195 	egl_display = eglGetDisplay(display);
    196 
    197 	struct window window;
    198 	create_egl_window(&window);
    199 
    200 	running = 1;
    201 	while (running) {
    202 		wl_display_dispatch_pending(display);
    203 		draw(&window);
    204 	}
    205 
    206 	destroy_egl_window(&window);
    207 
    208 	eglTerminate(egl_display);
    209 	wl_display_disconnect(display);
    210 
    211 	fprintf(stderr, "Goodbye, World!\n");
    212 
    213 	return 0;
    214 }