From 1a5275cdb099e3b15f82cabdd55d2eb6c5196c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 11 Jul 2019 13:32:01 +0200 Subject: [PATCH 08/28] clutter/event: Use all-events Hash table as a Set with auto deletion Avoid allocating memory for the value, since we don't use it, just add the key to the table, and check for its presence. Use a custom free function to free the event data and unref the GOBjects, so that in clutter_event_free we don't have to both check for the event presence in the set, clear the data and eventually remove it from the table, but we can just rely on a single g_hash_table_remove() call. This required to change the event data free/copy functions signatures so that we can pass to them the platform data directly, otherwise we might try to call get_platform_data on an even that has already been removed from the table, and thus that is not considered allocated anymore, causing a leak. https://gitlab.gnome.org/GNOME/mutter/merge_requests/682 --- clutter/clutter/clutter-backend-private.h | 16 +++---- clutter/clutter/clutter-backend.c | 21 ++++----- .../clutter/clutter-device-manager-private.h | 7 ++- clutter/clutter/clutter-event.c | 45 +++++++++++-------- .../evdev/clutter-device-manager-evdev.c | 15 +++---- .../clutter/x11/clutter-device-manager-xi2.c | 17 +++---- 6 files changed, 60 insertions(+), 61 deletions(-) diff --git a/clutter/clutter/clutter-backend-private.h b/clutter/clutter/clutter-backend-private.h index 864d896a3..2438f83e1 100644 --- a/clutter/clutter/clutter-backend-private.h +++ b/clutter/clutter/clutter-backend-private.h @@ -63,100 +63,98 @@ struct _ClutterBackend }; struct _ClutterBackendClass { /*< private >*/ GObjectClass parent_class; /* vfuncs */ gboolean (* pre_parse) (ClutterBackend *backend, GError **error); gboolean (* post_parse) (ClutterBackend *backend, GError **error); ClutterStageWindow * (* create_stage) (ClutterBackend *backend, ClutterStage *wrapper, GError **error); void (* init_events) (ClutterBackend *backend); void (* init_features) (ClutterBackend *backend); void (* add_options) (ClutterBackend *backend, GOptionGroup *group); ClutterFeatureFlags (* get_features) (ClutterBackend *backend); CoglRenderer * (* get_renderer) (ClutterBackend *backend, GError **error); CoglDisplay * (* get_display) (ClutterBackend *backend, CoglRenderer *renderer, CoglSwapChain *swap_chain, GError **error); gboolean (* create_context) (ClutterBackend *backend, GError **error); ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend); - void (* copy_event_data) (ClutterBackend *backend, - const ClutterEvent *src, - ClutterEvent *dest); - void (* free_event_data) (ClutterBackend *backend, - ClutterEvent *event); + gpointer (* copy_event_data) (ClutterBackend *backend, + gpointer data); + void (* free_event_data) (ClutterBackend *backend, + gpointer data); gboolean (* translate_event) (ClutterBackend *backend, gpointer native, ClutterEvent *event); PangoDirection (* get_keymap_direction) (ClutterBackend *backend); void (* bell_notify) (ClutterBackend *backend); /* signals */ void (* resolution_changed) (ClutterBackend *backend); void (* font_changed) (ClutterBackend *backend); void (* settings_changed) (ClutterBackend *backend); }; ClutterBackend * _clutter_create_backend (void); ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend, ClutterStage *wrapper, GError **error); gboolean _clutter_backend_create_context (ClutterBackend *backend, GError **error); void _clutter_backend_add_options (ClutterBackend *backend, GOptionGroup *group); gboolean _clutter_backend_pre_parse (ClutterBackend *backend, GError **error); gboolean _clutter_backend_post_parse (ClutterBackend *backend, GError **error); void _clutter_backend_init_events (ClutterBackend *backend); -void _clutter_backend_copy_event_data (ClutterBackend *backend, - const ClutterEvent *src, - ClutterEvent *dest); +gpointer _clutter_backend_copy_event_data (ClutterBackend *backend, + const gpointer data); void _clutter_backend_free_event_data (ClutterBackend *backend, - ClutterEvent *event); + gpointer data); gboolean _clutter_backend_translate_event (ClutterBackend *backend, gpointer native, ClutterEvent *event); CLUTTER_AVAILABLE_IN_MUTTER void _clutter_backend_add_event_translator (ClutterBackend *backend, ClutterEventTranslator *translator); void _clutter_backend_remove_event_translator (ClutterBackend *backend, ClutterEventTranslator *translator); ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend); gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend, PangoFontDescription *font_desc); gint32 _clutter_backend_get_units_serial (ClutterBackend *backend); PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend); CLUTTER_AVAILABLE_IN_MUTTER void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend); void clutter_set_allowed_drivers (const char *drivers); void clutter_try_set_windowing_backend (const char *drivers); G_END_DECLS #endif /* __CLUTTER_BACKEND_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c index 69aeec5eb..41ea3daed 100644 --- a/clutter/clutter/clutter-backend.c +++ b/clutter/clutter/clutter-backend.c @@ -804,96 +804,97 @@ _clutter_backend_get_features (ClutterBackend *backend) return klass->get_features (backend); return 0; } void _clutter_backend_init_events (ClutterBackend *backend) { ClutterBackendClass *klass; g_assert (CLUTTER_IS_BACKEND (backend)); klass = CLUTTER_BACKEND_GET_CLASS (backend); klass->init_events (backend); } gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend, PangoFontDescription *font_desc) { /* recompute for the font description, but do not cache the result */ if (font_desc != NULL) return get_units_per_em (backend, font_desc); if (backend->units_per_em < 0) backend->units_per_em = get_units_per_em (backend, NULL); return backend->units_per_em; } -void -_clutter_backend_copy_event_data (ClutterBackend *backend, - const ClutterEvent *src, - ClutterEvent *dest) +gpointer +_clutter_backend_copy_event_data (ClutterBackend *backend, + gpointer data) { ClutterEventExtenderInterface *iface; ClutterBackendClass *klass; klass = CLUTTER_BACKEND_GET_CLASS (backend); if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager)) { iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager); - iface->copy_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager), - src, dest); + return iface->copy_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager), + data); } else if (klass->copy_event_data != NULL) - klass->copy_event_data (backend, src, dest); + return klass->copy_event_data (backend, data); + + return NULL; } void _clutter_backend_free_event_data (ClutterBackend *backend, - ClutterEvent *event) + gpointer data) { ClutterEventExtenderInterface *iface; ClutterBackendClass *klass; klass = CLUTTER_BACKEND_GET_CLASS (backend); if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager)) { iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager); iface->free_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager), - event); + data); } else if (klass->free_event_data != NULL) - klass->free_event_data (backend, event); + klass->free_event_data (backend, data); } /** * clutter_get_default_backend: * * Retrieves the default #ClutterBackend used by Clutter. The * #ClutterBackend holds backend-specific configuration options. * * Return value: (transfer none): the default backend. You should * not ref or unref the returned object. Applications should rarely * need to use this. * * Since: 0.4 */ ClutterBackend * clutter_get_default_backend (void) { ClutterMainContext *clutter_context; clutter_context = _clutter_context_get_default (); return clutter_context->backend; } /** * clutter_backend_set_double_click_time: * @backend: a #ClutterBackend * @msec: milliseconds between two button press events * * Sets the maximum time between two button press events, used to diff --git a/clutter/clutter/clutter-device-manager-private.h b/clutter/clutter/clutter-device-manager-private.h index 2364fd27c..6b2c20c72 100644 --- a/clutter/clutter/clutter-device-manager-private.h +++ b/clutter/clutter/clutter-device-manager-private.h @@ -159,65 +159,64 @@ struct _ClutterInputDeviceClass ClutterInputDeviceTool *tool); gboolean (* is_mode_switch_button) (ClutterInputDevice *device, guint group, guint button); gint (* get_group_n_modes) (ClutterInputDevice *device, gint group); gboolean (* is_grouped) (ClutterInputDevice *device, ClutterInputDevice *other_device); /* Keyboard accessbility */ void (* process_kbd_a11y_event) (ClutterEvent *event, ClutterInputDevice *device, ClutterEmitInputDeviceEvent emit_event_func); }; /* Platform-dependent interface */ typedef struct _ClutterEventExtender ClutterEventExtender; typedef struct _ClutterEventExtenderInterface ClutterEventExtenderInterface; #define CLUTTER_TYPE_EVENT_EXTENDER (clutter_event_extender_get_type ()) #define CLUTTER_EVENT_EXTENDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtender)) #define CLUTTER_IS_EVENT_EXTENDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLUTTER_TYPE_EVENT_EXTENDER)) #define CLUTTER_EVENT_EXTENDER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtenderInterface)) struct _ClutterEventExtenderInterface { GTypeInterface g_iface; - void (* copy_event_data) (ClutterEventExtender *event_extender, - const ClutterEvent *src, - ClutterEvent *dest); + gpointer (* copy_event_data) (ClutterEventExtender *event_extender, + gpointer data); void (* free_event_data) (ClutterEventExtender *event_extender, - ClutterEvent *event); + gpointer data); }; GType clutter_event_extender_get_type (void) G_GNUC_CONST; /* device manager */ void _clutter_device_manager_add_device (ClutterDeviceManager *device_manager, ClutterInputDevice *device); void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager, ClutterInputDevice *device); void _clutter_device_manager_update_devices (ClutterDeviceManager *device_manager); void _clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manager, ClutterStage *stage); ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceManager *device_manager); void _clutter_device_manager_compress_motion (ClutterDeviceManager *device_manger, ClutterEvent *event, const ClutterEvent *to_discard); /* input device */ gboolean _clutter_input_device_has_sequence (ClutterInputDevice *device, ClutterEventSequence *sequence); void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, ClutterEvent *event); void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); void _clutter_input_device_set_coords (ClutterInputDevice *device, ClutterEventSequence *sequence, gfloat x, gfloat y, ClutterStage *stage); diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c index 1b21b6a97..60bdd325c 100644 --- a/clutter/clutter/clutter-event.c +++ b/clutter/clutter/clutter-event.c @@ -77,61 +77,73 @@ typedef struct _ClutterEventFilter { static GHashTable *all_events = NULL; G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event, clutter_event_copy, clutter_event_free); static ClutterEventSequence * clutter_event_sequence_copy (ClutterEventSequence *sequence) { /* Nothing to copy here */ return sequence; } static void clutter_event_sequence_free (ClutterEventSequence *sequence) { /* Nothing to free here */ } G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence, clutter_event_sequence_copy, clutter_event_sequence_free); static gboolean is_event_allocated (const ClutterEvent *event) { if (all_events == NULL) return FALSE; - return g_hash_table_lookup (all_events, event) != NULL; + return g_hash_table_contains (all_events, event); +} + +static void +clutter_event_private_data_free (ClutterEvent *event) +{ + ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; + + _clutter_backend_free_event_data (clutter_get_default_backend (), + real_event->platform_data); + + g_clear_object (&real_event->device); + g_clear_object (&real_event->source_device); } /* * _clutter_event_get_platform_data: * @event: a #ClutterEvent * * Retrieves the pointer to platform-specific data inside an event * * Return value: a pointer to platform-specific data * * Since: 1.4 */ gpointer _clutter_event_get_platform_data (const ClutterEvent *event) { if (!is_event_allocated (event)) return NULL; return ((ClutterEventPrivate *) event)->platform_data; } /*< private > * _clutter_event_set_platform_data: * @event: a #ClutterEvent * @data: a pointer to platform-specific data * * Sets the pointer to platform-specific data inside an event * * Since: 1.4 */ @@ -1303,200 +1315,195 @@ clutter_event_get_device_tool (const ClutterEvent *event) if (is_event_allocated (event)) { ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; return real_event->tool; } return NULL; } /** * clutter_event_new: * @type: The type of event. * * Creates a new #ClutterEvent of the specified type. * * Return value: (transfer full): A newly allocated #ClutterEvent. */ ClutterEvent * clutter_event_new (ClutterEventType type) { ClutterEvent *new_event; ClutterEventPrivate *priv; priv = g_slice_new0 (ClutterEventPrivate); new_event = (ClutterEvent *) priv; new_event->type = new_event->any.type = type; if (G_UNLIKELY (all_events == NULL)) - all_events = g_hash_table_new (NULL, NULL); + { + all_events = + g_hash_table_new_full (NULL, NULL, + (GDestroyNotify) clutter_event_private_data_free, + NULL); + } - g_hash_table_replace (all_events, priv, GUINT_TO_POINTER (1)); + g_hash_table_add (all_events, priv); return new_event; } /** * clutter_event_copy: * @event: A #ClutterEvent. * * Copies @event. * * Return value: (transfer full): A newly allocated #ClutterEvent */ ClutterEvent * clutter_event_copy (const ClutterEvent *event) { ClutterEvent *new_event; ClutterEventPrivate *new_real_event; ClutterInputDevice *device; gint n_axes = 0; g_return_val_if_fail (event != NULL, NULL); new_event = clutter_event_new (CLUTTER_NOTHING); new_real_event = (ClutterEventPrivate *) new_event; *new_event = *event; if (is_event_allocated (event)) { ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; g_set_object (&new_real_event->device, real_event->device); g_set_object (&new_real_event->source_device, real_event->source_device); new_real_event->delta_x = real_event->delta_x; new_real_event->delta_y = real_event->delta_y; new_real_event->is_pointer_emulated = real_event->is_pointer_emulated; new_real_event->base_state = real_event->base_state; new_real_event->button_state = real_event->button_state; new_real_event->latched_state = real_event->latched_state; new_real_event->locked_state = real_event->locked_state; new_real_event->tool = real_event->tool; + new_real_event->platform_data = + _clutter_backend_copy_event_data (clutter_get_default_backend (), + real_event->platform_data); } device = clutter_event_get_device (event); if (device != NULL) n_axes = clutter_input_device_get_n_axes (device); switch (event->type) { case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: if (event->button.axes != NULL) new_event->button.axes = g_memdup (event->button.axes, sizeof (gdouble) * n_axes); break; case CLUTTER_SCROLL: if (event->scroll.axes != NULL) new_event->scroll.axes = g_memdup (event->scroll.axes, sizeof (gdouble) * n_axes); break; case CLUTTER_MOTION: if (event->motion.axes != NULL) new_event->motion.axes = g_memdup (event->motion.axes, sizeof (gdouble) * n_axes); break; case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_CANCEL: if (event->touch.axes != NULL) new_event->touch.axes = g_memdup (event->touch.axes, sizeof (gdouble) * n_axes); break; default: break; } - if (is_event_allocated (event)) - _clutter_backend_copy_event_data (clutter_get_default_backend (), - event, - new_event); - return new_event; } /** * clutter_event_free: * @event: A #ClutterEvent. * * Frees all resources used by @event. */ void clutter_event_free (ClutterEvent *event) { if (G_LIKELY (event != NULL)) { - _clutter_backend_free_event_data (clutter_get_default_backend (), event); - - if (is_event_allocated (event)) - { - ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; - - g_clear_object (&real_event->device); - g_clear_object (&real_event->source_device); - } - switch (event->type) { case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: g_free (event->button.axes); break; case CLUTTER_MOTION: g_free (event->motion.axes); break; case CLUTTER_SCROLL: g_free (event->scroll.axes); break; case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_CANCEL: g_free (event->touch.axes); break; default: break; } - g_hash_table_remove (all_events, event); + if (G_LIKELY (all_events)) + g_hash_table_remove (all_events, event); + g_slice_free (ClutterEventPrivate, (ClutterEventPrivate *) event); } } /** * clutter_event_get: * * Pops an event off the event queue. Applications should not need to call * this. * * Return value: A #ClutterEvent or NULL if queue empty * * Since: 0.4 */ ClutterEvent * clutter_event_get (void) { ClutterMainContext *context = _clutter_context_get_default (); if (context->events_queue == NULL) return NULL; if (g_queue_is_empty (context->events_queue)) return NULL; return g_queue_pop_tail (context->events_queue); } /** * clutter_event_peek: diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c index f2aeda696..11cb4781a 100644 --- a/clutter/clutter/evdev/clutter-device-manager-evdev.c +++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c @@ -128,77 +128,76 @@ static gchar * evdev_seat_id; #ifdef CLUTTER_ENABLE_DEBUG static const char *device_type_str[] = { "pointer", /* CLUTTER_POINTER_DEVICE */ "keyboard", /* CLUTTER_KEYBOARD_DEVICE */ "extension", /* CLUTTER_EXTENSION_DEVICE */ "joystick", /* CLUTTER_JOYSTICK_DEVICE */ "tablet", /* CLUTTER_TABLET_DEVICE */ "touchpad", /* CLUTTER_TOUCHPAD_DEVICE */ "touchscreen", /* CLUTTER_TOUCHSCREEN_DEVICE */ "pen", /* CLUTTER_PEN_DEVICE */ "eraser", /* CLUTTER_ERASER_DEVICE */ "cursor", /* CLUTTER_CURSOR_DEVICE */ "pad", /* CLUTTER_PAD_DEVICE */ }; #endif /* CLUTTER_ENABLE_DEBUG */ /* * ClutterEventSource management * * The device manager is responsible for managing the GSource when devices * appear and disappear from the system. */ static const char *option_xkb_layout = "us"; static const char *option_xkb_variant = ""; static const char *option_xkb_options = ""; static void clutter_device_manager_evdev_copy_event_data (ClutterEventExtender *event_extender, - const ClutterEvent *src, - ClutterEvent *dest) + gpointer data) { - ClutterEventEvdev *event_evdev; + ClutterEventEvdev *event_evdev = data; - event_evdev = _clutter_event_get_platform_data (src); if (event_evdev != NULL) - _clutter_event_set_platform_data (dest, _clutter_event_evdev_copy (event_evdev)); + return _clutter_event_evdev_copy (event_evdev); + + return NULL; } static void clutter_device_manager_evdev_free_event_data (ClutterEventExtender *event_extender, - ClutterEvent *event) + gpointer data) { - ClutterEventEvdev *event_evdev; + ClutterEventEvdev *event_evdev = data; - event_evdev = _clutter_event_get_platform_data (event); if (event_evdev != NULL) _clutter_event_evdev_free (event_evdev); } static void clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface) { iface->copy_event_data = clutter_device_manager_evdev_copy_event_data; iface->free_event_data = clutter_device_manager_evdev_free_event_data; } /* * ClutterEventSource for reading input devices */ struct _ClutterEventSource { GSource source; ClutterDeviceManagerEvdev *manager_evdev; GPollFD event_poll_fd; }; static void process_events (ClutterDeviceManagerEvdev *manager_evdev); static gboolean clutter_event_prepare (GSource *source, gint *timeout) { diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c index 0718cd975..35e3808e7 100644 --- a/clutter/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/clutter/x11/clutter-device-manager-xi2.c @@ -63,79 +63,74 @@ static const char *clutter_input_axis_atom_names[] = { "Abs Tilt Y", /* CLUTTER_INPUT_AXIS_YTILT */ "Abs Wheel", /* CLUTTER_INPUT_AXIS_WHEEL */ "Abs Distance", /* CLUTTER_INPUT_AXIS_DISTANCE */ }; #define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names) enum { PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */ PAD_AXIS_STRIP1 = PAD_AXIS_FIRST, PAD_AXIS_STRIP2, PAD_AXIS_RING1, PAD_AXIS_RING2, }; static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, }; static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface); static void clutter_event_extender_iface_init (ClutterEventExtenderInterface *iface); #define clutter_device_manager_xi2_get_type _clutter_device_manager_xi2_get_type G_DEFINE_TYPE_WITH_CODE (ClutterDeviceManagerXI2, clutter_device_manager_xi2, CLUTTER_TYPE_DEVICE_MANAGER, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR, clutter_event_translator_iface_init) G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_EXTENDER, clutter_event_extender_iface_init)) -static void +static gpointer clutter_device_manager_x11_copy_event_data (ClutterEventExtender *event_extender, - const ClutterEvent *src, - ClutterEvent *dest) + gpointer event_x11) { - gpointer event_x11; - - event_x11 = _clutter_event_get_platform_data (src); if (event_x11 != NULL) - _clutter_event_set_platform_data (dest, _clutter_event_x11_copy (event_x11)); + return _clutter_event_x11_copy (event_x11); + + return NULL; } static void clutter_device_manager_x11_free_event_data (ClutterEventExtender *event_extender, - ClutterEvent *event) + gpointer event_x11) { - gpointer event_x11; - - event_x11 = _clutter_event_get_platform_data (event); if (event_x11 != NULL) _clutter_event_x11_free (event_x11); } static void clutter_event_extender_iface_init (ClutterEventExtenderInterface *iface) { iface->copy_event_data = clutter_device_manager_x11_copy_event_data; iface->free_event_data = clutter_device_manager_x11_free_event_data; } static void translate_valuator_class (Display *xdisplay, ClutterInputDevice *device, XIValuatorClassInfo *class) { static gboolean atoms_initialized = FALSE; ClutterInputAxis i, axis = CLUTTER_INPUT_AXIS_IGNORE; if (G_UNLIKELY (!atoms_initialized)) { XInternAtoms (xdisplay, (char **) clutter_input_axis_atom_names, N_AXIS_ATOMS, False, clutter_input_axis_atoms); atoms_initialized = TRUE; } for (i = 0; -- 2.26.2