add ability to work with constant-only driver

This commit is contained in:
2026-10-14 22:58:53 +03:00
parent 047ab2305f
commit 45c6265b45
+31 -2
View File
@@ -48,6 +48,9 @@ typedef struct _FbdDevVibra {
GUdevDevice *device;
gint fd;
gint id; /* currently used id */
/* The driver advertises rumble or periodic effects but rejects them (Qualcomm qti-haptics) */
gboolean constant_only;
gboolean has_constant;
FbdDevVibraFeatureFlags features;
} FbdDevVibra;
@@ -142,6 +145,8 @@ initable_init (GInitable *initable,
return FALSE;
}
self->has_constant = HAS_FEATURE (FF_CONSTANT, features);
/* Set gain to 75% if supported */
if (HAS_FEATURE(FF_GAIN, features)) {
self->features |= FBD_DEV_VIBRA_FEATURE_GAIN;
@@ -232,6 +237,30 @@ fbd_dev_vibra_new (GUdevDevice *device, GError **error)
NULL));
}
static gboolean
upload_effect (FbdDevVibra *self, struct ff_effect *effect, double magnitude)
{
struct ff_effect constant = { 0 };
if (!self->constant_only) {
if (ioctl (self->fd, EVIOCSFF, effect) != -1)
return TRUE;
if (errno != EINVAL || !self->has_constant)
return FALSE;
g_debug ("Effect type %u rejected, using constant effects", effect->type);
self->constant_only = TRUE;
}
constant.type = FF_CONSTANT;
constant.id = -1;
constant.u.constant.level = 0x7FFF * magnitude;
constant.replay = effect->replay;
if (ioctl (self->fd, EVIOCSFF, &constant) == -1)
return FALSE;
effect->id = constant.id;
return TRUE;
}
gboolean
fbd_dev_vibra_rumble (FbdDevVibra *self, double magnitude, guint duration, gboolean upload)
{
@@ -250,7 +279,7 @@ fbd_dev_vibra_rumble (FbdDevVibra *self, double magnitude, guint duration, gbool
if (upload) {
g_debug("Uploading rumbling vibra effect (%d)", self->fd);
if (ioctl(self->fd, EVIOCSFF, &effect) == -1) {
if (!upload_effect (self, &effect, magnitude)) {
g_warning ("Failed to upload rumbling vibra effect: %s", g_strerror (errno));
return FALSE;
}
@@ -301,7 +330,7 @@ fbd_dev_vibra_periodic (FbdDevVibra *self,
effect.replay.delay = 200;
g_debug("Uploading periodic effect (%d)", self->fd);
if (ioctl(self->fd, EVIOCSFF, &effect) == -1) {
if (!upload_effect (self, &effect, magnitude)) {
g_warning ("Failed to upload periodic vibra effect: %s", g_strerror (errno));
return FALSE;
}