[gtk+/wip/garnacho/gdkseat: 9/21] gdk: Add GdkSeatDefault



commit bf8db30cf58b57c006cf6bce5cfa6b24f929fdd2
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Nov 26 19:49:10 2015 +0100

    gdk: Add GdkSeatDefault

 gdk/Makefile.am             |    2 +
 gdk/gdkseatdefault.c        |  331 +++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkseatdefaultprivate.h |   56 ++++++++
 3 files changed, 389 insertions(+), 0 deletions(-)
---
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index f3ce6b9..bb0007a 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -114,6 +114,7 @@ gdk_private_headers =                               \
        gdkglcontextprivate.h                   \
        gdkscreenprivate.h                      \
        gdkseatprivate.h                        \
+       gdkseatdefaultprivate.h                 \
        gdkinternals.h                          \
        gdkintl.h                               \
        gdkkeysprivate.h                        \
@@ -153,6 +154,7 @@ gdk_c_sources =                             \
        gdkrgba.c                               \
        gdkscreen.c                             \
        gdkseat.c                               \
+       gdkseatdefault.c                        \
        gdkselection.c                          \
        gdkvisual.c                             \
        gdkwindow.c                             \
diff --git a/gdk/gdkseatdefault.c b/gdk/gdkseatdefault.c
new file mode 100644
index 0000000..913b186
--- /dev/null
+++ b/gdk/gdkseatdefault.c
@@ -0,0 +1,331 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2015 Red Hat
+ *
+ * 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/>.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#include "gdkseatdefaultprivate.h"
+#include "gdkdeviceprivate.h"
+
+typedef struct _GdkSeatDefaultPrivate GdkSeatDefaultPrivate;
+
+struct _GdkSeatDefaultPrivate
+{
+  GdkDevice *master_pointer;
+  GdkDevice *master_keyboard;
+  GList *slave_pointers;
+  GList *slave_keyboards;
+};
+
+#define KEYBOARD_EVENTS (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |    \
+                         GDK_FOCUS_CHANGE_MASK)
+#define TOUCH_EVENTS    (GDK_TOUCH_MASK)
+#define POINTER_EVENTS  (GDK_POINTER_MOTION_MASK |                      \
+                         GDK_BUTTON_PRESS_MASK |                        \
+                         GDK_BUTTON_RELEASE_MASK |                      \
+                         GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK |     \
+                         GDK_ENTER_NOTIFY_MASK |                        \
+                         GDK_LEAVE_NOTIFY_MASK |                        \
+                         GDK_PROXIMITY_IN_MASK |                        \
+                         GDK_PROXIMITY_OUT_MASK)
+
+G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
+
+static void
+gdk_seat_dispose (GObject *object)
+{
+  GdkSeatDefault *seat = GDK_SEAT_DEFAULT (object);
+  GdkSeatDefaultPrivate *priv = gdk_seat_default_get_instance_private (seat);
+  GList *l;
+
+  if (priv->master_pointer)
+    {
+      gdk_seat_device_removed (GDK_SEAT (seat), priv->master_pointer);
+      g_clear_object (&priv->master_pointer);
+    }
+
+  if (priv->master_keyboard)
+    {
+      gdk_seat_device_removed (GDK_SEAT (seat), priv->master_keyboard);
+      g_clear_object (&priv->master_pointer);
+    }
+
+  for (l = priv->slave_pointers; l; l = l->next)
+    {
+      gdk_seat_device_removed (GDK_SEAT (seat), l->data);
+      g_object_unref (l->data);
+    }
+
+  for (l = priv->slave_keyboards; l; l = l->next)
+    {
+      gdk_seat_device_removed (GDK_SEAT (seat), l->data);
+      g_object_unref (l->data);
+    }
+
+  g_list_free (priv->slave_pointers);
+  g_list_free (priv->slave_keyboards);
+  priv->slave_pointers = NULL;
+  priv->slave_keyboards = NULL;
+
+  G_OBJECT_CLASS (gdk_seat_default_parent_class)->dispose (object);
+}
+
+static GdkSeatCapabilities
+gdk_seat_default_get_capabilities (GdkSeat *seat)
+{
+  /* FIXME */
+  return GDK_SEAT_CAPABILITY_NONE;
+}
+
+static GdkGrabStatus
+gdk_seat_default_grab (GdkSeat                *seat,
+                       GdkWindow              *window,
+                       GdkSeatCapabilities     capabilities,
+                       gboolean                owner_events,
+                       GdkCursor              *cursor,
+                       const GdkEvent         *event,
+                       GdkSeatGrabPrepareFunc  prepare_func,
+                       gpointer                prepare_func_data)
+{
+  GdkSeatDefaultPrivate *priv;
+  guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
+  GdkGrabStatus status;
+
+  priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
+
+  if (prepare_func && !gdk_window_is_visible (window))
+    (prepare_func) (seat, window, prepare_func_data);
+
+  if (!gdk_window_is_visible (window))
+    {
+      g_critical ("Window %p has not been made visible in GdkSeatGrabPrepareFunc",
+                  window);
+      return GDK_GRAB_FAILED;
+    }
+
+  if (capabilities & ~GDK_SEAT_CAPABILITY_KEYBOARD)
+    {
+      status = gdk_device_grab (priv->master_pointer, window,
+                                GDK_OWNERSHIP_NONE, owner_events,
+                                POINTER_EVENTS, cursor,
+                                evtime);
+
+      if (status != GDK_GRAB_SUCCESS)
+        return status;
+    }
+
+  if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
+    {
+      status = gdk_device_grab (priv->master_keyboard, window,
+                                GDK_OWNERSHIP_NONE, owner_events,
+                                KEYBOARD_EVENTS, cursor,
+                                evtime);
+
+      if (status != GDK_GRAB_SUCCESS)
+        {
+          if (capabilities & ~GDK_SEAT_CAPABILITY_KEYBOARD)
+            gdk_device_ungrab (priv->master_pointer, evtime);
+          gdk_window_hide (window);
+        }
+    }
+
+  return status;
+}
+
+static void
+gdk_seat_default_ungrab (GdkSeat *seat)
+{
+  GdkSeatDefaultPrivate *priv;
+
+  priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
+  gdk_device_ungrab (priv->master_pointer, GDK_CURRENT_TIME);
+  gdk_device_ungrab (priv->master_keyboard, GDK_CURRENT_TIME);
+}
+
+static GdkDevice *
+gdk_seat_default_get_master (GdkSeat             *seat,
+                             GdkSeatCapabilities  capability)
+{
+  GdkSeatDefaultPrivate *priv;
+
+  priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
+
+  /* There must be only one flag set */
+  switch (capability)
+    {
+    case GDK_SEAT_CAPABILITY_POINTER:
+    case GDK_SEAT_CAPABILITY_TOUCH:
+      return priv->master_pointer;
+    case GDK_SEAT_CAPABILITY_KEYBOARD:
+      return priv->master_keyboard;
+    default:
+      g_warning ("Unhandled capability %x\n", capability);
+      break;
+    }
+
+  return NULL;
+}
+
+static GdkSeatCapabilities
+device_get_capability (GdkDevice *device)
+{
+  GdkInputSource source;
+
+  source = gdk_device_get_source (device);
+
+  switch (source)
+    {
+    case GDK_SOURCE_KEYBOARD:
+      return GDK_SEAT_CAPABILITY_KEYBOARD;
+    case GDK_SOURCE_TOUCHSCREEN:
+      return GDK_SEAT_CAPABILITY_TOUCH;
+    case GDK_SOURCE_MOUSE:
+    case GDK_SOURCE_TOUCHPAD:
+    default:
+      return GDK_SEAT_CAPABILITY_POINTER;
+    }
+
+  return GDK_SEAT_CAPABILITY_NONE;
+}
+
+static GList *
+append_filtered (GList               *list,
+                 GList               *devices,
+                 GdkSeatCapabilities  capabilities)
+{
+  GList *l;
+
+  for (l = devices; l; l = l->next)
+    {
+      GdkSeatCapabilities device_cap;
+
+      device_cap = device_get_capability (l->data);
+
+      if ((device_cap & capabilities) != 0)
+        list = g_list_prepend (list, l->data);
+    }
+
+  return list;
+}
+
+static GList *
+gdk_seat_default_get_slaves (GdkSeat             *seat,
+                             GdkSeatCapabilities  capabilities)
+{
+  GdkSeatDefaultPrivate *priv;
+  GList *devices = NULL;
+
+  priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
+
+  if (capabilities & (GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH))
+    devices = append_filtered (devices, priv->slave_pointers, capabilities);
+
+  if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
+    devices = append_filtered (devices, priv->slave_keyboards, capabilities);
+
+  return devices;
+}
+
+static void
+gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
+
+  object_class->dispose = gdk_seat_dispose;
+
+  seat_class->get_capabilities = gdk_seat_default_get_capabilities;
+
+  seat_class->grab = gdk_seat_default_grab;
+  seat_class->ungrab = gdk_seat_default_ungrab;
+
+  seat_class->get_master = gdk_seat_default_get_master;
+  seat_class->get_slaves = gdk_seat_default_get_slaves;
+}
+
+static void
+gdk_seat_default_init (GdkSeatDefault *seat)
+{
+}
+
+GdkSeat *
+gdk_seat_default_new_for_master_pair (GdkDevice *pointer,
+                                      GdkDevice *keyboard)
+{
+  GdkSeatDefaultPrivate *priv;
+  GdkSeat *seat;
+
+  seat = g_object_new (GDK_TYPE_SEAT_DEFAULT, NULL);
+
+  priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
+  priv->master_pointer = g_object_ref (pointer);
+  priv->master_keyboard = g_object_ref (keyboard);
+
+  gdk_seat_device_added (seat, priv->master_pointer);
+  gdk_seat_device_added (seat, priv->master_keyboard);
+
+  return seat;
+}
+
+void
+gdk_seat_default_add_slave (GdkSeatDefault *seat,
+                            GdkDevice      *device)
+{
+  GdkSeatDefaultPrivate *priv;
+  GdkSeatCapabilities capability;
+
+  g_return_if_fail (GDK_IS_SEAT_DEFAULT (seat));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  priv = gdk_seat_default_get_instance_private (seat);
+  capability = device_get_capability (device);
+
+  if (capability & (GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH))
+    priv->slave_pointers = g_list_prepend (priv->slave_pointers, g_object_ref (device));
+  else if (capability & GDK_SEAT_CAPABILITY_KEYBOARD)
+    priv->slave_keyboards = g_list_prepend (priv->slave_keyboards, g_object_ref (device));
+  else
+    {
+      g_critical ("Unhandled capability %x for device '%s'",
+                  capability, gdk_device_get_name (device));
+      return;
+    }
+
+  gdk_seat_device_added (GDK_SEAT (seat), device);
+}
+
+void
+gdk_seat_default_remove_slave (GdkSeatDefault *seat,
+                               GdkDevice      *device)
+{
+  GdkSeatDefaultPrivate *priv;
+
+  g_return_if_fail (GDK_IS_SEAT_DEFAULT (seat));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  priv = gdk_seat_default_get_instance_private (seat);
+
+  if (g_list_find (priv->slave_pointers, device))
+    {
+      priv->slave_pointers = g_list_remove (priv->slave_pointers, device);
+      gdk_seat_device_removed (GDK_SEAT (seat), device);
+    }
+  else if (g_list_find (priv->slave_keyboards, device))
+    {
+      priv->slave_keyboards = g_list_remove (priv->slave_keyboards, device);
+      gdk_seat_device_removed (GDK_SEAT (seat), device);
+    }
+}
diff --git a/gdk/gdkseatdefaultprivate.h b/gdk/gdkseatdefaultprivate.h
new file mode 100644
index 0000000..727bcc1
--- /dev/null
+++ b/gdk/gdkseatdefaultprivate.h
@@ -0,0 +1,56 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2015 Red Hat
+ *
+ * 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/>.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#ifndef __GDK_SEAT_DEFAULT_PRIVATE_H__
+#define __GDK_SEAT_DEFAULT_PRIVATE_H__
+
+#include "gdkseat.h"
+#include "gdkseatprivate.h"
+
+#define GDK_TYPE_SEAT_DEFAULT         (gdk_seat_default_get_type ())
+#define GDK_SEAT_DEFAULT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_SEAT_DEFAULT, 
GdkSeatDefault))
+#define GDK_IS_SEAT_DEFAULT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_SEAT_DEFAULT))
+#define GDK_SEAT_DEFAULT_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_SEAT_DEFAULT, 
GdkSeatDefaultClass))
+#define GDK_IS_SEAT_DEFAULT_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_SEAT_DEFAULT))
+#define GDK_SEAT_DEFAULT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_SEAT_DEFAULT, 
GdkSeatDefaultClass))
+
+typedef struct _GdkSeatDefault GdkSeatDefault;
+typedef struct _GdkSeatDefaultClass GdkSeatDefaultClass;
+
+struct _GdkSeatDefault
+{
+  GdkSeat parent_instance;
+};
+
+struct _GdkSeatDefaultClass
+{
+  GdkSeatClass parent_class;
+};
+
+GType     gdk_seat_default_get_type     (void) G_GNUC_CONST;
+
+GdkSeat * gdk_seat_default_new_for_master_pair (GdkDevice *pointer,
+                                                GdkDevice *keyboard);
+
+void      gdk_seat_default_add_slave    (GdkSeatDefault *seat,
+                                         GdkDevice      *device);
+void      gdk_seat_default_remove_slave (GdkSeatDefault *seat,
+                                         GdkDevice      *device);
+
+#endif /* __GDK_SEAT_DEFAULT_PRIVATE_H__ */


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