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"
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
struct {
|
2012-06-18 23:13:51 +04:00
|
|
|
struct wl_display *wl_display;
|
2012-10-11 05:34:26 +04:00
|
|
|
struct wl_registry *registry;
|
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;
|
2012-09-06 05:54:15 +04:00
|
|
|
struct wl_listener frame_listener;
|
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;
|
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 {
|
2012-08-10 18:01:33 +04:00
|
|
|
struct weston_seat base;
|
2010-11-27 21:04:12 +03:00
|
|
|
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;
|
2012-08-14 07:29:53 +04:00
|
|
|
uint32_t enter_serial;
|
|
|
|
int focus;
|
|
|
|
struct wayland_output *output;
|
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);
|
|
|
|
|
2012-04-20 13:44:06 +04:00
|
|
|
glUniform1i(shader->tex_uniforms[0], 0);
|
2012-02-01 16:45:51 +04:00
|
|
|
glUniform1f(shader->alpha_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
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
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-09-06 05:54:15 +04:00
|
|
|
static void
|
|
|
|
wayland_output_frame_notify(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct wayland_output *output =
|
|
|
|
container_of(listener,
|
|
|
|
struct wayland_output, frame_listener);
|
|
|
|
|
|
|
|
draw_border(output);
|
|
|
|
}
|
|
|
|
|
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,
|
2012-09-06 05:54:15 +04:00
|
|
|
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-09-06 06:49:55 +04:00
|
|
|
struct weston_compositor *ec = output->base.compositor;
|
2011-08-17 07:01:28 +04:00
|
|
|
struct wl_callback *callback;
|
2010-11-27 21:04:12 +03:00
|
|
|
|
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-10-10 13:49:31 +04:00
|
|
|
ec->renderer->repaint_output(&output->base, damage);
|
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-09-06 05:54:15 +04:00
|
|
|
eglDestroySurface(ec->egl_display, output->base.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;
|
2012-08-18 11:04:05 +04:00
|
|
|
weston_output_init(&output->base, &c->base, 0, 0, width, height,
|
|
|
|
WL_OUTPUT_TRANSFORM_NORMAL);
|
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;
|
2012-08-14 07:34:04 +04:00
|
|
|
output->base.make = "waywayland";
|
|
|
|
output->base.model = "none";
|
2012-02-01 16:45:51 +04:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-09-06 05:54:15 +04:00
|
|
|
output->base.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);
|
2012-09-06 05:54:15 +04:00
|
|
|
if (!output->base.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
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
2012-09-06 05:54:15 +04:00
|
|
|
output->frame_listener.notify = wayland_output_frame_notify;
|
|
|
|
wl_signal_add(&output->base.frame_signal, &output->frame_listener);
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
return 0;
|
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,
|
2012-07-22 23:49:57 +04:00
|
|
|
const char *model,
|
|
|
|
int transform)
|
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
|
|
|
};
|
|
|
|
|
2012-08-14 07:29:53 +04:00
|
|
|
static void
|
|
|
|
check_focus(struct wayland_input *input, wl_fixed_t x, wl_fixed_t y)
|
|
|
|
{
|
|
|
|
struct wayland_compositor *c = input->compositor;
|
|
|
|
int width, height, inside;
|
|
|
|
|
|
|
|
width = input->output->mode.width;
|
|
|
|
height = input->output->mode.height;
|
|
|
|
|
|
|
|
inside = c->border.left <= wl_fixed_to_int(x) &&
|
|
|
|
wl_fixed_to_int(x) < width + c->border.left &&
|
|
|
|
c->border.top <= wl_fixed_to_int(y) &&
|
|
|
|
wl_fixed_to_int(y) < height + c->border.top;
|
|
|
|
|
|
|
|
if (!input->focus && inside) {
|
|
|
|
notify_pointer_focus(&input->base, &input->output->base,
|
|
|
|
x - wl_fixed_from_int(c->border.left),
|
|
|
|
y = wl_fixed_from_int(c->border.top));
|
|
|
|
wl_pointer_set_cursor(input->pointer,
|
|
|
|
input->enter_serial, NULL, 0, 0);
|
|
|
|
} else if (input->focus && !inside) {
|
|
|
|
notify_pointer_focus(&input->base, NULL, 0, 0);
|
|
|
|
/* FIXME: Should set default cursor here. */
|
|
|
|
}
|
|
|
|
|
|
|
|
input->focus = inside;
|
|
|
|
}
|
|
|
|
|
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-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-08-14 07:29:53 +04:00
|
|
|
input->enter_serial = serial;
|
|
|
|
input->output = wl_surface_get_user_data(surface);
|
|
|
|
check_focus(input, x, y);
|
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;
|
|
|
|
|
2012-08-10 17:50:11 +04:00
|
|
|
notify_pointer_focus(&input->base, NULL, 0, 0);
|
2012-08-14 07:29:53 +04:00
|
|
|
input->output = NULL;
|
|
|
|
input->focus = 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-08-14 07:29:53 +04:00
|
|
|
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));
|
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;
|
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-08-10 17:50:11 +04:00
|
|
|
notify_button(&input->base, 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;
|
|
|
|
|
2012-08-10 17:50:11 +04:00
|
|
|
notify_axis(&input->base, 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;
|
|
|
|
}
|
|
|
|
|
2012-08-10 18:01:33 +04:00
|
|
|
weston_seat_init_keyboard(&input->base, keymap);
|
2012-06-01 15:14:06 +04:00
|
|
|
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;
|
|
|
|
|
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-08-10 17:50:11 +04:00
|
|
|
notify_keyboard_focus_in(&input->base, keys,
|
2012-06-22 16:21:29 +04:00
|
|
|
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;
|
|
|
|
|
2012-08-10 17:50:11 +04:00
|
|
|
notify_keyboard_focus_out(&input->base);
|
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;
|
|
|
|
|
2012-06-22 16:21:41 +04:00
|
|
|
input->key_serial = serial;
|
2012-08-10 17:50:11 +04:00
|
|
|
notify_key(&input->base, time, key,
|
2012-05-30 19:31:52 +04:00
|
|
|
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);
|
|
|
|
|
2012-08-10 18:01:33 +04:00
|
|
|
xkb_state_update_mask(input->base.xkb_state.state,
|
2012-06-22 16:21:41 +04:00
|
|
|
mods_depressed, mods_latched,
|
|
|
|
mods_locked, 0, 0, group);
|
2012-08-10 17:50:11 +04:00
|
|
|
notify_modifiers(&input->base, 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-08-10 18:01:33 +04:00
|
|
|
weston_seat_init_pointer(&input->base);
|
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);
|
|
|
|
|
2012-08-10 18:01:33 +04:00
|
|
|
weston_seat_init(&input->base, &c->base);
|
2010-11-27 21:04:12 +03:00
|
|
|
input->compositor = c;
|
2012-10-11 05:34:26 +04:00
|
|
|
input->seat = wl_registry_bind(c->parent.registry, id,
|
|
|
|
&wl_seat_interface, 1);
|
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
|
2012-10-11 05:34:26 +04:00
|
|
|
registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
|
|
|
const char *interface, uint32_t version)
|
2010-11-27 21:04:12 +03:00
|
|
|
{
|
|
|
|
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 =
|
2012-10-11 05:34:26 +04:00
|
|
|
wl_registry_bind(registry, name,
|
|
|
|
&wl_compositor_interface, 1);
|
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 =
|
2012-10-11 05:34:26 +04:00
|
|
|
wl_registry_bind(registry, name,
|
|
|
|
&wl_output_interface, 1);
|
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 =
|
2012-10-11 05:34:26 +04:00
|
|
|
wl_registry_bind(registry, name,
|
|
|
|
&wl_shell_interface, 1);
|
2012-06-22 17:04:36 +04:00
|
|
|
} else if (strcmp(interface, "wl_seat") == 0) {
|
2012-10-11 05:34:26 +04:00
|
|
|
display_add_seat(c, name);
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-11 05:34:26 +04:00
|
|
|
static const struct wl_registry_listener registry_listener = {
|
|
|
|
registry_handle_global
|
|
|
|
};
|
2010-11-27 21:04:12 +03:00
|
|
|
|
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-10-11 05:34:26 +04:00
|
|
|
wl_display_dispatch(c->parent.wl_display);
|
2011-12-29 07:51:20 +04:00
|
|
|
if (mask & WL_EVENT_WRITABLE)
|
2012-10-11 05:34:26 +04:00
|
|
|
wl_display_flush(c->parent.wl_display);
|
2011-04-22 21:01:26 +04:00
|
|
|
|
|
|
|
return 1;
|
2010-11-27 21:04:12 +03:00
|
|
|
}
|
|
|
|
|
2012-07-31 22:32:01 +04:00
|
|
|
static void
|
|
|
|
wayland_restore(struct weston_compositor *ec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2012-09-07 05:44:24 +04:00
|
|
|
gles2_renderer_destroy(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
|
|
|
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
|
|
|
|
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-10-11 05:34:26 +04:00
|
|
|
c->parent.registry = wl_display_get_registry(c->parent.wl_display);
|
|
|
|
wl_registry_add_listener(c->parent.registry, ®istry_listener, c);
|
|
|
|
wl_display_dispatch(c->parent.wl_display);
|
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-07-31 22:32:01 +04:00
|
|
|
c->base.restore = wayland_restore;
|
2011-01-15 14:34:48 +03:00
|
|
|
|
2012-10-04 22:42:17 +04:00
|
|
|
c->border.top = 30;
|
|
|
|
c->border.bottom = 24;
|
2012-10-04 22:42:16 +04:00
|
|
|
c->border.left = 25;
|
2012-10-04 22:42:17 +04:00
|
|
|
c->border.right = 26;
|
2012-10-04 22:42:16 +04:00
|
|
|
|
|
|
|
/* requires border fields */
|
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
|
|
|
|
2012-10-04 22:42:16 +04:00
|
|
|
/* requires wayland_compositor_create_output */
|
2012-09-07 04:51:00 +04:00
|
|
|
if (gles2_renderer_init(&c->base) < 0)
|
|
|
|
goto err_display;
|
|
|
|
|
2012-10-04 22:42:16 +04:00
|
|
|
/* requires gles2_renderer_init */
|
2012-10-03 20:02:22 +04:00
|
|
|
create_border(c);
|
|
|
|
|
2010-11-27 21:04:12 +03:00
|
|
|
loop = wl_display_get_event_loop(c->base.wl_display);
|
|
|
|
|
2012-10-11 05:34:26 +04:00
|
|
|
fd = wl_display_get_fd(c->parent.wl_display);
|
2010-11-27 21:04:12 +03:00
|
|
|
c->parent.wl_source =
|
2012-10-11 05:34:26 +04:00
|
|
|
wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
|
2010-11-27 21:04:12 +03:00
|
|
|
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
|
|
|
}
|