[gtkmm] Gdk: Add DevicePad and DeviceWithPad



commit ff93e69b975ae830e81939dd2dc5fa7b85e2f77a
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Sun Mar 3 17:15:09 2019 +0100

    Gdk: Add DevicePad and DeviceWithPad
    
    DeviceWithPad is a subclass of DevicePad with no corresponding C class.
    It implements the DevicePad interface, and makes it possible for C++
    programmers to call methods in DevicePad when the underlying C class
    implements GdkDevicePad. Kinda hacky, but it's the best I could think of.

 .gitignore                 |  2 ++
 gdk/gdkmm.h                |  2 ++
 gdk/gdkmm/devicewithpad.cc | 45 +++++++++++++++++++++++++++++
 gdk/gdkmm/devicewithpad.h  | 54 +++++++++++++++++++++++++++++++++++
 gdk/gdkmm/filelist.am      | 15 ++++++++--
 gdk/src/device.ccg         | 35 ++++++++++++++++++++++-
 gdk/src/device.hg          | 35 ++++++++++++++++++++++-
 gdk/src/devicepad.ccg      | 17 +++++++++++
 gdk/src/devicepad.hg       | 70 ++++++++++++++++++++++++++++++++++++++++++++++
 gdk/src/filelist.am        |  1 +
 tools/m4/convert_gdk.m4    |  1 +
 11 files changed, 273 insertions(+), 4 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 7ca49661..852e16a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,6 +65,8 @@ gdk/gdkmm/cursor.cc
 gdk/gdkmm/cursor.h
 gdk/gdkmm/device.cc
 gdk/gdkmm/device.h
+gdk/gdkmm/devicepad.cc
+gdk/gdkmm/devicepad.h
 gdk/gdkmm/devicetool.cc
 gdk/gdkmm/devicetool.h
 gdk/gdkmm/display.cc
diff --git a/gdk/gdkmm.h b/gdk/gdkmm.h
index 20753b51..c08b2e1f 100644
--- a/gdk/gdkmm.h
+++ b/gdk/gdkmm.h
@@ -26,7 +26,9 @@
 #include <gdkmm/contentformatsbuilder.h>
 #include <gdkmm/clipboard.h>
 #include <gdkmm/cursor.h>
+#include <gdkmm/devicepad.h>
 #include <gdkmm/devicetool.h>
+#include <gdkmm/devicewithpad.h>
 #include <gdkmm/display.h>
 #include <gdkmm/displaymanager.h>
 #include <gdkmm/drop.h>
