diff --git a/src/fbd-dev-vibra.c b/src/fbd-dev-vibra.c index c99444f..85368a4 100644 --- a/src/fbd-dev-vibra.c +++ b/src/fbd-dev-vibra.c @@ -243,7 +243,7 @@ fbd_dev_vibra_rumble (FbdDevVibra *self, double magnitude, guint duration, gbool memset(&effect, 0, sizeof(effect)); effect.type = FF_RUMBLE; effect.id = -1; - effect.u.rumble.strong_magnitude = (0x8000 * magnitude); + effect.u.rumble.strong_magnitude = 0xFFFF * magnitude; effect.u.rumble.weak_magnitude = 0; effect.replay.length = duration; effect.replay.delay = 0; diff --git a/src/fbd-feedback-vibra-rumble.c b/src/fbd-feedback-vibra-rumble.c index a35da03..d89ff52 100644 --- a/src/fbd-feedback-vibra-rumble.c +++ b/src/fbd-feedback-vibra-rumble.c @@ -27,6 +27,7 @@ enum { PROP_0, PROP_COUNT, PROP_PAUSE, + PROP_MAGNITUDE, PROP_LAST_PROP, }; static GParamSpec *props[PROP_LAST_PROP]; @@ -34,12 +35,13 @@ static GParamSpec *props[PROP_LAST_PROP]; typedef struct _FbdFeedbackVibraRumble { FbdFeedbackVibra parent; - guint count; /* number of rumbles */ - guint pause; /* pause in msecs */ + guint count; /* number of rumbles */ + guint pause; /* pause in msecs */ - guint rumble; /* rumble in msecs */ - guint periods; /* number of periods to play */ - guint timer_id; + double magnitude; /* magnitude [0.0, 1.0] */ + guint rumble; /* rumble in msecs */ + guint periods; /* number of periods to play */ + guint timer_id; } FbdFeedbackVibraRumble; G_DEFINE_TYPE (FbdFeedbackVibraRumble, fbd_feedback_vibra_rumble, FBD_TYPE_FEEDBACK_VIBRA); @@ -59,6 +61,9 @@ fbd_feedback_vibra_rumble_set_property (GObject *object, case PROP_PAUSE: self->pause = g_value_get_uint (value); break; + case PROP_MAGNITUDE: + self->magnitude = g_value_get_double (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -80,6 +85,9 @@ fbd_feedback_vibra_rumble_get_property (GObject *object, case PROP_PAUSE: g_value_set_uint (value, self->pause); break; + case PROP_MAGNITUDE: + g_value_set_double (value, self->magnitude); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -95,7 +103,11 @@ on_period_ended (FbdFeedbackVibraRumble *self) g_return_val_if_fail (FBD_IS_FEEDBACK_VIBRA_RUMBLE (self), G_SOURCE_REMOVE); if (self->periods) { - fbd_dev_vibra_rumble (dev, 1.0, self->rumble, FALSE); + double max_strength = fbd_feedback_vibra_get_max_strength (FBD_FEEDBACK_VIBRA (self)); + double magnitude; + + magnitude = MIN (self->magnitude, max_strength); + fbd_dev_vibra_rumble (dev, magnitude, self->rumble, FALSE); self->periods--; return G_SOURCE_CONTINUE; } @@ -120,7 +132,8 @@ fbd_feedback_vibra_rumble_start_vibra (FbdFeedbackVibra *vibra) FbdFeedbackManager *manager = fbd_feedback_manager_get_default (); FbdDevVibra *dev = fbd_feedback_manager_get_dev_vibra (manager); guint duration = fbd_feedback_vibra_get_duration (vibra); - double strength = fbd_feedback_vibra_get_max_strength (FBD_FEEDBACK_VIBRA (self)); + double max_strength = fbd_feedback_vibra_get_max_strength (FBD_FEEDBACK_VIBRA (self)); + double magnitude; guint period; self->rumble = (duration / self->count) - self->pause; @@ -132,9 +145,10 @@ fbd_feedback_vibra_rumble_start_vibra (FbdFeedbackVibra *vibra) period = self->rumble + self->pause; self->periods = self->count; - g_debug ("Rumble Vibra event: duration %d, rumble: %d, pause: %d, period: %d, strength %f", - duration, self->rumble, self->pause, period, strength); - fbd_dev_vibra_rumble (dev, strength, self->rumble, TRUE); + magnitude = MIN (self->magnitude, max_strength); + g_debug ("Rumble Vibra event: magnitude: %f, duration %d, rumble: %d, pause: %d, period: %d", + magnitude, duration, self->rumble, self->pause, period); + fbd_dev_vibra_rumble (dev, magnitude, self->rumble, TRUE); self->periods--; if (self->periods) { self->timer_id = g_timeout_add (period, (GSourceFunc) on_period_ended, self); @@ -181,6 +195,11 @@ fbd_feedback_vibra_rumble_class_init (FbdFeedbackVibraRumbleClass *klass) 0, G_MAXINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + props[PROP_MAGNITUDE] = + g_param_spec_double ("magnitude", "", "", + 0, 1.0, 0.5, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, PROP_LAST_PROP, props); } @@ -188,4 +207,5 @@ static void fbd_feedback_vibra_rumble_init (FbdFeedbackVibraRumble *self) { self->count = 1; + self->magnitude = 0.5; } diff --git a/tests/test-fbd-feedback-vibra.c b/tests/test-fbd-feedback-vibra.c index fca6845..73e4dac 100644 --- a/tests/test-fbd-feedback-vibra.c +++ b/tests/test-fbd-feedback-vibra.c @@ -9,10 +9,50 @@ #define GMOBILE_USE_UNSTABLE_API #include "fbd-feedback-manager.h" #include "fbd-feedback-vibra-pattern.h" +#include "fbd-feedback-vibra-rumble.h" #include +static void +test_fbd_feedback_vibra_rumble (void) +{ + /* Create manager upfront so we can dispose it, otherwise creating + * any feedback would create it implicitly */ + FbdFeedbackManager *manager = fbd_feedback_manager_get_default (); + g_autoptr (GError) err = NULL; + g_autoptr (JsonNode) node = NULL; + GObject *object; + double magnitude; + guint count, duration; + + node = json_from_string("{" + " \"event-name\" : \"button-pressed\"," + " \"type\" : \"VibraRumble\"," + " \"magnitude\" : 0.7," + " \"duration\" : 100," + " \"count\" : 2" + "}", &err); + g_assert_no_error (err); + + object = json_gobject_deserialize (FBD_TYPE_FEEDBACK_VIBRA_RUMBLE, node); + g_test_assert_expected_messages (); + + g_object_get (object, + "magnitude", &magnitude, + "duration", &duration, + "count", &count, + NULL); + + g_assert_cmpfloat_with_epsilon (magnitude, 0.7, FLT_EPSILON); + g_assert_cmpint (duration, ==, 100); + g_assert_cmpint (count, ==, 2); + + g_assert_finalize_object (object); + g_assert_finalize_object (manager); +} + + static void test_fbd_feedback_vibra_pattern (void) { @@ -60,6 +100,7 @@ main (gint argc, gchar *argv[]) { g_test_init (&argc, &argv, NULL); + g_test_add_func("/feedbackd/fbd/feedback-vibra/rumble", test_fbd_feedback_vibra_rumble); g_test_add_func("/feedbackd/fbd/feedback-vibra/pattern", test_fbd_feedback_vibra_pattern); return g_test_run();