Blame clutter-gtk/gtk-clutter-util.c

Packit 1069cd
#include "config.h"
Packit 1069cd
Packit 1069cd
#include "gtk-clutter-util.h"
Packit 1069cd
#include "gtk-clutter-offscreen.h"
Packit 1069cd
#include "gtk-clutter-version.h"
Packit 1069cd
Packit 1069cd
#include <gdk-pixbuf/gdk-pixbuf.h>
Packit 1069cd
#include <gdk/gdk.h>
Packit 1069cd
#include <gtk/gtk.h>
Packit 1069cd
#include <clutter/clutter.h>
Packit 1069cd
Packit 1069cd
#if defined(CLUTTER_WINDOWING_GDK)
Packit 1069cd
#include <clutter/gdk/clutter-gdk.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(CLUTTER_WINDOWING_X11)
Packit 1069cd
#include <clutter/x11/clutter-x11.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(CLUTTER_WINDOWING_WIN32)
Packit 1069cd
#include <clutter/win32/clutter-win32.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(CLUTTER_WINDOWING_WAYLAND)
Packit 1069cd
#include <clutter/wayland/clutter-wayland.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(GDK_WINDOWING_X11)
Packit 1069cd
#include <gdk/gdkx.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(GDK_WINDOWING_WIN32)
Packit 1069cd
#include <gdk/gdkwin32.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(GDK_WINDOWING_WAYLAND)
Packit 1069cd
#include <gdk/gdkwayland.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
#if defined(GDK_WINDOWING_MIR)
Packit 1069cd
#include <gdk/gdkmir.h>
Packit 1069cd
#endif
Packit 1069cd
Packit 1069cd
/**
Packit 1069cd
 * SECTION:gtk-clutter-util
Packit 1069cd
 * @Title: Utility Functions
Packit 1069cd
 * @short_description: Utility functions for integrating Clutter in GTK+
Packit 1069cd
 *
Packit 1069cd
 * In order to properly integrate a Clutter scene into a GTK+ applications
Packit 1069cd
 * a certain degree of state must be retrieved from GTK+ itself.
Packit 1069cd
 *
Packit 1069cd
 * Clutter-GTK provides API for easing the process of synchronizing colors
Packit 1069cd
 * with the current GTK+ theme and for loading image sources from #GdkPixbuf,
Packit 1069cd
 * GTK+ stock items and icon themes.
Packit 1069cd
 */
Packit 1069cd
Packit 1069cd
static const guint clutter_gtk_major_version = CLUTTER_GTK_MAJOR_VERSION;
Packit 1069cd
static const guint clutter_gtk_minor_version = CLUTTER_GTK_MINOR_VERSION;
Packit 1069cd
static const guint clutter_gtk_micro_version = CLUTTER_GTK_MICRO_VERSION;
Packit 1069cd
Packit 1069cd
static gboolean gtk_clutter_is_initialized = FALSE;
Packit 1069cd
Packit 1069cd
static void
Packit 1069cd
gtk_clutter_init_internal (void)
Packit 1069cd
{
Packit 1069cd
  GdkDisplay *display;
Packit 1069cd
Packit 1069cd
  display = gdk_display_get_default ();
Packit 1069cd
Packit 1069cd
#if defined(CLUTTER_WINDOWING_GDK)
Packit 1069cd
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_GDK))
Packit 1069cd
    {
Packit 1069cd
      clutter_gdk_set_display (gdk_display_get_default ());
Packit 1069cd
Packit 1069cd
      /* let GDK be in charge of the event handling */
Packit 1069cd
      clutter_gdk_disable_event_retrieval ();
Packit 1069cd
    }
Packit 1069cd
  else
Packit 1069cd
#endif
Packit 1069cd
#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11)
Packit 1069cd
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) &&
Packit 1069cd
      GDK_IS_X11_DISPLAY (display))
Packit 1069cd
    {
Packit 1069cd
      /* enable ARGB visuals by default for Clutter */
Packit 1069cd
      clutter_x11_set_use_argb_visual (TRUE);
Packit 1069cd
Packit 1069cd
      /* share the X11 Display with GTK+ */
Packit 1069cd
      clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
Packit 1069cd
Packit 1069cd
      /* let GTK+ be in charge of the event handling */
Packit 1069cd
      clutter_x11_disable_event_retrieval ();
Packit 1069cd
    }
Packit 1069cd
  else
