return 0;
}
+static void ffpl_calculate_trip_times(struct ffpl_effect *eff, const unsigned long now)
+{
+ const struct ff_effect *ueff = &eff->latest;
+
+ eff->start_at = now + msecs_to_jiffies(ueff->replay.delay);
+
+ if (ueff->replay.delay)
+ printk(KERN_NOTICE "KLGDFF: Delayed effect will be started at %lu, now: %lu\n", eff->start_at, now);
+
+ if (ueff->replay.length) {
+ eff->stop_at = eff->start_at + msecs_to_jiffies(ueff->replay.length);
+ printk(KERN_NOTICE "KLGDFF: Finite effect will be stopped at %lu, now: %lu\n", eff->stop_at, now);
+ }
+}
+
/* Destroy request - input device is being destroyed */
static void ffpl_destroy_rq(struct ff_device *ff)
{
struct klgd_plugin *self = dev->ff->private;
struct klgd_plugin_private *priv = self->private;
struct ffpl_effect *eff = &priv->effects[effect_id];
- struct ff_effect *ueff = &eff->latest;
const unsigned long now = jiffies;
klgd_lock_plugins(self->plugins_lock);
if (value) {
eff->repeat = value;
- eff->start_at = now + msecs_to_jiffies(ueff->replay.delay);
+ ffpl_calculate_trip_times(eff, now);
eff->trigger = FFPL_TRIG_START;
-
- if (ueff->replay.delay)
- printk(KERN_NOTICE "KLGDFF: Delayed effect will be started at %lu, now: %lu\n", eff->start_at, now);
-
- if (ueff->replay.length) {
- eff->stop_at = eff->start_at + msecs_to_jiffies(ueff->replay.length);
- printk(KERN_NOTICE "KLGDFF: Finite effect will be stopped at %lu, now: %lu\n", eff->stop_at, now);
- }
} else {
eff->trigger = FFPL_TRIG_STOP;
}
else
eff->trigger = FFPL_TRIG_NONE;
break;
+ case FFPL_TRIG_RESTART:
+ eff->trigger = FFPL_TRIG_STOP;
+ break;
case FFPL_TRIG_RECALC:
if (ffpl_needs_recalculation(&eff->active, now - eff->start_at, eff->stop_at, now))
break;
break;
}
case FFPL_TRIG_STOP:
+ if (eff->repeat > 0) {
+ eff->trigger = FFPL_TRIG_RESTART;
+ break;
+ }
case FFPL_TRIG_NOW:
eff->trigger = FFPL_TRIG_NONE;
break;
case FFPL_TRIG_NOW:
current_t = now;
break;
+ case FFPL_TRIG_RESTART:
+ ffpl_calculate_trip_times(eff, now);
case FFPL_TRIG_START:
current_t = eff->start_at;
eff->change = FFPL_TO_START;
case FFPL_TRIG_STOP:
current_t = eff->stop_at;
eff->change = FFPL_TO_STOP;
+ eff->repeat--;
break;
case FFPL_TRIG_RECALC:
current_t = ffpl_get_recalculation_time(eff);
FFPL_TRIG_NONE, /* No timing event scheduled for and effect */
FFPL_TRIG_NOW, /* State change has been set elsewhere and is to be processed immediately */
FFPL_TRIG_START, /* Effect is to be started */
+ FFPL_TRIG_RESTART,/* Effect is to be restarted */
FFPL_TRIG_STOP, /* Effect is to be stopped */
FFPL_TRIG_RECALC /* Effect needs to be recalculated */
};