[PATCH weston 5/5] clients: Replace transformed with a toytoolkit implementation

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Fri Nov 30 07:34:26 PST 2012


---
 clients/Makefile.am   |   11 +-
 clients/transformed.c |  812 +++++++++----------------------------------------
 2 files changed, 145 insertions(+), 678 deletions(-)

diff --git a/clients/Makefile.am b/clients/Makefile.am
index fd83a29..26a5c60 100644
--- a/clients/Makefile.am
+++ b/clients/Makefile.am
@@ -42,16 +42,11 @@ endif
 
 if BUILD_SIMPLE_EGL_CLIENTS
 simple_egl_clients_programs =			\
-	simple-egl				\
-	transformed
+	simple-egl
 
 simple_egl_SOURCES = simple-egl.c
 simple_egl_CPPFLAGS = $(SIMPLE_EGL_CLIENT_CFLAGS)
 simple_egl_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm
-
-transformed_SOURCES = transformed.c
-transformed_CPPFLAGS = $(SIMPLE_EGL_CLIENT_CFLAGS)
-transformed_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm
 endif
 
 if BUILD_CLIENTS
@@ -67,6 +62,7 @@ clients_programs =				\
 	eventdemo				\
 	clickdot				\
 	editor					\
+	transformed				\
 	$(full_gl_client_programs)
 
 desktop_shell = weston-desktop-shell
@@ -123,6 +119,9 @@ eventdemo_LDADD = $(toolkit_libs)
 clickdot_SOURCES = clickdot.c
 clickdot_LDADD = $(toolkit_libs)
 
+transformed_SOURCES = transformed.c
+transformed_LDADD = $(toolkit_libs)
+
 editor_SOURCES = 				\
 	editor.c				\
 	text-protocol.c				\
diff --git a/clients/transformed.c b/clients/transformed.c
index 9c019fb..be840d9 100644
--- a/clients/transformed.c
+++ b/clients/transformed.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2008 Kristian Høgsberg
  * Copyright © 2012 Intel Corporation
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -21,767 +21,235 @@
  * OF THIS SOFTWARE.
  */
 
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdbool.h>
 #include <math.h>
-#include <assert.h>
-#include <signal.h>
+#include <cairo.h>
 
 #include <linux/input.h>
-
 #include <wayland-client.h>
-#include <wayland-egl.h>
-
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
-
-struct window;
-struct seat;
-
-struct display {
-	struct wl_display *display;
-	struct wl_registry *registry;
-	struct wl_compositor *compositor;
-	struct wl_shell *shell;
-	struct wl_seat *seat;
-	struct wl_pointer *pointer;
-	struct wl_keyboard *keyboard;
-	struct wl_shm *shm;
-	struct wl_list output_list;
-	struct {
-		EGLDisplay dpy;
-		EGLContext ctx;
-		EGLConfig conf;
-	} egl;
-	struct window *window;
-};
-
-struct output {
-	struct wl_output *output;
-	int transform;
-	struct wl_list link;
-};
+#include "window.h"
 
