Add preliminary visual support.

Kristian Høgsberg 16 years ago
parent c8c5d5872d
commit de31d5ca6f
  1. 83
      egl-compositor.c
  2. 7
      flower.c
  3. 57
      wayland-client.c
  4. 12
      wayland-client.h
  5. 8
      wayland.c
  6. 3
      wayland.h
  7. 5
      window.c

@ -52,6 +52,10 @@
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
struct wl_visual {
struct wl_object base;
};
struct egl_input_device {
struct wl_object base;
int32_t x, y;
@ -66,6 +70,8 @@ struct egl_input_device {
struct egl_compositor {
struct wl_compositor base;
struct wl_visual argb_visual, premultiplied_argb_visual, rgb_visual;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
@ -91,6 +97,7 @@ struct egl_compositor {
struct egl_surface {
struct wl_surface base;
struct egl_compositor *compositor;
struct wl_visual *visual;
GLuint texture;
struct wl_map map;
EGLSurface surface;
@ -155,7 +162,8 @@ screenshooter_create(struct egl_compositor *ec)
};
static struct egl_surface *
egl_surface_create_from_cairo_surface(cairo_surface_t *surface,
egl_surface_create_from_cairo_surface(struct egl_compositor *ec,
cairo_surface_t *surface,
int x, int y, int width, int height)
{
struct egl_surface *es;
@ -178,11 +186,13 @@ egl_surface_create_from_cairo_surface(cairo_surface_t *surface,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, data);
es->compositor = ec;
es->map.x = x;
es->map.y = y;
es->map.width = width;
es->map.height = height;
es->surface = EGL_NO_SURFACE;
es->visual = &ec->premultiplied_argb_visual;
return es;
}
@ -213,7 +223,7 @@ pointer_path(cairo_t *cr, int x, int y)
}
static struct egl_surface *
pointer_create(int x, int y, int width, int height)
pointer_create(struct egl_compositor *ec, int x, int y, int width, int height)
{
struct egl_surface *es;
const int hotspot_x = 16, hotspot_y = 16;
@ -237,7 +247,8 @@ pointer_create(int x, int y, int width, int height)
cairo_fill(cr);
cairo_destroy(cr);
es = egl_surface_create_from_cairo_surface(surface,
es = egl_surface_create_from_cairo_surface(ec,
surface,
x - hotspot_x,
y - hotspot_y,
width, height);
@ -248,7 +259,8 @@ pointer_create(int x, int y, int width, int height)
}
static struct egl_surface *
background_create(const char *filename, int width, int height)
background_create(struct egl_compositor *ec,
const char *filename, int width, int height)
{
struct egl_surface *background;
GdkPixbuf *pixbuf;
@ -281,11 +293,13 @@ background_create(const char *filename, int width, int height)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pixbuf_width, pixbuf_height, 0,
GL_BGR, GL_UNSIGNED_BYTE, data);
background->compositor = ec;
background->map.x = 0;
background->map.y = 0;
background->map.width = width;
background->map.height = height;
background->surface = EGL_NO_SURFACE;
background->visual = &ec->rgb_visual;
return background;
}
@ -351,7 +365,7 @@ draw_button(cairo_t *cr, int x, int y, int width, int height, const char *text)
}
static struct egl_surface *
overlay_create(int x, int y, int width, int height)
overlay_create(struct egl_compositor *ec, int x, int y, int width, int height)
{
struct egl_surface *es;
cairo_surface_t *surface;
@ -378,7 +392,8 @@ overlay_create(int x, int y, int width, int height)
cairo_destroy(cr);
es = egl_surface_create_from_cairo_surface(surface, x, y, width, height);
es = egl_surface_create_from_cairo_surface(ec, surface,
x, y, width, height);
cairo_surface_destroy(surface);
@ -388,6 +403,7 @@ overlay_create(int x, int y, int width, int height)
static void
draw_surface(struct egl_surface *es)
{
struct egl_compositor *ec = es->compositor;
GLint vertices[12];
GLint tex_coords[12] = { 0, 0, 0, 1, 1, 0, 1, 1 };
GLuint indices[4] = { 0, 1, 2, 3 };
@ -408,13 +424,18 @@ draw_surface(struct egl_surface *es)
vertices[10] = es->map.y + es->map.height;
vertices[11] = 0;
glBindTexture(GL_TEXTURE_2D, es->texture);
glEnable(GL_TEXTURE_2D);
if (es->visual == &ec->argb_visual) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* Assume pre-multiplied alpha for now, this probably
* needs to be a wayland visual type of thing. */
} else if (es->visual == &ec->premultiplied_argb_visual) {
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
} else {
glDisable(GL_BLEND);
}
glBindTexture(GL_TEXTURE_2D, es->texture);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_INT, 0, vertices);
@ -549,7 +570,8 @@ surface_destroy(struct wl_client *client,
static void
surface_attach(struct wl_client *client,
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_object *visual)
{
struct egl_surface *es = (struct egl_surface *) surface;
struct egl_compositor *ec = es->compositor;
@ -561,6 +583,12 @@ surface_attach(struct wl_client *client,
es->height = height;
es->surface = eglCreateSurfaceForName(ec->display, ec->config,
name, width, height, stride, NULL);
if (visual == &ec->argb_visual.base)
es->visual = &ec->argb_visual;
else if (visual == &ec->premultiplied_argb_visual.base)
es->visual = &ec->premultiplied_argb_visual;
else
/* FIXME: Smack client with an exception event */;
glBindTexture(GL_TEXTURE_2D, es->texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -783,7 +811,8 @@ create_input_device(struct egl_compositor *ec, const char *glob)
wl_display_add_object(ec->wl_display, &device->base);
device->x = 100;
device->y = 100;
device->pointer_surface = pointer_create(device->x, device->y, 64, 64);
device->pointer_surface = pointer_create(ec,
device->x, device->y, 64, 64);
device->ec = ec;
dir = opendir(by_path_dir);
@ -947,6 +976,31 @@ pick_config(struct egl_compositor *ec)
return 0;
}
static const struct wl_interface visual_interface = {
"visual", 1,
};
static void
add_visuals(struct egl_compositor *ec)
{
ec->argb_visual.base.interface = &visual_interface;
ec->argb_visual.base.implementation = NULL;
wl_display_add_object(ec->wl_display, &ec->argb_visual.base);
wl_display_add_global(ec->wl_display, &ec->argb_visual.base);
ec->premultiplied_argb_visual.base.interface = &visual_interface;
ec->premultiplied_argb_visual.base.implementation = NULL;
wl_display_add_object(ec->wl_display,
&ec->premultiplied_argb_visual.base);
wl_display_add_global(ec->wl_display,
&ec->premultiplied_argb_visual.base);
ec->rgb_visual.base.interface = &visual_interface;
ec->rgb_visual.base.implementation = NULL;
wl_display_add_object(ec->wl_display, &ec->rgb_visual.base);
wl_display_add_global(ec->wl_display, &ec->rgb_visual.base);
}
static const char gem_device[] = "/dev/dri/card0";
static const char *macbook_air_default_input_device[] = {
@ -1025,15 +1079,16 @@ egl_compositor_create(struct wl_display *display)
glClearColor(0, 0, 0.2, 1);
wl_display_set_compositor(display, &ec->base, &compositor_interface);
add_visuals(ec);
wl_list_init(&ec->input_device_list);
for (i = 0; option_input_devices[i]; i++)
create_input_device(ec, option_input_devices[i]);
wl_list_init(&ec->surface_list);
ec->background = background_create(option_background,
ec->background = background_create(ec, option_background,
ec->width, ec->height);
ec->overlay = overlay_create(0, ec->height, ec->width, 200);
ec->overlay = overlay_create(ec, 0, ec->height, ec->width, 200);
ec->overlay_y = ec->height;
ec->overlay_target = ec->height;
ec->overlay_previous = ec->height;

@ -133,6 +133,7 @@ event_handler(struct wl_display *display,
int main(int argc, char *argv[])
{
struct wl_display *display;
struct wl_visual *visual;
int fd;
cairo_surface_t *s;
struct timespec ts;
@ -172,8 +173,10 @@ int main(int argc, char *argv[])
s = draw_stuff(flower.width, flower.height);
buffer = buffer_create_from_cairo_surface(fd, s);
wl_surface_attach(flower.surface, buffer->name, flower.width, flower.height,
buffer->stride);
visual = wl_display_get_premultiplied_argb_visual(display);
wl_surface_attach(flower.surface,
buffer->name, flower.width, flower.height,
buffer->stride, visual);
wl_display_set_event_handler(display, event_handler, &flower);
move_flower(&flower);

@ -56,6 +56,7 @@ struct wl_display {
uint32_t id;
uint32_t mask;
struct wl_list global_list;
struct wl_list visual_list;
wl_display_update_func_t update;
void *update_data;
@ -72,6 +73,11 @@ struct wl_surface {
struct wl_proxy proxy;
};
struct wl_visual {
struct wl_proxy proxy;
struct wl_list link;
};
static int
connection_update(struct wl_connection *connection,
uint32_t mask, void *data)
@ -86,6 +92,45 @@ connection_update(struct wl_connection *connection,
return 0;
}
static void
add_visual(struct wl_display *display, struct wl_global *global)
{
struct wl_visual *visual;
visual = malloc(sizeof *visual);
if (visual == NULL)
return;
visual->proxy.display = display;
visual->proxy.id = global->id;
wl_list_insert(display->visual_list.prev, &visual->link);
printf("added visual, id %d\n", global->id);
}
WL_EXPORT struct wl_visual *
wl_display_get_argb_visual(struct wl_display *display)
{
return container_of(display->visual_list.next,
struct wl_visual, link);
}
WL_EXPORT struct wl_visual *
wl_display_get_premultiplied_argb_visual(struct wl_display *display)
{
return container_of(display->visual_list.next->next,
struct wl_visual, link);
}
WL_EXPORT struct wl_visual *
wl_display_get_rgb_visual(struct wl_display *display)
{
/* FIXME: Where's cddar when you need it... */
return container_of(display->visual_list.next->next->next,
struct wl_visual, link);
}
WL_EXPORT struct wl_display *
wl_display_create(const char *name, size_t name_size)
{
@ -125,6 +170,7 @@ wl_display_create(const char *name, size_t name_size)
read(display->fd, &count, sizeof count);
wl_list_init(&display->global_list);
wl_list_init(&display->visual_list);
for (i = 0; i < count; i++) {
/* FIXME: actually discover advertised objects here. */
read(display->fd, &id, sizeof id);
@ -140,6 +186,9 @@ wl_display_create(const char *name, size_t name_size)
memcpy(global->interface, buffer, length);
global->interface[length] = '\0';
wl_list_insert(display->global_list.prev, &global->link);
if (strcmp(global->interface, "visual") == 0)
add_visual(display, global);
}
display->proxy.display = display;
@ -327,9 +376,10 @@ wl_surface_destroy(struct wl_surface *surface)
WL_EXPORT void
wl_surface_attach(struct wl_surface *surface, uint32_t name,
int32_t width, int32_t height, uint32_t stride)
int32_t width, int32_t height, uint32_t stride,
struct wl_visual *visual)
{
uint32_t request[6];
uint32_t request[7];
request[0] = surface->proxy.id;
request[1] = WL_SURFACE_ATTACH | ((sizeof request) << 16);
@ -337,6 +387,9 @@ wl_surface_attach(struct wl_surface *surface, uint32_t name,
request[3] = width;
request[4] = height;
request[5] = stride;
request[6] = visual->proxy.id;
printf("attach, visual id is %d\n", visual->proxy.id);
wl_connection_write(surface->proxy.display->connection,
request, sizeof request);

@ -32,6 +32,7 @@
struct wl_display;
struct wl_surface;
struct wl_visual;
#define WL_DISPLAY_READABLE 0x01
#define WL_DISPLAY_WRITABLE 0x02
@ -58,6 +59,12 @@ void wl_display_set_event_handler(struct wl_display *display,
struct wl_compositor *
wl_display_get_compositor(struct wl_display *display);
struct wl_visual *
wl_display_get_argb_visual(struct wl_display *display);
struct wl_visual *
wl_display_get_premultiplied_argb_visual(struct wl_display *display);
struct wl_visual *
wl_display_get_rgb_visual(struct wl_display *display);
struct wl_surface *
wl_compositor_create_surface(struct wl_compositor *compositor);
@ -65,8 +72,9 @@ void
wl_compositor_commit(struct wl_compositor *compositor, uint32_t key);
void wl_surface_destroy(struct wl_surface *surface);
void wl_surface_attach(struct wl_surface *surface,
uint32_t name, int32_t width, int32_t height, uint32_t stride);
void wl_surface_attach(struct wl_surface *surface, uint32_t name,
int32_t width, int32_t height, uint32_t stride,
struct wl_visual *visual);
void wl_surface_map(struct wl_surface *surface,
int32_t x, int32_t y, int32_t width, int32_t height);
void wl_surface_copy(struct wl_surface *surface, int32_t dst_x, int32_t dst_y,

@ -127,7 +127,7 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target,
ffi_type *types[20];
ffi_cif cif;
uint32_t *p, result;
int i, j, count;
int i, count;
union {
uint32_t uint32;
const char *string;
@ -161,7 +161,6 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target,
wl_connection_copy(client->connection, data, size);
p = &data[2];
j = 0;
for (i = 2; i < count; i++) {
switch (method->signature[i - 2]) {
case 'u':
@ -180,11 +179,8 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target,
object = wl_hash_lookup(client->display->objects, *p);
if (object == NULL)
printf("unknown object (%d)\n", *p);
if (object->interface != method->types[j])
printf("wrong object type\n");
values[i].object = object;
p++;
j++;
break;
case 'n':
types[i] = &ffi_type_uint32;
@ -369,7 +365,7 @@ wl_client_destroy(struct wl_client *client)
static const struct wl_method surface_methods[] = {
{ "destroy", "" },
{ "attach", "uuuu" },
{ "attach", "uuuuo" },
{ "map", "iiii" },
{ "copy", "iiuuiiii" },
{ "damage", "iiii" }

@ -142,7 +142,8 @@ struct wl_surface_interface {
struct wl_surface *surface);
void (*attach)(struct wl_client *client,
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_object *visual);
void (*map)(struct wl_client *client,
struct wl_surface *surface,
int32_t x, int32_t y, int32_t width, int32_t height);

@ -84,6 +84,7 @@ window_draw(struct window *window)
int border = 2, radius = 5;
cairo_text_extents_t extents;
cairo_pattern_t *gradient, *outline, *bright, *dim;
struct wl_visual *visual;
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
window->width + window->margin * 2,
@ -156,11 +157,13 @@ window_draw(struct window *window)
window->buffer = buffer_create_from_cairo_surface(window->fd, surface);
cairo_surface_destroy(surface);
visual = wl_display_get_premultiplied_argb_visual(window->display);
wl_surface_attach(window->surface,
window->buffer->name,
window->buffer->width,
window->buffer->height,
window->buffer->stride);
window->buffer->stride,
visual);
wl_surface_map(window->surface,
window->x - window->margin,

Loading…
Cancel
Save