diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 727a63a8f..01788c2cb 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -54,9 +54,6 @@ #ifdef HAVE_WAYLAND #include "meta-wayland-private.h" -#include -#include -#include #endif #define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" @@ -4084,18 +4081,6 @@ handle_set_spew_mark (MetaDisplay *display, } #ifdef HAVE_WAYLAND -static gboolean -activate_vt (int vt) -{ - int tty, reply; - - tty = open ("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC); - reply = ioctl (tty, VT_ACTIVATE, vt); - close (tty); - - return (reply == 0); -} - static void handle_switch_vt (MetaDisplay *display, MetaScreen *screen, @@ -4104,10 +4089,28 @@ handle_switch_vt (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - gint vt = binding->handler->data; + gint vt = binding->handler->data; + MetaWaylandCompositor *compositor; + MetaLauncher *launcher; - if (!activate_vt (vt)) - g_warning ("Failed to switch VT"); + compositor = meta_wayland_compositor_get_default (); + launcher = meta_wayland_compositor_get_launcher (compositor); + + if (launcher) + { + GError *error; + + error = NULL; + if (!meta_launcher_activate_vt (launcher, vt, &error)) + { + g_warning ("Failed to switch VT: %s", error->message); + g_error_free (error); + } + } + else + { + g_debug ("Ignoring VT switch keybinding, not running as VT manager"); + } } #endif diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 26cd88ee0..6dc9620f0 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -99,6 +99,7 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, const ClutterEvent *event); +MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor); gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor); MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 84b51edfe..1db2fceb4 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -764,6 +764,12 @@ meta_wayland_finalize (void) meta_launcher_free (compositor->launcher); } +MetaLauncher * +meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor) +{ + return compositor->launcher; +} + gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor) { diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c index c86185a88..f24221d1c 100644 --- a/src/wayland/meta-weston-launch.c +++ b/src/wayland/meta-weston-launch.c @@ -385,3 +385,17 @@ meta_launcher_free (MetaLauncher *launcher) g_slice_free (MetaLauncher, launcher); } + +gboolean +meta_launcher_activate_vt (MetaLauncher *launcher, + int vt, + GError **error) +{ + struct weston_launcher_activate_vt message; + + message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; + message.vt = vt; + + return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error); +} + diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h index 498edbb7f..96bc13bf7 100644 --- a/src/wayland/meta-weston-launch.h +++ b/src/wayland/meta-weston-launch.h @@ -28,6 +28,10 @@ typedef struct _MetaLauncher MetaLauncher; MetaLauncher *meta_launcher_new (void); void meta_launcher_free (MetaLauncher *self); +gboolean meta_launcher_activate_vt (MetaLauncher *self, + int number, + GError **error); + gboolean meta_launcher_set_drm_fd (MetaLauncher *self, int drm_fd, GError **error); diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c index cbd7c9e67..773eea4bd 100644 --- a/src/wayland/weston-launch.c +++ b/src/wayland/weston-launch.c @@ -269,6 +269,40 @@ out: return 0; } +static int +handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len) +{ + struct weston_launcher_reply reply; + struct weston_launcher_activate_vt *message; + + reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT; + reply.ret = -1; + + if (len != sizeof(*message)) { + error(0, 0, "missing value in activate_vt request"); + goto out; + } + + message = msg->msg_iov->iov_base; + + reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt); + if (reply.ret < 0) + reply.ret = -errno; + + if (wl->verbose) + fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret); + +out: + do { + len = send(wl->sock[0], &reply, sizeof reply, 0); + } while (len < 0 && errno == EINTR); + if (len < 0) + return -1; + + return 0; +} + + static int handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) { @@ -385,6 +419,9 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_CONFIRM_VT_SWITCH: ret = handle_confirm_vt_switch(wl, &msg, len); break; + case WESTON_LAUNCHER_ACTIVATE_VT: + ret = handle_activate_vt(wl, &msg, len); + break; } return ret; diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h index 63e28098c..74e6c3be6 100644 --- a/src/wayland/weston-launch.h +++ b/src/wayland/weston-launch.h @@ -32,7 +32,8 @@ enum weston_launcher_message_type { enum weston_launcher_opcode { WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST), WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST), - WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST), + WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST), }; enum weston_launcher_server_opcode {