#include "compositor.h"
#include "gl-renderer.h"
#include "../shared/image-loader.h"
+#include "../shared/os-compatibility.h"
struct wayland_compositor {
struct weston_compositor base;
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_output *output;
+ struct wl_shm *shm;
struct {
int32_t x, y, width, height;
struct wayland_output {
struct weston_output base;
struct {
+ int draw_initial_frame;
struct wl_surface *surface;
struct wl_shell_surface *shell_surface;
struct wl_egl_window *egl_window;
};
static void
+buffer_release(void *data, struct wl_buffer *buffer)
+{
+ wl_buffer_destroy(buffer);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+ buffer_release
+};
+
+static void
+draw_initial_frame(struct wayland_output *output)
+{
+ struct wayland_compositor *c =
+ (struct wayland_compositor *) output->base.compositor;
+ struct wl_shm *shm = c->parent.shm;
+ struct wl_surface *surface = output->parent.surface;
+ struct wl_shm_pool *pool;
+ struct wl_buffer *buffer;
+
+ int width, height, stride;
+ int size;
+ int fd;
+ void *data;
+
+ width = output->mode.width + c->border.left + c->border.right;
+ height = output->mode.height + c->border.top + c->border.bottom;
+ stride = width * 4;
+ size = height * stride;
+
+ fd = os_create_anonymous_file(size);
+ if (fd < 0) {
+ perror("os_create_anonymous_file");
+ return;
+ }
+
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED) {
+ perror("mmap");
+ close(fd);
+ return;
+ }
+
+ pool = wl_shm_create_pool(shm, fd, size);
+
+ buffer = wl_shm_pool_create_buffer(pool, 0,
+ width, height,
+ stride,
+ WL_SHM_FORMAT_ARGB8888);
+ wl_buffer_add_listener(buffer, &buffer_listener, buffer);
+ wl_shm_pool_destroy(pool);
+ close(fd);
+
+ memset(data, 0, size);
+
+ wl_surface_attach(surface, buffer, 0, 0);
+
+ /* We only need to damage some part, as its only transparant
+ * pixels anyway. */
+ wl_surface_damage(surface, 0, 0, 1, 1);
+}
+
+static void
+wayland_output_start_repaint_loop(struct weston_output *output_base)
+{
+ struct wayland_output *output = (struct wayland_output *) output_base;
+ struct wl_callback *callback;
+
+ /* If this is the initial frame, we need to attach a buffer so that
+ * the compositor can map the surface and include it in its render
+ * loop. If the surface doesn't end up in the render loop, the frame
+ * callback won't be invoked. The buffer is transparent and of the
+ * same size as the future real output buffer. */
+ if (output->parent.draw_initial_frame) {
+ output->parent.draw_initial_frame = 0;
+
+ draw_initial_frame(output);
+ }
+
+ callback = wl_surface_frame(output->parent.surface);
+ wl_callback_add_listener(callback, &frame_listener, output);
+ wl_surface_commit(output->parent.surface);
+}
+
+static void
wayland_output_repaint(struct weston_output *output_base,
pixman_region32_t *damage)
{
output->parent.egl_window) < 0)
goto cleanup_window;
+ output->parent.draw_initial_frame = 1;
output->parent.shell_surface =
wl_shell_get_shell_surface(c->parent.shell,
output->parent.surface);
wl_shell_surface_set_toplevel(output->parent.shell_surface);
output->base.origin = output->base.current;
+ output->base.start_repaint_loop = wayland_output_start_repaint_loop;
output->base.repaint = wayland_output_repaint;
output->base.destroy = wayland_output_destroy;
output->base.assign_planes = NULL;
check_focus(input, x, y);
if (input->focus)
notify_motion(&input->base, time,
- x - wl_fixed_from_int(c->border.left),
- y - wl_fixed_from_int(c->border.top));
+ x - wl_fixed_from_int(c->border.left) -
+ input->base.seat.pointer->x,
+ y - wl_fixed_from_int(c->border.top) -
+ input->base.seat.pointer->y);
}
static void
&wl_shell_interface, 1);
} else if (strcmp(interface, "wl_seat") == 0) {
display_add_seat(c, name);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ c->parent.shm =
+ wl_registry_bind(registry, name, &wl_shm_interface, 1);
}
}
static void
wayland_destroy(struct weston_compositor *ec)
{
+ struct wayland_compositor *c = (struct wayland_compositor *) ec;
+
ec->renderer->destroy(ec);
weston_compositor_shutdown(ec);
+ if (c->parent.shm)
+ wl_shm_destroy(c->parent.shm);
+
free(ec);
}
static struct weston_compositor *
wayland_compositor_create(struct wl_display *display,
int width, int height, const char *display_name,
- int argc, char *argv[], const char *config_file)
+ int *argc, char *argv[], const char *config_file)
{
struct wayland_compositor *c;
struct wl_event_loop *loop;
}
WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int argc, char *argv[],
+backend_init(struct wl_display *display, int *argc, char *argv[],
const char *config_file)
{
int width = 1024, height = 640;