-struct geometry {
-	int width, height;
-};
-
-struct window {
+struct transformed {
 	struct display *display;
-	struct geometry geometry, window_size;
-	struct {
-		GLuint fbo;
-		GLuint color_rbo;
-
-		GLuint transform_uniform;
-
-		GLuint pos;
-		GLuint col;
-	} gl;
-
-	struct output *output;
-	struct wl_egl_window *native;
-	struct wl_surface *surface;
-	struct wl_shell_surface *shell_surface;
-	EGLSurface egl_surface;
-	struct wl_callback *callback;
-	int fullscreen, configured;
-};
-
-static const char *vert_shader_text =
-	"uniform mat4 transform;\n"
-	"attribute vec4 pos;\n"
-	"attribute vec4 color;\n"
-	"varying vec4 v_color;\n"
-	"void main() {\n"
-	"  gl_Position = transform * pos;\n"
-	"  v_color = color;\n"
-	"}\n";
-
-static const char *frag_shader_text =
-	"precision mediump float;\n"
-	"varying vec4 v_color;\n"
-	"void main() {\n"
-	"  gl_FragColor = v_color;\n"
-	"}\n";
-
-static int running = 1;
-
-static void
-init_egl(struct display *display)
-{
-	static const EGLint context_attribs[] = {
-		EGL_CONTEXT_CLIENT_VERSION, 2,
-		EGL_NONE
-	};
-
-	EGLint config_attribs[] = {
-		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-		EGL_RED_SIZE, 1,
-		EGL_GREEN_SIZE, 1,
-		EGL_BLUE_SIZE, 1,
-		EGL_ALPHA_SIZE, 0,
-		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-		EGL_NONE
-	};
-
-	EGLint major, minor, n;
-	EGLBoolean ret;
-
-	display->egl.dpy = eglGetDisplay(display->display);
-	assert(display->egl.dpy);
-
-	ret = eglInitialize(display->egl.dpy, &major, &minor);
-	assert(ret == EGL_TRUE);
-	ret = eglBindAPI(EGL_OPENGL_ES_API);
-	assert(ret == EGL_TRUE);
-
-	ret = eglChooseConfig(display->egl.dpy, config_attribs,
-			      &display->egl.conf, 1, &n);
-	assert(ret && n == 1);
-
-	display->egl.ctx = eglCreateContext(display->egl.dpy,
-					    display->egl.conf,
-					    EGL_NO_CONTEXT, context_attribs);
-	assert(display->egl.ctx);
-
-}
-
-static void
-fini_egl(struct display *display)
-{
-	/* Required, otherwise segfault in egl_dri2.c: dri2_make_current()
-	 * on eglReleaseThread(). */
-	eglMakeCurrent(display->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
-		       EGL_NO_CONTEXT);
-
-	eglTerminate(display->egl.dpy);
-	eglReleaseThread();
-}
-
-static GLuint
-create_shader(struct window *window, const char *source, GLenum shader_type)
-{
-	GLuint shader;
-	GLint status;
-
-	shader = glCreateShader(shader_type);
-	assert(shader != 0);
-
-	glShaderSource(shader, 1, (const char **) &source, NULL);
-	glCompileShader(shader);
-
-	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
-	if (!status) {
-		char log[1000];
-		GLsizei len;
-		glGetShaderInfoLog(shader, 1000, &len, log);
-		fprintf(stderr, "Error: compiling %s: %*s\n",
-			shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
-			len, log);
-		exit(1);
-	}
-
-	return shader;
-}
-
-static void
-init_gl(struct window *window)
-{
-	GLuint frag, vert;
-	GLuint program;
-	GLint status;
-
-	frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER);
-	vert = create_shader(window, vert_shader_text, GL_VERTEX_SHADER);
-
-	program = glCreateProgram();
-	glAttachShader(program, frag);
-	glAttachShader(program, vert);
-	glLinkProgram(program);
-
-	glGetProgramiv(program, GL_LINK_STATUS, &status);
-	if (!status) {
-		char log[1000];
-		GLsizei len;
-		glGetProgramInfoLog(program, 1000, &len, log);
-		fprintf(stderr, "Error: linking:\n%*s\n", len, log);
-		exit(1);
-	}
-
-	glUseProgram(program);
-
-	window->gl.pos = 0;
-	window->gl.col = 1;
-
-	glBindAttribLocation(program, window->gl.pos, "pos");
-	glBindAttribLocation(program, window->gl.col, "color");
-	glLinkProgram(program);
-
-	window->gl.transform_uniform =
-		glGetUniformLocation(program, "transform");
-}
-
-static void
-handle_ping(void *data, struct wl_shell_surface *shell_surface,
-	    uint32_t serial)
-{
-	wl_shell_surface_pong(shell_surface, serial);
-}
-
-static void
-handle_configure(void *data, struct wl_shell_surface *shell_surface,
-		 uint32_t edges, int32_t width, int32_t height)
-{
-	struct window *window = data;
-	int transform = WL_OUTPUT_TRANSFORM_NORMAL;
-	int32_t tmp;
-
-	window->geometry.width = width;
-	window->geometry.height = height;
-
-	if (!window->fullscreen)
-		window->window_size = window->geometry;
-
-	if (window->output)
-		transform = window->output->transform;
-
-	switch (transform) {
-	case WL_OUTPUT_TRANSFORM_90:
-	case WL_OUTPUT_TRANSFORM_270:
-	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-		tmp = width;
-		width = height;
-		height = tmp;
-		break;
-	default:
-		break;
-	}
-
-	if (window->native)
-		wl_egl_window_resize(window->native, width, height, 0, 0);
-}
-
-static void
-handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
-{
-}
-
-static const struct wl_shell_surface_listener shell_surface_listener = {
-	handle_ping,
-	handle_configure,
-	handle_popup_done
-};
-
-static void
-toggle_fullscreen(struct window *window, int fullscreen);
-
-static void
-surface_enter(void *data, struct wl_surface *wl_surface,
-	      struct wl_output *wl_output)
-{
-	struct window *window = data;
-	struct output *output = NULL;
-
-	wl_list_for_each(output, &window->display->output_list, link) {
-		if (output->output == wl_output)
-			break;
-	}
-
-	if (output && output->output == wl_output) {
-		/* We use the output information only for rendering according
-		 * to the output transform. Since we can't "please" two
-		 * different outputs if they have a different transform, just
-		 * do it according to the last output the surface entered. */
-		window->output = output;
-
-		/* Force a redraw with the new transform */
-		toggle_fullscreen(window, window->fullscreen);
-	}
-}
-
-static void
-surface_leave(void *data, struct wl_surface *wl_surface,
-	      struct wl_output *wl_output)
-{
-	struct window *window = data;
-	struct output *output = NULL;
-
-	wl_list_for_each(output, &window->display->output_list, link) {
-		if (output->output == wl_output)
-			break;
-	}
-
-	if (output && output->output == wl_output && output == window->output)
-		window->output = NULL;
-}
-
-static const struct wl_surface_listener surface_listener = {
-	surface_enter,
-	surface_leave
-};
-
-static void
-redraw(struct window *window);
-
-static void
-configure_callback(void *data, struct wl_callback *callback, uint32_t  time)
-{
-	struct window *window = data;
-
-	wl_callback_destroy(callback);
-
-	redraw(window);
-}
-
-static struct wl_callback_listener configure_callback_listener = {
-	configure_callback,
+	struct window *window;
+	struct widget *widget;
+	int width, height;
+	int fullscreen;
 };
 
 static void
