mutter/clutter/clutter/clutter-main.c

1340 lines
40 KiB
C
Raw Normal View History

2006-05-29 08:59:36 +00:00
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* 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/>.
2006-05-29 08:59:36 +00:00
*/
/**
* SECTION:clutter-main
* @short_description: Various 'global' Clutter functions.
*
2006-06-22 14:36:05 +00:00
* Functions to retrieve various global Clutter resources and other utility
* functions for mainloops, events and threads
*
* ## The Clutter Threading Model
*
* Clutter is *thread-aware*: all operations performed by Clutter are assumed
* to be under the Big Clutter Lock, which is created when the threading is
* initialized through clutter_init(), and entered when calling user-related
* code during event handling and actor drawing.
*
* The only safe and portable way to use the Clutter API in a multi-threaded
* environment is to only access the Clutter API from a thread that did called
* clutter_init() and clutter_main().
*
* The common pattern for using threads with Clutter is to use worker threads
* to perform blocking operations and then install idle or timeout sources with
* the result when the thread finishes, and update the UI from those callbacks.
*
* For a working example of how to use a worker thread to update the UI, see
* [threads.c](https://git.gnome.org/browse/clutter/tree/examples/threads.c?h=clutter-1.18)
*/
#include "clutter/clutter-build-config.h"
2006-06-05 Emmanuele Bassi <ebassi@openedhand.com> * clutter-color.h: * clutter-color.c: Reimplement ClutterColor as a boxed type; add convenience API for color handling, like: add, subtract, shade, HSL color-space conversion, packing and unpacking. * clutter-private.h: Update ClutterMainContext, and export the main context pointer here. * clutter-rectangle.h: * clutter-rectangle.c: Update the color-related code; make clutter_rectangle_new() and empty constructor and provide clutter_rectangle_new_with_color(); provide color setter and getter API. * clutter-label.h: * clutter-label.c: Rename the "font" property to "font-name"; update the color-related code to the new ClutterColor object; rename clutter_label_new() to clutter_label_new_with_text(), and add setters and getters for the properties. * clutter-marshal.list: Add VOID:OBJECT and VOID:BOXED marshallers generators. * clutter-stage.h: * clutter-stage.c: Rework the API: provide a default constructor for a singleton object, named clutter_stage_get_default(), which supercedes the clutter_stage() function in clutter-main; provide new events: button-press-event, button-release-event, key-press-event and key-release-event; update the color-related code; (clutter_stage_snapshot): Allow negative width and height when taking a snapshot (meaning: use full width/height). (clutter_stage_get_element_at_pos): Rename clutter_stage_pick(). * clutter-element.c (clutter_element_paint): Clean up the stage and color related code. * clutter-event.h: * clutter-event.c: Add generic ClutterAnyEvent type; add clutter_event_new(), clutter_event_copy() and clutter_event_free(); make ClutterEvent a boxed type. * clutter-main.h: * clutter-main.c: Remove clutter_stage(); add clutter_main_quit(), for cleanly quitting from clutter_main(); add multiple mainloops support; allocate the ClutterCntx instead of adding it to the stack; re-work the ClutterEvent dispatching. * clutter-group.c (clutter_group_add), (clutter_group_remove): Keep a reference on the element when added to a ClutterGroup. * examples/rects.py * examples/test.c: * examples/test-text.c: * examples/video-cube.c: * examples/super-oh.c: * examples/test-video.c: Update.
2006-06-05 13:38:31 +00:00
#include <stdlib.h>
#include <glib/gi18n-lib.h>
#include <hb-glib.h>
2006-06-05 Emmanuele Bassi <ebassi@openedhand.com> * clutter-color.h: * clutter-color.c: Reimplement ClutterColor as a boxed type; add convenience API for color handling, like: add, subtract, shade, HSL color-space conversion, packing and unpacking. * clutter-private.h: Update ClutterMainContext, and export the main context pointer here. * clutter-rectangle.h: * clutter-rectangle.c: Update the color-related code; make clutter_rectangle_new() and empty constructor and provide clutter_rectangle_new_with_color(); provide color setter and getter API. * clutter-label.h: * clutter-label.c: Rename the "font" property to "font-name"; update the color-related code to the new ClutterColor object; rename clutter_label_new() to clutter_label_new_with_text(), and add setters and getters for the properties. * clutter-marshal.list: Add VOID:OBJECT and VOID:BOXED marshallers generators. * clutter-stage.h: * clutter-stage.c: Rework the API: provide a default constructor for a singleton object, named clutter_stage_get_default(), which supercedes the clutter_stage() function in clutter-main; provide new events: button-press-event, button-release-event, key-press-event and key-release-event; update the color-related code; (clutter_stage_snapshot): Allow negative width and height when taking a snapshot (meaning: use full width/height). (clutter_stage_get_element_at_pos): Rename clutter_stage_pick(). * clutter-element.c (clutter_element_paint): Clean up the stage and color related code. * clutter-event.h: * clutter-event.c: Add generic ClutterAnyEvent type; add clutter_event_new(), clutter_event_copy() and clutter_event_free(); make ClutterEvent a boxed type. * clutter-main.h: * clutter-main.c: Remove clutter_stage(); add clutter_main_quit(), for cleanly quitting from clutter_main(); add multiple mainloops support; allocate the ClutterCntx instead of adding it to the stack; re-work the ClutterEvent dispatching. * clutter-group.c (clutter_group_add), (clutter_group_remove): Keep a reference on the element when added to a ClutterGroup. * examples/rects.py * examples/test.c: * examples/test-text.c: * examples/video-cube.c: * examples/super-oh.c: * examples/test-video.c: Update.
2006-06-05 13:38:31 +00:00
#include "clutter/clutter-actor-private.h"
#include "clutter/clutter-backend-private.h"
#include "clutter/clutter-debug.h"
#include "clutter/clutter-event-private.h"
#include "clutter/clutter-input-device-private.h"
#include "clutter/clutter-input-pointer-a11y-private.h"
#include "clutter/clutter-graphene.h"
#include "clutter/clutter-main.h"
#include "clutter/clutter-mutter.h"
#include "clutter/clutter-paint-node-private.h"
#include "clutter/clutter-private.h"
#include "clutter/clutter-settings-private.h"
#include "clutter/clutter-stage.h"
#include "clutter/clutter-stage-manager.h"
#include "clutter/clutter-stage-private.h"
#include "clutter/clutter-backend-private.h"
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
#include "cogl/cogl.h"
#include "cogl-pango/cogl-pango.h"
#include "cally/cally.h" /* For accessibility support */
2007-08-08 10:20:14 +00:00
/* main context */
static ClutterMainContext *ClutterCntx = NULL;
2007-08-08 10:20:14 +00:00
/* command line options */
static gboolean clutter_is_initialized = FALSE;
static gboolean clutter_show_fps = FALSE;
static gboolean clutter_disable_mipmap_text = FALSE;
static gboolean clutter_enable_accessibility = TRUE;
static gboolean clutter_sync_to_vblank = TRUE;
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
static ClutterTextDirection clutter_text_direction = CLUTTER_TEXT_DIRECTION_LTR;
2011-10-10 15:42:36 +01:00
/* debug flags */
guint clutter_debug_flags = 0;
guint clutter_paint_debug_flags = 0;
2011-10-10 15:42:36 +01:00
guint clutter_pick_debug_flags = 0;
/* A constant added to heuristic max render time to account for variations
* in the estimates.
*/
int clutter_max_render_time_constant_us = 1000;
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
#ifdef CLUTTER_ENABLE_DEBUG
static const GDebugKey clutter_debug_keys[] = {
{ "misc", CLUTTER_DEBUG_MISC },
{ "actor", CLUTTER_DEBUG_ACTOR },
{ "texture", CLUTTER_DEBUG_TEXTURE },
{ "event", CLUTTER_DEBUG_EVENT },
{ "paint", CLUTTER_DEBUG_PAINT },
{ "pick", CLUTTER_DEBUG_PICK },
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
{ "pango", CLUTTER_DEBUG_PANGO },
{ "backend", CLUTTER_DEBUG_BACKEND },
{ "scheduler", CLUTTER_DEBUG_SCHEDULER },
{ "script", CLUTTER_DEBUG_SCRIPT },
{ "shader", CLUTTER_DEBUG_SHADER },
{ "animation", CLUTTER_DEBUG_ANIMATION },
{ "layout", CLUTTER_DEBUG_LAYOUT },
{ "clipping", CLUTTER_DEBUG_CLIPPING },
{ "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS },
{ "frame-timings", CLUTTER_DEBUG_FRAME_TIMINGS },
{ "detailed-trace", CLUTTER_DEBUG_DETAILED_TRACE },
{ "grabs", CLUTTER_DEBUG_GRABS },
{ "frame-clock", CLUTTER_DEBUG_FRAME_CLOCK },
};
#endif /* CLUTTER_ENABLE_DEBUG */
static const GDebugKey clutter_pick_debug_keys[] = {
{ "nop-picking", CLUTTER_DEBUG_NOP_PICKING },
};
static const GDebugKey clutter_paint_debug_keys[] = {
Adds initial clipped redraw support to Clutter A new (internal only currently) API, _clutter_actor_queue_clipped_redraw can be used to queue a redraw along with a clip rectangle in actor coordinates. This clip rectangle propagates up to the stage and clutter backend which may optionally use the information to optimize stage redraws. The GLX backend in particular may scissor the next redraw to the clip rectangle and use GLX_MESA_copy_sub_buffer to present the stage subregion. The intention is that any actors that can naturally determine the bounds of updates should queue clipped redraws to reduce the cost of updating small regions of the screen. Notes: » If GLX_MESA_copy_sub_buffer isn't available then the GLX backend ignores any clip rectangles. » queuing multiple clipped redraws will result in the bounding box of each clip rectangle being used. » If a clipped redraw has a height > 300 pixels then it's promoted into a full stage redraw, so that the GPU doesn't end up blocking too long waiting for the vsync to reach the optimal position to avoid tearing. » Note: no empirical data was used to come up with this threshold so we may need to tune this. » Currently only ClutterX11TexturePixmap makes use of this new API. This is done via a new "queue-damage-redraw" signal that is emitted when the pixmap is updated. The default handler queues a clipped redraw with the assumption that the pixmap is being painted as a rectangle covering the actors transformed allocation. If you subclass ClutterX11TexturePixmap and change how it's painted you now also need to override the signal handler and queue your own redraw. Technically this is a semantic break, but it's assumed that no one is currently doing this. This still leaves a few unsolved issues with regards to optimizing sub stage redraws that need to be addressed in further work so this can only be considered a stepping stone a this point: » Because we have no reliable way to determine if the painting of any given actor is being modified any optimizations implemented using _clutter_actor_queue_redraw_with_clip must be overridable by a subclass, and technically must be opt-in for existing classes to avoid a change in semantics. E.g. consider that a user connects to the paint signal for ClutterTexture and paints a circle instead of a rectangle. In this case any original logic to queue clipped redraws would be incorrect. » Currently only the implementation of an actor has enough information with which to queue clipped redraws. E.g. It is not possible for generic code in clutter-actor.c to queue a clipped redraw when hiding an actor because actors have no way to report a "paint box". (remember actors can draw outside their allocation and actors with depth may also be projected outside of their allocation) » The current plan is to add a actor_class->get_paint_cuboid() virtual so actors can report a bounding cube for everything they would draw in their current state and use that to queue clipped redraws against the stage by projecting the paint cube into stage coordinates. » Our heuristics for promoting clipped redraws into full redraws to avoid blocking the GPU while we wait for the vsync need improving: » vsync issues aren't relevant for redirected/composited applications so they should use different heuristics. In this case we instead need to trade off the cost of blitting when using glXCopySubBuffer vs promoting to a full redraw and flipping instead.
2009-11-30 17:47:55 +00:00
{ "disable-swap-events", CLUTTER_DEBUG_DISABLE_SWAP_EVENTS },
{ "disable-clipped-redraws", CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS },
{ "redraws", CLUTTER_DEBUG_REDRAWS },
{ "paint-volumes", CLUTTER_DEBUG_PAINT_VOLUMES },
{ "disable-culling", CLUTTER_DEBUG_DISABLE_CULLING },
{ "disable-offscreen-redirect", CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT },
{ "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW },
{ "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES },
{ "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION },
{ "disable-dynamic-max-render-time", CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME },
{ "max-render-time", CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME },
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
};
2006-05-29 08:59:36 +00:00
gboolean
_clutter_context_get_show_fps (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
return context->show_fps;
2006-05-29 08:59:36 +00:00
}
/**
* clutter_get_accessibility_enabled:
*
* Returns whether Clutter has accessibility support enabled. As
* least, a value of TRUE means that there are a proper AtkUtil
* implementation available
*
* Return value: %TRUE if Clutter has accessibility support enabled
*/
gboolean
clutter_get_accessibility_enabled (void)
{
return cally_get_cally_initialized ();
}
/**
* clutter_disable_accessibility:
*
* Disable loading the accessibility support. It has the same effect
* as setting the environment variable
* CLUTTER_DISABLE_ACCESSIBILITY. For the same reason, this method
* should be called before clutter_init().
*/
void
clutter_disable_accessibility (void)
{
if (clutter_is_initialized)
{
g_warning ("clutter_disable_accessibility() can only be called before "
"initializing Clutter.");
return;
}
clutter_enable_accessibility = FALSE;
}
static CoglPangoFontMap *
clutter_context_get_pango_fontmap (void)
{
ClutterMainContext *self;
CoglPangoFontMap *font_map;
gdouble resolution;
gboolean use_mipmapping;
self = _clutter_context_get_default ();
if (G_LIKELY (self->font_map != NULL))
return self->font_map;
font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new ());
resolution = clutter_backend_get_resolution (self->backend);
cogl_pango_font_map_set_resolution (font_map, resolution);
use_mipmapping = !clutter_disable_mipmap_text;
cogl_pango_font_map_set_use_mipmapping (font_map, use_mipmapping);
self->font_map = font_map;
return self->font_map;
}
ClutterTextDirection
clutter_get_text_direction (void)
{
ClutterTextDirection dir = CLUTTER_TEXT_DIRECTION_LTR;
const gchar *direction;
direction = g_getenv ("CLUTTER_TEXT_DIRECTION");
if (direction && *direction != '\0')
{
if (strcmp (direction, "rtl") == 0)
dir = CLUTTER_TEXT_DIRECTION_RTL;
else if (strcmp (direction, "ltr") == 0)
dir = CLUTTER_TEXT_DIRECTION_LTR;
}
else
{
PangoLanguage *language;
const PangoScript *scripts;
int n_scripts, i;
language = pango_language_get_default ();
scripts = pango_language_get_scripts (language, &n_scripts);
for (i = 0; i < n_scripts; i++)
{
hb_script_t script;
hb_direction_t text_dir;
script = hb_glib_script_to_script ((GUnicodeScript) scripts[i]);
text_dir = hb_script_get_horizontal_direction (script);
if (text_dir == HB_DIRECTION_LTR)
dir = CLUTTER_TEXT_DIRECTION_LTR;
else if (text_dir == HB_DIRECTION_RTL)
dir = CLUTTER_TEXT_DIRECTION_RTL;
else
continue;
}
}
CLUTTER_NOTE (MISC, "Text direction: %s",
dir == CLUTTER_TEXT_DIRECTION_RTL ? "rtl" : "ltr");
return dir;
}
gboolean
_clutter_threads_dispatch (gpointer data)
2007-08-08 10:20:14 +00:00
{
ClutterThreadsDispatch *dispatch = data;
gboolean ret = FALSE;
if (!g_source_is_destroyed (g_main_current_source ()))
ret = dispatch->func (dispatch->data);
return ret;
}
void
_clutter_threads_dispatch_free (gpointer data)
2007-08-08 10:20:14 +00:00
{
ClutterThreadsDispatch *dispatch = data;
/* XXX - we cannot hold the thread lock here because the main loop
* might destroy a source while still in the dispatcher function; so
* knowing whether the lock is being held or not is not known a priori.
*
* see bug: http://bugzilla.gnome.org/show_bug.cgi?id=459555
*/
2007-08-08 10:20:14 +00:00
if (dispatch->notify)
dispatch->notify (dispatch->data);
g_free (dispatch);
2007-08-08 10:20:14 +00:00
}
/**
* clutter_threads_add_idle_full: (rename-to clutter_threads_add_idle)
2007-08-08 10:20:14 +00:00
* @priority: the priority of the timeout source. Typically this will be in the
* range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE
* @func: function to call
* @data: data to pass to the function
* @notify: function to call when the idle source is removed
2007-08-08 10:20:14 +00:00
*
* Adds a function to be called whenever there are no higher priority
* events pending. If the function returns %FALSE it is automatically
2007-08-08 10:20:14 +00:00
* removed from the list of event sources and will not be called again.
*
* This function can be considered a thread-safe variant of g_idle_add_full():
* it will call @function while holding the Clutter lock. It is logically
* equivalent to the following implementation:
2007-08-08 10:20:14 +00:00
*
* ```c
2007-08-08 10:20:14 +00:00
* static gboolean
* idle_safe_callback (gpointer data)
2007-08-08 10:20:14 +00:00
* {
* SafeClosure *closure = data;
* gboolean res = FALSE;
2007-08-08 10:20:14 +00:00
*
* // the callback does not need to acquire the Clutter
* / lock itself, as it is held by the this proxy handler
* //
* res = closure->callback (closure->data);
*
* return res;
2007-08-08 10:20:14 +00:00
* }
* static gulong
* add_safe_idle (GSourceFunc callback,
* gpointer data)
2007-08-08 10:20:14 +00:00
* {
* SafeClosure *closure = g_new0 (SafeClosure, 1);
*
* closure->callback = callback;
* closure->data = data;
*
2011-10-10 15:42:36 +01:00
* return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
* idle_safe_callback,
* closure,
* g_free)
2007-08-08 10:20:14 +00:00
* }
* ```
2007-08-08 10:20:14 +00:00
*
* This function should be used by threaded applications to make sure
* that @func is emitted under the Clutter threads lock and invoked
* from the same thread that started the Clutter main loop. For instance,
* it can be used to update the UI using the results from a worker
* thread:
*
* ```c
* static gboolean
* update_ui (gpointer data)
2007-08-08 10:20:14 +00:00
* {
* SomeClosure *closure = data;
*
* // it is safe to call Clutter API from this function because
* / it is invoked from the same thread that started the main
* / loop and under the Clutter thread lock
* //
* clutter_label_set_text (CLUTTER_LABEL (closure->label),
* closure->text);
*
* g_object_unref (closure->label);
* g_free (closure);
*
* return FALSE;
2007-08-08 10:20:14 +00:00
* }
*
* // within another thread //
* closure = g_new0 (SomeClosure, 1);
* // always take a reference on GObject instances //
* closure->label = g_object_ref (my_application->label);
* closure->text = g_strdup (processed_text_to_update_the_label);
*
* clutter_threads_add_idle_full (G_PRIORITY_HIGH_IDLE,
* update_ui,
* closure,
* NULL);
* ```
2007-08-08 10:20:14 +00:00
*
* Return value: the ID (greater than 0) of the event source.
*/
guint
clutter_threads_add_idle_full (gint priority,
GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
ClutterThreadsDispatch *dispatch;
g_return_val_if_fail (func != NULL, 0);
dispatch = g_new0 (ClutterThreadsDispatch, 1);
2007-08-08 10:20:14 +00:00
dispatch->func = func;
dispatch->data = data;
dispatch->notify = notify;
return g_idle_add_full (priority,
_clutter_threads_dispatch, dispatch,
_clutter_threads_dispatch_free);
2007-08-08 10:20:14 +00:00
}
/**
2010-09-08 16:41:47 +01:00
* clutter_threads_add_idle: (skip)
2007-08-08 10:20:14 +00:00
* @func: function to call
* @data: data to pass to the function
*
* Simple wrapper around clutter_threads_add_idle_full() using the
* default priority.
2007-08-08 10:20:14 +00:00
*
* Return value: the ID (greater than 0) of the event source.
*/
guint
clutter_threads_add_idle (GSourceFunc func,
gpointer data)
{
g_return_val_if_fail (func != NULL, 0);
return clutter_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
func, data,
NULL);
}
/**
* clutter_threads_add_timeout_full: (rename-to clutter_threads_add_timeout)
2007-08-08 10:20:14 +00:00
* @priority: the priority of the timeout source. Typically this will be in the
* range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
* @interval: the time between calls to the function, in milliseconds
* @func: function to call
* @data: data to pass to the function
* @notify: function to call when the timeout source is removed
*
* Sets a function to be called at regular intervals holding the Clutter
* threads lock, with the given priority. The function is called repeatedly
* until it returns %FALSE, at which point the timeout is automatically
* removed and the function will not be called again. The @notify function
* is called when the timeout is removed.
2007-08-08 10:20:14 +00:00
*
* The first call to the function will be at the end of the first @interval.
2007-08-08 10:20:14 +00:00
*
* It is important to note that, due to how the Clutter main loop is
* implemented, the timing will not be accurate and it will not try to
2011-10-10 15:42:36 +01:00
* "keep up" with the interval.
*
* See also clutter_threads_add_idle_full().
2007-08-08 10:20:14 +00:00
*
* Return value: the ID (greater than 0) of the event source.
*/
guint
clutter_threads_add_timeout_full (gint priority,
guint interval,
GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
ClutterThreadsDispatch *dispatch;
g_return_val_if_fail (func != NULL, 0);
dispatch = g_new0 (ClutterThreadsDispatch, 1);
2007-08-08 10:20:14 +00:00
dispatch->func = func;
dispatch->data = data;
dispatch->notify = notify;
return g_timeout_add_full (priority,
interval,
_clutter_threads_dispatch, dispatch,
_clutter_threads_dispatch_free);
2007-08-08 10:20:14 +00:00
}
/**
2010-09-08 16:41:47 +01:00
* clutter_threads_add_timeout: (skip)
2007-08-08 10:20:14 +00:00
* @interval: the time between calls to the function, in milliseconds
* @func: function to call
* @data: data to pass to the function
*
* Simple wrapper around clutter_threads_add_timeout_full().
*
* Return value: the ID (greater than 0) of the event source.
*/
guint
clutter_threads_add_timeout (guint interval,
GSourceFunc func,
gpointer data)
{
g_return_val_if_fail (func != NULL, 0);
return clutter_threads_add_timeout_full (G_PRIORITY_DEFAULT,
interval,
func, data,
NULL);
}
gboolean
_clutter_context_is_initialized (void)
{
if (ClutterCntx == NULL)
return FALSE;
return ClutterCntx->is_initialized;
}
ClutterMainContext *
_clutter_context_get_default (void)
{
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
g_assert (ClutterCntx);
2006-06-05 Emmanuele Bassi <ebassi@openedhand.com> * clutter-color.h: * clutter-color.c: Reimplement ClutterColor as a boxed type; add convenience API for color handling, like: add, subtract, shade, HSL color-space conversion, packing and unpacking. * clutter-private.h: Update ClutterMainContext, and export the main context pointer here. * clutter-rectangle.h: * clutter-rectangle.c: Update the color-related code; make clutter_rectangle_new() and empty constructor and provide clutter_rectangle_new_with_color(); provide color setter and getter API. * clutter-label.h: * clutter-label.c: Rename the "font" property to "font-name"; update the color-related code to the new ClutterColor object; rename clutter_label_new() to clutter_label_new_with_text(), and add setters and getters for the properties. * clutter-marshal.list: Add VOID:OBJECT and VOID:BOXED marshallers generators. * clutter-stage.h: * clutter-stage.c: Rework the API: provide a default constructor for a singleton object, named clutter_stage_get_default(), which supercedes the clutter_stage() function in clutter-main; provide new events: button-press-event, button-release-event, key-press-event and key-release-event; update the color-related code; (clutter_stage_snapshot): Allow negative width and height when taking a snapshot (meaning: use full width/height). (clutter_stage_get_element_at_pos): Rename clutter_stage_pick(). * clutter-element.c (clutter_element_paint): Clean up the stage and color related code. * clutter-event.h: * clutter-event.c: Add generic ClutterAnyEvent type; add clutter_event_new(), clutter_event_copy() and clutter_event_free(); make ClutterEvent a boxed type. * clutter-main.h: * clutter-main.c: Remove clutter_stage(); add clutter_main_quit(), for cleanly quitting from clutter_main(); add multiple mainloops support; allocate the ClutterCntx instead of adding it to the stack; re-work the ClutterEvent dispatching. * clutter-group.c (clutter_group_add), (clutter_group_remove): Keep a reference on the element when added to a ClutterGroup. * examples/rects.py * examples/test.c: * examples/test-text.c: * examples/video-cube.c: * examples/super-oh.c: * examples/test-video.c: Update.
2006-06-05 13:38:31 +00:00
return ClutterCntx;
}
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
static gboolean
clutter_init_real (ClutterMainContext *clutter_context,
GError **error)
{
ClutterBackend *backend;
/* Note, creates backend if not already existing, though parse args will
* have likely created it
*/
backend = clutter_context->backend;
if (!_clutter_backend_finish_init (backend, error))
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
return FALSE;
/* If we are displaying the regions that would get redrawn with clipped
* redraws enabled we actually have to disable the clipped redrawing
* because otherwise we end up with nasty trails of rectangles everywhere.
*/
if (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)
clutter_paint_debug_flags |= CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS;
/* The same is true when drawing the outlines of paint volumes... */
if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES)
{
clutter_paint_debug_flags |=
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS | CLUTTER_DEBUG_DISABLE_CULLING;
}
if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)
g_message ("Enabling damaged region");
if (!_clutter_backend_create_context (clutter_context->backend, error))
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
return FALSE;
Fully integrates CoglMaterial throughout the rest of Cogl This glues CoglMaterial in as the fundamental way that Cogl describes how to fill in geometry. It adds cogl_set_source (), which is used to set the material which will be used by all subsequent drawing functions It adds cogl_set_source_texture as a convenience for setting up a default material with a single texture layer, and cogl_set_source_color is now also a convenience for setting up a material with a solid fill. "drawing functions" include, cogl_rectangle, cogl_texture_rectangle, cogl_texture_multiple_rectangles, cogl_texture_polygon (though the cogl_texture_* funcs have been renamed; see below for details), cogl_path_fill/stroke and cogl_vertex_buffer_draw*. cogl_texture_rectangle, cogl_texture_multiple_rectangles and cogl_texture_polygon no longer take a texture handle; instead the current source material is referenced. The functions have also been renamed to: cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords and cogl_polygon respectivly. Most code that previously did: cogl_texture_rectangle (tex_handle, x, y,...); needs to be changed to now do: cogl_set_source_texture (tex_handle); cogl_rectangle_with_texture_coords (x, y,....); In the less likely case where you were blending your source texture with a color like: cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */ cogl_texture_rectangle (tex_handle, x, y,...); you will need your own material to do that: mat = cogl_material_new (); cogl_material_set_color4ub (r,g,b,a); cogl_material_set_layer (mat, 0, tex_handle)); cogl_set_source_material (mat); Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use cog_rectangle_with_texure_coords since these are the coordinates that cogl_rectangle will use. For cogl_texture_polygon; as well as dropping the texture handle, the n_vertices and vertices arguments were transposed for consistency. So code previously written as: cogl_texture_polygon (tex_handle, 3, verts, TRUE); need to be written as: cogl_set_source_texture (tex_handle); cogl_polygon (verts, 3, TRUE); All of the unit tests have been updated to now use the material API and test-cogl-material has been renamed to test-cogl-multitexture since any textured quad is now technically a test of CoglMaterial but this test specifically creates a material with multiple texture layers. Note: The GLES backend has not been updated yet; that will be done in a following commit.
2009-01-23 16:15:40 +00:00
clutter_text_direction = clutter_get_text_direction ();
clutter_is_initialized = TRUE;
clutter_context->is_initialized = TRUE;
/* Initialize a11y */
if (clutter_enable_accessibility)
cally_accessibility_init ();
/* Initialize types required for paint nodes */
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
clutter_paint_node_init_types (clutter_context->backend);
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
return TRUE;
}
static void
init_clutter_debug (ClutterMainContext *clutter_context)
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
{
const char *env_string;
2006-05-29 08:59:36 +00:00
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
#ifdef CLUTTER_ENABLE_DEBUG
env_string = g_getenv ("CLUTTER_DEBUG");
if (env_string != NULL)
{
clutter_debug_flags =
g_parse_debug_string (env_string,
clutter_debug_keys,
G_N_ELEMENTS (clutter_debug_keys));
env_string = NULL;
}
#endif /* CLUTTER_ENABLE_DEBUG */
2006-05-29 08:59:36 +00:00
env_string = g_getenv ("CLUTTER_PICK");
if (env_string != NULL)
{
clutter_pick_debug_flags =
g_parse_debug_string (env_string,
clutter_pick_debug_keys,
G_N_ELEMENTS (clutter_pick_debug_keys));
env_string = NULL;
}
env_string = g_getenv ("CLUTTER_PAINT");
if (env_string != NULL)
{
clutter_paint_debug_flags =
g_parse_debug_string (env_string,
clutter_paint_debug_keys,
G_N_ELEMENTS (clutter_paint_debug_keys));
env_string = NULL;
}
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
env_string = g_getenv ("CLUTTER_SHOW_FPS");
if (env_string)
clutter_show_fps = TRUE;
2006-06-05 Emmanuele Bassi <ebassi@openedhand.com> * clutter-color.h: * clutter-color.c: Reimplement ClutterColor as a boxed type; add convenience API for color handling, like: add, subtract, shade, HSL color-space conversion, packing and unpacking. * clutter-private.h: Update ClutterMainContext, and export the main context pointer here. * clutter-rectangle.h: * clutter-rectangle.c: Update the color-related code; make clutter_rectangle_new() and empty constructor and provide clutter_rectangle_new_with_color(); provide color setter and getter API. * clutter-label.h: * clutter-label.c: Rename the "font" property to "font-name"; update the color-related code to the new ClutterColor object; rename clutter_label_new() to clutter_label_new_with_text(), and add setters and getters for the properties. * clutter-marshal.list: Add VOID:OBJECT and VOID:BOXED marshallers generators. * clutter-stage.h: * clutter-stage.c: Rework the API: provide a default constructor for a singleton object, named clutter_stage_get_default(), which supercedes the clutter_stage() function in clutter-main; provide new events: button-press-event, button-release-event, key-press-event and key-release-event; update the color-related code; (clutter_stage_snapshot): Allow negative width and height when taking a snapshot (meaning: use full width/height). (clutter_stage_get_element_at_pos): Rename clutter_stage_pick(). * clutter-element.c (clutter_element_paint): Clean up the stage and color related code. * clutter-event.h: * clutter-event.c: Add generic ClutterAnyEvent type; add clutter_event_new(), clutter_event_copy() and clutter_event_free(); make ClutterEvent a boxed type. * clutter-main.h: * clutter-main.c: Remove clutter_stage(); add clutter_main_quit(), for cleanly quitting from clutter_main(); add multiple mainloops support; allocate the ClutterCntx instead of adding it to the stack; re-work the ClutterEvent dispatching. * clutter-group.c (clutter_group_add), (clutter_group_remove): Keep a reference on the element when added to a ClutterGroup. * examples/rects.py * examples/test.c: * examples/test-text.c: * examples/video-cube.c: * examples/super-oh.c: * examples/test-video.c: Update.
2006-06-05 13:38:31 +00:00
env_string = g_getenv ("CLUTTER_DISABLE_MIPMAPPED_TEXT");
if (env_string)
clutter_disable_mipmap_text = TRUE;
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
}
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
ClutterContext *
clutter_context_new (ClutterBackendConstructor backend_constructor,
gpointer user_data,
GError **error)
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
{
ClutterMainContext *clutter_context;
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
if (ClutterCntx)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Currently only creating one clutter context is supported");
return NULL;
}
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
clutter_graphene_init ();
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com> * configure.ac: Enable debug messages also when --enable-debug is set to "minimum". * clutter/Makefile.am: * clutter/clutter-debug.h: Move all debugging macros inside this private header; make all debug macros depend on the CLUTTER_ENABLE_DEBUG compile time define, controlled by the --enable-debug configure switch; add G_LOG_DOMAIN define. * clutter/clutter-main.c: Clean up the debug stuff; add command line argument parsing using GOption; the debug messages now are triggered like this: CLUTTER_DEBUG=section:section:... clutter-app or like this: clutter-app --clutter-debug=section:section:... where "section" is one of the sections listed in clutter-main.c, or "all", for all sections; each section is bound to a flag, which can be used to define a domain when adding a debug note using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is just a wrapper around that, under the CLUTTER_DEBUG_MISC domain; CLUTTER_NOTE() is used like this: CLUTTER_NOTE (DOMAIN, log-function); where log function is g_printerr(), g_message(), g_warning(), g_critical() or directly g_log() - for instance: CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph)); will print the warning only if the "pango" flag has been set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug command line argument. similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps command line switch; also, the --display and --screen command line switches have been added: the first overrides the DISPLAY envvar and the second controls the X screen used by Clutter to get the root window on the display. * clutter/clutter-main.h: * clutter/clutter-main.c: Add extended support for GOption in Clutter; use clutter_init_with_args() to let Clutter parse your own command line arguments; use instead clutter_get_option_group() to get the GOptionGroup used by Clutter if you want to do the parsing yourself with g_option_context_parse(). The init sequence has been verified, updated and moved into common functions where possible. * clutter/pango/pangoclutter-render.c: * clutter/*.c: Include "clutter-debug.h" where needed; use CLUTTER_NOTE() instead of CLUTTER_DBG(). * examples/super-oh.c: Use the new clutter_init_with_args() function, and add a --num-hands command line switch to the SuperOH example code controlling the number of hands at runtime.
2006-11-21 21:27:53 +00:00
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
clutter_context = g_new0 (ClutterMainContext, 1);
init_clutter_debug (clutter_context);
clutter_context->show_fps = clutter_show_fps;
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
clutter_context->is_initialized = FALSE;
clutter_context->backend = backend_constructor (user_data);
clutter_context->settings = clutter_settings_get_default ();
_clutter_settings_set_backend (clutter_context->settings,
clutter_context->backend);
clutter_context->events_queue =
g_async_queue_new_full ((GDestroyNotify) clutter_event_free);
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
clutter_context->last_repaint_id = 1;
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
if (!clutter_init_real (clutter_context, error))
{
g_free (clutter_context);
return NULL;
}
Explicitly create the clutter context and backend This changes the setup phase of clutter to not be result of calling an init function that sets up a few global singletons, via global singleton setup vfuncs. The way it worked was that mutter first did some initial setup (connecting to the X11 server), then set a "custom backend" setup vfunc global, before calling clutter_init(). During the clutter_init() call, the context and backend was setup by calling the global singleton getters, which implicitly created the backend and context on-demand. This has now changed to mutter explicitly creating a `ClutterContext` (which is actually a `ClutterMainContext`, but with the name shortened to be consistent with `CoglContext` and `MetaContext`), calling it with a backend constructor vfunc and user data pointer. This function now explicitly creates the backend, without having to go via the previously set global vfunc. This changes the behavior of some "get_default()" like functions, which will now fail if called after mutter has shut down, as when it does so, it now destroys the backends and contexts, not only its own, but the clutter ones too. The "ownership" of the clutter backend is also moved to `ClutterContext`, and MetaBackend is changed to fetch it via the clutter context. This also removed the unused option parsing that existed in clutter. In some places, NULL checks for fetching the clutter context, or backend, and fetching the cogl context from the clutter backend, had to be added. The reason for this is that some code that handles EGL contexts attempts to restore the cogl EGL context tracking so that the right EGL context is used by cogl the next time. This makes no sense to do before Cogl and Clutter are even initialized, which was the case. It wasn't noticed because the relevant singletons were initialized on demand via their "getters". Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-09-16 11:38:49 +02:00
ClutterCntx = clutter_context;
return clutter_context;
}
void
clutter_context_free (ClutterMainContext *clutter_context)
{
g_clear_pointer (&clutter_context->events_queue, g_async_queue_unref);
g_clear_pointer (&clutter_context->backend, clutter_backend_destroy);
ClutterCntx = NULL;
g_free (clutter_context);
}
ClutterBackend *
clutter_context_get_backend (ClutterContext *clutter_context)
{
return clutter_context->backend;
2006-05-29 08:59:36 +00:00
}
gboolean
_clutter_boolean_handled_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,
gpointer dummy)
{
gboolean continue_emission;
gboolean signal_handled;
signal_handled = g_value_get_boolean (handler_return);
g_value_set_boolean (return_accu, signal_handled);
continue_emission = !signal_handled;
return continue_emission;
}
gboolean
_clutter_boolean_continue_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,
gpointer dummy)
{
gboolean continue_emission;
continue_emission = g_value_get_boolean (handler_return);
g_value_set_boolean (return_accu, continue_emission);
return continue_emission;
}
/*
* Emits a pointer event after having prepared the event for delivery (setting
* source, generating enter/leave etc.).
*/
static inline void
emit_event (ClutterStage *stage,
ClutterEvent *event)
{
ClutterEventType event_type;
event_type = clutter_event_type (event);
if (event_type == CLUTTER_KEY_PRESS ||
event_type == CLUTTER_KEY_RELEASE)
cally_snoop_key_event (stage, (ClutterKeyEvent *) event);
clutter_stage_emit_event (stage, event);
}
static ClutterActor *
update_device_for_event (ClutterStage *stage,
ClutterEvent *event,
gboolean emit_crossing)
{
ClutterInputDevice *device = clutter_event_get_device (event);
ClutterInputDevice *source_device = clutter_event_get_source_device (event);
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
ClutterDeviceUpdateFlags flags = CLUTTER_DEVICE_UPDATE_NONE;
graphene_point_t point;
uint32_t time_ms;
clutter_event_get_coords (event, &point.x, &point.y);
time_ms = clutter_event_get_time (event);
if (emit_crossing)
flags |= CLUTTER_DEVICE_UPDATE_EMIT_CROSSING;
return clutter_stage_pick_and_update_device (stage,
device,
sequence,
source_device,
flags,
point,
time_ms);
}
static void
maybe_remove_device_for_event (ClutterStage *stage,
ClutterEvent *event,
gboolean emit_crossing)
{
ClutterInputDevice *device = clutter_event_get_device (event);
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
graphene_point_t point;
uint32_t time;
if (clutter_event_type (event) == CLUTTER_DEVICE_REMOVED)
{
ClutterInputDeviceType device_type =
clutter_input_device_get_device_type (device);
if (device_type != CLUTTER_POINTER_DEVICE &&
device_type != CLUTTER_TABLET_DEVICE &&
device_type != CLUTTER_PEN_DEVICE &&
device_type != CLUTTER_ERASER_DEVICE &&
device_type != CLUTTER_CURSOR_DEVICE)
return;
}
clutter_event_get_coords (event, &point.x, &point.y);
time = clutter_event_get_time (event);
clutter_stage_update_device (stage,
device, sequence,
NULL,
point,
time,
NULL,
NULL,
TRUE);
clutter_stage_remove_device_entry (stage, device, sequence);
}
/**
* clutter_stage_handle_event:
* @stage: a #ClutterStage.
* @event: a #ClutterEvent.
*
* Processes an event.
*
* The @event must be a valid #ClutterEvent and have a #ClutterStage
* associated to it.
*
* This function is only useful when embedding Clutter inside another
* toolkit, and it should never be called by applications.
*/
void
clutter_stage_handle_event (ClutterStage *stage,
ClutterEvent *event)
{
ClutterContext *context = _clutter_context_get_default();
ClutterActor *event_actor = NULL;
ClutterEventType event_type;
gboolean filtered;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
g_return_if_fail (event != NULL);
/* stages in destruction do not process events */
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return;
event_type = clutter_event_type (event);
switch (event_type)
{
case CLUTTER_ENTER:
case CLUTTER_MOTION:
case CLUTTER_BUTTON_PRESS:
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_UPDATE:
case CLUTTER_TOUCHPAD_PINCH:
case CLUTTER_TOUCHPAD_SWIPE:
case CLUTTER_TOUCHPAD_HOLD:
case CLUTTER_PROXIMITY_IN:
update_device_for_event (stage, event, TRUE);
break;
default:
break;
}
if (event_type != CLUTTER_DEVICE_ADDED &&
event_type != CLUTTER_DEVICE_REMOVED &&
event_type != CLUTTER_NOTHING &&
event_type != CLUTTER_EVENT_LAST)
{
event_actor = clutter_stage_get_event_actor (stage, event);
}
context->current_event = g_slist_prepend (context->current_event, event);
filtered = _clutter_event_process_filters (event, event_actor);
context->current_event =
g_slist_delete_link (context->current_event, context->current_event);
clutter: Implicitly grab on button and touch event sequences We'll soon introduce a new gesture tracking framework which heavily depends on ClutterActions seeing all events of a sequence. For this to work, a larger change to event delivery is needed: Implicit grabbing of all events for button and touch press->motion->release sequences to ensure ClutterActions continue receiving events for the whole sequence. This commit takes care of that: At the start of an event sequence we collect all the event-handling actors and actions to a GArray that lives in the PointerDeviceEntry, and then deliver all events belonging to that sequence to the same actors/actions until the sequence ends. To avoid events getting pulled from under our feet when mutters event filter returns CLUTTER_EVENT_STOP, this also introduces private API (maybe_lost_implicit_grab()) on ClutterStage so that we can't end up with stale sequences. Note that this also slightly changes behavior when it comes to event delivery to actions: Because we now store actions separated from their actors, any action returning CLUTTER_EVENT_STOP now stops event propagation immediately. That was different before, where we'd emit events to all actions of the actor and only then stop propagation. Note that this isn't handling ClutterGrabs correctly right now, this will be a little tricky, so we'll take care of that in a future commit. To handle actors getting destroyed or unmapped during a grab, listen to notify::grab on the deepmost actor in the implicit grab tree. This gives us a notification when any actor inside the tree goes unmapped. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2342>
2022-08-03 17:57:13 +02:00
if (filtered)
{
if (event_type == CLUTTER_MOTION ||
event_type == CLUTTER_BUTTON_RELEASE ||
event_type == CLUTTER_TOUCH_UPDATE ||
event_type == CLUTTER_TOUCH_END ||
event_type == CLUTTER_TOUCH_CANCEL)
clutter: Implicitly grab on button and touch event sequences We'll soon introduce a new gesture tracking framework which heavily depends on ClutterActions seeing all events of a sequence. For this to work, a larger change to event delivery is needed: Implicit grabbing of all events for button and touch press->motion->release sequences to ensure ClutterActions continue receiving events for the whole sequence. This commit takes care of that: At the start of an event sequence we collect all the event-handling actors and actions to a GArray that lives in the PointerDeviceEntry, and then deliver all events belonging to that sequence to the same actors/actions until the sequence ends. To avoid events getting pulled from under our feet when mutters event filter returns CLUTTER_EVENT_STOP, this also introduces private API (maybe_lost_implicit_grab()) on ClutterStage so that we can't end up with stale sequences. Note that this also slightly changes behavior when it comes to event delivery to actions: Because we now store actions separated from their actors, any action returning CLUTTER_EVENT_STOP now stops event propagation immediately. That was different before, where we'd emit events to all actions of the actor and only then stop propagation. Note that this isn't handling ClutterGrabs correctly right now, this will be a little tricky, so we'll take care of that in a future commit. To handle actors getting destroyed or unmapped during a grab, listen to notify::grab on the deepmost actor in the implicit grab tree. This gives us a notification when any actor inside the tree goes unmapped. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2342>
2022-08-03 17:57:13 +02:00
{
ClutterInputDevice *device = clutter_event_get_device (event);
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
clutter_stage_maybe_lost_implicit_grab (stage, device, sequence);
clutter: Implicitly grab on button and touch event sequences We'll soon introduce a new gesture tracking framework which heavily depends on ClutterActions seeing all events of a sequence. For this to work, a larger change to event delivery is needed: Implicit grabbing of all events for button and touch press->motion->release sequences to ensure ClutterActions continue receiving events for the whole sequence. This commit takes care of that: At the start of an event sequence we collect all the event-handling actors and actions to a GArray that lives in the PointerDeviceEntry, and then deliver all events belonging to that sequence to the same actors/actions until the sequence ends. To avoid events getting pulled from under our feet when mutters event filter returns CLUTTER_EVENT_STOP, this also introduces private API (maybe_lost_implicit_grab()) on ClutterStage so that we can't end up with stale sequences. Note that this also slightly changes behavior when it comes to event delivery to actions: Because we now store actions separated from their actors, any action returning CLUTTER_EVENT_STOP now stops event propagation immediately. That was different before, where we'd emit events to all actions of the actor and only then stop propagation. Note that this isn't handling ClutterGrabs correctly right now, this will be a little tricky, so we'll take care of that in a future commit. To handle actors getting destroyed or unmapped during a grab, listen to notify::grab on the deepmost actor in the implicit grab tree. This gives us a notification when any actor inside the tree goes unmapped. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2342>
2022-08-03 17:57:13 +02:00
}
}
else
{
_clutter_stage_queue_event (stage, event, TRUE);
clutter: Implicitly grab on button and touch event sequences We'll soon introduce a new gesture tracking framework which heavily depends on ClutterActions seeing all events of a sequence. For this to work, a larger change to event delivery is needed: Implicit grabbing of all events for button and touch press->motion->release sequences to ensure ClutterActions continue receiving events for the whole sequence. This commit takes care of that: At the start of an event sequence we collect all the event-handling actors and actions to a GArray that lives in the PointerDeviceEntry, and then deliver all events belonging to that sequence to the same actors/actions until the sequence ends. To avoid events getting pulled from under our feet when mutters event filter returns CLUTTER_EVENT_STOP, this also introduces private API (maybe_lost_implicit_grab()) on ClutterStage so that we can't end up with stale sequences. Note that this also slightly changes behavior when it comes to event delivery to actions: Because we now store actions separated from their actors, any action returning CLUTTER_EVENT_STOP now stops event propagation immediately. That was different before, where we'd emit events to all actions of the actor and only then stop propagation. Note that this isn't handling ClutterGrabs correctly right now, this will be a little tricky, so we'll take care of that in a future commit. To handle actors getting destroyed or unmapped during a grab, listen to notify::grab on the deepmost actor in the implicit grab tree. This gives us a notification when any actor inside the tree goes unmapped. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2342>
2022-08-03 17:57:13 +02:00
}
clutter: Process device removing events immediately when they come in Having the stage device list be responsible for delivering the same events twice (first immediately to clients, then later to Clutter) was expected to be tricky, a sneaky problem with it right now is the following case: While collecting events for a stage update cycle, we get three touch events from the backend: TOUCH_BEGIN(seq=1) -> TOUCH_END(seq=1) -> TOUCH_BEGIN(seq=1) What we do right now when we see a TOUCH_BEGIN event is adding a device to the stage right when it comes in from the backend. And when we see a TOUCH_END, we remove the device from the stage not immediately but only after it went through the queue. In the case of the three events mentioned above, with the current behavior, this will happen when they come in from the backend: - TOUCH_BEGIN(seq=1): device gets added to the stage with seq 1, event gets queued - TOUCH_END(seq=1): Nothing happens, event gets queued - TOUCH_BEGIN(seq=1): we try to add device to the stage, but seq 1 is already there, event gets queued Now when we go through the queue and see the TOUCH_END, the device with seq 1 gets removed, but on the subsequent TOUCH_BEGIN, we won't add a new device, so this event (and all events with seq=1 that are still in the queue) is now ignored by Clutter because it has no device. What we want to do here is to cut short once the TOUCH_END event comes in: Process queued events immediately and make sure the device is removed from the stage list before a new device can be added. Same goes for any other events that will lead to devices getting removed. Small note: Since this leads to clutter_stage_get_device_actor() returning NULL, I was wondering why we never crash because of this: Turns out _clutter_actor_handle_event() handles self = NULL just fine without crashing... Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2696>
2022-11-05 21:16:20 +01:00
if (event_type == CLUTTER_TOUCH_END ||
event_type == CLUTTER_TOUCH_CANCEL ||
event_type == CLUTTER_DEVICE_REMOVED)
{
_clutter_stage_process_queued_events (stage);
maybe_remove_device_for_event (stage, event, TRUE);
}
}
static void
_clutter_process_event_details (ClutterActor *stage,
ClutterMainContext *context,
ClutterEvent *event)
{
switch (clutter_event_type (event))
{
case CLUTTER_NOTHING:
break;
case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE:
case CLUTTER_PAD_BUTTON_PRESS:
case CLUTTER_PAD_BUTTON_RELEASE:
case CLUTTER_PAD_STRIP:
case CLUTTER_PAD_RING:
case CLUTTER_IM_COMMIT:
case CLUTTER_IM_DELETE:
case CLUTTER_IM_PREEDIT:
case CLUTTER_ENTER:
case CLUTTER_LEAVE:
case CLUTTER_MOTION:
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_SCROLL:
case CLUTTER_TOUCHPAD_PINCH:
case CLUTTER_TOUCHPAD_SWIPE:
case CLUTTER_TOUCHPAD_HOLD:
case CLUTTER_TOUCH_UPDATE:
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_CANCEL:
case CLUTTER_TOUCH_END:
case CLUTTER_PROXIMITY_IN:
case CLUTTER_PROXIMITY_OUT:
emit_event (CLUTTER_STAGE (stage), event);
break;
case CLUTTER_DEVICE_REMOVED:
case CLUTTER_DEVICE_ADDED:
case CLUTTER_EVENT_LAST:
break;
}
}
/*
* clutter_stage_process_event
* @event: a #ClutterEvent.
*
* Does the actual work of processing an event that was queued earlier
* out of clutter_stage_handle_event().
*/
void
clutter_stage_process_event (ClutterStage *stage,
ClutterEvent *event)
{
ClutterMainContext *context;
ClutterSeat *seat;
context = _clutter_context_get_default ();
seat = clutter_backend_get_default_seat (context->backend);
/* push events on a stack, so that we don't need to
* add an event parameter to all signals that can be emitted within
* an event chain
*/
context->current_event = g_slist_prepend (context->current_event, event);
clutter_seat_handle_event_post (seat, event);
_clutter_process_event_details (CLUTTER_ACTOR (stage), context, event);
context->current_event = g_slist_delete_link (context->current_event, context->current_event);
}
/**
* clutter_get_font_map:
*
* Retrieves the #PangoFontMap instance used by Clutter.
* You can use the global font map object with the COGL
* Pango API.
*
* Return value: (transfer none): the #PangoFontMap instance. The returned
* value is owned by Clutter and it should never be unreferenced.
*/
PangoFontMap *
clutter_get_font_map (void)
{
return PANGO_FONT_MAP (clutter_context_get_pango_fontmap ());
}
typedef struct _ClutterRepaintFunction
{
guint id;
ClutterRepaintFlags flags;
GSourceFunc func;
gpointer data;
GDestroyNotify notify;
} ClutterRepaintFunction;
/**
* clutter_threads_remove_repaint_func:
* @handle_id: an unsigned integer greater than zero
*
* Removes the repaint function with @handle_id as its id
*/
void
clutter_threads_remove_repaint_func (guint handle_id)
{
ClutterRepaintFunction *repaint_func;
ClutterMainContext *context;
GList *l;
g_return_if_fail (handle_id > 0);
context = _clutter_context_get_default ();
l = context->repaint_funcs;
while (l != NULL)
{
repaint_func = l->data;
if (repaint_func->id == handle_id)
{
context->repaint_funcs =
g_list_remove_link (context->repaint_funcs, l);
g_list_free (l);
if (repaint_func->notify)
repaint_func->notify (repaint_func->data);
g_free (repaint_func);
break;
}
l = l->next;
}
}
/**
* clutter_threads_add_repaint_func:
* @func: the function to be called within the paint cycle
* @data: data to be passed to the function, or %NULL
* @notify: function to be called when removing the repaint
* function, or %NULL
*
* Adds a function to be called whenever Clutter is processing a new
* frame.
*
* If the function returns %FALSE it is automatically removed from the
* list of repaint functions and will not be called again.
*
* This function is guaranteed to be called from within the same thread
* that called clutter_main(), and while the Clutter lock is being held;
* the function will be called within the main loop, so it is imperative
* that it does not block, otherwise the frame time budget may be lost.
*
* A repaint function is useful to ensure that an update of the scenegraph
* is performed before the scenegraph is repainted. By default, a repaint
* function added using this function will be invoked prior to the frame
* being processed.
*
* Adding a repaint function does not automatically ensure that a new
* frame will be queued.
*
* When the repaint function is removed (either because it returned %FALSE
* or because clutter_threads_remove_repaint_func() has been called) the
* @notify function will be called, if any is set.
*
* See also: clutter_threads_add_repaint_func_full()
*
* Return value: the ID (greater than 0) of the repaint function. You
* can use the returned integer to remove the repaint function by
* calling clutter_threads_remove_repaint_func().
*/
guint
clutter_threads_add_repaint_func (GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
return clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
func,
data, notify);
}
/**
* clutter_threads_add_repaint_func_full:
* @flags: flags for the repaint function
* @func: the function to be called within the paint cycle
* @data: data to be passed to the function, or %NULL
* @notify: function to be called when removing the repaint
* function, or %NULL
*
* Adds a function to be called whenever Clutter is processing a new
* frame.
*
* If the function returns %FALSE it is automatically removed from the
* list of repaint functions and will not be called again.
*
* This function is guaranteed to be called from within the same thread
* that called clutter_main(), and while the Clutter lock is being held;
* the function will be called within the main loop, so it is imperative
* that it does not block, otherwise the frame time budget may be lost.
*
* A repaint function is useful to ensure that an update of the scenegraph
* is performed before the scenegraph is repainted. The @flags passed to this
* function will determine the section of the frame processing that will
* result in @func being called.
*
* Adding a repaint function does not automatically ensure that a new
* frame will be queued.
*
* When the repaint function is removed (either because it returned %FALSE
* or because clutter_threads_remove_repaint_func() has been called) the
* @notify function will be called, if any is set.
*
* Return value: the ID (greater than 0) of the repaint function. You
* can use the returned integer to remove the repaint function by
* calling clutter_threads_remove_repaint_func().
*/
guint
clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags,
GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
ClutterMainContext *context;
ClutterRepaintFunction *repaint_func;
g_return_val_if_fail (func != NULL, 0);
context = _clutter_context_get_default ();
repaint_func = g_new0 (ClutterRepaintFunction, 1);
repaint_func->id = context->last_repaint_id++;
repaint_func->flags = flags;
repaint_func->func = func;
repaint_func->data = data;
repaint_func->notify = notify;
context->repaint_funcs = g_list_prepend (context->repaint_funcs,
repaint_func);
return repaint_func->id;
}
/*
* _clutter_run_repaint_functions:
* @flags: only run the repaint functions matching the passed flags
*
* Executes the repaint functions added using the
* clutter_threads_add_repaint_func() function.
*
* Must be called with the Clutter thread lock held.
*/
void
_clutter_run_repaint_functions (ClutterRepaintFlags flags)
{
ClutterMainContext *context = _clutter_context_get_default ();
ClutterRepaintFunction *repaint_func;
GList *invoke_list, *reinvoke_list, *l;
if (context->repaint_funcs == NULL)
return;
/* steal the list */
invoke_list = context->repaint_funcs;
context->repaint_funcs = NULL;
reinvoke_list = NULL;
/* consume the whole list while we execute the functions */
while (invoke_list != NULL)
{
gboolean res = FALSE;
repaint_func = invoke_list->data;
l = invoke_list;
invoke_list = g_list_remove_link (invoke_list, invoke_list);
g_list_free (l);
if ((repaint_func->flags & flags) != 0)
res = repaint_func->func (repaint_func->data);
else
res = TRUE;
if (res)
reinvoke_list = g_list_prepend (reinvoke_list, repaint_func);
else
{
if (repaint_func->notify != NULL)
repaint_func->notify (repaint_func->data);
g_free (repaint_func);
}
}
if (context->repaint_funcs != NULL)
{
context->repaint_funcs = g_list_concat (context->repaint_funcs,
g_list_reverse (reinvoke_list));
}
else
context->repaint_funcs = g_list_reverse (reinvoke_list);
}
/**
* clutter_get_default_text_direction:
*
* Retrieves the default direction for the text. The text direction is
* determined by the locale and/or by the `CLUTTER_TEXT_DIRECTION`
2011-09-12 13:12:14 +01:00
* environment variable.
*
* The default text direction can be overridden on a per-actor basis by using
* [method@Actor.set_text_direction].
*
* Return value: the default text direction
*/
ClutterTextDirection
clutter_get_default_text_direction (void)
{
return clutter_text_direction;
}
/*< private >
* clutter_clear_events_queue:
*
* Clears the events queue stored in the main context.
*/
void
_clutter_clear_events_queue (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
ClutterEvent *event;
GAsyncQueue *events_queue;
if (!context->events_queue)
return;
g_async_queue_lock (context->events_queue);
while ((event = g_async_queue_try_pop_unlocked (context->events_queue)))
clutter_event_free (event);
events_queue = context->events_queue;
context->events_queue = NULL;
g_async_queue_unlock (events_queue);
g_async_queue_unref (events_queue);
}
/**
* clutter_add_debug_flags: (skip)
*
* Adds the debug flags passed to the list of debug flags.
*/
void
clutter_add_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_debug_flags |= debug_flags;
clutter_paint_debug_flags |= draw_flags;
clutter_pick_debug_flags |= pick_flags;
}
/**
* clutter_remove_debug_flags: (skip)
*
* Removes the debug flags passed from the list of debug flags.
*/
void
clutter_remove_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_debug_flags &= ~debug_flags;
clutter_paint_debug_flags &= ~draw_flags;
clutter_pick_debug_flags &= ~pick_flags;
}
void
clutter_debug_set_max_render_time_constant (int max_render_time_constant_us)
{
clutter_max_render_time_constant_us = max_render_time_constant_us;
}
void
clutter_get_debug_flags (ClutterDebugFlag *debug_flags,
ClutterDrawDebugFlag *draw_flags,
ClutterPickDebugFlag *pick_flags)
{
if (debug_flags)
*debug_flags = clutter_debug_flags;
if (draw_flags)
*draw_flags = clutter_paint_debug_flags;
if (pick_flags)
*pick_flags = clutter_pick_debug_flags;
}
void
_clutter_set_sync_to_vblank (gboolean sync_to_vblank)
{
clutter_sync_to_vblank = !!sync_to_vblank;
}
void
_clutter_debug_messagev (const char *format,
va_list var_args)
{
static gint64 last_debug_stamp;
gchar *stamp, *fmt;
gint64 cur_time, debug_stamp;
cur_time = g_get_monotonic_time ();
/* if the last debug message happened less than a second ago, just
* show the increments instead of the full timestamp
*/
if (last_debug_stamp == 0 ||
cur_time - last_debug_stamp >= G_USEC_PER_SEC)
{
debug_stamp = cur_time;
last_debug_stamp = debug_stamp;
stamp = g_strdup_printf ("[%16" G_GINT64_FORMAT "]", debug_stamp);
}
else
{
debug_stamp = cur_time - last_debug_stamp;
stamp = g_strdup_printf ("[%+16" G_GINT64_FORMAT "]", debug_stamp);
}
fmt = g_strconcat (stamp, ":", format, NULL);
g_free (stamp);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, var_args);
g_free (fmt);
}
void
_clutter_debug_message (const char *format, ...)
{
va_list args;
va_start (args, format);
_clutter_debug_messagev (format, args);
va_end (args);
}
gboolean
_clutter_diagnostic_enabled (void)
{
static const char *clutter_enable_diagnostic = NULL;
if (G_UNLIKELY (clutter_enable_diagnostic == NULL))
{
clutter_enable_diagnostic = g_getenv ("CLUTTER_ENABLE_DIAGNOSTIC");
if (clutter_enable_diagnostic == NULL)
clutter_enable_diagnostic = "0";
}
return *clutter_enable_diagnostic != '0';
}
void
_clutter_diagnostic_message (const char *format, ...)
{
va_list args;
char *fmt;
fmt = g_strconcat ("[DIAGNOSTIC]: ", format, NULL);
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, args);
va_end (args);
g_free (fmt);
}