Packit 1069cd
#endif
Packit 1069cd
#if defined(GDK_WINDOWING_WIN32) && defined(CLUTTER_WINDOWING_WIN32)
Packit 1069cd
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WIN32) &&
Packit 1069cd
      GDK_IS_WIN32_DISPLAY (display))
Packit 1069cd
    {
Packit 1069cd
      /* let GTK+ be in charge of the event handling */
Packit 1069cd
      clutter_win32_disable_event_retrieval ();
Packit 1069cd
    }
Packit 1069cd
  else
Packit 1069cd
#endif
Packit 1069cd
#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
Packit 1069cd
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WAYLAND) &&
Packit 1069cd
      GDK_IS_WAYLAND_DISPLAY (display))
Packit 1069cd
    {
Packit 1069cd
      /* let GTK+ be in charge of the event handling */
Packit 1069cd
      clutter_wayland_disable_event_retrieval ();
Packit 1069cd
Packit 1069cd
      clutter_wayland_set_display (gdk_wayland_display_get_wl_display (display));
Packit 1069cd
    }
Packit 1069cd
  else
Packit 1069cd
#endif
Packit 1069cd
#if defined(GDK_WINDOWING_MIR) && defined(CLUTTER_WINDOWING_MIR)
Packit 1069cd
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_MIR) &&
Packit 1069cd
      GDK_IS_MIR_DISPLAY (display))
Packit 1069cd
    {
Packit 1069cd
      /* let GTK+ be in charge of the event handling */
Packit 1069cd
      /* This is disabled until Mir does not support sub-surfaces.
Packit 1069cd
      clutter_mir_disable_event_retrieval ();
Packit 1069cd
      */
Packit 1069cd
Packit 1069cd
      clutter_mir_set_connection (gdk_mir_display_get_mir_connection (display));
Packit 1069cd
    }
Packit 1069cd
  else
Packit 1069cd
#endif
Packit 1069cd
    g_error ("*** Unsupported backend.");
Packit 1069cd
Packit 1069cd
  /* We disable clutter accessibility support in order to not
Packit 1069cd
   * interfere with gtk accessibility support.
Packit 1069cd
   */
Packit 1069cd
  clutter_disable_accessibility ();
Packit 1069cd
}
Packit 1069cd
Packit 1069cd
static gboolean
Packit 1069cd
post_parse_hook (GOptionContext  *context,
Packit 1069cd
                 GOptionGroup    *group,
Packit 1069cd
                 gpointer         data,
Packit 1069cd
                 GError         **error)
Packit 1069cd
{
Packit 1069cd
  gtk_clutter_is_initialized = TRUE;
Packit 1069cd
Packit 1069cd
  gtk_clutter_init_internal ();
Packit 1069cd
Packit 1069cd
  /* this is required since parsing clutter's option group did not
Packit 1069cd
   * complete the initialization process
Packit 1069cd
   */
Packit 1069cd
  return clutter_init_with_args (NULL, NULL, NULL, NULL, NULL, error) == CLUTTER_INIT_SUCCESS;
Packit 1069cd
}
Packit 1069cd
Packit 1069cd
/**
Packit 1069cd
 * gtk_clutter_get_option_group: (skip)
Packit 1069cd
 *
Packit 1069cd
 * Returns a #GOptionGroup for the command line arguments recognized
Packit 1069cd
 * by Clutter. You should add this group to your #GOptionContext with
Packit 1069cd
 * g_option_context_add_group(), if you are using g_option_context_parse()
Packit 1069cd
 * to parse your commandline arguments instead of using gtk_clutter_init()
Packit 1069cd
 * or gtk_clutter_init_with_args().
Packit 1069cd
 *
Packit 1069cd
 * You should add this option group to your #GOptionContext after
Packit 1069cd
 * the GTK option group created with gtk_get_option_group(), and after
Packit 1069cd
 * the clutter option group obtained from clutter_get_option_group_without_init().
Packit 1069cd
 * You should not use clutter_get_option_group() together with this function.
Packit 1069cd
 *
Packit 1069cd
 * You must pass %TRUE to gtk_get_option_group() since gtk-clutter's option
Packit 1069cd
 * group relies on it.
Packit 1069cd
 *
Packit 1069cd
 * Parsing options using g_option_context_parse() with a #GOptionContext
Packit 1069cd
 * containing the returned #GOptionGroupwith will result in Clutter's and
Packit 1069cd
 * GTK-Clutter's initialisation.  That is, the following code:
Packit 1069cd
 *
Packit 1069cd
 * |[
Packit 1069cd
 *   g_option_context_add_group (context, gtk_get_option_group (TRUE));
Packit 1069cd
 *   g_option_context_add_group (context, cogl_get_option_group ());
Packit 1069cd
 *   g_option_context_add_group (context, clutter_get_option_group_without_init ());
Packit 1069cd
 *   g_option_context_add_group (context, gtk_clutter_get_option_group ());
Packit 1069cd
 *   res = g_option_context_parse (context, &argc, &argc, NULL);
Packit 1069cd
 * ]|
Packit 1069cd
 *
Packit 1069cd
 * is functionally equivalent to:
Packit 1069cd
 *
Packit 1069cd
 * |[
Packit 1069cd
 *   gtk_clutter_init (&argc, &argv);
Packit 1069cd
 * ]|
Packit 1069cd
 *
Packit 1069cd
 * After g_option_context_parse() on a #GOptionContext containing the
Packit 1069cd
 * the returned #GOptionGroup has returned %TRUE, Clutter and GTK-Clutter are
Packit 1069cd
 * guaranteed to be initialized.
Packit 1069cd
 *
Packit 1069cd
 * Return value: (transfer full): a #GOptionGroup for the commandline arguments
Packit 1069cd
 *   recognized by ClutterGtk
Packit 1069cd
 */
