{
struct wl_display *display;
struct wl_surface *surface;
- const int x = 200, y = 100, width = 300, height = 300;
+ const int x = 200, y = 200, width = 200, height = 200;
int fd, i, ret;
uint32_t name, mask;
cairo_surface_t *s;
cairo_image_surface_get_stride(s));
i = 0;
- while (ret = poll(p, 1, 20), ret >= 0) {
+ while (ret = poll(p, 1, 200), ret >= 0) {
if (ret == 0) {
wl_surface_map(surface,
- x + cos(i / 10.0) * 50,
- y + sin(i / 10.0) * 50,
+ x + cos(i / 10.0) * 150,
+ y + sin(i / 10.0) * 150,
width, height);
i++;
continue;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
+ struct wl_display *wl_display;
int gem_fd;
};
uint32_t handle;
int32_t width, height, stride;
GLuint texture;
+ struct wl_map map;
};
void notify_surface_create(struct wl_compositor *compositor,
free(data);
}
-void notify_surface_map(struct wl_compositor *compositor,
- struct wl_surface *surface, struct wl_map *map)
+static void
+repaint(struct egl_compositor *ec)
{
- struct egl_compositor *ec = (struct egl_compositor *) compositor;
+ struct wl_surface_iterator *iterator;
+ struct wl_surface *surface;
struct surface_data *sd;
- GLint vertices[12] = {
- map->x, map->y, 0.0,
- map->x, map->y + map->height, 0.0,
- map->x + map->width, map->y + map->height, 0.0,
- map->x + map->width, map->y, 0.0
- };
- GLint tex_coords[8] = {
- 1, 0,
- 1, 1,
- 0, 1,
- 0, 0
- };
+ GLint vertices[12];
+ GLint tex_coords[8] = { 1, 0, 1, 1, 0, 1, 0, 0 };
GLuint indices[4] = { 0, 1, 2, 3 };
-
+
/* This part is where we actually copy the buffer to screen.
- * Needs to be part of the repaint loop, not in the notify_map
- * handler. */
-
- sd = wl_surface_get_data(surface);
- if (sd == NULL)
- return;
+ * Needs to be part of the repaint loop, not called from the
+ * notify_map handler. */
glClear(GL_COLOR_BUFFER_BIT);
- glBindTexture(GL_TEXTURE_2D, sd->texture);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, 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_QUADS, 4, GL_UNSIGNED_INT, indices);
+ iterator = wl_surface_iterator_create(ec->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 + sd->map.height;
+ vertices[8] = 0;
+
+ vertices[9] = sd->map.x + sd->map.width;
+ vertices[10] = sd->map.y;
+ vertices[11] = 0;
+
+ glBindTexture(GL_TEXTURE_2D, sd->texture);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, 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_QUADS, 4, GL_UNSIGNED_INT, indices);
+ }
+ wl_surface_iterator_destroy(iterator);
glFlush();
eglSwapBuffers(ec->display, ec->surface);
}
+void notify_surface_map(struct wl_compositor *compositor,
+ struct wl_surface *surface, struct wl_map *map)
+{
+ struct egl_compositor *ec = (struct egl_compositor *) compositor;
+ struct surface_data *sd;
+
+ sd = wl_surface_get_data(surface);
+ if (sd == NULL)
+ return;
+
+ sd->map = *map;
+ repaint(ec);
+}
+
struct wl_compositor_interface interface = {
notify_surface_create,
notify_surface_destroy,
static const char gem_device[] = "/dev/dri/card0";
struct wl_compositor *
-wl_compositor_create(void)
+wl_compositor_create(struct wl_display *display)
{
EGLConfig configs[64];
EGLint major, minor, count;
return NULL;
ec->base.interface = &interface;
+ ec->wl_display = display;
ec->display = eglCreateDisplay(gem_device, "i965");
if (ec->display == NULL) {
return NULL;
memset(display, 0, sizeof *display);
- display->id = 256; /* Need to get our id-range. */
display->fd = socket(PF_LOCAL, SOCK_STREAM, 0);
if (display->fd < 0) {
free(display);
return NULL;
}
+ /* FIXME: We'll need a protocol for getting a new range, I
+ * guess... */
+ read(display->fd, &display->id, sizeof display->id);
+
/* FIXME: actually discover advertised objects here. */
read(display->fd, &id, sizeof id);
read(display->fd, &length, sizeof length);
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-struct wl_region {
+struct wl_list {
+ struct wl_list *prev;
+ struct wl_list *next;
};
+void wl_list_init(struct wl_list *list)
+{
+ list->prev = list;
+ list->next = list;
+}
+
+void
+wl_list_insert(struct wl_list *list, struct wl_list *elm)
+{
+ elm->prev = list;
+ elm->next = list->next;
+ list->next = elm;
+ elm->next->prev = elm;
+}
+
+void
+wl_list_remove(struct wl_list *elm)
+{
+ elm->prev->next = elm->next;
+ elm->next->prev = elm->prev;
+}
+
struct wl_client {
struct wl_connection *connection;
struct wl_event_source *source;
struct wl_compositor *compositor;
struct wl_compositor_interface *compositor_interface;
+
+ struct wl_list surface_list;
+ uint32_t client_id_range;
};
struct wl_surface {
int stride;
struct wl_map map;
+ struct wl_list link;
/* how to convert buffer contents to pixels in screen format;
* yuv->rgb, indexed->rgb, svg->rgb, but mostly just rgb->rgb. */
struct wl_compositor_interface *interface;
interface = client->display->compositor->interface;
- interface->notify_surface_destroy(client->display->compositor, surface);
+ interface->notify_surface_destroy(client->display->compositor,
+ surface);
+ wl_list_remove(&surface->link);
}
static void
surface->base.id = id;
surface->base.interface = &surface_interface;
+ wl_list_insert(display->surface_list.prev, &surface->link);
+
interface = display->compositor->interface;
interface->notify_surface_create(display->compositor, surface);
static void
wl_client_event(struct wl_client *client, struct wl_object *object, uint32_t event)
{
- const struct wl_interface *interface;
uint32_t p[2];
- interface = object->interface;
-
p[0] = object->id;
p[1] = event | (8 << 16);
wl_connection_write(client->connection, p, sizeof p);
wl_client_connection_update,
client);
+ wl_connection_write(client->connection,
+ &display->client_id_range,
+ sizeof display->client_id_range);
+ display->client_id_range += 256;
+
advertise_object(client, &display->base);
return client;
display->base.id = 0;
display->base.interface = &display_interface;
wl_hash_insert(&display->objects, &display->base);
+ wl_list_init(&display->surface_list);
+
+ display->client_id_range = 256; /* Gah, arbitrary... */
return display;
}
}
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+struct wl_surface_iterator {
+ struct wl_list *head;
+ struct wl_surface *surface;
+ uint32_t mask;
+};
+
+struct wl_surface_iterator *
+wl_surface_iterator_create(struct wl_display *display, uint32_t mask)
+{
+ struct wl_surface_iterator *iterator;
+
+ iterator = malloc(sizeof *iterator);
+ if (iterator == NULL)
+ return NULL;
+
+ iterator->head = &display->surface_list;
+ iterator->surface = container_of(display->surface_list.next,
+ struct wl_surface, link);
+ iterator->mask = mask;
+
+ return iterator;
+}
+
+int
+wl_surface_iterator_next(struct wl_surface_iterator *iterator,
+ struct wl_surface **surface)
+{
+ if (&iterator->surface->link == iterator->head)
+ return 0;
+
+ *surface = iterator->surface;
+ iterator->surface = container_of(iterator->surface->link.next,
+ struct wl_surface, link);
+
+ return 1;
+}
+
+void
+wl_surface_iterator_destroy(struct wl_surface_iterator *iterator)
+{
+ free(iterator);
+}
+
int main(int argc, char *argv[])
{
struct wl_display *display;
exit(EXIT_FAILURE);
}
- compositor = wl_compositor_create();
+ compositor = wl_compositor_create(display);
wl_display_set_compositor(display, compositor);
printf("wayland online, display is %p\n", display);
void wl_surface_set_data(struct wl_surface *surface, void *data);
void *wl_surface_get_data(struct wl_surface *surface);
+struct wl_surface_iterator;
+struct wl_surface_iterator *
+wl_surface_iterator_create(struct wl_display *display, uint32_t mask);
+int wl_surface_iterator_next(struct wl_surface_iterator *iterator,
+ struct wl_surface **surface);
+void wl_surface_iterator_destroy(struct wl_surface_iterator *iterator);
+
struct wl_compositor {
struct wl_compositor_interface *interface;
};
struct wl_surface *surface, struct wl_map *map);
};
-struct wl_compositor *wl_compositor_create(void);
+struct wl_compositor *wl_compositor_create(struct wl_display *display);
void wl_display_set_compositor(struct wl_display *display,
struct wl_compositor *compositor);