[mutter/wip/barriers: 4/4] barrier: Add signals for when a barrier gets hit
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/barriers: 4/4] barrier: Add signals for when a barrier gets hit
- Date: Sat, 3 Nov 2012 23:56:47 +0000 (UTC)
commit 3720d88235c39171d252ccaf5260a97a336489dc
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Mon Jul 30 15:57:53 2012 -0300
barrier: Add signals for when a barrier gets hit
We want to know when a barrier gets hit so that we can implement
message tray pressure.
https://bugzilla.gnome.org/show_bug.cgi?id=677215
src/core/barrier.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
src/core/device-map-xi2.c | 2 +-
src/core/devices-xi2.c | 3 +
src/core/display-private.h | 7 +++
src/core/display.c | 10 ++++
src/meta/barrier.h | 16 +++++++
6 files changed, 138 insertions(+), 1 deletions(-)
---
diff --git a/src/core/barrier.c b/src/core/barrier.c
index 254d4e0..ee8738d 100644
--- a/src/core/barrier.c
+++ b/src/core/barrier.c
@@ -4,6 +4,7 @@
#include <glib-object.h>
+#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xfixes.h>
#include <meta/util.h>
#include <meta/barrier.h>
@@ -31,6 +32,14 @@ enum {
static GParamSpec *obj_props[PROP_LAST];
+enum {
+ HIT,
+
+ LAST_SIGNAL,
+};
+
+static guint obj_signals[LAST_SIGNAL];
+
struct _MetaBarrierPrivate
{
MetaDisplay *display;
@@ -183,6 +192,7 @@ meta_barrier_activate (MetaBarrier *barrier)
priv->x2, priv->y2,
priv->directions,
n_devices, devices);
+ g_hash_table_insert (priv->display->barriers, GINT_TO_POINTER (priv->barrier), g_object_ref (barrier));
}
static void
@@ -255,6 +265,24 @@ meta_barrier_class_init (MetaBarrierClass *klass)
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
+ /**
+ * MetaBarrier::hit:
+ * @barrier: The #MetaBarrier that was hit
+ * @event: A #MetaBarrierEvent that has the details of how
+ * things were hit.
+ *
+ * When a pointer barrier is hit, this will trigger. This
+ * requires an XI2-enabled server.
+ */
+ obj_signals[HIT] =
+ g_signal_new ("hit",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ META_TYPE_BARRIER_HIT_EVENT);
+
g_type_class_add_private (object_class, sizeof(MetaBarrierPrivate));
}
@@ -276,6 +304,7 @@ meta_barrier_destroy (MetaBarrier *barrier)
return;
XFixesDestroyPointerBarrier (dpy, priv->barrier);
+ g_hash_table_remove (priv->display->barriers, GINT_TO_POINTER (priv->barrier));
priv->barrier = 0;
}
@@ -284,3 +313,75 @@ meta_barrier_init (MetaBarrier *barrier)
{
barrier->priv = GET_PRIVATE (barrier);
}
+
+static void
+meta_barrier_hit (MetaBarrier *barrier,
+ XIBarrierNotifyEvent *xevent)
+{
+ MetaBarrierHitEvent *event = g_slice_new0 (MetaBarrierHitEvent);
+
+ event->ref_count = 1;
+ event->event_id = xevent->event_id;
+ event->dt = xevent->dt;
+
+ event->x = xevent->x;
+ event->y = xevent->y;
+ event->dx = xevent->dx;
+ event->dy = xevent->dy;
+ event->raw_dx = xevent->raw_dx;
+ event->raw_dy = xevent->raw_dy;
+
+ g_signal_emit (barrier, obj_signals[HIT], 0, event);
+}
+
+gboolean
+meta_display_process_barrier_event (MetaDisplay *display,
+ XEvent *ev)
+{
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ MetaBarrier *barrier;
+ XIBarrierNotifyEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ xev = (XIBarrierNotifyEvent *) ev->xcookie.data;
+
+ if (xev->evtype != XI_BarrierHitNotify)
+ return FALSE;
+
+ barrier = g_hash_table_lookup (display->barriers, GINT_TO_POINTER (xev->barrier));
+ if (barrier != NULL)
+ {
+ meta_barrier_hit (barrier, xev);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static MetaBarrierHitEvent *
+meta_barrier_hit_event_ref (MetaBarrierHitEvent *event)
+{
+ g_return_val_if_fail (event != NULL, NULL);
+ g_return_val_if_fail (event->ref_count > 0, NULL);
+
+ g_atomic_int_inc ((volatile int *)&event->ref_count);
+ return event;
+}
+
+static void
+meta_barrier_hit_event_unref (MetaBarrierHitEvent *event)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (event->ref_count > 0);
+
+ if (g_atomic_int_dec_and_test ((volatile int *)&event->ref_count))
+ g_slice_free (MetaBarrierHitEvent, event);
+}
+
+G_DEFINE_BOXED_TYPE (MetaBarrierHitEvent,
+ meta_barrier_hit_event,
+ meta_barrier_hit_event_ref,
+ meta_barrier_hit_event_unref)
diff --git a/src/core/device-map-xi2.c b/src/core/device-map-xi2.c
index 1d778b8..bc99006 100644
--- a/src/core/device-map-xi2.c
+++ b/src/core/device-map-xi2.c
@@ -28,7 +28,7 @@
#include "input-events.h"
#define XINPUT2_VERSION_MAJOR 2
-#define XINPUT2_VERSION_MINOR 2
+#define XINPUT2_VERSION_MINOR 3
G_DEFINE_TYPE (MetaDeviceMapXI2, meta_device_map_xi2, META_TYPE_DEVICE_MAP)
diff --git a/src/core/devices-xi2.c b/src/core/devices-xi2.c
index 303c2d4..390e1b4 100644
--- a/src/core/devices-xi2.c
+++ b/src/core/devices-xi2.c
@@ -107,6 +107,9 @@ meta_device_xi2_translate_event_mask (guint evmask,
}
#endif
+ /* XXX: Find a way to do this better. */
+ XISetMask (mask, XI_BarrierHitNotify);
+
return mask;
}
diff --git a/src/core/display-private.h b/src/core/display-private.h
index b321847..dacea70 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -40,6 +40,7 @@
#include "keybindings-private.h"
#include "device-map-private.h"
#include <meta/prefs.h>
+#include <meta/barrier.h>
#ifdef HAVE_STARTUP_NOTIFICATION
#include <libsn/sn.h>
@@ -279,6 +280,9 @@ struct _MetaDisplay
unsigned int meta_mask;
MetaKeyCombo overlay_key_combo;
gboolean overlay_key_only_pressed;
+
+ /* barriers */
+ GHashTable *barriers;
/* Monitor cache */
unsigned int monitor_cache_invalidated : 1;
@@ -321,6 +325,7 @@ struct _MetaDisplay
int damage_error_base;
int xfixes_event_base;
int xfixes_error_base;
+ int xfixes_major_opcode;
#ifdef HAVE_STARTUP_NOTIFICATION
SnDisplay *sn_display;
@@ -509,5 +514,7 @@ MetaGrabInfo * meta_display_get_grab_info (MetaDisplay *display,
MetaFocusInfo * meta_display_get_focus_info (MetaDisplay *display,
MetaDevice *device);
+gboolean meta_display_process_barrier_event (MetaDisplay *display,
+ XEvent *ev);
#endif
diff --git a/src/core/display.c b/src/core/display.c
index 7479367..8a7686d 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -794,6 +794,10 @@ meta_display_open (void)
meta_verbose ("Not compiled with Xcursor support\n");
#endif /* !HAVE_XCURSOR */
+ the_display->barriers = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL, g_object_unref);
+
/* Create the leader window here. Set its properties and
* use the timestamp from one of the PropertyNotify events
* that will follow.
@@ -1988,6 +1992,12 @@ event_callback (XEvent *event,
filter_out_event = FALSE;
bypass_compositor = FALSE;
}
+ else if (display->have_xinput2 &&
+ meta_display_process_barrier_event (display, event))
+ {
+ filter_out_event = TRUE;
+ bypass_compositor = TRUE;
+ }
else
#endif
if (meta_input_event_get_type (display, event, &evtype))
diff --git a/src/meta/barrier.h b/src/meta/barrier.h
index 42460fc..97aae20 100644
--- a/src/meta/barrier.h
+++ b/src/meta/barrier.h
@@ -45,6 +45,22 @@ typedef enum {
META_BARRIER_DIRECTION_NEGATIVE_Y = (1L << 3),
} MetaBarrierDirection;
+typedef struct {
+ int ref_count;
+
+ int event_id;
+ int dt;
+ double x;
+ double y;
+ double dx;
+ double dy;
+ double raw_dx;
+ double raw_dy;
+} MetaBarrierHitEvent;
+
+#define META_TYPE_BARRIER_HIT_EVENT (meta_barrier_hit_event_get_type ())
+GType meta_barrier_hit_event_get_type (void) G_GNUC_CONST;
+
G_END_DECLS
#endif /* __META_BARRIER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]