[mutter] Move out generic math parts out of the native barrier implementation



commit f0f638d2bdd40b20b6928d31eb6ce45e33dab106
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Jul 3 15:01:58 2015 +0800

    Move out generic math parts out of the native barrier implementation
    
    In order to reuse some vector math for pointer confinement, move out
    those parts to its own file, introducing the types old types
    "MetaVector2" and "MetaLine2" outside of meta-barrier-native.c, as well
    as introducing MetaBorder which is a line, with a blocking direction.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744104

 src/Makefile.am                           |    2 +
 src/backends/meta-barrier-private.h       |   11 +--
 src/backends/meta-barrier.c               |   25 +++--
 src/backends/native/meta-barrier-native.c |  181 +++++------------------------
 src/backends/x11/meta-barrier-x11.c       |   13 ++-
 src/core/meta-border.c                    |  154 ++++++++++++++++++++++++
 src/core/meta-border.h                    |   84 +++++++++++++
 7 files changed, 292 insertions(+), 178 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 71aa026..fb0ccbb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -112,6 +112,8 @@ libmutter_la_SOURCES =                              \
        core/boxes.c                            \
        core/boxes-private.h                    \
        meta/boxes.h                            \
+       core/meta-border.c                      \
+       core/meta-border.h                      \
        compositor/clutter-utils.c              \
        compositor/clutter-utils.h              \
        compositor/cogl-utils.c                 \
diff --git a/src/backends/meta-barrier-private.h b/src/backends/meta-barrier-private.h
index 8e1d223..8c71117 100644
--- a/src/backends/meta-barrier-private.h
+++ b/src/backends/meta-barrier-private.h
@@ -26,6 +26,8 @@
 #ifndef META_BARRIER_PRIVATE_H
 #define META_BARRIER_PRIVATE_H
 
+#include "core/meta-border.h"
+
 G_BEGIN_DECLS
 
 #define META_TYPE_BARRIER_IMPL            (meta_barrier_impl_get_type ())
@@ -67,14 +69,7 @@ G_END_DECLS
 struct _MetaBarrierPrivate
 {
   MetaDisplay *display;
-
-  int x1;
-  int y1;
-  int x2;
-  int y2;
-
-  MetaBarrierDirection directions;
-
+  MetaBorder border;
   MetaBarrierImpl *impl;
 };
 