-toggle_fullscreen(struct window *window, int fullscreen)
-{
-	struct wl_callback *callback;
-
-	window->fullscreen = fullscreen;
-
-	if (fullscreen) {
-		wl_shell_surface_set_fullscreen(window->shell_surface,
-						WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
-						0, NULL);
-	} else {
-		wl_shell_surface_set_toplevel(window->shell_surface);
-		handle_configure(window, window->shell_surface, 0,
-				 window->window_size.width,
-				 window->window_size.height);
-	}
-
-	callback = wl_display_sync(window->display->display);
-	wl_callback_add_listener(callback, &configure_callback_listener,
-				 window);
-}
-
-static void
-create_surface(struct window *window)
-{
-	struct display *display = window->display;
-	EGLBoolean ret;
-	
-	window->surface = wl_compositor_create_surface(display->compositor);
-	window->shell_surface = wl_shell_get_shell_surface(display->shell,
-							   window->surface);
-
-	wl_surface_add_listener(window->surface, &surface_listener, window);
-	wl_shell_surface_add_listener(window->shell_surface,
-				      &shell_surface_listener, window);
-
-	window->native =
-		wl_egl_window_create(window->surface,
-				     window->window_size.width,
-				     window->window_size.height);
-	window->egl_surface =
-		eglCreateWindowSurface(display->egl.dpy,
-				       display->egl.conf,
-				       window->native, NULL);
-
-	wl_shell_surface_set_title(window->shell_surface, "simple-egl");
-
-	ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
-			     window->egl_surface, window->display->egl.ctx);
-	assert(ret == EGL_TRUE);
-
-	toggle_fullscreen(window, window->fullscreen);
-}
-
-static void
-destroy_surface(struct window *window)
-{
-	wl_egl_window_destroy(window->native);
-
-	wl_shell_surface_destroy(window->shell_surface);
-	wl_surface_destroy(window->surface);
-
-	if (window->callback)
-		wl_callback_destroy(window->callback);
-}
-
-static void
-update_transform(struct window *window)
+update_transform(cairo_t *cr, enum wl_output_transform transform)
 {
-	int transform = WL_OUTPUT_TRANSFORM_NORMAL;
-	int swap_w_h = 0;
-	int flip;
+	double angle;
 
-	GLfloat mat[4][4] = {
-		{ 1, 0, 0, 0 },
-		{ 0, 1, 0, 0 },
-		{ 0, 0, 1, 0 },
-		{ 0, 0, 0, 1 }
-	};
-
-
-	if (window->output)
-		transform = window->output->transform;
+	cairo_matrix_t m;
 
 	switch(transform) {
 	case WL_OUTPUT_TRANSFORM_FLIPPED:
 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-		flip = -1;
+		cairo_matrix_init(&m, -1, 0, 0, 1, 0, 0);
 		break;
 	default:
-		flip = 1;
+		cairo_matrix_init_identity(&m);
 		break;
 	}
-
 	switch (transform) {
 	case WL_OUTPUT_TRANSFORM_NORMAL:
 	case WL_OUTPUT_TRANSFORM_FLIPPED:
-		mat[0][0] = flip;
-		mat[0][1] = 0;
-		mat[1][0] = 0;
-		mat[1][1] = 1;
+	default:
+		angle = 0;
 		break;
 	case WL_OUTPUT_TRANSFORM_90:
 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-		mat[0][0] = 0;
-		mat[0][1] = -flip;
-		mat[1][0] = 1;
-		mat[1][1] = 0;
-		swap_w_h = 1;
+		angle = M_PI_2;
 		break;
 	case WL_OUTPUT_TRANSFORM_180:
 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
-		mat[0][0] = -flip;
-		mat[0][1] = 0;
-		mat[1][0] = 0;
-		mat[1][1] = -1;
+		angle = M_PI;
 		break;
 	case WL_OUTPUT_TRANSFORM_270:
 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-		mat[0][0] = 0;
-		mat[0][1] = flip;
-		mat[1][0] = -1;
-		mat[1][1] = 0;
-		swap_w_h = 1;
-		break;
-	default:
+		angle = M_PI + M_PI_2;
 		break;
 	}
 
-	if (swap_w_h)
-		glViewport(0, 0, window->geometry.height,
-			   window->geometry.width);
-	else
-		glViewport(0, 0, window->geometry.width,
-			   window->geometry.height);
-
-	glUniformMatrix4fv(window->gl.transform_uniform, 1, GL_FALSE,
-			   (GLfloat *) mat);
-	wl_surface_set_buffer_transform(window->surface, transform);
-	printf("Rendering buffer with transform == %d\n", transform);
+	cairo_rotate(cr, angle);
+	cairo_transform(cr, &m);
 }
 
 static void
