summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>2014-09-22 16:18:45 +0900
committerNobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>2014-09-22 16:18:45 +0900
commit9bb3fcb10482980e6c7cee4346ec383b33d33ee7 (patch)
tree4845535906a1956c1603d0b1c2b8dbc1d2ef7e93
parente9568c17bbae5ad70d2b7d33299139a3cc4193ac (diff)
downloadweston-9bb3fcb10482980e6c7cee4346ec383b33d33ee7.tar.gz
apply 1.6
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am8
-rw-r--r--clients/clickdot.c50
-rw-r--r--clients/cliptest.c385
-rw-r--r--clients/desktop-shell.c10
-rw-r--r--clients/dnd.c15
-rw-r--r--clients/editor.c20
-rw-r--r--clients/eventdemo.c42
-rw-r--r--clients/image.c6
-rw-r--r--clients/keyboard.c5
-rw-r--r--clients/multi-resource.c2
-rw-r--r--clients/nested.c7
-rw-r--r--clients/scaler.c12
-rw-r--r--clients/simple-damage.c2
-rw-r--r--clients/simple-egl.c3
-rw-r--r--clients/simple-shm.c4
-rw-r--r--clients/subsurfaces.c4
-rw-r--r--clients/terminal.c11
-rw-r--r--clients/weston-simple-im.c22
-rw-r--r--clients/window.c124
-rw-r--r--clients/wscreensaver.c8
-rw-r--r--configure.ac18
-rw-r--r--desktop-shell/shell.c499
-rw-r--r--desktop-shell/shell.h8
-rw-r--r--man/weston.ini.man41
-rw-r--r--protocol/desktop-shell.xml25
-rw-r--r--protocol/scaler.xml2
-rw-r--r--protocol/xdg-shell.xml2
-rw-r--r--shared/cairo-util.c8
-rw-r--r--shared/cairo-util.h9
-rw-r--r--shared/config-parser.c12
-rw-r--r--shared/config-parser.h3
-rw-r--r--shared/frame.c33
-rw-r--r--shared/image-loader.c14
-rw-r--r--shared/option-parser.c97
-rw-r--r--src/compositor-drm.c2
-rw-r--r--src/compositor-wayland.c11
-rw-r--r--src/compositor-x11.c7
-rw-r--r--src/compositor.c216
-rw-r--r--src/compositor.h16
-rw-r--r--src/input.c143
-rw-r--r--src/libinput-device.c117
-rw-r--r--src/libinput-seat.c16
-rw-r--r--src/pixman-renderer.c9
-rw-r--r--src/screen-share.c11
-rw-r--r--src/screenshooter.c12
-rw-r--r--src/text-backend.c9
-rw-r--r--src/vertex-clipping.c12
-rw-r--r--src/weston-egl-ext.h8
-rw-r--r--tests/matrix-test.c4
-rw-r--r--tests/weston-test.c5
-rwxr-xr-xtests/weston-tests-env2
-rw-r--r--xwayland/launcher.c6
-rw-r--r--xwayland/window-manager.c24
54 files changed, 1409 insertions, 733 deletions
diff --git a/.gitignore b/.gitignore
index f9a6a7b3..fbffaa5b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ weston-scaler
weston-simple-egl
weston-simple-shm
weston-simple-touch
+weston-simple-damage
weston-smoke
weston-stacking
weston-subsurfaces
diff --git a/Makefile.am b/Makefile.am
index 191dcc9e..b2d68935 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,8 @@ module_LTLIBRARIES =
noinst_LTLIBRARIES =
BUILT_SOURCES =
-DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install
+# Do not run xwayland test while it is known broken.
+AM_DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install --disable-xwayland-test
EXTRA_DIST = weston.ini.in
@@ -476,7 +477,10 @@ weston_image_SOURCES = clients/image.c
weston_image_LDADD = libtoytoolkit.la
weston_image_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
-weston_cliptest_SOURCES = clients/cliptest.c
+weston_cliptest_SOURCES = \
+ clients/cliptest.c \
+ src/vertex-clipping.c \
+ src/vertex-clipping.h
weston_cliptest_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
weston_cliptest_LDADD = libtoytoolkit.la
diff --git a/clients/clickdot.c b/clients/clickdot.c
index e09cb142..5137ba66 100644
--- a/clients/clickdot.c
+++ b/clients/clickdot.c
@@ -31,6 +31,9 @@
#include <cairo.h>
#include <math.h>
#include <assert.h>
+#include <sys/timerfd.h>
+#include <sys/epoll.h>
+#include <unistd.h>
#include <linux/input.h>
#include <wayland-client.h>
@@ -54,6 +57,10 @@ struct clickdot {
} line;
int reset;
+
+ struct input *cursor_timeout_input;
+ int cursor_timeout_fd;
+ struct task cursor_timeout_task;
};
static void
@@ -211,6 +218,19 @@ button_handler(struct widget *widget,
widget_schedule_redraw(widget);
}
+static void
+cursor_timeout_reset(struct clickdot *clickdot)
+{
+ const long cursor_timeout = 500;
+ struct itimerspec its;
+
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = cursor_timeout / 1000;
+ its.it_value.tv_nsec = (cursor_timeout % 1000) * 1000 * 1000;
+ timerfd_settime(clickdot->cursor_timeout_fd, 0, &its, NULL);
+}
+
static int
motion_handler(struct widget *widget,
struct input *input, uint32_t time,
@@ -222,7 +242,10 @@ motion_handler(struct widget *widget,
window_schedule_redraw(clickdot->window);
- return CURSOR_LEFT_PTR;
+ cursor_timeout_reset(clickdot);
+ clickdot->cursor_timeout_input = input;
+
+ return CURSOR_BLANK;
}
static void
@@ -244,6 +267,21 @@ leave_handler(struct widget *widget,
clickdot->reset = 1;
}
+static void
+cursor_timeout_func(struct task *task, uint32_t events)
+{
+ struct clickdot *clickdot =
+ container_of(task, struct clickdot, cursor_timeout_task);
+ uint64_t exp;
+
+ if (read(clickdot->cursor_timeout_fd, &exp, sizeof (uint64_t)) !=
+ sizeof(uint64_t))
+ abort();
+
+ input_set_pointer_image(clickdot->cursor_timeout_input,
+ CURSOR_LEFT_PTR);
+}
+
static struct clickdot *
clickdot_create(struct display *display)
{
@@ -276,12 +314,22 @@ clickdot_create(struct display *display)
clickdot->line.old_y = -1;
clickdot->reset = 0;
+ clickdot->cursor_timeout_fd =
+ timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+ clickdot->cursor_timeout_task.run = cursor_timeout_func;
+ display_watch_fd(window_get_display(clickdot->window),
+ clickdot->cursor_timeout_fd,
+ EPOLLIN, &clickdot->cursor_timeout_task);
+
return clickdot;
}
static void
clickdot_destroy(struct clickdot *clickdot)
{
+ display_unwatch_fd(window_get_display(clickdot->window),
+ clickdot->cursor_timeout_fd);
+ close(clickdot->cursor_timeout_fd);
if (clickdot->buffer)
cairo_surface_destroy(clickdot->buffer);
widget_destroy(clickdot->widget);
diff --git a/clients/cliptest.c b/clients/cliptest.c
index a1928f40..f8e5dd15 100644
--- a/clients/cliptest.c
+++ b/clients/cliptest.c
@@ -21,8 +21,7 @@
* OF THIS SOFTWARE.
*/
-/* cliptest: for debugging calculate_edges() function, which is copied
- * from compositor.c.
+/* cliptest: for debugging calculate_edges() function.
* controls:
* clip box position: mouse left drag, keys: w a s d
* clip box size: mouse right drag, keys: i j k l
@@ -49,6 +48,7 @@
#include <linux/input.h>
#include <wayland-client.h>
+#include "src/vertex-clipping.h"
#include "window.h"
typedef float GLfloat;
@@ -62,7 +62,7 @@ struct geometry {
float phi;
};
-struct weston_surface {
+struct weston_view {
struct {
int enabled;
} transform;
@@ -71,10 +71,10 @@ struct weston_surface {
};
static void
-weston_surface_to_global_float(struct weston_surface *surface,
- GLfloat sx, GLfloat sy, GLfloat *x, GLfloat *y)
+weston_view_to_global_float(struct weston_view *view,
+ float sx, float sy, float *x, float *y)
{
- struct geometry *g = surface->geometry;
+ struct geometry *g = view->geometry;
/* pure rotation around origin by sine and cosine */
*x = g->c * sx + g->s * sy;
@@ -82,271 +82,10 @@ weston_surface_to_global_float(struct weston_surface *surface,
}
/* ---------------------- copied begins -----------------------*/
-
-struct polygon8 {
- GLfloat x[8];
- GLfloat y[8];
- int n;
-};
-
-struct clip_context {
- struct {
- GLfloat x;
- GLfloat y;
- } prev;
-
- struct {
- GLfloat x1, y1;
- GLfloat x2, y2;
- } clip;
-
- struct {
- GLfloat *x;
- GLfloat *y;
- } vertices;
-};
-
-static GLfloat
-float_difference(GLfloat a, GLfloat b)
-{
- /* http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/ */
- static const GLfloat max_diff = 4.0f * FLT_MIN;
- static const GLfloat max_rel_diff = 4.0e-5;
- GLfloat diff = a - b;
- GLfloat adiff = fabsf(diff);
-
- if (adiff <= max_diff)
- return 0.0f;
-
- a = fabsf(a);
- b = fabsf(b);
- if (adiff <= (a > b ? a : b) * max_rel_diff)
- return 0.0f;
-
- return diff;
-}
-
-/* A line segment (p1x, p1y)-(p2x, p2y) intersects the line x = x_arg.
- * Compute the y coordinate of the intersection.
- */
-static GLfloat
-clip_intersect_y(GLfloat p1x, GLfloat p1y, GLfloat p2x, GLfloat p2y,
- GLfloat x_arg)
-{
- GLfloat a;
- GLfloat diff = float_difference(p1x, p2x);
-
- /* Practically vertical line segment, yet the end points have already
- * been determined to be on different sides of the line. Therefore
- * the line segment is part of the line and intersects everywhere.
- * Return the end point, so we use the whole line segment.
- */
- if (diff == 0.0f)
- return p2y;
-
- a = (x_arg - p2x) / diff;
- return p2y + (p1y - p2y) * a;
-}
-
-/* A line segment (p1x, p1y)-(p2x, p2y) intersects the line y = y_arg.
- * Compute the x coordinate of the intersection.
- */
-static GLfloat
-clip_intersect_x(GLfloat p1x, GLfloat p1y, GLfloat p2x, GLfloat p2y,
- GLfloat y_arg)
-{
- GLfloat a;
- GLfloat diff = float_difference(p1y, p2y);
-
- /* Practically horizontal line segment, yet the end points have already
- * been determined to be on different sides of the line. Therefore
- * the line segment is part of the line and intersects everywhere.
- * Return the end point, so we use the whole line segment.
- */
- if (diff == 0.0f)
- return p2x;
-
- a = (y_arg - p2y) / diff;
- return p2x + (p1x - p2x) * a;
-}
-
-enum path_transition {
- PATH_TRANSITION_OUT_TO_OUT = 0,
- PATH_TRANSITION_OUT_TO_IN = 1,
- PATH_TRANSITION_IN_TO_OUT = 2,
- PATH_TRANSITION_IN_TO_IN = 3,
-};
-
-static void
-clip_append_vertex(struct clip_context *ctx, GLfloat x, GLfloat y)
-{
- *ctx->vertices.x++ = x;
- *ctx->vertices.y++ = y;
-}
-
-static enum path_transition
-path_transition_left_edge(struct clip_context *ctx, GLfloat x, GLfloat y)
-{
- return ((ctx->prev.x >= ctx->clip.x1) << 1) | (x >= ctx->clip.x1);
-}
-
-static enum path_transition
-path_transition_right_edge(struct clip_context *ctx, GLfloat x, GLfloat y)
-{
- return ((ctx->prev.x < ctx->clip.x2) << 1) | (x < ctx->clip.x2);
-}
-
-static enum path_transition
-path_transition_top_edge(struct clip_context *ctx, GLfloat x, GLfloat y)
-{
- return ((ctx->prev.y >= ctx->clip.y1) << 1) | (y >= ctx->clip.y1);
-}
-
-static enum path_transition
-path_transition_bottom_edge(struct clip_context *ctx, GLfloat x, GLfloat y)
-{
- return ((ctx->prev.y < ctx->clip.y2) << 1) | (y < ctx->clip.y2);
-}
-
-static void
-clip_polygon_leftright(struct clip_context *ctx,
- enum path_transition transition,
- GLfloat x, GLfloat y, GLfloat clip_x)
-{
- GLfloat yi;
-
- switch (transition) {
- case PATH_TRANSITION_IN_TO_IN:
- clip_append_vertex(ctx, x, y);
- break;
- case PATH_TRANSITION_IN_TO_OUT:
- yi = clip_intersect_y(ctx->prev.x, ctx->prev.y, x, y, clip_x);
- clip_append_vertex(ctx, clip_x, yi);
- break;
- case PATH_TRANSITION_OUT_TO_IN:
- yi = clip_intersect_y(ctx->prev.x, ctx->prev.y, x, y, clip_x);
- clip_append_vertex(ctx, clip_x, yi);
- clip_append_vertex(ctx, x, y);
- break;
- case PATH_TRANSITION_OUT_TO_OUT:
- /* nothing */
- break;
- default:
- assert(0 && "bad enum path_transition");
- }
-
- ctx->prev.x = x;
- ctx->prev.y = y;
-}
-
-static void
-clip_polygon_topbottom(struct clip_context *ctx,
- enum path_transition transition,
- GLfloat x, GLfloat y, GLfloat clip_y)
-{
- GLfloat xi;
-
- switch (transition) {
- case PATH_TRANSITION_IN_TO_IN:
- clip_append_vertex(ctx, x, y);
- break;
- case PATH_TRANSITION_IN_TO_OUT:
- xi = clip_intersect_x(ctx->prev.x, ctx->prev.y, x, y, clip_y);
- clip_append_vertex(ctx, xi, clip_y);
- break;
- case PATH_TRANSITION_OUT_TO_IN:
- xi = clip_intersect_x(ctx->prev.x, ctx->prev.y, x, y, clip_y);
- clip_append_vertex(ctx, xi, clip_y);
- clip_append_vertex(ctx, x, y);
- break;
- case PATH_TRANSITION_OUT_TO_OUT:
- /* nothing */
- break;
- default:
- assert(0 && "bad enum path_transition");
- }
-
- ctx->prev.x = x;
- ctx->prev.y = y;
-}
-
-static void
-clip_context_prepare(struct clip_context *ctx, const struct polygon8 *src,
- GLfloat *dst_x, GLfloat *dst_y)
-{
- ctx->prev.x = src->x[src->n - 1];
- ctx->prev.y = src->y[src->n - 1];
- ctx->vertices.x = dst_x;
- ctx->vertices.y = dst_y;
-}
-
-static int
-clip_polygon_left(struct clip_context *ctx, const struct polygon8 *src,
- GLfloat *dst_x, GLfloat *dst_y)
-{
- enum path_transition trans;
- int i;
-
- clip_context_prepare(ctx, src, dst_x, dst_y);
- for (i = 0; i < src->n; i++) {
- trans = path_transition_left_edge(ctx, src->x[i], src->y[i]);
- clip_polygon_leftright(ctx, trans, src->x[i], src->y[i],
- ctx->clip.x1);
- }
- return ctx->vertices.x - dst_x;
-}
-
-static int
-clip_polygon_right(struct clip_context *ctx, const struct polygon8 *src,
- GLfloat *dst_x, GLfloat *dst_y)
-{
- enum path_transition trans;
- int i;
-
- clip_context_prepare(ctx, src, dst_x, dst_y);
- for (i = 0; i < src->n; i++) {
- trans = path_transition_right_edge(ctx, src->x[i], src->y[i]);
- clip_polygon_leftright(ctx, trans, src->x[i], src->y[i],
- ctx->clip.x2);
- }
- return ctx->vertices.x - dst_x;
-}
-
-static int
-clip_polygon_top(struct clip_context *ctx, const struct polygon8 *src,
- GLfloat *dst_x, GLfloat *dst_y)
-{
- enum path_transition trans;
- int i;
-
- clip_context_prepare(ctx, src, dst_x, dst_y);
- for (i = 0; i < src->n; i++) {
- trans = path_transition_top_edge(ctx, src->x[i], src->y[i]);
- clip_polygon_topbottom(ctx, trans, src->x[i], src->y[i],
- ctx->clip.y1);
- }
- return ctx->vertices.x - dst_x;
-}
-
-static int
-clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src,
- GLfloat *dst_x, GLfloat *dst_y)
-{
- enum path_transition trans;
- int i;
-
- clip_context_prepare(ctx, src, dst_x, dst_y);
- for (i = 0; i < src->n; i++) {
- trans = path_transition_bottom_edge(ctx, src->x[i], src->y[i]);
- clip_polygon_topbottom(ctx, trans, src->x[i], src->y[i],
- ctx->clip.y2);
- }
- return ctx->vertices.x - dst_x;
-}
+/* Keep this in sync with what is in gl-renderer.c! */
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) > (b)) ? (b) : (a))
-#define clip(x, a, b) min(max(x, a), b)
/*
* Compute the boundary vertices of the intersection of the global coordinate
@@ -358,10 +97,10 @@ clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src,
* polygon area.
*/
static int
-calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
+calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
pixman_box32_t *surf_rect, GLfloat *ex, GLfloat *ey)
{
- struct polygon8 polygon;
+
struct clip_context ctx;
int i, n;
GLfloat min_x, max_x, min_y, max_y;
@@ -378,8 +117,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
/* transform surface to screen space: */
for (i = 0; i < surf.n; i++)
- weston_surface_to_global_float(es, surf.x[i], surf.y[i],
- &surf.x[i], &surf.y[i]);
+ weston_view_to_global_float(ev, surf.x[i], surf.y[i],
+ &surf.x[i], &surf.y[i]);
/* find bounding box: */
min_x = max_x = surf.x[0];
@@ -403,13 +142,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
* there will be only four edges. We just need to clip the surface
* vertices to the clip rect bounds:
*/
- if (!es->transform.enabled) {
- for (i = 0; i < surf.n; i++) {
- ex[i] = clip(surf.x[i], ctx.clip.x1, ctx.clip.x2);
- ey[i] = clip(surf.y[i], ctx.clip.y1, ctx.clip.y2);
- }
- return surf.n;
- }
+ if (!ev->transform.enabled)
+ return clip_simple(&ctx, &surf, ex, ey);
/* Transformed case: use a general polygon clipping algorithm to
* clip the surface rectangle with each side of 'rect'.
@@ -417,26 +151,7 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
* http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm
* but without looking at any of that code.
*/
- polygon.n = clip_polygon_left(&ctx, &surf, polygon.x, polygon.y);
- surf.n = clip_polygon_right(&ctx, &polygon, surf.x, surf.y);
- polygon.n = clip_polygon_top(&ctx, &surf, polygon.x, polygon.y);
- surf.n = clip_polygon_bottom(&ctx, &polygon, surf.x, surf.y);
-
- /* Get rid of duplicate vertices */
- ex[0] = surf.x[0];
- ey[0] = surf.y[0];
- n = 1;
- for (i = 1; i < surf.n; i++) {
- if (float_difference(ex[n - 1], surf.x[i]) == 0.0f &&
- float_difference(ey[n - 1], surf.y[i]) == 0.0f)
- continue;
- ex[n] = surf.x[i];
- ey[n] = surf.y[i];
- n++;
- }
- if (float_difference(ex[n - 1], surf.x[0]) == 0.0f &&
- float_difference(ey[n - 1], surf.y[0]) == 0.0f)
- n--;
+ n = clip_transformed(&ctx, &surf, ex, ey);
if (n < 3)
return 0;
@@ -488,7 +203,7 @@ struct cliptest {
struct ui_state ui;
struct geometry geometry;
- struct weston_surface surface;
+ struct weston_view view;
};
static void
@@ -531,15 +246,15 @@ draw_coordinates(cairo_t *cr, double ox, double oy, GLfloat *x, GLfloat *y, int
}
static void
-draw_box(cairo_t *cr, pixman_box32_t *box, struct weston_surface *surface)
+draw_box(cairo_t *cr, pixman_box32_t *box, struct weston_view *view)
{
GLfloat x[4], y[4];
- if (surface) {
- weston_surface_to_global_float(surface, box->x1, box->y1, &x[0], &y[0]);
- weston_surface_to_global_float(surface, box->x2, box->y1, &x[1], &y[1]);
- weston_surface_to_global_float(surface, box->x2, box->y2, &x[2], &y[2]);
- weston_surface_to_global_float(surface, box->x1, box->y2, &x[3], &y[3]);
+ if (view) {
+ weston_view_to_global_float(view, box->x1, box->y1, &x[0], &y[0]);
+ weston_view_to_global_float(view, box->x2, box->y1, &x[1], &y[1]);
+ weston_view_to_global_float(view, box->x2, box->y2, &x[2], &y[2]);
+ weston_view_to_global_float(view, box->x1, box->y2, &x[3], &y[3]);
} else {
x[0] = box->x1; y[0] = box->y1;
x[1] = box->x2; y[1] = box->y1;
@@ -551,18 +266,18 @@ draw_box(cairo_t *cr, pixman_box32_t *box, struct weston_surface *surface)
}
static void
-draw_geometry(cairo_t *cr, struct weston_surface *surface,
+draw_geometry(cairo_t *cr, struct weston_view *view,
GLfloat *ex, GLfloat *ey, int n)
{
- struct geometry *g = surface->geometry;
- GLfloat cx, cy;
+ struct geometry *g = view->geometry;
+ float cx, cy;
- draw_box(cr, &g->surf, surface);
+ draw_box(cr, &g->surf, view);
cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4);
cairo_fill(cr);
- weston_surface_to_global_float(surface, g->surf.x1 - 4, g->surf.y1 - 4, &cx, &cy);
+ weston_view_to_global_float(view, g->surf.x1 - 4, g->surf.y1 - 4, &cx, &cy);
cairo_arc(cr, cx, cy, 1.5, 0.0, 2.0 * M_PI);
- if (surface->transform.enabled == 0)
+ if (view->transform.enabled == 0)
cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.8);
cairo_fill(cr);
@@ -570,19 +285,21 @@ draw_geometry(cairo_t *cr, struct weston_surface *surface,
cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.4);
cairo_fill(cr);
- draw_polygon_closed(cr, ex, ey, n);
- cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
- cairo_stroke(cr);
+ if (n) {
+ draw_polygon_closed(cr, ex, ey, n);
+ cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
+ cairo_stroke(cr);
- cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.5);
- draw_polygon_labels(cr, ex, ey, n);
+ cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.5);
+ draw_polygon_labels(cr, ex, ey, n);
+ }
}
static void
redraw_handler(struct widget *widget, void *data)
{
struct cliptest *cliptest = data;
- struct geometry *g = cliptest->surface.geometry;
+ struct geometry *g = cliptest->view.geometry;
struct rectangle allocation;
cairo_t *cr;
cairo_surface_t *surface;
@@ -590,7 +307,7 @@ redraw_handler(struct widget *widget, void *data)
GLfloat ey[8];
int n;
- n = calculate_edges(&cliptest->surface, &g->clip, &g->surf, ex, ey);
+ n = calculate_edges(&cliptest->view, &g->clip, &g->surf, ex, ey);
widget_get_allocation(cliptest->widget, &allocation);
@@ -624,7 +341,7 @@ redraw_handler(struct widget *widget, void *data)
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 5.0);
- draw_geometry(cr, &cliptest->surface, ex, ey, n);
+ draw_geometry(cr, &cliptest->view, ex, ey, n);
cairo_pop_group_to_source(cr);
cairo_paint(cr);
@@ -703,7 +420,7 @@ axis_handler(struct widget *widget, struct input *input, uint32_t time,
geometry_set_phi(geom, geom->phi +
(M_PI / 12.0) * wl_fixed_to_double(value));
- cliptest->surface.transform.enabled = 1;
+ cliptest->view.transform.enabled = 1;
widget_schedule_redraw(cliptest->widget);
}
@@ -753,15 +470,15 @@ key_handler(struct window *window, struct input *input, uint32_t time,
break;
case XKB_KEY_n:
geometry_set_phi(g, g->phi + (M_PI / 24.0));
- cliptest->surface.transform.enabled = 1;
+ cliptest->view.transform.enabled = 1;
break;
case XKB_KEY_m:
geometry_set_phi(g, g->phi - (M_PI / 24.0));
- cliptest->surface.transform.enabled = 1;
+ cliptest->view.transform.enabled = 1;
break;
case XKB_KEY_r:
geometry_set_phi(g, 0.0);
- cliptest->surface.transform.enabled = 0;
+ cliptest->view.transform.enabled = 0;
break;
default:
return;
@@ -794,8 +511,8 @@ cliptest_create(struct display *display)
struct cliptest *cliptest;
cliptest = xzalloc(sizeof *cliptest);
- cliptest->surface.geometry = &cliptest->geometry;
- cliptest->surface.transform.enabled = 0;
+ cliptest->view.geometry = &cliptest->geometry;
+ cliptest->view.transform.enabled = 0;
geometry_init(&cliptest->geometry);
geometry_init(&cliptest->ui.geometry);
@@ -845,7 +562,7 @@ read_timer(void)
static int
benchmark(void)
{
- struct weston_surface surface;
+ struct weston_view view;
struct geometry geom;
GLfloat ex[8], ey[8];
int i;
@@ -864,13 +581,13 @@ benchmark(void)
geometry_set_phi(&geom, 0.0);
- surface.transform.enabled = 1;
- surface.geometry = &geom;
+ view.transform.enabled = 1;
+ view.geometry = &geom;
reset_timer();
for (i = 0; i < N; i++) {
geometry_set_phi(&geom, (float)i / 360.0f);
- calculate_edges(&surface, &geom.clip, &geom.surf, ex, ey);
+ calculate_edges(&view, &geom.clip, &geom.surf, ex, ey);
}
t = read_timer();
@@ -893,8 +610,12 @@ main(int argc, char *argv[])
struct display *d;
struct cliptest *cliptest;
- if (argc > 1)
- return benchmark();
+ if (argc > 1) {
+ if (argc == 2 && !strcmp(argv[1], "-b"))
+ return benchmark();
+ printf("Usage: %s [OPTIONS]\n -b run benchmark\n", argv[0]);
+ return 1;
+ }
d = display_create(&argc, argv);
if (d == NULL) {
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index db4a1fd7..961a9b24 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -695,8 +695,6 @@ background_draw(struct widget *widget, void *data)
double sx, sy, s;
double tx, ty;
struct rectangle allocation;
- struct display *display;
- struct wl_region *opaque;
surface = window_get_surface(background->window);
@@ -752,13 +750,6 @@ background_draw(struct widget *widget, void *data)
cairo_destroy(cr);
cairo_surface_destroy(surface);
- display = window_get_display(background->window);
- opaque = wl_compositor_create_region(display_get_compositor(display));
- wl_region_add(opaque, allocation.x, allocation.y,
- allocation.width, allocation.height);
- wl_surface_set_opaque_region(window_get_wl_surface(background->window), opaque);
- wl_region_destroy(opaque);
-
background->painted = 1;
check_desktop_ready(background->window);
}
@@ -1056,6 +1047,7 @@ background_create(struct desktop *desktop)
background->widget = window_add_widget(background->window, background);
window_set_user_data(background->window, background);
widget_set_redraw_handler(background->widget, background_draw);
+ widget_set_transparent(background->widget, 0);
window_set_preferred_format(background->window,
WINDOW_PREFERRED_FORMAT_RGB565);
diff --git a/clients/dnd.c b/clients/dnd.c
index 620cfff2..956c3064 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -652,7 +652,14 @@ main(int argc, char *argv[])
{
struct display *d;
struct dnd *dnd;
- int i;
+ int self_only = 0;
+
+ if (argc == 2 && !strcmp(argv[1], "--self-only"))
+ self_only = 1;
+ else if (argc > 1) {
+ printf("Usage: %s [OPTIONS]\n --self-only\n", argv[0]);
+ return 1;
+ }
d = display_create(&argc, argv);
if (d == NULL) {
@@ -661,10 +668,8 @@ main(int argc, char *argv[])
}
dnd = dnd_create(d);
-
- for (i = 1; i < argc; i++)
- if (strcmp("--self-only", argv[i]) == 0)
- dnd->self_only = 1;
+ if (self_only)
+ dnd->self_only = 1;
display_run(d);
diff --git a/clients/editor.c b/clients/editor.c
index 08d12036..421f8fed 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -1331,11 +1331,16 @@ main(int argc, char *argv[])
for (i = 1; i < argc; i++) {
if (strcmp("--click-to-show", argv[i]) == 0)
click_to_show = 1;
- else if (strcmp("--preferred-language", argv[i]) == 0) {
- if (i + 1 < argc) {
- preferred_language = argv[i + 1];
- i++;
- }
+ else if (strcmp("--preferred-language", argv[i]) == 0 &&
+ i + 1 < argc) {
+ preferred_language = argv[i + 1];
+ i++;
+ } else {
+ printf("Usage: %s [OPTIONS]\n"
+ " --click-to-show\n"
+ " --preferred-language LANGUAGE\n",
+ argv[0]);
+ return 1;
}
}
@@ -1354,6 +1359,11 @@ main(int argc, char *argv[])
display_set_user_data(editor.display, &editor);
display_set_global_handler(editor.display, global_handler);
+ if (editor.text_input_manager == NULL) {
+ fprintf(stderr, "No text input manager global\n");
+ return -1;
+ }
+
editor.window = window_create(editor.display);
editor.widget = window_frame_create(editor.window, &editor);
diff --git a/clients/eventdemo.c b/clients/eventdemo.c
index 5ec68296..50a9cb42 100644
--- a/clients/eventdemo.c
+++ b/clients/eventdemo.c
@@ -373,13 +373,13 @@ static const struct weston_option eventdemo_options[] = {
{ WESTON_OPTION_INTEGER, "max-width", 0, &width_max },
{ WESTON_OPTION_INTEGER, "max-height", 0, &height_max },
{ WESTON_OPTION_BOOLEAN, "no-border", 'b', &noborder },
- { WESTON_OPTION_BOOLEAN, "log-redraw", '0', &log_redraw },
- { WESTON_OPTION_BOOLEAN, "log-resize", '0', &log_resize },
- { WESTON_OPTION_BOOLEAN, "log-focus", '0', &log_focus },
- { WESTON_OPTION_BOOLEAN, "log-key", '0', &log_key },
- { WESTON_OPTION_BOOLEAN, "log-button", '0', &log_button },
- { WESTON_OPTION_BOOLEAN, "log-axis", '0', &log_axis },
- { WESTON_OPTION_BOOLEAN, "log-motion", '0', &log_motion },
+ { WESTON_OPTION_BOOLEAN, "log-redraw", 0, &log_redraw },
+ { WESTON_OPTION_BOOLEAN, "log-resize", 0, &log_resize },
+ { WESTON_OPTION_BOOLEAN, "log-focus", 0, &log_focus },
+ { WESTON_OPTION_BOOLEAN, "log-key", 0, &log_key },
+ { WESTON_OPTION_BOOLEAN, "log-button", 0, &log_button },
+ { WESTON_OPTION_BOOLEAN, "log-axis", 0, &log_axis },
+ { WESTON_OPTION_BOOLEAN, "log-motion", 0, &log_motion },
};
/**
@@ -392,8 +392,32 @@ main(int argc, char *argv[])
struct display *d;
struct eventdemo *e;
- parse_options(eventdemo_options,
- ARRAY_LENGTH(eventdemo_options), &argc, argv);
+ if (parse_options(eventdemo_options,
+ ARRAY_LENGTH(eventdemo_options), &argc, argv) > 1) {
+ unsigned k;
+ printf("Usage: %s [OPTIONS]\n\n", argv[0]);
+ for (k = 0; k < ARRAY_LENGTH(eventdemo_options); k++) {
+ const struct weston_option* p = &eventdemo_options[k];
+ if (p->name) {
+ printf(" --%s", p->name);
+ if (p->type != WESTON_OPTION_BOOLEAN)
+ printf("=VALUE");
+ putchar('\n');
+ }
+ if (p->short_name) {
+ printf(" -%c", p->short_name);
+ if (p->type != WESTON_OPTION_BOOLEAN)
+ printf("VALUE");
+ putchar('\n');
+ }
+ }
+ return 1;
+ }
+
+ if (!log_redraw && !log_resize && !log_focus && !log_key &&
+ !log_button && !log_axis && !log_motion)
+ log_redraw = log_resize = log_focus = log_key =
+ log_button = log_axis = log_motion = 1;
/* Connect to the display and have the arguments parsed */
d = display_create(&argc, argv);
diff --git a/clients/image.c b/clients/image.c
index 112b93d9..aee81122 100644
--- a/clients/image.c
+++ b/clients/image.c
@@ -373,7 +373,6 @@ image_create(struct display *display, const char *filename,
image->image = load_cairo_surface(filename);
if (!image->image) {
- fprintf(stderr, "could not find the image %s!\n", b);
free(image->filename);
free(image);
return NULL;
@@ -412,6 +411,11 @@ main(int argc, char *argv[])
int i;
int image_counter = 0;
+ if (argc <= 1 || argv[1][0]=='-') {
+ printf("Usage: %s image...\n", argv[0]);
+ return 1;
+ }
+
d = display_create(&argc, argv);
if (d == NULL) {
fprintf(stderr, "failed to create display: %m\n");
diff --git a/clients/keyboard.c b/clients/keyboard.c
index 7c11cec5..2579571e 100644
--- a/clients/keyboard.c
+++ b/clients/keyboard.c
@@ -995,6 +995,11 @@ main(int argc, char *argv[])
display_set_user_data(virtual_keyboard.display, &virtual_keyboard);
display_set_global_handler(virtual_keyboard.display, global_handler);
+ if (virtual_keyboard.input_panel == NULL) {
+ fprintf(stderr, "No input panel global\n");
+ return -1;
+ }
+
output = display_get_output(virtual_keyboard.display);
keyboard_create(output, &virtual_keyboard);
diff --git a/clients/multi-resource.c b/clients/multi-resource.c
index c4a0c18c..0dc2c74b 100644
--- a/clients/multi-resource.c
+++ b/clients/multi-resource.c
@@ -258,8 +258,6 @@ create_display(void)
exit(1);
}
- wl_display_get_fd(display->display);
-
wl_list_init(&display->devices);
return display;
diff --git a/clients/nested.c b/clients/nested.c
index 2a952beb..f0942378 100644
--- a/clients/nested.c
+++ b/clients/nested.c
@@ -1115,8 +1115,11 @@ main(int argc, char *argv[])
struct display *display;
struct nested *nested;
- parse_options(nested_options,
- ARRAY_LENGTH(nested_options), &argc, argv);
+ if (parse_options(nested_options,
+ ARRAY_LENGTH(nested_options), &argc, argv) > 1) {
+ printf("Usage: %s [OPTIONS]\n --blit or -b\n", argv[0]);
+ exit(1);
+ }
display = display_create(&argc, argv);
if (display == NULL) {
diff --git a/clients/scaler.c b/clients/scaler.c
index 39390220..f6d45c73 100644
--- a/clients/scaler.c
+++ b/clients/scaler.c
@@ -274,12 +274,6 @@ main(int argc, char *argv[])
struct timeval tv;
int i;
- d = display_create(&argc, argv);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
box.mode = MODE_SRC_DST;
for (i = 1; i < argc; i++) {
@@ -297,6 +291,12 @@ main(int argc, char *argv[])
}
}
+ d = display_create(&argc, argv);
+ if (d == NULL) {
+ fprintf(stderr, "failed to create display: %m\n");
+ return -1;
+ }
+
gettimeofday(&tv, NULL);
srandom(tv.tv_usec);
diff --git a/clients/simple-damage.c b/clients/simple-damage.c
index d7a7c700..fe532fe2 100644
--- a/clients/simple-damage.c
+++ b/clients/simple-damage.c
@@ -642,7 +642,7 @@ static const struct xdg_shell_listener xdg_shell_listener = {
xdg_shell_ping,
};
-#define XDG_VERSION 3 /* The version of xdg-shell that we implement */
+#define XDG_VERSION 4 /* The version of xdg-shell that we implement */
#ifdef static_assert
static_assert(XDG_VERSION == XDG_SHELL_VERSION_CURRENT,
"Interface version doesn't match implementation version");
diff --git a/clients/simple-egl.c b/clients/simple-egl.c
index f23fb8c5..33e711c5 100644
--- a/clients/simple-egl.c
+++ b/clients/simple-egl.c
@@ -133,6 +133,7 @@ init_egl(struct display *display, struct window *window)
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
@@ -670,7 +671,7 @@ static const struct xdg_shell_listener xdg_shell_listener = {
xdg_shell_ping,
};
-#define XDG_VERSION 3 /* The version of xdg-shell that we implement */
+#define XDG_VERSION 4 /* The version of xdg-shell that we implement */
#ifdef static_assert
static_assert(XDG_VERSION == XDG_SHELL_VERSION_CURRENT,
"Interface version doesn't match implementation version");
diff --git a/clients/simple-shm.c b/clients/simple-shm.c
index 29abb8bc..c1cb386c 100644
--- a/clients/simple-shm.c
+++ b/clients/simple-shm.c
@@ -321,7 +321,7 @@ static const struct xdg_shell_listener xdg_shell_listener = {
xdg_shell_ping,
};
-#define XDG_VERSION 3 /* The version of xdg-shell that we implement */
+#define XDG_VERSION 4 /* The version of xdg-shell that we implement */
#ifdef static_assert
static_assert(XDG_VERSION == XDG_SHELL_VERSION_CURRENT,
"Interface version doesn't match implementation version");
@@ -393,8 +393,6 @@ create_display(void)
exit(1);
}
- wl_display_get_fd(display->display);
-
return display;
}
diff --git a/clients/subsurfaces.c b/clients/subsurfaces.c
index 66a10f25..833030f0 100644
--- a/clients/subsurfaces.c
+++ b/clients/subsurfaces.c
@@ -775,8 +775,8 @@ main(int argc, char *argv[])
struct display *display;
struct demoapp *app;
- parse_options(options, ARRAY_LENGTH(options), &argc, argv);
- if (option_help) {
+ if (parse_options(options, ARRAY_LENGTH(options), &argc, argv) > 1
+ || option_help) {
printf(help_text, argv[0]);
return 0;
}
diff --git a/clients/terminal.c b/clients/terminal.c
index 0bacbe09..7c371016 100644
--- a/clients/terminal.c
+++ b/clients/terminal.c
@@ -3042,6 +3042,7 @@ terminal_run(struct terminal *terminal, const char *path)
static const struct weston_option terminal_options[] = {
{ WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &option_fullscreen },
{ WESTON_OPTION_STRING, "font", 0, &option_font },
+ { WESTON_OPTION_INTEGER, "font-size", 0, &option_font_size },
{ WESTON_OPTION_STRING, "shell", 0, &option_shell },
};
@@ -3067,6 +3068,16 @@ int main(int argc, char *argv[])
weston_config_section_get_string(s, "term", &option_term, "xterm");
weston_config_destroy(config);
+ if (parse_options(terminal_options,
+ ARRAY_LENGTH(terminal_options), &argc, argv) > 1) {
+ printf("Usage: %s [OPTIONS]\n"
+ " --fullscreen or -f\n"
+ " --font=NAME\n"
+ " --font-size=SIZE\n"
+ " --shell=NAME\n", argv[0]);
+ return 1;
+ }
+
d = display_create(&argc, argv);
if (d == NULL) {
fprintf(stderr, "failed to create display: %m\n");
diff --git a/clients/weston-simple-im.c b/clients/weston-simple-im.c
index ded6a04d..787782fe 100644
--- a/clients/weston-simple-im.c
+++ b/clients/weston-simple-im.c
@@ -187,10 +187,10 @@ input_method_keyboard_keymap(void *data,
}
keyboard->keymap =
- xkb_map_new_from_string(keyboard->xkb_context,
- map_str,
- XKB_KEYMAP_FORMAT_TEXT_V1,
- 0);
+ xkb_keymap_new_from_string(keyboard->xkb_context,
+ map_str,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ 0);
munmap(map_str, size);
close(fd);
@@ -203,16 +203,16 @@ input_method_keyboard_keymap(void *data,
keyboard->state = xkb_state_new(keyboard->keymap);
if (!keyboard->state) {
fprintf(stderr, "failed to create XKB state\n");
- xkb_map_unref(keyboard->keymap);
+ xkb_keymap_unref(keyboard->keymap);
return;
}
keyboard->control_mask =
- 1 << xkb_map_mod_get_index(keyboard->keymap, "Control");
+ 1 << xkb_keymap_mod_get_index(keyboard->keymap, "Control");
keyboard->alt_mask =
- 1 << xkb_map_mod_get_index(keyboard->keymap, "Mod1");
+ 1 << xkb_keymap_mod_get_index(keyboard->keymap, "Mod1");
keyboard->shift_mask =
- 1 << xkb_map_mod_get_index(keyboard->keymap, "Shift");
+ 1 << xkb_keymap_mod_get_index(keyboard->keymap, "Shift");
}
static void
@@ -234,7 +234,7 @@ input_method_keyboard_key(void *data,
return;
code = key + 8;
- num_syms = xkb_key_get_syms(keyboard->state, code, &syms);
+ num_syms = xkb_state_key_get_syms(keyboard->state, code, &syms);
sym = XKB_KEY_NoSymbol;
if (num_syms == 1)
@@ -261,8 +261,8 @@ input_method_keyboard_modifiers(void *data,
xkb_state_update_mask(keyboard->state, mods_depressed,
mods_latched, mods_locked, 0, 0, group);
mask = xkb_state_serialize_mods(keyboard->state,
- XKB_STATE_DEPRESSED |
- XKB_STATE_LATCHED);
+ XKB_STATE_MODS_DEPRESSED |
+ XKB_STATE_MODS_LATCHED);
keyboard->modifiers = 0;
if (mask & keyboard->control_mask)
diff --git a/clients/window.c b/clients/window.c
index a8bc2602..e44d65c9 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -217,6 +217,7 @@ struct window {
struct rectangle saved_allocation;
struct rectangle min_allocation;
struct rectangle pending_allocation;
+ struct rectangle last_geometry;
int x, y;
int redraw_needed;
int redraw_task_scheduled;
@@ -246,6 +247,7 @@ struct window {
struct xdg_popup *xdg_popup;
struct window *parent;
+ struct wl_surface *last_parent_surface;
struct window_frame *frame;
@@ -365,6 +367,9 @@ struct window_frame {
struct widget *widget;
struct widget *child;
struct frame *frame;
+
+ uint32_t last_time;
+ uint32_t did_double, double_click;
};
struct menu {
@@ -576,8 +581,8 @@ egl_window_surface_release(struct toysurface *base)
if (!device)
return;
- if (!eglMakeCurrent(surface->display->dpy, NULL, NULL,
- surface->display->argb_ctx))
+ if (!eglMakeCurrent(surface->display->dpy,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
fprintf(stderr, "failed to make context current\n");
cairo_device_release(device);
@@ -2233,19 +2238,61 @@ frame_get_pointer_image_for_location(struct window_frame *frame,
}
}
+static void
+frame_menu_func(void *data, struct input *input, int index)
+{
+ struct window *window = data;
+ struct display *display;
+
+ switch (index) {
+ case 0: /* close */
+ window_close(window);
+ break;
+ case 1: /* move to workspace above */
+ display = window->display;
+ if (display->workspace > 0)
+ workspace_manager_move_surface(
+ display->workspace_manager,
+ window->main_surface->surface,
+ display->workspace - 1);
+ break;
+ case 2: /* move to workspace below */
+ display = window->display;
+ if (display->workspace < display->workspace_count - 1)
+ workspace_manager_move_surface(
+ display->workspace_manager,
+ window->main_surface->surface,
+ display->workspace + 1);
+ break;
+ case 3: /* fullscreen */
+ /* we don't have a way to get out of fullscreen for now */
+ if (window->fullscreen_handler)
+ window->fullscreen_handler(window, window->user_data);
+ break;
+ }
+}
+
void
window_show_frame_menu(struct window *window,
struct input *input, uint32_t time)
{
int32_t x, y;
+ int count;
- if (window->xdg_surface) {
- input_get_position(input, &x, &y);
- xdg_surface_show_window_menu(window->xdg_surface,
- input_get_seat(input),
- window->display->serial,
- x - 10, y - 10);
- }
+ static const char *entries[] = {
+ "Close",
+ "Move to workspace above", "Move to workspace below",
+ "Fullscreen"
+ };
+
+ if (window->fullscreen_handler)
+ count = ARRAY_LENGTH(entries);
+ else
+ count = ARRAY_LENGTH(entries) - 1;
+
+ input_get_position(input, &x, &y);
+ window_show_menu(window->display, input, time, window,
+ x - 10, y - 10, frame_menu_func, entries, count);
}
static int
@@ -2340,6 +2387,7 @@ frame_handle_status(struct window_frame *frame, struct input *input,
}
}
+#define DOUBLE_CLICK_PERIOD 250
static void
frame_button_handler(struct widget *widget,
struct input *input, uint32_t time,
@@ -2350,7 +2398,27 @@ frame_button_handler(struct widget *widget,
struct window_frame *frame = data;
enum theme_location location;
- location = frame_pointer_button(frame->frame, input, button, state);
+ frame->double_click = 0;
+ if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
+ if (time - frame->last_time <= DOUBLE_CLICK_PERIOD) {
+ frame->double_click = 1;
+ frame->did_double = 1;
+ } else
+ frame->did_double = 0;
+
+ frame->last_time = time;
+ } else if (frame->did_double == 1) {
+ frame->double_click = 1;
+ frame->did_double = 0;
+ }
+
+ if (frame->double_click)
+ location = frame_double_click(frame->frame, input,
+ button, state);
+ else
+ location = frame_pointer_button(frame->frame, input,
+ button, state);
+
frame_handle_status(frame, input, time, location);
}
@@ -2749,10 +2817,10 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
return;
}
- keymap = xkb_map_new_from_string(input->display->xkb_context,
- map_str,
- XKB_KEYMAP_FORMAT_TEXT_V1,
- 0);
+ keymap = xkb_keymap_new_from_string(input->display->xkb_context,
+ map_str,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ 0);
munmap(map_str, size);
close(fd);
@@ -2764,7 +2832,7 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
state = xkb_state_new(keymap);
if (!state) {
fprintf(stderr, "failed to create XKB state\n");
- xkb_map_unref(keymap);
+ xkb_keymap_unref(keymap);
return;
}
@@ -2774,11 +2842,11 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
input->xkb.state = state;
input->xkb.control_mask =
- 1 << xkb_map_mod_get_index(input->xkb.keymap, "Control");
+ 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Control");
input->xkb.alt_mask =
- 1 << xkb_map_mod_get_index(input->xkb.keymap, "Mod1");
+ 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Mod1");
input->xkb.shift_mask =
- 1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift");
+ 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Shift");
}
static void
@@ -2834,7 +2902,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
if (input->grab && input->grab_button == 0)
return;
- num_syms = xkb_key_get_syms(input->xkb.state, code, &syms);
+ num_syms = xkb_state_key_get_syms(input->xkb.state, code, &syms);
sym = XKB_KEY_NoSymbol;
if (num_syms == 1)
@@ -2893,8 +2961,8 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);
mask = xkb_state_serialize_mods(input->xkb.state,
- XKB_STATE_DEPRESSED |
- XKB_STATE_LATCHED);
+ XKB_STATE_MODS_DEPRESSED |
+ XKB_STATE_MODS_LATCHED);
input->modifiers = 0;
if (mask & input->xkb.control_mask)
input->modifiers |= MOD_CONTROL_MASK;
@@ -3927,7 +3995,11 @@ window_sync_parent(struct window *window)
else
parent_surface = NULL;
+ if (parent_surface == window->last_parent_surface)
+ return;
+
xdg_surface_set_parent(window->xdg_surface, parent_surface);
+ window->last_parent_surface = parent_surface;
}
static void
@@ -3952,12 +4024,18 @@ window_sync_geometry(struct window *window)
return;
window_get_geometry(window, &geometry);
+ if (geometry.x == window->last_geometry.x &&
+ geometry.y == window->last_geometry.y &&
+ geometry.width == window->last_geometry.width &&
+ geometry.height == window->last_geometry.height)
+ return;
xdg_surface_set_window_geometry(window->xdg_surface,
geometry.x,
geometry.y,
geometry.width,
geometry.height);
+ window->last_geometry = geometry;
}
static void
@@ -4993,7 +5071,7 @@ static void
fini_xkb(struct input *input)
{
xkb_state_unref(input->xkb.state);
- xkb_map_unref(input->xkb.keymap);
+ xkb_keymap_unref(input->xkb.keymap);
}
#define MIN(a,b) ((a) < (b) ? a : b)
@@ -5103,7 +5181,7 @@ static const struct xdg_shell_listener xdg_shell_listener = {
xdg_shell_ping,
};
-#define XDG_VERSION 3 /* The version of xdg-shell that we implement */
+#define XDG_VERSION 4 /* The version of xdg-shell that we implement */
#ifdef static_assert
static_assert(XDG_VERSION == XDG_SHELL_VERSION_CURRENT,
"Interface version doesn't match implementation version");
diff --git a/clients/wscreensaver.c b/clients/wscreensaver.c
index 47f6c8a3..f75d0d8d 100644
--- a/clients/wscreensaver.c
+++ b/clients/wscreensaver.c
@@ -310,8 +310,12 @@ int main(int argc, char *argv[])
init_frand();
- parse_options(wscreensaver_options,
- ARRAY_LENGTH(wscreensaver_options), &argc, argv);
+ if (parse_options(wscreensaver_options,
+ ARRAY_LENGTH(wscreensaver_options), &argc, argv) > 1) {
+ printf("Usage: %s [OPTIONS]\n --demo for demo mode\n",
+ argv[0]);
+ exit(1);
+ }
d = display_create(&argc, argv);
if (d == NULL) {
diff --git a/configure.ac b/configure.ac
index 354db145..05e883da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
m4_define([weston_major_version], [1])
-m4_define([weston_minor_version], [5])
-m4_define([weston_micro_version], [90])
+m4_define([weston_minor_version], [6])
+m4_define([weston_micro_version], [0])
m4_define([weston_version],
[weston_major_version.weston_minor_version.weston_micro_version])
@@ -59,7 +59,7 @@ AC_CHECK_HEADERS([execinfo.h])
AC_CHECK_FUNCS([mkostemp strchrnul initgroups posix_fallocate])
-COMPOSITOR_MODULES="wayland-server >= 1.3.90 pixman-1 >= 0.25.2"
+COMPOSITOR_MODULES="wayland-server >= 1.5.91 pixman-1 >= 0.25.2"
AC_ARG_ENABLE(egl, [ --disable-egl],,
enable_egl=yes)
@@ -155,12 +155,12 @@ if test x$enable_drm_compositor = xyes; then
fi
-AC_ARG_ENABLE(libinput-backend, [ --enable-libinput-backend],,
- enable_libinput_backend=no)
+AC_ARG_ENABLE(libinput-backend, [ --disable-libinput-backend],,
+ enable_libinput_backend=yes)
AM_CONDITIONAL([ENABLE_LIBINPUT_BACKEND], [test x$enable_libinput_backend = xyes])
if test x$enable_libinput_backend = xyes; then
AC_DEFINE([BUILD_LIBINPUT_BACKEND], [1], [Build the libinput input device backend])
- PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.5.0])
+ PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.6.0])
fi
@@ -173,7 +173,7 @@ AM_CONDITIONAL(ENABLE_WAYLAND_COMPOSITOR,
if test x$enable_wayland_compositor = xyes -a x$enable_egl = xyes; then
AC_DEFINE([BUILD_WAYLAND_COMPOSITOR], [1],
[Build the Wayland (nested) compositor])
- PKG_CHECK_MODULES(WAYLAND_COMPOSITOR, [wayland-client wayland-egl wayland-cursor])
+ PKG_CHECK_MODULES(WAYLAND_COMPOSITOR, [wayland-client >= 1.5.91 wayland-egl wayland-cursor])
fi
@@ -323,9 +323,9 @@ AM_CONDITIONAL(BUILD_CLIENTS, test x$enable_clients = xyes)
if test x$enable_clients = xyes; then
AC_DEFINE([BUILD_CLIENTS], [1], [Build the Wayland clients])
- PKG_CHECK_MODULES(CLIENT, [wayland-client cairo >= 1.10.0 xkbcommon wayland-cursor])
+ PKG_CHECK_MODULES(CLIENT, [wayland-client >= 1.5.91 cairo >= 1.10.0 xkbcommon wayland-cursor])
PKG_CHECK_MODULES(SERVER, [wayland-server])
- PKG_CHECK_MODULES(WESTON_INFO, [wayland-client])
+ PKG_CHECK_MODULES(WESTON_INFO, [wayland-client >= 1.5.91])
# Only check for cairo-egl if a GL or GLES renderer requested
AS_IF([test "x$cairo_modules" = "xcairo-gl" -o "x$cairo_modules" = "xcairo-glesv2"], [
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index ec722874..3a5a702a 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -223,9 +223,11 @@ struct shell_seat {
struct {
struct weston_pointer_grab grab;
+ struct weston_touch_grab touch_grab;
struct wl_list surfaces_list;
struct wl_client *client;
int32_t initial_up;
+ enum { POINTER, TOUCH } type;
} popup_grab;
};
@@ -251,9 +253,10 @@ shell_fade_startup(struct desktop_shell *shell);
static struct shell_seat *
get_shell_seat(struct weston_seat *seat);
-static int
-get_output_panel_height(struct desktop_shell *shell,
- struct weston_output *output);
+static void
+get_output_panel_size(struct desktop_shell *shell,
+ struct weston_output *output,
+ int *width, int *height);
static void
shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
@@ -321,6 +324,8 @@ get_default_view(struct weston_surface *surface)
static void
popup_grab_end(struct weston_pointer *pointer);
+static void
+touch_popup_grab_end(struct weston_touch *touch);
static void
shell_grab_start(struct shell_grab *grab,
@@ -332,6 +337,8 @@ shell_grab_start(struct shell_grab *grab,
struct desktop_shell *shell = shsurf->shell;
popup_grab_end(pointer);
+ if (pointer->seat->touch)
+ touch_popup_grab_end(pointer->seat->touch);
grab->grab.interface = interface;
grab->shsurf = shsurf;
@@ -351,24 +358,85 @@ shell_grab_start(struct shell_grab *grab,
}
}
-static int
-get_output_panel_height(struct desktop_shell *shell,
- struct weston_output *output)
+static void
+get_output_panel_size(struct desktop_shell *shell,
+ struct weston_output *output,
+ int *width,
+ int *height)
{
struct weston_view *view;
- int panel_height = 0;
+
+ *width = 0;
+ *height = 0;
if (!output)
- return 0;
+ return;
wl_list_for_each(view, &shell->panel_layer.view_list.link, layer_link.link) {
- if (view->surface->output == output) {
- panel_height = view->surface->height;
+ float x, y;
+
+ if (view->surface->output != output)
+ continue;
+
+ switch (shell->panel_position) {
+ case DESKTOP_SHELL_PANEL_POSITION_TOP:
+ case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
+
+ weston_view_to_global_float(view,
+ view->surface->width, 0,
+ &x, &y);
+
+ *width = (int) x;
+ *height = view->surface->height + (int) y;
+ return;
+
+ case DESKTOP_SHELL_PANEL_POSITION_LEFT:
+ case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
+ weston_view_to_global_float(view,
+ 0, view->surface->height,
+ &x, &y);
+
+ *width = view->surface->width + (int) x;
+ *height = (int) y;
+ return;
+
+ default:
+ /* we've already set width and height to
+ * fallback values. */
break;
}
}
- return panel_height;
+ /* the correct view wasn't found */
+}
+
+static void
+get_output_work_area(struct desktop_shell *shell,
+ struct weston_output *output,
+ pixman_rectangle32_t *area)
+{
+ int32_t panel_width = 0, panel_height = 0;
+
+ area->x = 0;
+ area->y = 0;
+
+ get_output_panel_size(shell, output, &panel_width, &panel_height);
+
+ switch (shell->panel_position) {
+ case DESKTOP_SHELL_PANEL_POSITION_TOP:
+ default:
+ area->y = panel_height;
+ case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
+ area->width = output->width;
+ area->height = output->height - panel_height;
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_LEFT:
+ area->x = panel_width;
+ case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
+ area->width = output->width - panel_width;
+ area->height = output->height;
+ break;
+ }
}
static void
@@ -389,13 +457,13 @@ send_configure_for_surface(struct shell_surface *shsurf)
height = shsurf->output->height;
} else if (state->maximized) {
struct desktop_shell *shell;
- uint32_t panel_height = 0;
+ pixman_rectangle32_t area;
shell = shell_surface_get_shell(shsurf);
- panel_height = get_output_panel_height(shell, shsurf->output);
+ get_output_work_area(shell, shsurf->output, &area);
- width = shsurf->output->width;
- height = shsurf->output->height - panel_height;
+ width = area.width;
+ height = area.height;
} else {
width = 0;
height = 0;
@@ -435,6 +503,7 @@ shell_touch_grab_start(struct shell_touch_grab *grab,
{
struct desktop_shell *shell = shsurf->shell;
+ touch_popup_grab_end(touch);
if (touch->seat->pointer)
popup_grab_end(touch->seat->pointer);
@@ -505,7 +574,8 @@ shell_configuration(struct desktop_shell *shell)
{
struct weston_config_section *section;
int duration;
- char *s;
+ char *s, *client;
+ int ret;
section = weston_config_get_section(shell->compositor->config,
"screensaver", NULL, NULL);
@@ -516,8 +586,13 @@ shell_configuration(struct desktop_shell *shell)
section = weston_config_get_section(shell->compositor->config,
"shell", NULL, NULL);
+ ret = asprintf(&client, "%s/%s", weston_config_get_libexec_dir(),
+ WESTON_SHELL_CLIENT);
+ if (ret < 0)
+ client = NULL;
weston_config_section_get_string(section,
- "client", &s, LIBEXECDIR "/" WESTON_SHELL_CLIENT);
+ "client", &s, client);
+ free(client);
shell->client = s;
weston_config_section_get_string(section,
"binding-modifier", &s, "super");
@@ -1550,20 +1625,25 @@ constrain_position(struct weston_move_grab *move, int *cx, int *cy)
{
struct shell_surface *shsurf = move->base.shsurf;
struct weston_pointer *pointer = move->base.grab.pointer;
- int x, y, panel_height, bottom;
+ int x, y, panel_width, panel_height, bottom;
const int safety = 50;
x = wl_fixed_to_int(pointer->x + move->dx);
y = wl_fixed_to_int(pointer->y + move->dy);
- panel_height = get_output_panel_height(shsurf->shell,
- shsurf->surface->output);
- bottom = y + shsurf->geometry.height;
- if (bottom - panel_height < safety)
- y = panel_height + safety - shsurf->geometry.height;
+ if (shsurf->shell->panel_position == DESKTOP_SHELL_PANEL_POSITION_TOP) {
+ get_output_panel_size(shsurf->shell, shsurf->surface->output,
+ &panel_width, &panel_height);
+
+ bottom = y + shsurf->geometry.height;
+ if (bottom - panel_height < safety)
+ y = panel_height + safety -
+ shsurf->geometry.height;
- if (move->client_initiated && y + shsurf->geometry.y < panel_height)
- y = panel_height - shsurf->geometry.y;
+ if (move->client_initiated &&
+ y + shsurf->geometry.y < panel_height)
+ y = panel_height - shsurf->geometry.y;
+ }
*cx = x;
*cy = y;
@@ -1817,13 +1897,20 @@ surface_resize(struct shell_surface *shsurf,
struct weston_seat *seat, uint32_t edges)
{
struct weston_resize_grab *resize;
+ const unsigned resize_topbottom =
+ WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_BOTTOM;
+ const unsigned resize_leftright =
+ WL_SHELL_SURFACE_RESIZE_LEFT | WL_SHELL_SURFACE_RESIZE_RIGHT;
+ const unsigned resize_any = resize_topbottom | resize_leftright;
if (shsurf->grabbed ||
shsurf->state.fullscreen || shsurf->state.maximized)
return 0;
- if (edges == 0 || edges > 15 ||
- (edges & 3) == 3 || (edges & 12) == 12)
+ /* Check for invalid edge combinations. */
+ if (edges == WL_SHELL_SURFACE_RESIZE_NONE || edges > resize_any ||
+ (edges & resize_topbottom) == resize_topbottom ||
+ (edges & resize_leftright) == resize_leftright)
return 0;
resize = malloc(sizeof *resize);
@@ -3040,6 +3127,81 @@ static const struct weston_pointer_grab_interface popup_grab_interface = {
};
static void
+touch_popup_grab_down(struct weston_touch_grab *grab, uint32_t time,
+ int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+ struct wl_resource *resource;
+ struct shell_seat *shseat =
+ container_of(grab, struct shell_seat, popup_grab.touch_grab);
+ struct wl_display *display = shseat->seat->compositor->wl_display;
+ uint32_t serial;
+ struct wl_list *resource_list;
+
+ resource_list = &grab->touch->focus_resource_list;
+ if (!wl_list_empty(resource_list)) {
+ serial = wl_display_get_serial(display);
+ wl_resource_for_each(resource, resource_list) {
+ wl_touch_send_down(resource, serial, time,
+ grab->touch->focus->surface->resource,
+ touch_id, sx, sy);
+ }
+ }
+}
+
+static void
+touch_popup_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
+{
+ struct wl_resource *resource;
+ struct shell_seat *shseat =
+ container_of(grab, struct shell_seat, popup_grab.touch_grab);
+ struct wl_display *display = shseat->seat->compositor->wl_display;
+ uint32_t serial;
+ struct wl_list *resource_list;
+
+ resource_list = &grab->touch->focus_resource_list;
+ if (!wl_list_empty(resource_list)) {
+ serial = wl_display_get_serial(display);
+ wl_resource_for_each(resource, resource_list) {
+ wl_touch_send_up(resource, serial, time, touch_id);
+ }
+ }
+}
+
+static void
+touch_popup_grab_motion(struct weston_touch_grab *grab, uint32_t time,
+ int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+ struct wl_resource *resource;
+ struct wl_list *resource_list;
+
+ resource_list = &grab->touch->focus_resource_list;
+ if (!wl_list_empty(resource_list)) {
+ wl_resource_for_each(resource, resource_list) {
+ wl_touch_send_motion(resource, time, touch_id, sx, sy);
+ }
+ }
+}
+
+static void
+touch_popup_grab_frame(struct weston_touch_grab *grab)
+{
+}
+
+static void
+touch_popup_grab_cancel(struct weston_touch_grab *grab)
+{
+ touch_popup_grab_end(grab->touch);
+}
+
+static const struct weston_touch_grab_interface touch_popup_grab_interface = {
+ touch_popup_grab_down,
+ touch_popup_grab_up,
+ touch_popup_grab_motion,
+ touch_popup_grab_frame,
+ touch_popup_grab_cancel,
+};
+
+static void
shell_surface_send_popup_done(struct shell_surface *shsurf)
{
if (shell_surface_is_wl_shell_surface(shsurf))
@@ -3078,21 +3240,59 @@ popup_grab_end(struct weston_pointer *pointer)
}
static void
-add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat)
+touch_popup_grab_end(struct weston_touch *touch)
+{
+ struct weston_touch_grab *grab = touch->grab;
+ struct shell_seat *shseat =
+ container_of(grab, struct shell_seat, popup_grab.touch_grab);
+ struct shell_surface *shsurf;
+ struct shell_surface *prev = NULL;
+
+ if (touch->grab->interface == &touch_popup_grab_interface) {
+ weston_touch_end_grab(grab->touch);
+ shseat->popup_grab.client = NULL;
+ shseat->popup_grab.touch_grab.interface = NULL;
+ assert(!wl_list_empty(&shseat->popup_grab.surfaces_list));
+ /* Send the popup_done event to all the popups open */
+ wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
+ shell_surface_send_popup_done(shsurf);
+ shsurf->popup.shseat = NULL;
+ if (prev) {
+ wl_list_init(&prev->popup.grab_link);
+ }
+ prev = shsurf;
+ }
+ wl_list_init(&prev->popup.grab_link);
+ wl_list_init(&shseat->popup_grab.surfaces_list);
+ }
+}
+
+static void
+add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat, int32_t type)
{
struct weston_seat *seat = shseat->seat;
if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
+ shseat->popup_grab.type = type;
shseat->popup_grab.client = wl_resource_get_client(shsurf->resource);
- shseat->popup_grab.grab.interface = &popup_grab_interface;
- /* We must make sure here that this popup was opened after
- * a mouse press, and not just by moving around with other
- * popups already open. */
- if (shseat->seat->pointer->button_count > 0)
- shseat->popup_grab.initial_up = 0;
+
+ if (type == POINTER) {
+ shseat->popup_grab.grab.interface = &popup_grab_interface;
+ /* We must make sure here that this popup was opened after
+ * a mouse press, and not just by moving around with other
+ * popups already open. */
+ if (shseat->seat->pointer->button_count > 0)
+ shseat->popup_grab.initial_up = 0;
+ } else if (type == TOUCH) {
+ shseat->popup_grab.touch_grab.interface = &touch_popup_grab_interface;
+ }
wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
- weston_pointer_start_grab(seat->pointer, &shseat->popup_grab.grab);
+
+ if (type == POINTER)
+ weston_pointer_start_grab(seat->pointer, &shseat->popup_grab.grab);
+ else if (type == TOUCH)
+ weston_touch_start_grab(seat->touch, &shseat->popup_grab.touch_grab);
} else {
wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
}
@@ -3106,8 +3306,13 @@ remove_popup_grab(struct shell_surface *shsurf)
wl_list_remove(&shsurf->popup.grab_link);
wl_list_init(&shsurf->popup.grab_link);
if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
- weston_pointer_end_grab(shseat->popup_grab.grab.pointer);
- shseat->popup_grab.grab.interface = NULL;
+ if (shseat->popup_grab.type == POINTER) {
+ weston_pointer_end_grab(shseat->popup_grab.grab.pointer);
+ shseat->popup_grab.grab.interface = NULL;
+ } else if (shseat->popup_grab.type == TOUCH) {
+ weston_touch_end_grab(shseat->popup_grab.touch_grab.touch);
+ shseat->popup_grab.touch_grab.interface = NULL;
+ }
}
}
@@ -3126,7 +3331,10 @@ shell_map_popup(struct shell_surface *shsurf)
if (shseat->seat->pointer &&
shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
- add_popup_grab(shsurf, shseat);
+ add_popup_grab(shsurf, shseat, POINTER);
+ } else if (shseat->seat->touch &&
+ shseat->seat->touch->grab_serial == shsurf->popup.serial) {
+ add_popup_grab(shsurf, shseat, TOUCH);
} else {
shell_surface_send_popup_done(shsurf);
shseat->popup_grab.client = NULL;
@@ -3333,6 +3541,32 @@ get_primary_view(void *shell, struct shell_surface *shsurf)
return shsurf->view;
}
+static struct weston_output *
+get_focused_output(struct weston_compositor *compositor)
+{
+ struct weston_seat *seat;
+ struct weston_output *output = NULL;
+
+ wl_list_for_each(seat, &compositor->seat_list, link) {
+ /* Priority has touch focus, then pointer and
+ * then keyboard focus. We should probably have
+ * three for loops and check frist for touch,
+ * then for pointer, etc. but unless somebody has some
+ * objections, I think this is sufficient. */
+ if (seat->touch && seat->touch->focus)
+ output = seat->touch->focus->output;
+ else if (seat->pointer && seat->pointer->focus)
+ output = seat->pointer->focus->output;
+ else if (seat->keyboard && seat->keyboard->focus)
+ output = seat->keyboard->focus->output;
+
+ if (output)
+ break;
+ }
+
+ return output;
+}
+
static void
shell_get_shell_surface(struct wl_client *client,
struct wl_resource *resource,
@@ -3488,9 +3722,17 @@ xdg_surface_set_maximized(struct wl_client *client,
struct wl_resource *resource)
{
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+ struct weston_output *output;
shsurf->state_requested = true;
shsurf->requested_state.maximized = true;
+
+ if (!weston_surface_is_mapped(shsurf->surface))
+ output = get_focused_output(shsurf->surface->compositor);
+ else
+ output = shsurf->surface->output;
+
+ shell_surface_set_output(shsurf, output);
send_configure_for_surface(shsurf);
}
@@ -3521,6 +3763,13 @@ xdg_surface_set_fullscreen(struct wl_client *client,
else
output = NULL;
+ /* handle clients launching in fullscreen */
+ if (output == NULL && !weston_surface_is_mapped(shsurf->surface)) {
+ /* Set the output to the one that has focus currently. */
+ assert(shsurf->surface);
+ output = get_focused_output(shsurf->surface->compositor);
+ }
+
shell_surface_set_output(shsurf, output);
shsurf->fullscreen_output = shsurf->output;
@@ -3816,7 +4065,7 @@ xdg_shell_unversioned_dispatch(const void *implementation,
return 0;
}
-#define XDG_SERVER_VERSION 3
+#define XDG_SERVER_VERSION 4
static_assert(XDG_SERVER_VERSION == XDG_SHELL_VERSION_CURRENT,
"shell implementation doesn't match protocol version");
@@ -4124,13 +4373,34 @@ desktop_shell_desktop_ready(struct wl_client *client,
shell_fade_startup(shell);
}
+static void
+desktop_shell_set_panel_position(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t position)
+{
+ struct desktop_shell *shell = wl_resource_get_user_data(resource);
+
+ if (position != DESKTOP_SHELL_PANEL_POSITION_TOP &&
+ position != DESKTOP_SHELL_PANEL_POSITION_BOTTOM &&
+ position != DESKTOP_SHELL_PANEL_POSITION_LEFT &&
+ position != DESKTOP_SHELL_PANEL_POSITION_RIGHT) {
+ wl_resource_post_error(resource,
+ DESKTOP_SHELL_ERROR_INVALID_ARGUMENT,
+ "bad position argument");
+ return;
+ }
+
+ shell->panel_position = position;
+}
+
static const struct desktop_shell_interface desktop_shell_implementation = {
desktop_shell_set_background,
desktop_shell_set_panel,
desktop_shell_set_lock_surface,
desktop_shell_unlock,
desktop_shell_set_grab_surface,
- desktop_shell_desktop_ready
+ desktop_shell_desktop_ready,
+ desktop_shell_set_panel_position
};
static enum shell_surface_type
@@ -4218,10 +4488,14 @@ fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, voi
static void
touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
{
- struct weston_surface *focus = seat->touch->focus->surface;
+ struct weston_surface *focus;
struct weston_surface *surface;
struct shell_surface *shsurf;
+ if (seat->touch->focus == NULL)
+ return;
+
+ focus = seat->touch->focus->surface;
surface = weston_surface_get_main_surface(focus);
if (surface == NULL)
return;
@@ -4432,7 +4706,7 @@ rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
shsurf->view->geometry.y + dposy);
}
- /* Repaint implies weston_surface_update_transform(), which
+ /* Repaint implies weston_view_update_transform(), which
* lazily applies the damage due to rotation update.
*/
weston_compositor_schedule_repaint(shsurf->surface->compositor);
@@ -4916,9 +5190,12 @@ idle_handler(struct wl_listener *listener, void *data)
container_of(listener, struct desktop_shell, idle_listener);
struct weston_seat *seat;
- wl_list_for_each(seat, &shell->compositor->seat_list, link)
+ wl_list_for_each(seat, &shell->compositor->seat_list, link) {
if (seat->pointer)
popup_grab_end(seat->pointer);
+ if (seat->touch)
+ touch_popup_grab_end(seat->touch);
+ }
shell_fade(shell, FADE_OUT);
/* lock() is called from shell_fade_done() */
@@ -4953,10 +5230,11 @@ weston_view_set_initial_position(struct weston_view *view,
{
struct weston_compositor *compositor = shell->compositor;
int ix = 0, iy = 0;
- int range_x, range_y;
- int dx, dy, x, y, panel_height;
+ int32_t range_x, range_y;
+ int32_t dx, dy, x, y;
struct weston_output *output, *target_output = NULL;
struct weston_seat *seat;
+ pixman_rectangle32_t area;
/* As a heuristic place the new window on the same output as the
* pointer. Falling back to the output containing 0, 0.
@@ -4988,20 +5266,18 @@ weston_view_set_initial_position(struct weston_view *view,
* If this is negative it means that the surface is bigger than
* output.
*/
- panel_height = get_output_panel_height(shell, target_output);
- range_x = target_output->width - view->surface->width;
- range_y = (target_output->height - panel_height) -
- view->surface->height;
+ get_output_work_area(shell, target_output, &area);
+
+ dx = area.x;
+ dy = area.y;
+ range_x = area.width - view->surface->width;
+ range_y = area.height - view->surface->height;
if (range_x > 0)
- dx = random() % range_x;
- else
- dx = 0;
+ dx += random() % range_x;
if (range_y > 0)
- dy = panel_height + random() % range_y;
- else
- dy = panel_height;
+ dy += random() % range_y;
x = target_output->x + dx;
y = target_output->y + dy;
@@ -5010,13 +5286,29 @@ weston_view_set_initial_position(struct weston_view *view,
}
static void
+set_maximized_position(struct desktop_shell *shell,
+ struct shell_surface *shsurf)
+{
+ int32_t surf_x, surf_y;
+ pixman_rectangle32_t area;
+ pixman_box32_t *e;
+
+ get_output_work_area(shell, shsurf->output, &area);
+ surface_subsurfaces_boundingbox(shsurf->surface,
+ &surf_x, &surf_y, NULL, NULL);
+ e = pixman_region32_extents(&shsurf->output->region);
+
+ weston_view_set_position(shsurf->view,
+ e->x1 + area.x - surf_x,
+ e->y1 + area.y - surf_y);
+}
+
+static void
map(struct desktop_shell *shell, struct shell_surface *shsurf,
int32_t sx, int32_t sy)
{
struct weston_compositor *compositor = shell->compositor;
struct weston_seat *seat;
- int panel_height = 0;
- int32_t surf_x, surf_y;
/* initial positioning, see also configure() */
switch (shsurf->type) {
@@ -5025,14 +5317,7 @@ map(struct desktop_shell *shell, struct shell_surface *shsurf,
center_on_output(shsurf->view, shsurf->fullscreen_output);
shell_map_fullscreen(shsurf);
} else if (shsurf->state.maximized) {
- /* use surface configure to set the geometry */
- panel_height = get_output_panel_height(shell, shsurf->output);
- surface_subsurfaces_boundingbox(shsurf->surface,
- &surf_x, &surf_y, NULL, NULL);
- weston_view_set_position(shsurf->view,
- shsurf->output->x - surf_x,
- shsurf->output->y +
- panel_height - surf_y);
+ set_maximized_position(shell, shsurf);
} else if (!shsurf->state.relative) {
weston_view_set_initial_position(shsurf->view, shell);
}
@@ -5105,7 +5390,6 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
{
struct shell_surface *shsurf;
struct weston_view *view;
- int32_t mx, my, surf_x, surf_y;
shsurf = get_shell_surface(surface);
@@ -5114,13 +5398,7 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
if (shsurf->state.fullscreen)
shell_configure_fullscreen(shsurf);
else if (shsurf->state.maximized) {
- /* setting x, y and using configure to change that geometry */
- surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
- NULL, NULL);
- mx = shsurf->output->x - surf_x;
- my = shsurf->output->y +
- get_output_panel_height(shell,shsurf->output) - surf_y;
- weston_view_set_position(shsurf->view, mx, my);
+ set_maximized_position(shell, shsurf);
} else {
weston_view_set_position(shsurf->view, x, y);
}
@@ -5200,17 +5478,38 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
}
}
+static bool
+check_desktop_shell_crash_too_early(struct desktop_shell *shell)
+{
+ struct timespec now;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
+ return false;
+
+ /*
+ * If the shell helper client dies before the session has been
+ * up for roughly 30 seconds, better just make Weston shut down,
+ * because the user likely has no way to interact with the desktop
+ * anyway.
+ */
+ if (now.tv_sec - shell->startup_time.tv_sec < 30) {
+ weston_log("Error: %s apparently cannot run at all.\n",
+ shell->client);
+ weston_log_continue(STAMP_SPACE "Quitting...");
+ wl_display_terminate(shell->compositor->wl_display);
+
+ return true;
+ }
+
+ return false;
+}
+
static void launch_desktop_shell_process(void *data);
static void
-desktop_shell_sigchld(struct weston_process *process, int status)
+respawn_desktop_shell_process(struct desktop_shell *shell)
{
uint32_t time;
- struct desktop_shell *shell =
- container_of(process, struct desktop_shell, child.process);
-
- shell->child.process.pid = 0;
- shell->child.client = NULL; /* already destroyed by wayland */
/* if desktop-shell dies more than 5 times in 30 seconds, give up */
time = weston_compositor_get_time();
@@ -5221,13 +5520,12 @@ desktop_shell_sigchld(struct weston_process *process, int status)
shell->child.deathcount++;
if (shell->child.deathcount > 5) {
- weston_log("%s died, giving up.\n", shell->client);
+ weston_log("%s disconnected, giving up.\n", shell->client);
return;
}
- weston_log("%s died, respawning...\n", shell->client);
+ weston_log("%s disconnected, respawning...\n", shell->client);
launch_desktop_shell_process(shell);
- shell_fade_startup(shell);
}
static void
@@ -5238,7 +5536,20 @@ desktop_shell_client_destroy(struct wl_listener *listener, void *data)
shell = container_of(listener, struct desktop_shell,
child.client_destroy_listener);
+ wl_list_remove(&shell->child.client_destroy_listener.link);
shell->child.client = NULL;
+ /*
+ * unbind_desktop_shell() will reset shell->child.desktop_shell
+ * before the respawned process has a chance to create a new
+ * desktop_shell object, because we are being called from the
+ * wl_client destructor which destroys all wl_resources before
+ * returning.
+ */
+
+ if (!check_desktop_shell_crash_too_early(shell))
+ respawn_desktop_shell_process(shell);
+
+ shell_fade_startup(shell);
}
static void
@@ -5246,13 +5557,13 @@ launch_desktop_shell_process(void *data)
{
struct desktop_shell *shell = data;
- shell->child.client = weston_client_launch(shell->compositor,
- &shell->child.process,
- shell->client,
- desktop_shell_sigchld);
+ shell->child.client = weston_client_start(shell->compositor,
+ shell->client);
- if (!shell->child.client)
+ if (!shell->child.client) {
weston_log("not able to start %s\n", shell->client);
+ return;
+ }
shell->child.client_destroy_listener.notify =
desktop_shell_client_destroy;
@@ -5344,7 +5655,7 @@ bind_desktop_shell(struct wl_client *client,
struct wl_resource *resource;
resource = wl_resource_create(client, &desktop_shell_interface,
- MIN(version, 2), id);
+ MIN(version, 3), id);
if (client == shell->child.client) {
wl_resource_set_implementation(resource,
@@ -6061,8 +6372,12 @@ shell_destroy(struct wl_listener *listener, void *data)
/* Force state to unlocked so we don't try to fade */
shell->locked = false;
- if (shell->child.client)
+
+ if (shell->child.client) {
+ /* disable respawn */
+ wl_list_remove(&shell->child.client_destroy_listener.link);
wl_client_destroy(shell->child.client);
+ }
wl_list_remove(&shell->idle_listener.link);
wl_list_remove(&shell->wake_listener.link);
@@ -6265,7 +6580,7 @@ module_init(struct weston_compositor *ec,
return -1;
if (wl_global_create(ec->wl_display,
- &desktop_shell_interface, 2,
+ &desktop_shell_interface, 3,
shell, bind_desktop_shell) == NULL)
return -1;
@@ -6279,6 +6594,8 @@ module_init(struct weston_compositor *ec,
shell->child.deathstamp = weston_compositor_get_time();
+ shell->panel_position = DESKTOP_SHELL_PANEL_POSITION_TOP;
+
setup_output_destroy_handler(ec, shell);
loop = wl_display_get_event_loop(ec->wl_display);
@@ -6298,5 +6615,7 @@ module_init(struct weston_compositor *ec,
shell_fade_init(shell);
+ clock_gettime(CLOCK_MONOTONIC, &shell->startup_time);
+
return 0;
}
diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
index e994cdbe..2cfd1d62 100644
--- a/desktop-shell/shell.h
+++ b/desktop-shell/shell.h
@@ -23,9 +23,12 @@
*/
#include <stdbool.h>
+#include <time.h>
#include "compositor.h"
+#include "desktop-shell-server-protocol.h"
+
enum animation_type {
ANIMATION_NONE,
@@ -132,7 +135,6 @@ struct desktop_shell {
struct weston_surface *grab_surface;
struct {
- struct weston_process process;
struct wl_client *client;
struct wl_resource *desktop_shell;
struct wl_listener client_destroy_listener;
@@ -205,7 +207,11 @@ struct desktop_shell {
struct wl_listener output_move_listener;
struct wl_list output_list;
+ enum desktop_shell_panel_position panel_position;
+
char *client;
+
+ struct timespec startup_time;
};
struct weston_output *
diff --git a/man/weston.ini.man b/man/weston.ini.man
index fbcec81a..c05a2215 100644
--- a/man/weston.ini.man
+++ b/man/weston.ini.man
@@ -70,6 +70,7 @@ The section headers are:
.RS 4
.nf
.BR "core " "The core modules"
+.BR "libinput " "Input device configuration"
.BR "shell " "Desktop customization"
.BR "launcher " "Add launcher to the panel"
.BR "screensaver " "Screensaver selection"
@@ -78,6 +79,7 @@ The section headers are:
.BR "keyboard " "Keyboard layouts"
.BR "terminal " "Terminal application options"
.BR "xwayland " "XWayland options"
+.BR "screen-share " "Screen sharing options"
.fi
.RE
.PP
@@ -115,6 +117,7 @@ directory are:
.nf
.BR xwayland.so
.BR cms-colord.so
+.BR screen-share.so
.fi
.RE
.TP 7
@@ -144,6 +147,19 @@ By default, xrgb8888 is used.
.RS
.PP
+.SH "LIBINPUT SECTION"
+The
+.B libinput
+section is used to configure input devices when using the libinput input device
+backend.
+.PP
+Available configuration are:
+.TP 7
+.BI "enable_tap=" true
+enables tap to click on touchpad devices
+.RS
+.PP
+
.SH "SHELL SECTION"
The
.B shell
@@ -358,6 +374,18 @@ be one of the following 8 strings:
.fi
.RE
.TP 7
+.BI "scale=" factor
+An integer, 1 by default, typically configured as 2 when needed, denoting
+the scale factor of the output. Applications that support it render at the
+appropriate scale. For other applications, weston will scale their output
+by this factor.
+.RE
+.RS
+.PP
+Use a value of 2 for outputs with high resolution. Such displays are often
+called "HiDPI" or "retina" displays.
+.RE
+.TP 7
.BI "seat=" name
The logical seat name that that this output should be associated with. If this
is set then the seat's input will be confined to the output that has the seat
@@ -418,6 +446,12 @@ sets the delay in milliseconds since key down until repeating starts (unsigned
integer)
.RE
.RE
+.TP 7
+.BI "numlock-on=" "false"
+sets the default state of the numlock on weston startup for the backends which
+support it.
+.RE
+.RE
.SH "TERMINAL SECTION"
Contains settings for the weston terminal application (weston-terminal). It
allows to customize the font and shell of the command line interface.
@@ -443,6 +477,13 @@ The terminal shell (string). Sets the $TERM variable.
sets the path to the xserver to run (string).
.RE
.RE
+.SH "SCREEN-SHARE SECTION"
+.TP 7
+.BI "command=" "/usr/bin/weston --backend=rdp-backend.so \
+--shell=fullscreen-shell.so --no-clients-resize"
+sets the command to start a fullscreen-shell server for screen sharing (string).
+.RE
+.RE
.SH "SEE ALSO"
.BR weston (1),
.BR weston-launch (1),
diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml
index fdcb17ba..fb0b7481 100644
--- a/protocol/desktop-shell.xml
+++ b/protocol/desktop-shell.xml
@@ -1,6 +1,6 @@
<protocol name="desktop">
- <interface name="desktop_shell" version="2">
+ <interface name="desktop_shell" version="3">
<description summary="create desktop widgets and helpers">
Traditional user interfaces can rely on this interface to define the
foundations of typical desktops. Currently it's possible to set up
@@ -94,6 +94,29 @@
</description>
</request>
+ <!-- Version 3 additions -->
+
+ <enum name="panel_position">
+ <entry name="top" value="0"/>
+ <entry name="bottom" value="1"/>
+ <entry name="left" value="2"/>
+ <entry name="right" value="3"/>
+ </enum>
+
+ <enum name="error">
+ <entry name="invalid_argument" value="0"
+ summary="an invalid argument was provided in a request"/>
+ </enum>
+
+ <request name="set_panel_position" since="3">
+ <arg name="position" type="uint"/>
+ <description summary="set panel position">
+ Tell the shell which side of the screen the panel is
+ located. This is so that new windows do not overlap the panel
+ and maximized windows maximize properly.
+ </description>
+ </request>
+
</interface>
<interface name="screensaver" version="1">
diff --git a/protocol/scaler.xml b/protocol/scaler.xml
index e21ae5b0..9642af2c 100644
--- a/protocol/scaler.xml
+++ b/protocol/scaler.xml
@@ -168,7 +168,7 @@
wl_viewport for the description, and relation to the wl_buffer
size.
- If width is -1.0 and height is -1.0, the destination size is unset
+ If width is -1.0 and height is -1.0, the source rectangle is unset
instead. Any other pair of values for width and height that
contains zero or negative values raises the bad_value protocol
error.
diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml
index bd36231a..275837f3 100644
--- a/protocol/xdg-shell.xml
+++ b/protocol/xdg-shell.xml
@@ -45,7 +45,7 @@
they implement using static_assert to ensure the protocol and
implementation versions match.
</description>
- <entry name="current" value="3" summary="Always the latest version"/>
+ <entry name="current" value="4" summary="Always the latest version"/>
</enum>
diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index 2a332490..26286c5e 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <stdio.h>
#include <math.h>
+#include <wayland-util.h>
#include <cairo.h>
#include "cairo-util.h"
@@ -413,7 +414,8 @@ theme_destroy(struct theme *t)
void
theme_render_frame(struct theme *t,
cairo_t *cr, int width, int height,
- const char *title, uint32_t flags)
+ const char *title, struct wl_list *buttons,
+ uint32_t flags)
{
cairo_text_extents_t extents;
cairo_font_extents_t font_extents;
@@ -439,7 +441,7 @@ theme_render_frame(struct theme *t,
else
source = t->inactive_frame;
- if (title)
+ if (title || !wl_list_empty(buttons))
top_margin = t->titlebar_height;
else
top_margin = t->width;
@@ -449,7 +451,7 @@ theme_render_frame(struct theme *t,
width - margin * 2, height - margin * 2,
t->width, top_margin);
- if (title) {
+ if (title || !wl_list_empty(buttons)) {
cairo_rectangle (cr, margin + t->width, margin,
width - (margin + t->width) * 2,
t->titlebar_height - t->width);
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 4493b0d9..99c77363 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -26,6 +26,8 @@
#include <stdint.h>
#include <cairo.h>
+#include <wayland-util.h>
+
void
surface_flush_device(cairo_surface_t *surface);
@@ -69,7 +71,8 @@ theme_set_background_source(struct theme *t, cairo_t *cr, uint32_t flags);
void
theme_render_frame(struct theme *t,
cairo_t *cr, int width, int height,
- const char *title, uint32_t flags);
+ const char *title, struct wl_list *buttons,
+ uint32_t flags);
enum theme_location {
THEME_LOCATION_INTERIOR = 0,
@@ -210,6 +213,10 @@ frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y);
void
frame_touch_up(struct frame *frame, void *data, int32_t id);
+enum theme_location
+frame_double_click(struct frame *frame, void *pointer,
+ uint32_t button, enum frame_button_state state);
+
void
frame_repaint(struct frame *frame, cairo_t *cr);
diff --git a/shared/config-parser.c b/shared/config-parser.c
index 8defbbb4..4542ca61 100644
--- a/shared/config-parser.c
+++ b/shared/config-parser.c
@@ -282,6 +282,18 @@ weston_config_section_get_bool(struct weston_config_section *section,
return 0;
}
+WL_EXPORT
+const char *
+weston_config_get_libexec_dir(void)
+{
+ const char *path = getenv("WESTON_BUILD_DIR");
+
+ if (path)
+ return path;
+
+ return LIBEXECDIR;
+}
+
static struct weston_config_section *
config_add_section(struct weston_config *config, const char *name)
{
diff --git a/shared/config-parser.h b/shared/config-parser.h
index 745562bc..1ecc8cc2 100644
--- a/shared/config-parser.h
+++ b/shared/config-parser.h
@@ -92,6 +92,9 @@ int
weston_config_section_get_bool(struct weston_config_section *section,
const char *key,
int *value, int default_value);
+const char *
+weston_config_get_libexec_dir(void);
+
struct weston_config *
weston_config_parse(const char *name);
diff --git a/shared/frame.c b/shared/frame.c
index 53f3f5f7..a983d845 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -837,6 +837,37 @@ frame_touch_up(struct frame *frame, void *data, int32_t id)
}
}
+enum theme_location
+frame_double_click(struct frame *frame, void *data,
+ uint32_t btn, enum frame_button_state state)
+{
+ struct frame_pointer *pointer = frame_pointer_get(frame, data);
+ struct frame_button *button;
+ enum theme_location location = THEME_LOCATION_EXTERIOR;
+
+ location = theme_get_location(frame->theme, pointer->x, pointer->y,
+ frame->width, frame->height,
+ frame->flags & FRAME_FLAG_MAXIMIZED ?
+ THEME_FRAME_MAXIMIZED : 0);
+
+ button = frame_find_button(frame, pointer->x, pointer->y);
+
+ if (location != THEME_LOCATION_TITLEBAR || btn != BTN_LEFT)
+ return location;
+
+ if (state == FRAME_BUTTON_PRESSED) {
+ if (button)
+ frame_button_press(button);
+ else
+ frame->status |= FRAME_STATUS_MAXIMIZE;
+ } else if (state == FRAME_BUTTON_RELEASED) {
+ if (button)
+ frame_button_release(button);
+ }
+
+ return location;
+}
+
void
frame_repaint(struct frame *frame, cairo_t *cr)
{
@@ -853,7 +884,7 @@ frame_repaint(struct frame *frame, cairo_t *cr)
cairo_save(cr);
theme_render_frame(frame->theme, cr, frame->width, frame->height,
- frame->title, flags);
+ frame->title, &frame->buttons, flags);
cairo_restore(cr);
wl_list_for_each(button, &frame->buttons, link)
diff --git a/shared/image-loader.c b/shared/image-loader.c
index 35dadd3d..c4d763f3 100644
--- a/shared/image-loader.c
+++ b/shared/image-loader.c
@@ -23,6 +23,7 @@
#include "config.h"
+#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -374,12 +375,18 @@ load_image(const char *filename)
FILE *fp;
unsigned int i;
+ if (!filename || !*filename)
+ return NULL;
+
fp = fopen(filename, "rb");
- if (fp == NULL)
+ if (!fp) {
+ fprintf(stderr, "%s: %s\n", filename, strerror(errno));
return NULL;
+ }
if (fread(header, sizeof header, 1, fp) != 1) {
fclose(fp);
+ fprintf(stderr, "%s: unable to read file header\n", filename);
return NULL;
}
@@ -395,10 +402,13 @@ load_image(const char *filename)
fclose(fp);
if (i == ARRAY_LENGTH(loaders)) {
- fprintf(stderr, "unrecognized file header for %s: "
+ fprintf(stderr, "%s: unrecognized file header "
"0x%02x 0x%02x 0x%02x 0x%02x\n",
filename, header[0], header[1], header[2], header[3]);
image = NULL;
+ } else if (!image) {
+ /* load probably printed something, but just in case */
+ fprintf(stderr, "%s: error reading image\n", filename);
}
return image;
diff --git a/shared/option-parser.c b/shared/option-parser.c
index c00349a8..70612689 100644
--- a/shared/option-parser.c
+++ b/shared/option-parser.c
@@ -30,53 +30,94 @@
#include "config-parser.h"
-static void
+static int
handle_option(const struct weston_option *option, char *value)
{
+ char* p;
+
switch (option->type) {
case WESTON_OPTION_INTEGER:
- * (int32_t *) option->data = strtol(value, NULL, 0);
- return;
+ * (int32_t *) option->data = strtol(value, &p, 0);
+ return *value && !*p;
case WESTON_OPTION_UNSIGNED_INTEGER:
- * (uint32_t *) option->data = strtoul(value, NULL, 0);
- return;
+ * (uint32_t *) option->data = strtoul(value, &p, 0);
+ return *value && !*p;
case WESTON_OPTION_STRING:
* (char **) option->data = strdup(value);
- return;
- case WESTON_OPTION_BOOLEAN:
- * (int32_t *) option->data = 1;
- return;
+ return 1;
default:
assert(0);
}
}
+static int
+long_option(const struct weston_option *options, int count, char *arg)
+{
+ int k, len;
+
+ for (k = 0; k < count; k++) {
+ if (!options[k].name)
+ continue;
+
+ len = strlen(options[k].name);
+ if (strncmp(options[k].name, arg + 2, len) != 0)
+ continue;
+
+ if (options[k].type == WESTON_OPTION_BOOLEAN) {
+ if (!arg[len + 2]) {
+ * (int32_t *) options[k].data = 1;
+
+ return 1;
+ }
+ } else if (arg[len+2] == '=') {
+ return handle_option(options + k, arg + len + 3);
+ }
+ }
+
+ return 0;
+}
+
+static int
+short_option(const struct weston_option *options, int count, char *arg)
+{
+ int k;
+
+ if (!arg[1])
+ return 0;
+
+ for (k = 0; k < count; k++) {
+ if (options[k].short_name != arg[1])
+ continue;
+
+ if (options[k].type == WESTON_OPTION_BOOLEAN) {
+ if (!arg[2]) {
+ * (int32_t *) options[k].data = 1;
+
+ return 1;
+ }
+ } else {
+ return handle_option(options + k, arg + 2);
+ }
+ }
+
+ return 0;
+}
+
int
parse_options(const struct weston_option *options,
int count, int *argc, char *argv[])
{
- int i, j, k, len = 0;
+ int i, j;
for (i = 1, j = 1; i < *argc; i++) {
- for (k = 0; k < count; k++) {
- if (options[k].name)
- len = strlen(options[k].name);
- if (options[k].name &&
- argv[i][0] == '-' &&
- argv[i][1] == '-' &&
- strncmp(options[k].name, &argv[i][2], len) == 0 &&
- (argv[i][len + 2] == '=' || argv[i][len + 2] == '\0')) {
- handle_option(&options[k], &argv[i][len + 3]);
- break;
- } else if (options[k].short_name &&
- argv[i][0] == '-' &&
- options[k].short_name == argv[i][1]) {
- handle_option(&options[k], &argv[i][2]);
- break;
- }
+ if (argv[i][0] == '-') {
+ if (argv[i][1] == '-') {
+ if (long_option(options, count, argv[i]))
+ continue;
+ } else if (short_option(options, count, argv[i]))
+ continue;
}
- if (k == count)
- argv[j++] = argv[i];
+ argv[j++] = argv[i];
}
argv[j] = NULL;
*argc = j;
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 9c83b1a7..e4496e76 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -900,7 +900,7 @@ drm_output_prepare_overlay_view(struct weston_output *output_base,
/*
* Calculate the source & dest rects properly based on actual
- * position (note the caller has called weston_surface_update_transform()
+ * position (note the caller has called weston_view_update_transform()
* for us already).
*/
pixman_region32_init(&dest_rect);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index d5ea9251..5f73c787 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -1436,10 +1436,10 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
goto error;
}
- keymap = xkb_map_new_from_string(input->compositor->base.xkb_context,
- map_str,
- XKB_KEYMAP_FORMAT_TEXT_V1,
- 0);
+ keymap = xkb_keymap_new_from_string(input->compositor->base.xkb_context,
+ map_str,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ 0);
munmap(map_str, size);
if (!keymap) {
@@ -1464,8 +1464,7 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
else
weston_seat_init_keyboard(&input->base, keymap);
- if (keymap)
- xkb_map_unref(keymap);
+ xkb_keymap_unref(keymap);
return;
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 56b32287..b602bc9a 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -154,7 +154,7 @@ x11_compositor_get_keymap(struct x11_compositor *c)
copy_prop_value(options);
#undef copy_prop_value
- ret = xkb_map_new_from_names(c->base.xkb_context, &names, 0);
+ ret = xkb_keymap_new_from_names(c->base.xkb_context, &names, 0);
free(reply);
return ret;
@@ -322,8 +322,7 @@ x11_input_create(struct x11_compositor *c, int no_input)
keymap = x11_compositor_get_keymap(c);
if (weston_seat_init_keyboard(&c->core_seat, keymap) < 0)
return -1;
- if (keymap)
- xkb_map_unref(keymap);
+ xkb_keymap_unref(keymap);
x11_compositor_setup_xkb(c);
@@ -870,7 +869,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
output->base.set_dpms = NULL;
output->base.switch_mode = NULL;
output->base.current_mode = &output->mode;
- output->base.make = "xwayland";
+ output->base.make = "weston-X11";
output->base.model = "none";
if (configured_name)
diff --git a/src/compositor.c b/src/compositor.c
index 96e3435f..a2197662 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -46,6 +46,7 @@
#include <setjmp.h>
#include <sys/time.h>
#include <time.h>
+#include <errno.h>
#ifdef HAVE_LIBUNWIND
#define UNW_LOCAL_ONLY
@@ -68,22 +69,23 @@ sigchld_handler(int signal_number, void *data)
int status;
pid_t pid;
- pid = waitpid(-1, &status, WNOHANG);
- if (!pid)
- return 1;
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+ wl_list_for_each(p, &child_process_list, link) {
+ if (p->pid == pid)
+ break;
+ }
- wl_list_for_each(p, &child_process_list, link) {
- if (p->pid == pid)
- break;
- }
+ if (&p->link == &child_process_list) {
+ weston_log("unknown child process exited\n");
+ continue;
+ }
- if (&p->link == &child_process_list) {
- weston_log("unknown child process exited\n");
- return 1;
+ wl_list_remove(&p->link);
+ p->cleanup(p, status);
}
- wl_list_remove(&p->link);
- p->cleanup(p, status);
+ if (pid < 0 && errno != ECHILD)
+ weston_log("waitpid error %m\n");
return 1;
}
@@ -319,6 +321,66 @@ weston_client_launch(struct weston_compositor *compositor,
return client;
}
+struct process_info {
+ struct weston_process proc;
+ char *path;
+};
+
+static void
+process_handle_sigchld(struct weston_process *process, int status)
+{
+ struct process_info *pinfo =
+ container_of(process, struct process_info, proc);
+
+ /*
+ * There are no guarantees whether this runs before or after
+ * the wl_client destructor.
+ */
+
+ if (WIFEXITED(status)) {
+ weston_log("%s exited with status %d\n", pinfo->path,
+ WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ weston_log("%s died on signal %d\n", pinfo->path,
+ WTERMSIG(status));
+ } else {
+ weston_log("%s disappeared\n", pinfo->path);
+ }
+
+ free(pinfo->path);
+ free(pinfo);
+}
+
+WL_EXPORT struct wl_client *
+weston_client_start(struct weston_compositor *compositor, const char *path)
+{
+ struct process_info *pinfo;
+ struct wl_client *client;
+
+ pinfo = zalloc(sizeof *pinfo);
+ if (!pinfo)
+ return NULL;
+
+ pinfo->path = strdup(path);
+ if (!pinfo->path)
+ goto out_free;
+
+ client = weston_client_launch(compositor, &pinfo->proc, path,
+ process_handle_sigchld);
+ if (!client)
+ goto out_str;
+
+ return client;
+
+out_str:
+ free(pinfo->path);
+
+out_free:
+ free(pinfo);
+
+ return NULL;
+}
+
static void
region_init_infinite(pixman_region32_t *region)
{
@@ -2187,7 +2249,7 @@ weston_surface_commit_state(struct weston_surface *surface,
&state->damage);
pixman_region32_intersect_rect(&surface->damage, &surface->damage,
0, 0, surface->width, surface->height);
- pixman_region32_clear(&surface->pending.damage);
+ pixman_region32_clear(&state->damage);
/* wl_surface.set_opaque_region */
pixman_region32_init(&opaque);
@@ -2559,13 +2621,13 @@ subsurface_configure(struct weston_surface *surface, int32_t dx, int32_t dy)
if (!weston_surface_is_mapped(surface)) {
struct weston_output *output;
- /* Cannot call weston_surface_update_transform(),
+ /* Cannot call weston_view_update_transform(),
* because that would call it also for the parent surface,
* which might not be mapped yet. That would lead to
* inconsistent state, where the window could never be
* mapped.
*
- * Instead just assing any output, to make
+ * Instead just assign any output, to make
* weston_surface_is_mapped() return true, so that when the
* parent surface does get mapped, this one will get
* included, too. See view_list_add().
@@ -3186,6 +3248,8 @@ weston_compositor_remove_output(struct weston_compositor *compositor,
WL_EXPORT void
weston_output_destroy(struct weston_output *output)
{
+ struct wl_resource *resource;
+
output->destroying = 1;
weston_compositor_remove_output(output->compositor, output);
@@ -3199,6 +3263,10 @@ weston_output_destroy(struct weston_output *output)
pixman_region32_fini(&output->previous_damage);
output->compositor->output_id_pool &= ~(1 << output->id);
+ wl_resource_for_each(resource, &output->resource_list) {
+ wl_resource_set_destructor(resource, NULL);
+ }
+
wl_global_destroy(output->global);
}
@@ -4217,6 +4285,42 @@ handle_primary_client_destroyed(struct wl_listener *listener, void *data)
wl_display_terminate(wl_client_get_display(client));
}
+static char *
+weston_choose_default_backend(void)
+{
+ char *backend = NULL;
+
+ if (getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"))
+ backend = strdup("wayland-backend.so");
+ else if (getenv("DISPLAY"))
+ backend = strdup("x11-backend.so");
+ else
+ backend = strdup(WESTON_NATIVE_BACKEND);
+
+ return backend;
+}
+
+static int
+weston_create_listening_socket(struct wl_display *display, const char *socket_name)
+{
+ if (socket_name) {
+ if (wl_display_add_socket(display, socket_name)) {
+ weston_log("fatal: failed to add socket: %m\n");
+ return -1;
+ }
+ } else {
+ socket_name = wl_display_add_socket_auto(display);
+ if (!socket_name) {
+ weston_log("fatal: failed to add socket: %m\n");
+ return -1;
+ }
+ }
+
+ setenv("WAYLAND_DISPLAY", socket_name, 1);
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int ret = EXIT_SUCCESS;
@@ -4230,25 +4334,26 @@ int main(int argc, char *argv[])
struct weston_config *config);
int i, fd;
char *backend = NULL;
- char *option_backend = NULL;
char *shell = NULL;
- char *option_shell = NULL;
- char *modules, *option_modules = NULL;
+ char *modules = NULL;
+ char *option_modules = NULL;
char *log = NULL;
char *server_socket = NULL, *end;
int32_t idle_time = 300;
int32_t help = 0;
- const char *socket_name = NULL;
+ char *socket_name = NULL;
int32_t version = 0;
int32_t noconfig = 0;
+ int32_t numlock_on;
struct weston_config *config = NULL;
struct weston_config_section *section;
struct wl_client *primary_client;
struct wl_listener primary_client_destroyed;
+ struct weston_seat *seat;
const struct weston_option core_options[] = {
- { WESTON_OPTION_STRING, "backend", 'B', &option_backend },
- { WESTON_OPTION_STRING, "shell", 0, &option_shell },
+ { WESTON_OPTION_STRING, "backend", 'B', &backend },
+ { WESTON_OPTION_STRING, "shell", 0, &shell },
{ WESTON_OPTION_STRING, "socket", 'S', &socket_name },
{ WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
{ WESTON_OPTION_STRING, "modules", 0, &option_modules },
@@ -4309,23 +4414,14 @@ int main(int argc, char *argv[])
}
section = weston_config_get_section(config, "core", NULL, NULL);
- if (option_backend)
- backend = strdup(option_backend);
- else
+ if (!backend) {
weston_config_section_get_string(section, "backend", &backend,
NULL);
-
- if (!backend) {
- if (getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"))
- backend = strdup("wayland-backend.so");
- else if (getenv("DISPLAY"))
- backend = strdup("x11-backend.so");
- else
- backend = strdup(WESTON_NATIVE_BACKEND);
+ if (!backend)
+ backend = weston_choose_default_backend();
}
backend_init = weston_load_module(backend, "backend_init");
- free(backend);
if (!backend_init) {
ret = EXIT_FAILURE;
goto out_signals;
@@ -4374,52 +4470,41 @@ int main(int argc, char *argv[])
handle_primary_client_destroyed;
wl_client_add_destroy_listener(primary_client,
&primary_client_destroyed);
- } else {
- if (socket_name) {
- if (wl_display_add_socket(display, socket_name)) {
- weston_log("fatal: failed to add socket: %m\n");
- ret = EXIT_FAILURE;
- goto out;
- }
- } else {
- socket_name = wl_display_add_socket_auto(display);
- if (!socket_name) {
- weston_log("fatal: failed to add socket: %m\n");
- ret = EXIT_FAILURE;
- goto out;
- }
- }
-
- setenv("WAYLAND_DISPLAY", socket_name, 1);
+ } else if (weston_create_listening_socket(display, socket_name)) {
+ ret = EXIT_FAILURE;
+ goto out;
}
- if (option_shell)
- shell = strdup(option_shell);
- else
+ if (!shell)
weston_config_section_get_string(section, "shell", &shell,
"desktop-shell.so");
- if (load_modules(ec, shell, &argc, argv) < 0) {
- free(shell);
+ if (load_modules(ec, shell, &argc, argv) < 0)
goto out;
- }
- free(shell);
weston_config_section_get_string(section, "modules", &modules, "");
- if (load_modules(ec, modules, &argc, argv) < 0) {
- free(modules);
+ if (load_modules(ec, modules, &argc, argv) < 0)
goto out;
- }
- free(modules);
if (load_modules(ec, option_modules, &argc, argv) < 0)
goto out;
+ section = weston_config_get_section(config, "keyboard", NULL, NULL);
+ weston_config_section_get_bool(section, "numlock-on", &numlock_on, 0);
+ if (numlock_on) {
+ wl_list_for_each(seat, &ec->seat_list, link) {
+ if (seat->keyboard)
+ weston_keyboard_set_locks(seat->keyboard,
+ WESTON_NUM_LOCK,
+ WESTON_NUM_LOCK);
+ }
+ }
+
weston_compositor_wake(ec);
wl_display_run(display);
- out:
+out:
/* prevent further rendering while shutting down */
ec->state = WESTON_COMPOSITOR_OFFSCREEN;
@@ -4438,5 +4523,12 @@ out_signals:
weston_log_file_close();
+ free(backend);
+ free(shell);
+ free(socket_name);
+ free(option_modules);
+ free(log);
+ free(modules);
+
return ret;
}
diff --git a/src/compositor.h b/src/compositor.h
index c0fc0a6e..9611deae 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -68,6 +68,11 @@ enum weston_keyboard_modifier {
MODIFIER_SHIFT = (1 << 3),
};
+enum weston_keyboard_locks {
+ WESTON_NUM_LOCK = (1 << 0),
+ WESTON_CAPS_LOCK = (1 << 1),
+};
+
enum weston_led {
LED_NUM_LOCK = (1 << 0),
LED_CAPS_LOCK = (1 << 1),
@@ -195,7 +200,6 @@ struct weston_output {
int dirty;
struct wl_signal frame_signal;
struct wl_signal destroy_signal;
- struct wl_signal move_signal;
int move_x, move_y;
uint32_t frame_time;
int disable_planes;
@@ -393,6 +397,13 @@ weston_keyboard_start_grab(struct weston_keyboard *device,
struct weston_keyboard_grab *grab);
void
weston_keyboard_end_grab(struct weston_keyboard *keyboard);
+int
+/*
+ * 'mask' and 'value' should be a bitwise mask of one or more
+ * valued of the weston_keyboard_locks enum.
+ */
+weston_keyboard_set_locks(struct weston_keyboard *keyboard,
+ uint32_t mask, uint32_t value);
struct weston_touch *
weston_touch_create(void);
@@ -1345,6 +1356,9 @@ weston_client_launch(struct weston_compositor *compositor,
const char *path,
weston_process_cleanup_func_t cleanup);
+struct wl_client *
+weston_client_start(struct weston_compositor *compositor, const char *path);
+
void
weston_watch_process(struct weston_process *process);
diff --git a/src/input.c b/src/input.c
index 1ab55cea..530904d6 100644
--- a/src/input.c
+++ b/src/input.c
@@ -544,12 +544,10 @@ weston_keyboard_destroy(struct weston_keyboard *keyboard)
#ifdef ENABLE_XKBCOMMON
if (keyboard->seat->compositor->use_xkbcommon) {
- if (keyboard->xkb_state.state != NULL)
- xkb_state_unref(keyboard->xkb_state.state);
+ xkb_state_unref(keyboard->xkb_state.state);
if (keyboard->xkb_info)
weston_xkb_info_destroy(keyboard->xkb_info);
- if (keyboard->pending_keymap)
- xkb_keymap_unref(keyboard->pending_keymap);
+ xkb_keymap_unref(keyboard->pending_keymap);
}
#endif
@@ -1064,6 +1062,58 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
value);
}
+WL_EXPORT int
+weston_keyboard_set_locks(struct weston_keyboard *keyboard,
+ uint32_t mask, uint32_t value)
+{
+#ifdef ENABLE_XKBCOMMON
+ uint32_t serial;
+ xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
+ xkb_mod_mask_t num, caps;
+
+ /* We don't want the leds to go out of sync with the actual state
+ * so if the backend has no way to change the leds don't try to
+ * change the state */
+ if (!keyboard->seat->led_update)
+ return -1;
+
+ mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
+ XKB_STATE_DEPRESSED);
+ mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
+ XKB_STATE_LATCHED);
+ mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
+ XKB_STATE_LOCKED);
+ group = xkb_state_serialize_group(keyboard->xkb_state.state,
+ XKB_STATE_EFFECTIVE);
+
+ num = (1 << keyboard->xkb_info->mod2_mod);
+ caps = (1 << keyboard->xkb_info->caps_mod);
+ if (mask & WESTON_NUM_LOCK) {
+ if (value & WESTON_NUM_LOCK)
+ mods_locked |= num;
+ else
+ mods_locked &= ~num;
+ }
+ if (mask & WESTON_CAPS_LOCK) {
+ if (value & WESTON_CAPS_LOCK)
+ mods_locked |= caps;
+ else
+ mods_locked &= ~caps;
+ }
+
+ xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
+ mods_latched, mods_locked, 0, 0, group);
+
+ serial = wl_display_next_serial(
+ keyboard->seat->compositor->wl_display);
+ notify_modifiers(keyboard->seat, serial);
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
#ifdef ENABLE_XKBCOMMON
WL_EXPORT void
notify_modifiers(struct weston_seat *seat, uint32_t serial)
@@ -1078,13 +1128,13 @@ notify_modifiers(struct weston_seat *seat, uint32_t serial)
/* Serialize and update our internal state, checking to see if it's
* different to the previous state. */
mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
- XKB_STATE_DEPRESSED);
+ XKB_STATE_MODS_DEPRESSED);
mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
- XKB_STATE_LATCHED);
+ XKB_STATE_MODS_LATCHED);
mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
- XKB_STATE_LOCKED);
- group = xkb_state_serialize_group(keyboard->xkb_state.state,
- XKB_STATE_EFFECTIVE);
+ XKB_STATE_MODS_LOCKED);
+ group = xkb_state_serialize_layout(keyboard->xkb_state.state,
+ XKB_STATE_LAYOUT_EFFECTIVE);
if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
mods_latched != seat->keyboard->modifiers.mods_latched ||
@@ -1421,8 +1471,14 @@ weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
}
if (view) {
- struct wl_client *surface_client =
- wl_resource_get_client(view->surface->resource);
+ struct wl_client *surface_client;
+
+ if (!view->surface->resource) {
+ seat->touch->focus = NULL;
+ return;
+ }
+
+ surface_client = wl_resource_get_client(view->surface->resource);
move_resources_for_client(focus_resource_list,
&seat->touch->resource_list,
surface_client);
@@ -1609,8 +1665,10 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
pointer->hotspot_x = x;
pointer->hotspot_y = y;
- if (surface->buffer_ref.buffer)
+ if (surface->buffer_ref.buffer) {
pointer_cursor_surface_configure(surface, 0, 0);
+ weston_view_schedule_repaint(pointer->sprite);
+ }
}
static void
@@ -1869,8 +1927,7 @@ weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
if (--xkb_info->ref_count > 0)
return;
- if (xkb_info->keymap)
- xkb_map_unref(xkb_info->keymap);
+ xkb_keymap_unref(xkb_info->keymap);
if (xkb_info->keymap_area)
munmap(xkb_info->keymap_area, xkb_info->keymap_size);
@@ -1907,33 +1964,37 @@ weston_xkb_info_create(struct xkb_keymap *keymap)
if (xkb_info == NULL)
return NULL;
- xkb_info->keymap = xkb_map_ref(keymap);
+ xkb_info->keymap = xkb_keymap_ref(keymap);
xkb_info->ref_count = 1;
char *keymap_str;
- xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
- XKB_MOD_NAME_SHIFT);
- xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
- XKB_MOD_NAME_CAPS);
- xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
- XKB_MOD_NAME_CTRL);
- xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
- XKB_MOD_NAME_ALT);
- xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
- xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
- xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
- XKB_MOD_NAME_LOGO);
- xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
-
- xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
- XKB_LED_NAME_NUM);
- xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
- XKB_LED_NAME_CAPS);
- xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
- XKB_LED_NAME_SCROLL);
-
- keymap_str = xkb_map_get_as_string(xkb_info->keymap);
+ xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ XKB_MOD_NAME_SHIFT);
+ xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ XKB_MOD_NAME_CAPS);
+ xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ XKB_MOD_NAME_CTRL);
+ xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ XKB_MOD_NAME_ALT);
+ xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ "Mod2");
+ xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ "Mod3");
+ xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ XKB_MOD_NAME_LOGO);
+ xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
+ "Mod5");
+
+ xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
+ XKB_LED_NAME_NUM);
+ xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
+ XKB_LED_NAME_CAPS);
+ xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
+ XKB_LED_NAME_SCROLL);
+
+ keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
+ XKB_KEYMAP_FORMAT_TEXT_V1);
if (keymap_str == NULL) {
weston_log("failed to get string version of keymap\n");
goto err_keymap;
@@ -1965,7 +2026,7 @@ err_dev_zero:
err_keymap_str:
free(keymap_str);
err_keymap:
- xkb_map_unref(xkb_info->keymap);
+ xkb_keymap_unref(xkb_info->keymap);
free(xkb_info);
return NULL;
}
@@ -1978,9 +2039,9 @@ weston_compositor_build_global_keymap(struct weston_compositor *ec)
if (ec->xkb_info != NULL)
return 0;
- keymap = xkb_map_new_from_names(ec->xkb_context,
- &ec->xkb_names,
- 0);
+ keymap = xkb_keymap_new_from_names(ec->xkb_context,
+ &ec->xkb_names,
+ 0);
if (keymap == NULL) {
weston_log("failed to compile global XKB keymap\n");
weston_log(" tried rules %s, model %s, layout %s, variant %s, "
diff --git a/src/libinput-device.c b/src/libinput-device.c
index 6e50eebb..0e3f46de 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -282,6 +282,90 @@ notify_output_destroy(struct wl_listener *listener, void *data)
}
}
+/**
+ * The WL_CALIBRATION property requires a pixel-specific matrix to be
+ * applied after scaling device coordinates to screen coordinates. libinput
+ * can't do that, so we need to convert the calibration to the normalized
+ * format libinput expects.
+ */
+static void
+evdev_device_set_calibration(struct evdev_device *device)
+{
+ struct udev *udev;
+ struct udev_device *udev_device = NULL;
+ const char *sysname = libinput_device_get_sysname(device->device);
+ const char *calibration_values;
+ uint32_t width, height;
+ float calibration[6];
+ enum libinput_config_status status;
+
+ if (!device->output)
+ return;
+
+ width = device->output->width;
+ height = device->output->height;
+ if (width == 0 || height == 0)
+ return;
+
+ /* If libinput has a pre-set calibration matrix, don't override it */
+ if (!libinput_device_config_calibration_has_matrix(device->device) ||
+ libinput_device_config_calibration_get_default_matrix(
+ device->device,
+ calibration) != 0)
+ return;
+
+ udev = udev_new();
+ if (!udev)
+ return;
+
+ udev_device = udev_device_new_from_subsystem_sysname(udev,
+ "input",
+ sysname);
+ if (!udev_device)
+ goto out;
+
+ calibration_values =
+ udev_device_get_property_value(udev_device,
+ "WL_CALIBRATION");
+
+ if (!calibration_values || sscanf(calibration_values,
+ "%f %f %f %f %f %f",
+ &calibration[0],
+ &calibration[1],
+ &calibration[2],
+ &calibration[3],
+ &calibration[4],
+ &calibration[5]) != 6)
+ goto out;
+
+ weston_log("Applying calibration: %f %f %f %f %f %f "
+ "(normalized %f %f)\n",
+ calibration[0],
+ calibration[1],
+ calibration[2],
+ calibration[3],
+ calibration[4],
+ calibration[5],
+ calibration[2] / width,
+ calibration[5] / height);
+
+ /* normalize to a format libinput can use. There is a chance of
+ this being wrong if the width/height don't match the device
+ width/height but I'm not sure how to fix that */
+ calibration[2] /= width;
+ calibration[5] /= height;
+
+ status = libinput_device_config_calibration_set_matrix(device->device,
+ calibration);
+ if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
+ weston_log("Failed to apply calibration.\n");
+
+out:
+ if (udev_device)
+ udev_device_unref(udev_device);
+ udev_unref(udev);
+}
+
void
evdev_device_set_output(struct evdev_device *device,
struct weston_output *output)
@@ -295,6 +379,7 @@ evdev_device_set_output(struct evdev_device *device,
device->output_destroy_listener.notify = notify_output_destroy;
wl_signal_add(&output->destroy_signal,
&device->output_destroy_listener);
+ evdev_device_set_calibration(device);
}
static void
@@ -318,6 +403,8 @@ configure_device(struct evdev_device *device)
libinput_device_config_tap_set_enabled(device->device,
enable_tap);
}
+
+ evdev_device_set_calibration(device);
}
struct evdev_device *
@@ -381,42 +468,12 @@ void
evdev_notify_keyboard_focus(struct weston_seat *seat,
struct wl_list *evdev_devices)
{
- struct evdev_device *device;
struct wl_array keys;
- unsigned int i, set;
- char evdev_keys[(KEY_CNT + 7) / 8];
- char all_keys[(KEY_CNT + 7) / 8];
- uint32_t *k;
- int ret;
if (!seat->keyboard_device_count > 0)
return;
- memset(all_keys, 0, sizeof all_keys);
- wl_list_for_each(device, evdev_devices, link) {
- memset(evdev_keys, 0, sizeof evdev_keys);
- ret = libinput_device_get_keys(device->device,
- evdev_keys,
- sizeof evdev_keys);
- if (ret < 0) {
- weston_log("failed to get keys for device %s\n",
- device->devnode);
- continue;
- }
- for (i = 0; i < ARRAY_LENGTH(evdev_keys); i++)
- all_keys[i] |= evdev_keys[i];
- }
-
wl_array_init(&keys);
- for (i = 0; i < KEY_CNT; i++) {
- set = all_keys[i >> 3] & (1 << (i & 7));
- if (set) {
- k = wl_array_add(&keys, sizeof *k);
- *k = i;
- }
- }
-
notify_keyboard_focus_in(seat, &keys, STATE_UPDATE_AUTOMATIC);
-
wl_array_release(&keys);
}
diff --git a/src/libinput-seat.c b/src/libinput-seat.c
index 09cf7c7e..ef2d804a 100644
--- a/src/libinput-seat.c
+++ b/src/libinput-seat.c
@@ -260,9 +260,10 @@ libinput_log_func(struct libinput *libinput,
}
int
-udev_input_init(struct udev_input *input, struct weston_compositor *c, struct udev *udev,
- const char *seat_id)
+udev_input_init(struct udev_input *input, struct weston_compositor *c,
+ struct udev *udev, const char *seat_id)
{
+ enum libinput_log_priority priority = LIBINPUT_LOG_PRIORITY_INFO;
const char *log_priority = NULL;
memset(input, 0, sizeof *input);
@@ -281,17 +282,16 @@ udev_input_init(struct udev_input *input, struct weston_compositor *c, struct ud
if (log_priority) {
if (strcmp(log_priority, "debug") == 0) {
- libinput_log_set_priority(input->libinput,
- LIBINPUT_LOG_PRIORITY_DEBUG);
+ priority = LIBINPUT_LOG_PRIORITY_DEBUG;
} else if (strcmp(log_priority, "info") == 0) {
- libinput_log_set_priority(input->libinput,
- LIBINPUT_LOG_PRIORITY_INFO);
+ priority = LIBINPUT_LOG_PRIORITY_INFO;
} else if (strcmp(log_priority, "error") == 0) {
- libinput_log_set_priority(input->libinput,
- LIBINPUT_LOG_PRIORITY_ERROR);
+ priority = LIBINPUT_LOG_PRIORITY_ERROR;
}
}
+ libinput_log_set_priority(input->libinput, priority);
+
if (libinput_udev_assign_seat(input->libinput, seat_id) != 0) {
libinput_unref(input->libinput);
return -1;
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index a816d02e..2c26c3af 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -385,6 +385,7 @@ static void
draw_view(struct weston_view *ev, struct weston_output *output,
pixman_region32_t *damage) /* in global coordinates */
{
+ static int zoom_logged = 0;
struct pixman_surface_state *ps = get_surface_state(ev->surface);
/* repaint bounding region in global coordinates: */
pixman_region32_t repaint;
@@ -403,9 +404,9 @@ draw_view(struct weston_view *ev, struct weston_output *output,
if (!pixman_region32_not_empty(&repaint))
goto out;
- if (output->zoom.active) {
+ if (output->zoom.active && !zoom_logged) {
weston_log("pixman renderer does not support zoom\n");
- goto out;
+ zoom_logged = 1;
}
/* TODO: Implement repaint_region_complex() using pixman_composite_trapezoids() */
@@ -456,6 +457,7 @@ copy_to_hw_buffer(struct weston_output *output, pixman_region32_t *region)
region_global_to_output(output, &output_region);
pixman_image_set_clip_region32 (po->hw_buffer, &output_region);
+ pixman_region32_fini(&output_region);
pixman_image_composite32(PIXMAN_OP_SRC,
po->shadow_image, /* src */
@@ -786,6 +788,9 @@ pixman_renderer_output_destroy(struct weston_output *output)
if (po->hw_buffer)
pixman_image_unref(po->hw_buffer);
+ free(po->shadow_buffer);
+
+ po->shadow_buffer = NULL;
po->shadow_image = NULL;
po->hw_buffer = NULL;
diff --git a/src/screen-share.c b/src/screen-share.c
index f9dcba1c..524a0cac 100644
--- a/src/screen-share.c
+++ b/src/screen-share.c
@@ -186,10 +186,10 @@ ss_seat_handle_keymap(void *data, struct wl_keyboard *keyboard,
goto error;
}
- keymap = xkb_map_new_from_string(seat->base.compositor->xkb_context,
- map_str,
- XKB_KEYMAP_FORMAT_TEXT_V1,
- 0);
+ keymap = xkb_keymap_new_from_string(seat->base.compositor->xkb_context,
+ map_str,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ 0);
munmap(map_str, size);
if (!keymap) {
@@ -214,8 +214,7 @@ ss_seat_handle_keymap(void *data, struct wl_keyboard *keyboard,
else
weston_seat_init_keyboard(&seat->base, keymap);
- if (keymap)
- xkb_map_unref(keymap);
+ xkb_keymap_unref(keymap);
return;
diff --git a/src/screenshooter.c b/src/screenshooter.c
index 44039332..cafbf107 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -286,12 +286,22 @@ screenshooter_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
void *data)
{
struct screenshooter *shooter = data;
- const char *screenshooter_exe = LIBEXECDIR "/weston-screenshooter";
+ char *screenshooter_exe;
+ int ret;
+
+ ret = asprintf(&screenshooter_exe, "%s/%s",
+ weston_config_get_libexec_dir(),
+ "/weston-screenshooter");
+ if (ret < 0) {
+ weston_log("Could not construct screenshooter path.\n");
+ return;
+ }
if (!shooter->client)
shooter->client = weston_client_launch(shooter->ec,
&shooter->process,
screenshooter_exe, screenshooter_sigchld);
+ free(screenshooter_exe);
}
struct weston_recorder {
diff --git a/src/text-backend.c b/src/text-backend.c
index 1d549d43..e9578a41 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -937,12 +937,19 @@ static void
text_backend_configuration(struct text_backend *text_backend)
{
struct weston_config_section *section;
+ char *client;
+ int ret;
section = weston_config_get_section(text_backend->compositor->config,
"input-method", NULL, NULL);
+ ret = asprintf(&client, "%s/weston-keyboard",
+ weston_config_get_libexec_dir());
+ if (ret < 0)
+ client = NULL;
weston_config_section_get_string(section, "path",
&text_backend->input_method.path,
- LIBEXECDIR "/weston-keyboard");
+ client);
+ free(client);
}
static void
diff --git a/src/vertex-clipping.c b/src/vertex-clipping.c
index db527e14..2bb8c0ab 100644
--- a/src/vertex-clipping.c
+++ b/src/vertex-clipping.c
@@ -206,6 +206,9 @@ clip_polygon_left(struct clip_context *ctx, const struct polygon8 *src,
enum path_transition trans;
int i;
+ if (src->n < 2)
+ return 0;
+
clip_context_prepare(ctx, src, dst_x, dst_y);
for (i = 0; i < src->n; i++) {
trans = path_transition_left_edge(ctx, src->x[i], src->y[i]);
@@ -222,6 +225,9 @@ clip_polygon_right(struct clip_context *ctx, const struct polygon8 *src,
enum path_transition trans;
int i;
+ if (src->n < 2)
+ return 0;
+
clip_context_prepare(ctx, src, dst_x, dst_y);
for (i = 0; i < src->n; i++) {
trans = path_transition_right_edge(ctx, src->x[i], src->y[i]);
@@ -238,6 +244,9 @@ clip_polygon_top(struct clip_context *ctx, const struct polygon8 *src,
enum path_transition trans;
int i;
+ if (src->n < 2)
+ return 0;
+
clip_context_prepare(ctx, src, dst_x, dst_y);
for (i = 0; i < src->n; i++) {
trans = path_transition_top_edge(ctx, src->x[i], src->y[i]);
@@ -254,6 +263,9 @@ clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src,
enum path_transition trans;
int i;
+ if (src->n < 2)
+ return 0;
+
clip_context_prepare(ctx, src, dst_x, dst_y);
for (i = 0; i < src->n; i++) {
trans = path_transition_bottom_edge(ctx, src->x[i], src->y[i]);
diff --git a/src/weston-egl-ext.h b/src/weston-egl-ext.h
index 8ddf97f0..48883233 100644
--- a/src/weston-egl-ext.h
+++ b/src/weston-egl-ext.h
@@ -51,7 +51,15 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
+#endif
+
+#ifndef EGL_WL_create_wayland_buffer_from_image
+#define EGL_WL_create_wayland_buffer_from_image 1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI struct wl_buffer * EGLAPIENTRY eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image);
+#endif
+typedef struct wl_buffer * (EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL) (EGLDisplay dpy, EGLImageKHR image);
#endif
#ifndef EGL_TEXTURE_EXTERNAL_WL
diff --git a/tests/matrix-test.c b/tests/matrix-test.c
index 7b414c9a..6bf4ba3a 100644
--- a/tests/matrix-test.c
+++ b/tests/matrix-test.c
@@ -288,7 +288,7 @@ test_loop_speed_matrixvector(void)
}
t = read_timer();
- printf("%lu iterations in %f seconds, avg. %.1f us/iter.\n",
+ printf("%lu iterations in %f seconds, avg. %.1f ns/iter.\n",
count, t, 1e9 * t / count);
}
@@ -315,7 +315,7 @@ test_loop_speed_inversetransform(void)
}
t = read_timer();
- printf("%lu iterations in %f seconds, avg. %.1f us/iter.\n",
+ printf("%lu iterations in %f seconds, avg. %.1f ns/iter.\n",
count, t, 1e9 * t / count);
}
diff --git a/tests/weston-test.c b/tests/weston-test.c
index ca2f2194..f1e45c10 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -251,6 +251,11 @@ bind_test(struct wl_client *client, void *data, uint32_t version, uint32_t id)
struct wl_resource *resource;
resource = wl_resource_create(client, &wl_test_interface, 1, id);
+ if (!resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
wl_resource_set_implementation(resource,
&test_implementation, test, NULL);
diff --git a/tests/weston-tests-env b/tests/weston-tests-env
index 473e0925..e332354c 100755
--- a/tests/weston-tests-env
+++ b/tests/weston-tests-env
@@ -28,6 +28,7 @@ XWAYLAND_PLUGIN=$abs_builddir/.libs/xwayland.so
case $TESTNAME in
*.la|*.so)
+ WESTON_BUILD_DIR=$abs_builddir \
$WESTON --backend=$BACKEND \
--no-config \
--shell=$SHELL_PLUGIN \
@@ -37,6 +38,7 @@ case $TESTNAME in
&> "$OUTLOG"
;;
*)
+ WESTON_BUILD_DIR=$abs_builddir \
WESTON_TEST_CLIENT_PATH=$abs_builddir/$TESTNAME $WESTON \
--socket=test-$(basename $TESTNAME) \
--backend=$BACKEND \
diff --git a/xwayland/launcher.c b/xwayland/launcher.c
index bf1e17eb..df2efd2e 100644
--- a/xwayland/launcher.c
+++ b/xwayland/launcher.c
@@ -43,7 +43,7 @@ handle_sigusr1(int signal_number, void *data)
/* We'd be safer if we actually had the struct
* signalfd_siginfo from the signalfd data and could verify
* this came from Xwayland.*/
- weston_wm_create(wxs, wxs->wm_fd);
+ wxs->wm = weston_wm_create(wxs, wxs->wm_fd);
wl_event_source_remove(wxs->sigusr1_source);
return 1;
@@ -163,8 +163,10 @@ weston_xserver_shutdown(struct weston_xserver *wxs)
}
close(wxs->abstract_fd);
close(wxs->unix_fd);
- if (wxs->wm)
+ if (wxs->wm) {
weston_wm_destroy(wxs->wm);
+ wxs->wm = NULL;
+ }
wxs->loop = NULL;
}
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 6cac2782..4e91f9dc 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -701,6 +701,9 @@ weston_wm_window_activate(struct wl_listener *listener, void *data)
}
if (window) {
+ if (window->override_redirect)
+ return;
+
client_message.response_type = XCB_CLIENT_MESSAGE;
client_message.format = 32;
client_message.window = window->id;
@@ -1244,8 +1247,8 @@ weston_wm_window_handle_moveresize(struct weston_wm_window *window,
struct weston_shell_interface *shell_interface =
&wm->server->compositor->shell_interface;
- if (seat->pointer->button_count != 1 || !window->view
- || seat->pointer->focus != window->view)
+ if (seat == NULL || seat->pointer->button_count != 1
+ || !window->view || seat->pointer->focus != window->view)
return;
detail = client_message->data.data32[2];
@@ -1648,12 +1651,14 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
weston_wm_window_schedule_repaint(window);
if (frame_status(window->frame) & FRAME_STATUS_MOVE) {
- shell_interface->move(window->shsurf, seat);
+ if (seat != NULL)
+ shell_interface->move(window->shsurf, seat);
frame_status_clear(window->frame, FRAME_STATUS_MOVE);
}
if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
- shell_interface->resize(window->shsurf, seat, location);
+ if (seat != NULL)
+ shell_interface->resize(window->shsurf, seat, location);
frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
}
@@ -2188,15 +2193,12 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
struct theme *t = window->wm->theme;
int vborder, hborder;
- if (window->fullscreen) {
+ if (window->decorate) {
+ hborder = 2 * t->width;
+ vborder = t->titlebar_height + t->width;
+ } else {
hborder = 0;
vborder = 0;
- } else if (window->decorate) {
- hborder = 2 * (t->margin + t->width);
- vborder = 2 * t->margin + t->titlebar_height + t->width;
- } else {
- hborder = 2 * t->margin;
- vborder = 2 * t->margin;
}
if (width > hborder)