Hi Peter, One possible documentation error, one minor nit, and a string error (see "TABLET_PAD_MODE") inline below.
Otherwise, this is, uh, Proofread-by: Yong Bakos <[email protected]> Regards, yong > On Jun 6, 2016, at 1:50 AM, Peter Hutterer <[email protected]> wrote: > > 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 > * checking which mode transition will happen > > and in the future potentially: > * 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 <[email protected]> > --- > doc/tablet-support.dox | 59 ++++++++- > src/libinput-private.h | 6 + > src/libinput.c | 128 +++++++++++++++++++ > src/libinput.h | 324 +++++++++++++++++++++++++++++++++++++++++++++++++ > src/libinput.sym | 16 +++ > test/litest.c | 3 + > tools/event-debug.c | 61 ++++++++-- > tools/event-gui.c | 1 + > 8 files changed, 586 insertions(+), 12 deletions(-) > > diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox > index c555cea..b7267a8 100644 > --- a/doc/tablet-support.dox > +++ b/doc/tablet-support.dox > @@ -240,8 +240,7 @@ tablet. > > Some buttons may have expected default behaviors. For example, on Wacom > Intuos Pro series tablets, the button inside the touch ring is expected to > -switch between a mode switch. Mode switching is a feature implemented in the > -caller and libinput does not provide specific handling. Callers should use > +switch between a mode switch, see @ref tablet-pad-modes. Callers should use > external sources like libwacom to identify which buttons have semantic > behaviors. > > @@ -276,4 +275,60 @@ symmetric and thus do not support left-handed mode. > libinput requires > libwacom to determine if a tablet is capable of being switched to > left-handed mode. > > +@section tablet-pad-modes Tablet pad modes > + > +Tablet pad modes are virtual groupings of button, ring and strip > +functionality. A caller may assign different functionalities depending on > +the mode the tablet is in. For example, in mode 0 the touch ring may emulate > +scrolling, in mode 1 the touch ring may emulate zooming, etc. libinput > +handles the modes and mode switching but does not assign specific > +functionality to buttons, rings or strips based on the mode. It is up to the > +caller to decide whether the mode only applies to buttons, rings and strips > +or only to rings and strips (this is the case with the Wacom OS X and > +Windows driver). > + > +The availability of modes on a touchpad usually depends on visual feedback > +such as LEDs around the touch ring. If no visual feedback is available, only > +one mode may be available. > + > +Mode switching is controlled by libinput and usually toggled by one or > +more buttons on the device. For example, on the Wacom Intuos 4, 5, and > +Pro series tablets the mode button is the button centered in the touch > +ring and toggles the modes sequentially. On the Wacom Cintiq 24HD the > +three buttons next to each touch ring allow for directly changing the > +mode to the desired setting. > + > +Multiple modes may exist on the tablet, libinput uses the term "mode group" > +for such groupings of buttons that share a mode and mode toggle. For > +example, the Wacom Cintiq 24HD has two separate mode groups, one for the > +left set of buttons, strips, and touch rings and one for the right set. > +libinput handles the mode groups independently and returns the mode for each > +button as appropriate. The mode group is static for the lifetime of the > +device. > + > +@image html tablet-intuos-modes.svg "Modes on an Intuos Pro-like tablet" > + > +In the image above, the Intuos Pro-like tablet provides 4 LEDs to indicate > +the currently active modes. The button inside the touch ring cycles through > +the modes in a clockwise fashion. The upper-right LED indicates that the > +currently active mode is 1, based on 0-indexed mode numbering. > +libinput_event_tablet_pad_get_mode() would thus return 1 for all button and > +ring events on this tablet. When the center button is pressed, the mode > +switches to mode 2, the LED changes to the bottom-right and > +libinput_event_tablet_pad_get_mode() returns 2 for the center button event > +and all subsequent events. > + > +@image html tablet-cintiq24hd-modes.svg "Modes on an Cintiq 24HD-like tablet" > + > +In the image above, the Cintiq 24HD-like tablet provides 3 LEDs on each side > +of the tablet to indicate the currently active mode for that group of > +buttons and the respective ring. The buttons next to the touch ring select > +the mode directly. The two LEDs indicate that the mode for the left set of > +buttons is currently 0, the mode for the right set of buttons is currently > +1, based on 0-indexed mode numbering. libinput_event_tablet_pad_get_mode() > +would thus return 0 for all button and ring events on the left and 1 for all > +button and ring events on the right. When one of the three mode toggle > +buttons on the right is pressed, the right mode switches to that button's > +mode but the left mode remains unchanged. > + > */ > diff --git a/src/libinput-private.h b/src/libinput-private.h > index 1052212..98cb419 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 0f676a3..e174aae 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 button; > @@ -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,105 @@ 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 1; > +} > + > +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 unsigned int > +libinput_tablet_pad_mode_group_button_get_target_mode(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 +3091,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 212bf4a..88345ba 100644 > --- a/src/libinput.h > +++ b/src/libinput.h > @@ -356,6 +356,277 @@ 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 less 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 Missing period. > + * > + * @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 > + */ > +unsigned int > +libinput_tablet_pad_mode_group_get_mode(struct > libinput_tablet_pad_mode_group *group); > + > +/** > + * @ingroup tablet_pad_modes > + * > + * Devices without mode switching capabilies 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 capabilies 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 capabilies 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 capabilies 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 > + * > + * Semantic mode values used by > + * libinput_tablet_pad_mode_group_button_get_target_mode(). > + * > + * A mode toggle button may either select a specific mode directly or > + * toggle to the previous or next mode. > + */ > +enum libinput_tablet_pad_mode_group_targets { > + /** > + * Marks the maximum target mode allowed for direct mode selection. > + * Any mode number equal or below should be considered a direct mode > + * selection. e.g. a value of 2 means "select mode index 2" > + */ > + LIBINPUT_TABLET_PAD_MODE_GROUP_TARGET_MAX_DIRECT = 0xffff, > + LIBINPUT_TABLET_PAD_MODE_GROUP_TARGET_PREVIOUS = 0x10000, > + LIBINPUT_TABLET_PAD_MODE_GROUP_TARGET_NEXT, > +}; > + > +/** > + * @ingroup tablet_pad_modes > + * > + * Return the target mode for this mode toggle button. If the returned value > + * is less or equal to @ref > + * LIBINPUT_TABLET_PAD_MODE_GROUP_TARGET_MAX_DIRECT, the target mode index > + * is the returned value. > + * > + * It is an application bug to call this function for a button index that is > + * not a mode toggle button. In that case, the return value is always 0. > + * > + * @param group A previously obtained mode group > + * @param button A button index, starting at 0 > + * @return the mode selected when this mode toggle button is > + * pressed, starting at index 0 > + * @retval LIBINPUT_TABLET_PAD_MODE_GROUP_TARGET_PREVIOUS Upon pressing > + * this button, the previous mode is selected > + * @retval LIBINPUT_TABLET_PAD_MODE_GROUP_TARGET_NEXT Upon pressing this > button, the next mode is selected > + */ > +unsigned int > +libinput_tablet_pad_mode_group_button_get_target_mode(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 +775,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) occuring 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 +2664,46 @@ 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 the button, ring or strip > + * of this event 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. > + * > + * @param event The libinput tablet pad event > + * @return the current 0-indexed mode of this button, ring or strip > + */ > +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 c6a0e4c..631c36d 100644 > --- a/src/libinput.sym > +++ b/src/libinput.sym > @@ -258,4 +258,20 @@ 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_get_target_mode; > + 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; > diff --git a/test/litest.c b/test/litest.c > index 66f08f2..41a9308 100644 > --- a/test/litest.c > +++ b/test/litest.c > @@ -2097,6 +2097,9 @@ litest_event_type_str(struct libinput_event *event) > case LIBINPUT_EVENT_TABLET_PAD_STRIP: > str = "TABLET PAD STRIP"; > break; > + case LIBINPUT_EVENT_TABLET_PAD_MODE: > + str = "TABLET PAD MODE"; > + break; > } > return str; > } > diff --git a/tools/event-debug.c b/tools/event-debug.c > index a5608d2..c875035 100644 > --- a/tools/event-debug.c > +++ b/tools/event-debug.c > @@ -130,6 +130,9 @@ print_event_header(struct libinput_event *ev) > case LIBINPUT_EVENT_TABLET_PAD_STRIP: > type = "TABLET_PAD_STRIP"; > break; > + case LIBINPUT_EVENT_TABLET_PAD_MODE: > + type = "TABLET_PAD_STRIP"; "TABLET_PAD_MODE" > + break; > } > > printf("%-7s %-16s ", libinput_device_get_sysname(dev), type); > @@ -232,16 +235,18 @@ print_device_notify(struct libinput_event *ev) > > if (libinput_device_has_capability(dev, > LIBINPUT_DEVICE_CAP_TABLET_PAD)) { > - int nbuttons, nstrips, nrings; > + int nbuttons, nstrips, nrings, ngroups; > > nbuttons = libinput_device_tablet_pad_get_num_buttons(dev); > nstrips = libinput_device_tablet_pad_get_num_strips(dev); > nrings = libinput_device_tablet_pad_get_num_rings(dev); > + ngroups = libinput_device_tablet_pad_get_num_mode_groups(dev); > > - printf(" buttons:%d strips:%d rings:%d", > + printf(" buttons:%d strips:%d rings:%d mode groups:%d", > nbuttons, > nstrips, > - nrings); > + nrings, > + ngroups); > } > > printf("\n"); > @@ -604,14 +609,25 @@ static void > print_tablet_pad_button_event(struct libinput_event *ev) > { > struct libinput_event_tablet_pad *p = > libinput_event_get_tablet_pad_event(ev); > + struct libinput_tablet_pad_mode_group *group; > enum libinput_button_state state; > + unsigned int button, mode; > > print_event_time(libinput_event_tablet_pad_get_time(p)); > > + button = libinput_event_tablet_pad_get_button_number(p), > state = libinput_event_tablet_pad_get_button_state(p); > - printf("%3d %s\n", > - libinput_event_tablet_pad_get_button_number(p), > - state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released"); > + mode = libinput_event_tablet_pad_get_mode(p); > + printf("%3d %s (mode %d)", > + button, > + state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released", > + mode); > + > + group = libinput_event_tablet_pad_get_mode_group(p); > + if (libinput_tablet_pad_mode_group_button_is_toggle(group, button)) > + printf(" <mode toggle>"); > + > + printf("\n"); > } > > static void > @@ -619,6 +635,7 @@ print_tablet_pad_ring_event(struct libinput_event *ev) > { > struct libinput_event_tablet_pad *p = > libinput_event_get_tablet_pad_event(ev); > const char *source = "<invalid>"; > + unsigned int mode; > > print_event_time(libinput_event_tablet_pad_get_time(p)); > > @@ -631,10 +648,12 @@ print_tablet_pad_ring_event(struct libinput_event *ev) > break; > } > > - printf("ring %d position %.2f (source %s)\n", > + mode = libinput_event_tablet_pad_get_mode(p); > + printf("ring %d position %.2f (source %s) (mode %d)\n", > libinput_event_tablet_pad_get_ring_number(p), > libinput_event_tablet_pad_get_ring_position(p), > - source); > + source, > + mode); > } > > static void > @@ -642,6 +661,7 @@ print_tablet_pad_strip_event(struct libinput_event *ev) > { > struct libinput_event_tablet_pad *p = > libinput_event_get_tablet_pad_event(ev); > const char *source = "<invalid>"; > + unsigned int mode; > > print_event_time(libinput_event_tablet_pad_get_time(p)); > > @@ -654,10 +674,28 @@ print_tablet_pad_strip_event(struct libinput_event *ev) > break; > } > > - printf("strip %d position %.2f (source %s)\n", > + mode = libinput_event_tablet_pad_get_mode(p); > + printf("strip %d position %.2f (source %s) (mode %d)\n", > libinput_event_tablet_pad_get_strip_number(p), > libinput_event_tablet_pad_get_strip_position(p), > - source); > + source, > + mode); > +} > + > +static void > +print_tablet_pad_mode_event(struct libinput_event *ev) > +{ > + struct libinput_event_tablet_pad *p = > libinput_event_get_tablet_pad_event(ev); > + struct libinput_tablet_pad_mode_group *group; > + unsigned int mode; > + > + print_event_time(libinput_event_tablet_pad_get_time(p)); > + > + group = libinput_event_tablet_pad_get_mode_group(p); > + mode = libinput_event_tablet_pad_get_mode(p); > + printf("group %d mode %d\n", > + libinput_tablet_pad_mode_group_get_index(group), > + mode); > } > > static int > @@ -748,6 +786,9 @@ handle_and_print_events(struct libinput *li) > case LIBINPUT_EVENT_TABLET_PAD_STRIP: > print_tablet_pad_strip_event(ev); > break; > + case LIBINPUT_EVENT_TABLET_PAD_MODE: > + print_tablet_pad_mode_event(ev); > + break; > } > > libinput_event_destroy(ev); > diff --git a/tools/event-gui.c b/tools/event-gui.c > index 605f00a..5eeea1e 100644 > --- a/tools/event-gui.c > +++ b/tools/event-gui.c > @@ -843,6 +843,7 @@ handle_event_libinput(GIOChannel *source, GIOCondition > condition, gpointer data) > case LIBINPUT_EVENT_TABLET_PAD_BUTTON: > case LIBINPUT_EVENT_TABLET_PAD_RING: > case LIBINPUT_EVENT_TABLET_PAD_STRIP: > + case LIBINPUT_EVENT_TABLET_PAD_MODE: > break; > } > > -- > 2.7.4 > > _______________________________________________ > wayland-devel mailing list > [email protected] > https://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
