barrier: Add a new Meta wrapper for pointer barriers

Currently, we have a few function wrappers in the shell for pointer
barriers. If we want to implement interactive features on barriers,
we need some sort of signal to be notified of the interactivity.
In that case, we need to make a more sophisticated object-based wrapper
for a pointer barrier. Add one, and stick it in mutter.

https://bugzilla.gnome.org/show_bug.cgi?id=677215
This commit is contained in:
Jasper St. Pierre 2012-07-30 15:54:03 -03:00
parent e914595062
commit 8b21df92f0
3 changed files with 296 additions and 0 deletions

View File

@ -33,6 +33,8 @@ mutter_built_sources = \
libmutter_la_SOURCES = \ libmutter_la_SOURCES = \
core/async-getprop.c \ core/async-getprop.c \
core/async-getprop.h \ core/async-getprop.h \
core/barrier.c \
meta/barrier.h \
core/bell.c \ core/bell.c \
core/bell.h \ core/bell.h \
core/boxes.c \ core/boxes.c \
@ -157,6 +159,7 @@ libmutter_la_LIBADD = $(MUTTER_LIBS)
# Headers installed for plugins; introspected information will # Headers installed for plugins; introspected information will
# be extracted into Mutter-<version>.gir # be extracted into Mutter-<version>.gir
libmutterinclude_base_headers = \ libmutterinclude_base_headers = \
meta/barrier.h \
meta/boxes.h \ meta/boxes.h \
meta/common.h \ meta/common.h \
meta/compositor-mutter.h \ meta/compositor-mutter.h \

243
src/core/barrier.c Normal file
View File

