diff options
author | emersion <contact@emersion.fr> | 2018-06-17 14:49:18 +0100 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-06-17 14:49:18 +0100 |
commit | 57548b557ae9e4f2b03c2d78996706f0990ab9d6 (patch) | |
tree | 85d7ae8d5d3f302d16914690f8e30e40e8ba0969 /backend | |
parent | bd0c1b794992bf94560bd429f4057c9d09989f06 (diff) | |
parent | fb118ac9966bbb663ddb9964f54c879a0bb88fba (diff) |
Merge branch 'master' into screencontent
Diffstat (limited to 'backend')
-rw-r--r-- | backend/libinput/backend.c | 4 | ||||
-rw-r--r-- | backend/session/direct.c | 60 | ||||
-rw-r--r-- | backend/session/logind.c | 5 | ||||
-rw-r--r-- | backend/session/session.c | 4 | ||||
-rw-r--r-- | backend/wayland/wl_seat.c | 40 |
5 files changed, 85 insertions, 28 deletions
diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index f4d54c97..1dde5854 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -55,8 +55,8 @@ static bool backend_start(struct wlr_backend *_backend) { return false; } - // TODO: Let user customize seat used - if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) { + if (libinput_udev_assign_seat(backend->libinput_context, + backend->session->seat) != 0) { wlr_log(L_ERROR, "Failed to assign libinput seat"); return false; } diff --git a/backend/session/direct.c b/backend/session/direct.c index 13a26d99..7fa7d05b 100644 --- a/backend/session/direct.c +++ b/backend/session/direct.c @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE 200809L #include <errno.h> +#include <fcntl.h> #include <linux/input.h> #include <linux/kd.h> #include <linux/major.h> @@ -76,30 +77,39 @@ static void direct_session_close(struct wlr_session *base, int fd) { static bool direct_change_vt(struct wlr_session *base, unsigned vt) { struct direct_session *session = wl_container_of(base, session, base); + + // Only seat0 has VTs associated with it + if (strcmp(session->base.seat, "seat0") != 0) { + return true; + } + return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0; } static void direct_session_destroy(struct wlr_session *base) { struct direct_session *session = wl_container_of(base, session, base); - struct vt_mode mode = { - .mode = VT_AUTO, - }; - errno = 0; + if (strcmp(session->base.seat, "seat0") == 0) { + struct vt_mode mode = { + .mode = VT_AUTO, + }; + errno = 0; + + ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); + ioctl(session->tty_fd, KDSETMODE, KD_TEXT); + ioctl(session->tty_fd, VT_SETMODE, &mode); - ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); - ioctl(session->tty_fd, KDSETMODE, KD_TEXT); - ioctl(session->tty_fd, VT_SETMODE, &mode); + if (errno) { + wlr_log(L_ERROR, "Failed to restore tty"); + } - if (errno) { - wlr_log(L_ERROR, "Failed to restore tty"); + wl_event_source_remove(session->vt_source); + close(session->tty_fd); } direct_ipc_finish(session->sock, session->child); close(session->sock); - wl_event_source_remove(session->vt_source); - close(session->tty_fd); free(session); } @@ -138,19 +148,19 @@ static int vt_handler(int signo, void *data) { } static bool setup_tty(struct direct_session *session, struct wl_display *display) { - int fd = dup(STDIN_FILENO); + int fd = open("/dev/tty", O_RDWR); if (fd == -1) { - wlr_log_errno(L_ERROR, "Cannot open tty"); + wlr_log_errno(L_ERROR, "Cannot open /dev/tty"); return false; } - struct stat st; - if (fstat(fd, &st) == -1 || major(st.st_rdev) != TTY_MAJOR || minor(st.st_rdev) == 0) { - wlr_log(L_ERROR, "Not running from a virtual terminal"); + struct vt_stat vt_stat; + if (ioctl(fd, VT_GETSTATE, &vt_stat)) { + wlr_log_errno(L_ERROR, "Could not get current tty number"); goto error; } - int tty = minor(st.st_rdev); + int tty = vt_stat.v_active; int ret, kd_mode, old_kbmode; ret = ioctl(fd, KDGETMODE, &kd_mode); @@ -224,20 +234,24 @@ static struct wlr_session *direct_session_create(struct wl_display *disp) { goto error_session; } - if (!setup_tty(session, disp)) { - goto error_ipc; - } - - // XXX: Is it okay to trust the environment like this? const char *seat = getenv("XDG_SEAT"); if (!seat) { seat = "seat0"; } - wlr_log(L_INFO, "Successfully loaded direct session"); + if (strcmp(seat, "seat0") == 0) { + if (!setup_tty(session, disp)) { + goto error_ipc; + } + } else { + session->base.vtnr = 0; + session->tty_fd = -1; + } snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat); session->base.impl = &session_direct; + + wlr_log(L_INFO, "Successfully loaded direct session"); return &session->base; error_ipc: diff --git a/backend/session/logind.c b/backend/session/logind.c index f0ac1e93..3a3cc57d 100644 --- a/backend/session/logind.c +++ b/backend/session/logind.c @@ -109,6 +109,11 @@ static void logind_release_device(struct wlr_session *base, int fd) { static bool logind_change_vt(struct wlr_session *base, unsigned vt) { struct logind_session *session = wl_container_of(base, session, base); + // Only seat0 has VTs associated with it + if (strcmp(session->base.seat, "seat0") != 0) { + return true; + } + int ret; sd_bus_message *msg = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; diff --git a/backend/session/session.c b/backend/session/session.c index 2d5d9776..026040fd 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -19,9 +19,7 @@ extern const struct session_impl session_logind; extern const struct session_impl session_direct; static const struct session_impl *impls[] = { -#ifdef WLR_HAS_SYSTEMD - &session_logind, -#elif defined(WLR_HAS_ELOGIND) +#if defined(WLR_HAS_SYSTEMD) || defined(WLR_HAS_ELOGIND) &session_logind, #endif &session_direct, diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index cf9b9372..8ed61409 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -3,6 +3,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <wayland-client.h> #include <wlr/interfaces/wlr_input_device.h> #include <wlr/interfaces/wlr_keyboard.h> @@ -169,12 +170,51 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, // TODO: set keymap } +static uint32_t get_current_time_msec() { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + return now.tv_nsec / 1000; +} + static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { + struct wlr_input_device *dev = data; + + uint32_t time = get_current_time_msec(); + + uint32_t *keycode_ptr; + wl_array_for_each(keycode_ptr, keys) { + struct wlr_event_keyboard_key event = { + .keycode = *keycode_ptr, + .state = WLR_KEY_PRESSED, + .time_msec = time, + .update_state = false, + }; + wlr_keyboard_notify_key(dev->keyboard, &event); + } } static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface) { + struct wlr_input_device *dev = data; + + uint32_t time = get_current_time_msec(); + + uint32_t pressed[dev->keyboard->num_keycodes]; + memcpy(pressed, dev->keyboard->keycodes, + dev->keyboard->num_keycodes * sizeof(uint32_t)); + + for (size_t i = 0; i < sizeof(pressed)/sizeof(pressed[0]); ++i) { + uint32_t keycode = pressed[i]; + + struct wlr_event_keyboard_key event = { + .keycode = keycode, + .state = WLR_KEY_RELEASED, + .time_msec = time, + .update_state = false, + }; + wlr_keyboard_notify_key(dev->keyboard, &event); + } } static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, |