Packit 1069cd
GOptionGroup *
Packit 1069cd
gtk_clutter_get_option_group  (void)
Packit 1069cd
{
Packit 1069cd
  GOptionGroup *group;
Packit 1069cd
Packit 1069cd
  group = g_option_group_new ("clutter-gtk", "", "", NULL, NULL);
Packit 1069cd
  g_option_group_set_parse_hooks (group, NULL, post_parse_hook);
Packit 1069cd
Packit 1069cd
  return group;
Packit 1069cd
}
Packit 1069cd
Packit 1069cd
/**
Packit 1069cd
 * gtk_clutter_init:
Packit 1069cd
 * @argc: (inout) (allow-none): pointer to the arguments count, or %NULL
Packit 1069cd
 * @argv: (array length=argc) (inout) (allow-none): pointer to the
Packit 1069cd
 *   arguments vector, or %NULL
Packit 1069cd
 *
Packit 1069cd
 * This function should be called instead of clutter_init() and
Packit 1069cd
 * gtk_init().
Packit 1069cd
 *
Packit 1069cd
 * Return value: %CLUTTER_INIT_SUCCESS on success, a negative integer
Packit 1069cd
 *   on failure.
Packit 1069cd
 */
Packit 1069cd
ClutterInitError
Packit 1069cd
gtk_clutter_init (int    *argc,
Packit 1069cd
                  char ***argv)
Packit 1069cd
{
Packit 1069cd
  if (gtk_clutter_is_initialized)
Packit 1069cd
    return CLUTTER_INIT_SUCCESS;
Packit 1069cd
Packit 1069cd
  gtk_clutter_is_initialized = TRUE;
Packit 1069cd
Packit 1069cd
  if (!gtk_init_check (argc, argv))
Packit 1069cd
    return CLUTTER_INIT_ERROR_UNKNOWN;
Packit 1069cd
Packit 1069cd
  gtk_clutter_init_internal ();
Packit 1069cd
Packit 1069cd
  return clutter_init (argc, argv);
Packit 1069cd
}
Packit 1069cd
Packit 1069cd
/**
Packit 1069cd
 * gtk_clutter_init_with_args:
Packit 1069cd
 * @argc: (inout) (allow-none): a pointer to the number of command line
Packit 1069cd
 *   arguments, or %NULL
Packit 1069cd
 * @argv: (inout) (allow-none) (array length=argc): a pointer to the array
Packit 1069cd
 *   of command line arguments, or %NULL
Packit 1069cd
 * @parameter_string: (allow-none): a string which is displayed in
Packit 1069cd
 *    the first line of <option>--help</option> output, after
Packit 1069cd
 *    <literal><replaceable>programname</replaceable> [OPTION...]</literal>
Packit 1069cd
 * @entries: (allow-none) (array zero-terminated=1): a
Packit 1069cd
 *    %NULL-terminated array of #GOptionEntrys describing the
Packit 1069cd
 *    options of your program
Packit 1069cd
 * @translation_domain: (allow-none): a translation domain to use for
Packit 1069cd
 *    translating the <option>--help</option> output for the options
Packit 1069cd
 *    in @entries with gettext(), or %NULL
Packit 1069cd
 * @error: (allow-none): a return location for errors, or %NULL
Packit 1069cd
 *
Packit 1069cd
 * This function should be called instead of clutter_init() and
Packit 1069cd
 * gtk_init_with_args().
Packit 1069cd
 *
Packit 1069cd
 * Return value: %CLUTTER_INIT_SUCCESS on success, a negative integer
Packit 1069cd
 *   on failure.
Packit 1069cd
 */
