summaryrefslogtreecommitdiff
path: root/clutter/mir/clutter-backend-mir.c
diff options
context:
space:
mode:
Diffstat (limited to 'clutter/mir/clutter-backend-mir.c')
-rw-r--r--clutter/mir/clutter-backend-mir.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/clutter/mir/clutter-backend-mir.c b/clutter/mir/clutter-backend-mir.c
new file mode 100644
index 000000000..d537483da
--- /dev/null
+++ b/clutter/mir/clutter-backend-mir.c
@@ -0,0 +1,231 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2014 Canonical Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Marco Trevisan <marco.trevisan@canonical.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "clutter-debug.h"
+#include "clutter-main.h"
+#include "clutter-stage-private.h"
+
+#include "mir/clutter-backend-mir-priv.h"
+#include "mir/clutter-backend-mir.h"
+#include "mir/clutter-device-manager-mir.h"
+#include "mir/clutter-event-mir.h"
+#include "mir/clutter-stage-mir.h"
+#include "mir/clutter-mir.h"
+
+#define clutter_backend_mir_get_type _clutter_backend_mir_get_type
+
+G_DEFINE_TYPE (ClutterBackendMir, clutter_backend_mir, CLUTTER_TYPE_BACKEND);
+
+static MirConnection *_foreign_connection = NULL;
+static gboolean _no_event_dispatch = FALSE;
+
+static gboolean
+clutter_backend_mir_post_parse (ClutterBackend *backend,
+ GError **error)
+{
+ ClutterBackendMir *backend_mir = CLUTTER_BACKEND_MIR (backend);
+
+ backend_mir->mir_connection = _foreign_connection;
+ if (backend_mir->mir_connection == NULL)
+ backend_mir->mir_connection = mir_connect_sync (NULL, "Clutter");
+
+ if (!mir_connection_is_valid (backend_mir->mir_connection))
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "Failed to open Mir display socket %s",
+ mir_connection_get_error_message (backend_mir->mir_connection));
+ mir_connection_release (backend_mir->mir_connection);
+ return FALSE;
+ }
+
+ g_object_set (clutter_settings_get_default (), "font-dpi", 96 * 1024, NULL);
+
+ return TRUE;
+}
+
+static CoglRenderer *
+clutter_backend_mir_get_renderer (ClutterBackend *backend,
+ GError **error)
+{
+ ClutterBackendMir *backend_mir = CLUTTER_BACKEND_MIR (backend);
+ CoglRenderer *renderer;
+
+ CLUTTER_NOTE (BACKEND, "Creating a new Mir renderer");
+
+ renderer = cogl_renderer_new ();
+
+ cogl_renderer_set_winsys_id (renderer, COGL_WINSYS_ID_EGL_MIR);
+ cogl_mir_renderer_set_foreign_connection (renderer,
+ backend_mir->mir_connection);
+
+ return renderer;
+}
+
+static CoglDisplay *
+clutter_backend_mir_get_display (ClutterBackend *backend,
+ CoglRenderer *renderer,
+ CoglSwapChain *swap_chain,
+ GError **error)
+{
+ CoglOnscreenTemplate *onscreen_template = NULL;
+ CoglDisplay *display;
+
+ onscreen_template = cogl_onscreen_template_new (swap_chain);
+
+ if (!cogl_renderer_check_onscreen_template (renderer,
+ onscreen_template,
+ error))
+ goto error;
+
+ display = cogl_display_new (renderer, onscreen_template);
+
+ return display;
+
+error:
+ if (onscreen_template)
+ cogl_object_unref (onscreen_template);
+
+ return NULL;
+}
+
+static void
+on_mir_event_cb (CoglMirEvent *mir_event,
+ void *data)
+{
+ ClutterBackend *backend = data;
+ _clutter_mir_handle_event (backend, mir_event->surface, mir_event->event);
+}
+
+void
+_clutter_events_mir_init (ClutterBackend *backend)
+{
+ ClutterBackendMir *backend_mir = CLUTTER_BACKEND_MIR (backend);
+ CoglRenderer *cogl_renderer = backend->cogl_renderer;
+
+ backend->device_manager = _clutter_device_manager_mir_new (backend);
+
+ if (_no_event_dispatch)
+ return;
+
+ cogl_mir_renderer_add_event_listener (cogl_renderer, on_mir_event_cb, backend);
+ backend_mir->mir_source = _clutter_event_source_mir_new ();
+}
+
+
+static void
+clutter_backend_mir_init (ClutterBackendMir *backend_mir)
+{
+}
+
+static void
+clutter_backend_mir_dispose (GObject *gobject)
+{
+ ClutterBackend *backend = CLUTTER_BACKEND (gobject);
+ ClutterBackendMir *backend_mir = CLUTTER_BACKEND_MIR (backend);
+ CoglRenderer *cogl_renderer = backend->cogl_renderer;
+
+ g_clear_object (&backend->device_manager);
+ g_clear_pointer (&backend_mir->mir_source, g_source_unref);
+ cogl_mir_renderer_remove_event_listener (cogl_renderer, on_mir_event_cb,
+ backend);
+
+ G_OBJECT_CLASS (clutter_backend_mir_parent_class)->dispose (gobject);
+}
+
+static void
+clutter_backend_mir_class_init (ClutterBackendMirClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
+
+ gobject_class->dispose = clutter_backend_mir_dispose;
+
+ backend_class->stage_window_type = CLUTTER_TYPE_STAGE_MIR;
+
+ backend_class->post_parse = clutter_backend_mir_post_parse;
+ backend_class->get_renderer = clutter_backend_mir_get_renderer;
+ backend_class->get_display = clutter_backend_mir_get_display;
+}
+
+/**
+ * clutter_mir_set_connection
+ * @connection: pointer to a mir connection
+ *
+ * Sets the display connection Clutter should use; must be called
+ * before clutter_init(), clutter_init_with_args() or other functions
+ * pertaining Clutter's initialization process.
+ *
+ * If you are parsing the command line arguments by retrieving Clutter's
+ * #GOptionGroup with clutter_get_option_group() and calling
+ * g_option_context_parse() yourself, you should also call
+ * clutter_mir_set_connection() before g_option_context_parse().
+ *
+ * Since: 1.22
+ */
+void
+clutter_mir_set_connection (MirConnection *connection)
+{
+ g_return_if_fail (mir_connection_is_valid (connection));
+
+ if (_clutter_context_is_initialized ())
+ {
+ g_warning ("%s() can only be used before calling clutter_init()",
+ G_STRFUNC);
+ return;
+ }
+
+ _foreign_connection = connection;
+}
+
+/**
+ * clutter_mir_disable_event_retrieval:
+ *
+ * Disables the dispatch of the events in the main loop.
+ *
+ * This is useful for integrating Clutter with another library that will do the
+ * event dispatch;
+ *
+ * This function can only be called before calling clutter_init().
+ *
+ * This function should not be normally used by applications.
+ *
+ * Since: 1.22
+ */
+void
+clutter_mir_disable_event_retrieval (void)
+{
+ if (_clutter_context_is_initialized ())
+ {
+ g_warning ("%s() can only be used before calling clutter_init()",
+ G_STRFUNC);
+ return;
+ }
+
+ _no_event_dispatch = TRUE;
+}