uint32_t event_mask;
} parent;
+ struct {
+ int32_t top, bottom, left, right;
+ GLuint texture;
+ int32_t width, height;
+ } border;
+
struct wl_list input_list;
};
struct wl_list link;
};
+
+static int
+texture_border(struct wayland_output *output)
+{
+ struct wayland_compositor *c =
+ (struct wayland_compositor *) output->base.compositor;
+ GLfloat *d;
+ unsigned int *p;
+ int i, j, k, n;
+ GLfloat x[4], y[4], u[4], v[4];
+
+ x[0] = -c->border.left;
+ x[1] = 0;
+ x[2] = output->base.current->width;
+ x[3] = output->base.current->width + c->border.right;
+
+ y[0] = -c->border.top;
+ y[1] = 0;
+ y[2] = output->base.current->height;
+ y[3] = output->base.current->height + c->border.bottom;
+
+ u[0] = 0.0;
+ u[1] = (GLfloat) c->border.left / c->border.width;
+ u[2] = (GLfloat) (c->border.width - c->border.right) / c->border.width;
+ u[3] = 1.0;
+
+ v[0] = 0.0;
+ v[1] = (GLfloat) c->border.top / c->border.height;
+ v[2] = (GLfloat) (c->border.height - c->border.bottom) / c->border.height;
+ v[3] = 1.0;
+
+ n = 8;
+ d = wl_array_add(&c->base.vertices, n * 16 * sizeof *d);
+ p = wl_array_add(&c->base.indices, n * 6 * sizeof *p);
+
+ k = 0;
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++) {
+
+ if (i == 1 && j == 1)
+ continue;
+
+ d[ 0] = x[i];
+ d[ 1] = y[j];
+ d[ 2] = u[i];
+ d[ 3] = v[j];
+
+ d[ 4] = x[i];
+ d[ 5] = y[j + 1];
+ d[ 6] = u[i];
+ d[ 7] = v[j + 1];
+
+ d[ 8] = x[i + 1];
+ d[ 9] = y[j];
+ d[10] = u[i + 1];
+ d[11] = v[j];
+
+ d[12] = x[i + 1];
+ d[13] = y[j + 1];
+ d[14] = u[i + 1];
+ d[15] = v[j + 1];
+
+ p[0] = k + 0;
+ p[1] = k + 1;
+ p[2] = k + 2;
+ p[3] = k + 2;
+ p[4] = k + 1;
+ p[5] = k + 3;
+
+ d += 16;
+ p += 6;
+ k += 4;
+ }
+
+ return k / 4;
+}
+
+static void
+draw_border(struct wayland_output *output)
+{
+ struct wayland_compositor *c =
+ (struct wayland_compositor *) output->base.compositor;
+ struct weston_shader *shader = &c->base.texture_shader;
+ GLfloat *v;
+ int n;
+
+ glDisable(GL_BLEND);
+ glUseProgram(shader->program);
+ c->base.current_shader = shader;
+
+ glUniformMatrix4fv(shader->proj_uniform,
+ 1, GL_FALSE, output->base.matrix.d);
+
+ glUniform1i(shader->tex_uniform, 0);
+ glUniform1f(shader->alpha_uniform, 1);
+ glUniform1f(shader->texwidth_uniform, 1);
+
+ n = texture_border(output);
+
+ glBindTexture(GL_TEXTURE_2D, c->border.texture);
+
+ v = c->base.vertices.data;
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[2]);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glDrawElements(GL_TRIANGLES, n * 6,
+ GL_UNSIGNED_INT, c->base.indices.data);
+
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(0);
+
+ c->base.vertices.size = 0;
+ c->base.indices.size = 0;
+}
+
+static void
+create_border(struct wayland_compositor *c)
+{
+ pixman_image_t *image;
+
+ image = load_image(DATADIR "/weston/border.png");
+ if (!image) {
+ fprintf(stderr, "could'nt load border image\n");
+ return;
+ }
+
+ c->border.width = pixman_image_get_width(image);
+ c->border.height = pixman_image_get_height(image);
+
+ glGenTextures(1, &c->border.texture);
+ glBindTexture(GL_TEXTURE_2D, c->border.texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+ c->border.width,
+ c->border.height,
+ 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
+ pixman_image_get_data(image));
+
+ c->border.top = 25;
+ c->border.bottom = 50;
+ c->border.left = 25;
+ c->border.right = 25;
+
+ pixman_image_unref(image);
+}
+
static int
wayland_input_create(struct wayland_compositor *c)
{
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
- EGL_ALPHA_SIZE, 0,
- EGL_DEPTH_SIZE, 1,
+ EGL_ALPHA_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
return 0;
}
-static int
-wayland_output_prepare_render(struct weston_output *output_base)
-{
- struct wayland_output *output = (struct wayland_output *) output_base;
- struct weston_compositor *ec = output->base.compositor;
-
- if (!eglMakeCurrent(ec->display, output->egl_surface,
- output->egl_surface, ec->context)) {
- fprintf(stderr, "failed to make current\n");
- return -1;
- }
-
- return 0;
-}
-
static void
-frame_done(void *data, struct wl_callback *wl_callback, uint32_t time)
+frame_done(void *data, struct wl_callback *callback, uint32_t time)
{
struct weston_output *output = data;
+ wl_callback_destroy(callback);
weston_output_finish_frame(output, time);
}
frame_done
};
-static int
-wayland_output_present(struct weston_output *output_base)
+static void
+wayland_output_repaint(struct weston_output *output_base,
+ pixman_region32_t *damage)
{
struct wayland_output *output = (struct wayland_output *) output_base;
- struct wayland_compositor *c =
+ struct wayland_compositor *compositor =
(struct wayland_compositor *) output->base.compositor;
struct wl_callback *callback;
+ struct weston_surface *surface;
- if (wayland_output_prepare_render(&output->base))
- return -1;
+ if (!eglMakeCurrent(compositor->base.display, output->egl_surface,
+ output->egl_surface, compositor->base.context)) {
+ fprintf(stderr, "failed to make current\n");
+ return;
+ }
- eglSwapBuffers(c->base.display, output->egl_surface);
- callback = wl_surface_frame(output->parent.surface);
- wl_callback_add_listener(callback, &frame_listener, output);
+ wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
+ weston_surface_draw(surface, &output->base, damage);
- return 0;
-}
+ draw_border(output);
-static int
-wayland_output_prepare_scanout_surface(struct weston_output *output_base,
- struct weston_surface *es)
-{
- return -1;
-}
+ eglSwapBuffers(compositor->base.display, output->egl_surface);
+ callback = wl_surface_frame(output->parent.surface);
+ wl_callback_add_listener(callback, &frame_listener, output);
-static int
-wayland_output_set_cursor(struct weston_output *output_base,
- struct weston_input_device *input)
-{
- return -1;
+ return;
}
static void
weston_output_init(&output->base, &c->base, 0, 0, width, height,
WL_OUTPUT_FLIPPED);
+ output->base.border.top = c->border.top;
+ output->base.border.bottom = c->border.bottom;
+ output->base.border.left = c->border.left;
+ output->base.border.right = c->border.right;
+
+ weston_output_move(&output->base, 0, 0);
+
output->parent.surface =
wl_compositor_create_surface(c->parent.compositor);
wl_surface_set_user_data(output->parent.surface, output);
output->parent.egl_window =
- wl_egl_window_create(output->parent.surface, width, height);
+ wl_egl_window_create(output->parent.surface,
+ width + c->border.left + c->border.right,
+ height + c->border.top + c->border.bottom);
if (!output->parent.egl_window) {
fprintf(stderr, "failure to create wl_egl_window\n");
goto cleanup_output;
/* FIXME: add shell_surface listener for resizing */
wl_shell_surface_set_toplevel(output->parent.shell_surface);
- glClearColor(0, 0, 0, 0.5);
-
- output->base.prepare_render = wayland_output_prepare_render;
- output->base.present = wayland_output_present;
- output->base.prepare_scanout_surface =
- wayland_output_prepare_scanout_surface;
- output->base.set_hardware_cursor = wayland_output_set_cursor;
+ output->base.repaint = wayland_output_repaint;
output->base.destroy = wayland_output_destroy;
+ output->base.assign_planes = NULL;
+ output->base.set_backlight = NULL;
+ output->base.set_dpms = NULL;
wl_list_insert(c->base.output_list.prev, &output->base.link);
/* parent input interface */
static void
input_handle_motion(void *data, struct wl_input_device *input_device,
- uint32_t time,
- int32_t x, int32_t y, int32_t sx, int32_t sy)
+ uint32_t time, int32_t sx, int32_t sy)
{
struct wayland_input *input = data;
struct wayland_compositor *c = input->compositor;
- notify_motion(c->base.input_device, time, sx, sy);
+ notify_motion(c->base.input_device, time,
+ sx - c->border.left, sy - c->border.top);
}
static void
}
static void
+input_handle_axis(void *data, struct wl_input_device *input_device,
+ uint32_t time, uint32_t axis, int32_t value)
+{
+ struct wayland_input *input = data;
+ struct wayland_compositor *c = input->compositor;
+
+ notify_axis(c->base.input_device, time, axis, value);
+}
+
+static void
input_handle_key(void *data, struct wl_input_device *input_device,
uint32_t time, uint32_t key, uint32_t state)
{
}
static void
-input_handle_pointer_focus(void *data,
- struct wl_input_device *input_device,
- uint32_t time, struct wl_surface *surface,
- int32_t x, int32_t y, int32_t sx, int32_t sy)
+input_handle_pointer_enter(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, struct wl_surface *surface,
+ int32_t sx, int32_t sy)
{
struct wayland_input *input = data;
struct wayland_output *output;
struct wayland_compositor *c = input->compositor;
- if (surface) {
- output = wl_surface_get_user_data(surface);
- notify_pointer_focus(c->base.input_device,
- time, &output->base, sx, sy);
- } else {
- notify_pointer_focus(c->base.input_device, time, NULL, 0, 0);
- }
+ output = wl_surface_get_user_data(surface);
+ notify_pointer_focus(c->base.input_device,
+ time, &output->base, sx, sy);
+ wl_input_device_attach(input->input_device, time, NULL, 0, 0);
}
static void
-input_handle_keyboard_focus(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- struct wl_surface *surface,
- struct wl_array *keys)
+input_handle_pointer_leave(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time, struct wl_surface *surface)
+{
+ struct wayland_input *input = data;
+ struct wayland_compositor *c = input->compositor;
+
+ notify_pointer_focus(c->base.input_device, time, NULL, 0, 0);
+}
+
+static void
+input_handle_keyboard_enter(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys)
{
struct wayland_input *input = data;
struct wayland_compositor *c = input->compositor;
struct wayland_output *output;
- if (surface) {
- output = wl_surface_get_user_data(surface);
- notify_keyboard_focus(c->base.input_device,
- time, &output->base, keys);
- } else {
- notify_keyboard_focus(c->base.input_device, time, NULL, NULL);
- }
+ output = wl_surface_get_user_data(surface);
+ notify_keyboard_focus(c->base.input_device, time, &output->base, keys);
+}
+
+static void
+input_handle_keyboard_leave(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface)
+{
+ struct wayland_input *input = data;
+ struct wayland_compositor *c = input->compositor;
+
+ notify_keyboard_focus(c->base.input_device, time, NULL, NULL);
}
static const struct wl_input_device_listener input_device_listener = {
input_handle_motion,
input_handle_button,
+ input_handle_axis,
input_handle_key,
- input_handle_pointer_focus,
- input_handle_keyboard_focus,
+ input_handle_pointer_enter,
+ input_handle_pointer_leave,
+ input_handle_keyboard_enter,
+ input_handle_keyboard_leave,
};
static void
}
static struct weston_compositor *
-wayland_compositor_create(struct wl_display *display, int width, int height)
+wayland_compositor_create(struct wl_display *display,
+ int width, int height, const char *display_name)
{
struct wayland_compositor *c;
struct wl_event_loop *loop;
memset(c, 0, sizeof *c);
- c->parent.display = wl_display_connect(NULL);
+ c->parent.display = wl_display_connect(display_name);
if (c->parent.display == NULL) {
fprintf(stderr, "failed to create display: %m\n");
if (weston_compositor_init(&c->base, display) < 0)
return NULL;
+ create_border(c);
if (wayland_compositor_create_output(c, width, height) < 0)
return NULL;
return &c->base;
}
-struct weston_compositor *
-backend_init(struct wl_display *display, char *options);
-
WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, char *options)
+backend_init(struct wl_display *display, int argc, char *argv[])
{
- int width = 1024, height = 640, i;
- char *p, *value;
-
- static char * const tokens[] = { "width", "height", NULL };
-
- p = options;
- while (i = getsubopt(&p, tokens, &value), i != -1) {
- switch (i) {
- case 0:
- width = strtol(value, NULL, 0);
- break;
- case 1:
- height = strtol(value, NULL, 0);
- break;
- }
- }
+ int width = 1024, height = 640;
+ char *display_name = NULL;
+
+ const struct weston_option wayland_options[] = {
+ { WESTON_OPTION_INTEGER, "width", 0, &width },
+ { WESTON_OPTION_INTEGER, "height", 0, &height },
+ { WESTON_OPTION_STRING, "display", 0, &display_name },
+ };
+
+ parse_options(wayland_options,
+ ARRAY_LENGTH(wayland_options), argc, argv);
- return wayland_compositor_create(display, width, height);
+ return wayland_compositor_create(display, width, height, display_name);
}