[mutter/wip/wayland-display: 5/17] Improve handling while VT switched
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-display: 5/17] Improve handling while VT switched
- Date: Fri, 19 Jul 2013 14:06:54 +0000 (UTC)
commit 84596ebd32888f5f2f05e5c5351999ee83e1a68a
Author: Giovanni Campagna <gcampagn redhat com>
Date: Tue Jul 16 14:10:14 2013 +0200
Improve handling while VT switched
When we don't have the DRM master, there is absolutely nothing
we can do (no event processing, no video output), so emulate
the old X DRM lock with a nested GMainContext without sources.
src/wayland/meta-tty.c | 69 +++++++++++++++++++++++++------------
src/wayland/meta-wayland.c | 12 +++++-
src/wayland/meta-weston-launch.c | 15 ++++----
3 files changed, 64 insertions(+), 32 deletions(-)
---
diff --git a/src/wayland/meta-tty.c b/src/wayland/meta-tty.c
index 8b5174e..82967fe 100644
--- a/src/wayland/meta-tty.c
+++ b/src/wayland/meta-tty.c
@@ -59,9 +59,12 @@ struct _MetaTTY
int fd;
struct termios terminal_attributes;
- int input_source, vt_source;
+ GMainContext *nested_context;
+ GMainLoop *nested_loop;
+
+ int input_source;
+ GSource *vt_enter_source, *vt_leave_source;
int vt, starting_vt;
- gboolean has_vt;
int kb_mode;
};
@@ -79,27 +82,35 @@ G_DEFINE_TYPE_WITH_CODE (MetaTTY, meta_tty, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
meta_tty_initable_iface_init));
-static int
-vt_handler (gpointer user_data)
+static gboolean
+vt_acquire_handler (gpointer user_data)
{
MetaTTY *tty = user_data;
- if (tty->has_vt)
- {
- tty->has_vt = FALSE;
- g_signal_emit (tty, signals[SIGNAL_LEAVE], 0);
+ g_main_loop_quit (tty->nested_loop);
- ioctl (tty->fd, VT_RELDISP, 1);
- }
- else
- {
- ioctl (tty->fd, VT_RELDISP, VT_ACKACQ);
+ return FALSE;
+}
- tty->has_vt = 1;
- g_signal_emit (tty, signals[SIGNAL_ENTER], 0);
- }
+static gboolean
+vt_release_handler (gpointer user_data)
+{
+ MetaTTY *tty = user_data;
- return 1;
+ g_signal_emit (tty, signals[SIGNAL_LEAVE], 0);
+
+ ioctl (tty->fd, VT_RELDISP, 1);
+
+ /* We can't do anything at this point, because we don't
+ have input devices and we don't have the DRM master,
+ so let's run a nested busy loop until the VT is reentered */
+ g_main_loop_run (tty->nested_loop);
+
+ ioctl (tty->fd, VT_RELDISP, VT_ACKACQ);
+
+ g_signal_emit (tty, signals[SIGNAL_ENTER], 0);
+
+ return FALSE;
}
static int
@@ -164,7 +175,7 @@ env_get_fd (const char *env)
if (value == NULL)
return -1;
else
- return g_ascii_strtoll (env, NULL, 10);
+ return g_ascii_strtoll (value, NULL, 10);
}
static gboolean
@@ -269,10 +280,9 @@ meta_tty_initable_init(GInitable *initable,
goto err_kdkbmode;
}
- tty->has_vt = 1;
mode.mode = VT_PROCESS;
mode.relsig = SIGUSR1;
- mode.acqsig = SIGUSR1;
+ mode.acqsig = SIGUSR2;
if (ioctl(tty->fd, VT_SETMODE, &mode) < 0)
{
g_set_error (error, G_IO_ERROR,
@@ -281,7 +291,16 @@ meta_tty_initable_init(GInitable *initable,
goto err_kdmode;
}
- tty->vt_source = g_unix_signal_add (SIGUSR1, vt_handler, tty);
+ tty->vt_enter_source = g_unix_signal_source_new (SIGUSR2);
+ g_source_set_callback (tty->vt_enter_source, vt_acquire_handler, tty, NULL);
+ tty->vt_leave_source = g_unix_signal_source_new (SIGUSR1);
+ g_source_set_callback (tty->vt_leave_source, vt_release_handler, tty, NULL);
+
+ tty->nested_context = g_main_context_new ();
+ tty->nested_loop = g_main_loop_new (tty->nested_context, FALSE);
+
+ g_source_attach (tty->vt_leave_source, NULL);
+ g_source_attach (tty->vt_enter_source, tty->nested_context);
return TRUE;
@@ -319,7 +338,7 @@ tty_reset (MetaTTY *tty)
if (ioctl (tty->fd, VT_SETMODE, &mode) < 0)
g_warning ("could not reset vt handling\n");
- if (tty->has_vt && tty->vt != tty->starting_vt)
+ if (tty->vt != tty->starting_vt)
{
ioctl(tty->fd, VT_ACTIVATE, tty->starting_vt);
ioctl(tty->fd, VT_WAITACTIVE, tty->starting_vt);
@@ -334,7 +353,11 @@ meta_tty_finalize (GObject *object)
if (tty->input_source)
g_source_remove (tty->input_source);
- g_source_remove (tty->vt_source);
+ g_source_destroy (tty->vt_enter_source);
+ g_source_destroy (tty->vt_leave_source);
+
+ g_main_loop_unref (tty->nested_loop);
+ g_main_context_unref (tty->nested_context);
tty_reset (tty);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 7516af0..ffdde94 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -1738,7 +1738,7 @@ env_get_fd (const char *env)
if (value == NULL)
return -1;
else
- return g_ascii_strtoll (env, NULL, 10);
+ return g_ascii_strtoll (value, NULL, 10);
}
static void
@@ -1853,6 +1853,8 @@ meta_wayland_init (void)
if (compositor->drm_fd >= 0)
{
+ GError *error;
+
/* Running on bare metal, let's initalize DRM master and VT handling */
compositor->tty = meta_tty_new ();
if (compositor->tty)
@@ -1861,7 +1863,13 @@ meta_wayland_init (void)
g_signal_connect (compositor->tty, "leave", G_CALLBACK (on_our_vt_leave), compositor);
}
- on_our_vt_enter (compositor->tty, compositor);
+ error = NULL;
+ if (!meta_weston_launch_set_master (compositor->weston_launch,
+ compositor->drm_fd, TRUE, &error))
+ {
+ g_error ("Failed to become DRM master: %s", error->message);
+ g_error_free (error);
+ }
}
compositor->stage = meta_wayland_stage_new ();
diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c
index 68f14cf..225ef2e 100644
--- a/src/wayland/meta-weston-launch.c
+++ b/src/wayland/meta-weston-launch.c
@@ -79,14 +79,14 @@ send_message_to_wl (GSocket *weston_launch,
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ok),
"Got failure from weston-launch: %s", strerror (-ok));
- for (i = 0; in_all_cmsg[i]; i++)
+ for (i = 0; in_all_cmsg && in_all_cmsg[i]; i++)
g_object_unref (in_all_cmsg[i]);
g_free (in_all_cmsg);
return FALSE;
}
- if (in_all_cmsg[0])
+ if (in_all_cmsg && in_all_cmsg[0])
{
for (i = 1; in_all_cmsg[i]; i++)
g_object_unref (in_all_cmsg[i]);
@@ -156,17 +156,18 @@ meta_weston_launch_open_input_device (GSocket *weston_launch,
struct weston_launcher_open *message;
GSocketControlMessage *cmsg;
gboolean ok;
+ gsize size;
int *fds, n_fd;
int ret;
- message = g_malloc (sizeof (struct weston_launcher_open) +
- strlen (name));
+ size = sizeof (struct weston_launcher_open) + strlen (name) + 1;
+ message = g_malloc (size);
message->header.opcode = WESTON_LAUNCHER_OPEN;
message->flags = flags;
strcpy (message->path, name);
+ message->path[strlen(name)] = 0;
- ok = send_message_to_wl (weston_launch, message,
- sizeof (struct weston_launcher_open) + strlen (name),
+ ok = send_message_to_wl (weston_launch, message, size,
NULL, &cmsg, error);
if (ok)
@@ -178,12 +179,12 @@ meta_weston_launch_open_input_device (GSocket *weston_launch,
ret = fds[0];
g_free (fds);
+ g_object_unref (cmsg);
}
else
ret = -1;
g_free (message);
- g_object_unref (cmsg);
return ret;
}
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]