2010-11-27 21:04:12 +03:00
|
|
|
/*
|
Change remaining GPLv2 headers to MIT
The files in question are copyright Benjamin Franzke (who agrees),
Intel Corporation, Red Hat and myself. On behalf of Red Hat,
Richard Fontana says:
"Therefore, to the extent that Red Hat, Inc. has any copyright
interest in the files you cited as of this date (compositor-drm.c,
compositor.c, compositor.h, screenshooter.c in
http://cgit.freedesktop.org/wayland/wayland-demos/tree/compositor),
Red Hat hereby elects to apply the CC0 1.0 Universal Public Domain
Dedication to such copyrighted material. See:
http://creativecommons.org/publicdomain/zero/1.0/legalcode .
Thanks,
Richard E. Fontana
Open Source Licensing and Patent Counsel
Red Hat, Inc."
2011-09-15 23:43:14 +04:00
|
|
|
* Copyright © 2010-2011 Benjamin Franzke
|
2010-11-27 21:04:12 +03:00
|
|
|
*
|
Change remaining GPLv2 headers to MIT
The files in question are copyright Benjamin Franzke (who agrees),
Intel Corporation, Red Hat and myself. On behalf of Red Hat,
Richard Fontana says:
"Therefore, to the extent that Red Hat, Inc. has any copyright
interest in the files you cited as of this date (compositor-drm.c,
compositor.c, compositor.h, screenshooter.c in
http://cgit.freedesktop.org/wayland/wayland-demos/tree/compositor),
Red Hat hereby elects to apply the CC0 1.0 Universal Public Domain
Dedication to such copyrighted material. See:
http://creativecommons.org/publicdomain/zero/1.0/legalcode .
Thanks,
Richard E. Fontana
Open Source Licensing and Patent Counsel
Red Hat, Inc."
2011-09-15 23:43:14 +04:00
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and
|
|
|
|
* its documentation for any purpose is hereby granted without fee, provided
|
|
|
|
* that the above copyright notice appear in all copies and that both that
|
|
|
|
* copyright notice and this permission notice appear in supporting
|
|
|
|
* documentation, and that the name of the copyright holders not be used in
|
|
|
|
* advertising or publicity pertaining to distribution of the software
|
|
|
|
* without specific, written prior permission. The copyright holders make
|
|
|
|
* no representations about the suitability of this software for any
|
|
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
2010-11-27 21:04:12 +03:00
|
|
|
*
|
Change remaining GPLv2 headers to MIT
The files in question are copyright Benjamin Franzke (who agrees),
Intel Corporation, Red Hat and myself. On behalf of Red Hat,
Richard Fontana says:
"Therefore, to the extent that Red Hat, Inc. has any copyright
interest in the files you cited as of this date (compositor-drm.c,
compositor.c, compositor.h, screenshooter.c in
http://cgit.freedesktop.org/wayland/wayland-demos/tree/compositor),
Red Hat hereby elects to apply the CC0 1.0 Universal Public Domain
Dedication to such copyrighted material. See:
http://creativecommons.org/publicdomain/zero/1.0/legalcode .
Thanks,
Richard E. Fontana
Open Source Licensing and Patent Counsel
Red Hat, Inc."
2011-09-15 23:43:14 +04:00
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
|
|
|
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
|
|
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
2010-11-27 21:04:12 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
2012-06-01 15:14:06 +04:00
|
|
|
#include <sys/mman.h>
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2011-02-18 19:04:24 +03:00
|
|
|
#include <wayland-client.h>
|
|
|
|
#include <wayland-egl.h>
|
2010-11-27 21:04:12 +03:00
|
|
|
|
|
|
|
#include <GLES2/gl2.h>
|
|
|
|
#include <GLES2/gl2ext.h>
|
|
|
|
#include <EGL/egl.h>
|
|
|
|
#include <EGL/eglext.h>
|
|
|
|
|
|
|
|
#include "compositor.h"
|
2012-06-07 20:01:59 +04:00
|
|
|
#include "log.h"
|
2010-11-27 21:04:12 +03:00
|
|
|
|
|
|
|
struct wayland_compositor {
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_compositor base;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-03-29 06:53:49 +04:00
|
|
|
struct wl_egl_pixmap *dummy_pixmap;
|
2012-05-10 20:28:35 +04:00
|
|
|
EGLSurface dummy_egl_surface;
|
2012-03-29 06:53:49 +04:00
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
struct {
|
2012-06-18 23:13:51 +04:00
|
|
|
struct wl_display *wl_display;
|
2010-11-27 21:04:12 +03:00
|
|
|
struct wl_compositor *compositor;
|
|
|
|
struct wl_shell *shell;
|
|
|
|
struct wl_output *output;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
int32_t x, y, width, height;
|
|
|
|
} screen_allocation;
|
|
|
|
|
|
|
|
struct wl_event_source *wl_source;
|
|
|
|
uint32_t event_mask;
|
|
|
|
} parent;
|
|
|
|
|
2012-02-01 16:45:51 +04:00
|
|
|
struct {
|
|
|
|
int32_t top, bottom, left, right;
|
|
|
|
GLuint texture;
|
|
|
|
int32_t width, height;
|
|
|
|
} border;
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
struct wl_list input_list;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct wayland_output {
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_output base;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
|
|
|
struct {
|
|
|
|
struct wl_surface *surface;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct wl_shell_surface *shell_surface;
|
2011-02-18 19:04:24 +03:00
|
|
|
struct wl_egl_window *egl_window;
|
2010-11-27 21:04:12 +03:00
|
|
|
} parent;
|
2011-02-18 19:04:24 +03:00
|
|
|
EGLSurface egl_surface;
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_mode mode;
|
2010-11-27 21:04:12 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wayland_input {
|
|
|
|
struct wayland_compositor *compositor;
|
2012-05-16 21:45:18 +04:00
|
|
|
struct wl_seat *seat;
|
|
|
|
struct wl_pointer *pointer;
|
|
|
|
struct wl_keyboard *keyboard;
|
|
|
|
struct wl_touch *touch;
|
2010-11-27 21:04:12 +03:00
|
|
|
struct wl_list link;
|
2012-06-22 16:21:41 +04:00
|
|
|
uint32_t key_serial;
|
2010-11-27 21:04:12 +03:00
|
|
|
};
|
|
|
|
|
2012-02-01 16:45:51 +04:00
|
|
|
|
|
|
|
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;
|
2012-04-20 13:15:51 +04:00
|
|
|
struct weston_shader *shader = &c->base.texture_shader_rgba;
|
2012-02-01 16:45:51 +04:00
|
|
|
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)
|
|
|
|
{
|
2012-03-16 19:25:09 +04:00
|
|
|
pixman_image_t *image;
|
2012-02-01 16:45:51 +04:00
|
|
|
|
2012-03-16 19:25:09 +04:00
|
|
|
image = load_image(DATADIR "/weston/border.png");
|
|
|
|
if (!image) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("could'nt load border image\n");
|
2012-02-01 16:45:51 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-16 19:25:09 +04:00
|
|
|
c->border.width = pixman_image_get_width(image);
|
|
|
|
c->border.height = pixman_image_get_height(image);
|
|
|
|
|
2012-02-01 16:45:51 +04:00
|
|
|
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,
|
2012-03-16 19:25:09 +04:00
|
|
|
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
|
|
|
|
pixman_image_get_data(image));
|
2012-02-01 16:45:51 +04:00
|
|
|
|
|
|
|
c->border.top = 25;
|
|
|
|
c->border.bottom = 50;
|
|
|
|
c->border.left = 25;
|
|
|
|
c->border.right = 25;
|
2012-03-16 19:25:09 +04:00
|
|
|
|
|
|
|
pixman_image_unref(image);
|
2012-02-01 16:45:51 +04:00
|
|
|
}
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
static int
|
|
|
|
wayland_compositor_init_egl(struct wayland_compositor *c)
|
|
|
|
{
|
|
|
|
EGLint major, minor;
|
2011-02-18 19:04:24 +03:00
|
|
|
EGLint n;
|
|
|
|
EGLint config_attribs[] = {
|
|
|
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
|
|
|
EGL_RED_SIZE, 1,
|
|
|
|
EGL_GREEN_SIZE, 1,
|
|
|
|
EGL_BLUE_SIZE, 1,
|
2012-02-01 16:45:51 +04:00
|
|
|
EGL_ALPHA_SIZE, 1,
|
2011-03-02 19:36:30 +03:00
|
|
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
2011-02-18 19:04:24 +03:00
|
|
|
EGL_NONE
|
|
|
|
};
|
2010-11-27 21:04:12 +03:00
|
|
|
static const EGLint context_attribs[] = {
|
|
|
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
|
|
|
EGL_NONE
|
|
|
|
};
|
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
c->base.egl_display = eglGetDisplay(c->parent.wl_display);
|
|
|
|
if (c->base.egl_display == NULL) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to create display\n");
|
2010-11-27 21:04:12 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
if (!eglInitialize(c->base.egl_display, &major, &minor)) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to initialize display\n");
|
2010-11-27 21:04:12 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!eglBindAPI(EGL_OPENGL_ES_API)) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to bind EGL_OPENGL_ES_API\n");
|
2010-11-27 21:04:12 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2012-06-18 23:13:51 +04:00
|
|
|
if (!eglChooseConfig(c->base.egl_display, config_attribs,
|
|
|
|
&c->base.egl_config, 1, &n) || n == 0) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to choose config: %d\n", n);
|
2011-02-18 19:04:24 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
c->base.egl_context =
|
|
|
|
eglCreateContext(c->base.egl_display, c->base.egl_config,
|
|
|
|
EGL_NO_CONTEXT, context_attribs);
|
|
|
|
if (c->base.egl_context == NULL) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to create context\n");
|
2010-11-27 21:04:12 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-03-29 06:53:49 +04:00
|
|
|
c->dummy_pixmap = wl_egl_pixmap_create(10, 10, 0);
|
|
|
|
if (!c->dummy_pixmap) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failure to create dummy_pixmap\n");
|
2012-03-29 06:53:49 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
c->dummy_egl_surface =
|
2012-06-18 23:13:51 +04:00
|
|
|
eglCreatePixmapSurface(c->base.egl_display, c->base.egl_config,
|
2012-03-29 06:53:49 +04:00
|
|
|
c->dummy_pixmap, NULL);
|
2012-06-18 23:13:51 +04:00
|
|
|
if (!eglMakeCurrent(c->base.egl_display, c->dummy_egl_surface,
|
|
|
|
c->dummy_egl_surface, c->base.egl_context)) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to make context current\n");
|
2010-11-27 21:04:12 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-08-17 07:01:28 +04:00
|
|
|
static void
|
2012-02-07 18:56:15 +04:00
|
|
|
frame_done(void *data, struct wl_callback *callback, uint32_t time)
|
2011-08-17 07:01:28 +04:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_output *output = data;
|
2011-08-17 07:01:28 +04:00
|
|
|
|
2012-02-07 18:56:15 +04:00
|
|
|
wl_callback_destroy(callback);
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_output_finish_frame(output, time);
|
2011-08-17 07:01:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_callback_listener frame_listener = {
|
|
|
|
frame_done
|
|
|
|
};
|
|
|
|
|
2012-01-26 08:47:45 +04:00
|
|
|
static void
|
2012-02-29 07:31:58 +04:00
|
|
|
wayland_output_repaint(struct weston_output *output_base,
|
|
|
|
pixman_region32_t *damage)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
2011-03-14 14:07:26 +03:00
|
|
|
struct wayland_output *output = (struct wayland_output *) output_base;
|
2012-01-26 08:47:45 +04:00
|
|
|
struct wayland_compositor *compositor =
|
2011-03-14 14:07:26 +03:00
|
|
|
(struct wayland_compositor *) output->base.compositor;
|
2011-08-17 07:01:28 +04:00
|
|
|
struct wl_callback *callback;
|
2012-01-26 08:47:45 +04:00
|
|
|
struct weston_surface *surface;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
if (!eglMakeCurrent(compositor->base.egl_display, output->egl_surface,
|
|
|
|
output->egl_surface,
|
|
|
|
compositor->base.egl_context)) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to make current\n");
|
2012-01-26 08:47:45 +04:00
|
|
|
return;
|
|
|
|
}
|
2011-03-11 18:39:20 +03:00
|
|
|
|
2012-01-26 08:47:45 +04:00
|
|
|
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
|
2012-02-29 07:31:58 +04:00
|
|
|
weston_surface_draw(surface, &output->base, damage);
|
2012-01-26 08:47:45 +04:00
|
|
|
|
2012-02-01 16:45:51 +04:00
|
|
|
draw_border(output);
|
|
|
|
|
2012-06-20 08:13:18 +04:00
|
|
|
wl_signal_emit(&output->base.frame_signal, output);
|
2012-04-20 23:37:33 +04:00
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
eglSwapBuffers(compositor->base.egl_display, output->egl_surface);
|
2011-08-17 07:01:28 +04:00
|
|
|
callback = wl_surface_frame(output->parent.surface);
|
|
|
|
wl_callback_add_listener(callback, &frame_listener, output);
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-01-26 08:47:45 +04:00
|
|
|
return;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2011-08-30 00:52:23 +04:00
|
|
|
static void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
wayland_output_destroy(struct weston_output *output_base)
|
2011-08-30 00:52:23 +04:00
|
|
|
{
|
|
|
|
struct wayland_output *output = (struct wayland_output *) output_base;
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_compositor *ec = output->base.compositor;
|
2011-08-30 00:52:23 +04:00
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
eglDestroySurface(ec->egl_display, output->egl_surface);
|
2011-08-30 00:52:23 +04:00
|
|
|
wl_egl_window_destroy(output->parent.egl_window);
|
|
|
|
free(output);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-18 18:36:21 +04:00
|
|
|
static const struct wl_shell_surface_listener shell_surface_listener;
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
static int
|
|
|
|
wayland_compositor_create_output(struct wayland_compositor *c,
|
|
|
|
int width, int height)
|
|
|
|
{
|
|
|
|
struct wayland_output *output;
|
|
|
|
|
|
|
|
output = malloc(sizeof *output);
|
|
|
|
if (output == NULL)
|
|
|
|
return -1;
|
|
|
|
memset(output, 0, sizeof *output);
|
|
|
|
|
2011-06-21 19:16:58 +04:00
|
|
|
output->mode.flags =
|
|
|
|
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
|
|
|
|
output->mode.width = width;
|
|
|
|
output->mode.height = height;
|
|
|
|
output->mode.refresh = 60;
|
|
|
|
wl_list_init(&output->base.mode_list);
|
|
|
|
wl_list_insert(&output->base.mode_list, &output->mode.link);
|
|
|
|
|
|
|
|
output->base.current = &output->mode;
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_output_init(&output->base, &c->base, 0, 0, width, height,
|
2011-02-18 19:04:24 +03:00
|
|
|
WL_OUTPUT_FLIPPED);
|
2011-06-21 19:16:58 +04:00
|
|
|
|
2012-02-01 16:45:51 +04:00
|
|
|
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);
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
output->parent.surface =
|
|
|
|
wl_compositor_create_surface(c->parent.compositor);
|
|
|
|
wl_surface_set_user_data(output->parent.surface, output);
|
|
|
|
|
2011-02-18 19:04:24 +03:00
|
|
|
output->parent.egl_window =
|
2012-02-01 16:45:51 +04:00
|
|
|
wl_egl_window_create(output->parent.surface,
|
|
|
|
width + c->border.left + c->border.right,
|
|
|
|
height + c->border.top + c->border.bottom);
|
2011-02-18 19:04:24 +03:00
|
|
|
if (!output->parent.egl_window) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failure to create wl_egl_window\n");
|
2011-02-18 19:04:24 +03:00
|
|
|
goto cleanup_output;
|
|
|
|
}
|
|
|
|
|
|
|
|
output->egl_surface =
|
2012-06-18 23:13:51 +04:00
|
|
|
eglCreateWindowSurface(c->base.egl_display, c->base.egl_config,
|
2011-02-18 19:04:24 +03:00
|
|
|
output->parent.egl_window, NULL);
|
|
|
|
if (!output->egl_surface) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to create window surface\n");
|
2011-02-18 19:04:24 +03:00
|
|
|
goto cleanup_window;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
if (!eglMakeCurrent(c->base.egl_display, output->egl_surface,
|
|
|
|
output->egl_surface, c->base.egl_context)) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to make surface current\n");
|
2011-02-18 19:04:24 +03:00
|
|
|
goto cleanup_surface;
|
|
|
|
return -1;
|
|
|
|
}
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
output->parent.shell_surface =
|
|
|
|
wl_shell_get_shell_surface(c->parent.shell,
|
|
|
|
output->parent.surface);
|
2012-06-18 18:36:21 +04:00
|
|
|
wl_shell_surface_add_listener(output->parent.shell_surface,
|
|
|
|
&shell_surface_listener, output);
|
2011-11-25 14:09:16 +04:00
|
|
|
wl_shell_surface_set_toplevel(output->parent.shell_surface);
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-04-17 13:20:49 +04:00
|
|
|
output->base.origin = output->base.current;
|
2012-01-26 08:32:28 +04:00
|
|
|
output->base.repaint = wayland_output_repaint;
|
2011-08-30 00:52:23 +04:00
|
|
|
output->base.destroy = wayland_output_destroy;
|
2012-02-10 01:12:57 +04:00
|
|
|
output->base.assign_planes = NULL;
|
2012-02-29 21:53:50 +04:00
|
|
|
output->base.set_backlight = NULL;
|
|
|
|
output->base.set_dpms = NULL;
|
2012-04-17 13:20:47 +04:00
|
|
|
output->base.switch_mode = NULL;
|
2011-03-11 18:39:20 +03:00
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
wl_list_insert(c->base.output_list.prev, &output->base.link);
|
|
|
|
|
|
|
|
return 0;
|
2011-02-18 19:04:24 +03:00
|
|
|
|
|
|
|
cleanup_surface:
|
2012-06-18 23:13:51 +04:00
|
|
|
eglDestroySurface(c->base.egl_display, output->egl_surface);
|
2011-02-18 19:04:24 +03:00
|
|
|
cleanup_window:
|
|
|
|
wl_egl_window_destroy(output->parent.egl_window);
|
|
|
|
cleanup_output:
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
/* FIXME: cleanup weston_output */
|
2011-02-18 19:04:24 +03:00
|
|
|
free(output);
|
|
|
|
|
|
|
|
return -1;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2012-06-18 18:36:21 +04:00
|
|
|
static void
|
|
|
|
shell_surface_ping(void *data, struct wl_shell_surface *shell_surface,
|
|
|
|
uint32_t serial)
|
|
|
|
{
|
|
|
|
wl_shell_surface_pong(shell_surface, serial);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_surface_configure(void *data, struct wl_shell_surface *shell_surface,
|
|
|
|
uint32_t edges, int32_t width, int32_t height)
|
|
|
|
{
|
|
|
|
/* FIXME: implement resizing */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_shell_surface_listener shell_surface_listener = {
|
|
|
|
shell_surface_ping,
|
|
|
|
shell_surface_configure,
|
|
|
|
shell_surface_popup_done
|
|
|
|
};
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
/* Events received from the wayland-server this compositor is client of: */
|
|
|
|
|
|
|
|
/* parent output interface */
|
|
|
|
static void
|
|
|
|
display_handle_geometry(void *data,
|
2011-06-21 19:16:58 +04:00
|
|
|
struct wl_output *wl_output,
|
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
int physical_width,
|
|
|
|
int physical_height,
|
|
|
|
int subpixel,
|
|
|
|
const char *make,
|
|
|
|
const char *model)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_compositor *c = data;
|
|
|
|
|
2010-12-02 04:10:10 +03:00
|
|
|
c->parent.screen_allocation.x = x;
|
|
|
|
c->parent.screen_allocation.y = y;
|
2011-06-21 19:16:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
display_handle_mode(void *data,
|
|
|
|
struct wl_output *wl_output,
|
|
|
|
uint32_t flags,
|
|
|
|
int width,
|
|
|
|
int height,
|
|
|
|
int refresh)
|
|
|
|
{
|
|
|
|
struct wayland_compositor *c = data;
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
c->parent.screen_allocation.width = width;
|
|
|
|
c->parent.screen_allocation.height = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_output_listener output_listener = {
|
|
|
|
display_handle_geometry,
|
2011-06-21 19:16:58 +04:00
|
|
|
display_handle_mode
|
2010-11-27 21:04:12 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/* parent input interface */
|
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_pointer_enter(void *data, struct wl_pointer *pointer,
|
|
|
|
uint32_t serial, struct wl_surface *surface,
|
|
|
|
wl_fixed_t x, wl_fixed_t y)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
2012-05-16 21:45:18 +04:00
|
|
|
struct wayland_output *output;
|
2010-11-27 21:04:12 +03:00
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-06-22 16:21:41 +04:00
|
|
|
/* XXX: If we get a modifier event immediately before the focus,
|
|
|
|
* we should try to keep the same serial. */
|
2012-05-16 21:45:18 +04:00
|
|
|
output = wl_surface_get_user_data(surface);
|
|
|
|
notify_pointer_focus(&c->base.seat->seat, &output->base, x, y);
|
2012-06-15 18:27:35 +04:00
|
|
|
wl_pointer_set_cursor(input->pointer, serial, NULL, 0, 0);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_pointer_leave(void *data, struct wl_pointer *pointer,
|
|
|
|
uint32_t serial, struct wl_surface *surface)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
notify_pointer_focus(&c->base.seat->seat, NULL, 0, 0);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2012-03-22 20:47:01 +04:00
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_motion(void *data, struct wl_pointer *pointer,
|
|
|
|
uint32_t time, wl_fixed_t x, wl_fixed_t y)
|
2012-03-22 20:47:01 +04:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
notify_motion(&c->base.seat->seat, time,
|
|
|
|
x - wl_fixed_from_int(c->border.left),
|
|
|
|
y - wl_fixed_from_int(c->border.top));
|
2012-03-22 20:47:01 +04:00
|
|
|
}
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_button(void *data, struct wl_pointer *pointer,
|
2012-05-30 19:31:51 +04:00
|
|
|
uint32_t serial, uint32_t time, uint32_t button,
|
|
|
|
uint32_t state_w)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
2012-05-30 19:31:51 +04:00
|
|
|
enum wl_pointer_button_state state = state_w;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
notify_button(&c->base.seat->seat, time, button, state);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_axis(void *data, struct wl_pointer *pointer,
|
2012-05-30 19:32:00 +04:00
|
|
|
uint32_t time, uint32_t axis, wl_fixed_t value)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-05-30 19:32:00 +04:00
|
|
|
notify_axis(&c->base.seat->seat, time, axis, value);
|
2012-02-23 18:59:05 +04:00
|
|
|
}
|
2012-02-07 18:56:51 +04:00
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
static const struct wl_pointer_listener pointer_listener = {
|
|
|
|
input_handle_pointer_enter,
|
|
|
|
input_handle_pointer_leave,
|
|
|
|
input_handle_motion,
|
|
|
|
input_handle_button,
|
|
|
|
input_handle_axis,
|
|
|
|
};
|
|
|
|
|
2012-06-01 15:14:06 +04:00
|
|
|
static void
|
|
|
|
input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
|
|
|
|
int fd, uint32_t size)
|
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct xkb_keymap *keymap;
|
|
|
|
char *map_str;
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
close(fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
|
|
|
close(fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
|
|
|
if (map_str == MAP_FAILED) {
|
|
|
|
close(fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
keymap = xkb_map_new_from_string(input->compositor->base.xkb_context,
|
|
|
|
map_str,
|
|
|
|
XKB_KEYMAP_FORMAT_TEXT_V1,
|
|
|
|
0);
|
|
|
|
munmap(map_str, size);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
if (!keymap) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to compile keymap\n");
|
2012-06-01 15:14:06 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_seat_init_keyboard(input->compositor->base.seat, keymap);
|
|
|
|
xkb_map_unref(keymap);
|
|
|
|
}
|
|
|
|
|
2012-02-23 18:59:05 +04:00
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_keyboard_enter(void *data,
|
|
|
|
struct wl_keyboard *keyboard,
|
|
|
|
uint32_t serial,
|
|
|
|
struct wl_surface *surface,
|
|
|
|
struct wl_array *keys)
|
2012-02-23 18:59:05 +04:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-06-22 16:21:41 +04:00
|
|
|
/* XXX: If we get a modifier event immediately before the focus,
|
|
|
|
* we should try to keep the same serial. */
|
2012-06-22 16:21:29 +04:00
|
|
|
notify_keyboard_focus_in(&c->base.seat->seat, keys,
|
|
|
|
STATE_UPDATE_AUTOMATIC);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_keyboard_leave(void *data,
|
|
|
|
struct wl_keyboard *keyboard,
|
|
|
|
uint32_t serial,
|
|
|
|
struct wl_surface *surface)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
2011-01-28 04:18:17 +03:00
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-06-22 16:21:29 +04:00
|
|
|
notify_keyboard_focus_out(&c->base.seat->seat);
|
2012-02-23 18:59:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_key(void *data, struct wl_keyboard *keyboard,
|
|
|
|
uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
2012-02-23 18:59:05 +04:00
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
|
2012-06-22 16:21:41 +04:00
|
|
|
input->key_serial = serial;
|
2012-05-30 19:31:52 +04:00
|
|
|
notify_key(&c->base.seat->seat, time, key,
|
|
|
|
state ? WL_KEYBOARD_KEY_STATE_PRESSED :
|
2012-06-22 16:21:37 +04:00
|
|
|
WL_KEYBOARD_KEY_STATE_RELEASED,
|
2012-06-22 16:21:41 +04:00
|
|
|
STATE_UPDATE_NONE);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2012-05-31 23:27:47 +04:00
|
|
|
static void
|
|
|
|
input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
2012-06-22 16:21:41 +04:00
|
|
|
uint32_t serial_in, uint32_t mods_depressed,
|
2012-05-31 23:27:47 +04:00
|
|
|
uint32_t mods_latched, uint32_t mods_locked,
|
|
|
|
uint32_t group)
|
|
|
|
{
|
2012-06-22 16:21:41 +04:00
|
|
|
struct wayland_input *input = data;
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
uint32_t serial_out;
|
|
|
|
|
|
|
|
/* If we get a key event followed by a modifier event with the
|
|
|
|
* same serial number, then we try to preserve those semantics by
|
|
|
|
* reusing the same serial number on the way out too. */
|
|
|
|
if (serial_in == input->key_serial)
|
|
|
|
serial_out = wl_display_get_serial(c->base.wl_display);
|
|
|
|
else
|
|
|
|
serial_out = wl_display_next_serial(c->base.wl_display);
|
|
|
|
|
|
|
|
xkb_state_update_mask(c->base.seat->xkb_state.state,
|
|
|
|
mods_depressed, mods_latched,
|
|
|
|
mods_locked, 0, 0, group);
|
|
|
|
notify_modifiers(&c->base.seat->seat, serial_out);
|
2012-05-31 23:27:47 +04:00
|
|
|
}
|
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
static const struct wl_keyboard_listener keyboard_listener = {
|
2012-06-01 15:14:06 +04:00
|
|
|
input_handle_keymap,
|
2012-02-23 18:59:05 +04:00
|
|
|
input_handle_keyboard_enter,
|
|
|
|
input_handle_keyboard_leave,
|
2012-05-16 21:45:18 +04:00
|
|
|
input_handle_key,
|
2012-05-31 23:27:47 +04:00
|
|
|
input_handle_modifiers,
|
2012-05-16 21:45:18 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
input_handle_capabilities(void *data, struct wl_seat *seat,
|
|
|
|
enum wl_seat_capability caps)
|
|
|
|
{
|
|
|
|
struct wayland_input *input = data;
|
|
|
|
|
|
|
|
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
|
|
|
|
input->pointer = wl_seat_get_pointer(seat);
|
|
|
|
wl_pointer_set_user_data(input->pointer, input);
|
|
|
|
wl_pointer_add_listener(input->pointer, &pointer_listener,
|
|
|
|
input);
|
2012-06-01 15:14:00 +04:00
|
|
|
weston_seat_init_pointer(input->compositor->base.seat);
|
2012-05-16 21:45:18 +04:00
|
|
|
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
|
|
|
|
wl_pointer_destroy(input->pointer);
|
|
|
|
input->pointer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
|
|
|
|
input->keyboard = wl_seat_get_keyboard(seat);
|
|
|
|
wl_keyboard_set_user_data(input->keyboard, input);
|
|
|
|
wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
|
|
|
|
input);
|
|
|
|
} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
|
|
|
|
wl_keyboard_destroy(input->keyboard);
|
|
|
|
input->keyboard = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_seat_listener seat_listener = {
|
|
|
|
input_handle_capabilities,
|
2010-11-27 21:04:12 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2012-05-16 21:45:18 +04:00
|
|
|
display_add_seat(struct wayland_compositor *c, uint32_t id)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_input *input;
|
|
|
|
|
|
|
|
input = malloc(sizeof *input);
|
|
|
|
if (input == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
memset(input, 0, sizeof *input);
|
|
|
|
|
|
|
|
input->compositor = c;
|
2012-06-18 23:13:51 +04:00
|
|
|
input->seat = wl_display_bind(c->parent.wl_display, id,
|
2012-05-16 21:45:18 +04:00
|
|
|
&wl_seat_interface);
|
2010-11-27 21:04:12 +03:00
|
|
|
wl_list_insert(c->input_list.prev, &input->link);
|
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
wl_seat_add_listener(input->seat, &seat_listener, input);
|
|
|
|
wl_seat_set_user_data(input->seat, input);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
display_handle_global(struct wl_display *display, uint32_t id,
|
|
|
|
const char *interface, uint32_t version, void *data)
|
|
|
|
{
|
|
|
|
struct wayland_compositor *c = data;
|
|
|
|
|
2011-04-30 12:41:27 +04:00
|
|
|
if (strcmp(interface, "wl_compositor") == 0) {
|
2011-08-19 22:41:57 +04:00
|
|
|
c->parent.compositor =
|
|
|
|
wl_display_bind(display, id, &wl_compositor_interface);
|
2011-04-30 12:41:27 +04:00
|
|
|
} else if (strcmp(interface, "wl_output") == 0) {
|
2011-08-19 22:41:57 +04:00
|
|
|
c->parent.output =
|
|
|
|
wl_display_bind(display, id, &wl_output_interface);
|
2010-11-27 21:04:12 +03:00
|
|
|
wl_output_add_listener(c->parent.output, &output_listener, c);
|
2011-04-30 12:41:27 +04:00
|
|
|
} else if (strcmp(interface, "wl_shell") == 0) {
|
2011-08-19 22:41:57 +04:00
|
|
|
c->parent.shell =
|
|
|
|
wl_display_bind(display, id, &wl_shell_interface);
|
2012-06-22 17:04:36 +04:00
|
|
|
} else if (strcmp(interface, "wl_seat") == 0) {
|
|
|
|
display_add_seat(c, id);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
update_event_mask(uint32_t mask, void *data)
|
|
|
|
{
|
|
|
|
struct wayland_compositor *c = data;
|
|
|
|
|
|
|
|
c->parent.event_mask = mask;
|
|
|
|
if (c->parent.wl_source)
|
|
|
|
wl_event_source_fd_update(c->parent.wl_source, mask);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-22 21:01:26 +04:00
|
|
|
static int
|
2010-11-27 21:04:12 +03:00
|
|
|
wayland_compositor_handle_event(int fd, uint32_t mask, void *data)
|
|
|
|
{
|
|
|
|
struct wayland_compositor *c = data;
|
|
|
|
|
|
|
|
if (mask & WL_EVENT_READABLE)
|
2012-06-18 23:13:51 +04:00
|
|
|
wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE);
|
2011-12-29 07:51:20 +04:00
|
|
|
if (mask & WL_EVENT_WRITABLE)
|
2012-06-18 23:13:51 +04:00
|
|
|
wl_display_iterate(c->parent.wl_display, WL_DISPLAY_WRITABLE);
|
2011-04-22 21:01:26 +04:00
|
|
|
|
|
|
|
return 1;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2012-06-04 14:40:46 +04:00
|
|
|
static int
|
|
|
|
wayland_input_create(struct wayland_compositor *c)
|
|
|
|
{
|
|
|
|
struct weston_seat *seat;
|
|
|
|
|
|
|
|
seat = malloc(sizeof *seat);
|
|
|
|
if (seat == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
memset(seat, 0, sizeof *seat);
|
|
|
|
weston_seat_init(seat, &c->base);
|
|
|
|
|
|
|
|
c->base.seat = seat;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-02 00:52:15 +03:00
|
|
|
static void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
wayland_destroy(struct weston_compositor *ec)
|
2010-12-02 00:52:15 +03:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_compositor_shutdown(ec);
|
2011-08-30 00:52:23 +04:00
|
|
|
|
2010-12-02 00:52:15 +03:00
|
|
|
free(ec);
|
|
|
|
}
|
|
|
|
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
static struct weston_compositor *
|
2012-02-07 18:57:25 +04:00
|
|
|
wayland_compositor_create(struct wl_display *display,
|
2012-06-01 19:11:10 +04:00
|
|
|
int width, int height, const char *display_name,
|
2012-06-01 19:14:02 +04:00
|
|
|
int argc, char *argv[], const char *config_file)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
struct wayland_compositor *c;
|
|
|
|
struct wl_event_loop *loop;
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
c = malloc(sizeof *c);
|
|
|
|
if (c == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memset(c, 0, sizeof *c);
|
|
|
|
|
2012-06-22 17:04:36 +04:00
|
|
|
if (weston_compositor_init(&c->base, display, argc, argv,
|
|
|
|
config_file) < 0)
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_free;
|
2012-06-22 17:04:36 +04:00
|
|
|
|
|
|
|
if (wayland_input_create(c) < 0)
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_compositor;
|
2012-06-22 17:04:36 +04:00
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
c->parent.wl_display = wl_display_connect(display_name);
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
if (c->parent.wl_display == NULL) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("failed to create display: %m\n");
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_compositor;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_init(&c->input_list);
|
2012-06-18 23:13:51 +04:00
|
|
|
wl_display_add_global_listener(c->parent.wl_display,
|
2010-11-27 21:04:12 +03:00
|
|
|
display_handle_global, c);
|
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE);
|
2010-11-27 21:04:12 +03:00
|
|
|
|
|
|
|
c->base.wl_display = display;
|
|
|
|
if (wayland_compositor_init_egl(c) < 0)
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_display;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2011-01-15 14:34:48 +03:00
|
|
|
c->base.destroy = wayland_destroy;
|
|
|
|
|
2012-06-22 17:04:36 +04:00
|
|
|
if (weston_compositor_init_gl(&c->base) < 0)
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_display;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
2012-02-01 16:45:51 +04:00
|
|
|
create_border(c);
|
2010-11-27 21:04:12 +03:00
|
|
|
if (wayland_compositor_create_output(c, width, height) < 0)
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_display;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
|
|
|
loop = wl_display_get_event_loop(c->base.wl_display);
|
|
|
|
|
2012-06-18 23:13:51 +04:00
|
|
|
fd = wl_display_get_fd(c->parent.wl_display, update_event_mask, c);
|
2010-11-27 21:04:12 +03:00
|
|
|
c->parent.wl_source =
|
|
|
|
wl_event_loop_add_fd(loop, fd, c->parent.event_mask,
|
|
|
|
wayland_compositor_handle_event, c);
|
|
|
|
if (c->parent.wl_source == NULL)
|
2012-07-08 05:03:43 +04:00
|
|
|
goto err_display;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
|
|
|
return &c->base;
|
2012-07-08 05:03:43 +04:00
|
|
|
|
|
|
|
err_display:
|
|
|
|
wl_display_disconnect(c->parent.wl_display);
|
|
|
|
err_compositor:
|
|
|
|
weston_compositor_shutdown(&c->base);
|
|
|
|
err_free:
|
|
|
|
free(c);
|
|
|
|
return NULL;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
2011-05-03 06:09:20 +04:00
|
|
|
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
WL_EXPORT struct weston_compositor *
|
2012-06-01 19:14:02 +04:00
|
|
|
backend_init(struct wl_display *display, int argc, char *argv[],
|
|
|
|
const char *config_file)
|
2011-05-03 06:09:20 +04:00
|
|
|
{
|
2012-03-12 05:05:57 +04:00
|
|
|
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);
|
2011-05-03 06:09:20 +04:00
|
|
|
|
2012-06-01 19:11:10 +04:00
|
|
|
return wayland_compositor_create(display, width, height, display_name,
|
2012-06-01 19:14:02 +04:00
|
|
|
argc, argv, config_file);
|
2011-05-03 06:09:20 +04:00
|
|
|
}
|