plugin: add hooks to disable internal features

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
This commit is contained in:
Peter Hutterer 2025-06-25 13:37:23 +10:00
parent 4f0b82800a
commit 7ac051ab41
7 changed files with 126 additions and 0 deletions

View file

@ -36,6 +36,7 @@
#include "evdev-frame.h"
#include "filter.h"
#include "libinput-feature.h"
#include "libinput-private.h"
#include "linux/input.h"
#include "quirks.h"
@ -352,6 +353,9 @@ struct evdev_dispatch_interface {
void (*left_handed_toggle)(struct evdev_dispatch *dispatch,
struct evdev_device *device,
bool left_handed_enabled);
void (*disable_feature)(struct evdev_dispatch *dispatch,
enum libinput_feature feature);
};
enum evdev_dispatch_type {
@ -389,6 +393,14 @@ evdev_libinput_context(const struct evdev_device *device)
return device->base.seat->libinput;
}
static inline void
evdev_device_disable_feature(struct evdev_device *device, enum libinput_feature feature)
{
if (device->dispatch && device->dispatch->interface &&
device->dispatch->interface->disable_feature)
device->dispatch->interface->disable_feature(device->dispatch, feature);
}
static inline bool
evdev_device_has_model_quirk(struct evdev_device *device, enum quirk model_quirk)
{

26
src/libinput-feature.h Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright © 2025 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#pragma once
enum libinput_feature { LIBINPUT_FEATURE_BUTTON_DEBOUNCING = 1, _LIBINPUT_N_FEATURES };

View file

@ -34,6 +34,7 @@
#include "evdev-frame.h"
#include "libinput.h"
enum libinput_feature;
struct libinput;
struct libinput_plugin;
@ -95,3 +96,9 @@ void
libinput_plugin_system_notify_evdev_frame(struct libinput_plugin_system *system,
struct libinput_device *device,
struct evdev_frame *frame);
void
libinput_plugin_system_notify_device_feature_disabled(
struct libinput_plugin_system *system,
struct libinput_device *device,
enum libinput_feature feature);

View file

@ -30,12 +30,14 @@
#include "evdev-frame.h"
#include "evdev-plugin.h"
#include "libinput-feature.h"
#include "libinput-plugin-button-debounce.h"
#include "libinput-plugin-lua.h"
#include "libinput-plugin-mouse-wheel-lowres.h"
#include "libinput-plugin-mouse-wheel.h"
#include "libinput-plugin-mtdev.h"
#include "libinput-plugin-private.h"
#include "libinput-plugin-system.h"
#include "libinput-plugin-tablet-double-tool.h"
#include "libinput-plugin-tablet-eraser-button.h"
#include "libinput-plugin-tablet-forced-tool.h"
@ -208,6 +210,22 @@ libinput_plugin_enable_evdev_usage(struct libinput_plugin *plugin,
evdev_mask_set_usage(plugin->mask, evdev_usage_from(usage));
}
void
libinput_plugin_disable_device_feature(struct libinput_plugin *plugin,
struct libinput_device *device,
enum libinput_feature feature)
{
struct libinput *libinput = plugin->libinput;
/* During device-added, only some plugins are loaded so this notifies
* some of the plugins. All plugins are notified once device-added is
* complete. */
libinput_plugin_system_notify_device_feature_disabled(&libinput->plugin_system,
device,
feature);
bitmask_set_bit(&device->disabled_features, feature);
}
struct plugin_queued_event {
struct list link;
struct evdev_frame *frame; /* owns a ref */
@ -501,6 +519,21 @@ libinput_plugin_system_notify_device_added(struct libinput_plugin_system *system
libinput_plugin_notify_device_added(plugin, device);
}
libinput_plugin_system_drop_unregistered_plugins(system);
/* Now that we added all our devices in all our plugins, notify
* all plugins about disabled features. Some plugins may get
* this notification twice but they should be able to handle that
* case.
*/
enum libinput_feature feature = _LIBINPUT_N_FEATURES;
while (--feature > 0) {
if (bitmask_bit_is_set(device->disabled_features, feature)) {
libinput_plugin_system_notify_device_feature_disabled(system,
device,
feature);
}
}
}
void
@ -538,6 +571,22 @@ libinput_plugin_system_notify_tablet_tool_configured(
libinput_plugin_system_drop_unregistered_plugins(system);
}
void
libinput_plugin_system_notify_device_feature_disabled(
struct libinput_plugin_system *system,
struct libinput_device *device,
enum libinput_feature feature)
{
libinput_device_disable_feature(device, feature);
struct libinput_plugin *plugin;
list_for_each_safe(plugin, &system->plugins, link) {
if (plugin->interface->feature_disabled)
plugin->interface->feature_disabled(plugin, device, feature);
}
libinput_plugin_system_drop_unregistered_plugins(system);
}
static void
libinput_plugin_process_frame(struct libinput_plugin *plugin,
struct libinput_device *device,

View file

@ -39,6 +39,7 @@ struct libinput_device;
struct libinput_tablet_tool;
struct libinput_plugin;
enum libinput_log_priority;
enum libinput_feature;
#define plugin_log_debug(p_, ...) plugin_log_msg((p_), LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__)
#define plugin_log_info(p_, ...) plugin_log_msg((p_), LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__)
@ -107,6 +108,14 @@ struct libinput_plugin_interface {
*/
void (*tool_configured)(struct libinput_plugin *plugin,
struct libinput_tablet_tool *tool);
/**
* Notification that the given feature was disabled on
* the given device.
*/
void (*feature_disabled)(struct libinput_plugin *plugin,
struct libinput_device *device,
enum libinput_feature feature);
};
/**
@ -159,6 +168,11 @@ libinput_plugin_enable_device_event_frame(struct libinput_plugin *plugin,
struct libinput_device *device,
bool enable);
void
libinput_plugin_disable_device_feature(struct libinput_plugin *plugin,
struct libinput_device *device,
enum libinput_feature feature);
/**
* Mask this plugin's evdev_frame function to be called only
* if the frame **contains** the given evdev usage. Plugins

View file

@ -35,6 +35,7 @@
#include <libwacom/libwacom.h>
#endif
#include "util-bits.h"
#include "util-newtype.h"
#include "libinput-log.h"
@ -528,6 +529,11 @@ struct libinput_device {
struct libinput_device_config config;
bitmask_t plugin_frame_callbacks;
/**
* Lua plugins see the device before our internal
* plugins do any calls need to be cached.
*/
bitmask_t disabled_features;
void (*inject_evdev_frame)(struct libinput_device *device,
struct evdev_frame *frame);
@ -724,6 +730,10 @@ libinput_device_init(struct libinput_device *device, struct libinput_seat *seat)
bool
libinput_device_has_model_quirk(struct libinput_device *device, enum quirk model_quirk);
void
libinput_device_disable_feature(struct libinput_device *device,
enum libinput_feature feature);
struct libinput_device_group *
libinput_device_group_create(struct libinput *libinput, const char *identifier);

View file

@ -38,6 +38,7 @@
#include "util-libinput.h"
#include "evdev.h"
#include "libinput-feature.h"
#include "libinput-private.h"
#include "libinput.h"
#include "quirks.h"
@ -2166,6 +2167,13 @@ libinput_device_unref(struct libinput_device *device)
return device;
}
void
libinput_device_disable_feature(struct libinput_device *device,
enum libinput_feature feature)
{
evdev_device_disable_feature((struct evdev_device *)device, feature);
}
LIBINPUT_EXPORT int
libinput_get_fd(struct libinput *libinput)
{