add ability to work with constant-only driver
This commit is contained in:
+31
-2
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user