From patchwork Sat Aug 14 16:29:27 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henrik Rydberg X-Patchwork-Id: 61731 X-Patchwork-Delegate: leann.ogasawara@canonical.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 66305B70DE for ; Sun, 15 Aug 2010 02:30:04 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1OkJcE-0003LY-Qe; Sat, 14 Aug 2010 17:29:50 +0100 Received: from ch-smtp02.sth.basefarm.net ([80.76.149.213]) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1OkJcD-0003LP-4M for kernel-team@lists.ubuntu.com; Sat, 14 Aug 2010 17:29:49 +0100 Received: from c83-248-196-134.bredband.comhem.se ([83.248.196.134]:35409 helo=alnilam) by ch-smtp02.sth.basefarm.net with smtp (Exim 4.68) (envelope-from ) id 1OkJbv-0002SZ-91; Sat, 14 Aug 2010 18:29:35 +0200 Received: by alnilam (sSMTP sendmail emulation); Sat, 14 Aug 2010 17:29:31 +0100 From: "Henrik Rydberg" To: kernel-team@lists.ubuntu.com Subject: [PATCH] hid: 3m: Simplify touchsreen emulation logic Date: Sat, 14 Aug 2010 17:29:27 +0100 Message-Id: <1281803367-2590-1-git-send-email-rydberg@euromail.se> X-Mailer: git-send-email 1.7.1 X-Originating-IP: 83.248.196.134 X-Scan-Result: No virus found in message 1OkJbv-0002SZ-91. X-Scan-Signature: ch-smtp02.sth.basefarm.net 1OkJbv-0002SZ-91 c0352663f6e10ae9f4ee1a27dcb2f204 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com The ten-finger 3M screen M2256PW has a kernel driver already (hid-3m-pct), but with a couple of glitches: 1. The one-touch down/up, which emits BTN_TOUCH events, sometimes does not work properly. This results in buttons getting stuck in the button-down state in the window manager. 2. The action after touch-up in one spot followed by a touch-down in another spot sometimes causes a sequence of strange finger-tracing events along the perimeter of the rectangle between the two spots. The root of the problem lies in how the kernel inteprets the HID hybrid event type which is used by the 3M device [1]. While a proper HID solution is being worked out upstream, this patch simplifies the driver logic such that BTN_TOUCH and ABS_X/Y events are emitted properly, in effect papering over the worst problems. Suggested for inclusion in Maverick. [1] Suggested by Stephane Chatty, who also confirms the observed problems. Signed-off-by: Henrik Rydberg Acked-by: Chase Douglas --- drivers/hid/hid-3m-pct.c | 47 +++++++++------------------------------------ 1 files changed, 10 insertions(+), 37 deletions(-) diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c index 2a0d56b..fc57c0c 100644 --- a/drivers/hid/hid-3m-pct.c +++ b/drivers/hid/hid-3m-pct.c @@ -125,9 +125,7 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, */ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) { - struct mmm_finger *oldest = 0; - bool pressed = false, released = false; - int i; + int i, index = -1; /* * we need to iterate on all fingers to decide if we have a press @@ -149,45 +147,20 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? f->h : f->w); input_mt_sync(input); - /* - * touchscreen emulation: maintain the age rank - * of this finger, decide if we have a press - */ - if (f->rank == 0) { - f->rank = ++(md->num); - if (f->rank == 1) - pressed = true; - } - if (f->rank == 1) - oldest = f; - } else { - /* this finger took off the screen */ - /* touchscreen emulation: maintain age rank of others */ - int j; - - for (j = 0; j < 10; ++j) { - struct mmm_finger *g = &md->f[j]; - if (g->rank > f->rank) { - g->rank--; - if (g->rank == 1) - oldest = g; - } - } - f->rank = 0; - --(md->num); - if (md->num == 0) - released = true; + + if (index < 0) + index = i; } f->valid = 0; } /* touchscreen emulation */ - if (oldest) { - if (pressed) - input_event(input, EV_KEY, BTN_TOUCH, 1); - input_event(input, EV_ABS, ABS_X, oldest->x); - input_event(input, EV_ABS, ABS_Y, oldest->y); - } else if (released) { + if (index >= 0) { + struct mmm_finger *f = &md->f[index]; + input_event(input, EV_KEY, BTN_TOUCH, 1); + input_event(input, EV_ABS, ABS_X, f->x); + input_event(input, EV_ABS, ABS_Y, f->y); + } else { input_event(input, EV_KEY, BTN_TOUCH, 0); } }