summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2016-05-26 10:05:10 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2016-06-22 11:57:07 +1000
commit6583f4bb53fbb26183d6035e51f6db7db6e801ca (patch)
tree6aa22c728652cfb9d92bab1e687729a4fb433c03 /src
parent8aa5576adb66618b984259ace7bcb955141221e2 (diff)
pad: Add a new API for modes and mode groups
Move mode control to libinput. This reduces some flexibility on what we can do with modes but makes it a lot easier for anyone to implement modes correctly and have the LEDs apply appropriately, etc. Let's go with the option to make the 95% use-case easy. Note: whether the mode is actually used is up to the caller, e.g. under Windows and OS X the mode only applies to the rings/strips, not the buttons. A tablet pad has 1 or more mode groups, all buttons/ring/strips are assigned to a mode group. That group has a numeric mode index and is hooked to the LEDs. libinput will switch the LEDs accordingly. The mode group is a separate object. This allows for better APIs when it comes to: * checking whether a button/ring/strip is part of a mode group * checking whether a button will trigger a mode transition and in the future potentially: * checking which mode transition will happen * setting which button should change the mode transition * changing what type of mode transition should happen. * moving a button from one mode group to the other This patch adds the basic scaffolding, without any real implementation. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Proofread-by: Yong Bakos <ybakos@humanoriented.com> Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com> Reviewed-by: Carlos Garnacho <carlosg@gnome.org>
Diffstat (limited to 'src')
-rw-r--r--src/libinput-private.h6
-rw-r--r--src/libinput.c127
-rw-r--r--src/libinput.h290
-rw-r--r--src/libinput.sym15
4 files changed, 438 insertions, 0 deletions
diff --git a/src/libinput-private.h b/src/libinput-private.h
index 10522125..98cb419f 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -329,6 +329,12 @@ struct libinput_tablet_tool {
bool has_pressure_offset;
};
+struct libinput_tablet_pad_mode_group {
+ struct list link;
+ int refcount;
+ void *user_data;
+};
+
struct libinput_event {
enum libinput_event_type type;
struct libinput_device *device;
diff --git a/src/libinput.c b/src/libinput.c
index 6ff4e9a1..a7892e14 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -140,6 +140,8 @@ struct libinput_event_tablet_tool {
struct libinput_event_tablet_pad {
struct libinput_event base;
+ unsigned int mode;
+ struct libinput_tablet_pad_mode_group *mode_group;
uint64_t time;
struct {
uint32_t number;
@@ -2580,6 +2582,7 @@ event_type_to_str(enum libinput_event_type type)
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP);
+ CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_MODE);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END);
@@ -2829,6 +2832,104 @@ libinput_device_tablet_pad_get_num_strips(struct libinput_device *device)
return evdev_device_tablet_pad_get_num_strips((struct evdev_device *)device);
}
+LIBINPUT_EXPORT int
+libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device *device)
+{
+ return 0;
+}
+
+LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group*
+libinput_device_tablet_pad_get_mode_group(struct libinput_device *device,
+ unsigned int index)
+{
+ return NULL;
+}
+
+LIBINPUT_EXPORT unsigned int
+libinput_tablet_pad_mode_group_get_num_modes(
+ struct libinput_tablet_pad_mode_group *group)
+{
+ return 1;
+}
+
+LIBINPUT_EXPORT unsigned int
+libinput_tablet_pad_mode_group_get_mode(struct libinput_tablet_pad_mode_group *group)
+{
+ return 0;
+}
+
+LIBINPUT_EXPORT unsigned int
+libinput_tablet_pad_mode_group_get_index(struct libinput_tablet_pad_mode_group *group)
+{
+ return 0;
+}
+
+LIBINPUT_EXPORT int
+libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group *group,
+ unsigned int button)
+{
+ return 1;
+}
+
+LIBINPUT_EXPORT int
+libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group *group,
+ unsigned int ring)
+{
+ return 1;
+}
+
+LIBINPUT_EXPORT int
+libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group *group,
+ unsigned int strip)
+{
+ return 1;
+}
+
+LIBINPUT_EXPORT int
+libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_group *group,
+ unsigned int button)
+{
+ return 0;
+}
+
+LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group *
+libinput_tablet_pad_mode_group_ref(
+ struct libinput_tablet_pad_mode_group *group)
+{
+ group->refcount++;
+ return group;
+}
+
+LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group *
+libinput_tablet_pad_mode_group_unref(
+ struct libinput_tablet_pad_mode_group *group)
+{
+ assert(group->refcount > 0);
+
+ group->refcount--;
+ if (group->refcount > 0)
+ return group;
+
+ list_remove(&group->link);
+ free(group);
+ return NULL;
+}
+
+LIBINPUT_EXPORT void
+libinput_tablet_pad_mode_group_set_user_data(
+ struct libinput_tablet_pad_mode_group *group,
+ void *user_data)
+{
+ group->user_data = user_data;
+}
+
+LIBINPUT_EXPORT void *
+libinput_tablet_pad_mode_group_get_user_data(
+ struct libinput_tablet_pad_mode_group *group)
+{
+ return group->user_data;
+}
+
LIBINPUT_EXPORT struct libinput_event *
libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event)
{
@@ -2989,6 +3090,32 @@ libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *eve
return event->button.state;
}
+LIBINPUT_EXPORT unsigned int
+libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event)
+{
+ require_event_type(libinput_event_get_context(&event->base),
+ event->base.type,
+ 0,
+ LIBINPUT_EVENT_TABLET_PAD_RING,
+ LIBINPUT_EVENT_TABLET_PAD_STRIP,
+ LIBINPUT_EVENT_TABLET_PAD_BUTTON);
+
+ return event->mode;
+}
+
+LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group *
+libinput_event_tablet_pad_get_mode_group(struct libinput_event_tablet_pad *event)
+{
+ require_event_type(libinput_event_get_context(&event->base),
+ event->base.type,
+ NULL,
+ LIBINPUT_EVENT_TABLET_PAD_RING,
+ LIBINPUT_EVENT_TABLET_PAD_STRIP,
+ LIBINPUT_EVENT_TABLET_PAD_BUTTON);
+
+ return event->mode_group;
+}
+
LIBINPUT_EXPORT uint32_t
libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event)
{
diff --git a/src/libinput.h b/src/libinput.h
index 212bf4ac..26d21de5 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -356,6 +356,236 @@ enum libinput_tablet_tool_tip_state {
};
/**
+ * @defgroup tablet_pad_modes Tablet pad modes
+ *
+ * Handling the virtual mode groups of buttons, strips and rings on tablet
+ * pad devices. See @ref tablet-pad-modes for details.
+ */
+
+/**
+ * @ingroup tablet_pad_modes
+ * @struct libinput_tablet_pad_mode_group
+ *
+ * A mode on a tablet pad is a virtual grouping of functionality, usually
+ * based on some visual feedback like LEDs on the pad. The set of buttons,
+ * rings and strips that share the same mode are a "mode group". Whenever
+ * the mode changes, all buttons, rings and strips within this mode group
+ * are affected. See @ref tablet-pad-modes for detail.
+ *
+ * Most tablets only have a single mode group, some tablets provide multiple
+ * mode groups through independent banks of LEDs (e.g. the Wacom Cintiq
+ * 24HD). libinput guarantees that at least one mode group is always
+ * available.
+ *
+ * This struct is refcounted, use libinput_tablet_pad_mode_group_ref() and
+ * libinput_tablet_pad_mode_group_unref().
+ */
+struct libinput_tablet_pad_mode_group;
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Most devices only provide a single mode group, however devices such as
+ * the Wacom Cintiq 22HD provide two mode groups. If multiple mode groups
+ * are available, a caller should use
+ * libinput_tablet_pad_mode_group_has_button(),
+ * libinput_tablet_pad_mode_group_has_ring() and
+ * libinput_tablet_pad_mode_group_has_strip() to associate each button,
+ * ring and strip with the correct mode group.
+ *
+ * @return the number of mode groups available on this device
+ */
+int
+libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device *device);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * The returned mode group is not refcounted and may become invalid after
+ * the next call to libinput. Use libinput_tablet_pad_mode_group_ref() and
+ * libinput_tablet_pad_mode_group_unref() to continue using the handle
+ * outside of the immediate scope.
+ *
+ * While at least one reference is kept by the caller, the returned mode
+ * group will be identical for each subsequent call of this function with
+ * the same index and that same struct is returned from
+ * libinput_event_tablet_pad_get_mode_group(), provided the event was
+ * generated by this mode group.
+ *
+ * @param device A device with the @ref LIBINPUT_DEVICE_CAP_TABLET_PAD
+ * capability
+ * @param index A mode group index
+ * @return the mode group with the given index or NULL if an invalid index
+ * is given.
+ */
+struct libinput_tablet_pad_mode_group*
+libinput_device_tablet_pad_get_mode_group(struct libinput_device *device,
+ unsigned int index);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * The returned number is the same index as passed to
+ * libinput_device_tablet_pad_get_mode_group(). For tablets with only one
+ * mode this number is always 0.
+ *
+ * @param group A previously obtained mode group
+ * @return the numeric index this mode group represents, starting at 0
+ */
+unsigned int
+libinput_tablet_pad_mode_group_get_index(struct libinput_tablet_pad_mode_group *group);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Query the mode group for the number of available modes. This number is
+ * usually decided by the number of physical LEDs available on the device.
+ * Different mode groups may have a different number of modes.
+ * Use libinput_tablet_pad_mode_group_get_mode() to get the currently active
+ * mode.
+ *
+ * libinput guarantees that at least one mode is available. A device without
+ * mode switching capability has a single mode group and a single mode.
+ *
+ * @param group A previously obtained mode group
+ * @return the number of modes available in this mode group
+ */
+unsigned int
+libinput_tablet_pad_mode_group_get_num_modes(struct libinput_tablet_pad_mode_group *group);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Return the current mode this mode group is in. Note that the returned
+ * mode is the mode valid as of completing the last libinput_dispatch().
+ * The returned mode may thus be different to the mode returned by
+ * libinput_event_tablet_pad_get_mode().
+ *
+ * For example, if the mode was toggled three times between the call to
+ * libinput_dispatch(), this function returns the third mode but the events
+ * in the event queue will return the modes 1, 2 and 3, respectively.
+ *
+ * @param group A previously obtained mode group
+ * @return the numeric index of the current mode in this group, starting at 0
+ *
+ * @see libinput_event_tablet_pad_get_mode
+ */
+unsigned int
+libinput_tablet_pad_mode_group_get_mode(struct libinput_tablet_pad_mode_group *group);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Devices without mode switching capabilities return true for every button.
+ *
+ * @param group A previously obtained mode group
+ * @param button A button index, starting at 0
+ * @return true if the given button index is part of this mode group or
+ * false otherwise
+ */
+int
+libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group *group,
+ unsigned int button);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Devices without mode switching capabilities return true for every ring.
+ *
+ * @param group A previously obtained mode group
+ * @param ring A ring index, starting at 0
+ * @return true if the given ring index is part of this mode group or
+ * false otherwise
+ */
+int
+libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group *group,
+ unsigned int ring);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Devices without mode switching capabilities return true for every strip.
+ *
+ * @param group A previously obtained mode group
+ * @param strip A strip index, starting at 0
+ * @return true if the given strip index is part of this mode group or
+ * false otherwise
+ */
+int
+libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group *group,
+ unsigned int strip);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Devices without mode switching capabilities return false for every button.
+ *
+ * @param group A previously obtained mode group
+ * @param button A button index, starting at 0
+ * @retval non-zero if the button is a mode toggle button for this group, or
+ * zero otherwise
+ */
+int
+libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_group *group,
+ unsigned int button);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Increase the refcount of the mode group. A mode device group will be
+ * freed whenever the refcount reaches 0.
+ *
+ * @param group A previously obtained mode group
+ * @return The passed mode group
+ */
+struct libinput_tablet_pad_mode_group *
+libinput_tablet_pad_mode_group_ref(
+ struct libinput_tablet_pad_mode_group *group);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Decrease the refcount of the mode group. A mode device group will be
+ * freed whenever the refcount reaches 0.
+ *
+ * @param group A previously obtained mode group
+ * @return NULL if the group was destroyed, otherwise the passed mode group
+ */
+struct libinput_tablet_pad_mode_group *
+libinput_tablet_pad_mode_group_unref(
+ struct libinput_tablet_pad_mode_group *group);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Set caller-specific data associated with this mode group. libinput does
+ * not manage, look at, or modify this data. The caller must ensure the
+ * data is valid.
+ *
+ * @param group A previously obtained mode group
+ * @param user_data Caller-specific data pointer
+ * @see libinput_tablet_pad_mode_group_get_user_data
+ *
+ */
+void
+libinput_tablet_pad_mode_group_set_user_data(
+ struct libinput_tablet_pad_mode_group *group,
+ void *user_data);
+
+/**
+ * @ingroup tablet_pad_modes
+ *
+ * Get the caller-specific data associated with this input device, if any.
+ *
+ * @param group A previously obtained mode group
+ * @return Caller-specific data pointer or NULL if none was set
+ * @see libinput_tablet_pad_mode_group_set_user_data
+ */
+void *
+libinput_tablet_pad_mode_group_get_user_data(
+ struct libinput_tablet_pad_mode_group *group);
+
+/**
* @ingroup base
*
* Event type for events returned by libinput_get_event().
@@ -504,6 +734,19 @@ enum libinput_event_type {
*/
LIBINPUT_EVENT_TABLET_PAD_STRIP,
+ /**
+ * A mode change on a device with the @ref
+ * LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
+ *
+ * This event is triggered when the mode is changed through
+ * external means. The event reflects a mode change (see @ref
+ * tablet-pad-modes) occurring as a result other than that of
+ * pressing a mode toggle button.
+ *
+ * @note Support for this event is not yet implemented.
+ */
+ LIBINPUT_EVENT_TABLET_PAD_MODE,
+
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800,
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
LIBINPUT_EVENT_GESTURE_SWIPE_END,
@@ -2380,6 +2623,53 @@ libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *eve
/**
* @ingroup event_tablet_pad
*
+ * Returns the current mode this button, ring, or strip is considered in.
+ * The mode is a virtual grouping of functionality, usually based on some
+ * visual feedback like LEDs on the pad. See @ref tablet-pad-modes for
+ * details. Mode indices start at 0, a device that does not support modes
+ * always returns 0.
+ *
+ * Mode switching is controlled by libinput and more than one mode may exist
+ * on the tablet. This function returns the mode that this event's button,
+ * ring or strip is logically grouped in. If the button is the mode toggle
+ * button and the button event caused a new mode to be toggled, the mode
+ * returned is the new mode the button is in.
+ *
+ * Note that the returned mode is the mode valid as of the time of the
+ * event. The returned mode may thus be different to the mode returned by
+ * libinput_tablet_pad_mode_group_get_mode(). See
+ * libinput_tablet_pad_mode_group_get_mode() for details.
+ *
+ * @param event The libinput tablet pad event
+ * @return the current 0-indexed mode of this button, ring or strip
+ *
+ * @see libinput_tablet_pad_mode_group_get_mode
+ */
+unsigned int
+libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event);
+
+/**
+ * @ingroup event_tablet_pad
+ *
+ * Returns the current mode group this button, ring, or strip is considered in.
+ * The mode is a virtual grouping of functionality, usually based on some
+ * visual feedback like LEDs on the pad. See @ref tablet-pad-modes for
+ * details.
+ *
+ * The returned mode group is not refcounted and may become invalid after
+ * the next call to libinput. Use libinput_tablet_pad_mode_group_ref() and
+ * libinput_tablet_pad_mode_group_unref() to continue using the handle
+ * outside of the immediate scope.
+ *
+ * @param event The libinput tablet pad event
+ * @return the current 0-indexed mode of this button, ring or strip
+ */
+struct libinput_tablet_pad_mode_group *
+libinput_event_tablet_pad_get_mode_group(struct libinput_event_tablet_pad *event);
+
+/**
+ * @ingroup event_tablet
+ *
* @param event The libinput tablet pad event
* @return The event time for this event
*/
diff --git a/src/libinput.sym b/src/libinput.sym
index c6a0e4c9..cb3f2b84 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -258,4 +258,19 @@ LIBINPUT_1.4 {
libinput_device_config_rotation_get_default_angle;
libinput_device_config_rotation_is_available;
libinput_device_config_rotation_set_angle;
+ libinput_device_tablet_pad_get_mode_group;
+ libinput_device_tablet_pad_get_num_mode_groups;
+ libinput_event_tablet_pad_get_mode;
+ libinput_event_tablet_pad_get_mode_group;
+ libinput_tablet_pad_mode_group_button_is_toggle;
+ libinput_tablet_pad_mode_group_get_index;
+ libinput_tablet_pad_mode_group_get_mode;
+ libinput_tablet_pad_mode_group_get_num_modes;
+ libinput_tablet_pad_mode_group_get_user_data;
+ libinput_tablet_pad_mode_group_has_button;
+ libinput_tablet_pad_mode_group_has_strip;
+ libinput_tablet_pad_mode_group_has_ring;
+ libinput_tablet_pad_mode_group_ref;
+ libinput_tablet_pad_mode_group_set_user_data;
+ libinput_tablet_pad_mode_group_unref;
} LIBINPUT_1.3;