[PATCH v3 22/23] Scroll: Prepare ScrollData for smooth scrolling
Daniel Stone
daniel at fooishbar.org
Thu Jun 23 15:12:57 PDT 2011
Convert ScrollData from up/down/left/right members for button presses,
to more fine-grained delta_x and delta_y members, and move these to
priv->scroll.
Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
src/synaptics.c | 135 +++++++++++++++++++--------------------------------
src/synapticsstr.h | 2 +
2 files changed, 52 insertions(+), 85 deletions(-)
v3: Move ScrollData into priv->scroll to fix non-smooth-scrolling with
small-delta packets.
Fixed indentation.
Variables renamed.
Store values normalised to 1.0 per button event, as with old ScrollData,
rather than pixel deltas.
diff --git a/src/synaptics.c b/src/synaptics.c
index 03a67ab..f17a33b 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -2016,10 +2016,6 @@ out:
return delay;
}
-struct ScrollData {
- int left, right, up, down;
-};
-
static double
estimate_delta_circ(SynapticsPrivate *priv)
{
@@ -2100,13 +2096,11 @@ stop_coasting(SynapticsPrivate *priv)
static int
HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
- edge_type edge, Bool finger, struct ScrollData *sd)
+ edge_type edge, Bool finger)
{
SynapticsParameters *para = &priv->synpara;
int delay = 1000000000;
- sd->left = sd->right = sd->up = sd->down = 0;
-
if ((priv->synpara.touchpad_off == 2) || (priv->finger_state == FS_BLOCKED)) {
stop_coasting(priv);
priv->circ_scroll_on = FALSE;
@@ -2282,96 +2276,56 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
if (priv->vert_scroll_edge_on || priv->vert_scroll_twofinger_on) {
/* + = down, - = up */
- int delta = para->scroll_dist_vert;
- if (delta > 0) {
- while (hw->y - priv->scroll.last_y > delta) {
- sd->down++;
- priv->scroll.last_y += delta;
- }
- while (hw->y - priv->scroll.last_y < -delta) {
- sd->up++;
- priv->scroll.last_y -= delta;
- }
+ double delta = para->scroll_dist_vert;
+ if (delta > 0 && hw->y != priv->scroll.last_y) {
+ priv->scroll.delta_y += (hw->y - priv->scroll.last_y) / delta;
+ priv->scroll.last_y = hw->y;
}
}
if (priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on) {
/* + = right, - = left */
- int delta = para->scroll_dist_horiz;
- if (delta > 0) {
- while (hw->x - priv->scroll.last_x > delta) {
- sd->right++;
- priv->scroll.last_x += delta;
- }
- while (hw->x - priv->scroll.last_x < -delta) {
- sd->left++;
- priv->scroll.last_x -= delta;
- }
+ double delta = para->scroll_dist_horiz;
+ if (delta > 0 && hw->x != priv->scroll.last_x) {
+ priv->scroll.delta_x += (hw->x - priv->scroll.last_x) / delta;
+ priv->scroll.last_x = hw->x;
}
}
if (priv->circ_scroll_on) {
/* + = counter clockwise, - = clockwise */
double delta = para->scroll_dist_circ;
- if (delta >= 0.005) {
- while (diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y)) > delta) {
- if (priv->circ_scroll_vert)
- sd->up++;
- else
- sd->right++;
- priv->scroll.last_a += delta;
- if (priv->scroll.last_a > M_PI)
- priv->scroll.last_a -= 2 * M_PI;
- }
- while (diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y)) < -delta) {
- if (priv->circ_scroll_vert)
- sd->down++;
- else
- sd->left++;
- priv->scroll.last_a -= delta;
- if (priv->scroll.last_a < -M_PI)
- priv->scroll.last_a += 2 * M_PI;
- }
- }
+ double diff = diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y));
+ if (delta >= 0.005 && diff != 0.0) {
+ if (priv->circ_scroll_vert)
+ priv->scroll.delta_y += diff / delta;
+ else
+ priv->scroll.delta_x += diff / delta;
+ priv->scroll.last_a = angle(priv, hw->x, hw->y);
+ }
}
if (priv->scroll.coast_speed_y) {
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
double ddy = para->coasting_friction * dtime;
- priv->scroll.coast_delta_y += priv->scroll.coast_speed_y * dtime;
+ priv->scroll.delta_y += priv->scroll.coast_speed_y * dtime;
delay = MIN(delay, POLL_MS);
- while (priv->scroll.coast_delta_y > 1.0) {
- sd->down++;
- priv->scroll.coast_delta_y -= 1.0;
- }
- while (priv->scroll.coast_delta_y < -1.0) {
- sd->up++;
- priv->scroll.coast_delta_y += 1.0;
- }
if (abs(priv->scroll.coast_speed_y) < ddy) {
priv->scroll.coast_speed_y = 0;
priv->scroll.packets_this_scroll = 0;
} else {
- priv->scroll.coast_speed_y += (priv->scroll.coast_speed_y < 0 ? ddy : -1*ddy);
+ priv->scroll.coast_speed_y += (priv->scroll.coast_speed_y < 0 ? ddy : -ddy);
}
}
if (priv->scroll.coast_speed_x) {
double dtime = (hw->millis - priv->scroll.last_millis) / 1000.0;
double ddx = para->coasting_friction * dtime;
- priv->scroll.coast_delta_x += priv->scroll.coast_speed_x * dtime;
+ priv->scroll.delta_x += priv->scroll.coast_speed_x * dtime;
delay = MIN(delay, POLL_MS);
- while (priv->scroll.coast_delta_x > 1.0) {
- sd->right++;
- priv->scroll.coast_delta_x -= 1.0;
- }
- while (priv->scroll.coast_delta_x < -1.0) {
- sd->left++;
- priv->scroll.coast_delta_x += 1.0;
- }
if (abs(priv->scroll.coast_speed_x) < ddx) {
priv->scroll.coast_speed_x = 0;
priv->scroll.packets_this_scroll = 0;
} else {
- priv->scroll.coast_speed_x += (priv->scroll.coast_speed_x < 0 ? ddx : -1*ddx);
+ priv->scroll.coast_speed_x += (priv->scroll.coast_speed_x < 0 ? ddx : -ddx);
}
}
@@ -2510,26 +2464,40 @@ post_button_click(const InputInfoPtr pInfo, const int button)
static void
-post_scroll_events(const InputInfoPtr pInfo, struct ScrollData scroll)
+post_scroll_events(const InputInfoPtr pInfo)
{
- while (scroll.up-- > 0)
+ SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
+ SynapticsParameters *para = &priv->synpara;
+
+ while (priv->scroll.delta_y <= -1.0)
+ {
post_button_click(pInfo, 4);
+ priv->scroll.delta_y += 1.0;
+ }
- while (scroll.down-- > 0)
+ while (priv->scroll.delta_y >= 1.0)
+ {
post_button_click(pInfo, 5);
+ priv->scroll.delta_y -= 1.0;
+ }
- while (scroll.left-- > 0)
+ while (priv->scroll.delta_x <= -1.0)
+ {
post_button_click(pInfo, 6);
+ priv->scroll.delta_x += 1.0;
+ }
- while (scroll.right-- > 0)
+ while (priv->scroll.delta_x >= 1.0)
+ {
post_button_click(pInfo, 7);
+ priv->scroll.delta_x -= 1.0;
+ }
}
static inline int
repeat_scrollbuttons(const InputInfoPtr pInfo,
const struct SynapticsHwState *hw,
- int buttons, CARD32 now, int delay,
- struct ScrollData *sd)
+ int buttons, CARD32 now, int delay)
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
@@ -2567,13 +2535,13 @@ repeat_scrollbuttons(const InputInfoPtr pInfo,
id = ffs(change);
change &= ~(1 << (id - 1));
if (id == 4)
- sd->up++;
+ priv->scroll.delta_y -= 1.0;
else if (id == 5)
- sd->down++;
+ priv->scroll.delta_y += 1.0;
else if (id == 6)
- sd->left++;
+ priv->scroll.delta_x -= 1.0;
else if (id == 7)
- sd->right++;
+ priv->scroll.delta_x += 1.0;
}
priv->nextRepeat = now + repeat_delay;
@@ -2604,7 +2572,6 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
int dx, dy, buttons, id;
edge_type edge = NO_EDGE;
int change;
- struct ScrollData scroll;
int double_click = FALSE;
int delay = 1000000000;
int timeleft;
@@ -2669,8 +2636,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
if (inside_active_area)
{
/* Don't bother about scrolling in the dead area of the touchpad. */
- timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED),
- &scroll);
+ timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED));
if (timeleft > 0)
delay = MIN(delay, timeleft);
@@ -2738,15 +2704,14 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
}
if (priv->has_scrollbuttons)
- delay = repeat_scrollbuttons(pInfo, hw, buttons, now, delay, &scroll);
+ delay = repeat_scrollbuttons(pInfo, hw, buttons, now, delay);
/* Process scroll events only if coordinates are
* in the Synaptics Area
*/
if (inside_active_area &&
- (scroll.down != 0 || scroll.up != 0 || scroll.left != 0 ||
- scroll.right != 0)) {
- post_scroll_events(pInfo, scroll);
+ (priv->scroll.delta_x != 0.0 || priv->scroll.delta_y != 0.0)) {
+ post_scroll_events(pInfo);
priv->scroll.last_millis = hw->millis;
}
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 00d3fb4..c53de53 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -202,6 +202,8 @@ typedef struct _SynapticsPrivateRec
struct {
int last_x; /* last x-scroll position */
int last_y; /* last y-scroll position */
+ double delta_x; /* accumulated horiz scroll delta */
+ double delta_y; /* accumulated vert scroll delta */
double last_a; /* last angle-scroll position */
CARD32 last_millis; /* time last scroll event posted */
double coast_speed_x; /* Horizontal coasting speed */
--
1.7.5.4
More information about the xorg-devel
mailing list