2013-04-18 23:07:39 +04:00
|
|
|
/*
|
|
|
|
* Copyright © 2013 Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and
|
|
|
|
* its documentation for any purpose is hereby granted without fee, provided
|
|
|
|
* that the above copyright notice appear in all copies and that both that
|
|
|
|
* copyright notice and this permission notice appear in supporting
|
|
|
|
* documentation, and that the name of the copyright holders not be used in
|
|
|
|
* advertising or publicity pertaining to distribution of the software
|
|
|
|
* without specific, written prior permission. The copyright holders make
|
|
|
|
* no representations about the suitability of this software for any
|
|
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
|
|
|
*
|
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
|
|
|
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
|
|
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2013-08-15 04:10:24 +04:00
|
|
|
#include "config.h"
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
2013-04-18 23:40:10 +04:00
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <unistd.h>
|
2013-06-24 19:52:44 +04:00
|
|
|
#include <fcntl.h>
|
2013-12-14 00:10:56 +04:00
|
|
|
#include <limits.h>
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
#include "../shared/os-compatibility.h"
|
2013-04-18 23:07:39 +04:00
|
|
|
#include "compositor.h"
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
static void
|
|
|
|
empty_region(pixman_region32_t *region)
|
|
|
|
{
|
|
|
|
pixman_region32_fini(region);
|
|
|
|
pixman_region32_init(region);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void unbind_resource(struct wl_resource *resource)
|
|
|
|
{
|
2013-06-14 19:08:00 +04:00
|
|
|
wl_list_remove(wl_resource_get_link(resource));
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-10-18 01:04:08 +04:00
|
|
|
WL_EXPORT void
|
2013-05-07 05:51:21 +04:00
|
|
|
weston_seat_repick(struct weston_seat *seat)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-07-04 08:58:07 +04:00
|
|
|
const struct weston_pointer *pointer = seat->pointer;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-07-04 08:58:07 +04:00
|
|
|
if (pointer == NULL)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
|
2013-07-04 08:58:07 +04:00
|
|
|
pointer->grab->interface->focus(seat->pointer->grab);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_compositor_idle_inhibit(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
weston_compositor_wake(compositor);
|
|
|
|
compositor->idle_inhibit++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_compositor_idle_release(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
compositor->idle_inhibit--;
|
|
|
|
weston_compositor_wake(compositor);
|
|
|
|
}
|
|
|
|
|
2013-11-20 21:00:24 +04:00
|
|
|
static void
|
|
|
|
pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_pointer *pointer =
|
|
|
|
container_of(listener, struct weston_pointer,
|
|
|
|
focus_view_listener);
|
|
|
|
|
|
|
|
weston_pointer_set_focus(pointer, NULL, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_pointer *pointer =
|
|
|
|
container_of(listener, struct weston_pointer,
|
|
|
|
focus_resource_listener);
|
|
|
|
|
|
|
|
weston_pointer_set_focus(pointer, NULL, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_keyboard *keyboard =
|
|
|
|
container_of(listener, struct weston_keyboard,
|
|
|
|
focus_resource_listener);
|
|
|
|
|
|
|
|
weston_keyboard_set_focus(keyboard, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
touch_focus_view_destroyed(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_touch *touch =
|
|
|
|
container_of(listener, struct weston_touch,
|
|
|
|
focus_view_listener);
|
|
|
|
|
|
|
|
weston_touch_set_focus(touch->seat, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_touch *touch =
|
|
|
|
container_of(listener, struct weston_touch,
|
|
|
|
focus_resource_listener);
|
|
|
|
|
|
|
|
weston_touch_set_focus(touch->seat, NULL);
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
static void
|
2013-09-19 20:32:00 +04:00
|
|
|
move_resources(struct wl_list *destination, struct wl_list *source)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_list_insert_list(destination, source);
|
|
|
|
wl_list_init(source);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-09-19 20:32:00 +04:00
|
|
|
move_resources_for_client(struct wl_list *destination,
|
|
|
|
struct wl_list *source,
|
|
|
|
struct wl_client *client)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_resource *resource, *tmp;
|
|
|
|
wl_resource_for_each_safe(resource, tmp, source) {
|
|
|
|
if (wl_resource_get_client(resource) == client) {
|
|
|
|
wl_list_remove(wl_resource_get_link(resource));
|
|
|
|
wl_list_insert(destination,
|
|
|
|
wl_resource_get_link(resource));
|
|
|
|
}
|
|
|
|
}
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-10-29 02:32:02 +04:00
|
|
|
default_grab_pointer_focus(struct weston_pointer_grab *grab)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-07 06:15:05 +04:00
|
|
|
struct weston_pointer *pointer = grab->pointer;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view;
|
2013-05-09 06:02:59 +04:00
|
|
|
wl_fixed_t sx, sy;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
|
|
|
if (pointer->button_count > 0)
|
|
|
|
return;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view = weston_compositor_pick_view(pointer->seat->compositor,
|
|
|
|
pointer->x, pointer->y,
|
|
|
|
&sx, &sy);
|
2013-05-09 06:02:59 +04:00
|
|
|
|
2014-02-06 05:14:42 +04:00
|
|
|
if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_pointer_set_focus(pointer, view, sx, sy);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-11-15 02:42:52 +04:00
|
|
|
default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
|
|
|
|
wl_fixed_t x, wl_fixed_t y)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-09 05:03:21 +04:00
|
|
|
struct weston_pointer *pointer = grab->pointer;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_list *resource_list;
|
|
|
|
struct wl_resource *resource;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2014-02-06 05:14:42 +04:00
|
|
|
if (pointer->focus)
|
|
|
|
weston_view_from_global_fixed(pointer->focus, x, y,
|
|
|
|
&pointer->sx, &pointer->sy);
|
|
|
|
|
2013-11-15 02:42:52 +04:00
|
|
|
weston_pointer_move(pointer, x, y);
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
resource_list = &pointer->focus_resource_list;
|
|
|
|
wl_resource_for_each(resource, resource_list) {
|
2014-02-06 05:14:42 +04:00
|
|
|
wl_pointer_send_motion(resource, time,
|
|
|
|
pointer->sx, pointer->sy);
|
2013-05-09 05:03:21 +04:00
|
|
|
}
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-10-29 02:32:02 +04:00
|
|
|
default_grab_pointer_button(struct weston_pointer_grab *grab,
|
|
|
|
uint32_t time, uint32_t button, uint32_t state_w)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-07 06:15:05 +04:00
|
|
|
struct weston_pointer *pointer = grab->pointer;
|
2013-05-09 00:47:00 +04:00
|
|
|
struct weston_compositor *compositor = pointer->seat->compositor;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view;
|
2013-04-18 23:07:39 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
uint32_t serial;
|
|
|
|
enum wl_pointer_button_state state = state_w;
|
2013-07-22 20:31:38 +04:00
|
|
|
struct wl_display *display = compositor->wl_display;
|
2013-05-09 00:47:00 +04:00
|
|
|
wl_fixed_t sx, sy;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_list *resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
resource_list = &pointer->focus_resource_list;
|
|
|
|
if (!wl_list_empty(resource_list)) {
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, resource_list)
|
|
|
|
wl_pointer_send_button(resource,
|
|
|
|
serial,
|
|
|
|
time,
|
|
|
|
button,
|
|
|
|
state_w);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pointer->button_count == 0 &&
|
2013-05-09 00:47:00 +04:00
|
|
|
state == WL_POINTER_BUTTON_STATE_RELEASED) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view = weston_compositor_pick_view(compositor,
|
|
|
|
pointer->x, pointer->y,
|
|
|
|
&sx, &sy);
|
2013-05-09 00:47:00 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_pointer_set_focus(pointer, view, sx, sy);
|
2013-05-09 00:47:00 +04:00
|
|
|
}
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2013-10-26 01:18:05 +04:00
|
|
|
static void
|
|
|
|
default_grab_pointer_cancel(struct weston_pointer_grab *grab)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-05-07 06:15:05 +04:00
|
|
|
static const struct weston_pointer_grab_interface
|
2013-04-18 23:07:39 +04:00
|
|
|
default_pointer_grab_interface = {
|
2013-10-29 02:32:02 +04:00
|
|
|
default_grab_pointer_focus,
|
|
|
|
default_grab_pointer_motion,
|
|
|
|
default_grab_pointer_button,
|
2013-10-26 01:18:05 +04:00
|
|
|
default_grab_pointer_cancel,
|
2013-04-18 23:07:39 +04:00
|
|
|
};
|
|
|
|
|
2013-05-07 06:19:57 +04:00
|
|
|
static void
|
|
|
|
default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
|
|
|
|
int touch_id, wl_fixed_t sx, wl_fixed_t sy)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-07 06:19:57 +04:00
|
|
|
struct weston_touch *touch = grab->touch;
|
2013-07-22 20:31:38 +04:00
|
|
|
struct wl_display *display = touch->seat->compositor->wl_display;
|
2013-04-18 23:07:39 +04:00
|
|
|
uint32_t serial;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
struct wl_list *resource_list;
|
|
|
|
|
|
|
|
resource_list = &touch->focus_resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
if (!wl_list_empty(resource_list) && touch->focus) {
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, resource_list)
|
|
|
|
wl_touch_send_down(resource, serial, time,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
touch->focus->surface->resource,
|
2013-09-19 20:32:00 +04:00
|
|
|
touch_id, sx, sy);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-07 06:19:57 +04:00
|
|
|
static void
|
|
|
|
default_grab_touch_up(struct weston_touch_grab *grab,
|
|
|
|
uint32_t time, int touch_id)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-07 06:19:57 +04:00
|
|
|
struct weston_touch *touch = grab->touch;
|
2013-07-22 20:31:38 +04:00
|
|
|
struct wl_display *display = touch->seat->compositor->wl_display;
|
2013-04-18 23:07:39 +04:00
|
|
|
uint32_t serial;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
struct wl_list *resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
resource_list = &touch->focus_resource_list;
|
|
|
|
|
|
|
|
if (!wl_list_empty(resource_list)) {
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, resource_list)
|
|
|
|
wl_touch_send_up(resource, serial, time, touch_id);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-07 06:19:57 +04:00
|
|
|
static void
|
|
|
|
default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
|
|
|
|
int touch_id, wl_fixed_t sx, wl_fixed_t sy)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-07 06:19:57 +04:00
|
|
|
struct weston_touch *touch = grab->touch;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
struct wl_list *resource_list;
|
|
|
|
|
|
|
|
resource_list = &touch->focus_resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, resource_list) {
|
|
|
|
wl_touch_send_motion(resource, time,
|
2013-05-07 06:19:57 +04:00
|
|
|
touch_id, sx, sy);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-12 11:39:51 +04:00
|
|
|
static void
|
|
|
|
default_grab_touch_frame(struct weston_touch_grab *grab)
|
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
wl_resource_for_each(resource, &grab->touch->focus_resource_list)
|
|
|
|
wl_touch_send_frame(resource);
|
|
|
|
}
|
|
|
|
|
2013-10-26 01:18:05 +04:00
|
|
|
static void
|
|
|
|
default_grab_touch_cancel(struct weston_touch_grab *grab)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-05-07 06:19:57 +04:00
|
|
|
static const struct weston_touch_grab_interface default_touch_grab_interface = {
|
2013-04-18 23:07:39 +04:00
|
|
|
default_grab_touch_down,
|
|
|
|
default_grab_touch_up,
|
2013-10-26 01:18:05 +04:00
|
|
|
default_grab_touch_motion,
|
2014-04-12 11:39:51 +04:00
|
|
|
default_grab_touch_frame,
|
2013-10-26 01:18:05 +04:00
|
|
|
default_grab_touch_cancel,
|
2013-04-18 23:07:39 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2013-10-29 02:32:02 +04:00
|
|
|
default_grab_keyboard_key(struct weston_keyboard_grab *grab,
|
|
|
|
uint32_t time, uint32_t key, uint32_t state)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-04-18 23:25:39 +04:00
|
|
|
struct weston_keyboard *keyboard = grab->keyboard;
|
2013-04-18 23:07:39 +04:00
|
|
|
struct wl_resource *resource;
|
2013-07-22 20:31:38 +04:00
|
|
|
struct wl_display *display = keyboard->seat->compositor->wl_display;
|
2013-04-18 23:07:39 +04:00
|
|
|
uint32_t serial;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_list *resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
resource_list = &keyboard->focus_resource_list;
|
|
|
|
if (!wl_list_empty(resource_list)) {
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, resource_list)
|
|
|
|
wl_keyboard_send_key(resource,
|
|
|
|
serial,
|
|
|
|
time,
|
|
|
|
key,
|
|
|
|
state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
send_modifiers_to_resource(struct weston_keyboard *keyboard,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
uint32_t serial)
|
|
|
|
{
|
|
|
|
wl_keyboard_send_modifiers(resource,
|
|
|
|
serial,
|
|
|
|
keyboard->modifiers.mods_depressed,
|
|
|
|
keyboard->modifiers.mods_latched,
|
|
|
|
keyboard->modifiers.mods_locked,
|
|
|
|
keyboard->modifiers.group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
send_modifiers_to_client_in_list(struct wl_client *client,
|
|
|
|
struct wl_list *list,
|
|
|
|
uint32_t serial,
|
|
|
|
struct weston_keyboard *keyboard)
|
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
wl_resource_for_each(resource, list) {
|
|
|
|
if (wl_resource_get_client(resource) == client)
|
|
|
|
send_modifiers_to_resource(keyboard,
|
|
|
|
resource,
|
|
|
|
serial);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct wl_resource *
|
2013-05-08 17:54:37 +04:00
|
|
|
find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
if (!surface)
|
|
|
|
return NULL;
|
|
|
|
|
2013-06-14 19:08:00 +04:00
|
|
|
if (!surface->resource)
|
|
|
|
return NULL;
|
2013-09-17 13:54:09 +04:00
|
|
|
|
2013-06-14 19:08:00 +04:00
|
|
|
return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
static struct wl_resource *
|
|
|
|
find_resource_for_view(struct wl_list *list, struct weston_view *view)
|
|
|
|
{
|
|
|
|
if (!view)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return find_resource_for_surface(list, view->surface);
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
static void
|
2013-10-29 02:32:02 +04:00
|
|
|
default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
|
|
|
|
uint32_t serial, uint32_t mods_depressed,
|
|
|
|
uint32_t mods_latched,
|
|
|
|
uint32_t mods_locked, uint32_t group)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-04-18 23:25:39 +04:00
|
|
|
struct weston_keyboard *keyboard = grab->keyboard;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct weston_pointer *pointer = grab->keyboard->seat->pointer;
|
|
|
|
struct wl_resource *resource;
|
|
|
|
struct wl_list *resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
resource_list = &keyboard->focus_resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, resource_list) {
|
|
|
|
wl_keyboard_send_modifiers(resource, serial, mods_depressed,
|
|
|
|
mods_latched, mods_locked, group);
|
|
|
|
}
|
2013-11-15 06:06:16 +04:00
|
|
|
if (pointer && pointer->focus && pointer->focus->surface->resource &&
|
|
|
|
pointer->focus->surface != keyboard->focus) {
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_client *pointer_client =
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_resource_get_client(pointer->focus->surface->resource);
|
2013-09-19 20:32:00 +04:00
|
|
|
send_modifiers_to_client_in_list(pointer_client,
|
|
|
|
&keyboard->resource_list,
|
|
|
|
serial,
|
|
|
|
keyboard);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-26 01:18:05 +04:00
|
|
|
static void
|
|
|
|
default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:25:39 +04:00
|
|
|
static const struct weston_keyboard_grab_interface
|
2013-04-18 23:07:39 +04:00
|
|
|
default_keyboard_grab_interface = {
|
2013-10-29 02:32:02 +04:00
|
|
|
default_grab_keyboard_key,
|
|
|
|
default_grab_keyboard_modifiers,
|
2013-10-26 01:18:05 +04:00
|
|
|
default_grab_keyboard_cancel,
|
2013-04-18 23:07:39 +04:00
|
|
|
};
|
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
static void
|
|
|
|
pointer_unmap_sprite(struct weston_pointer *pointer)
|
|
|
|
{
|
2014-11-12 17:42:52 +03:00
|
|
|
struct weston_surface *surface = pointer->sprite->surface;
|
|
|
|
|
|
|
|
if (weston_surface_is_mapped(surface))
|
|
|
|
weston_surface_unmap(surface);
|
2013-05-08 23:02:05 +04:00
|
|
|
|
|
|
|
wl_list_remove(&pointer->sprite_destroy_listener.link);
|
2014-11-12 17:42:52 +03:00
|
|
|
surface->configure = NULL;
|
|
|
|
surface->configure_private = NULL;
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
weston_surface_set_label_func(surface, NULL);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_destroy(pointer->sprite);
|
2013-05-08 23:02:05 +04:00
|
|
|
pointer->sprite = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_pointer *pointer =
|
|
|
|
container_of(listener, struct weston_pointer,
|
|
|
|
sprite_destroy_listener);
|
|
|
|
|
|
|
|
pointer->sprite = NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-03 01:05:05 +04:00
|
|
|
static void
|
|
|
|
weston_pointer_reset_state(struct weston_pointer *pointer)
|
|
|
|
{
|
|
|
|
pointer->button_count = 0;
|
|
|
|
}
|
|
|
|
|
2014-01-29 20:47:51 +04:00
|
|
|
static void
|
|
|
|
weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
|
|
|
|
|
2013-05-08 07:52:07 +04:00
|
|
|
WL_EXPORT struct weston_pointer *
|
2013-11-15 02:42:53 +04:00
|
|
|
weston_pointer_create(struct weston_seat *seat)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-08 07:52:07 +04:00
|
|
|
struct weston_pointer *pointer;
|
|
|
|
|
2013-08-08 05:57:05 +04:00
|
|
|
pointer = zalloc(sizeof *pointer);
|
2013-05-08 07:52:07 +04:00
|
|
|
if (pointer == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
wl_list_init(&pointer->resource_list);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_list_init(&pointer->focus_resource_list);
|
2013-11-15 02:42:53 +04:00
|
|
|
weston_pointer_set_default_grab(pointer,
|
|
|
|
seat->compositor->default_pointer_grab);
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_init(&pointer->focus_resource_listener.link);
|
|
|
|
pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
|
2013-04-18 23:07:39 +04:00
|
|
|
pointer->default_grab.pointer = pointer;
|
|
|
|
pointer->grab = &pointer->default_grab;
|
2013-11-15 02:42:50 +04:00
|
|
|
wl_signal_init(&pointer->motion_signal);
|
2013-11-19 14:37:15 +04:00
|
|
|
wl_signal_init(&pointer->focus_signal);
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_init(&pointer->focus_view_listener.link);
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
/* FIXME: Pick better co-ords. */
|
|
|
|
pointer->x = wl_fixed_from_int(100);
|
|
|
|
pointer->y = wl_fixed_from_int(100);
|
2013-05-08 07:52:07 +04:00
|
|
|
|
2014-01-29 20:47:51 +04:00
|
|
|
pointer->output_destroy_listener.notify =
|
|
|
|
weston_pointer_handle_output_destroy;
|
|
|
|
wl_signal_add(&seat->compositor->output_destroyed_signal,
|
|
|
|
&pointer->output_destroy_listener);
|
|
|
|
|
2013-05-08 07:52:07 +04:00
|
|
|
return pointer;
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
2013-05-08 07:52:07 +04:00
|
|
|
weston_pointer_destroy(struct weston_pointer *pointer)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-08 23:02:05 +04:00
|
|
|
if (pointer->sprite)
|
|
|
|
pointer_unmap_sprite(pointer);
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
/* XXX: What about pointer->resource_list? */
|
2013-09-19 20:32:00 +04:00
|
|
|
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_remove(&pointer->focus_resource_listener.link);
|
|
|
|
wl_list_remove(&pointer->focus_view_listener.link);
|
2014-01-29 20:47:51 +04:00
|
|
|
wl_list_remove(&pointer->output_destroy_listener.link);
|
2013-05-08 07:52:07 +04:00
|
|
|
free(pointer);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2013-11-15 02:42:53 +04:00
|
|
|
void
|
|
|
|
weston_pointer_set_default_grab(struct weston_pointer *pointer,
|
|
|
|
const struct weston_pointer_grab_interface *interface)
|
|
|
|
{
|
|
|
|
if (interface)
|
|
|
|
pointer->default_grab.interface = interface;
|
|
|
|
else
|
|
|
|
pointer->default_grab.interface =
|
|
|
|
&default_pointer_grab_interface;
|
|
|
|
}
|
|
|
|
|
2013-05-08 07:52:07 +04:00
|
|
|
WL_EXPORT struct weston_keyboard *
|
|
|
|
weston_keyboard_create(void)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-08 07:52:07 +04:00
|
|
|
struct weston_keyboard *keyboard;
|
|
|
|
|
2013-08-08 05:57:05 +04:00
|
|
|
keyboard = zalloc(sizeof *keyboard);
|
2013-05-08 07:52:07 +04:00
|
|
|
if (keyboard == NULL)
|
2013-09-19 20:32:00 +04:00
|
|
|
return NULL;
|
2013-05-08 07:52:07 +04:00
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
wl_list_init(&keyboard->resource_list);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_list_init(&keyboard->focus_resource_list);
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_init(&keyboard->focus_resource_listener.link);
|
|
|
|
keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
|
2013-04-18 23:07:39 +04:00
|
|
|
wl_array_init(&keyboard->keys);
|
|
|
|
keyboard->default_grab.interface = &default_keyboard_grab_interface;
|
|
|
|
keyboard->default_grab.keyboard = keyboard;
|
|
|
|
keyboard->grab = &keyboard->default_grab;
|
|
|
|
wl_signal_init(&keyboard->focus_signal);
|
2013-05-08 07:52:07 +04:00
|
|
|
|
|
|
|
return keyboard;
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
static void
|
|
|
|
weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
WL_EXPORT void
|
2013-05-08 07:52:07 +04:00
|
|
|
weston_keyboard_destroy(struct weston_keyboard *keyboard)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
/* XXX: What about keyboard->resource_list? */
|
2013-09-19 20:32:00 +04:00
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
#ifdef ENABLE_XKBCOMMON
|
|
|
|
if (keyboard->seat->compositor->use_xkbcommon) {
|
2014-08-20 00:59:52 +04:00
|
|
|
xkb_state_unref(keyboard->xkb_state.state);
|
2013-12-03 12:14:26 +04:00
|
|
|
if (keyboard->xkb_info)
|
|
|
|
weston_xkb_info_destroy(keyboard->xkb_info);
|
2014-08-20 00:59:52 +04:00
|
|
|
xkb_keymap_unref(keyboard->pending_keymap);
|
2013-12-03 12:14:26 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
wl_array_release(&keyboard->keys);
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_remove(&keyboard->focus_resource_listener.link);
|
2013-05-08 07:52:07 +04:00
|
|
|
free(keyboard);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2013-12-03 01:05:04 +04:00
|
|
|
static void
|
|
|
|
weston_touch_reset_state(struct weston_touch *touch)
|
|
|
|
{
|
|
|
|
touch->num_tp = 0;
|
|
|
|
}
|
|
|
|
|
2013-05-08 07:52:07 +04:00
|
|
|
WL_EXPORT struct weston_touch *
|
|
|
|
weston_touch_create(void)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-05-08 07:52:07 +04:00
|
|
|
struct weston_touch *touch;
|
|
|
|
|
2013-08-08 05:57:05 +04:00
|
|
|
touch = zalloc(sizeof *touch);
|
2013-05-08 07:52:07 +04:00
|
|
|
if (touch == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
wl_list_init(&touch->resource_list);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_list_init(&touch->focus_resource_list);
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_init(&touch->focus_view_listener.link);
|
|
|
|
touch->focus_view_listener.notify = touch_focus_view_destroyed;
|
|
|
|
wl_list_init(&touch->focus_resource_listener.link);
|
|
|
|
touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
|
2013-04-18 23:07:39 +04:00
|
|
|
touch->default_grab.interface = &default_touch_grab_interface;
|
|
|
|
touch->default_grab.touch = touch;
|
|
|
|
touch->grab = &touch->default_grab;
|
|
|
|
wl_signal_init(&touch->focus_signal);
|
2013-05-08 07:52:07 +04:00
|
|
|
|
|
|
|
return touch;
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
2013-05-08 07:52:07 +04:00
|
|
|
weston_touch_destroy(struct weston_touch *touch)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
/* XXX: What about touch->resource_list? */
|
2013-09-19 20:32:00 +04:00
|
|
|
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_remove(&touch->focus_view_listener.link);
|
|
|
|
wl_list_remove(&touch->focus_resource_listener.link);
|
2013-05-08 07:52:07 +04:00
|
|
|
free(touch);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-05-07 07:19:49 +04:00
|
|
|
seat_send_updated_caps(struct weston_seat *seat)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
enum wl_seat_capability caps = 0;
|
2013-09-06 20:48:19 +04:00
|
|
|
struct wl_resource *resource;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->pointer_device_count > 0)
|
2013-04-18 23:07:39 +04:00
|
|
|
caps |= WL_SEAT_CAPABILITY_POINTER;
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->keyboard_device_count > 0)
|
2013-04-18 23:07:39 +04:00
|
|
|
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->touch_device_count > 0)
|
2013-04-18 23:07:39 +04:00
|
|
|
caps |= WL_SEAT_CAPABILITY_TOUCH;
|
|
|
|
|
2013-09-06 20:48:19 +04:00
|
|
|
wl_resource_for_each(resource, &seat->base_resource_list) {
|
|
|
|
wl_seat_send_capabilities(resource, caps);
|
2013-06-14 19:08:00 +04:00
|
|
|
}
|
2014-04-03 04:53:45 +04:00
|
|
|
wl_signal_emit(&seat->updated_caps_signal, seat);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
2013-05-07 06:15:05 +04:00
|
|
|
weston_pointer_set_focus(struct weston_pointer *pointer,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view,
|
2013-05-07 06:15:05 +04:00
|
|
|
wl_fixed_t sx, wl_fixed_t sy)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
2013-04-18 23:25:39 +04:00
|
|
|
struct weston_keyboard *kbd = pointer->seat->keyboard;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_resource *resource;
|
2013-07-22 20:31:38 +04:00
|
|
|
struct wl_display *display = pointer->seat->compositor->wl_display;
|
2013-04-18 23:07:39 +04:00
|
|
|
uint32_t serial;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_list *focus_resource_list;
|
2014-02-06 05:14:42 +04:00
|
|
|
int refocus = 0;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
if ((!pointer->focus && view) ||
|
|
|
|
(pointer->focus && !view) ||
|
2014-02-06 05:14:42 +04:00
|
|
|
(pointer->focus && pointer->focus->surface != view->surface) ||
|
|
|
|
pointer->sx != sx || pointer->sy != sy)
|
|
|
|
refocus = 1;
|
2013-09-19 20:32:00 +04:00
|
|
|
|
|
|
|
focus_resource_list = &pointer->focus_resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2014-02-06 05:14:42 +04:00
|
|
|
if (!wl_list_empty(focus_resource_list) && refocus) {
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, focus_resource_list) {
|
|
|
|
wl_pointer_send_leave(resource, serial,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pointer->focus->surface->resource);
|
2013-09-19 20:32:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
move_resources(&pointer->resource_list, focus_resource_list);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2014-02-06 05:14:42 +04:00
|
|
|
if (find_resource_for_view(&pointer->resource_list, view) && refocus) {
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_client *surface_client =
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_resource_get_client(view->surface->resource);
|
2013-09-19 20:32:00 +04:00
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (kbd && kbd->focus != view->surface)
|
2013-10-09 21:54:03 +04:00
|
|
|
send_modifiers_to_client_in_list(surface_client,
|
|
|
|
&kbd->resource_list,
|
|
|
|
serial,
|
|
|
|
kbd);
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
move_resources_for_client(focus_resource_list,
|
|
|
|
&pointer->resource_list,
|
|
|
|
surface_client);
|
|
|
|
|
|
|
|
wl_resource_for_each(resource, focus_resource_list) {
|
|
|
|
wl_pointer_send_enter(resource,
|
|
|
|
serial,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->surface->resource,
|
2013-09-19 20:32:00 +04:00
|
|
|
sx, sy);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
2013-09-19 20:32:00 +04:00
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
pointer->focus_serial = serial;
|
2013-12-06 15:46:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_remove(&pointer->focus_view_listener.link);
|
|
|
|
wl_list_init(&pointer->focus_view_listener.link);
|
|
|
|
wl_list_remove(&pointer->focus_resource_listener.link);
|
|
|
|
wl_list_init(&pointer->focus_resource_listener.link);
|
|
|
|
if (view)
|
|
|
|
wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
|
|
|
|
if (view && view->surface->resource)
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_resource_add_destroy_listener(view->surface->resource,
|
|
|
|
&pointer->focus_resource_listener);
|
2013-04-18 23:07:39 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pointer->focus = view;
|
2013-11-20 21:00:24 +04:00
|
|
|
pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
|
2014-02-06 05:14:42 +04:00
|
|
|
pointer->sx = sx;
|
|
|
|
pointer->sy = sy;
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
wl_signal_emit(&pointer->focus_signal, pointer);
|
|
|
|
}
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
static void
|
|
|
|
send_enter_to_resource_list(struct wl_list *list,
|
|
|
|
struct weston_keyboard *keyboard,
|
|
|
|
struct weston_surface *surface,
|
|
|
|
uint32_t serial)
|
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
wl_resource_for_each(resource, list) {
|
|
|
|
send_modifiers_to_resource(keyboard, resource, serial);
|
|
|
|
wl_keyboard_send_enter(resource, serial,
|
|
|
|
surface->resource,
|
|
|
|
&keyboard->keys);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
WL_EXPORT void
|
2013-04-18 23:25:39 +04:00
|
|
|
weston_keyboard_set_focus(struct weston_keyboard *keyboard,
|
2013-05-08 17:54:37 +04:00
|
|
|
struct weston_surface *surface)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
2013-07-22 20:31:38 +04:00
|
|
|
struct wl_display *display = keyboard->seat->compositor->wl_display;
|
2013-04-18 23:07:39 +04:00
|
|
|
uint32_t serial;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_list *focus_resource_list;
|
2013-04-18 23:07:39 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
focus_resource_list = &keyboard->focus_resource_list;
|
|
|
|
|
|
|
|
if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_for_each(resource, focus_resource_list) {
|
|
|
|
wl_keyboard_send_leave(resource, serial,
|
|
|
|
keyboard->focus->resource);
|
|
|
|
}
|
|
|
|
move_resources(&keyboard->resource_list, focus_resource_list);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
if (find_resource_for_surface(&keyboard->resource_list, surface) &&
|
|
|
|
keyboard->focus != surface) {
|
|
|
|
struct wl_client *surface_client =
|
|
|
|
wl_resource_get_client(surface->resource);
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
serial = wl_display_next_serial(display);
|
2013-09-19 20:32:00 +04:00
|
|
|
|
|
|
|
move_resources_for_client(focus_resource_list,
|
|
|
|
&keyboard->resource_list,
|
|
|
|
surface_client);
|
|
|
|
send_enter_to_resource_list(focus_resource_list,
|
|
|
|
keyboard,
|
|
|
|
surface,
|
|
|
|
serial);
|
2013-04-18 23:07:39 +04:00
|
|
|
keyboard->focus_serial = serial;
|
2013-12-06 15:46:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_remove(&keyboard->focus_resource_listener.link);
|
|
|
|
wl_list_init(&keyboard->focus_resource_listener.link);
|
|
|
|
if (surface && surface->resource)
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_resource_add_destroy_listener(surface->resource,
|
|
|
|
&keyboard->focus_resource_listener);
|
2013-04-18 23:07:39 +04:00
|
|
|
|
|
|
|
keyboard->focus = surface;
|
|
|
|
wl_signal_emit(&keyboard->focus_signal, keyboard);
|
|
|
|
}
|
|
|
|
|
2014-11-22 12:16:56 +03:00
|
|
|
/* Users of this function must manually manage the keyboard focus */
|
2013-04-18 23:07:39 +04:00
|
|
|
WL_EXPORT void
|
2013-04-18 23:25:39 +04:00
|
|
|
weston_keyboard_start_grab(struct weston_keyboard *keyboard,
|
|
|
|
struct weston_keyboard_grab *grab)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
keyboard->grab = grab;
|
|
|
|
grab->keyboard = keyboard;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
2013-04-18 23:25:39 +04:00
|
|
|
weston_keyboard_end_grab(struct weston_keyboard *keyboard)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
keyboard->grab = &keyboard->default_grab;
|
|
|
|
}
|
|
|
|
|
2013-10-26 01:18:05 +04:00
|
|
|
static void
|
|
|
|
weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
|
|
|
|
{
|
|
|
|
keyboard->grab->interface->cancel(keyboard->grab);
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
WL_EXPORT void
|
2013-05-07 06:15:05 +04:00
|
|
|
weston_pointer_start_grab(struct weston_pointer *pointer,
|
|
|
|
struct weston_pointer_grab *grab)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
pointer->grab = grab;
|
|
|
|
grab->pointer = pointer;
|
2013-07-04 08:58:07 +04:00
|
|
|
pointer->grab->interface->focus(pointer->grab);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
2013-05-07 06:15:05 +04:00
|
|
|
weston_pointer_end_grab(struct weston_pointer *pointer)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
pointer->grab = &pointer->default_grab;
|
2013-07-04 08:58:07 +04:00
|
|
|
pointer->grab->interface->focus(pointer->grab);
|
2013-04-18 23:07:39 +04:00
|
|
|
}
|
|
|
|
|
2013-10-26 01:18:05 +04:00
|
|
|
static void
|
|
|
|
weston_pointer_cancel_grab(struct weston_pointer *pointer)
|
|
|
|
{
|
|
|
|
pointer->grab->interface->cancel(pointer->grab);
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:07:39 +04:00
|
|
|
WL_EXPORT void
|
2013-05-07 06:19:57 +04:00
|
|
|
weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
touch->grab = grab;
|
|
|
|
grab->touch = touch;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
2013-05-07 06:19:57 +04:00
|
|
|
weston_touch_end_grab(struct weston_touch *touch)
|
2013-04-18 23:07:39 +04:00
|
|
|
{
|
|
|
|
touch->grab = &touch->default_grab;
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-10-26 01:18:05 +04:00
|
|
|
static void
|
|
|
|
weston_touch_cancel_grab(struct weston_touch *touch)
|
|
|
|
{
|
|
|
|
touch->grab->interface->cancel(touch->grab);
|
|
|
|
}
|
|
|
|
|
2013-12-14 00:10:56 +04:00
|
|
|
static void
|
|
|
|
weston_pointer_clamp_for_output(struct weston_pointer *pointer,
|
|
|
|
struct weston_output *output,
|
|
|
|
wl_fixed_t *fx, wl_fixed_t *fy)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
x = wl_fixed_to_int(*fx);
|
|
|
|
y = wl_fixed_to_int(*fy);
|
|
|
|
|
|
|
|
if (x < output->x)
|
|
|
|
*fx = wl_fixed_from_int(output->x);
|
|
|
|
else if (x >= output->x + output->width)
|
|
|
|
*fx = wl_fixed_from_int(output->x +
|
|
|
|
output->width - 1);
|
|
|
|
if (y < output->y)
|
|
|
|
*fy = wl_fixed_from_int(output->y);
|
|
|
|
else if (y >= output->y + output->height)
|
|
|
|
*fy = wl_fixed_from_int(output->y +
|
|
|
|
output->height - 1);
|
|
|
|
}
|
|
|
|
|
2013-06-25 21:56:41 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-06-25 21:56:41 +04:00
|
|
|
struct weston_compositor *ec = pointer->seat->compositor;
|
2013-04-18 23:40:10 +04:00
|
|
|
struct weston_output *output, *prev = NULL;
|
|
|
|
int x, y, old_x, old_y, valid = 0;
|
|
|
|
|
|
|
|
x = wl_fixed_to_int(*fx);
|
|
|
|
y = wl_fixed_to_int(*fy);
|
2013-06-25 21:56:41 +04:00
|
|
|
old_x = wl_fixed_to_int(pointer->x);
|
|
|
|
old_y = wl_fixed_to_int(pointer->y);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
wl_list_for_each(output, &ec->output_list, link) {
|
2013-06-25 21:56:42 +04:00
|
|
|
if (pointer->seat->output && pointer->seat->output != output)
|
|
|
|
continue;
|
2013-04-18 23:40:10 +04:00
|
|
|
if (pixman_region32_contains_point(&output->region,
|
|
|
|
x, y, NULL))
|
|
|
|
valid = 1;
|
|
|
|
if (pixman_region32_contains_point(&output->region,
|
|
|
|
old_x, old_y, NULL))
|
|
|
|
prev = output;
|
|
|
|
}
|
|
|
|
|
2013-06-25 21:56:42 +04:00
|
|
|
if (!prev)
|
|
|
|
prev = pointer->seat->output;
|
|
|
|
|
2013-12-14 00:10:56 +04:00
|
|
|
if (prev && !valid)
|
|
|
|
weston_pointer_clamp_for_output(pointer, prev, fx, fy);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Takes absolute values */
|
2013-11-15 02:42:52 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_pointer_move(struct weston_pointer *pointer, wl_fixed_t x, wl_fixed_t y)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
|
|
|
int32_t ix, iy;
|
|
|
|
|
2013-06-25 21:56:41 +04:00
|
|
|
weston_pointer_clamp (pointer, &x, &y);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
pointer->x = x;
|
|
|
|
pointer->y = y;
|
|
|
|
|
|
|
|
ix = wl_fixed_to_int(x);
|
|
|
|
iy = wl_fixed_to_int(y);
|
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
if (pointer->sprite) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_set_position(pointer->sprite,
|
|
|
|
ix - pointer->hotspot_x,
|
|
|
|
iy - pointer->hotspot_y);
|
|
|
|
weston_view_schedule_repaint(pointer->sprite);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
2013-11-15 02:42:50 +04:00
|
|
|
|
2013-11-15 02:42:52 +04:00
|
|
|
pointer->grab->interface->focus(pointer->grab);
|
2013-11-15 02:42:50 +04:00
|
|
|
wl_signal_emit(&pointer->motion_signal, pointer);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-12-14 00:10:56 +04:00
|
|
|
/** Verify if the pointer is in a valid position and move it if it isn't.
|
|
|
|
*/
|
2014-01-29 20:47:51 +04:00
|
|
|
static void
|
|
|
|
weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
|
2013-12-14 00:10:56 +04:00
|
|
|
{
|
2014-01-29 20:47:51 +04:00
|
|
|
struct weston_pointer *pointer;
|
|
|
|
struct weston_compositor *ec;
|
2013-12-14 00:10:56 +04:00
|
|
|
struct weston_output *output, *closest = NULL;
|
|
|
|
int x, y, distance, min = INT_MAX;
|
|
|
|
wl_fixed_t fx, fy;
|
|
|
|
|
2014-01-29 20:47:51 +04:00
|
|
|
pointer = container_of(listener, struct weston_pointer,
|
|
|
|
output_destroy_listener);
|
|
|
|
ec = pointer->seat->compositor;
|
|
|
|
|
2013-12-14 00:10:56 +04:00
|
|
|
x = wl_fixed_to_int(pointer->x);
|
|
|
|
y = wl_fixed_to_int(pointer->y);
|
|
|
|
|
|
|
|
wl_list_for_each(output, &ec->output_list, link) {
|
|
|
|
if (pixman_region32_contains_point(&output->region,
|
|
|
|
x, y, NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Aproximante the distance from the pointer to the center of
|
|
|
|
* the output. */
|
|
|
|
distance = abs(output->x + output->width / 2 - x) +
|
|
|
|
abs(output->y + output->height / 2 - y);
|
|
|
|
if (distance < min) {
|
|
|
|
min = distance;
|
|
|
|
closest = output;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Nothing to do if there's no output left. */
|
|
|
|
if (!closest)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fx = pointer->x;
|
|
|
|
fy = pointer->y;
|
|
|
|
|
|
|
|
weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
|
|
|
|
weston_pointer_move(pointer, fx, fy);
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
notify_motion(struct weston_seat *seat,
|
|
|
|
uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
|
|
|
|
{
|
|
|
|
struct weston_compositor *ec = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_pointer *pointer = seat->pointer;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
weston_compositor_wake(ec);
|
2013-11-15 02:42:52 +04:00
|
|
|
pointer->grab->interface->motion(pointer->grab, time, pointer->x + dx, pointer->y + dy);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-11-19 14:37:12 +04:00
|
|
|
static void
|
|
|
|
run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
2013-12-03 12:14:26 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-11-19 14:37:12 +04:00
|
|
|
uint32_t diff;
|
|
|
|
unsigned int i;
|
|
|
|
struct {
|
|
|
|
uint32_t xkb;
|
|
|
|
enum weston_keyboard_modifier weston;
|
|
|
|
} mods[] = {
|
2013-12-03 12:14:26 +04:00
|
|
|
{ keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
|
|
|
|
{ keyboard->xkb_info->alt_mod, MODIFIER_ALT },
|
|
|
|
{ keyboard->xkb_info->super_mod, MODIFIER_SUPER },
|
|
|
|
{ keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
|
2013-11-19 14:37:12 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
diff = new & ~old;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(mods); i++) {
|
|
|
|
if (diff & (1 << mods[i].xkb))
|
|
|
|
weston_compositor_run_modifier_binding(compositor,
|
|
|
|
seat,
|
|
|
|
mods[i].weston,
|
|
|
|
WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
|
|
}
|
|
|
|
|
|
|
|
diff = old & ~new;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(mods); i++) {
|
|
|
|
if (diff & (1 << mods[i].xkb))
|
|
|
|
weston_compositor_run_modifier_binding(compositor,
|
|
|
|
seat,
|
|
|
|
mods[i].weston,
|
|
|
|
WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
notify_motion_absolute(struct weston_seat *seat,
|
|
|
|
uint32_t time, wl_fixed_t x, wl_fixed_t y)
|
|
|
|
{
|
|
|
|
struct weston_compositor *ec = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_pointer *pointer = seat->pointer;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
weston_compositor_wake(ec);
|
2013-11-15 02:42:52 +04:00
|
|
|
pointer->grab->interface->motion(pointer->grab, time, x, y);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_activate(struct weston_surface *surface,
|
|
|
|
struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
if (seat->keyboard) {
|
2013-05-08 17:54:37 +04:00
|
|
|
weston_keyboard_set_focus(seat->keyboard, surface);
|
2013-05-07 07:19:49 +04:00
|
|
|
wl_data_device_set_keyboard_focus(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
wl_signal_emit(&compositor->activate_signal, surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
|
|
|
|
enum wl_pointer_button_state state)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_pointer *pointer = seat->pointer;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
|
|
|
weston_compositor_idle_inhibit(compositor);
|
|
|
|
if (pointer->button_count == 0) {
|
|
|
|
pointer->grab_button = button;
|
|
|
|
pointer->grab_time = time;
|
|
|
|
pointer->grab_x = pointer->x;
|
|
|
|
pointer->grab_y = pointer->y;
|
|
|
|
}
|
|
|
|
pointer->button_count++;
|
|
|
|
} else {
|
|
|
|
weston_compositor_idle_release(compositor);
|
|
|
|
pointer->button_count--;
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_compositor_run_button_binding(compositor, seat, time, button,
|
|
|
|
state);
|
|
|
|
|
|
|
|
pointer->grab->interface->button(pointer->grab, time, button, state);
|
|
|
|
|
|
|
|
if (pointer->button_count == 1)
|
|
|
|
pointer->grab_serial =
|
|
|
|
wl_display_get_serial(compositor->wl_display);
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
|
|
|
|
wl_fixed_t value)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_pointer *pointer = seat->pointer;
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
struct wl_list *resource_list;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
weston_compositor_wake(compositor);
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (weston_compositor_run_axis_binding(compositor, seat,
|
|
|
|
time, axis, value))
|
|
|
|
return;
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
resource_list = &pointer->focus_resource_list;
|
|
|
|
wl_resource_for_each(resource, resource_list)
|
|
|
|
wl_pointer_send_axis(resource, time, axis,
|
2013-04-18 23:40:10 +04:00
|
|
|
value);
|
|
|
|
}
|
|
|
|
|
2014-08-28 20:44:09 +04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2013-06-24 19:52:45 +04:00
|
|
|
#ifdef ENABLE_XKBCOMMON
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
notify_modifiers(struct weston_seat *seat, uint32_t serial)
|
|
|
|
{
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-04-18 23:40:10 +04:00
|
|
|
struct weston_keyboard_grab *grab = keyboard->grab;
|
|
|
|
uint32_t mods_depressed, mods_latched, mods_locked, group;
|
|
|
|
uint32_t mods_lookup;
|
|
|
|
enum weston_led leds = 0;
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
/* Serialize and update our internal state, checking to see if it's
|
|
|
|
* different to the previous state. */
|
2013-12-03 12:14:26 +04:00
|
|
|
mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
|
2014-08-20 00:59:51 +04:00
|
|
|
XKB_STATE_MODS_DEPRESSED);
|
2013-12-03 12:14:26 +04:00
|
|
|
mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
|
2014-08-20 00:59:51 +04:00
|
|
|
XKB_STATE_MODS_LATCHED);
|
2013-12-03 12:14:26 +04:00
|
|
|
mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
|
2014-08-20 00:59:51 +04:00
|
|
|
XKB_STATE_MODS_LOCKED);
|
|
|
|
group = xkb_state_serialize_layout(keyboard->xkb_state.state,
|
|
|
|
XKB_STATE_LAYOUT_EFFECTIVE);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
|
|
|
|
mods_latched != seat->keyboard->modifiers.mods_latched ||
|
|
|
|
mods_locked != seat->keyboard->modifiers.mods_locked ||
|
|
|
|
group != seat->keyboard->modifiers.group)
|
2013-04-18 23:40:10 +04:00
|
|
|
changed = 1;
|
|
|
|
|
2013-11-19 14:37:12 +04:00
|
|
|
run_modifier_bindings(seat, seat->keyboard->modifiers.mods_depressed,
|
|
|
|
mods_depressed);
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
seat->keyboard->modifiers.mods_depressed = mods_depressed;
|
|
|
|
seat->keyboard->modifiers.mods_latched = mods_latched;
|
|
|
|
seat->keyboard->modifiers.mods_locked = mods_locked;
|
|
|
|
seat->keyboard->modifiers.group = group;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
/* And update the modifier_state for bindings. */
|
|
|
|
mods_lookup = mods_depressed | mods_latched;
|
|
|
|
seat->modifier_state = 0;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
|
2013-04-18 23:40:10 +04:00
|
|
|
seat->modifier_state |= MODIFIER_CTRL;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
|
2013-04-18 23:40:10 +04:00
|
|
|
seat->modifier_state |= MODIFIER_ALT;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
|
2013-04-18 23:40:10 +04:00
|
|
|
seat->modifier_state |= MODIFIER_SUPER;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
|
2013-04-18 23:40:10 +04:00
|
|
|
seat->modifier_state |= MODIFIER_SHIFT;
|
|
|
|
|
|
|
|
/* Finally, notify the compositor that LEDs have changed. */
|
2013-12-03 12:14:26 +04:00
|
|
|
if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
|
|
|
|
keyboard->xkb_info->num_led))
|
2013-04-18 23:40:10 +04:00
|
|
|
leds |= LED_NUM_LOCK;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
|
|
|
|
keyboard->xkb_info->caps_led))
|
2013-04-18 23:40:10 +04:00
|
|
|
leds |= LED_CAPS_LOCK;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
|
|
|
|
keyboard->xkb_info->scroll_led))
|
2013-04-18 23:40:10 +04:00
|
|
|
leds |= LED_SCROLL_LOCK;
|
2013-12-03 12:14:26 +04:00
|
|
|
if (leds != keyboard->xkb_state.leds && seat->led_update)
|
2013-04-18 23:40:10 +04:00
|
|
|
seat->led_update(seat, leds);
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard->xkb_state.leds = leds;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (changed) {
|
|
|
|
grab->interface->modifiers(grab,
|
|
|
|
serial,
|
|
|
|
keyboard->modifiers.mods_depressed,
|
|
|
|
keyboard->modifiers.mods_latched,
|
|
|
|
keyboard->modifiers.mods_locked,
|
|
|
|
keyboard->modifiers.group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
|
|
|
|
enum wl_keyboard_key_state state)
|
|
|
|
{
|
2013-12-03 12:14:26 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-04-18 23:40:10 +04:00
|
|
|
enum xkb_key_direction direction;
|
|
|
|
|
2013-06-24 19:52:44 +04:00
|
|
|
/* Keyboard modifiers don't exist in raw keyboard mode */
|
|
|
|
if (!seat->compositor->use_xkbcommon)
|
|
|
|
return;
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
|
|
|
direction = XKB_KEY_DOWN;
|
|
|
|
else
|
|
|
|
direction = XKB_KEY_UP;
|
|
|
|
|
|
|
|
/* Offset the keycode by 8, as the evdev XKB rules reflect X's
|
|
|
|
* broken keycode system, which starts at 8. */
|
2013-12-03 12:14:26 +04:00
|
|
|
xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
notify_modifiers(seat, serial);
|
|
|
|
}
|
2013-10-10 21:44:19 +04:00
|
|
|
|
|
|
|
static void
|
|
|
|
send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
|
|
|
|
{
|
|
|
|
wl_keyboard_send_keymap(resource,
|
|
|
|
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
|
|
|
xkb_info->keymap_fd,
|
|
|
|
xkb_info->keymap_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
|
|
|
|
{
|
|
|
|
wl_keyboard_send_modifiers(resource, serial,
|
|
|
|
keyboard->modifiers.mods_depressed,
|
|
|
|
keyboard->modifiers.mods_latched,
|
|
|
|
keyboard->modifiers.mods_locked,
|
|
|
|
keyboard->modifiers.group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct weston_xkb_info *
|
|
|
|
weston_xkb_info_create(struct xkb_keymap *keymap);
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_keymap(struct weston_seat *seat)
|
|
|
|
{
|
2013-12-03 12:14:26 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-10-10 21:44:19 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
struct weston_xkb_info *xkb_info;
|
|
|
|
struct xkb_state *state;
|
|
|
|
xkb_mod_mask_t latched_mods;
|
|
|
|
xkb_mod_mask_t locked_mods;
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
|
2013-10-10 21:44:19 +04:00
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
xkb_keymap_unref(keyboard->pending_keymap);
|
|
|
|
keyboard->pending_keymap = NULL;
|
2013-10-10 21:44:19 +04:00
|
|
|
|
|
|
|
if (!xkb_info) {
|
|
|
|
weston_log("failed to create XKB info\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
state = xkb_state_new(xkb_info->keymap);
|
|
|
|
if (!state) {
|
|
|
|
weston_log("failed to initialise XKB state\n");
|
|
|
|
weston_xkb_info_destroy(xkb_info);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
|
|
|
|
XKB_STATE_MODS_LATCHED);
|
|
|
|
locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
|
|
|
|
XKB_STATE_MODS_LOCKED);
|
2013-10-10 21:44:19 +04:00
|
|
|
xkb_state_update_mask(state,
|
|
|
|
0, /* depressed */
|
|
|
|
latched_mods,
|
|
|
|
locked_mods,
|
|
|
|
0, 0, 0);
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
weston_xkb_info_destroy(keyboard->xkb_info);
|
|
|
|
keyboard->xkb_info = xkb_info;
|
2013-10-10 21:44:19 +04:00
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
xkb_state_unref(keyboard->xkb_state.state);
|
|
|
|
keyboard->xkb_state.state = state;
|
2013-10-10 21:44:19 +04:00
|
|
|
|
|
|
|
wl_resource_for_each(resource, &seat->keyboard->resource_list)
|
|
|
|
send_keymap(resource, xkb_info);
|
|
|
|
wl_resource_for_each(resource, &seat->keyboard->focus_resource_list)
|
|
|
|
send_keymap(resource, xkb_info);
|
|
|
|
|
|
|
|
notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
|
|
|
|
|
|
|
|
if (!latched_mods && !locked_mods)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wl_resource_for_each(resource, &seat->keyboard->resource_list)
|
|
|
|
send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), seat->keyboard);
|
|
|
|
wl_resource_for_each(resource, &seat->keyboard->focus_resource_list)
|
|
|
|
send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), seat->keyboard);
|
|
|
|
}
|
2013-06-24 19:52:45 +04:00
|
|
|
#else
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_modifiers(struct weston_seat *seat, uint32_t serial)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
|
|
|
|
enum wl_keyboard_key_state state)
|
|
|
|
{
|
|
|
|
}
|
2013-10-10 21:44:19 +04:00
|
|
|
|
|
|
|
static void
|
|
|
|
update_keymap(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
}
|
2013-06-24 19:52:45 +04:00
|
|
|
#endif
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
|
|
|
|
enum wl_keyboard_key_state state,
|
|
|
|
enum weston_key_state_update update_state)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-04-18 23:40:10 +04:00
|
|
|
struct weston_keyboard_grab *grab = keyboard->grab;
|
2014-11-19 14:43:32 +03:00
|
|
|
uint32_t *k, *end;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
|
|
|
weston_compositor_idle_inhibit(compositor);
|
|
|
|
} else {
|
|
|
|
weston_compositor_idle_release(compositor);
|
|
|
|
}
|
|
|
|
|
2014-11-19 14:43:32 +03:00
|
|
|
end = keyboard->keys.data + keyboard->keys.size;
|
|
|
|
for (k = keyboard->keys.data; k < end; k++) {
|
|
|
|
if (*k == key) {
|
|
|
|
/* Ignore server-generated repeats. */
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
|
|
|
return;
|
|
|
|
*k = *--end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
keyboard->keys.size = (void *) end - keyboard->keys.data;
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
|
|
|
k = wl_array_add(&keyboard->keys, sizeof *k);
|
|
|
|
*k = key;
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (grab == &keyboard->default_grab ||
|
|
|
|
grab == &keyboard->input_method_grab) {
|
2014-11-19 14:43:32 +03:00
|
|
|
weston_compositor_run_key_binding(compositor, seat, time, key,
|
|
|
|
state);
|
2013-04-18 23:40:10 +04:00
|
|
|
grab = keyboard->grab;
|
|
|
|
}
|
|
|
|
|
|
|
|
grab->interface->key(grab, time, key, state);
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
if (keyboard->pending_keymap &&
|
2014-11-19 14:43:32 +03:00
|
|
|
keyboard->keys.size == 0)
|
2013-10-10 21:44:19 +04:00
|
|
|
update_keymap(seat);
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
if (update_state == STATE_UPDATE_AUTOMATIC) {
|
|
|
|
update_modifier_state(seat,
|
|
|
|
wl_display_get_serial(compositor->wl_display),
|
|
|
|
key,
|
|
|
|
state);
|
|
|
|
}
|
2015-02-06 20:06:54 +03:00
|
|
|
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
|
|
|
keyboard->grab_serial =
|
|
|
|
wl_display_get_serial(compositor->wl_display);
|
|
|
|
keyboard->grab_time = time;
|
|
|
|
keyboard->grab_key = key;
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
|
|
|
|
wl_fixed_t x, wl_fixed_t y)
|
|
|
|
{
|
|
|
|
if (output) {
|
2013-11-15 02:42:52 +04:00
|
|
|
weston_pointer_move(seat->pointer, x, y);
|
2013-04-18 23:40:10 +04:00
|
|
|
} else {
|
2013-05-07 06:15:05 +04:00
|
|
|
/* FIXME: We should call weston_pointer_set_focus(seat,
|
2013-04-18 23:40:10 +04:00
|
|
|
* NULL) here, but somehow that breaks re-entry... */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_seat *ws;
|
|
|
|
|
|
|
|
ws = container_of(listener, struct weston_seat,
|
|
|
|
saved_kbd_focus_listener);
|
|
|
|
|
|
|
|
ws->saved_kbd_focus = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
|
|
|
|
enum weston_key_state_update update_state)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-05-08 17:54:37 +04:00
|
|
|
struct weston_surface *surface;
|
2013-04-18 23:40:10 +04:00
|
|
|
uint32_t *k, serial;
|
|
|
|
|
|
|
|
serial = wl_display_next_serial(compositor->wl_display);
|
|
|
|
wl_array_copy(&keyboard->keys, keys);
|
|
|
|
wl_array_for_each(k, &keyboard->keys) {
|
|
|
|
weston_compositor_idle_inhibit(compositor);
|
|
|
|
if (update_state == STATE_UPDATE_AUTOMATIC)
|
|
|
|
update_modifier_state(seat, serial, *k,
|
|
|
|
WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
|
|
}
|
|
|
|
|
|
|
|
surface = seat->saved_kbd_focus;
|
|
|
|
|
|
|
|
if (surface) {
|
|
|
|
wl_list_remove(&seat->saved_kbd_focus_listener.link);
|
|
|
|
weston_keyboard_set_focus(keyboard, surface);
|
|
|
|
seat->saved_kbd_focus = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_keyboard_focus_out(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-04-18 23:40:10 +04:00
|
|
|
uint32_t *k, serial;
|
|
|
|
|
|
|
|
serial = wl_display_next_serial(compositor->wl_display);
|
|
|
|
wl_array_for_each(k, &keyboard->keys) {
|
|
|
|
weston_compositor_idle_release(compositor);
|
|
|
|
update_modifier_state(seat, serial, *k,
|
|
|
|
WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
|
|
}
|
|
|
|
|
|
|
|
seat->modifier_state = 0;
|
|
|
|
|
|
|
|
if (keyboard->focus) {
|
|
|
|
seat->saved_kbd_focus = keyboard->focus;
|
|
|
|
seat->saved_kbd_focus_listener.notify =
|
|
|
|
destroy_device_saved_kbd_focus;
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_signal_add(&keyboard->focus->destroy_signal,
|
2013-04-18 23:40:10 +04:00
|
|
|
&seat->saved_kbd_focus_listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_keyboard_set_focus(keyboard, NULL);
|
2013-10-26 01:18:05 +04:00
|
|
|
weston_keyboard_cancel_grab(keyboard);
|
2013-11-23 09:12:19 +04:00
|
|
|
if (seat->pointer)
|
|
|
|
weston_pointer_cancel_grab(seat->pointer);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-07-23 11:51:06 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-09-19 20:32:00 +04:00
|
|
|
struct wl_list *focus_resource_list;
|
|
|
|
|
|
|
|
focus_resource_list = &seat->touch->focus_resource_list;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-10-25 01:21:53 +04:00
|
|
|
if (view && seat->touch->focus &&
|
|
|
|
seat->touch->focus->surface == view->surface) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
seat->touch->focus = view;
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_list_remove(&seat->touch->focus_resource_listener.link);
|
|
|
|
wl_list_init(&seat->touch->focus_resource_listener.link);
|
|
|
|
wl_list_remove(&seat->touch->focus_view_listener.link);
|
|
|
|
wl_list_init(&seat->touch->focus_view_listener.link);
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
if (!wl_list_empty(focus_resource_list)) {
|
|
|
|
move_resources(&seat->touch->resource_list,
|
|
|
|
focus_resource_list);
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view) {
|
2014-09-04 19:23:05 +04:00
|
|
|
struct wl_client *surface_client;
|
|
|
|
|
|
|
|
if (!view->surface->resource) {
|
|
|
|
seat->touch->focus = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
surface_client = wl_resource_get_client(view->surface->resource);
|
2013-09-19 20:32:00 +04:00
|
|
|
move_resources_for_client(focus_resource_list,
|
|
|
|
&seat->touch->resource_list,
|
|
|
|
surface_client);
|
2013-11-20 21:00:24 +04:00
|
|
|
wl_resource_add_destroy_listener(view->surface->resource,
|
|
|
|
&seat->touch->focus_resource_listener);
|
|
|
|
wl_signal_add(&view->destroy_signal, &seat->touch->focus_view_listener);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
seat->touch->focus = view;
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* notify_touch - emulates button touches and notifies surfaces accordingly.
|
|
|
|
*
|
|
|
|
* It assumes always the correct cycle sequence until it gets here: touch_down
|
|
|
|
* → touch_update → ... → touch_update → touch_end. The driver is responsible
|
|
|
|
* for sending along such order.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
|
|
|
|
wl_fixed_t x, wl_fixed_t y, int touch_type)
|
|
|
|
{
|
|
|
|
struct weston_compositor *ec = seat->compositor;
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_touch *touch = seat->touch;
|
2013-05-07 06:19:57 +04:00
|
|
|
struct weston_touch_grab *grab = touch->grab;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *ev;
|
2013-04-18 23:40:10 +04:00
|
|
|
wl_fixed_t sx, sy;
|
|
|
|
|
|
|
|
/* Update grab's global coordinates. */
|
2013-10-03 19:43:06 +04:00
|
|
|
if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
|
|
|
|
touch->grab_x = x;
|
|
|
|
touch->grab_y = y;
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
switch (touch_type) {
|
|
|
|
case WL_TOUCH_DOWN:
|
|
|
|
weston_compositor_idle_inhibit(ec);
|
|
|
|
|
2013-12-03 01:05:03 +04:00
|
|
|
touch->num_tp++;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
/* the first finger down picks the view, and all further go
|
|
|
|
* to that view for the remainder of the touch session i.e.
|
2013-04-18 23:40:10 +04:00
|
|
|
* until all touch points are up again. */
|
2013-12-03 01:05:03 +04:00
|
|
|
if (touch->num_tp == 1) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
|
|
|
|
weston_touch_set_focus(seat, ev);
|
2013-04-18 23:40:10 +04:00
|
|
|
} else if (touch->focus) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
ev = touch->focus;
|
|
|
|
weston_view_from_global_fixed(ev, x, y, &sx, &sy);
|
2013-04-18 23:40:10 +04:00
|
|
|
} else {
|
|
|
|
/* Unexpected condition: We have non-initial touch but
|
|
|
|
* there is no focused surface.
|
|
|
|
*/
|
|
|
|
weston_log("touch event received with %d points down"
|
2013-12-03 01:05:03 +04:00
|
|
|
"but no surface focused\n", touch->num_tp);
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-02-06 02:25:18 +04:00
|
|
|
weston_compositor_run_touch_binding(ec, seat,
|
|
|
|
time, touch_type);
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
grab->interface->down(grab, time, touch_id, sx, sy);
|
2013-12-03 01:05:03 +04:00
|
|
|
if (touch->num_tp == 1) {
|
2013-08-09 08:13:57 +04:00
|
|
|
touch->grab_serial =
|
|
|
|
wl_display_get_serial(ec->wl_display);
|
2013-10-03 19:43:06 +04:00
|
|
|
touch->grab_touch_id = touch_id;
|
2013-08-09 08:13:57 +04:00
|
|
|
touch->grab_time = time;
|
|
|
|
touch->grab_x = x;
|
|
|
|
touch->grab_y = y;
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
break;
|
|
|
|
case WL_TOUCH_MOTION:
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
ev = touch->focus;
|
|
|
|
if (!ev)
|
2013-04-18 23:40:10 +04:00
|
|
|
break;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global_fixed(ev, x, y, &sx, &sy);
|
2013-04-18 23:40:10 +04:00
|
|
|
grab->interface->motion(grab, time, touch_id, sx, sy);
|
|
|
|
break;
|
|
|
|
case WL_TOUCH_UP:
|
2014-01-09 10:29:20 +04:00
|
|
|
if (touch->num_tp == 0) {
|
|
|
|
/* This can happen if we start out with one or
|
|
|
|
* more fingers on the touch screen, in which
|
|
|
|
* case we didn't get the corresponding down
|
|
|
|
* event. */
|
|
|
|
weston_log("unmatched touch up event\n");
|
|
|
|
break;
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
weston_compositor_idle_release(ec);
|
2013-12-03 01:05:03 +04:00
|
|
|
touch->num_tp--;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
grab->interface->up(grab, time, touch_id);
|
2013-12-03 01:05:03 +04:00
|
|
|
if (touch->num_tp == 0)
|
2013-07-23 11:51:06 +04:00
|
|
|
weston_touch_set_focus(seat, NULL);
|
2013-04-18 23:40:10 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-12 11:39:51 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
notify_touch_frame(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
struct weston_touch *touch = seat->touch;
|
|
|
|
struct weston_touch_grab *grab = touch->grab;
|
|
|
|
|
|
|
|
grab->interface->frame(grab);
|
|
|
|
}
|
|
|
|
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
static int
|
|
|
|
pointer_cursor_surface_get_label(struct weston_surface *surface,
|
|
|
|
char *buf, size_t len)
|
|
|
|
{
|
|
|
|
return snprintf(buf, len, "cursor");
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
static void
|
|
|
|
pointer_cursor_surface_configure(struct weston_surface *es,
|
2013-12-03 07:01:53 +04:00
|
|
|
int32_t dx, int32_t dy)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-05-08 23:02:05 +04:00
|
|
|
struct weston_pointer *pointer = es->configure_private;
|
2013-04-18 23:40:10 +04:00
|
|
|
int x, y;
|
|
|
|
|
2013-12-03 07:01:53 +04:00
|
|
|
if (es->width == 0)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
assert(es == pointer->sprite->surface);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
pointer->hotspot_x -= dx;
|
|
|
|
pointer->hotspot_y -= dy;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
|
|
|
|
y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-12-03 07:01:53 +04:00
|
|
|
weston_view_set_position(pointer->sprite, x, y);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
empty_region(&es->pending.input);
|
2014-01-31 18:07:51 +04:00
|
|
|
empty_region(&es->input);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (!weston_surface_is_mapped(es)) {
|
2014-07-09 23:12:56 +04:00
|
|
|
weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
|
|
|
|
&pointer->sprite->layer_link);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform(pointer->sprite);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
uint32_t serial, struct wl_resource *surface_resource,
|
|
|
|
int32_t x, int32_t y)
|
|
|
|
{
|
2013-06-14 19:08:00 +04:00
|
|
|
struct weston_pointer *pointer = wl_resource_get_user_data(resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
struct weston_surface *surface = NULL;
|
|
|
|
|
|
|
|
if (surface_resource)
|
2013-06-14 19:07:53 +04:00
|
|
|
surface = wl_resource_get_user_data(surface_resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
if (pointer->focus == NULL)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
/* pointer->focus->surface->resource can be NULL. Surfaces like the
|
2013-06-20 20:13:07 +04:00
|
|
|
black_surface used in shell.c for fullscreen don't have
|
|
|
|
a resource, but can still have focus */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (pointer->focus->surface->resource == NULL)
|
2013-06-20 20:13:07 +04:00
|
|
|
return;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (wl_resource_get_client(pointer->focus->surface->resource) != client)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
2013-05-08 23:02:05 +04:00
|
|
|
if (pointer->focus_serial - serial > UINT32_MAX / 2)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
|
compositor: send error for surface role resets
With the more accurate definition of wl_surface roles in Wayland,
enforce the restriction: a role is always set permanently, and
attempting to change it is a protocol error.
This patch is based on Jasper's patch:
http://lists.freedesktop.org/archives/wayland-devel/2014-August/016811.html
The difference in this patch compared to his are:
- send role errors on the interface whose request triggers it, not on
wl_surface
- an interface could have several requests assigning different roles,
cannot use wl_interface as the unique key; use an arbitary string
instead
- ensure in window-manager.c that create_shell_surface() ->
create_common_surface() is never called with surface->configure set,
to avoid compositor abort
- use wl_resource_post_no_memory() where appropriate instead of
hand-rolling it with wl_resource_post_error()
Ideally we would not add weston_surface::role_name field, but use
weston_surface::configure. At the moment this is not possible though,
because at least shell.c uses several different roles with the same
configure function. Drag'n'drop uses two configure functions for the
same role. The configure hook is also reset in several places,
which is not good for role tracking.
This patch overlooks the wl_surface roles assigned in privileged
extensions: screensaver, panel, background, lock, input panel.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
2014-10-01 16:02:41 +04:00
|
|
|
if (surface) {
|
|
|
|
if (weston_surface_set_role(surface, "wl_pointer-cursor",
|
|
|
|
resource,
|
|
|
|
WL_POINTER_ERROR_ROLE) < 0)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-18 10:08:03 +03:00
|
|
|
if (pointer->sprite && pointer->sprite->surface == surface &&
|
|
|
|
pointer->hotspot_x == x && pointer->hotspot_y == y)
|
|
|
|
return;
|
|
|
|
|
2013-05-08 23:02:05 +04:00
|
|
|
if (pointer->sprite)
|
|
|
|
pointer_unmap_sprite(pointer);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (!surface)
|
|
|
|
return;
|
|
|
|
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_signal_add(&surface->destroy_signal,
|
2013-05-08 23:02:05 +04:00
|
|
|
&pointer->sprite_destroy_listener);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
surface->configure = pointer_cursor_surface_configure;
|
2013-05-08 23:02:05 +04:00
|
|
|
surface->configure_private = pointer;
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
weston_surface_set_label_func(surface,
|
|
|
|
pointer_cursor_surface_get_label);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pointer->sprite = weston_view_create(surface);
|
2013-05-08 23:02:05 +04:00
|
|
|
pointer->hotspot_x = x;
|
|
|
|
pointer->hotspot_y = y;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2014-09-08 21:33:41 +04:00
|
|
|
if (surface->buffer_ref.buffer) {
|
2013-12-03 07:01:53 +04:00
|
|
|
pointer_cursor_surface_configure(surface, 0, 0);
|
2014-09-08 21:33:41 +04:00
|
|
|
weston_view_schedule_repaint(pointer->sprite);
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-08-13 23:11:02 +04:00
|
|
|
static void
|
|
|
|
pointer_release(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
static const struct wl_pointer_interface pointer_interface = {
|
2013-08-13 23:11:02 +04:00
|
|
|
pointer_set_cursor,
|
|
|
|
pointer_release
|
2013-04-18 23:40:10 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
uint32_t id)
|
|
|
|
{
|
2013-06-14 19:08:00 +04:00
|
|
|
struct weston_seat *seat = wl_resource_get_user_data(resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
struct wl_resource *cr;
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
if (!seat->pointer)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
cr = wl_resource_create(client, &wl_pointer_interface,
|
|
|
|
wl_resource_get_version(resource), id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (cr == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
/* May be moved to focused list later by either
|
|
|
|
* weston_pointer_set_focus or directly if this client is already
|
|
|
|
* focused */
|
2013-06-14 19:08:00 +04:00
|
|
|
wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
|
2013-06-28 05:17:02 +04:00
|
|
|
wl_resource_set_implementation(cr, &pointer_interface, seat->pointer,
|
|
|
|
unbind_resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (seat->pointer->focus && seat->pointer->focus->surface->resource &&
|
|
|
|
wl_resource_get_client(seat->pointer->focus->surface->resource) == client) {
|
2013-04-18 23:40:10 +04:00
|
|
|
wl_fixed_t sx, sy;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global_fixed(seat->pointer->focus,
|
|
|
|
seat->pointer->x,
|
|
|
|
seat->pointer->y,
|
|
|
|
&sx, &sy);
|
2013-09-19 20:32:00 +04:00
|
|
|
|
|
|
|
wl_list_remove(wl_resource_get_link(cr));
|
|
|
|
wl_list_insert(&seat->pointer->focus_resource_list,
|
|
|
|
wl_resource_get_link(cr));
|
|
|
|
wl_pointer_send_enter(cr,
|
|
|
|
seat->pointer->focus_serial,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
seat->pointer->focus->surface->resource,
|
2013-09-19 20:32:00 +04:00
|
|
|
sx, sy);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-13 23:11:02 +04:00
|
|
|
static void
|
|
|
|
keyboard_release(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_keyboard_interface keyboard_interface = {
|
|
|
|
keyboard_release
|
|
|
|
};
|
|
|
|
|
2014-10-03 22:13:42 +04:00
|
|
|
static bool
|
2013-09-19 20:32:00 +04:00
|
|
|
should_send_modifiers_to_client(struct weston_seat *seat,
|
|
|
|
struct wl_client *client)
|
|
|
|
{
|
|
|
|
if (seat->keyboard &&
|
|
|
|
seat->keyboard->focus &&
|
2013-11-15 06:06:16 +04:00
|
|
|
seat->keyboard->focus->resource &&
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_resource_get_client(seat->keyboard->focus->resource) == client)
|
2014-10-03 22:13:42 +04:00
|
|
|
return true;
|
2013-09-19 20:32:00 +04:00
|
|
|
|
|
|
|
if (seat->pointer &&
|
|
|
|
seat->pointer->focus &&
|
2013-11-15 06:06:16 +04:00
|
|
|
seat->pointer->focus->surface->resource &&
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_resource_get_client(seat->pointer->focus->surface->resource) == client)
|
2014-10-03 22:13:42 +04:00
|
|
|
return true;
|
2013-09-19 20:32:00 +04:00
|
|
|
|
2014-10-03 22:13:42 +04:00
|
|
|
return false;
|
2013-09-19 20:32:00 +04:00
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
static void
|
|
|
|
seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
uint32_t id)
|
|
|
|
{
|
2013-06-14 19:08:00 +04:00
|
|
|
struct weston_seat *seat = wl_resource_get_user_data(resource);
|
2013-12-03 12:14:26 +04:00
|
|
|
struct weston_keyboard *keyboard = seat->keyboard;
|
2013-04-18 23:40:10 +04:00
|
|
|
struct wl_resource *cr;
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
if (!seat->keyboard)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
cr = wl_resource_create(client, &wl_keyboard_interface,
|
|
|
|
wl_resource_get_version(resource), id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (cr == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
/* May be moved to focused list later by either
|
|
|
|
* weston_keyboard_set_focus or directly if this client is already
|
|
|
|
* focused */
|
2013-06-14 19:08:00 +04:00
|
|
|
wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
|
2013-08-13 23:11:02 +04:00
|
|
|
wl_resource_set_implementation(cr, &keyboard_interface,
|
|
|
|
seat, unbind_resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2014-08-12 16:58:25 +04:00
|
|
|
if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
|
|
|
|
wl_keyboard_send_repeat_info(cr,
|
|
|
|
seat->compositor->kb_repeat_rate,
|
|
|
|
seat->compositor->kb_repeat_delay);
|
|
|
|
}
|
2014-08-04 21:43:24 +04:00
|
|
|
|
2013-06-24 19:52:44 +04:00
|
|
|
if (seat->compositor->use_xkbcommon) {
|
|
|
|
wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard->xkb_info->keymap_fd,
|
|
|
|
keyboard->xkb_info->keymap_size);
|
2013-06-24 19:52:44 +04:00
|
|
|
} else {
|
|
|
|
int null_fd = open("/dev/null", O_RDONLY);
|
|
|
|
wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
|
|
|
|
null_fd,
|
|
|
|
0);
|
|
|
|
close(null_fd);
|
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
if (should_send_modifiers_to_client(seat, client)) {
|
|
|
|
send_modifiers_to_resource(seat->keyboard,
|
|
|
|
cr,
|
|
|
|
seat->keyboard->focus_serial);
|
|
|
|
}
|
|
|
|
|
2014-10-11 00:46:50 +04:00
|
|
|
if (seat->keyboard->focus && seat->keyboard->focus->resource &&
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_resource_get_client(seat->keyboard->focus->resource) == client) {
|
2013-09-19 20:32:00 +04:00
|
|
|
struct weston_surface *surface =
|
|
|
|
(struct weston_surface *) seat->keyboard->focus;
|
|
|
|
|
|
|
|
wl_list_remove(wl_resource_get_link(cr));
|
|
|
|
wl_list_insert(&seat->keyboard->focus_resource_list,
|
|
|
|
wl_resource_get_link(cr));
|
|
|
|
wl_keyboard_send_enter(cr,
|
|
|
|
seat->keyboard->focus_serial,
|
|
|
|
surface->resource,
|
|
|
|
&seat->keyboard->keys);
|
|
|
|
|
|
|
|
/* If this is the first keyboard resource for this
|
|
|
|
* client... */
|
|
|
|
if (seat->keyboard->focus_resource_list.prev ==
|
|
|
|
wl_resource_get_link(cr))
|
|
|
|
wl_data_device_set_keyboard_focus(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-13 23:11:02 +04:00
|
|
|
static void
|
|
|
|
touch_release(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_touch_interface touch_interface = {
|
|
|
|
touch_release
|
|
|
|
};
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
static void
|
|
|
|
seat_get_touch(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
uint32_t id)
|
|
|
|
{
|
2013-06-14 19:08:00 +04:00
|
|
|
struct weston_seat *seat = wl_resource_get_user_data(resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
struct wl_resource *cr;
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
if (!seat->touch)
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
cr = wl_resource_create(client, &wl_touch_interface,
|
|
|
|
wl_resource_get_version(resource), id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (cr == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-19 20:32:00 +04:00
|
|
|
if (seat->touch->focus &&
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_resource_get_client(seat->touch->focus->surface->resource) == client) {
|
2013-09-19 20:32:00 +04:00
|
|
|
wl_list_insert(&seat->touch->resource_list,
|
|
|
|
wl_resource_get_link(cr));
|
|
|
|
} else {
|
|
|
|
wl_list_insert(&seat->touch->focus_resource_list,
|
|
|
|
wl_resource_get_link(cr));
|
|
|
|
}
|
2013-08-13 23:11:02 +04:00
|
|
|
wl_resource_set_implementation(cr, &touch_interface,
|
|
|
|
seat, unbind_resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_seat_interface seat_interface = {
|
|
|
|
seat_get_pointer,
|
|
|
|
seat_get_keyboard,
|
|
|
|
seat_get_touch,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
2013-05-07 07:19:49 +04:00
|
|
|
struct weston_seat *seat = data;
|
2013-04-18 23:40:10 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
enum wl_seat_capability caps = 0;
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
resource = wl_resource_create(client,
|
2014-08-12 16:58:25 +04:00
|
|
|
&wl_seat_interface, MIN(version, 4), id);
|
2013-06-14 19:08:00 +04:00
|
|
|
wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
|
2013-06-28 05:17:02 +04:00
|
|
|
wl_resource_set_implementation(resource, &seat_interface, data,
|
|
|
|
unbind_resource);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (seat->pointer)
|
|
|
|
caps |= WL_SEAT_CAPABILITY_POINTER;
|
|
|
|
if (seat->keyboard)
|
|
|
|
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
|
|
|
if (seat->touch)
|
|
|
|
caps |= WL_SEAT_CAPABILITY_TOUCH;
|
|
|
|
|
|
|
|
wl_seat_send_capabilities(resource, caps);
|
2014-08-08 00:43:11 +04:00
|
|
|
if (version >= WL_SEAT_NAME_SINCE_VERSION)
|
2013-05-31 21:09:51 +04:00
|
|
|
wl_seat_send_name(resource, seat->seat_name);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-06-24 19:52:45 +04:00
|
|
|
#ifdef ENABLE_XKBCOMMON
|
2013-04-18 23:40:10 +04:00
|
|
|
int
|
|
|
|
weston_compositor_xkb_init(struct weston_compositor *ec,
|
|
|
|
struct xkb_rule_names *names)
|
|
|
|
{
|
2013-06-24 19:52:45 +04:00
|
|
|
ec->use_xkbcommon = 1;
|
2013-06-24 19:52:44 +04:00
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
if (ec->xkb_context == NULL) {
|
|
|
|
ec->xkb_context = xkb_context_new(0);
|
|
|
|
if (ec->xkb_context == NULL) {
|
|
|
|
weston_log("failed to create XKB context\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (names)
|
|
|
|
ec->xkb_names = *names;
|
|
|
|
if (!ec->xkb_names.rules)
|
|
|
|
ec->xkb_names.rules = strdup("evdev");
|
|
|
|
if (!ec->xkb_names.model)
|
|
|
|
ec->xkb_names.model = strdup("pc105");
|
|
|
|
if (!ec->xkb_names.layout)
|
|
|
|
ec->xkb_names.layout = strdup("us");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-09-17 13:54:09 +04:00
|
|
|
static void
|
2013-09-05 17:31:40 +04:00
|
|
|
weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-09-05 17:31:40 +04:00
|
|
|
if (--xkb_info->ref_count > 0)
|
|
|
|
return;
|
|
|
|
|
2014-08-20 00:59:52 +04:00
|
|
|
xkb_keymap_unref(xkb_info->keymap);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
if (xkb_info->keymap_area)
|
|
|
|
munmap(xkb_info->keymap_area, xkb_info->keymap_size);
|
|
|
|
if (xkb_info->keymap_fd >= 0)
|
|
|
|
close(xkb_info->keymap_fd);
|
2013-09-05 17:31:40 +04:00
|
|
|
free(xkb_info);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
weston_compositor_xkb_destroy(struct weston_compositor *ec)
|
|
|
|
{
|
2013-06-24 19:52:44 +04:00
|
|
|
/*
|
|
|
|
* If we're operating in raw keyboard mode, we never initialized
|
|
|
|
* libxkbcommon so there's no cleanup to do either.
|
|
|
|
*/
|
|
|
|
if (!ec->use_xkbcommon)
|
|
|
|
return;
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
free((char *) ec->xkb_names.rules);
|
|
|
|
free((char *) ec->xkb_names.model);
|
|
|
|
free((char *) ec->xkb_names.layout);
|
|
|
|
free((char *) ec->xkb_names.variant);
|
|
|
|
free((char *) ec->xkb_names.options);
|
2013-09-17 13:54:09 +04:00
|
|
|
|
2013-09-05 17:31:40 +04:00
|
|
|
if (ec->xkb_info)
|
|
|
|
weston_xkb_info_destroy(ec->xkb_info);
|
2013-04-18 23:40:10 +04:00
|
|
|
xkb_context_unref(ec->xkb_context);
|
|
|
|
}
|
|
|
|
|
2013-09-05 17:31:40 +04:00
|
|
|
static struct weston_xkb_info *
|
|
|
|
weston_xkb_info_create(struct xkb_keymap *keymap)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-09-05 17:31:40 +04:00
|
|
|
struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
|
|
|
|
if (xkb_info == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2014-08-20 00:59:51 +04:00
|
|
|
xkb_info->keymap = xkb_keymap_ref(keymap);
|
2013-09-05 17:31:40 +04:00
|
|
|
xkb_info->ref_count = 1;
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
char *keymap_str;
|
|
|
|
|
2014-08-20 00:59:51 +04:00
|
|
|
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);
|
2013-04-18 23:40:10 +04:00
|
|
|
if (keymap_str == NULL) {
|
|
|
|
weston_log("failed to get string version of keymap\n");
|
2013-09-05 17:31:40 +04:00
|
|
|
goto err_keymap;
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
xkb_info->keymap_size = strlen(keymap_str) + 1;
|
|
|
|
|
|
|
|
xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
|
|
|
|
if (xkb_info->keymap_fd < 0) {
|
|
|
|
weston_log("creating a keymap file for %lu bytes failed: %m\n",
|
|
|
|
(unsigned long) xkb_info->keymap_size);
|
|
|
|
goto err_keymap_str;
|
|
|
|
}
|
|
|
|
|
|
|
|
xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
|
|
|
|
PROT_READ | PROT_WRITE,
|
|
|
|
MAP_SHARED, xkb_info->keymap_fd, 0);
|
|
|
|
if (xkb_info->keymap_area == MAP_FAILED) {
|
|
|
|
weston_log("failed to mmap() %lu bytes\n",
|
|
|
|
(unsigned long) xkb_info->keymap_size);
|
|
|
|
goto err_dev_zero;
|
|
|
|
}
|
|
|
|
strcpy(xkb_info->keymap_area, keymap_str);
|
|
|
|
free(keymap_str);
|
|
|
|
|
2013-09-05 17:31:40 +04:00
|
|
|
return xkb_info;
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
err_dev_zero:
|
|
|
|
close(xkb_info->keymap_fd);
|
|
|
|
err_keymap_str:
|
|
|
|
free(keymap_str);
|
2013-09-05 17:31:40 +04:00
|
|
|
err_keymap:
|
2014-08-20 00:59:51 +04:00
|
|
|
xkb_keymap_unref(xkb_info->keymap);
|
2013-09-05 17:31:40 +04:00
|
|
|
free(xkb_info);
|
|
|
|
return NULL;
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
weston_compositor_build_global_keymap(struct weston_compositor *ec)
|
|
|
|
{
|
2013-09-05 17:31:40 +04:00
|
|
|
struct xkb_keymap *keymap;
|
|
|
|
|
|
|
|
if (ec->xkb_info != NULL)
|
2013-04-18 23:40:10 +04:00
|
|
|
return 0;
|
|
|
|
|
2014-08-20 00:59:51 +04:00
|
|
|
keymap = xkb_keymap_new_from_names(ec->xkb_context,
|
|
|
|
&ec->xkb_names,
|
|
|
|
0);
|
2013-09-05 17:31:40 +04:00
|
|
|
if (keymap == NULL) {
|
2013-04-18 23:40:10 +04:00
|
|
|
weston_log("failed to compile global XKB keymap\n");
|
|
|
|
weston_log(" tried rules %s, model %s, layout %s, variant %s, "
|
|
|
|
"options %s\n",
|
|
|
|
ec->xkb_names.rules, ec->xkb_names.model,
|
|
|
|
ec->xkb_names.layout, ec->xkb_names.variant,
|
|
|
|
ec->xkb_names.options);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-09-05 17:31:40 +04:00
|
|
|
ec->xkb_info = weston_xkb_info_create(keymap);
|
2013-10-24 21:28:41 +04:00
|
|
|
xkb_keymap_unref(keymap);
|
2013-09-17 13:54:09 +04:00
|
|
|
if (ec->xkb_info == NULL)
|
2013-04-18 23:40:10 +04:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2013-06-24 19:52:45 +04:00
|
|
|
#else
|
|
|
|
int
|
|
|
|
weston_compositor_xkb_init(struct weston_compositor *ec,
|
|
|
|
struct xkb_rule_names *names)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
weston_compositor_xkb_destroy(struct weston_compositor *ec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-10-10 21:44:19 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
|
|
|
|
{
|
|
|
|
if (!seat->keyboard || !keymap)
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef ENABLE_XKBCOMMON
|
|
|
|
if (!seat->compositor->use_xkbcommon)
|
|
|
|
return;
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
xkb_keymap_unref(seat->keyboard->pending_keymap);
|
|
|
|
seat->keyboard->pending_keymap = xkb_keymap_ref(keymap);
|
2013-10-10 21:44:19 +04:00
|
|
|
|
2014-11-19 14:43:32 +03:00
|
|
|
if (seat->keyboard->keys.size == 0)
|
2013-10-10 21:44:19 +04:00
|
|
|
update_keymap(seat);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT int
|
|
|
|
weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
|
|
|
|
{
|
2013-05-08 07:52:07 +04:00
|
|
|
struct weston_keyboard *keyboard;
|
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->keyboard) {
|
|
|
|
seat->keyboard_device_count += 1;
|
|
|
|
if (seat->keyboard_device_count == 1)
|
|
|
|
seat_send_updated_caps(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
return 0;
|
2013-10-18 01:04:05 +04:00
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard = weston_keyboard_create();
|
|
|
|
if (keyboard == NULL) {
|
|
|
|
weston_log("failed to allocate weston keyboard struct\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-06-24 19:52:45 +04:00
|
|
|
#ifdef ENABLE_XKBCOMMON
|
2013-06-24 19:52:44 +04:00
|
|
|
if (seat->compositor->use_xkbcommon) {
|
|
|
|
if (keymap != NULL) {
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard->xkb_info = weston_xkb_info_create(keymap);
|
|
|
|
if (keyboard->xkb_info == NULL)
|
2014-01-31 19:35:45 +04:00
|
|
|
goto err;
|
2013-06-24 19:52:44 +04:00
|
|
|
} else {
|
|
|
|
if (weston_compositor_build_global_keymap(seat->compositor) < 0)
|
2014-01-31 19:35:45 +04:00
|
|
|
goto err;
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard->xkb_info = seat->compositor->xkb_info;
|
|
|
|
keyboard->xkb_info->ref_count++;
|
2013-06-24 19:52:44 +04:00
|
|
|
}
|
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
|
|
|
|
if (keyboard->xkb_state.state == NULL) {
|
2013-06-24 19:52:44 +04:00
|
|
|
weston_log("failed to initialise XKB state\n");
|
2014-01-31 19:35:45 +04:00
|
|
|
goto err;
|
2013-06-24 19:52:44 +04:00
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-12-03 12:14:26 +04:00
|
|
|
keyboard->xkb_state.leds = 0;
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
2013-06-24 19:52:45 +04:00
|
|
|
#endif
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2014-01-31 19:35:45 +04:00
|
|
|
seat->keyboard = keyboard;
|
|
|
|
seat->keyboard_device_count = 1;
|
|
|
|
keyboard->seat = seat;
|
|
|
|
|
2013-05-08 07:52:07 +04:00
|
|
|
seat_send_updated_caps(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
return 0;
|
2014-01-31 19:35:45 +04:00
|
|
|
|
|
|
|
err:
|
|
|
|
if (keyboard->xkb_info)
|
|
|
|
weston_xkb_info_destroy(keyboard->xkb_info);
|
|
|
|
free(keyboard);
|
|
|
|
|
|
|
|
return -1;
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-12-03 12:14:27 +04:00
|
|
|
static void
|
|
|
|
weston_keyboard_reset_state(struct weston_keyboard *keyboard)
|
|
|
|
{
|
|
|
|
struct weston_seat *seat = keyboard->seat;
|
|
|
|
struct xkb_state *state;
|
|
|
|
|
|
|
|
#ifdef ENABLE_XKBCOMMON
|
|
|
|
if (seat->compositor->use_xkbcommon) {
|
|
|
|
state = xkb_state_new(keyboard->xkb_info->keymap);
|
|
|
|
if (!state) {
|
|
|
|
weston_log("failed to reset XKB state\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
xkb_state_unref(keyboard->xkb_state.state);
|
|
|
|
keyboard->xkb_state.state = state;
|
|
|
|
|
|
|
|
keyboard->xkb_state.leds = 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
seat->modifier_state = 0;
|
|
|
|
}
|
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_release_keyboard(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
seat->keyboard_device_count--;
|
2014-11-19 20:04:12 +03:00
|
|
|
assert(seat->keyboard_device_count >= 0);
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->keyboard_device_count == 0) {
|
2013-10-18 01:04:06 +04:00
|
|
|
weston_keyboard_set_focus(seat->keyboard, NULL);
|
2013-10-26 01:18:05 +04:00
|
|
|
weston_keyboard_cancel_grab(seat->keyboard);
|
2013-12-03 12:14:27 +04:00
|
|
|
weston_keyboard_reset_state(seat->keyboard);
|
2013-10-18 01:04:05 +04:00
|
|
|
seat_send_updated_caps(seat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_init_pointer(struct weston_seat *seat)
|
|
|
|
{
|
2013-05-08 07:52:07 +04:00
|
|
|
struct weston_pointer *pointer;
|
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->pointer) {
|
|
|
|
seat->pointer_device_count += 1;
|
|
|
|
if (seat->pointer_device_count == 1)
|
|
|
|
seat_send_updated_caps(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
2013-10-18 01:04:05 +04:00
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-11-15 02:42:53 +04:00
|
|
|
pointer = weston_pointer_create(seat);
|
2013-05-08 07:52:07 +04:00
|
|
|
if (pointer == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
seat->pointer = pointer;
|
2013-10-18 01:04:05 +04:00
|
|
|
seat->pointer_device_count = 1;
|
|
|
|
pointer->seat = seat;
|
2013-05-08 07:52:07 +04:00
|
|
|
|
|
|
|
seat_send_updated_caps(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_release_pointer(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
struct weston_pointer *pointer = seat->pointer;
|
|
|
|
|
|
|
|
seat->pointer_device_count--;
|
|
|
|
if (seat->pointer_device_count == 0) {
|
2013-10-18 01:04:06 +04:00
|
|
|
weston_pointer_set_focus(pointer, NULL,
|
|
|
|
wl_fixed_from_int(0),
|
|
|
|
wl_fixed_from_int(0));
|
2013-10-26 01:18:05 +04:00
|
|
|
weston_pointer_cancel_grab(pointer);
|
2013-10-18 01:04:06 +04:00
|
|
|
|
2013-10-18 01:04:07 +04:00
|
|
|
if (pointer->sprite)
|
|
|
|
pointer_unmap_sprite(pointer);
|
|
|
|
|
2013-12-03 01:05:05 +04:00
|
|
|
weston_pointer_reset_state(pointer);
|
2013-10-18 01:04:05 +04:00
|
|
|
seat_send_updated_caps(seat);
|
2015-01-08 00:00:25 +03:00
|
|
|
|
|
|
|
/* seat->pointer is intentionally not destroyed so that
|
|
|
|
* a newly attached pointer on this seat will retain
|
|
|
|
* the previous cursor co-ordinates.
|
|
|
|
*/
|
2013-10-18 01:04:05 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_init_touch(struct weston_seat *seat)
|
|
|
|
{
|
2013-05-08 07:52:07 +04:00
|
|
|
struct weston_touch *touch;
|
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
if (seat->touch) {
|
|
|
|
seat->touch_device_count += 1;
|
|
|
|
if (seat->touch_device_count == 1)
|
|
|
|
seat_send_updated_caps(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
return;
|
2013-10-18 01:04:05 +04:00
|
|
|
}
|
2013-04-18 23:40:10 +04:00
|
|
|
|
2013-05-08 07:52:07 +04:00
|
|
|
touch = weston_touch_create();
|
|
|
|
if (touch == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
seat->touch = touch;
|
2013-10-18 01:04:05 +04:00
|
|
|
seat->touch_device_count = 1;
|
2013-05-08 07:52:07 +04:00
|
|
|
touch->seat = seat;
|
|
|
|
|
|
|
|
seat_send_updated_caps(seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
}
|
|
|
|
|
2013-10-18 01:04:05 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_release_touch(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
seat->touch_device_count--;
|
|
|
|
if (seat->touch_device_count == 0) {
|
2013-10-18 01:04:06 +04:00
|
|
|
weston_touch_set_focus(seat, NULL);
|
2013-10-26 01:18:05 +04:00
|
|
|
weston_touch_cancel_grab(seat->touch);
|
2013-12-03 01:05:04 +04:00
|
|
|
weston_touch_reset_state(seat->touch);
|
2013-10-18 01:04:05 +04:00
|
|
|
seat_send_updated_caps(seat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
WL_EXPORT void
|
2013-05-31 21:09:50 +04:00
|
|
|
weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
|
|
|
|
const char *seat_name)
|
2013-04-18 23:40:10 +04:00
|
|
|
{
|
2013-05-07 06:24:50 +04:00
|
|
|
memset(seat, 0, sizeof *seat);
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
seat->selection_data_source = NULL;
|
|
|
|
wl_list_init(&seat->base_resource_list);
|
|
|
|
wl_signal_init(&seat->selection_signal);
|
|
|
|
wl_list_init(&seat->drag_resource_list);
|
|
|
|
wl_signal_init(&seat->destroy_signal);
|
2014-04-03 04:53:45 +04:00
|
|
|
wl_signal_init(&seat->updated_caps_signal);
|
2013-05-07 06:24:50 +04:00
|
|
|
|
2014-08-04 21:43:24 +04:00
|
|
|
seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
|
2013-07-09 03:03:57 +04:00
|
|
|
seat, bind_seat);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
seat->compositor = ec;
|
|
|
|
seat->modifier_state = 0;
|
2013-05-31 21:09:50 +04:00
|
|
|
seat->seat_name = strdup(seat_name);
|
2013-04-18 23:40:10 +04:00
|
|
|
|
|
|
|
wl_list_insert(ec->seat_list.prev, &seat->link);
|
|
|
|
|
|
|
|
clipboard_create(seat);
|
|
|
|
|
|
|
|
wl_signal_emit(&ec->seat_created_signal, seat);
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_seat_release(struct weston_seat *seat)
|
|
|
|
{
|
|
|
|
wl_list_remove(&seat->link);
|
|
|
|
|
2014-01-03 22:46:51 +04:00
|
|
|
if (seat->saved_kbd_focus)
|
|
|
|
wl_list_remove(&seat->saved_kbd_focus_listener.link);
|
|
|
|
|
2013-05-07 07:19:49 +04:00
|
|
|
if (seat->pointer)
|
2013-05-08 07:52:07 +04:00
|
|
|
weston_pointer_destroy(seat->pointer);
|
2013-05-07 07:19:49 +04:00
|
|
|
if (seat->keyboard)
|
2013-05-08 07:52:07 +04:00
|
|
|
weston_keyboard_destroy(seat->keyboard);
|
2013-05-07 07:19:49 +04:00
|
|
|
if (seat->touch)
|
2013-05-08 07:52:07 +04:00
|
|
|
weston_touch_destroy(seat->touch);
|
2013-05-07 06:24:50 +04:00
|
|
|
|
2013-05-31 21:09:50 +04:00
|
|
|
free (seat->seat_name);
|
|
|
|
|
2013-07-09 03:03:57 +04:00
|
|
|
wl_global_destroy(seat->global);
|
2013-07-09 00:20:31 +04:00
|
|
|
|
2013-04-18 23:40:10 +04:00
|
|
|
wl_signal_emit(&seat->destroy_signal, seat);
|
|
|
|
}
|