Module Name: src Committed By: mlelstv Date: Sat Sep 17 06:33:55 UTC 2022
Modified Files: src/sys/dev/pckbport: synaptics.c Log Message: - synaptics_filter_policy no longer generates movements from stale data. - button boundary is now computed consistently. - multi finger operation now works for MULTI_FINGER and MULTI_FINGER_REPORT. Fixes PR kern/56476 and probably kern/56998. To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/dev/pckbport/synaptics.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pckbport/synaptics.c diff -u src/sys/dev/pckbport/synaptics.c:1.79 src/sys/dev/pckbport/synaptics.c:1.80 --- src/sys/dev/pckbport/synaptics.c:1.79 Tue May 31 08:43:16 2022 +++ src/sys/dev/pckbport/synaptics.c Sat Sep 17 06:33:55 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: synaptics.c,v 1.79 2022/05/31 08:43:16 andvar Exp $ */ +/* $NetBSD: synaptics.c,v 1.80 2022/09/17 06:33:55 mlelstv Exp $ */ /* * Copyright (c) 2005, Steve C. Woodford @@ -48,7 +48,7 @@ #include "opt_pms.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.79 2022/05/31 08:43:16 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.80 2022/09/17 06:33:55 mlelstv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -296,32 +296,33 @@ pms_synaptics_set_boundaries(void) } if (synaptics_button_pct != synaptics_old_button_pct) { - synaptics_button_boundary = synaptics_edge_bottom + - ((unsigned long) synaptics_button_pct * - (synaptics_edge_top - synaptics_edge_bottom)) / 100; synaptics_old_button_pct = synaptics_button_pct; - synaptics_old_button_boundary = synaptics_button_boundary; } if (synaptics_button_boundary != synaptics_old_button_boundary) { if (synaptics_button_boundary <= synaptics_edge_bottom) { synaptics_button_pct = 0; - synaptics_button_boundary = synaptics_edge_bottom; + } else if (synaptics_button_boundary >= synaptics_edge_top) { + synaptics_button_pct = 100; } else { - synaptics_button_pct = 100 - - ((unsigned long) 100 * synaptics_button_boundary) / - (synaptics_edge_top - synaptics_edge_bottom); + synaptics_button_pct = + (synaptics_button_boundary - synaptics_edge_bottom) + * 100 + / (synaptics_edge_top - synaptics_edge_bottom); } - synaptics_old_button_boundary = synaptics_button_boundary; + synaptics_old_button_pct = synaptics_button_pct; } /* - * recalculate the button boundary yet again just in case the - * bottom edge changed above. + * calculate the button boundary */ - synaptics_button_boundary = synaptics_edge_bottom + - ((unsigned long) synaptics_button_pct * - (synaptics_edge_top - synaptics_edge_bottom)) / 100; + if (synaptics_edge_top > synaptics_edge_bottom) { + synaptics_button_boundary = synaptics_edge_bottom + + ((unsigned long) synaptics_button_pct * + (synaptics_edge_top - synaptics_edge_bottom)) / 100; + } else { + synaptics_button_boundary = synaptics_edge_bottom; + } synaptics_old_button_boundary = synaptics_button_boundary; synaptics_button2 = synaptics_edge_left + @@ -1231,7 +1232,7 @@ pms_synaptics_get_fingers(struct pms_sof * just punt with one finger, if this really is a palm * then it will be caught later. */ - if (sc->flags & SYN_FLAG_HAS_MULTI_FINGER) { + if (sc->flags & (SYN_FLAG_HAS_MULTI_FINGER | SYN_FLAG_HAS_MULTI_FINGER_REPORT)) { if (w == SYNAPTICS_WIDTH_TWO_FINGERS) fingers = 2; else if (w == SYNAPTICS_WIDTH_THREE_OR_MORE) @@ -1636,75 +1637,13 @@ skip_position: nsp.sp_primary, nsp.sp_secondary, v, primary_finger, secondary_finger); + pms_synaptics_process_packet(psc, &nsp); - /* If no fingers and we at least saw the primary finger - * or the buttons changed then process the last packet. - */ - if (pms_synaptics_get_fingers(psc, nsp.sp_w, nsp.sp_z) == 0 || - nsp.sp_left != packet.sp_left || - nsp.sp_right != packet.sp_right || - nsp.sp_middle != packet.sp_middle || - nsp.sp_up != packet.sp_up || - nsp.sp_down != packet.sp_down) { - if (nsp.sp_primary == 1) { - pms_synaptics_process_packet(psc, &nsp); - sc->packet_count[SYN_PRIMARY_FINGER] = 0; - sc->packet_count[SYN_SECONDARY_FINGER] = 0; - } - - /* clear the fingers seen since we have processed */ + /* Clear fingers */ + if ((nsp.sp_primary && nsp.sp_finger_count <= 1) || nsp.sp_secondary) { nsp.sp_primary = 0; nsp.sp_secondary = 0; nsp.sp_finger_status = 0; - } else if (nsp.sp_finger_count != packet.sp_finger_count) { - /* - * If the number of fingers changes then send the current packet - * for processing and restart the process. - */ - if (packet.sp_primary == 1) { - pms_synaptics_process_packet(psc, &packet); - sc->packet_count[SYN_PRIMARY_FINGER]++; - } - - sc->packet_count[SYN_PRIMARY_FINGER] = 0; - sc->packet_count[SYN_SECONDARY_FINGER] = 0; - } - - /* Only one finger, process the new packet */ - if (nsp.sp_finger_count == 1) { - if (nsp.sp_finger_count != packet.sp_finger_count) { - sc->packet_count[SYN_PRIMARY_FINGER] = 0; - sc->packet_count[SYN_SECONDARY_FINGER] = 0; - } - pms_synaptics_process_packet(psc, &nsp); - - /* clear the fingers seen since we have processed */ - nsp.sp_primary = 0; - nsp.sp_secondary = 0; - nsp.sp_finger_status = 0; - - sc->packet_count[SYN_PRIMARY_FINGER]++; - } - - /* - * More than one finger and we have seen the primary and secondary - * fingers then process the packet. - */ - if ((nsp.sp_finger_count > 1) && (nsp.sp_primary == 1) - && (nsp.sp_secondary == 1)) { - if (nsp.sp_finger_count != packet.sp_finger_count) { - sc->packet_count[SYN_PRIMARY_FINGER] = 0; - sc->packet_count[SYN_SECONDARY_FINGER] = 0; - } - pms_synaptics_process_packet(psc, &nsp); - - /* clear the fingers seen since we have processed */ - nsp.sp_primary = 0; - nsp.sp_secondary = 0; - nsp.sp_finger_status = 0; - - sc->packet_count[SYN_PRIMARY_FINGER]++; - sc->packet_count[SYN_SECONDARY_FINGER]++; } memcpy(&packet, &nsp, sizeof(packet)); @@ -2095,10 +2034,10 @@ synaptics_filter_policy(struct synaptics * tiny finger movements. */ if (count >= SYN_HIST_SIZE) { - a = (history[(count + 0) % SYN_HIST_SIZE] + - history[(count + 1) % SYN_HIST_SIZE]) / 2; + a = (history[(count - 2) % SYN_HIST_SIZE] + + history[(count - 1) % SYN_HIST_SIZE]) / 2; - b = (value + history[(count + 0) % SYN_HIST_SIZE]) / 2; + b = (value + history[(count - 1) % SYN_HIST_SIZE]) / 2; rv = b - a; @@ -2114,7 +2053,7 @@ synaptics_filter_policy(struct synaptics /* * Add the new value to the history buffer. */ - history[(count + 1) % SYN_HIST_SIZE] = value; + history[(count + 0) % SYN_HIST_SIZE] = value; return (rv); } @@ -2201,6 +2140,7 @@ synaptics_movement(struct synaptics_soft dy = synaptics_filter_policy(sc, 0, sc->history_y[SYN_PRIMARY_FINGER], sp->sp_y, sc->packet_count[SYN_PRIMARY_FINGER]); + sc->packet_count[SYN_PRIMARY_FINGER]++; if (sp->sp_finger_count > 1) { sdx = synaptics_filter_policy(sc, 1, @@ -2209,6 +2149,7 @@ synaptics_movement(struct synaptics_soft sdy = synaptics_filter_policy(sc, 1, sc->history_y[SYN_SECONDARY_FINGER], sp->sp_sy, sc->packet_count[SYN_SECONDARY_FINGER]); + sc->packet_count[SYN_SECONDARY_FINGER]++; DPRINTF(10, sc, "synaptics_movement: dx %d dy %d sdx %d sdy %d\n", dx, dy, sdx, sdy); } @@ -2419,6 +2360,9 @@ pms_synaptics_process_packet(struct pms_ sc->rem_x[SYN_SECONDARY_FINGER] = 0; sc->rem_y[SYN_SECONDARY_FINGER] = 0; dx = dy = 0; + + sc->packet_count[SYN_PRIMARY_FINGER] = 0; + sc->packet_count[SYN_SECONDARY_FINGER] = 0; } } else { /*