mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	dlopen the compositor, add a glx compositor.
This commit is contained in:
		
							parent
							
								
									61ba898b73
								
							
						
					
					
						commit
						5503bf82c4
					
				
					 5 changed files with 395 additions and 32 deletions
				
			
		
							
								
								
									
										40
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -1,16 +1,22 @@
 | 
				
			||||||
CFLAGS +=  -Wall -g $(shell pkg-config --cflags libffi libdrm)
 | 
					CFLAGS = -Wall -g
 | 
				
			||||||
LDLIBS += $(shell pkg-config --libs libffi libdrm)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
EAGLE_CFLAGS = -I../eagle
 | 
					EAGLE_CFLAGS = -I../eagle
 | 
				
			||||||
EAGLE_LDLIBS = -L../eagle -leagle
 | 
					EAGLE_LDLIBS = -L../eagle -leagle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clients = flower pointer background window
 | 
					clients = flower pointer background window
 | 
				
			||||||
 | 
					compositors = egl-compositor.so glx-compositor.so
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all : wayland $(clients)
 | 
					all : wayland libwayland.so $(compositors) $(clients)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wayland_objs = wayland.o event-loop.o connection.o hash.o input.o egl-compositor.o
 | 
					wayland_objs =					\
 | 
				
			||||||
wayland : CFLAGS += $(EAGLE_CFLAGS)
 | 
						wayland.o				\
 | 
				
			||||||
wayland : LDLIBS += $(EAGLE_LDLIBS)
 | 
						event-loop.o				\
 | 
				
			||||||
 | 
						connection.o				\
 | 
				
			||||||
 | 
						hash.o					\
 | 
				
			||||||
 | 
						input.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wayland : CFLAGS += $(shell pkg-config --cflags libffi)
 | 
				
			||||||
 | 
					wayland : LDLIBS += $(shell pkg-config --libs libffi) -ldl -rdynamic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wayland : $(wayland_objs)
 | 
					wayland : $(wayland_objs)
 | 
				
			||||||
	gcc -o $@ $(LDLIBS) $(wayland_objs)
 | 
						gcc -o $@ $(LDLIBS) $(wayland_objs)
 | 
				
			||||||
| 
						 | 
					@ -18,7 +24,23 @@ wayland : $(wayland_objs)
 | 
				
			||||||