diff --git a/gdk/gdkmm/devicewithpad.cc b/gdk/gdkmm/devicewithpad.cc
new file mode 100644
index 00000000..254f3866
--- /dev/null
+++ b/gdk/gdkmm/devicewithpad.cc
@@ -0,0 +1,45 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * 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.1 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/>.
+ */
+
+#include <gdkmm/devicewithpad.h>
+
+namespace Gdk
+{
+
+DeviceWithPad::DeviceWithPad(GdkDevice* castitem)
+:
+  Device(castitem)
+{}
+
+
+DeviceWithPad::DeviceWithPad(DeviceWithPad&& src) noexcept
+: Device(std::move(src)),
+  DevicePad(std::move(src))
+{}
+
+DeviceWithPad& DeviceWithPad::operator=(DeviceWithPad&& src) noexcept
+{
+  Device::operator=(std::move(src));
+  DevicePad::operator=(std::move(src));
+  return *this;
+}
+
+DeviceWithPad::~DeviceWithPad() noexcept
+{}
+
+} // namespace Gdk
+
+
diff --git a/gdk/gdkmm/devicewithpad.h b/gdk/gdkmm/devicewithpad.h
new file mode 100644
index 00000000..62bc4f3b
--- /dev/null
+++ b/gdk/gdkmm/devicewithpad.h
@@ -0,0 +1,54 @@
+#ifndef _GDKMM_DEVICEWITHPAD_H
+#define _GDKMM_DEVICEWITHPAD_H
+
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * 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.1 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/>.
+ */
+
+#include <gdkmm/device.h>
+#include <gdkmm/devicepad.h>
+
+namespace Gdk
+{
+
+/** A %Gdk::DeviceWithPad is a Gdk::Device that implements the Gdk::DevicePad interface.
+ *
+ * Use Gdk::Device::has_device_pad() to check if a %Gdk::Device is in fact a %Gdk::DeviceWithPad.
+ * Use Gdk::Device::device_with_pad_cast() to get a Glib::RefPtr<Gdk::DeviceWithPad>.
+ */
+
+class DeviceWithPad : public Device, public DevicePad
+{
+private:
+  // noncopyable
+  DeviceWithPad(const DeviceWithPad&) = delete;
+  DeviceWithPad& operator=(const DeviceWithPad&) = delete;
+
+  friend class Device_Class;
+
+protected:
+  explicit DeviceWithPad(GdkDevice* castitem);
+
+public:
+
+  DeviceWithPad(DeviceWithPad&& src) noexcept;
+  DeviceWithPad& operator=(DeviceWithPad&& src) noexcept;
+
+  ~DeviceWithPad() noexcept override;
+};
+
+} // namespace Gdk
+
+#endif /* _GDKMM_DEVICEWITHPAD_H */
diff --git a/gdk/gdkmm/filelist.am b/gdk/gdkmm/filelist.am
index 51ed6496..5ae0d78b 100644
--- a/gdk/gdkmm/filelist.am
+++ b/gdk/gdkmm/filelist.am
@@ -3,6 +3,17 @@
 gdkmm_files_built_cc = $(gdkmm_files_used_hg:.hg=.cc) wrap_init.cc
 gdkmm_files_built_h  = $(gdkmm_files_used_hg:.hg=.h)
 
-gdkmm_files_extra_cc = cairoutils.cc general.cc value_cairo.cc
-gdkmm_files_extra_h  = cairoutils.h general.h value_cairo.h wrap_init.h
+gdkmm_files_extra_cc = \
+  cairoutils.cc \
+  devicewithpad.cc \
+  general.cc \
+  value_cairo.cc
+
+gdkmm_files_extra_h  = \
+  cairoutils.h \
+  devicewithpad.h \
+  general.h \
+  value_cairo.h \
+  wrap_init.h
+
 gdkmm_files_extra_ph =
diff --git a/gdk/src/device.ccg b/gdk/src/device.ccg
index 08e32302..6f3f6ef3 100644
--- a/gdk/src/device.ccg
+++ b/gdk/src/device.ccg
@@ -18,6 +18,7 @@
 #include <gdk/gdk.h>
 #include <gdkmm/cursor.h>
 #include <gdkmm/devicetool.h>
+#include <gdkmm/devicewithpad.h>
 #include <gdkmm/display.h>
 #include <gdkmm/seat.h>
 #include <gdkmm/surface.h>
@@ -67,5 +68,37 @@ std::vector<std::string> Device::list_axes() const
   return Glib::ListHandler<std::string, AtomStringTraits>::list_to_vector(glist, Glib::OWNERSHIP_SHALLOW);
 }
 
-} // namespace Gdk
+// Custom wrap_new() because we want to create a DeviceWithPad, if the underlying
+// C class implements the GdkDevicePad interface.
+Glib::ObjectBase* Device_Class::wrap_new(GObject* object)
+{
+  // GdkDevice is an abstract class. C functions that return a GdkDevice* usually
+  // (always?) return a pointer to a subclass of GdkDevice. Some subclasses, e.g.
+  // GdkWaylandDevicePad, implement the GdkDevicePad interface.
+  // Give C++ programmers a chance to access methods in that interface, although
+  // gtkmm does not wrap subclasses of GdkDevice.
+
+  if (GDK_IS_DEVICE_PAD(object))
+     return new DeviceWithPad((GdkDevice*)object);
+  return new Device((GdkDevice*)object);
+}
 