@ -0,0 +1,243 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
#include "config.h"
#include <glib-object.h>
#include <X11/extensions/Xfixes.h>
#include <meta/util.h>
#include <meta/barrier.h>
#include "display-private.h"
#include "mutter-enum-types.h"
#include "core.h"
G_DEFINE_TYPE (MetaBarrier, meta_barrier, G_TYPE_OBJECT)
enum {
PROP_0,
PROP_DISPLAY,
PROP_X1,
PROP_Y1,
PROP_X2,
PROP_Y2,
PROP_DIRECTIONS,
PROP_LAST,
};
static GParamSpec *obj_props[PROP_LAST];
struct _MetaBarrierPrivate
{
MetaDisplay *display;
int x1;
int y1;
int x2;
int y2;
MetaBarrierDirection directions;
PointerBarrier xbarrier;
};
static void
meta_barrier_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaBarrier *barrier = META_BARRIER (object);
MetaBarrierPrivate *priv = barrier->priv;
switch (prop_id)
{
case PROP_DISPLAY:
g_value_set_object (value, priv->display);
break;
case PROP_X1:
g_value_set_int (value, priv->x1);
break;
case PROP_Y1:
g_value_set_int (value, priv->y1);
break;
case PROP_X2:
g_value_set_int (value, priv->x2);
break;
case PROP_Y2:
g_value_set_int (value, priv->y2);
break;
case PROP_DIRECTIONS:
g_value_set_flags (value, priv->directions);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_barrier_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaBarrier *barrier = META_BARRIER (object);
MetaBarrierPrivate *priv = barrier->priv;
switch (prop_id)
{
case PROP_DISPLAY:
priv->display = g_value_get_object (value);
break;
case PROP_X1:
priv->x1 = g_value_get_int (value);
break;
case PROP_Y1:
priv->y1 = g_value_get_int (value);
break;
case PROP_X2:
priv->x2 = g_value_get_int (value);
break;
case PROP_Y2:
priv->y2 = g_value_get_int (value);
break;
case PROP_DIRECTIONS:
priv->directions = g_value_get_flags (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_barrier_dispose (GObject *object)
{
MetaBarrier *barrier = META_BARRIER (object);
MetaBarrierPrivate *priv = barrier->priv;
if (meta_barrier_is_active (barrier))
{
meta_bug ("MetaBarrier wrapper %p for X barrier %ld was destroyed"
" while the X barrier is still active.",
barrier, priv->xbarrier);
}
G_OBJECT_CLASS (meta_barrier_parent_class)->dispose (object);
}
gboolean
meta_barrier_is_active (MetaBarrier *barrier)
{
return barrier->priv->xbarrier != 0;
}
static void
meta_barrier_constructed (GObject *object)
{
MetaBarrier *barrier = META_BARRIER (object);
MetaBarrierPrivate *priv = barrier->priv;
Display *dpy;
Window root;
g_return_if_fail (priv->x1 == priv->x2 || priv->y1 == priv->y2);
if (priv->display == NULL)
{
g_warning ("A display must be provided when constructing a barrier.");
return;
}
dpy = priv->display->xdisplay;
root = DefaultRootWindow (dpy);
priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
priv->x1, priv->y1,
priv->x2, priv->y2,
priv->directions, 0, NULL);
G_OBJECT_CLASS (meta_barrier_parent_class)->constructed (object);
}
static void
meta_barrier_class_init (MetaBarrierClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = meta_barrier_get_property;
object_class->set_property = meta_barrier_set_property;
object_class->dispose = meta_barrier_dispose;
object_class->constructed = meta_barrier_constructed;
obj_props[PROP_DISPLAY] =
g_param_spec_object ("display",
"Display",
"The display to construct the pointer barrier on",
META_TYPE_DISPLAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
obj_props[PROP_X1] =
g_param_spec_int ("x1",
"X1",
"The first X coordinate of the barrier",
0, G_MAXSHORT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
obj_props[PROP_Y1] =
g_param_spec_int ("y1",
"Y1",
"The first Y coordinate of the barrier",
0, G_MAXSHORT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
obj_props[PROP_X2] =
g_param_spec_int ("x2",
"X2",
"The second X coordinate of the barrier",
0, G_MAXSHORT, G_MAXSHORT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
obj_props[PROP_Y2] =
g_param_spec_int ("y2",
"Y2",
"The second Y coordinate of the barrier",
0, G_MAXSHORT, G_MAXSHORT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
obj_props[PROP_DIRECTIONS] =
g_param_spec_flags ("directions",
"Directions",
"A set of directions to let the pointer through",
META_TYPE_BARRIER_DIRECTION,
0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
g_type_class_add_private (object_class, sizeof(MetaBarrierPrivate));
}
void
meta_barrier_destroy (MetaBarrier *barrier)
{
MetaBarrierPrivate *priv = barrier->priv;
Display *dpy;
if (priv->display == NULL)
return;
dpy = priv->display->xdisplay;
if (!meta_barrier_is_active (barrier))
return;
XFixesDestroyPointerBarrier (dpy, priv->xbarrier);
priv->xbarrier = 0;
}
static void
meta_barrier_init (MetaBarrier *barrier)
{
barrier->priv = G_TYPE_INSTANCE_GET_PRIVATE (barrier, META_TYPE_BARRIER, MetaBarrierPrivate);
}

50
src/meta/barrier.h Normal file
View File

@ -0,0 +1,50 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
#ifndef __META_BARRIER_H__
#define __META_BARRIER_H__
#include <glib-object.h>
#include <meta/display.h>
G_BEGIN_DECLS
#define META_TYPE_BARRIER (meta_barrier_get_type ())
#define META_BARRIER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER, MetaBarrier))
#define META_BARRIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER, MetaBarrierClass))
#define META_IS_BARRIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER))
#define META_IS_BARRIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER))
#define META_BARRIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER, MetaBarrierClass))
typedef struct _MetaBarrier MetaBarrier;
typedef struct _MetaBarrierClass MetaBarrierClass;
typedef struct _MetaBarrierPrivate MetaBarrierPrivate;
struct _MetaBarrier
{
GObject parent;
MetaBarrierPrivate *priv;
};
struct _MetaBarrierClass
{
GObjectClass parent_class;
};
GType meta_barrier_get_type (void) G_GNUC_CONST;
gboolean meta_barrier_is_active (MetaBarrier *barrier);
void meta_barrier_destroy (MetaBarrier *barrier);
/* Keep in sync with XFixes */
typedef enum {
META_BARRIER_DIRECTION_POSITIVE_X = 1 << 0,
META_BARRIER_DIRECTION_POSITIVE_Y = 1 << 1,
META_BARRIER_DIRECTION_NEGATIVE_X = 1 << 2,
META_BARRIER_DIRECTION_NEGATIVE_Y = 1 << 3,
} MetaBarrierDirection;
G_END_DECLS
#endif /* __META_BARRIER_H__ */