-redraw(struct window *window)
+draw_stuff(cairo_surface_t *surface, int width, int height, int transform)
 {
-	static const GLfloat verts[8][2] = {
-		{  0.0,  0.0 },
-		{  0.0,  1.0 },
-		{  0.0,  0.0 },
-		{  1.0,  0.0 },
-		{  0.0,  0.0 },
-		{ -1.0,  0.0 },
-		{  0.0,  0.0 },
-		{  0.0, -1.0 }
-	};
-	static const GLfloat colors[8][3] = {
-		{ 1, 0, 0 },
-		{ 1, 0, 0 },
-		{ 0, 1, 0 },
-		{ 0, 1, 0 },
-		{ 1, 1, 1 },
-		{ 1, 1, 1 },
-		{ 1, 1, 1 },
-		{ 1, 1, 1 }
-	};
-	struct wl_region *region;
-
-	update_transform(window);
-
-	glClearColor(0.0, 0.0, 0.0, 1.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-
-	glVertexAttribPointer(window->gl.pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
-	glVertexAttribPointer(window->gl.col, 3, GL_FLOAT, GL_FALSE, 0, colors);
-	glEnableVertexAttribArray(window->gl.pos);
-	glEnableVertexAttribArray(window->gl.col);
-
-	glDrawArrays(GL_LINES, 0, 8);
-
-	glDisableVertexAttribArray(window->gl.pos);
-	glDisableVertexAttribArray(window->gl.col);
-
-	region = wl_compositor_create_region(window->display->compositor);
-	wl_region_add(region, 0, 0,
-		      window->geometry.width,
-		      window->geometry.height);
-	wl_surface_set_opaque_region(window->surface, region);
-	wl_region_destroy(region);
-
-	eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
-}
+	cairo_t *cr;
+	int tmp;
 
-static void
-pointer_handle_enter(void *data, struct wl_pointer *pointer,
-		     uint32_t serial, struct wl_surface *surface,
-		     wl_fixed_t sx, wl_fixed_t sy)
-{
-	wl_pointer_set_cursor(pointer, serial, NULL, 0, 0);
-}
+	if (transform & 1) {
+		tmp = width;
+		width = height;
+		height = tmp;
+	}
 
-static void
-pointer_handle_leave(void *data, struct wl_pointer *pointer,
-		     uint32_t serial, struct wl_surface *surface)
-{
-}
+	cr = cairo_create(surface);
 
-static void
-pointer_handle_motion(void *data, struct wl_pointer *pointer,
-		      uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
-{
-}
+	cairo_identity_matrix(cr);
+	cairo_translate(cr, width / 2, height / 2);
+	cairo_scale(cr, width / 2, height / 2);
 
-static void
-pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
-		      uint32_t serial, uint32_t time, uint32_t button,
-		      uint32_t state)
-{
-}
+	update_transform(cr, transform);
 
-static void
-pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
-		    uint32_t time, uint32_t axis, wl_fixed_t value)
-{
-}
+	cairo_set_source_rgba(cr, 0, 0, 0.3, 1.0);
+	cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
+	cairo_rectangle(cr, -1, -1, 2, 2);
+	cairo_fill(cr);
 
-static const struct wl_pointer_listener pointer_listener = {
-	pointer_handle_enter,
-	pointer_handle_leave,
-	pointer_handle_motion,
-	pointer_handle_button,
-	pointer_handle_axis,
-};
+	cairo_set_source_rgb(cr, 1, 0, 0);
+	cairo_move_to(cr, 0,  0);
+	cairo_line_to(cr, 0, -1);
 
-static void
-keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
-		       uint32_t format, int fd, uint32_t size)
-{
-}
+	cairo_save(cr);
+	cairo_identity_matrix(cr);
+	cairo_set_line_width(cr, 2.0);
+	cairo_stroke(cr);
+	cairo_restore(cr);
 