diff --git a/src/backends/meta-barrier.c b/src/backends/meta-barrier.c
index f5422ee..a1e1180 100644
--- a/src/backends/meta-barrier.c
+++ b/src/backends/meta-barrier.c
@@ -61,19 +61,20 @@ meta_barrier_get_property (GObject    *object,
       g_value_set_object (value, priv->display);
       break;
     case PROP_X1:
-      g_value_set_int (value, priv->x1);
+      g_value_set_int (value, priv->border.line.a.x);
       break;
     case PROP_Y1:
-      g_value_set_int (value, priv->y1);
+      g_value_set_int (value, priv->border.line.a.y);
       break;
     case PROP_X2:
-      g_value_set_int (value, priv->x2);
+      g_value_set_int (value, priv->border.line.b.x);
       break;
     case PROP_Y2:
-      g_value_set_int (value, priv->y2);
+      g_value_set_int (value, priv->border.line.b.y);
       break;
     case PROP_DIRECTIONS:
-      g_value_set_flags (value, priv->directions);
+      g_value_set_flags (value,
+                         meta_border_get_allows_directions (&priv->border));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -95,19 +96,20 @@ meta_barrier_set_property (GObject      *object,
       priv->display = g_value_get_object (value);
       break;
     case PROP_X1:
-      priv->x1 = g_value_get_int (value);
+      priv->border.line.a.x = g_value_get_int (value);
       break;
     case PROP_Y1:
-      priv->y1 = g_value_get_int (value);
+      priv->border.line.a.y = g_value_get_int (value);
       break;
     case PROP_X2:
-      priv->x2 = g_value_get_int (value);
+      priv->border.line.b.x = g_value_get_int (value);
       break;
     case PROP_Y2:
-      priv->y2 = g_value_get_int (value);
+      priv->border.line.b.y = g_value_get_int (value);
       break;
     case PROP_DIRECTIONS:
-      priv->directions = g_value_get_flags (value);
+      meta_border_set_allows_directions (&priv->border,
+                                         g_value_get_flags (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -166,7 +168,8 @@ meta_barrier_constructed (GObject *object)
   MetaBarrier *barrier = META_BARRIER (object);
   MetaBarrierPrivate *priv = barrier->priv;
 
-  g_return_if_fail (priv->x1 == priv->x2 || priv->y1 == priv->y2);
+  g_return_if_fail (priv->border.line.a.x == priv->border.line.b.x ||
+                    priv->border.line.a.y == priv->border.line.b.y);
 
 #if defined(HAVE_NATIVE_BACKEND)
   if (META_IS_BACKEND_NATIVE (meta_get_backend ()))
diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c
index 8f81d34..c6a6be6 100644
--- a/src/backends/native/meta-barrier-native.c
+++ b/src/backends/native/meta-barrier-native.c
@@ -93,126 +93,18 @@ next_serial (void)
   return barrier_serial;
 }
 
-typedef struct _Vector2
-{
-  float x, y;
-} Vector2;
-
-static float
-vector2_cross_product (Vector2 a, Vector2 b)
-{
-  return a.x * b.y - a.y * b.x;
-}
-
-static Vector2
-vector2_add (Vector2 a, Vector2 b)
-{
-  return (Vector2) {
-    .x = a.x + b.x,
-    .y = a.y + b.y,
-  };
-}
-
-static Vector2
-vector2_subtract (Vector2 a, Vector2 b)
-{
-  return (Vector2) {
-    .x = a.x - b.x,
-    .y = a.y - b.y,
-  };
-}
-
-static Vector2
-vector2_multiply_constant (float c, Vector2 a)
-{
-  return (Vector2) {
-    .x = c * a.x,
-    .y = c * a.y,
-  };
-}
-
-typedef struct _Line2
-{
-  Vector2 a;
-  Vector2 b;
-} Line2;
-
-static gboolean
-lines_intersect (Line2 *line1, Line2 *line2, Vector2 *intersection)
-{
-  Vector2 p = line1->a;
-  Vector2 r = vector2_subtract (line1->b, line1->a);
-  Vector2 q = line2->a;
-  Vector2 s = vector2_subtract (line2->b, line2->a);
-  float rxs;
-  float sxr;
-  float t;
-  float u;
-
-  /*
-   * The line (p, r) and (q, s) intersects where
-   *
-   *   p + t r = q + u s
-   *
-   * Calculate t:
-   *
-   *   (p + t r) × s = (q + u s) × s
-   *   p × s + t (r × s) = q × s + u (s × s)
-   *   p × s + t (r × s) = q × s
-   *   t (r × s) = q × s - p × s
-   *   t (r × s) = (q - p) × s
-   *   t = ((q - p) × s) / (r × s)
-   *
-   * Using the same method, for u we get:
-   *
-   *   u = ((p - q) × r) / (s × r)
-   */
-
-  rxs = vector2_cross_product (r, s);
-  sxr = vector2_cross_product (s, r);
-
-  /* If r × s = 0 then the lines are either parallel or collinear. */
-  if (fabs ( rxs) < DBL_MIN)
-    return FALSE;
-
-  t = vector2_cross_product (vector2_subtract (q, p), s) / rxs;
-  u = vector2_cross_product (vector2_subtract (p, q), r) / sxr;
-
-
-  /* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */
-  if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0)
-    return FALSE;
-
-  *intersection = vector2_add (p, vector2_multiply_constant (t, r));
-
-  return TRUE;
-}
-
 static gboolean
 is_barrier_horizontal (MetaBarrier *barrier)
 {
-  return barrier->priv->y1 == barrier->priv->y2;
+  return meta_border_is_horizontal (&barrier->priv->border);
 }
 
 static gboolean
 is_barrier_blocking_directions (MetaBarrier         *barrier,
                                 MetaBarrierDirection directions)
 {
-  /* Barriers doesn't block parallel motions. */
-  if (is_barrier_horizontal (barrier))
-    {
-      if ((directions & (META_BARRIER_DIRECTION_POSITIVE_Y |
-                         META_BARRIER_DIRECTION_NEGATIVE_Y)) == 0)
-        return FALSE;
-    }
-  else
-    {
-      if ((directions & (META_BARRIER_DIRECTION_POSITIVE_X |
-                         META_BARRIER_DIRECTION_NEGATIVE_X)) == 0)
-        return FALSE;
-    }
-
-  return (barrier->priv->directions & directions) != directions;
+  return meta_border_is_blocking_directions (&barrier->priv->border,
+                                             directions);
 }
 
 static void
@@ -224,31 +116,16 @@ dismiss_pointer (MetaBarrierImplNative *self)
   priv->state = META_BARRIER_STATE_LEFT;
 }
 
-static Line2
-barrier_to_line (MetaBarrier *barrier)
-{
-  return (Line2) {
-    .a = (Vector2) {
-      .x = MIN (barrier->priv->x1, barrier->priv->x2),
-      .y = MIN (barrier->priv->y1, barrier->priv->y2),
-    },
-    .b = (Vector2) {
-      .x = MAX (barrier->priv->x1, barrier->priv->x2),
-      .y = MAX (barrier->priv->y1, barrier->priv->y2),
-    },
-  };
-}
-
 /*
  * Calculate the hit box for a held motion. The hit box is a 2 px wide region
  * in the opposite direction of every direction the barrier blocks. The purpose
  * of this is to allow small movements without receiving a "left" signal. This
  * heuristic comes from the X.org pointer barrier implementation.
  */
-static Line2
+static MetaLine2
 calculate_barrier_hit_box (MetaBarrier *barrier)
 {
-  Line2 hit_box = barrier_to_line (barrier);
+  MetaLine2 hit_box = barrier->priv->border.line;
 
   if (is_barrier_horizontal (barrier))
     {
@@ -273,7 +150,8 @@ calculate_barrier_hit_box (MetaBarrier *barrier)
 }
 
 static gboolean
-is_within_box (Line2 box, Vector2 point)
+is_within_box (MetaLine2   box,
+               MetaVector2 point)
 {
   return (point.x >= box.a.x && point.x < box.b.x &&
           point.y >= box.a.y && point.y < box.b.y);
@@ -288,8 +166,8 @@ maybe_release_barrier (gpointer key,
   MetaBarrierImplNativePrivate *priv =
     meta_barrier_impl_native_get_instance_private (self);
   MetaBarrier *barrier = priv->barrier;
-  Line2 *motion = user_data;
-  Line2 hit_box;
+  MetaLine2 *motion = user_data;
+  MetaLine2 hit_box;
 
   if (priv->state != META_BARRIER_STATE_HELD)
     return;
@@ -297,8 +175,10 @@ maybe_release_barrier (gpointer key,
   /* Release if we end up outside barrier end points. */
   if (is_barrier_horizontal (barrier))
     {
-      if (motion->b.x > MAX (barrier->priv->x1, barrier->priv->x2) ||
-          motion->b.x < MIN (barrier->priv->x1, barrier->priv->x2))
+      if (motion->b.x > MAX (barrier->priv->border.line.a.x,
+                             barrier->priv->border.line.b.x) ||
+          motion->b.x < MIN (barrier->priv->border.line.a.x,
+                             barrier->priv->border.line.b.x))
         {
           dismiss_pointer (self);
           return;
@@ -306,8 +186,10 @@ maybe_release_barrier (gpointer key,
     }
   else
     {
-      if (motion->b.y > MAX (barrier->priv->y1, barrier->priv->y2) ||
-          motion->b.y < MIN (barrier->priv->y1, barrier->priv->y2))
+      if (motion->b.y > MAX (barrier->priv->border.line.a.y,
+                             barrier->priv->border.line.b.y) ||
+          motion->b.y < MIN (barrier->priv->border.line.a.y,
+                             barrier->priv->border.line.b.y))
         {
           dismiss_pointer (self);
           return;
@@ -330,7 +212,7 @@ maybe_release_barriers (MetaBarrierManagerNative *manager,
                         float                     x,
                         float                     y)
 {
-  Line2 motion = {
+  MetaLine2 motion = {
     .a = {
       .x = prev_x,
       .y = prev_y,
@@ -350,7 +232,7 @@ typedef struct _MetaClosestBarrierData
 {
   struct
   {
-    Line2                       motion;
+    MetaLine2                   motion;
     MetaBarrierDirection        directions;
   } in;
 
@@ -371,8 +253,7 @@ update_closest_barrier (gpointer key,
     meta_barrier_impl_native_get_instance_private (self);
   MetaBarrier *barrier = priv->barrier;
   MetaClosestBarrierData *data = user_data;
-  Line2 barrier_line;
-  Vector2 intersection;
+  MetaVector2 intersection;
   float dx, dy;
   float distance_2;
 
@@ -391,17 +272,9 @@ update_closest_barrier (gpointer key,
 
   /* Check if the motion intersects with the barrier, and retrieve the
    * intersection point if any. */
-  barrier_line = (Line2) {
-    .a = {
-      .x = barrier->priv->x1,
-      .y = barrier->priv->y1
-    },
-    .b = {
-      .x = barrier->priv->x2,
-      .y = barrier->priv->y2
-    },
-  };
-  if (!lines_intersect (&barrier_line, &data->in.motion, &intersection))
+  if (!meta_line2_intersects_with (&barrier->priv->border.line,
+                                   &data->in.motion,
+                                   &intersection))
     return;
 
   /* Calculate the distance to the barrier and keep track of the closest
@@ -570,9 +443,9 @@ clamp_to_barrier (MetaBarrierImplNative *self,
   if (is_barrier_horizontal (barrier))
     {
       if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_Y)
-        *y = barrier->priv->y1;
+        *y = barrier->priv->border.line.a.y;
       else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_Y)
-        *y = barrier->priv->y1;
+        *y = barrier->priv->border.line.a.y;
 
       priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_Y |
                                          META_BARRIER_DIRECTION_NEGATIVE_Y);
@@ -582,9 +455,9 @@ clamp_to_barrier (MetaBarrierImplNative *self,
   else
     {
       if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_X)
-        *x = barrier->priv->x1;
+        *x = barrier->priv->border.line.a.x;
       else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_X)
-        *x = barrier->priv->x1;
+        *x = barrier->priv->border.line.a.x;
 
       priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_X |
                                          META_BARRIER_DIRECTION_NEGATIVE_X);
diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c
index 1a813c4..054e5cd 100644
--- a/src/backends/x11/meta-barrier-x11.c
+++ b/src/backends/x11/meta-barrier-x11.c
@@ -107,6 +107,7 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
   MetaDisplay *display = barrier->priv->display;
   Display *dpy;
   Window root;
+  unsigned int allowed_motion_dirs;
 
   if (display == NULL)
     {
@@ -121,12 +122,14 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
   dpy = display->xdisplay;
   root = DefaultRootWindow (dpy);
 
+  allowed_motion_dirs =
+    meta_border_get_allows_directions (&barrier->priv->border);
   priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
-                                               barrier->priv->x1,
-                                               barrier->priv->y1,
-                                               barrier->priv->x2,
-                                               barrier->priv->y2,
-                                               barrier->priv->directions,
+                                               barrier->priv->border.line.a.x,
+                                               barrier->priv->border.line.a.y,
+                                               barrier->priv->border.line.b.x,
+                                               barrier->priv->border.line.b.y,
+                                               allowed_motion_dirs,
                                                0, NULL);
 
   g_hash_table_insert (display->xids, &priv->xbarrier, barrier);
diff --git a/src/core/meta-border.c b/src/core/meta-border.c
new file mode 100644
index 0000000..cc996fe
--- /dev/null
+++ b/src/core/meta-border.c
@@ -0,0 +1,154 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2015 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ *     Jonas Ådahl <jadahl gmail com>
+ */
+
+#include "config.h"
+
+#include "core/meta-border.h"
+
+#include <math.h>
+
+static inline float
+meta_vector2_cross_product (const MetaVector2 a,
+                            const MetaVector2 b)
+{
+  return a.x * b.y - a.y * b.x;
+}
+
+static inline MetaVector2
+meta_vector2_add (const MetaVector2 a,
+                  const MetaVector2 b)
+{
+  return (MetaVector2) {
+    .x = a.x + b.x,
+    .y = a.y + b.y,
+  };
+}
+
+static inline MetaVector2
+meta_vector2_multiply_constant (const float       c,
+                                const MetaVector2 a)
+{
+  return (MetaVector2) {
+    .x = c * a.x,
+    .y = c * a.y,
+  };
+}
+
+gboolean
+meta_line2_intersects_with (const MetaLine2 *line1,
+                            const MetaLine2 *line2,
+                            MetaVector2     *intersection)
+{
+  MetaVector2 p = line1->a;
+  MetaVector2 r = meta_vector2_subtract (line1->b, line1->a);
+  MetaVector2 q = line2->a;
+  MetaVector2 s = meta_vector2_subtract (line2->b, line2->a);
+  float rxs;
+  float sxr;
+  float t;
+  float u;
+
+  /*
+   * The line (p, r) and (q, s) intersects where
+   *
+   *   p + t r = q + u s
+   *
+   * Calculate t:
+   *
+   *   (p + t r) × s = (q + u s) × s
+   *   p × s + t (r × s) = q × s + u (s × s)
+   *   p × s + t (r × s) = q × s
+   *   t (r × s) = q × s - p × s
+   *   t (r × s) = (q - p) × s
+   *   t = ((q - p) × s) / (r × s)
+   *
+   * Using the same method, for u we get:
+   *
+   *   u = ((p - q) × r) / (s × r)
+   */
+
+  rxs = meta_vector2_cross_product (r, s);
+  sxr = meta_vector2_cross_product (s, r);
+
+  /* If r × s = 0 then the lines are either parallel or collinear. */
+  if (fabs (rxs) < DBL_MIN)
+    return FALSE;
+
+  t = meta_vector2_cross_product (meta_vector2_subtract (q, p), s) / rxs;
+  u = meta_vector2_cross_product (meta_vector2_subtract (p, q), r) / sxr;
+
+  /* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */
+  if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0)
+    return FALSE;
+
+  *intersection = meta_vector2_add (p, meta_vector2_multiply_constant (t, r));
+
+  return TRUE;
+}
+
+gboolean
+meta_border_is_horizontal (MetaBorder *border)
+{
+  return border->line.a.y == border->line.b.y;
+}
+
+gboolean
+meta_border_is_blocking_directions (MetaBorder               *border,
+                                    MetaBorderMotionDirection directions)
+{
+  if (meta_border_is_horizontal (border))
+    {
+      if ((directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_Y |
+                         META_BORDER_MOTION_DIRECTION_NEGATIVE_Y)) == 0)
+        return FALSE;
+    }
+  else
+    {
+      if ((directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_X |
+                         META_BORDER_MOTION_DIRECTION_NEGATIVE_X)) == 0)
+        return FALSE;
+    }
+
+  return (~border->blocking_directions & directions) != directions;
+}
+
+unsigned int
+meta_border_get_allows_directions (MetaBorder *border)
+{
+  return ~border->blocking_directions &
+    (META_BORDER_MOTION_DIRECTION_POSITIVE_X |
+     META_BORDER_MOTION_DIRECTION_POSITIVE_Y |
+     META_BORDER_MOTION_DIRECTION_NEGATIVE_X |
+     META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
+}
+
+void
+meta_border_set_allows_directions (MetaBorder *border, unsigned int directions)
+{
+  border->blocking_directions =
+    ~directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_X |
+                   META_BORDER_MOTION_DIRECTION_POSITIVE_Y |
+                   META_BORDER_MOTION_DIRECTION_NEGATIVE_X |
+                   META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
+}
diff --git a/src/core/meta-border.h b/src/core/meta-border.h
new file mode 100644
index 0000000..dd76db5
--- /dev/null
+++ b/src/core/meta-border.h
@@ -0,0 +1,84 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2015 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ *     Jonas Ådahl <jadahl gmail com>
+ */
+
+#ifndef META_BORDER_H
+#define META_BORDER_H
+
+#include <glib.h>
+
+typedef enum
+{
+  META_BORDER_MOTION_DIRECTION_POSITIVE_X = 1 << 0,
+  META_BORDER_MOTION_DIRECTION_POSITIVE_Y = 1 << 1,
+  META_BORDER_MOTION_DIRECTION_NEGATIVE_X = 1 << 2,
+  META_BORDER_MOTION_DIRECTION_NEGATIVE_Y = 1 << 3,
+} MetaBorderMotionDirection;
+
+typedef struct _MetaVector2
+{
+  float x;
+  float y;
+} MetaVector2;
+
+typedef struct _MetaLine2
+{
+  MetaVector2 a;
+  MetaVector2 b;
+} MetaLine2;
+
+typedef struct _MetaBorder
+{
+  MetaLine2 line;
+  MetaBorderMotionDirection blocking_directions;
+} MetaBorder;
+
+static inline MetaVector2
+meta_vector2_subtract (const MetaVector2 a,
+                       const MetaVector2 b)
+{
+  return (MetaVector2) {
+    .x = a.x - b.x,
+    .y = a.y - b.y,
+  };
+}
+
+gboolean
+meta_line2_intersects_with (const MetaLine2 *line1,
+                            const MetaLine2 *line2,
+                            MetaVector2     *intersection);
+
+gboolean
+meta_border_is_horizontal (MetaBorder *border);
+
+gboolean
+meta_border_is_blocking_directions (MetaBorder               *border,
+                                    MetaBorderMotionDirection directions);
+
+unsigned int
+meta_border_get_allows_directions (MetaBorder *border);
+
+void
+meta_border_set_allows_directions (MetaBorder *border, unsigned int directions);
+
+#endif /* META_BORDER_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]