static struct wl_output *output;
static struct wl_shm *shm;
-static struct wl_visual *visual;
static struct screenshooter *screenshooter;
static int output_width, output_height;
handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data)
{
- static int visual_count;
-
if (strcmp(interface, "wl_output") == 0) {
output = wl_display_bind(display, id, &wl_output_interface);
wl_output_add_listener(output, &output_listener, NULL);
} else if (strcmp(interface, "wl_shm") == 0) {
shm = wl_display_bind(display, id, &wl_shm_interface);
- } else if (strcmp(interface, "wl_visual") == 0) {
- if (visual_count++ == 1)
- visual = wl_display_bind(display, id,
- &wl_visual_interface);
} else if (strcmp(interface, "screenshooter") == 0) {
screenshooter = wl_display_bind(display, id, &screenshooter_interface);
}
return NULL;
}
- buffer = wl_shm_create_buffer(shm, fd, width, height, stride, visual);
+ buffer = wl_shm_create_buffer(shm, fd, width, height, stride,
+ WL_SHM_FORMAT_XRGB32);
close(fd);
};
static const EGLint config_attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
struct display *display = window->display;
struct wl_visual *visual;
EGLBoolean ret;
+ static const EGLint surface_attribs[] = {
+ EGL_ALPHA_FORMAT, EGL_ALPHA_FORMAT_PRE,
+ EGL_NONE
+ };
- if (!display->premultiplied_argb_visual)
- wl_display_roundtrip(display->display);
- if (!display->premultiplied_argb_visual) {
- fprintf(stderr, "premultiplied argb visual missing\n");
- exit(1);
- }
-
window->surface = wl_compositor_create_surface(display->compositor);
visual = display->premultiplied_argb_visual;
window->native =
wl_egl_window_create(window->surface,
window->geometry.width,
- window->geometry.height,
- visual);
+ window->geometry.height);
window->egl_surface =
eglCreateWindowSurface(display->egl.dpy,
display->egl.conf,
window->native,
- NULL);
+ surface_attribs);
wl_shell_set_toplevel(display->shell, window->surface);
};
static void
-compositor_handle_visual(void *data,
- struct wl_compositor *compositor,
- uint32_t id, uint32_t token)
-{
- struct display *d = data;
-
- switch (token) {
- case WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32:
- d->premultiplied_argb_visual =
- wl_display_bind(d->display, id, &wl_visual_interface);
- break;
- }
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- compositor_handle_visual,
-};
-
-static void
display_handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data)
{
if (strcmp(interface, "wl_compositor") == 0) {
d->compositor =
wl_display_bind(display, id, &wl_compositor_interface);
- wl_compositor_add_listener(d->compositor,
- &compositor_listener, d);
} else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_display_bind(display, id, &wl_shell_interface);
}
struct display {
struct wl_display *display;
- struct wl_visual *xrgb_visual;
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_shm *shm;
static struct wl_buffer *
create_shm_buffer(struct display *display,
- int width, int height, struct wl_visual *visual,
- void **data_out)
+ int width, int height, uint32_t format, void **data_out)
{
char filename[] = "/tmp/wayland-shm-XXXXXX";
struct wl_buffer *buffer;
}
buffer = wl_shm_create_buffer(display->shm, fd,
- width, height, stride, visual);
+ width, height, stride, format);
close(fd);
create_window(struct display *display, int width, int height)
{
struct window *window;
- struct wl_visual *visual;
window = malloc(sizeof *window);
window->display = display;
window->width = width;
window->height = height;
window->surface = wl_compositor_create_surface(display->compositor);
- visual = display->xrgb_visual;
window->buffer = create_shm_buffer(display,
width, height,
- visual, &window->data);
+ WL_SHM_FORMAT_XRGB32,
+ &window->data);
wl_shell_set_toplevel(display->shell, window->surface);
};
static void
-compositor_handle_visual(void *data,
- struct wl_compositor *compositor,
- uint32_t id, uint32_t token)
-{
- struct display *d = data;
-
- switch (token) {
- case WL_COMPOSITOR_VISUAL_XRGB32:
- d->xrgb_visual = wl_display_bind(d->display,
- id, &wl_visual_interface);
- break;
- }
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- compositor_handle_visual,
-};
-
-static void
display_handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data)
{
if (strcmp(interface, "wl_compositor") == 0) {
d->compositor =
wl_display_bind(display, id, &wl_compositor_interface);
- wl_compositor_add_listener(d->compositor,
- &compositor_listener, d);
} else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_display_bind(display, id, &wl_shell_interface);
} else if (strcmp(interface, "wl_shm") == 0) {
wl_display_get_fd(display->display, event_mask_update, display);
- while (!display->xrgb_visual)
- wl_display_roundtrip(display->display);
-
return display;
}
struct wl_shell *shell;
struct wl_shm *shm;
struct wl_output *output;
- struct wl_visual *argb_visual, *premultiplied_argb_visual, *rgb_visual;
struct rectangle screen_allocation;
int authenticated;
EGLDisplay dpy;
- EGLConfig conf;
+ EGLConfig rgb_config;
+ EGLConfig premul_argb_config;
EGLContext ctx;
cairo_device_t *device;
int fd;
static cairo_surface_t *
display_create_egl_window_surface(struct display *display,
struct wl_surface *surface,
- struct wl_visual *visual,
+ uint32_t flags,
struct rectangle *rectangle)
{
cairo_surface_t *cairo_surface;
struct egl_window_surface_data *data;
+ EGLConfig config;
+ const EGLint *attribs;
+ static const EGLint premul_attribs[] = {
+ EGL_ALPHA_FORMAT, EGL_ALPHA_FORMAT_PRE,
+ EGL_NONE
+ };
+
data = malloc(sizeof *data);
if (data == NULL)
return NULL;
data->display = display;
data->surface = surface;
+ if (flags & SURFACE_OPAQUE) {
+ config = display->rgb_config;
+ attribps = NULL;
+ } else {
+ config = display->premultiplied_argb_config;
+ attribs = premul_attribs;
+ }
+
data->window = wl_egl_window_create(surface,
rectangle->width,
- rectangle->height,
- visual);
+ rectangle->height);
- data->surf = eglCreateWindowSurface(display->dpy, display->conf,
- data->window, NULL);
+ data->surf = eglCreateWindowSurface(display->dpy, config,
+ data->window, attribs);
cairo_surface = cairo_gl_surface_create_for_egl(display->device,
data->surf,
static cairo_surface_t *
display_create_egl_image_surface(struct display *display,
- struct wl_visual *visual,
+ uint32_t flags,
struct rectangle *rectangle)
{
struct egl_image_surface_data *data;
EGLDisplay dpy = display->dpy;
cairo_surface_t *surface;
+ EGLConfig config;
data = malloc(sizeof *data);
if (data == NULL)
data->display = display;
data->pixmap = wl_egl_pixmap_create(rectangle->width,
- rectangle->height,
- visual, 0);
+ rectangle->height, 0);
if (data->pixmap == NULL) {
free(data);
return NULL;
}
+ if (flags & SURFACE_OPAQUE)
+ config = display->rgb_config;
+ else
+ config = display->premultiplied_argb_config;
+
data->image = display->create_image(dpy, NULL,
EGL_NATIVE_PIXMAP_KHR,
(EGLClientBuffer) data->pixmap,
int stride, i;
unsigned char *pixels, *p, *end;
struct egl_image_surface_data *data;
- struct wl_visual *visual;
pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
rect->width, rect->height,
struct rectangle *rectangle, uint32_t flags)
{
struct shm_surface_data *data;
- struct wl_visual *visual;
+ uint32_t format;
cairo_surface_t *surface;
int stride, fd;
char filename[] = "/tmp/wayland-shm-XXXXXX";
data, shm_surface_data_destroy);
if (flags & SURFACE_OPAQUE)
- visual = display->rgb_visual;
+ format = WL_SHM_FORMAT_XRGB32;
else
- visual = display->premultiplied_argb_visual;
+ format = WL_SHM_FORMAT_PREMULTIPLIED_ARGB32;
data->data.buffer = wl_shm_create_buffer(display->shm,
fd,
rectangle->width,
rectangle->height,
- stride, visual);
+ stride, format);
close(fd);
struct rectangle *rectangle,
uint32_t flags)
{
- struct wl_visual *visual;
-
- if (flags & SURFACE_OPAQUE)
- visual = display->rgb_visual;
- else
- visual = display->premultiplied_argb_visual;
-
if (check_size(rectangle) < 0)
return NULL;
#ifdef HAVE_CAIRO_EGL
if (surface)
return display_create_egl_window_surface(display,
surface,
- visual,
+ flags,
rectangle);
else
return display_create_egl_image_surface(display,
- visual,
+ flags,
rectangle);
}
#endif
window->buffer_type = type;
}
-static void
-compositor_handle_visual(void *data,
- struct wl_compositor *compositor,
- uint32_t id, uint32_t token)
-{
- struct display *d = data;
-
- switch (token) {
- case WL_COMPOSITOR_VISUAL_ARGB32:
- d->argb_visual =
- wl_display_bind(d->display, id, &wl_visual_interface);
- break;
- case WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32:
- d->premultiplied_argb_visual =
- wl_display_bind(d->display, id, &wl_visual_interface);
- break;
- case WL_COMPOSITOR_VISUAL_XRGB32:
- d->rgb_visual =
- wl_display_bind(d->display, id, &wl_visual_interface);
- break;
- }
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- compositor_handle_visual,
-};
static void
display_handle_geometry(void *data,
if (strcmp(interface, "wl_compositor") == 0) {
d->compositor =
wl_display_bind(display, id, &wl_compositor_interface);
- wl_compositor_add_listener(d->compositor,
- &compositor_listener, d);
} else if (strcmp(interface, "wl_output") == 0) {
d->output = wl_display_bind(display, id, &wl_output_interface);
wl_output_add_listener(d->output, &output_listener, d);
{
EGLint major, minor;
EGLint n;
- static const EGLint cfg_attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
+
+ static const EGLint premul_argb_cfg_attribs[] = {
+ EGL_SURFACE_TYPE,
+ EGL_WINDOW_BIT | EGL_PIXMAP_BIT |
+ EGL_VG_ALPHA_FORMAT_PRE_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_NONE
};
+ static const EGLint rgb_cfg_attribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 1,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+ EGL_NONE
+ };
+
setenv("EGL_PLATFORM", "wayland", 1);
d->dpy = eglGetDisplay(d->display);
if (!eglInitialize(d->dpy, &major, &minor)) {
return -1;
}
- if (!eglChooseConfig(d->dpy, cfg_attribs, &d->conf, 1, &n) || n != 1) {
- fprintf(stderr, "failed to choose config\n");
+ if (!eglChooseConfig(d->dpy, premul_argb_cfg_attribs,
+ &d->premul_argb_config, 1, &n) || n != 1) {
+ fprintf(stderr, "failed to choose premul argb config\n");
+ return -1;
+ }
+
+ if (!eglChooseConfig(d->dpy, rgb_cfg_attribs,
+ &d->rgb_config, 1, &n) || n != 1) {
+ fprintf(stderr, "failed to choose rgb config\n");
return -1;
}
- d->ctx = eglCreateContext(d->dpy, d->conf, EGL_NO_CONTEXT, NULL);
+ d->ctx = eglCreateContext(d->dpy, d->rgb_config, EGL_NO_CONTEXT, NULL);
if (d->ctx == NULL) {
fprintf(stderr, "failed to create context\n");
return -1;
d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
- if (!d->premultiplied_argb_visual || !d->rgb_visual) {
- wl_display_roundtrip(d->display);
- if (!d->premultiplied_argb_visual || !d->rgb_visual) {
- fprintf(stderr, "failed to retreive visuals\n");
- return NULL;
- }
- }
-
create_pointer_surfaces(d);
display_render_frame(d);
EGLConfig
display_get_egl_config(struct display *d)
{
- return d->conf;
+ return d->rgb_config;
}
struct wl_shell *
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_output *output;
- struct wl_visual *visual;
struct {
int32_t x, y, width, height;
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
wl_surface_set_user_data(output->parent.surface, output);
output->parent.egl_window =
- wl_egl_window_create(output->parent.surface,
- width, height, c->parent.visual);
+ wl_egl_window_create(output->parent.surface, width, height);
if (!output->parent.egl_window) {
fprintf(stderr, "failure to create wl_egl_window\n");
goto cleanup_output;
}
static void
-compositor_handle_visual(void *data,
- struct wl_compositor *compositor,
- uint32_t id, uint32_t token)
-{
- struct wayland_compositor *c = data;
-
- switch (token) {
- case WL_COMPOSITOR_VISUAL_ARGB32:
- c->parent.visual = wl_display_bind(c->parent.display,
- id, &wl_visual_interface);
- break;
- }
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- compositor_handle_visual,
-};
-
-static void
display_handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data)
{
if (strcmp(interface, "wl_compositor") == 0) {
c->parent.compositor =
wl_display_bind(display, id, &wl_compositor_interface);
- wl_compositor_add_listener(c->parent.compositor,
- &compositor_listener, c);
} else if (strcmp(interface, "wl_output") == 0) {
c->parent.output =
wl_display_bind(display, id, &wl_output_interface);
surface->surface.resource.client = NULL;
surface->compositor = compositor;
- surface->visual = NULL;
+ surface->visual = WLSC_NONE_VISUAL;
surface->image = EGL_NO_IMAGE_KHR;
surface->saved_texture = 0;
surface->x = x;
wlsc_surface_configure(struct wlsc_surface *surface,
int x, int y, int width, int height)
{
- struct wlsc_compositor *compositor = surface->compositor;
-
wlsc_surface_damage_below(surface);
surface->x = x;
wlsc_surface_damage(surface);
pixman_region32_fini(&surface->opaque);
- if (surface->visual == &compositor->compositor.rgb_visual)
+ if (surface->visual == WLSC_RGB_VISUAL)
pixman_region32_init_rect(&surface->opaque,
surface->x, surface->y,
surface->width, surface->height);
es->pitch, buffer->height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
wl_shm_buffer_get_data(buffer));
- es->visual = buffer->visual;
+
+ switch (wl_shm_buffer_get_format(buffer)) {
+ case WL_SHM_FORMAT_ARGB32:
+ es->visual = WLSC_ARGB_VISUAL;
+ break;
+ case WL_SHM_FORMAT_PREMULTIPLIED_ARGB32:
+ es->visual = WLSC_PREMUL_ARGB_VISUAL;
+ break;
+ case WL_SHM_FORMAT_XRGB32:
+ es->visual = WLSC_RGB_VISUAL;
+ break;
+ }
surfaces_attached_to = buffer->user_data;
buffer, NULL);
ec->image_target_texture_2d(GL_TEXTURE_2D, es->image);
- es->visual = buffer->visual;
+
+ /* FIXME: we need to get the visual from the wl_buffer */
+ es->visual = WLSC_PREMUL_ARGB_VISUAL;
es->pitch = es->width;
}
}
return NULL;
}
- sprite->visual = &ec->compositor.premultiplied_argb_visual;
+ sprite->visual = WLSC_PREMUL_ARGB_VISUAL;
sprite->width = width;
sprite->height = height;
sprite->image = EGL_NO_IMAGE_KHR;
if (!pixman_region32_not_empty(&repaint))
return;
- if (es->visual == &ec->compositor.argb_visual) {
+ switch (es->visual) {
+ case WLSC_ARGB_VISUAL:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- } else if (es->visual == &ec->compositor.premultiplied_argb_visual) {
+ break;
+ case WLSC_PREMUL_ARGB_VISUAL:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- } else {
+ break;
+ case WLSC_RGB_VISUAL:
glDisable(GL_BLEND);
+ break;
+ default:
+ fprintf(stderr, "bogus visual\n");
+ break;
}
if (es->transform == NULL) {
surface.transform = NULL;
if (tint <= 1.0)
- surface.visual =
- &compositor->compositor.premultiplied_argb_visual;
+ surface.visual = WLSC_PREMUL_ARGB_VISUAL;
else
- surface.visual = &compositor->compositor.rgb_visual;
+ surface.visual = WLSC_RGB_VISUAL;
glUseProgram(compositor->solid_shader.program);
glUniformMatrix4fv(compositor->solid_shader.proj_uniform,
es = container_of(ec->surface_list.next, struct wlsc_surface, link);
- if (es->visual == &ec->compositor.rgb_visual &&
+ if (es->visual == WLSC_RGB_VISUAL &&
output->prepare_scanout_surface(output, es) == 0) {
/* We're drawing nothing now,
* draw the damaged regions later. */
wl_list_insert(es->buffer->resource.destroy_listener_list.prev,
&es->buffer_destroy_listener.link);
- if (es->visual == NULL)
+ if (es->visual == WLSC_NONE_VISUAL)
wl_list_insert(&es->compositor->surface_list, &es->link);
- es->visual = buffer->visual;
if (x != 0 || y != 0 ||
es->width != buffer->width || es->height != buffer->height)
wlsc_surface_configure(es, es->x + x, es->y + y,
struct wl_selection *selection;
};
+enum wlsc_visual {
+ WLSC_NONE_VISUAL,
+ WLSC_ARGB_VISUAL,
+ WLSC_PREMUL_ARGB_VISUAL,
+ WLSC_RGB_VISUAL
+};
+
struct wlsc_sprite {
GLuint texture;
EGLImageKHR image;
- struct wl_visual *visual;
+ uint32_t visual;
int width;
int height;
};
struct wl_list link;
struct wl_list buffer_link;
struct wlsc_transform *transform;
- struct wl_visual *visual;
+ uint32_t visual;
struct wlsc_output *output;
enum wlsc_surface_map_type map_type;
struct wlsc_output *fullscreen_output;