+bool Device::has_device_pad() const
+{
+  return dynamic_cast<const DeviceWithPad*>(this) != nullptr;
+}
+
+Glib::RefPtr<DeviceWithPad> Device::device_with_pad_cast()
+{
+  auto retvalue = Glib::make_refptr_for_instance<DeviceWithPad>(dynamic_cast<DeviceWithPad*>(this));
+  if (retvalue)
+    retvalue->reference();
+  return retvalue;
+}
+
+Glib::RefPtr<const DeviceWithPad> Device::device_with_pad_cast() const
+{
+  return const_cast<Device*>(this)->device_with_pad_cast();
+}
+
+} // namespace Gdk
diff --git a/gdk/src/device.hg b/gdk/src/device.hg
index 8f80a278..1ceadadb 100644
--- a/gdk/src/device.hg
+++ b/gdk/src/device.hg
@@ -34,10 +34,11 @@ namespace Gdk
 _WRAP_ENUM(EventMask, GdkEventMask)
 _WRAP_ENUM(InputMode, GdkInputMode)
 _WRAP_ENUM(InputSource, GdkInputSource)
-//_WRAP_ENUM(GrabOwnership, GdkGrabOwnership)
+//_WRAP_ENUM(GrabOwnership, GdkGrabOwnership) Used only in deprecated gdk_device_grab()
 _WRAP_ENUM(GrabStatus, GdkGrabStatus)
 
 class DeviceTool;
+class DeviceWithPad;
 class Display;
 class Seat;
 class Surface;
