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

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