-static void
-keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
-		      uint32_t serial, struct wl_surface *surface,
-		      struct wl_array *keys)
-{
-}
+	cairo_set_source_rgb(cr, 0, 1, 0);
+	cairo_move_to(cr, 0, 0);
+	cairo_line_to(cr, 1, 0);
 
-static void
-keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
-		      uint32_t serial, struct wl_surface *surface)
-{
-}
+	cairo_save(cr);
+	cairo_identity_matrix(cr);
+	cairo_set_line_width(cr, 2.0);
+	cairo_stroke(cr);
+	cairo_restore(cr);
 
-static void
-keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
-		    uint32_t serial, uint32_t time, uint32_t key,
-		    uint32_t state)
-{
-	struct display *d = data;
+	cairo_set_source_rgb(cr, 1, 1, 1);
+	cairo_move_to(cr, 0, 0);
+	cairo_line_to(cr, 0, 1);
+	cairo_move_to(cr,  0, 0);
+	cairo_line_to(cr, -1, 0);
+
+	cairo_save(cr);
+	cairo_identity_matrix(cr);
+	cairo_set_line_width(cr, 2.0);
+	cairo_stroke(cr);
+	cairo_restore(cr);
 
-	if (key == KEY_F11 && state)
-		toggle_fullscreen(d->window, d->window->fullscreen ^ 1);
-	else if (key == KEY_ESC && state)
-		running = 0;
+	cairo_destroy(cr);
 }
 
 static void
-keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
-			  uint32_t serial, uint32_t mods_depressed,
-			  uint32_t mods_latched, uint32_t mods_locked,
-			  uint32_t group)
+fullscreen_handler(struct window *window, void *data)
 {
-}
+	struct transformed *transformed = data;
 
-static const struct wl_keyboard_listener keyboard_listener = {
-	keyboard_handle_keymap,
-	keyboard_handle_enter,
-	keyboard_handle_leave,
-	keyboard_handle_key,
-	keyboard_handle_modifiers,
-};
+	transformed->fullscreen ^= 1;
+	window_set_fullscreen(window, transformed->fullscreen);
+}
 
 static void
-seat_handle_capabilities(void *data, struct wl_seat *seat,
-			 enum wl_seat_capability caps)
+redraw_handler(struct widget *widget, void *data)
 {
-	struct display *d = data;
-
-	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !d->pointer) {
-		d->pointer = wl_seat_get_pointer(seat);
-		wl_pointer_add_listener(d->pointer, &pointer_listener, d);
-	} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && d->pointer) {
-		wl_pointer_destroy(d->pointer);
-		d->pointer = NULL;
-	}
+	struct transformed *transformed = data;
+	struct rectangle allocation;
+	cairo_surface_t *surface;
+	int transform;
 
-	if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !d->keyboard) {
-		d->keyboard = wl_seat_get_keyboard(seat);
-		wl_keyboard_add_listener(d->keyboard, &keyboard_listener, d);
-	} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && d->keyboard) {
-		wl_keyboard_destroy(d->keyboard);
-		d->keyboard = NULL;
+	surface = window_get_surface(transformed->window);
+	if (surface == NULL ||
+	    cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+		fprintf(stderr, "failed to create cairo egl surface\n");
+		return;
 	}
-}
 
-static const struct wl_seat_listener seat_listener = {
-	seat_handle_capabilities,
-};
+	widget_get_allocation(transformed->widget, &allocation);
+	transform = window_get_buffer_transform(transformed->window);
 
-static void
-output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
-		       int physical_width, int physical_height, int subpixel,
-		       const char *make, const char *model, int transform)
-{
-	struct output *output = data;
+	draw_stuff(surface, allocation.width, allocation.height, transform);
 
-	output->transform = transform;
+	cairo_surface_destroy(surface);
 }
 
 static void
-output_handle_mode(void *data, struct wl_output *output, uint32_t flags,
-		   int width, int height, int refresh)
+output_handler(struct window *window, struct output *output, int enter,
+	       void *data)
 {
-}
-
-static const struct wl_output_listener output_listener = {
-	output_handle_geometry,
-	output_handle_mode
-};
+	if (!enter)
+		return;
 
-static void
-registry_handle_global(void *data, struct wl_registry *registry,
-		       uint32_t name, const char *interface, uint32_t version)
-{
-	struct display *d = data;
-
-	if (strcmp(interface, "wl_compositor") == 0) {
-		d->compositor =
-			wl_registry_bind(registry, name,
-					 &wl_compositor_interface, 1);
-	} else if (strcmp(interface, "wl_shell") == 0) {
-		d->shell = wl_registry_bind(registry, name,
-					    &wl_shell_interface, 1);
-	} else if (strcmp(interface, "wl_seat") == 0) {
-		d->seat = wl_registry_bind(registry, name,
-					   &wl_seat_interface, 1);
-		wl_seat_add_listener(d->seat, &seat_listener, d);
-	} else if (strcmp(interface, "wl_output") == 0) {
-		struct output *output = malloc(sizeof *output);
-
-		if (!output)
-			return;
-
-		output->output = wl_registry_bind(registry, name,
-						  &wl_output_interface, 1);
-		wl_output_add_listener(output->output, &output_listener,
-				       output);
-		wl_list_insert(&d->output_list, &output->link);
-	}
+	window_set_buffer_transform(window, output_get_transform(output));
+	window_schedule_redraw(window);
 }
 