@@ -47,6 +48,7 @@ class Surface;
 class Device : public Glib::Object
 {
   _CLASS_GOBJECT(Device,GdkDevice,GDK_DEVICE,Glib::Object,GObject)
+  _CUSTOM_WRAP_NEW
 
 protected:
   _CTOR_DEFAULT()
@@ -179,6 +181,37 @@ public:
 
   _WRAP_METHOD(AxisFlags get_axes() const, gdk_device_get_axes)
 
+  /** Checks if this %Device instance is a DeviceWithPad.
+   *
+   * The underlying C object is usually a subclass of GdkDevice. If that subclass
+   * implements the GdkDevicePad interface, this C++ %Gdk::Device instance is
+   * a Gdk::DeviceWithPad instance, and can be cast to a Gdk::DeviceWithPad
+   * by device_with_pad_cast().
+   *
+   * @return <tt>true</tt> if this instance is a DeviceWithPad.
+   *
+   * @newin{3,96}
+   */
+  bool has_device_pad() const;
+
+  /** Casts this %Device instance to a DeviceWithPad, if possible.
+   *
+   * @return A DeviceWithPad pointer, or an empty Glib::RefPtr if this %Device
+   *         can't be dynamic_cast to a %DeviceWithPad.
+   *
+   * @newin{3,96}
+   */
+  Glib::RefPtr<DeviceWithPad> device_with_pad_cast();
+
+  /** Casts this %Device instance to a DeviceWithPad, if possible.
+   *
+   * @return A DeviceWithPad pointer, or an empty Glib::RefPtr if this %Device
+   *         can't be dynamic_cast to a %DeviceWithPad.
+   *
+   * @newin{3,96}
+   */
+  Glib::RefPtr<const DeviceWithPad> device_with_pad_cast() const;
+
   // We use no_default_handler because _GdkDeviceClass is private.
   _WRAP_SIGNAL(void changed(), "changed", no_default_handler, newin "3,22")
 #m4 _CONVERSION(`GdkDeviceTool*',`const Glib::RefPtr<DeviceTool>&', Glib::wrap($3, true))
diff --git a/gdk/src/devicepad.ccg b/gdk/src/devicepad.ccg
new file mode 100644
index 00000000..cf32ee34
--- /dev/null
+++ b/gdk/src/devicepad.ccg
@@ -0,0 +1,17 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * 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.1 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/>.
+ */
+
+#include <gdk/gdk.h>
diff --git a/gdk/src/devicepad.hg b/gdk/src/devicepad.hg
new file mode 100644
index 00000000..9576f810
--- /dev/null
+++ b/gdk/src/devicepad.hg
@@ -0,0 +1,70 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * 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.1 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/>.
+ */
+
+#include <glibmm/interface.h>
+
+_DEFS(gdkmm,gdk)
+_PINCLUDE(glibmm/private/interface_p.h)
+_PINCLUDE(gdk/gdk.h)
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+extern "C"
+{
+typedef struct _GdkDevicePadInterface GdkDevicePadInterface;
+}
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+namespace Gdk
+{
+
+/** Pad device interface.
+ *
+ * %Gdk::DevicePad is an interface implemented by devices of type
+ * Gdk::InputSource::TABLET_PAD. It allows querying the features provided
+ * by the pad device.
+ *
+ * Tablet pads may contain one or more groups, each containing a subset
+ * of the buttons/rings/strips available. get_n_groups()
+ * can be used to obtain the number of groups, get_n_features()
+ * and get_feature_group() can be combined to find out the
+ * number of buttons/rings/strips the device has, and how are they grouped.
+ *
+ * Each of those groups have different modes, which may be used to map
+ * each individual pad feature to multiple actions. Only one mode is
+ * effective (current) for each given group, different groups may have
+ * different current modes. The number of available modes in a group can
+ * be found out through get_group_n_modes(), and the current mode for
+ * a given group will be notified through the Gdk::EventPadGroupMode event.
+ *
+ * @newin{3,96}
+ */
+class DevicePad : public Glib::Interface
+{
+  _CLASS_INTERFACE(DevicePad, GdkDevicePad, GDK_DEVICE_PAD, GdkDevicePadInterface)
+
+public:
+  _WRAP_ENUM(Feature, GdkDevicePadFeature)
+
+  _WRAP_METHOD(int get_n_groups() const, gdk_device_pad_get_n_groups)
+  _WRAP_METHOD(int get_group_n_modes(int group_idx) const, gdk_device_pad_get_group_n_modes)
+  _WRAP_METHOD(int get_n_features(Feature feature) const, gdk_device_pad_get_n_features)
+  _WRAP_METHOD(int get_feature_group(Feature feature, int feature_idx) const,
+    gdk_device_pad_get_feature_group)
+
+  // There are no properties, signals or vfuncs.
+};
+
+} // namespace Gdk
diff --git a/gdk/src/filelist.am b/gdk/src/filelist.am
index dc0501e9..5d05bf13 100644
--- a/gdk/src/filelist.am
+++ b/gdk/src/filelist.am
@@ -22,6 +22,7 @@ gdkmm_files_any_hg =          \
        contentprovider.hg              \
        cursor.hg               \
        device.hg               \
+       devicepad.hg \
        devicetool.hg           \
        display.hg              \
        displaymanager.hg       \
diff --git a/tools/m4/convert_gdk.m4 b/tools/m4/convert_gdk.m4
index 3a692b78..8965757c 100644
--- a/tools/m4/convert_gdk.m4
+++ b/tools/m4/convert_gdk.m4
@@ -33,6 +33,7 @@ _CONV_ENUM(Gdk,CapStyle)
 _CONV_ENUM(Gdk,Colorspace)
 _CONV_ENUM(Gdk,CrossingMode)
 _CONV_INCLASS_ENUM(Gdk,Device,Type)
+_CONV_INCLASS_ENUM(Gdk,DevicePad,Feature)
 _CONV_INCLASS_ENUM(Gdk,DeviceTool,Type)
 _CONV_ENUM(Gdk,DragAction)
 _CONV_ENUM(Gdk,DragCancelReason)


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