COMPOSITOR_MODULES="$COMPOSITOR_MODULES xkbcommon >= 0.3.0"
fi
+AC_ARG_ENABLE([multiseat],
+ [AC_HELP_STRING([--enable-multiseat],
+ [Enable multiseat feature])],
+ [],
+ [enable_multiseat=no])
+
+if test "x$enable_multiseat" = "xyes"; then
+ AC_DEFINE(HAVE_MULTISEAT, [1], [Enable multiseat feature])
+fi
+AM_CONDITIONAL(HAVE_MULTISEAT, test "x$enable_multiseat" = xyes)
+
AC_ARG_ENABLE(sys-uid, [ --enable-sys-uid],,
enable_sys_uid=no)
if test x$enable_sys_uid = xyes; then
#include "compositor.h"
#include "fullscreen-shell-server-protocol.h"
-struct fullscreen_shell {
+struct fs_client {
struct wl_client *client;
struct wl_listener client_destroyed;
+ struct wl_list link;
+};
+
+struct fullscreen_shell {
+ struct wl_list client_list;
struct weston_compositor *compositor;
struct weston_layer layer;
static void
client_destroyed(struct wl_listener *listener, void *data)
{
- struct fullscreen_shell *shell = container_of(listener,
- struct fullscreen_shell,
- client_destroyed);
- shell->client = NULL;
+ struct fs_client *client = container_of(listener,
+ struct fs_client, client_destroyed);
+ if (client) wl_list_remove(&client->link);
}
static void
{
struct fullscreen_shell *shell = data;
struct wl_resource *resource;
-
- if (shell->client != NULL && shell->client != client)
- return;
- else if (shell->client == NULL) {
- shell->client = client;
- wl_client_add_destroy_listener(client, &shell->client_destroyed);
+ struct fs_client *new_client;
+
+ new_client = malloc(sizeof *new_client);
+ if (new_client) {
+ memset(new_client, 0, sizeof *new_client);
+ new_client->client = client;
+ new_client->client_destroyed.notify = client_destroyed;
+ wl_list_insert(&shell->client_list, &new_client->link);
+ wl_client_add_destroy_listener(client, &new_client->client_destroyed);
}
resource = wl_resource_create(client, &_wl_fullscreen_shell_interface,
memset(shell, 0, sizeof *shell);
shell->compositor = compositor;
- shell->client_destroyed.notify = client_destroyed;
+ wl_list_init(&shell->client_list);
weston_layer_init(&shell->layer, &compositor->cursor_layer.link);
wl_signal_add(&compositor->seat_created_signal,
&shell->seat_created_listener);
wl_list_for_each(seat, &compositor->seat_list, link)
- seat_created(NULL, seat);
+ seat_created(&shell->seat_created_listener, seat);
wl_global_create(compositor->wl_display,
&_wl_fullscreen_shell_interface, 1, shell,
%define extra_config_options3 --enable-sys-uid
%endif
+%if "%{profile}" == "ivi"
+%define extra_config_options4 --enable-multiseat
+%endif
+
Name: weston
Version: 1.6.0
Release: 0
#Git-Clone: git://anongit.freedesktop.org/wayland/weston
#Git-Web: http://cgit.freedesktop.org/wayland/weston/
Source0: %name-%version.tar.xz
-Source1: %name.target
-Source1001: %name.manifest
+Source1001: %name.manifest
BuildRequires: autoconf >= 2.64, automake >= 1.11
BuildRequires: expat-devel
BuildRequires: libjpeg-devel
--with-cairo=glesv2 \
%{?extra_config_options1:%extra_config_options1} \
%{?extra_config_options2:%extra_config_options2} \
- %{?extra_config_options3:%extra_config_options3}
+ %{?extra_config_options3:%extra_config_options3} \
+ %{?extra_config_options4:%extra_config_options4}
make %{?_smp_mflags}
install -m 755 weston-fullscreen %{buildroot}%{_bindir}
-install -d %{buildroot}%{_unitdir_user}
-install -m 644 %{SOURCE1} %{buildroot}%{_unitdir_user}/weston.target
# The weston.service unit file must be provided by the weston-startup
# virtual package, i.e. "Provide: weston-startup". The weston-startup
# virtual package requirement is intended to force Tizen profile
%{_libdir}/weston/wayland-backend.so
%{_libdir}/weston/gl-renderer.so
%{_datadir}/weston
-%{_unitdir_user}/weston.target
%files devel
%manifest %{name}.manifest
clockid_t clock;
struct udev_input input;
+ char *main_seat;
uint32_t cursor_width;
uint32_t cursor_height;
if (strcmp(s, "") != 0) {
struct udev_seat *seat;
- seat = udev_seat_get_named(&ec->input, s);
- if (seat)
- seat->base.output = output;
-
- if (seat && seat->base.pointer)
- weston_pointer_clamp(seat->base.pointer,
+ seat = udev_seat_get_named(&ec->base, s);
+ if (seat) {
+ udev_seat_link_output(seat, output);
+#if HAVE_MULTISEAT
+ if (!seat->input.libinput)
+ udev_input_init(&seat->input, &ec->base,
+ ec->udev, s);
+ else if (seat->input.suspended)
+ udev_input_enable(&seat->input);
+#endif
+ if (seat->base.pointer)
+ weston_pointer_clamp(seat->base.pointer,
&seat->base.pointer->x,
&seat->base.pointer->y);
+ }
}
}
output->format = ec->format;
weston_config_section_get_string(section, "seat", &s, "");
+ output->base.seat_data.seatname = strdup(s);
+ weston_log("output %p belongs to seat '%s'\n", output,
+ output->base.seat_data.seatname);
setup_output_seat_constraint(ec, &output->base, s);
free(s);
{
struct drm_compositor *d = (struct drm_compositor *) ec;
- udev_input_destroy(&d->input);
-
wl_event_source_remove(d->udev_drm_source);
wl_event_source_remove(d->drm_source);
weston_launcher_destroy(d->base.launcher);
close(d->drm.fd);
-
+ free (d->main_seat);
free(d);
}
struct drm_compositor *ec = data;
struct drm_sprite *sprite;
struct drm_output *output;
+ struct udev_seat *useat;
+ struct weston_seat *seat, *next;
if (ec->base.session_active) {
weston_log("activating session\n");
compositor->state = ec->prev_state;
drm_compositor_set_modes(ec);
weston_compositor_damage_all(compositor);
- udev_input_enable(&ec->input);
+ wl_list_for_each_safe(seat, next, &ec->base.seat_list, link) {
+ useat = container_of(seat, struct udev_seat, base);
+ udev_input_enable(&useat->input);
+ }
} else {
weston_log("deactivating session\n");
- udev_input_disable(&ec->input);
+ wl_list_for_each_safe(seat, next, &ec->base.seat_list, link) {
+ useat = container_of(seat, struct udev_seat, base);
+ udev_input_disable(&useat->input);
+ }
ec->prev_state = compositor->state;
weston_compositor_offscreen(compositor);
switch_to_gl_renderer(c);
}
+static int
+create_seats(struct drm_compositor *ec, int connector,
+ struct udev_device *drm_device)
+{
+ struct udev_seat *seat = udev_seat_get_named(&ec->base, ec->main_seat);
+ if (seat && udev_input_init(&seat->input, &ec->base,
+ ec->udev, ec->main_seat) < 0) {
+ weston_log("failed to create input devices\n");
+ return -1;
+ }
+
+ if (create_outputs(ec, connector, drm_device) < 0)
+ return -1;
+
+ return 0;
+}
+
static struct weston_compositor *
drm_compositor_create(struct wl_display *display,
struct drm_parameters *param,
wl_list_init(&ec->sprite_list);
create_sprites(ec);
- if (udev_input_init(&ec->input,
- &ec->base, ec->udev, param->seat_id) < 0) {
- weston_log("failed to create input devices\n");
- goto err_sprite;
- }
-
- if (create_outputs(ec, param->connector, drm_device) < 0) {
+ ec->main_seat = strdup(param->seat_id);
+ if (create_seats(ec, param->connector, drm_device) < 0) {
weston_log("failed to create output for %s\n", path);
- goto err_udev_input;
+ goto err_sprite;
}
/* A this point we have some idea of whether or not we have a working
udev_monitor_unref(ec->udev_monitor);
err_drm_source:
wl_event_source_remove(ec->drm_source);
-err_udev_input:
- udev_input_destroy(&ec->input);
err_sprite:
ec->base.renderer->destroy(&ec->base);
gbm_device_destroy(ec->gbm);
err_compositor:
weston_compositor_shutdown(&ec->base);
err_base:
+ free(ec->main_seat);
free(ec);
return NULL;
}
#include <winpr/input.h>
#include "compositor.h"
+#include "../shared/str-util.h"
#include "pixman-renderer.h"
#define MAX_FREERDP_FDS 32
int use_pixman;
int sprawl_across_outputs;
+ int seatfilter;
+ char *seatname;
struct theme *theme;
cairo_device_t *frame_device;
struct wayland_parent_output {
struct wayland_output *output;
+ struct wayland_compositor *c;
struct wl_list link;
struct wl_output *global;
struct wl_list mode_list;
struct weston_mode *preferred_mode;
struct weston_mode *current_mode;
+ char *seatname;
};
struct wayland_shm_buffer {
struct wayland_output *output;
+
struct wl_list link;
struct wl_list free_link;
int focus;
struct wayland_output *output;
struct wayland_output *keyboard_focus;
+
+ enum wl_seat_capability caps;
+ int initialized;
+ int caps_update_required;
};
struct gl_renderer_interface *gl_renderer;
if (output->frame)
frame_destroy(output->frame);
+ free(output->name);
cairo_surface_destroy(output->gl.border.top);
cairo_surface_destroy(output->gl.border.left);
struct weston_mode *mode;
int32_t x;
+ if(poutput->output) {
+ weston_log("parent output already exists\n");
+ return poutput->output;
+ }
+
if (poutput->current_mode) {
mode = poutput->current_mode;
} else if (poutput->preferred_mode) {
mode = container_of(poutput->mode_list.next,
struct weston_mode, link);
} else {
- weston_log("No valid modes found. Skipping output");
+ weston_log("No valid modes found. Skipping output\n");
return NULL;
}
if (!output)
return NULL;
+ poutput->output = output;
output->parent.output = poutput->global;
output->base.make = poutput->physical.make;
};
static void
-input_handle_capabilities(void *data, struct wl_seat *seat,
- enum wl_seat_capability caps)
+input_capabilities_updated(struct wayland_input *input)
{
- struct wayland_input *input = data;
-
- if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->parent.pointer) {
- input->parent.pointer = wl_seat_get_pointer(seat);
+ if ((input->caps & WL_SEAT_CAPABILITY_POINTER) &&
+ !input->parent.pointer) {
+ input->parent.pointer = wl_seat_get_pointer(input->parent.seat);
wl_pointer_set_user_data(input->parent.pointer, input);
wl_pointer_add_listener(input->parent.pointer,
&pointer_listener, input);
weston_seat_init_pointer(&input->base);
- } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->parent.pointer) {
+ } else if (!(input->caps & WL_SEAT_CAPABILITY_POINTER) &&
+ input->parent.pointer) {
wl_pointer_destroy(input->parent.pointer);
input->parent.pointer = NULL;
}
- if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->parent.keyboard) {
- input->parent.keyboard = wl_seat_get_keyboard(seat);
+ if ((input->caps & WL_SEAT_CAPABILITY_KEYBOARD) &&
+ !input->parent.keyboard) {
+ input->parent.keyboard = wl_seat_get_keyboard(
+ input->parent.seat);
wl_keyboard_set_user_data(input->parent.keyboard, input);
wl_keyboard_add_listener(input->parent.keyboard,
&keyboard_listener, input);
- } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->parent.keyboard) {
+ } else if (!(input->caps & WL_SEAT_CAPABILITY_KEYBOARD) &&
+ input->parent.keyboard) {
wl_keyboard_destroy(input->parent.keyboard);
input->parent.keyboard = NULL;
}
+ input->caps_update_required = 0;
+}
+
+static void
+input_handle_capabilities(void *data, struct wl_seat *seat,
+ enum wl_seat_capability caps)
+{
+ struct wayland_input *input = data;
+
+ input->caps = caps;
+ weston_log ("input_handle_capabilities input with seatname %s"
+ " and caps %d\n", input->base.seat_name, input->caps);
+ if (input->base.seat_name || !input->compositor->seatfilter) {
+ input_capabilities_updated (input);
+ } else {
+ input->caps_update_required = 1;
+ }
}
static void
input_handle_name(void *data, struct wl_seat *seat,
- const char *name)
+ const char *name)
{
+ struct wayland_input *input = data;
+ if (input->compositor->seatfilter &&
+ (!name || !input->compositor->seatname ||
+ strcmp(input->compositor->seatname, name) != 0)) {
+ weston_log("seatname does not match %s:%s; remove "
+ "input\n", name, input->compositor->seatname);
+ wl_seat_destroy(input->parent.seat);
+ wl_list_remove(&input->link);
+ free(input);
+ return;
+ }
+ if (!input->initialized) {
+ weston_log ("initialise input with seat name %s\n", name);
+ weston_seat_init (&input->base, &input->compositor->base, name);
+ input->parent.cursor.surface = wl_compositor_create_surface(
+ input->compositor->parent.compositor);
+ input->initialized = 1;
+ }
+ if (input->caps_update_required)
+ input_capabilities_updated (input);
}
static const struct wl_seat_listener seat_listener = {
if (input == NULL)
return;
- weston_seat_init(&input->base, &c->base, "default");
+ weston_log ("create input with id %d\n", id);
input->compositor = c;
- input->parent.seat = wl_registry_bind(c->parent.registry, id,
- &wl_seat_interface, MIN(version, 4));
+ if (c->seatfilter)
+ input->parent.seat = wl_registry_bind(c->parent.registry, id,
+ &wl_seat_interface,
+ version > 2 ? version : 2);
+ else
+ input->parent.seat = wl_registry_bind(c->parent.registry, id,
+ &wl_seat_interface, MIN(version, 4));
+ input->base.seat_name = NULL;
+ input->initialized = 0;
+
wl_list_insert(c->input_list.prev, &input->link);
wl_seat_add_listener(input->parent.seat, &seat_listener, input);
wl_seat_set_user_data(input->parent.seat, input);
- input->parent.cursor.surface =
- wl_compositor_create_surface(c->parent.compositor);
+ if (!input->compositor->seatfilter) {
+ weston_log ("initialise input with seat name %s\n",
+ c->seatname);
+ weston_seat_init (&input->base, &input->compositor->base,
+ c->seatname ? c->seatname : "");
+ input->parent.cursor.surface = wl_compositor_create_surface(
+ c->parent.compositor);
+ input->initialized = 1;
+ }
+}
+
+static void
+wayland_parent_output_destroy(struct wayland_parent_output *output)
+{
+ struct weston_mode *mode, *next;
+
+ if (output->output)
+ wayland_output_destroy(&output->output->base);
+
+ wl_output_destroy(output->global);
+ free(output->physical.make);
+ free(output->physical.model);
+ free(output->seatname);
+
+ wl_list_for_each_safe(mode, next, &output->mode_list, link) {
+ wl_list_remove(&mode->link);
+ free(mode);
+ }
}
static void
}
}
+#if HAVE_MULTISEAT
+static void
+wayland_parent_output_done(void *data,
+ struct wl_output *wl_output)
+{
+ struct wayland_parent_output *output = data;
+ if (!output->seatname || !output->c || !output->c->seatname ||
+ strcmp(output->c->seatname, output->seatname) != 0) {
+ weston_log("output seatname (%s) doesnt match with"
+ " compositor seatname. destroying output\n",
+ output->seatname);
+ wayland_parent_output_destroy (output);
+ wl_list_remove(&output->link);
+ return;
+ }
+ if (output->c->sprawl_across_outputs) {
+ wayland_output_create_for_parent_output(output->c, output);
+ }
+}
+
+static void
+wayland_parent_output_scale(void *data,
+ struct wl_output *wl_output,
+ int32_t scale)
+{
+}
+
+static void
+wayland_parent_output_name(void *data, struct wl_output *wl_output_proxy,
+ const char *name)
+{
+ weston_log("output name %s\n", name);
+}
+
+static void
+wayland_parent_output_seatname(void *data, struct wl_output *wl_output_proxy,
+ const char *name)
+{
+ struct wayland_parent_output *poutput = data;
+ weston_log("output seatname %s\n", name);
+ poutput->seatname = strdup(name);
+}
+#endif
+
static const struct wl_output_listener output_listener = {
wayland_parent_output_geometry,
wayland_parent_output_mode
+#if HAVE_MULTISEAT
+ ,
+ wayland_parent_output_done,
+ wayland_parent_output_scale,
+ wayland_parent_output_name,
+ wayland_parent_output_seatname
+#endif
};
static void
return;
output->id = id;
- output->global = wl_registry_bind(c->parent.registry, id,
+
+ if (c->seatfilter)
+ output->global = wl_registry_bind(c->parent.registry, id,
+ &wl_output_interface, 3);
+ else
+ output->global = wl_registry_bind(c->parent.registry, id,
&wl_output_interface, 1);
if (!output->global) {
free(output);
return;
}
+ output->c = c;
+ output->seatname = NULL;
+ output->output = NULL;
wl_output_add_listener(output->global, &output_listener, output);
output->scale = 0;
wl_list_init(&output->mode_list);
wl_list_insert(&c->parent.output_list, &output->link);
- if (c->sprawl_across_outputs) {
- wl_display_roundtrip(c->parent.wl_display);
- wayland_output_create_for_parent_output(c, output);
- }
-}
-
-static void
-wayland_parent_output_destroy(struct wayland_parent_output *output)
-{
- struct weston_mode *mode, *next;
-
- if (output->output)
- wayland_output_destroy(&output->output->base);
-
- wl_output_destroy(output->global);
- free(output->physical.make);
- free(output->physical.model);
-
- wl_list_for_each_safe(mode, next, &output->mode_list, link) {
- wl_list_remove(&mode->link);
- free(mode);
+ if (!c->seatfilter && output->c->sprawl_across_outputs) {
+ wl_display_roundtrip(output->c->parent.wl_display);
+ wayland_output_create_for_parent_output(output->c, output);
}
}
static struct wayland_compositor *
wayland_compositor_create(struct wl_display *display, int use_pixman,
const char *display_name, int *argc, char *argv[],
- struct weston_config *config)
+ struct weston_config *config, const char* seatname,
+ int seatfilter)
{
struct wayland_compositor *c;
struct wl_event_loop *loop;
c = zalloc(sizeof *c);
if (c == NULL)
return NULL;
+ c->seatname = seatname ? strdup(seatname) : NULL;
+ c->seatfilter = seatfilter;
if (weston_compositor_init(&c->base, display, argc, argv,
config) < 0)
err_compositor:
weston_compositor_shutdown(&c->base);
err_free:
+ free(c->seatname);
free(c);
return NULL;
}
wl_cursor_theme_destroy(c->cursor_theme);
weston_compositor_shutdown(&c->base);
+ free(c->seatname);
free(c);
}
struct wayland_parent_output *poutput;
struct weston_config_section *section;
int x, count, width, height, scale, use_pixman, fullscreen, sprawl;
- const char *section_name, *display_name;
+#if HAVE_MULTISEAT
+ int seatfilter = 1;
+#else
+ int seatfilter = 0;
+#endif
+ const char *section_name, *display_name, *seatname;
char *name;
const struct weston_option wayland_options[] = {
parse_options(wayland_options,
ARRAY_LENGTH(wayland_options), argc, argv);
+ seatname = getenv("XDG_SEAT");
+ if (!seatname && seatfilter) {
+ weston_log("unable to determine seat for the compositor from"
+ "XDG_SEAT env. Disabling seat filter\n");
+ seatfilter = 0;
+ }
+
+ weston_log("Multiseat enabled %d\n", seatfilter);
c = wayland_compositor_create(display, use_pixman, display_name,
- argc, argv, config);
+ argc, argv, config, seatname, seatfilter);
if (!c)
return NULL;
if (sprawl || c->parent.fshell) {
c->sprawl_across_outputs = 1;
wl_display_roundtrip(c->parent.wl_display);
+ if (wl_list_empty(&c->parent.output_list))
+ return NULL;
wl_list_for_each(poutput, &c->parent.output_list, link)
wayland_output_create_for_parent_output(c, poutput);
#include "compositor.h"
#include "scaler-server-protocol.h"
#include "../shared/os-compatibility.h"
+#include "../shared/str-util.h"
#include "git-version.h"
#include "version.h"
struct wl_resource *resource;
resource = wl_resource_create(client, &wl_output_interface,
- MIN(version, 2), id);
+#if HAVE_MULTISEAT
+ MIN(version, 2),
+#else
+ MIN(version, 3),
+#endif
+ id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
wl_output_send_scale(resource,
output->current_scale);
+#if HAVE_MULTISEAT
+ if (version >= WL_OUTPUT_NAME_SINCE_VERSION)
+ wl_output_send_name(resource, output->name);
+
+ if (version >= WL_OUTPUT_SEATNAME_SINCE_VERSION)
+ wl_output_send_seatname(resource, output->seat_data.seatname);
+#endif
+
wl_list_for_each (mode, &output->mode_list, link) {
wl_output_send_mode(resource,
mode->flags,
wl_signal_emit(&output->destroy_signal, output);
free(output->name);
+ free(output->seat_data.seatname);
pixman_region32_fini(&output->region);
pixman_region32_fini(&output->previous_damage);
output->compositor->output_id_pool &= ~(1 << output->id);
int x, int y, int mm_width, int mm_height, uint32_t transform,
int32_t scale)
{
+#if HAVE_MULTISEAT
+ const int version = 3;
+#else
+ const int version = 2;
+#endif
output->compositor = c;
output->x = x;
output->y = y;
output->compositor->output_id_pool |= 1 << output->id;
output->global =
- wl_global_create(c->wl_display, &wl_output_interface, 2,
+ wl_global_create(c->wl_display, &wl_output_interface, version,
output, bind_output);
wl_signal_emit(&c->output_created_signal, output);
}
WL_EXPORT int
weston_environment_get_fd(const char *env)
{
- char *e, *end;
+ char *e;
int fd, flags;
e = getenv(env);
if (!e)
return -1;
- fd = strtol(e, &end, 0);
- if (*end != '\0')
+ if (!weston_strtoi(e, NULL, 0, &fd))
return -1;
flags = fcntl(fd, F_GETFD);
char *modules = NULL;
char *option_modules = NULL;
char *log = NULL;
- char *server_socket = NULL, *end;
+ char *server_socket = NULL;
int32_t idle_time = 300;
int32_t help = 0;
char *socket_name = NULL;
struct wl_client *primary_client;
struct wl_listener primary_client_destroyed;
struct weston_seat *seat;
+ const char *conf_file = NULL;
const struct weston_option core_options[] = {
{ WESTON_OPTION_STRING, "backend", 'B', &backend },
}
if (noconfig == 0)
- config = weston_config_parse("weston.ini");
+ conf_file = getenv("WESTON_CONFIG");
+ if (conf_file == NULL)
+ conf_file = "weston.ini";
+ config = weston_config_parse(conf_file);
if (config != NULL) {
weston_log("Using config file '%s'\n",
weston_config_get_full_path(config));
server_socket = getenv("WAYLAND_SERVER_SOCKET");
if (server_socket) {
weston_log("Running with single client\n");
- fd = strtol(server_socket, &end, 0);
- if (*end != '\0')
+ if (!weston_strtoi(server_socket, NULL, 0, &fd))
fd = -1;
} else {
fd = -1;
uint32_t id;
char *name;
+ struct {
+ char *seatname;
+ struct weston_seat *seat;
+ } seat_data;
+
void *renderer_state;
struct wl_list link;
int keyboard_device_count;
int touch_device_count;
- struct weston_output *output; /* constraint */
-
struct wl_signal destroy_signal;
struct wl_signal updated_caps_signal;
weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
{
struct weston_compositor *ec = pointer->seat->compositor;
- struct weston_output *output, *prev = NULL;
- int x, y, old_x, old_y, valid = 0;
+ struct weston_output *output, *prev = NULL, *closest = NULL;
+ int x, y, old_x, old_y;
+ int distance, min = INT_MAX;
+ int has_output = 0;
+
+ /* check if any output is attached to the pointer's seat or not */
+ wl_list_for_each(output, &ec->output_list, link) {
+ if (pointer->seat == output->seat_data.seat) {
+ has_output = 1;
+ break;
+ }
+ }
x = wl_fixed_to_int(*fx);
y = wl_fixed_to_int(*fy);
old_y = wl_fixed_to_int(pointer->y);
wl_list_for_each(output, &ec->output_list, link) {
- if (pointer->seat->output && pointer->seat->output != output)
+ if (has_output && pointer->seat != output->seat_data.seat)
continue;
if (pixman_region32_contains_point(&output->region,
x, y, NULL))
- valid = 1;
+ return;
if (pixman_region32_contains_point(&output->region,
old_x, old_y, NULL))
prev = output;
+ distance = abs(output->x + output->width / 2 - x) +
+ abs(output->y + output->height / 2 - y);
+ if (distance < min) {
+ min = distance;
+ closest = output;
+ }
}
if (!prev)
- prev = pointer->seat->output;
+ prev = closest;
- if (prev && !valid)
+ if (prev)
weston_pointer_clamp_for_output(pointer, prev, fx, fy);
}
struct weston_output *output, *closest = NULL;
int x, y, distance, min = INT_MAX;
wl_fixed_t fx, fy;
-
pointer = container_of(listener, struct weston_pointer,
output_destroy_listener);
ec = pointer->seat->compositor;
if (pixman_region32_contains_point(&output->region,
x, y, NULL))
return;
-
- /* Aproximante the distance from the pointer to the center of
+ /* Approximate the distance from the pointer to the centre of
* the output. */
distance = abs(output->x + output->width / 2 - x) +
abs(output->y + output->height / 2 - y);
weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
weston_pointer_move(pointer, fx, fy);
+
}
WL_EXPORT void
weston_logind_destroy(launcher->logind);
} else if (launcher->fd != -1) {
close(launcher->fd);
- wl_event_source_remove(launcher->source);
+ if (launcher->source) wl_event_source_remove(launcher->source);
} else {
weston_launcher_restore(launcher);
- wl_event_source_remove(launcher->vt_source);
+ if (launcher->vt_source) wl_event_source_remove(launcher->vt_source);
}
if (launcher->tty >= 0)
static void
process_events(struct udev_input *input);
static struct udev_seat *
-udev_seat_create(struct udev_input *input, const char *seat_name);
+udev_seat_create(struct weston_compositor *c, const char *seat_name);
static void
udev_seat_destroy(struct udev_seat *seat);
+static int
+udev_seat_has_output(struct udev_seat *seat)
+{
+ struct weston_output *output;
+ wl_list_for_each(output, &seat->base.compositor->output_list, link) {
+ if (seat && (&seat->base == output->seat_data.seat))
+ return 1;
+ }
+ return 0;
+}
+
static void
device_added(struct udev_input *input, struct libinput_device *libinput_device)
{
libinput_seat = libinput_device_get_seat(libinput_device);
seat_name = libinput_seat_get_logical_name(libinput_seat);
- udev_seat = udev_seat_get_named(input, seat_name);
+ udev_seat = udev_seat_get_named(c, seat_name);
if (!udev_seat)
return;
if (device == NULL)
return;
- udev_seat = (struct udev_seat *) seat;
wl_list_insert(udev_seat->devices_list.prev, &device->link);
- if (seat->output && seat->pointer)
+ if (udev_seat_has_output(udev_seat) && seat->pointer)
weston_pointer_clamp(seat->pointer,
&seat->pointer->x,
&seat->pointer->y);
if (!input->suspended)
weston_seat_repick(seat);
+
}
static void
evdev_led_update(device, leds);
}
+static int
+udev_seat_is_output_linked(struct udev_seat *seat, struct weston_output *output)
+{
+ if (seat && output->seat_data.seat &&
+ (&seat->base == output->seat_data.seat)) {
+ weston_log("output seatname (%s) is linked already with seat\n",
+ output->seat_data.seatname);
+ return 1;
+ }
+ return 0;
+}
+
+int
+udev_seat_link_output(struct udev_seat *seat, struct weston_output *output)
+{
+ if (udev_seat_is_output_linked(seat, output)) return 1;
+
+ if (!seat || !output || !seat->base.seat_name ||
+ !output->seat_data.seatname ||
+ strcmp(seat->base.seat_name, output->seat_data.seatname) != 0) {
+ return 0;
+ }
+
+ free(output->seat_data.seatname);
+ output->seat_data.seatname = strdup(seat->base.seat_name);
+ output->seat_data.seat = &seat->base;
+ weston_log("link output to seat %s\n", seat->base.seat_name);
+ return 1;
+}
+
static void
notify_output_create(struct wl_listener *listener, void *data)
{
struct udev_seat *seat = container_of(listener, struct udev_seat,
output_create_listener);
- struct evdev_device *device;
+ struct evdev_device *device, *next;
struct weston_output *output = data;
- wl_list_for_each(device, &seat->devices_list, link) {
- if (device->output_name &&
+ weston_log("notify received for output created for seat %s\n",
+ seat->base.seat_name);
+ udev_seat_link_output(seat, output);
+
+ wl_list_for_each_safe(device, next, &seat->devices_list, link) {
+ if (device->output_name && output->name &&
strcmp(output->name, device->output_name) == 0) {
evdev_device_set_output(device, output);
}
}
static struct udev_seat *
-udev_seat_create(struct udev_input *input, const char *seat_name)
+udev_seat_create(struct weston_compositor *c, const char *seat_name)
{
- struct weston_compositor *c = input->compositor;
struct udev_seat *seat;
seat = zalloc(sizeof *seat);
wl_list_init(&seat->devices_list);
+ weston_log("seat created with name %s\n", seat_name);
return seat;
}
}
struct udev_seat *
-udev_seat_get_named(struct udev_input *input, const char *seat_name)
+udev_seat_get_named(struct weston_compositor *c, const char *seat_name)
{
struct udev_seat *seat;
- wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
+ wl_list_for_each(seat, &c->seat_list, base.link) {
if (strcmp(seat->base.seat_name, seat_name) == 0)
return seat;
}
- return udev_seat_create(input, seat_name);
+ return udev_seat_create(c, seat_name);
}
#include "compositor.h"
-struct udev_seat {
- struct weston_seat base;
- struct wl_list devices_list;
- struct wl_listener output_create_listener;
-};
-
struct udev_input {
struct libinput *libinput;
struct wl_event_source *libinput_source;
int suspended;
};
+struct udev_seat {
+ struct weston_seat base;
+ struct udev_input input;
+ struct wl_list devices_list;
+ struct wl_listener output_create_listener;
+};
+
int
udev_input_enable(struct udev_input *input);
void
udev_input_destroy(struct udev_input *input);
struct udev_seat *
-udev_seat_get_named(struct udev_input *u,
+udev_seat_get_named(struct weston_compositor *c,
const char *seat_name);
+int udev_seat_link_output(struct udev_seat *seat,
+ struct weston_output *output);
+
#endif
#include "udev-seat.h"
static const char default_seat[] = "seat0";
-static const char default_seat_name[] = "default";
+static const char default_seat_name[] = "seat0";
static void
udev_seat_destroy(struct udev_seat *seat);
static int
+udev_seat_has_output(struct udev_seat *seat)
+{
+ struct weston_output *output;
+ wl_list_for_each(output, &seat->base.compositor->output_list, link) {
+ if (seat && (&seat->base == output->seat_data.seat))
+ return 1;
+ }
+ return 0;
+}
+
+static int
device_added(struct udev_device *udev_device, struct udev_input *input)
{
struct weston_compositor *c;
if (!seat_name)
seat_name = default_seat_name;
- seat = udev_seat_get_named(input, seat_name);
+ seat = udev_seat_get_named(c, seat_name);
if (seat == NULL)
return -1;
wl_list_insert(seat->devices_list.prev, &device->link);
- if (seat->base.output && seat->base.pointer)
+ if (udev_seat_has_output(seat) && seat->base.pointer)
weston_pointer_clamp(seat->base.pointer,
&seat->base.pointer->x,
&seat->base.pointer->y);
if (input->enabled == 1)
weston_seat_repick(&seat->base);
+ weston_log("device with path %s is added to seat %s\n", devnode,
+ input->seat_id);
return 0;
}
memset(input, 0, sizeof *input);
input->seat_id = strdup(seat_id);
input->compositor = c;
- input->udev = udev;
input->udev = udev_ref(udev);
if (udev_input_enable(input) < 0)
goto err;
return 0;
err:
- free(input->seat_id);
return -1;
}
drm_led_update(struct weston_seat *seat_base, enum weston_led leds)
{
struct udev_seat *seat = (struct udev_seat *) seat_base;
- struct evdev_device *device;
+ struct evdev_device *device, *next;
- wl_list_for_each(device, &seat->devices_list, link)
+ wl_list_for_each_safe(device, next, &seat->devices_list, link)
evdev_led_update(device, leds);
}
+static int
+udev_seat_is_output_linked(struct udev_seat *seat, struct weston_output *output)
+{
+ if (seat && output->seat_data.seat &&
+ (&seat->base == output->seat_data.seat)) {
+ weston_log("output seatname (%s) is linked already with seat\n",
+ output->seat_data.seatname);
+ return 1;
+ }
+ return 0;
+}
+
+int
+udev_seat_link_output(struct udev_seat *seat, struct weston_output *output)
+{
+ if (udev_seat_is_output_linked(seat, output)) return 1;
+
+ if (!seat || !output || !seat->base.seat_name ||
+ !output->seat_data.seatname ||
+ strcmp(seat->base.seat_name, output->seat_data.seatname) != 0) {
+ return 0;
+ }
+
+ weston_log("link output to seat %s\n", seat->base.seat_name);
+ free(output->seat_data.seatname);
+ output->seat_data.seatname = strdup(seat->base.seat_name);
+ output->seat_data.seat = &seat->base;
+ return 1;
+}
+
static void
notify_output_create(struct wl_listener *listener, void *data)
{
struct udev_seat *seat = container_of(listener, struct udev_seat,
output_create_listener);
- struct evdev_device *device;
+ struct evdev_device *device, *next;
struct weston_output *output = data;
- wl_list_for_each(device, &seat->devices_list, link) {
- if (device->output_name &&
+ weston_log("notify received for output created for seat %s\n",
+ seat->base.seat_name);
+ if (!udev_seat_link_output(seat, output))
+ return;
+
+ wl_list_for_each_safe(device, next, &seat->devices_list, link) {
+ if (device->output_name && output->name &&
strcmp(output->name, device->output_name) == 0) {
evdev_device_set_output(device, output);
}
}
static struct udev_seat *
-udev_seat_create(struct udev_input *input, const char *seat_name)
+udev_seat_create(struct weston_compositor *c, const char *seat_name)
{
- struct weston_compositor *c = input->compositor;
struct udev_seat *seat;
seat = zalloc(sizeof *seat);
&seat->output_create_listener);
wl_list_init(&seat->devices_list);
+ weston_log("created seat with name %s\n", seat_name);
+
return seat;
}
static void
udev_seat_destroy(struct udev_seat *seat)
{
+ weston_log("seat destroyed with name %s\n", seat->base.seat_name);
weston_seat_release(&seat->base);
wl_list_remove(&seat->output_create_listener.link);
free(seat);
}
struct udev_seat *
-udev_seat_get_named(struct udev_input *input, const char *seat_name)
+udev_seat_get_named(struct weston_compositor *c, const char *seat_name)
{
- struct weston_compositor *c = input->compositor;
- struct udev_seat *seat;
+ struct udev_seat *seat, *next;
- wl_list_for_each(seat, &c->seat_list, base.link) {
+ wl_list_for_each_safe(seat, next, &c->seat_list, base.link) {
if (strcmp(seat->base.seat_name, seat_name) == 0)
return seat;
}
- seat = udev_seat_create(input, seat_name);
+ seat = udev_seat_create(c, seat_name);
if (!seat)
return NULL;
#include "compositor.h"
-struct udev_seat {
- struct weston_seat base;
- struct wl_list devices_list;
- struct wl_listener output_create_listener;
-};
-
struct udev_input {
struct udev *udev;
struct udev_monitor *udev_monitor;
int enabled;
};
+struct udev_seat {
+ struct weston_seat base;
+ struct udev_input input;
+ struct wl_list devices_list;
+ struct wl_listener output_create_listener;
+};
+
int udev_input_enable(struct udev_input *input);
void udev_input_disable(struct udev_input *input);
int udev_input_init(struct udev_input *input,
const char *seat_id);
void udev_input_destroy(struct udev_input *input);
-struct udev_seat *udev_seat_get_named(struct udev_input *input,
+struct udev_seat *udev_seat_get_named(struct weston_compositor *c,
const char *seat_name);
+
+int udev_seat_link_output(struct udev_seat *seat,
+ struct weston_output *output);
+
#endif