Packit 1069cd
ClutterInitError
Packit 1069cd
gtk_clutter_init_with_args (int            *argc,
Packit 1069cd
                            char         ***argv,
Packit 1069cd
                            const char     *parameter_string,
Packit 1069cd
                            GOptionEntry   *entries,
Packit 1069cd
                            const char     *translation_domain,
Packit 1069cd
                            GError        **error)
Packit 1069cd
{
Packit 1069cd
  GOptionGroup *gtk_group, *clutter_group, *cogl_group, *clutter_gtk_group;
Packit 1069cd
  GOptionContext *context;
Packit 1069cd
  gboolean res;
Packit 1069cd
Packit 1069cd
  if (gtk_clutter_is_initialized)
Packit 1069cd
    return CLUTTER_INIT_SUCCESS;
Packit 1069cd
Packit 1069cd
  /* we let gtk+ open the display */
Packit 1069cd
  gtk_group = gtk_get_option_group (TRUE);
Packit 1069cd
Packit 1069cd
  /* and we prevent clutter from doing so too */
Packit 1069cd
  clutter_group = clutter_get_option_group_without_init ();
Packit 1069cd
Packit 1069cd
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
Packit 1069cd
  cogl_group = cogl_get_option_group ();
Packit 1069cd
  G_GNUC_END_IGNORE_DEPRECATIONS
Packit 1069cd
Packit 1069cd
  clutter_gtk_group = gtk_clutter_get_option_group ();
Packit 1069cd
Packit 1069cd
  context = g_option_context_new (parameter_string);
Packit 1069cd
Packit 1069cd
  g_option_context_add_group (context, gtk_group);
Packit 1069cd
  g_option_context_add_group (context, cogl_group);
Packit 1069cd
  g_option_context_add_group (context, clutter_group);
Packit 1069cd
  g_option_context_add_group (context, clutter_gtk_group);
Packit 1069cd
Packit 1069cd
  if (entries)
Packit 1069cd
    g_option_context_add_main_entries (context, entries, translation_domain);
Packit 1069cd
Packit 1069cd
  res = g_option_context_parse (context, argc, argv, error);
Packit 1069cd
  g_option_context_free (context);
Packit 1069cd
Packit 1069cd
  if (!res)
Packit 1069cd
    return CLUTTER_INIT_ERROR_UNKNOWN;
Packit 1069cd
Packit 1069cd
  return CLUTTER_INIT_SUCCESS;
Packit 1069cd
}
Packit 1069cd
Packit 1069cd
/**
Packit 1069cd
 * gtk_clutter_check_version:
Packit 1069cd
 * @major: the major component of the version,
Packit 1069cd
 *   i.e. 1 if the version is 1.2.3
Packit 1069cd
 * @minor: the minor component of the version,
Packit 1069cd
 *   i.e. 2 if the version is 1.2.3
Packit 1069cd
 * @micro: the micro component of the version,
Packit 1069cd
 *   i.e. 3 if the version is 1.2.3
Packit 1069cd
 *
Packit 1069cd
 * Checks the version of the Clutter-GTK library at run-time.
Packit 1069cd
 *
Packit 1069cd
 * Return value: %TRUE if the version of the library is greater or
Packit 1069cd
 *   equal than the one requested
Packit 1069cd
 *
Packit 1069cd
 * Since: 1.0
Packit 1069cd
 */
Packit 1069cd
gboolean
Packit 1069cd
gtk_clutter_check_version (guint major,
Packit 1069cd
                           guint minor,
Packit 1069cd
                           guint micro)
Packit 1069cd
{
Packit 1069cd
  return (major > clutter_gtk_major_version) ||
Packit 1069cd
         ((major == clutter_gtk_major_version) && (minor > clutter_gtk_minor_version)) ||
Packit 1069cd
         ((major == clutter_gtk_major_version) && (minor == clutter_gtk_minor_version) && (micro >= clutter_gtk_micro_version));
Packit 1069cd
}