[mutter/wip/wayland-bare-metal: 6/7] wayland: add TTY and DRM master management
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-bare-metal: 6/7] wayland: add TTY and DRM master management
- Date: Wed, 28 Aug 2013 09:07:34 +0000 (UTC)
commit 179e48b511257af99f403244a45680bf50b0efe7
Author: Giovanni Campagna <gcampagn redhat com>
Date: Mon Aug 19 14:57:16 2013 +0200
wayland: add TTY and DRM master management
Now that we have a setuid launcher binary, we can make use of
using a private protocol through the socket we're passed at startup.
We also use the new hook in clutter-evdev to ask mutter-launch for
the FDs of the input devices we need, and we emulate the old X
DRM lock with a nested GMainContext without sources.
In the future, mutter-launch will be replaced with the new logind
API currently in development.
https://bugzilla.gnome.org/show_bug.cgi?id=705861
configure.ac | 2 +-
src/Makefile.am | 4 +-
src/core/main.c | 70 +------
src/wayland/meta-wayland-private.h | 6 +
src/wayland/meta-wayland.c | 43 ++++-
src/wayland/meta-weston-launch.c | 432 ++++++++++++++++++++++++++++++++++++
src/wayland/meta-weston-launch.h | 54 +++++
7 files changed, 543 insertions(+), 68 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 415ca5d..efd8fb8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -232,7 +232,7 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
AC_SUBST([WAYLAND_SCANNER])
AC_SUBST(XWAYLAND_PATH)
-MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server"
+MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server libdrm"
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
diff --git a/src/Makefile.am b/src/Makefile.am
index 4fc7c58..462e8a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -195,7 +195,9 @@ libmutter_wayland_la_SOURCES += \
wayland/meta-wayland-seat.c \
wayland/meta-wayland-seat.h \
wayland/meta-wayland-stage.h \
- wayland/meta-wayland-stage.c
+ wayland/meta-wayland-stage.c \
+ wayland/meta-weston-launch.c \
+ wayland/meta-weston-launch.h
libmutter_wayland_la_LDFLAGS = -no-undefined
libmutter_wayland_la_LIBADD = $(MUTTER_LIBS)
diff --git a/src/core/main.c b/src/core/main.c
index c4620a1..5f1f4da 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -58,6 +58,7 @@
#include "meta-wayland-private.h"
#include <glib-object.h>
+#include <glib-unix.h>
#include <gdk/gdkx.h>
#include <stdlib.h>
@@ -352,59 +353,12 @@ meta_finalize (void)
meta_wayland_finalize ();
}
-static int signal_pipe_fds[2] = { -1, -1 };
-
-static void
-signal_handler (int signum)
-{
- if (signal_pipe_fds[1] >= 0)
- {
- switch (signum)
- {
- case SIGTERM:
- write (signal_pipe_fds[1], "T", 1);
- break;
- default:
- break;
- }
- }
-}
-
static gboolean
-on_signal (GIOChannel *source,
- GIOCondition condition,
- void *data)
+on_sigterm (gpointer user_data)
{
- char signal;
- int count;
+ meta_quit (EXIT_SUCCESS);
- for (;;)
- {
- count = read (signal_pipe_fds[0], &signal, 1);
- if (count == EINTR)
- continue;
- if (count < 0)
- {
- const char *msg = strerror (errno);
- g_warning ("Error handling signal: %s", msg);
- }
- if (count != 1)
- {
- g_warning ("Unexpectedly failed to read byte from signal pipe\n");
- return TRUE;
- }
- break;
- }
- switch (signal)
- {
- case 'T': /* SIGTERM */
- meta_quit (META_EXIT_SUCCESS);
- break;
- default:
- g_warning ("Spurious character '%c' read from signal pipe", signal);
- }
-
- return TRUE;
+ return G_SOURCE_REMOVE;
}
/**
@@ -418,7 +372,6 @@ meta_init (void)
{
struct sigaction act;
sigset_t empty_mask;
- GIOChannel *channel;
sigemptyset (&empty_mask);
act.sa_handler = SIG_IGN;
@@ -433,20 +386,7 @@ meta_init (void)
g_strerror (errno));
#endif
- if (pipe (signal_pipe_fds) != 0)
- g_printerr ("Failed to create signal pipe: %s\n",
- g_strerror (errno));
-
- channel = g_io_channel_unix_new (signal_pipe_fds[0]);
- g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
- g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_signal, NULL);
- g_io_channel_set_close_on_unref (channel, TRUE);
- g_io_channel_unref (channel);
-
- act.sa_handler = &signal_handler;
- if (sigaction (SIGTERM, &act, NULL) < 0)
- g_printerr ("Failed to register SIGTERM handler: %s\n",
- g_strerror (errno));
+ g_unix_signal_add (SIGTERM, on_sigterm, NULL);
if (g_getenv ("MUTTER_VERBOSE"))
meta_set_verbose (TRUE);
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index 40fc88a..1676e4f 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -28,6 +28,7 @@
#include <cairo.h>
#include "window-private.h"
+#include "meta-weston-launch.h"
#include <meta/meta-cursor-tracker.h>
typedef struct _MetaWaylandCompositor MetaWaylandCompositor;
@@ -148,6 +149,9 @@ struct _MetaWaylandCompositor
struct wl_client *xwayland_client;
struct wl_resource *xserver_resource;
+ MetaLauncher *launcher;
+ int drm_fd;
+
MetaWaylandSeat *seat;
/* This surface is only used to keep drag of the implicit grab when
@@ -338,6 +342,8 @@ void meta_wayland_compositor_repick (MetaWaylandComp
void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
MetaWindow *window);
+MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor);
+
void meta_wayland_surface_free (MetaWaylandSurface *surface);
#endif /* META_WAYLAND_PRIVATE_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 5908ed6..4ebd4d2 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -50,6 +50,7 @@
#include <meta/main.h>
#include "frame.h"
#include "meta-idle-monitor-private.h"
+#include "meta-weston-launch.h"
#include "monitor-private.h"
static MetaWaylandCompositor _meta_wayland_compositor;
@@ -1529,6 +1530,9 @@ meta_wayland_init (void)
MetaWaylandCompositor *compositor = &_meta_wayland_compositor;
guint event_signal;
MetaMonitorManager *monitors;
+ ClutterBackend *backend;
+ CoglContext *cogl_context;
+ CoglRenderer *cogl_renderer;
memset (compositor, 0, sizeof (MetaWaylandCompositor));
@@ -1565,9 +1569,35 @@ meta_wayland_init (void)
clutter_wayland_set_compositor_display (compositor->wayland_display);
+ if (getenv ("WESTON_LAUNCHER_SOCK"))
+ compositor->launcher = meta_launcher_new ();
+
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
g_error ("Failed to initialize Clutter");
+ backend = clutter_get_default_backend ();
+ cogl_context = clutter_backend_get_cogl_context (backend);
+ cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context));
+
+ if (cogl_renderer_get_winsys_id (cogl_renderer) == COGL_WINSYS_ID_EGL_KMS)
+ compositor->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
+ else
+ compositor->drm_fd = -1;
+
+ if (compositor->drm_fd >= 0)
+ {
+ GError *error;
+
+ meta_launcher_set_drm_fd (compositor->launcher, compositor->drm_fd);
+
+ error = NULL;
+ if (!meta_launcher_set_master (compositor->launcher, TRUE, &error))
+ {
+ g_error ("Failed to become DRM master: %s", error->message);
+ g_error_free (error);
+ }
+ }
+
meta_monitor_manager_initialize ();
monitors = meta_monitor_manager_get ();
g_signal_connect (monitors, "monitors-changed",
@@ -1630,5 +1660,16 @@ meta_wayland_init (void)
void
meta_wayland_finalize (void)
{
- meta_xwayland_stop (meta_wayland_compositor_get_default ());
+ MetaWaylandCompositor *compositor;
+
+ compositor = meta_wayland_compositor_get_default ();
+
+ meta_xwayland_stop (compositor);
+ g_clear_object (&compositor->launcher);
+}
+
+MetaLauncher *
+meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor)
+{
+ return compositor->launcher;
}
diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c
new file mode 100644
index 0000000..ea9461e
--- /dev/null
+++ b/src/wayland/meta-weston-launch.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gio/gio.h>
+#include <gio/gunixfdmessage.h>
+
+#include <clutter/clutter.h>
+#include <clutter/evdev/clutter-evdev.h>
+
+#include <glib.h>
+#include <sys/time.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include <drm.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "meta-weston-launch.h"
+
+struct _MetaLauncherClass
+{
+ GObjectClass parent_class;
+
+ void (*enter) (MetaLauncher *);
+ void (*leave) (MetaLauncher *);
+};
+
+struct _MetaLauncher
+{
+ GObject parent;
+
+ GSocket *weston_launch;
+ int drm_fd;
+
+ gboolean vt_switched;
+
+ GMainContext *nested_context;
+ GMainLoop *nested_loop;
+
+ GSource *inner_source;
+ GSource *outer_source;
+};
+
+enum {
+ SIGNAL_ENTER,
+ SIGNAL_LEAVE,
+ SIGNAL_LAST
+};
+
+static int signals[SIGNAL_LAST];
+
+G_DEFINE_TYPE (MetaLauncher, meta_launcher, G_TYPE_OBJECT);
+
+static gboolean
+send_message_to_wl (GSocket *weston_launch,
+ void *message,
+ gsize size,
+ GSocketControlMessage *out_cmsg,
+ GSocketControlMessage **in_cmsg,
+ GError **error)
+{
+ int ok;
+ GInputVector in_iov = { &ok, sizeof (int) };
+ GOutputVector out_iov = { message, size };
+ GSocketControlMessage *out_all_cmsg[2];
+ GSocketControlMessage **in_all_cmsg;
+ int flags = 0;
+ int i;
+
+ out_all_cmsg[0] = out_cmsg;
+ out_all_cmsg[1] = NULL;
+ if (g_socket_send_message (weston_launch, NULL,
+ &out_iov, 1,
+ out_all_cmsg, -1,
+ flags, NULL, error) != (gssize)size)
+ return FALSE;
+
+ if (g_socket_receive_message (weston_launch, NULL,
+ &in_iov, 1,
+ &in_all_cmsg, NULL,
+ &flags, NULL, error) != sizeof (int))
+ return FALSE;
+
+ if (ok != 0)
+ {
+ if (ok == -1)
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Got failure from weston-launch");
+ else
+ 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 && in_all_cmsg[i]; i++)
+ g_object_unref (in_all_cmsg[i]);
+ g_free (in_all_cmsg);
+
+ return FALSE;
+ }
+
+ if (in_all_cmsg && in_all_cmsg[0])
+ {
+ for (i = 1; in_all_cmsg[i]; i++)
+ g_object_unref (in_all_cmsg[i]);
+ *in_cmsg = in_all_cmsg[0];
+ }
+
+ g_free (in_all_cmsg);
+ return TRUE;
+}
+
+gboolean
+meta_launcher_set_master (MetaLauncher *self,
+ gboolean master,
+ GError **error)
+{
+ struct weston_launcher_set_master message;
+ GSocketControlMessage *cmsg;
+ gboolean ok;
+
+ message.header.opcode = WESTON_LAUNCHER_DRM_SET_MASTER;
+ message.set_master = master;
+
+ cmsg = g_unix_fd_message_new ();
+ if (g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (cmsg),
+ self->drm_fd, error) == FALSE)
+ {
+ g_object_unref (cmsg);
+ return FALSE;
+ }
+
+ ok = send_message_to_wl (self->weston_launch, &message,
+ sizeof message, cmsg, NULL, error);
+
+ g_object_unref (cmsg);
+ return ok;
+}
+
+int
+meta_launcher_open_input_device (MetaLauncher *self,
+ const char *name,
+ int flags,
+ GError **error)
+{
+ struct weston_launcher_open *message;
+ GSocketControlMessage *cmsg;
+ gboolean ok;
+ gsize size;
+ int *fds, n_fd;
+ int ret;
+
+ 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 (self->weston_launch, message, size,
+ NULL, &cmsg, error);
+
+ if (ok)
+ {
+ g_assert (G_IS_UNIX_FD_MESSAGE (cmsg));
+
+ fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (cmsg), &n_fd);
+ g_assert (n_fd == 1);
+
+ ret = fds[0];
+ g_free (fds);
+ g_object_unref (cmsg);
+ }
+ else
+ ret = -1;
+
+ g_free (message);
+ return ret;
+}
+
+static void
+meta_launcher_finalize (GObject *object)
+{
+ MetaLauncher *launcher = META_LAUNCHER (object);
+
+ g_source_destroy (launcher->outer_source);
+ g_source_destroy (launcher->inner_source);
+
+ g_main_loop_unref (launcher->nested_loop);
+ g_main_context_unref (launcher->nested_context);
+
+ g_object_unref (launcher->weston_launch);
+
+ G_OBJECT_CLASS (meta_launcher_parent_class)->finalize (object);
+}
+
+static void
+meta_launcher_enter (MetaLauncher *launcher)
+{
+ GError *error;
+
+ error = NULL;
+ if (!meta_launcher_set_master (launcher, TRUE, &error))
+ {
+ g_critical ("Failed to become DRM master: %s", error->message);
+ g_error_free (error);
+ }
+
+ clutter_evdev_reclaim_devices ();
+}
+
+static void
+meta_launcher_leave (MetaLauncher *launcher)
+{
+ GError *error;
+
+ error = NULL;
+ if (!meta_launcher_set_master (launcher, FALSE, &error))
+ {
+ g_critical ("Failed to release DRM master: %s", error->message);
+ g_error_free (error);
+ }
+
+ clutter_evdev_release_devices ();
+}
+
+
+static int
+on_evdev_device_open (const char *path,
+ int flags,
+ gpointer user_data,
+ GError **error)
+{
+ MetaLauncher *launcher = user_data;
+
+ return meta_launcher_open_input_device (launcher, path, flags, error);
+}
+
+static void
+handle_vt_enter (MetaLauncher *launcher)
+{
+ g_assert (launcher->vt_switched);
+
+ g_main_loop_quit (launcher->nested_loop);
+}
+
+static void
+handle_request_vt_switch (MetaLauncher *launcher)
+{
+ struct weston_launcher_message message;
+ GError *error;
+ gboolean ok;
+
+ g_signal_emit (launcher, signals[SIGNAL_LEAVE], 0);
+
+ message.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
+
+ error = NULL;
+ ok = send_message_to_wl (launcher->weston_launch, &message,
+ sizeof (message), NULL, NULL, &error);
+ if (!ok) {
+ g_warning ("Failed to acknowledge VT switch: %s", error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ g_assert (!launcher->vt_switched);
+ launcher->vt_switched = TRUE;
+
+ /* 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 (launcher->nested_loop);
+
+ g_assert (launcher->vt_switched);
+ launcher->vt_switched = FALSE;
+
+ g_signal_emit (launcher, signals[SIGNAL_ENTER], 0);
+}
+
+static void
+on_socket_readable (GSocket *socket,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ MetaLauncher *launcher = user_data;
+ struct weston_launcher_message header;
+ gssize read;
+ GError *error;
+
+ if ((condition & G_IO_IN) == 0)
+ return;
+
+ error = NULL;
+ read = g_socket_receive (socket, (char*)&header, sizeof(header), NULL, &error);
+ if (read < (gssize)sizeof(header))
+ {
+ g_warning ("Error reading from weston-launcher socket: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ switch (header.opcode)
+ {
+ case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
+ handle_request_vt_switch (launcher);
+ break;
+
+ case WESTON_LAUNCHER_SERVER_VT_ENTER:
+ handle_vt_enter (launcher);
+ break;
+ }
+}
+
+static int
+env_get_fd (const char *env)
+{
+ const char *value;
+
+ value = g_getenv (env);
+
+ if (value == NULL)
+ return -1;
+ else
+ return g_ascii_strtoll (value, NULL, 10);
+}
+
+static void
+meta_launcher_init (MetaLauncher *self)
+{
+ int launch_fd;
+
+ launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK");
+ if (launch_fd < 0)
+ g_error ("Invalid mutter-launch socket");
+
+ self->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
+
+ clutter_evdev_set_open_callback (on_evdev_device_open, self);
+
+ self->nested_context = g_main_context_new ();
+ self->nested_loop = g_main_loop_new (self->nested_context, FALSE);
+
+ self->outer_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
+ g_source_set_callback (self->outer_source, (GSourceFunc)on_socket_readable, self, NULL);
+ g_source_attach (self->outer_source, NULL);
+ g_source_unref (self->outer_source);
+
+ self->inner_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
+ g_source_set_callback (self->inner_source, (GSourceFunc)on_socket_readable, self, NULL);
+ g_source_attach (self->inner_source, self->nested_context);
+ g_source_unref (self->inner_source);
+}
+
+static void
+meta_launcher_class_init (MetaLauncherClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meta_launcher_finalize;
+
+ klass->enter = meta_launcher_enter;
+ klass->leave = meta_launcher_leave;
+
+ signals[SIGNAL_ENTER] = g_signal_new ("enter",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (MetaLauncherClass, enter),
+ NULL, NULL, /* accumulator */
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SIGNAL_LEAVE] = g_signal_new ("leave",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (MetaLauncherClass, leave),
+ NULL, NULL, /* accumulator */
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+MetaLauncher *
+meta_launcher_new (void)
+{
+ return g_object_new (META_TYPE_LAUNCHER, NULL);
+}
+
+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->weston_launch, &message,
+ sizeof (message), NULL, NULL, error);
+}
+
+void
+meta_launcher_set_drm_fd (MetaLauncher *launcher,
+ int drm_fd)
+{
+ launcher->drm_fd = drm_fd;
+}
diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-weston-launch.h
new file mode 100644
index 0000000..ccb08f3
--- /dev/null
+++ b/src/wayland/meta-weston-launch.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_WESTON_LAUNCH_H
+#define META_WESTON_LAUNCH_H
+
+#include <glib-object.h>
+#include "weston-launch.h"
+
+#define META_TYPE_LAUNCHER (meta_launcher_get_type())
+#define META_LAUNCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_LAUNCHER,
MetaLauncher))
+#define META_LAUNCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_LAUNCHER,
MetaLauncherClass))
+#define META_IS_LAUNCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_LAUNCHER))
+#define META_IS_LAUNCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_LAUNCHER))
+#define META_LAUNCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_LAUNCHER, MetaLauncherClass))
+
+typedef struct _MetaLauncher MetaLauncher;
+typedef struct _MetaLauncherClass MetaLauncherClass;
+
+GType meta_launcher_get_type (void) G_GNUC_CONST;
+
+MetaLauncher *meta_launcher_new (void);
+
+gboolean meta_launcher_activate_vt (MetaLauncher *self,
+ int number,
+ GError **error);
+
+void meta_launcher_set_drm_fd (MetaLauncher *self,
+ int drm_fd);
+gboolean meta_launcher_set_master (MetaLauncher *self,
+ gboolean master,
+ GError **error);
+int meta_launcher_open_input_device (MetaLauncher *self,
+ const char *name,
+ int flags,
+ GError **error);
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]