-static const struct wl_registry_listener registry_listener = {
-	registry_handle_global
-};
-
-static void
-signal_int(int signum)
+static int
+motion_handler(struct widget *widget, struct input *input,
+	       uint32_t time, float x, float y, void *data)
 {
-	running = 0;
+	return CURSOR_BLANK;
 }
 
 static void
-usage(int error_code)
+button_handler(struct widget *widget,
+	       struct input *input, uint32_t time,
+	       uint32_t button, enum wl_pointer_button_state state, void *data)
 {
-	fprintf(stderr, "Usage: simple-egl [OPTIONS]\n\n"
-		"  -f\tRun in fullscreen mode\n"
-		"  -h\tThis help text\n\n");
+	struct transformed *transformed = data;
 
-	exit(error_code);
+	switch (button) {
+	case BTN_LEFT:
+		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+			window_move(transformed->window, input,
+				    display_get_serial(transformed->display));
+		break;
+	case BTN_MIDDLE:
+		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+			widget_schedule_redraw(widget);
+		break;
+	case BTN_RIGHT:
+		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+			window_show_frame_menu(transformed->window, input, time);
+		break;
+	}
 }
 
-int
-main(int argc, char **argv)
+int main(int argc, char *argv[])
 {
-	struct sigaction sigint;
-	struct display display = { 0 };
-	struct window  window  = { 0 };
-	int i, ret = 0;
-
-	window.display = &display;
-	display.window = &window;
-	window.window_size.width  = 500;
-	window.window_size.height = 250;
-
-	wl_list_init(&display.output_list);
-
-	for (i = 1; i < argc; i++) {
-		if (strcmp("-f", argv[i]) == 0)
-			window.fullscreen = 1;
-		else if (strcmp("-h", argv[i]) == 0)
-			usage(EXIT_SUCCESS);
-		else
-			usage(EXIT_FAILURE);
-	}
+	struct transformed transformed;
+	struct display *d;
 
-	display.display = wl_display_connect(NULL);
-	assert(display.display);
-
-	display.registry = wl_display_get_registry(display.display);
-	wl_registry_add_listener(display.registry,
-				 &registry_listener, &display);
-
-	wl_display_dispatch(display.display);
-
-	init_egl(&display);
-	create_surface(&window);
-	init_gl(&window);
-
-	sigint.sa_handler = signal_int;
-	sigemptyset(&sigint.sa_mask);
-	sigint.sa_flags = SA_RESETHAND;
-	sigaction(SIGINT, &sigint, NULL);
+	d = display_create(argc, argv);
+	if (d == NULL) {
+		fprintf(stderr, "failed to create display: %m\n");
+		return -1;
+	}
 
-	while (running && ret != -1)
-		ret = wl_display_dispatch(display.display);
+	transformed.width = 500;
+	transformed.height = 250;
+	transformed.display = d;
+	transformed.fullscreen = 0;
+	transformed.window = window_create(d);
+	transformed.widget =
+		window_add_widget(transformed.window, &transformed);
+	window_set_title(transformed.window, "Transformed");
 
-	fprintf(stderr, "simple-egl exiting\n");
+	widget_set_transparent(transformed.widget, 0);
 
-	destroy_surface(&window);
-	fini_egl(&display);
+	widget_set_redraw_handler(transformed.widget, redraw_handler);
+	widget_set_motion_handler(transformed.widget, motion_handler);
+	widget_set_button_handler(transformed.widget, button_handler);
 
-	if (display.shell)
-		wl_shell_destroy(display.shell);
+	window_set_fullscreen_handler(transformed.window, fullscreen_handler);
+	window_set_output_handler(transformed.window, output_handler);
 
-	if (display.compositor)
-		wl_compositor_destroy(display.compositor);
+	window_set_user_data(transformed.window, &transformed);
+	window_schedule_resize(transformed.window,
+			       transformed.width, transformed.height);
 
-	wl_display_flush(display.display);
-	wl_display_disconnect(display.display);
+	display_run(d);
 
 	return 0;
 }
-- 
1.7.10.4



More information about the wayland-devel mailing list