4 * An OpenGL based 'interactive canvas' library.
7 * Matthew Allum <mallum@openedhand.com>
8 * Emmanuele Bassi <ebassi@linux.intel.com>
10 * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
11 * Copyright (C) 2009, 2010 Intel Corp
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
28 * SECTION:clutter-backend
29 * @short_description: Backend abstraction
31 * Clutter can be compiled against different backends. Each backend
32 * has to implement a set of functions, in order to be used by Clutter.
34 * #ClutterBackend is the base class abstracting the various implementation;
35 * it provides a basic API to query the backend for generic information
38 * #ClutterBackend is available since Clutter 0.4
45 #define CLUTTER_ENABLE_EXPERIMENTAL_API
47 #include "clutter-backend-private.h"
48 #include "clutter-debug.h"
49 #include "clutter-event-private.h"
50 #include "clutter-marshal.h"
51 #include "clutter-private.h"
52 #include "clutter-profile.h"
53 #include "clutter-stage-manager-private.h"
54 #include "clutter-stage-private.h"
55 #include "clutter-stage-window.h"
56 #include "clutter-version.h"
58 #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
59 #include "wayland/clutter-wayland-compositor.h"
60 #endif /* HAVE_CLUTTER_WAYLAND_COMPOSITOR */
62 #include <cogl/cogl.h>
64 #ifdef CLUTTER_INPUT_X11
65 #include "x11/clutter-backend-x11.h"
67 #ifdef CLUTTER_INPUT_WIN32
68 #include "win32/clutter-backend-win32.h"
70 #ifdef CLUTTER_INPUT_OSX
71 #include "osx/clutter-backend-osx.h"
73 #ifdef CLUTTER_INPUT_GDK
74 #include "gdk/clutter-backend-gdk.h"
76 #ifdef CLUTTER_INPUT_EVDEV
77 #include "evdev/clutter-device-manager-evdev.h"
79 #ifdef CLUTTER_INPUT_TSLIB
80 /* XXX - should probably warn, here */
81 #include "tslib/clutter-event-tslib.h"
83 #ifdef CLUTTER_INPUT_WAYLAND
84 #include "wayland/clutter-device-manager-wayland.h"
87 #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
88 #include <cogl/cogl-wayland-server.h>
89 #include <wayland-server.h>
90 #include "wayland/clutter-wayland-compositor.h"
93 G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
95 #define DEFAULT_FONT_NAME "Sans 10"
97 #define CLUTTER_BACKEND_GET_PRIVATE(obj) \
98 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendPrivate))
100 struct _ClutterBackendPrivate
102 cairo_font_options_t *font_options;
109 GList *event_translators;
121 static guint backend_signals[LAST_SIGNAL] = { 0, };
123 /* Global for being able to specify a compositor side wayland display
124 * pointer before clutter initialization */
125 #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
126 static struct wl_display *_wayland_compositor_display;
131 clutter_backend_dispose (GObject *gobject)
133 ClutterBackendPrivate *priv = CLUTTER_BACKEND (gobject)->priv;
135 /* clear the events still in the queue of the main context */
136 _clutter_clear_events_queue ();
138 /* remove all event translators */
139 if (priv->event_translators != NULL)
141 g_list_free (priv->event_translators);
142 priv->event_translators = NULL;
145 G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
149 clutter_backend_finalize (GObject *gobject)
151 ClutterBackend *backend = CLUTTER_BACKEND (gobject);
153 g_source_destroy (backend->cogl_source);
155 g_free (backend->priv->font_name);
156 clutter_backend_set_font_options (backend, NULL);
158 G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject);
162 get_units_per_em (ClutterBackend *backend,
163 PangoFontDescription *font_desc)
165 gfloat units_per_em = -1.0;
166 gboolean free_font_desc = FALSE;
169 dpi = clutter_backend_get_resolution (backend);
171 if (font_desc == NULL)
173 ClutterSettings *settings;
174 gchar *font_name = NULL;
176 settings = clutter_settings_get_default ();
177 g_object_get (settings, "font-name", &font_name, NULL);
179 if (G_LIKELY (font_name != NULL && *font_name != '\0'))
181 font_desc = pango_font_description_from_string (font_name);
182 free_font_desc = TRUE;
188 if (font_desc != NULL)
190 gdouble font_size = 0;
192 gboolean is_absolute;
194 pango_size = pango_font_description_get_size (font_desc);
195 is_absolute = pango_font_description_get_size_is_absolute (font_desc);
197 /* "absolute" means "device units" (usually, pixels); otherwise,
198 * it means logical units (points)
201 font_size = (gdouble) pango_size / PANGO_SCALE;
203 font_size = dpi * ((gdouble) pango_size / PANGO_SCALE) / 72.0f;
205 /* 10 points at 96 DPI is 13.3 pixels */
206 units_per_em = (1.2f * font_size) * dpi / 96.0f;
209 units_per_em = -1.0f;
212 pango_font_description_free (font_desc);
218 clutter_backend_real_resolution_changed (ClutterBackend *backend)
220 ClutterBackendPrivate *priv = backend->priv;
221 ClutterMainContext *context;
222 ClutterSettings *settings;
226 settings = clutter_settings_get_default ();
227 g_object_get (settings, "font-dpi", &dpi, NULL);
232 resolution = dpi / 1024.0;
234 context = _clutter_context_get_default ();
235 if (context->font_map != NULL)
236 cogl_pango_font_map_set_resolution (context->font_map, resolution);
238 priv->units_per_em = get_units_per_em (backend, NULL);
239 priv->units_serial += 1;
241 CLUTTER_NOTE (BACKEND, "Units per em: %.2f", priv->units_per_em);
245 clutter_backend_real_font_changed (ClutterBackend *backend)
247 ClutterBackendPrivate *priv = backend->priv;
249 priv->units_per_em = get_units_per_em (backend, NULL);
250 priv->units_serial += 1;
252 CLUTTER_NOTE (BACKEND, "Units per em: %.2f", priv->units_per_em);
256 clutter_backend_real_create_context (ClutterBackend *backend,
259 ClutterBackendClass *klass;
260 CoglSwapChain *swap_chain;
261 GError *internal_error;
263 if (backend->cogl_context != NULL)
266 klass = CLUTTER_BACKEND_GET_CLASS (backend);
269 internal_error = NULL;
271 CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
272 if (klass->get_renderer != NULL)
273 backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
275 backend->cogl_renderer = cogl_renderer_new ();
277 if (backend->cogl_renderer == NULL)
280 #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
281 /* If the application is trying to act as a Wayland compositor then
282 it needs to have an EGL-based renderer backend */
283 if (_wayland_compositor_display)
284 cogl_renderer_add_constraint (backend->cogl_renderer,
285 COGL_RENDERER_CONSTRAINT_USES_EGL);
288 CLUTTER_NOTE (BACKEND, "Connecting the renderer");
289 if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
292 CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain");
293 swap_chain = cogl_swap_chain_new ();
295 CLUTTER_NOTE (BACKEND, "Creating Cogl display");
296 if (klass->get_display != NULL)
298 backend->cogl_display = klass->get_display (backend,
299 backend->cogl_renderer,
305 CoglOnscreenTemplate *tmpl;
308 tmpl = cogl_onscreen_template_new (swap_chain);
310 /* XXX: I have some doubts that this is a good design.
312 * Conceptually should we be able to check an onscreen_template
313 * without more details about the CoglDisplay configuration?
315 res = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
322 backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl);
324 /* the display owns the template */
325 cogl_object_unref (tmpl);
328 if (backend->cogl_display == NULL)
331 #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
332 cogl_wayland_display_set_compositor_display (backend->cogl_display,
333 _wayland_compositor_display);
336 CLUTTER_NOTE (BACKEND, "Setting up the display");
337 if (!cogl_display_setup (backend->cogl_display, &internal_error))
340 CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
341 backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error);
342 if (backend->cogl_context == NULL)
345 backend->cogl_source = cogl_glib_source_new (backend->cogl_context,
347 g_source_attach (backend->cogl_source, NULL);
349 /* the display owns the renderer and the swap chain */
350 cogl_object_unref (backend->cogl_renderer);
351 cogl_object_unref (swap_chain);
356 if (backend->cogl_display != NULL)
358 cogl_object_unref (backend->cogl_display);
359 backend->cogl_display = NULL;
362 if (backend->cogl_renderer != NULL)
364 cogl_object_unref (backend->cogl_renderer);
365 backend->cogl_renderer = NULL;
368 if (swap_chain != NULL)
369 cogl_object_unref (swap_chain);
371 if (internal_error != NULL)
372 g_propagate_error (error, internal_error);
374 g_set_error_literal (error, CLUTTER_INIT_ERROR,
375 CLUTTER_INIT_ERROR_BACKEND,
376 _("Unable to initialize the Clutter backend"));
382 clutter_backend_real_ensure_context (ClutterBackend *backend,
385 ClutterStageWindow *stage_impl;
386 CoglFramebuffer *framebuffer;
391 stage_impl = _clutter_stage_get_window (stage);
392 if (stage_impl == NULL)
395 framebuffer = _clutter_stage_window_get_active_framebuffer (stage_impl);
396 if (framebuffer == NULL)
399 cogl_set_framebuffer (framebuffer);
402 static ClutterFeatureFlags
403 clutter_backend_real_get_features (ClutterBackend *backend)
405 ClutterFeatureFlags flags = 0;
407 if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
409 CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
410 flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
414 CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
415 flags |= CLUTTER_FEATURE_STAGE_STATIC;
418 if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
420 CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
421 flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
424 CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
426 if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
428 CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
429 flags |= CLUTTER_FEATURE_SWAP_EVENTS;
435 static ClutterStageWindow *
436 clutter_backend_real_create_stage (ClutterBackend *backend,
437 ClutterStage *wrapper,
440 ClutterBackendClass *klass;
442 if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
444 ClutterStageManager *manager = clutter_stage_manager_get_default ();
446 if (clutter_stage_manager_get_default_stage (manager) != NULL)
448 g_set_error (error, CLUTTER_INIT_ERROR,
449 CLUTTER_INIT_ERROR_BACKEND,
450 _("The backend of type '%s' does not support "
451 "creating multiple stages"),
452 G_OBJECT_TYPE_NAME (backend));
457 klass = CLUTTER_BACKEND_GET_CLASS (backend);
458 g_assert (klass->stage_window_type != G_TYPE_INVALID);
460 return g_object_new (klass->stage_window_type,
467 clutter_backend_real_init_events (ClutterBackend *backend)
469 const char *input_backend = NULL;
471 input_backend = g_getenv ("CLUTTER_INPUT_BACKEND");
472 if (input_backend != NULL)
473 input_backend = g_intern_string (input_backend);
475 #ifdef CLUTTER_INPUT_OSX
476 if (clutter_check_windowing_backend (CLUTTER_WINDOWING_OSX) &&
477 (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_OSX)))
479 _clutter_backend_osx_events_init (backend);
483 #ifdef CLUTTER_INPUT_WIN32
484 if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WIN32) &&
485 (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_WIN32)))
487 _clutter_backend_win32_events_init (backend);
491 #ifdef CLUTTER_INPUT_X11
492 if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) &&
493 (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_X11)))
495 _clutter_backend_x11_events_init (backend);
499 #ifdef CLUTTER_INPUT_GDK
500 if (clutter_check_windowing_backend (CLUTTER_WINDOWING_GDK) &&
501 (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_GDK)))
503 _clutter_backend_gdk_events_init (backend);
507 #ifdef CLUTTER_INPUT_EVDEV
508 /* Evdev can be used regardless of the windowing system */
509 if (input_backend != NULL &&
510 strcmp (input_backend, CLUTTER_INPUT_EVDEV) == 0)
512 _clutter_events_evdev_init (backend);
516 #ifdef CLUTTER_INPUT_TSLIB
517 /* Tslib can be used regardless of the windowing system */
518 if (input_backend != NULL &&
519 strcmp (input_backend, CLUTTER_INPUT_TSLIB) == 0)
521 _clutter_events_tslib_init (backend);
525 #ifdef CLUTTER_INPUT_WAYLAND
526 if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WAYLAND) &&
527 (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_WAYLAND)))
529 _clutter_events_wayland_init (backend);
533 if (input_backend != NULL)
535 if (input_backend != I_(CLUTTER_INPUT_NULL))
536 g_error ("Unrecognized input backend '%s'", input_backend);
539 g_error ("Unknown input backend");
542 static ClutterDeviceManager *
543 clutter_backend_real_get_device_manager (ClutterBackend *backend)
545 if (G_UNLIKELY (backend->device_manager == NULL))
547 g_critical ("No device manager available, expect broken input");
551 return backend->device_manager;
555 clutter_backend_real_translate_event (ClutterBackend *backend,
559 ClutterBackendPrivate *priv = backend->priv;
562 for (l = priv->event_translators;
566 ClutterEventTranslator *translator = l->data;
567 ClutterTranslateReturn retval;
569 retval = _clutter_event_translator_translate_event (translator,
573 if (retval == CLUTTER_TRANSLATE_QUEUE)
576 if (retval == CLUTTER_TRANSLATE_REMOVE)
584 clutter_backend_class_init (ClutterBackendClass *klass)
586 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
588 gobject_class->dispose = clutter_backend_dispose;
589 gobject_class->finalize = clutter_backend_finalize;
591 g_type_class_add_private (gobject_class, sizeof (ClutterBackendPrivate));
593 klass->stage_window_type = G_TYPE_INVALID;
596 * ClutterBackend::resolution-changed:
597 * @backend: the #ClutterBackend that emitted the signal
599 * The ::resolution-changed signal is emitted each time the font
600 * resolutions has been changed through #ClutterSettings.
604 backend_signals[RESOLUTION_CHANGED] =
605 g_signal_new (I_("resolution-changed"),
606 G_TYPE_FROM_CLASS (klass),
608 G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed),
610 _clutter_marshal_VOID__VOID,
614 * ClutterBackend::font-changed:
615 * @backend: the #ClutterBackend that emitted the signal
617 * The ::font-changed signal is emitted each time the font options
618 * have been changed through #ClutterSettings.
622 backend_signals[FONT_CHANGED] =
623 g_signal_new (I_("font-changed"),
624 G_TYPE_FROM_CLASS (klass),
626 G_STRUCT_OFFSET (ClutterBackendClass, font_changed),
628 _clutter_marshal_VOID__VOID,
632 * ClutterBackend::settings-changed:
633 * @backend: the #ClutterBackend that emitted the signal
635 * The ::settings-changed signal is emitted each time the #ClutterSettings
636 * properties have been changed.
640 backend_signals[SETTINGS_CHANGED] =
641 g_signal_new (I_("settings-changed"),
642 G_TYPE_FROM_CLASS (klass),
644 G_STRUCT_OFFSET (ClutterBackendClass, settings_changed),
646 _clutter_marshal_VOID__VOID,
649 klass->resolution_changed = clutter_backend_real_resolution_changed;
650 klass->font_changed = clutter_backend_real_font_changed;
652 klass->init_events = clutter_backend_real_init_events;
653 klass->get_device_manager = clutter_backend_real_get_device_manager;
654 klass->translate_event = clutter_backend_real_translate_event;
655 klass->create_context = clutter_backend_real_create_context;
656 klass->ensure_context = clutter_backend_real_ensure_context;
657 klass->get_features = clutter_backend_real_get_features;
658 klass->create_stage = clutter_backend_real_create_stage;
662 clutter_backend_init (ClutterBackend *backend)
664 ClutterBackendPrivate *priv;
666 priv = backend->priv = CLUTTER_BACKEND_GET_PRIVATE (backend);
668 priv->units_per_em = -1.0;
669 priv->units_serial = 1;
673 _clutter_backend_add_options (ClutterBackend *backend,
676 ClutterBackendClass *klass;
678 g_assert (CLUTTER_IS_BACKEND (backend));
680 klass = CLUTTER_BACKEND_GET_CLASS (backend);
681 if (klass->add_options)
682 klass->add_options (backend, group);
686 _clutter_backend_pre_parse (ClutterBackend *backend,
689 ClutterBackendClass *klass;
691 g_assert (CLUTTER_IS_BACKEND (backend));
693 klass = CLUTTER_BACKEND_GET_CLASS (backend);
694 if (klass->pre_parse)
695 return klass->pre_parse (backend, error);
701 _clutter_backend_post_parse (ClutterBackend *backend,
704 ClutterBackendClass *klass;
706 g_assert (CLUTTER_IS_BACKEND (backend));
708 klass = CLUTTER_BACKEND_GET_CLASS (backend);
709 if (klass->post_parse)
710 return klass->post_parse (backend, error);
716 _clutter_backend_create_stage (ClutterBackend *backend,
717 ClutterStage *wrapper,
720 ClutterBackendClass *klass;
721 ClutterStageWindow *stage_window;
723 g_assert (CLUTTER_IS_BACKEND (backend));
724 g_assert (CLUTTER_IS_STAGE (wrapper));
726 klass = CLUTTER_BACKEND_GET_CLASS (backend);
727 if (klass->create_stage != NULL)
728 stage_window = klass->create_stage (backend, wrapper, error);
732 if (stage_window == NULL)
735 g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window));
741 _clutter_backend_create_context (ClutterBackend *backend,
744 ClutterBackendClass *klass;
746 klass = CLUTTER_BACKEND_GET_CLASS (backend);
748 return klass->create_context (backend, error);
752 _clutter_backend_ensure_context_internal (ClutterBackend *backend,
755 ClutterBackendClass *klass = CLUTTER_BACKEND_GET_CLASS (backend);
756 if (G_LIKELY (klass->ensure_context))
757 klass->ensure_context (backend, stage);
761 _clutter_backend_ensure_context (ClutterBackend *backend,
764 static ClutterStage *current_context_stage = NULL;
766 g_assert (CLUTTER_IS_BACKEND (backend));
767 g_assert (CLUTTER_IS_STAGE (stage));
769 if (current_context_stage != stage || !CLUTTER_ACTOR_IS_REALIZED (stage))
771 ClutterStage *new_stage = NULL;
773 if (!CLUTTER_ACTOR_IS_REALIZED (stage))
777 CLUTTER_NOTE (BACKEND,
778 "Stage [%p] is not realized, unsetting the stage",
785 CLUTTER_NOTE (BACKEND,
786 "Setting the new stage [%p]",
790 /* XXX: Until Cogl becomes fully responsible for backend windows
791 * Clutter need to manually keep it informed of the current window size
793 * NB: This must be done after we ensure_context above because Cogl
794 * always assumes there is a current GL context.
796 if (new_stage != NULL)
800 _clutter_backend_ensure_context_internal (backend, new_stage);
802 clutter_actor_get_size (CLUTTER_ACTOR (stage), &width, &height);
804 cogl_onscreen_clutter_backend_set_size (width, height);
806 /* Eventually we will have a separate CoglFramebuffer for
807 * each stage and each one will track private projection
808 * matrix and viewport state, but until then we need to make
809 * sure we update the projection and viewport whenever we
810 * switch between stages.
812 * This dirty mechanism will ensure they are asserted before
815 _clutter_stage_dirty_viewport (stage);
816 _clutter_stage_dirty_projection (stage);
819 /* FIXME: With a NULL stage and thus no active context it may make more
820 * sense to clean the context but then re call with the default stage
821 * so at least there is some kind of context in place (as to avoid
822 * potential issue of GL calls with no context).
824 current_context_stage = new_stage;
827 CLUTTER_NOTE (BACKEND, "Stage is the same");
832 _clutter_backend_get_features (ClutterBackend *backend)
834 ClutterBackendClass *klass;
837 g_assert (CLUTTER_IS_BACKEND (backend));
839 klass = CLUTTER_BACKEND_GET_CLASS (backend);
841 /* we need to have a context here; so we create the
842 * GL context first and the ask for features. if the
843 * context already exists this should be a no-op
846 if (klass->create_context != NULL)
850 res = klass->create_context (backend, &error);
855 g_critical ("Unable to create a context: %s", error->message);
856 g_error_free (error);
859 g_critical ("Unable to create a context: unknown error");
865 if (klass->get_features)
866 return klass->get_features (backend);
872 _clutter_backend_init_events (ClutterBackend *backend)
874 ClutterBackendClass *klass;
876 g_assert (CLUTTER_IS_BACKEND (backend));
878 klass = CLUTTER_BACKEND_GET_CLASS (backend);
879 klass->init_events (backend);
883 _clutter_backend_get_units_per_em (ClutterBackend *backend,
884 PangoFontDescription *font_desc)
886 ClutterBackendPrivate *priv;
888 priv = backend->priv;
890 /* recompute for the font description, but do not cache the result */
891 if (font_desc != NULL)
892 return get_units_per_em (backend, font_desc);
894 if (priv->units_per_em < 0)
895 priv->units_per_em = get_units_per_em (backend, NULL);
897 return priv->units_per_em;
901 _clutter_backend_copy_event_data (ClutterBackend *backend,
902 const ClutterEvent *src,
905 ClutterBackendClass *klass;
907 klass = CLUTTER_BACKEND_GET_CLASS (backend);
908 if (klass->copy_event_data != NULL)
909 klass->copy_event_data (backend, src, dest);
913 _clutter_backend_free_event_data (ClutterBackend *backend,
916 ClutterBackendClass *klass;
918 klass = CLUTTER_BACKEND_GET_CLASS (backend);
919 if (klass->free_event_data != NULL)
920 klass->free_event_data (backend, event);
924 * clutter_get_default_backend:
926 * Retrieves the default #ClutterBackend used by Clutter. The
927 * #ClutterBackend holds backend-specific configuration options.
929 * Return value: (transfer none): the default backend. You should
930 * not ref or unref the returned object. Applications should rarely
936 clutter_get_default_backend (void)
938 ClutterMainContext *clutter_context;
940 clutter_context = _clutter_context_get_default ();
942 return clutter_context->backend;
946 * clutter_backend_set_double_click_time:
947 * @backend: a #ClutterBackend
948 * @msec: milliseconds between two button press events
950 * Sets the maximum time between two button press events, used to
951 * verify whether it's a double click event or not.
955 * Deprecated: 1.4: Use #ClutterSettings:double-click-time instead
958 clutter_backend_set_double_click_time (ClutterBackend *backend,
961 ClutterSettings *settings = clutter_settings_get_default ();
963 g_object_set (settings, "double-click-time", msec, NULL);
967 * clutter_backend_get_double_click_time:
968 * @backend: a #ClutterBackend
970 * Gets the maximum time between two button press events, as set
971 * by clutter_backend_set_double_click_time().
973 * Return value: a time in milliseconds
977 * Deprecated: 1.4: Use #ClutterSettings:double-click-time instead
980 clutter_backend_get_double_click_time (ClutterBackend *backend)
982 ClutterSettings *settings = clutter_settings_get_default ();
985 g_object_get (settings, "double-click-time", &retval, NULL);
991 * clutter_backend_set_double_click_distance:
992 * @backend: a #ClutterBackend
993 * @distance: a distance, in pixels
995 * Sets the maximum distance used to verify a double click event.
999 * Deprecated: 1.4: Use #ClutterSettings:double-click-distance instead
1002 clutter_backend_set_double_click_distance (ClutterBackend *backend,
1005 ClutterSettings *settings = clutter_settings_get_default ();
1007 g_object_set (settings, "double-click-distance", distance, NULL);
1011 * clutter_backend_get_double_click_distance:
1012 * @backend: a #ClutterBackend
1014 * Retrieves the distance used to verify a double click event
1016 * Return value: a distance, in pixels.
1020 * Deprecated: 1.4: Use #ClutterSettings:double-click-distance instead
1023 clutter_backend_get_double_click_distance (ClutterBackend *backend)
1025 ClutterSettings *settings = clutter_settings_get_default ();
1028 g_object_get (settings, "double-click-distance", &retval, NULL);
1034 * clutter_backend_set_resolution:
1035 * @backend: a #ClutterBackend
1036 * @dpi: the resolution in "dots per inch" (Physical inches aren't
1037 * actually involved; the terminology is conventional).
1039 * Sets the resolution for font handling on the screen. This is a
1040 * scale factor between points specified in a #PangoFontDescription
1041 * and cairo units. The default value is 96, meaning that a 10 point
1042 * font will be 13 units high. (10 * 96. / 72. = 13.3).
1044 * Applications should never need to call this function.
1048 * Deprecated: 1.4: Use #ClutterSettings:font-dpi instead
1051 clutter_backend_set_resolution (ClutterBackend *backend,
1054 ClutterSettings *settings;
1057 g_return_if_fail (CLUTTER_IS_BACKEND (backend));
1062 resolution = dpi * 1024;
1064 settings = clutter_settings_get_default ();
1065 g_object_set (settings, "font-dpi", resolution, NULL);
1069 * clutter_backend_get_resolution:
1070 * @backend: a #ClutterBackend
1072 * Gets the resolution for font handling on the screen.
1074 * The resolution is a scale factor between points specified in a
1075 * #PangoFontDescription and cairo units. The default value is 96.0,
1076 * meaning that a 10 point font will be 13 units
1077 * high (10 * 96. / 72. = 13.3).
1079 * Clutter will set the resolution using the current backend when
1080 * initializing; the resolution is also stored in the
1081 * #ClutterSettings:font-dpi property.
1083 * Return value: the current resolution, or -1 if no resolution
1089 clutter_backend_get_resolution (ClutterBackend *backend)
1091 ClutterSettings *settings;
1094 g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), -1.0);
1096 settings = clutter_settings_get_default ();
1097 g_object_get (settings, "font-dpi", &resolution, NULL);
1102 return resolution / 1024.0;
1106 * clutter_backend_set_font_options:
1107 * @backend: a #ClutterBackend
1108 * @options: Cairo font options for the backend, or %NULL
1110 * Sets the new font options for @backend. The #ClutterBackend will
1111 * copy the #cairo_font_options_t.
1113 * If @options is %NULL, the first following call to
1114 * clutter_backend_get_font_options() will return the default font
1115 * options for @backend.
1117 * This function is intended for actors creating a Pango layout
1118 * using the PangoCairo API.
1123 clutter_backend_set_font_options (ClutterBackend *backend,
1124 const cairo_font_options_t *options)
1126 ClutterBackendPrivate *priv;
1128 g_return_if_fail (CLUTTER_IS_BACKEND (backend));
1130 priv = backend->priv;
1132 if (priv->font_options != options)
1134 if (priv->font_options)
1135 cairo_font_options_destroy (priv->font_options);
1138 priv->font_options = cairo_font_options_copy (options);
1140 priv->font_options = NULL;
1142 g_signal_emit (backend, backend_signals[FONT_CHANGED], 0);
1147 * clutter_backend_get_font_options:
1148 * @backend: a #ClutterBackend
1150 * Retrieves the font options for @backend.
1152 * Return value: (transfer none): the font options of the #ClutterBackend.
1153 * The returned #cairo_font_options_t is owned by the backend and should
1154 * not be modified or freed
1158 const cairo_font_options_t *
1159 clutter_backend_get_font_options (ClutterBackend *backend)
1161 ClutterBackendPrivate *priv;
1163 g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
1165 priv = backend->priv;
1167 if (G_LIKELY (priv->font_options))
1168 return priv->font_options;
1170 priv->font_options = cairo_font_options_create ();
1172 cairo_font_options_set_hint_style (priv->font_options,
1173 CAIRO_HINT_STYLE_NONE);
1174 cairo_font_options_set_subpixel_order (priv->font_options,
1175 CAIRO_SUBPIXEL_ORDER_DEFAULT);
1176 cairo_font_options_set_antialias (priv->font_options,
1177 CAIRO_ANTIALIAS_DEFAULT);
1179 g_signal_emit (backend, backend_signals[FONT_CHANGED], 0);
1181 return priv->font_options;
1185 * clutter_backend_set_font_name:
1186 * @backend: a #ClutterBackend
1187 * @font_name: the name of the font
1189 * Sets the default font to be used by Clutter. The @font_name string
1190 * must either be %NULL, which means that the font name from the
1191 * default #ClutterBackend will be used; or be something that can
1192 * be parsed by the pango_font_description_from_string() function.
1196 * Deprecated: 1.4: Use #ClutterSettings:font-name instead
1199 clutter_backend_set_font_name (ClutterBackend *backend,
1200 const gchar *font_name)
1202 ClutterSettings *settings = clutter_settings_get_default ();
1204 g_object_set (settings, "font-name", font_name, NULL);
1208 * clutter_backend_get_font_name:
1209 * @backend: a #ClutterBackend
1211 * Retrieves the default font name as set by
1212 * clutter_backend_set_font_name().
1214 * Return value: the font name for the backend. The returned string is
1215 * owned by the #ClutterBackend and should never be modified or freed
1219 * Deprecated: 1.4: Use #ClutterSettings:font-name instead
1222 clutter_backend_get_font_name (ClutterBackend *backend)
1224 ClutterBackendPrivate *priv;
1225 ClutterSettings *settings;
1227 g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
1229 priv = backend->priv;
1231 settings = clutter_settings_get_default ();
1233 /* XXX yuck. but we return a const pointer, so we need to
1234 * store it in the backend
1236 g_free (priv->font_name);
1237 g_object_get (settings, "font-name", &priv->font_name, NULL);
1239 return priv->font_name;
1243 _clutter_backend_get_units_serial (ClutterBackend *backend)
1245 return backend->priv->units_serial;
1249 _clutter_backend_translate_event (ClutterBackend *backend,
1251 ClutterEvent *event)
1253 return CLUTTER_BACKEND_GET_CLASS (backend)->translate_event (backend,
1259 _clutter_backend_add_event_translator (ClutterBackend *backend,
1260 ClutterEventTranslator *translator)
1262 ClutterBackendPrivate *priv = backend->priv;
1264 if (g_list_find (priv->event_translators, translator) != NULL)
1267 priv->event_translators =
1268 g_list_prepend (priv->event_translators, translator);
1272 _clutter_backend_remove_event_translator (ClutterBackend *backend,
1273 ClutterEventTranslator *translator)
1275 ClutterBackendPrivate *priv = backend->priv;
1277 if (g_list_find (priv->event_translators, translator) == NULL)
1280 priv->event_translators =
1281 g_list_remove (priv->event_translators, translator);
1285 * clutter_backend_get_cogl_context:
1286 * @backend: a #ClutterBackend
1288 * Retrieves the #CoglContext associated with the given clutter
1289 * @backend. A #CoglContext is required when using some of the
1290 * experimental 2.0 Cogl API.
1292 * <note>Since CoglContext is itself experimental API this API should
1293 * be considered experimental too.</note>
1295 * <note>This API is not yet supported on OSX because OSX still
1296 * uses the stub Cogl winsys and the Clutter backend doesn't
1297 * explicitly create a CoglContext.</note>
1299 * Return value: The #CoglContext associated with @backend.
1302 * Stability: unstable
1305 clutter_backend_get_cogl_context (ClutterBackend *backend)
1307 return backend->cogl_context;
1310 #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
1312 * clutter_wayland_set_compositor_display:
1313 * @display: A compositor side struct wl_display pointer
1315 * This informs Clutter of your compositor side Wayland display
1316 * object. This must be called before calling clutter_init().
1319 * Stability: unstable
1322 clutter_wayland_set_compositor_display (struct wl_display *display)
1324 if (_clutter_context_is_initialized ())
1326 g_warning ("%s() can only be used before calling clutter_init()",
1331 _wayland_compositor_display = display;