libwayland_objs = wayland-client.o connection.o
 | 
					libwayland_objs = wayland-client.o connection.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libwayland.so : $(libwayland_objs)
 | 
					libwayland.so : $(libwayland_objs)
 | 
				
			||||||
	gcc -o $@ $(libwayland_objs) -shared
 | 
					
 | 
				
			||||||
 | 
					$(compositors) $(clients) : CFLAGS += $(shell pkg-config --cflags libdrm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					egl_compositor_objs = egl-compositor.o
 | 
				
			||||||
 | 
					egl-compositor.so : CFLAGS += $(EAGLE_CFLAGS)
 | 
				
			||||||
 | 
					egl-compositor.so : LDLIBS += $(EAGLE_LDLIBS) -rdynamic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					egl-compositor.so : $(egl_compositor_objs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					glx_compositor_objs = glx-compositor.o
 | 
				
			||||||
 | 
					glx-compositor.so : LDLIBS += -lGL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					glx-compositor.so : $(glx_compositor_objs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libwayland.so $(compositors) :
 | 
				
			||||||
 | 
						gcc -o $@ $^ $(LDLIBS) -shared 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
flower_objs = flower.o
 | 
					flower_objs = flower.o
 | 
				
			||||||
pointer_objs = pointer.o
 | 
					pointer_objs = pointer.o
 | 
				
			||||||
| 
						 | 
					@ -26,7 +48,7 @@ background_objs = background.o
 | 
				
			||||||
window_objs = window.o gears.o
 | 
					window_objs = window.o gears.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(clients) : CFLAGS += $(shell pkg-config --cflags cairo)
 | 
					$(clients) : CFLAGS += $(shell pkg-config --cflags cairo)
 | 
				
			||||||
$(clients) : LDLIBS += $(shell pkg-config --libs cairo gdk-pixbuf-2.0) -lrt
 | 
					$(clients) : LDLIBS += $(shell pkg-config --libs cairo) -lrt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
background : CFLAGS += $(shell pkg-config --cflags gdk-pixbuf-2.0)
 | 
					background : CFLAGS += $(shell pkg-config --cflags gdk-pixbuf-2.0)
 | 
				
			||||||
background : LDLIBS += $(shell pkg-config --libs gdk-pixbuf-2.0)
 | 
					background : LDLIBS += $(shell pkg-config --libs gdk-pixbuf-2.0)
 | 
				
			||||||
| 
						 | 
					@ -44,4 +66,4 @@ $(clients) :
 | 
				
			||||||
	gcc -o $@ -L. -lwayland $(LDLIBS) $^
 | 
						gcc -o $@ -L. -lwayland $(LDLIBS) $^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean :
 | 
					clean :
 | 
				
			||||||
	rm -f $(clients) wayland *.o libwayland.so
 | 
						rm -f $(clients) wayland *.o *.so
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,8 @@ repaint(void *data)
 | 
				
			||||||
	eglSwapBuffers(ec->display, ec->surface);
 | 
						eglSwapBuffers(ec->display, ec->surface);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void schedule_repaint(struct egl_compositor *ec)
 | 
					static void
 | 
				
			||||||
 | 
					schedule_repaint(struct egl_compositor *ec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_event_loop *loop;
 | 
						struct wl_event_loop *loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,7 +94,8 @@ static void schedule_repaint(struct egl_compositor *ec)
 | 
				
			||||||
	wl_event_loop_add_idle(loop, repaint, ec);
 | 
						wl_event_loop_add_idle(loop, repaint, ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void notify_surface_create(struct wl_compositor *compositor,
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_create(struct wl_compositor *compositor,
 | 
				
			||||||
		      struct wl_surface *surface)
 | 
							      struct wl_surface *surface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct surface_data *sd;
 | 
						struct surface_data *sd;
 | 
				
			||||||
| 
						 | 
					@ -108,7 +110,8 @@ void notify_surface_create(struct wl_compositor *compositor,
 | 
				
			||||||
	glGenTextures(1, &sd->texture);
 | 
						glGenTextures(1, &sd->texture);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
				   
 | 
									   
 | 
				
			||||||
void notify_surface_destroy(struct wl_compositor *compositor,
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_destroy(struct wl_compositor *compositor,
 | 
				
			||||||
		       struct wl_surface *surface)
 | 
							       struct wl_surface *surface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct egl_compositor *ec = (struct egl_compositor *) compositor;
 | 
						struct egl_compositor *ec = (struct egl_compositor *) compositor;
 | 
				
			||||||
| 
						 | 
					@ -128,7 +131,8 @@ void notify_surface_destroy(struct wl_compositor *compositor,
 | 
				
			||||||
	schedule_repaint(ec);
 | 
						schedule_repaint(ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void notify_surface_attach(struct wl_compositor *compositor,
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_attach(struct wl_compositor *compositor,
 | 
				
			||||||
		      struct wl_surface *surface, uint32_t name, 
 | 
							      struct wl_surface *surface, uint32_t name, 
 | 
				
			||||||
		      uint32_t width, uint32_t height, uint32_t stride)
 | 
							      uint32_t width, uint32_t height, uint32_t stride)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -158,7 +162,8 @@ void notify_surface_attach(struct wl_compositor *compositor,
 | 
				
			||||||
	schedule_repaint(ec);
 | 
						schedule_repaint(ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void notify_surface_map(struct wl_compositor *compositor,
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_map(struct wl_compositor *compositor,
 | 
				
			||||||
		   struct wl_surface *surface, struct wl_map *map)
 | 
							   struct wl_surface *surface, struct wl_map *map)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct egl_compositor *ec = (struct egl_compositor *) compositor;
 | 
						struct egl_compositor *ec = (struct egl_compositor *) compositor;
 | 
				
			||||||
| 
						 | 
					@ -173,7 +178,7 @@ void notify_surface_map(struct wl_compositor *compositor,
 | 
				
			||||||
	schedule_repaint(ec);
 | 
						schedule_repaint(ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_compositor_interface interface = {
 | 
					static const struct wl_compositor_interface interface = {
 | 
				
			||||||
	notify_surface_create,
 | 
						notify_surface_create,
 | 
				
			||||||
	notify_surface_destroy,
 | 
						notify_surface_destroy,
 | 
				
			||||||
	notify_surface_attach,
 | 
						notify_surface_attach,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										307
									
								
								glx-compositor.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								glx-compositor.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,307 @@
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <i915_drm.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					#include <sys/mman.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <linux/fb.h>
 | 
				
			||||||
 | 
					#include <X11/Xlib.h>
 | 
				
			||||||
 | 
					#include <X11/keysym.h>
 | 
				
			||||||
 | 
					#include <GL/gl.h>
 | 
				
			||||||
 | 
					#include <GL/glx.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "wayland.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct glx_compositor {
 | 
				
			||||||
 | 
						struct wl_compositor base;
 | 
				
			||||||
 | 
						Display *display;
 | 
				
			||||||
 | 
						GLXContext context;
 | 
				
			||||||
 | 
						Window window;
 | 
				
			||||||
 | 
						struct wl_display *wl_display;
 | 
				
			||||||
 | 
						int gem_fd;
 | 
				
			||||||
 | 
						struct wl_event_source *x_source;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct surface_data {
 | 
				
			||||||
 | 
						GLuint texture;
 | 
				
			||||||
 | 
						struct wl_map map;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					repaint(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct glx_compositor *gc = data;
 | 
				
			||||||
 | 
						struct wl_surface_iterator *iterator;
 | 
				
			||||||
 | 
						struct wl_surface *surface;
 | 
				
			||||||
 | 
						struct surface_data *sd;
 | 
				
			||||||
 | 
						GLint vertices[12];
 | 
				
			||||||
 | 
						GLint tex_coords[12] = { 0, 0,  0, 1,  1, 0,  1, 1 };
 | 
				
			||||||
 | 
						GLuint indices[4] = { 0, 1, 2, 3 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iterator = wl_surface_iterator_create(gc->wl_display, 0);
 | 
				
			||||||
 | 
						while (wl_surface_iterator_next(iterator, &surface)) {
 | 
				
			||||||
 | 
							sd = wl_surface_get_data(surface);
 | 
				
			||||||
 | 
							if (sd == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vertices[0] = sd->map.x;
 | 
				
			||||||
 | 
							vertices[1] = sd->map.y;
 | 
				
			||||||
 | 
							vertices[2] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vertices[3] = sd->map.x;
 | 
				
			||||||
 | 
							vertices[4] = sd->map.y + sd->map.height;
 | 
				
			||||||
 | 
							vertices[5] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vertices[6] = sd->map.x + sd->map.width;
 | 
				
			||||||
 | 
							vertices[7] = sd->map.y;
 | 
				
			||||||
 | 
							vertices[8] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vertices[9] = sd->map.x + sd->map.width;
 | 
				
			||||||
 | 
							vertices[10] = sd->map.y + sd->map.height;
 | 
				
			||||||
 | 
							vertices[11] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							glBindTexture(GL_TEXTURE_2D, sd->texture);
 | 
				
			||||||
 | 
							glEnable(GL_TEXTURE_2D);
 | 
				
			||||||
 | 
							glEnable(GL_BLEND);
 | 
				
			||||||
 | 
							/* Assume pre-multiplied alpha for now, this probably
 | 
				
			||||||
 | 
							 * needs to be a wayland visual type of thing. */
 | 
				
			||||||
 | 
							glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							glEnableClientState(GL_VERTEX_ARRAY);
 | 
				
			||||||
 | 
							glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 | 
				
			||||||
 | 
							glVertexPointer(3, GL_INT, 0, vertices);
 | 
				
			||||||
 | 
							glTexCoordPointer(2, GL_INT, 0, tex_coords);
 | 
				
			||||||
 | 
							glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, indices);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						wl_surface_iterator_destroy(iterator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glXSwapBuffers(gc->display, gc->window);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					schedule_repaint(struct glx_compositor *gc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wl_event_loop *loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						loop = wl_display_get_event_loop(gc->wl_display);
 | 
				
			||||||
 | 
						wl_event_loop_add_idle(loop, repaint, gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_create(struct wl_compositor *compositor,
 | 
				
			||||||
 | 
							      struct wl_surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct surface_data *sd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sd = malloc(sizeof *sd);
 | 
				
			||||||
 | 
						if (sd == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_surface_set_data(surface, sd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glGenTextures(1, &sd->texture);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
									   
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_destroy(struct wl_compositor *compositor,
 | 
				
			||||||
 | 
							       struct wl_surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct glx_compositor *gc = (struct glx_compositor *) compositor;
 | 
				
			||||||
 | 
						struct surface_data *sd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sd = wl_surface_get_data(surface);
 | 
				
			||||||
 | 
						if (sd == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glDeleteTextures(1, &sd->texture);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(sd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						schedule_repaint(gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_attach(struct wl_compositor *compositor,
 | 
				
			||||||
 | 
							      struct wl_surface *surface, uint32_t name, 
 | 
				
			||||||
 | 
							      uint32_t width, uint32_t height,
 | 
				
			||||||
 | 
							      uint32_t stride)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct glx_compositor *gc = (struct glx_compositor *) compositor;
 | 
				
			||||||
 | 
						struct surface_data *sd;
 | 
				
			||||||
 | 
						struct drm_gem_open open_arg;
 | 
				
			||||||
 | 
						struct drm_gem_close close_arg;
 | 
				
			||||||
 | 
						struct drm_i915_gem_pread pread;
 | 
				
			||||||
 | 
						uint32_t size;
 | 
				
			||||||
 | 
						void *data;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sd = wl_surface_get_data(surface);
 | 
				
			||||||
 | 
						if (sd == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						open_arg.name = name;
 | 
				
			||||||
 | 
						ret = ioctl(gc->gem_fd, DRM_IOCTL_GEM_OPEN, &open_arg);
 | 
				
			||||||
 | 
						if (ret != 0) {
 | 
				
			||||||
 | 
							fprintf(stderr,
 | 
				
			||||||
 | 
								"failed to gem_open name %d, fd=%d: %m\n",
 | 
				
			||||||
 | 
								name, gc->gem_fd);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size = height * stride;
 | 
				
			||||||
 | 
						data = malloc(size);
 | 
				
			||||||
 | 
						if (data == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "malloc for gem_pread failed\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pread.handle = open_arg.handle;
 | 
				
			||||||
 | 
						pread.pad = 0;
 | 
				
			||||||
 | 
						pread.offset = 0;
 | 
				
			||||||
 | 
						pread.size = size;
 | 
				
			||||||
 | 
						pread.data_ptr = (long) data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ioctl(gc->gem_fd, DRM_IOCTL_I915_GEM_PREAD, &pread)) {
 | 
				
			||||||
 | 
							fprintf(stderr, "gem_pread failed");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						close_arg.handle = open_arg.handle;
 | 
				
			||||||
 | 
						ret = ioctl(gc->gem_fd, DRM_IOCTL_GEM_CLOSE, &close_arg);
 | 
				
			||||||
 | 
						if (ret != 0) {
 | 
				
			||||||
 | 
							fprintf(stderr, "failed to gem_close name %d: %m\n", name);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glBindTexture(GL_TEXTURE_2D, sd->texture);
 | 
				
			||||||
 | 
						glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 | 
				
			||||||
 | 
						glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
 | 
				
			||||||
 | 
						glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
				
			||||||
 | 
						glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
				
			||||||
 | 
						glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
 | 
				
			||||||
 | 
							     GL_BGRA, GL_UNSIGNED_BYTE, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						schedule_repaint(gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					notify_surface_map(struct wl_compositor *compositor,
 | 
				
			||||||
 | 
							   struct wl_surface *surface, struct wl_map *map)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct glx_compositor *gc = (struct glx_compositor *) compositor;
 | 
				
			||||||
 | 
						struct surface_data *sd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sd = wl_surface_get_data(surface);
 | 
				
			||||||
 | 
						if (sd == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sd->map = *map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						schedule_repaint(gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wl_compositor_interface interface = {
 | 
				
			||||||
 | 
						notify_surface_create,
 | 
				
			||||||
 | 
						notify_surface_destroy,
 | 
				
			||||||
 | 
						notify_surface_attach,
 | 
				
			||||||
 | 
						notify_surface_map
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char gem_device[] = "/dev/dri/card0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					display_data(int fd, uint32_t mask, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct glx_compositor *gc = data;
 | 
				
			||||||
 | 
						XEvent ev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (XPending(gc->display) > 0) {
 | 
				
			||||||
 | 
							XNextEvent(gc->display, &ev);
 | 
				
			||||||
 | 
							/* Some day we'll do something useful with these events. */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wl_compositor *
 | 
				
			||||||
 | 
					wl_compositor_create(struct wl_display *display)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static int attribs[] = {
 | 
				
			||||||
 | 
							GLX_RGBA,
 | 
				
			||||||
 | 
							GLX_RED_SIZE, 1,
 | 
				
			||||||
 | 
							GLX_GREEN_SIZE, 1,
 | 
				
			||||||
 | 
							GLX_BLUE_SIZE, 1,
 | 
				
			||||||
 | 
							GLX_DOUBLEBUFFER,
 | 
				
			||||||
 | 
							GLX_DEPTH_SIZE, 1,
 | 
				
			||||||
 | 
							None
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						struct glx_compositor *gc;
 | 
				
			||||||
 | 
						const int x = 100, y = 100, width = 1024, height = 768;
 | 
				
			||||||
 | 
						XSetWindowAttributes attr;
 | 
				
			||||||
 | 
						unsigned long mask;
 | 
				
			||||||
 | 
						Window root;
 | 
				
			||||||
 | 
						XVisualInfo *visinfo;
 | 
				
			||||||
 | 
						int screen;
 | 
				
			||||||
 | 
						struct wl_event_loop *loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gc = malloc(sizeof *gc);
 | 
				
			||||||
 | 
						if (gc == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gc->base.interface = &interface;
 | 
				
			||||||
 | 
						gc->wl_display = display;
 | 
				
			||||||
 | 
						gc->display = XOpenDisplay(NULL);
 | 
				
			||||||
 | 
						if (gc->display == NULL) {
 | 
				
			||||||
 | 
							free(gc);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						loop = wl_display_get_event_loop(gc->wl_display);
 | 
				
			||||||
 | 
						gc->x_source = wl_event_loop_add_fd(loop,
 | 
				
			||||||
 | 
										    ConnectionNumber(gc->display),
 | 
				
			||||||
 | 
										    WL_EVENT_READABLE,
 | 
				
			||||||
 | 
										    display_data, gc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen = DefaultScreen(gc->display);
 | 
				
			||||||
 | 
						root = RootWindow(gc->display, screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						visinfo = glXChooseVisual(gc->display, screen, attribs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* window attributes */
 | 
				
			||||||
 | 
						attr.background_pixel = 0;
 | 
				
			||||||
 | 
						attr.border_pixel = 0;
 | 
				
			||||||
 | 
						attr.colormap = XCreateColormap(gc->display,
 | 
				
			||||||
 | 
										root, visinfo->visual, AllocNone);
 | 
				
			||||||
 | 
						attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
 | 
				
			||||||
 | 
						mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
 | 
				
			||||||
 | 
						gc->window = XCreateWindow(gc->display, root, x, y, width, height,
 | 
				
			||||||
 | 
									   0, visinfo->depth, InputOutput,
 | 
				
			||||||
 | 
									   visinfo->visual, mask, &attr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gc->context = glXCreateContext(gc->display, visinfo, NULL, True);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						XMapWindow(gc->display, gc->window);
 | 
				
			||||||
 | 
						glXMakeCurrent(gc->display, gc->window, gc->context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glViewport(0, 0, width, height);
 | 
				
			||||||
 | 
						glMatrixMode(GL_PROJECTION);
 | 
				
			||||||
 | 
						glLoadIdentity();
 | 
				
			||||||
 | 
						glOrtho(0, width, height, 0, 0, 1000.0);
 | 
				
			||||||
 | 
						glMatrixMode(GL_MODELVIEW);
 | 
				
			||||||
 | 
						glClearColor(0.0, 0.05, 0.2, 0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gc->gem_fd = open(gem_device, O_RDWR);
 | 
				
			||||||
 | 
						if (gc->gem_fd < 0) {
 | 
				
			||||||
 | 
							fprintf(stderr, "failed to open drm device\n");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						schedule_repaint(gc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &gc->base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								wayland.c
									
										
									
									
									
								
							
							
						
						
									
										49
									
								
								wayland.c
									
										
									
									
									
								
							| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <sys/un.h>
 | 
					#include <sys/un.h>
 | 
				
			||||||
 | 
					#include <dlfcn.h>
 | 
				
			||||||
#include <ffi.h>
 | 
					#include <ffi.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "wayland.h"
 | 
					#include "wayland.h"
 | 
				
			||||||
| 
						 | 
					@ -98,7 +99,7 @@ static void
 | 
				
			||||||
wl_surface_destroy(struct wl_client *client,
 | 
					wl_surface_destroy(struct wl_client *client,
 | 
				
			||||||
		   struct wl_surface *surface)
 | 
							   struct wl_surface *surface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_compositor_interface *interface;
 | 
						const struct wl_compositor_interface *interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	interface = client->display->compositor->interface;
 | 
						interface = client->display->compositor->interface;
 | 
				
			||||||
	interface->notify_surface_destroy(client->display->compositor,
 | 
						interface->notify_surface_destroy(client->display->compositor,
 | 
				
			||||||
| 
						 | 
					@ -111,7 +112,7 @@ wl_surface_attach(struct wl_client *client,
 | 
				
			||||||
		  struct wl_surface *surface, uint32_t name, 
 | 
							  struct wl_surface *surface, uint32_t name, 
 | 
				
			||||||
		  uint32_t width, uint32_t height, uint32_t stride)
 | 
							  uint32_t width, uint32_t height, uint32_t stride)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_compositor_interface *interface;
 | 
						const struct wl_compositor_interface *interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	interface = client->display->compositor->interface;
 | 
						interface = client->display->compositor->interface;
 | 
				
			||||||
	interface->notify_surface_attach(client->display->compositor,
 | 
						interface->notify_surface_attach(client->display->compositor,
 | 
				
			||||||
| 
						 | 
					@ -129,7 +130,7 @@ void
 | 
				
			||||||
wl_surface_map(struct wl_client *client, struct wl_surface *surface,
 | 
					wl_surface_map(struct wl_client *client, struct wl_surface *surface,
 | 
				
			||||||
	       int32_t x, int32_t y, int32_t width, int32_t height)
 | 
						       int32_t x, int32_t y, int32_t width, int32_t height)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_compositor_interface *interface;
 | 
						const struct wl_compositor_interface *interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* FIXME: This needs to take a tri-mesh argument... - count
 | 
						/* FIXME: This needs to take a tri-mesh argument... - count
 | 
				
			||||||
	 * and a list of tris. 0 tris means unmap. */
 | 
						 * and a list of tris. 0 tris means unmap. */
 | 
				
			||||||
| 
						 | 
					@ -170,7 +171,7 @@ struct wl_surface *
 | 
				
			||||||
wl_surface_create(struct wl_display *display, uint32_t id)
 | 
					wl_surface_create(struct wl_display *display, uint32_t id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_surface *surface;
 | 
						struct wl_surface *surface;
 | 
				
			||||||
	struct wl_compositor_interface *interface;
 | 
						const struct wl_compositor_interface *interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	surface = malloc(sizeof *surface);
 | 
						surface = malloc(sizeof *surface);
 | 
				
			||||||
	if (surface == NULL)
 | 
						if (surface == NULL)
 | 
				
			||||||
| 
						 | 
					@ -706,10 +707,41 @@ wl_surface_iterator_destroy(struct wl_surface_iterator *iterator)
 | 
				
			||||||
	free(iterator);
 | 
						free(iterator);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					load_compositor(struct wl_display *display, const char *path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wl_compositor *(*create)(struct wl_display *display);
 | 
				
			||||||
 | 
						struct wl_compositor *compositor;
 | 
				
			||||||
 | 
						void *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
 | 
				
			||||||
 | 
						if (p == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "failed to open compositor %s: %s\n",
 | 
				
			||||||
 | 
								path, dlerror());
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						create = dlsym(p, "wl_compositor_create");
 | 
				
			||||||
 | 
						if (create == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "failed to look up compositor constructor\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						compositor = create(display);
 | 
				
			||||||
 | 
						if (compositor == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "couldn't create compositor\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_display_set_compositor(display, compositor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[])
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_display *display;
 | 
						struct wl_display *display;
 | 
				
			||||||
	struct wl_compositor *compositor;
 | 
						const char *compositor = "egl-compositor.so";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	display = wl_display_create();
 | 
						display = wl_display_create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -718,10 +750,9 @@ int main(int argc, char *argv[])
 | 
				
			||||||
		exit(EXIT_FAILURE);
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	compositor = wl_compositor_create(display);
 | 
						if (argc == 2)
 | 
				
			||||||
	wl_display_set_compositor(display, compositor);
 | 
							compositor = argv[1];
 | 
				
			||||||
 | 
						load_compositor(display, compositor);
 | 
				
			||||||
	printf("wayland online, display is %p\n", display);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_display_run(display);
 | 
						wl_display_run(display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,7 +113,7 @@ wl_display_post_button_event(struct wl_display *display,
 | 
				
			||||||
			     struct wl_object *source, int button, int state);
 | 
								     struct wl_object *source, int button, int state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_compositor {
 | 
					struct wl_compositor {
 | 
				
			||||||
	struct wl_compositor_interface *interface;
 | 
						const struct wl_compositor_interface *interface;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_compositor_interface {
 | 
					struct wl_compositor_interface {
 | 
				
			||||||
| 
						 | 
					@ -128,8 +128,6 @@ struct wl_compositor_interface {
 | 
				
			||||||
				   struct wl_surface *surface, struct wl_map *map);
 | 
									   struct wl_surface *surface, struct wl_map *map);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_compositor *wl_compositor_create(struct wl_display *display);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void wl_display_set_compositor(struct wl_display *display,
 | 
					void wl_display_set_compositor(struct wl_display *display,
 | 
				
			||||||
			       struct wl_compositor *compositor);
 | 
								       struct wl_compositor *compositor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue