All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dtor_core@ameritech.net>
To: Vojtech Pavlik <vojtech@suse.cz>
Cc: Andrew Morton <akpm@osdl.org>, linux-kernel@vger.kernel.org
Subject: [PATCH 9/9] New set of input patches - 14-mousedev-multiplexing.patch
Date: Tue, 11 May 2004 01:11:43 -0500	[thread overview]
Message-ID: <200405110111.45903.dtor_core@ameritech.net> (raw)
In-Reply-To: <200405110111.03332.dtor_core@ameritech.net>


===================================================================


ChangeSet@1.1587.20.15, 2004-05-10 01:44:03-05:00, dtor_core@ameritech.net
  Input: mousedev - better multiplex absolute and relative devices;
         cleanups


 mousedev.c |  260 ++++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 146 insertions(+), 114 deletions(-)


===================================================================



diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Tue May 11 00:59:25 2004
+++ b/drivers/input/mousedev.c	Tue May 11 00:59:25 2004
@@ -2,6 +2,7 @@
  * Input driver to ExplorerPS/2 device driver module.
  *
  * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2004      Dmitry Torokhov
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as published by
@@ -47,15 +48,24 @@
 module_param(yres, uint, 0);
 MODULE_PARM_DESC(yres, "Vertical screen resolution");
 
+struct mousedev_motion {
+	int dx, dy, dz;
+};
+
 struct mousedev {
 	int exist;
 	int open;
 	int minor;
-	int misc;
 	char name[16];
 	wait_queue_head_t wait;
 	struct list_head list;
 	struct input_handle handle;
+
+	struct mousedev_motion packet;
+	unsigned long buttons;
+	unsigned int pkt_count;
+	int old_x[4], old_y[4];
+	unsigned int touch;
 };
 
 struct mousedev_list {
@@ -63,13 +73,10 @@
 	struct mousedev *mousedev;
 	struct list_head node;
 	int dx, dy, dz;
-	int old_x[4], old_y[4];
 	unsigned long buttons;
 	signed char ps2[6];
 	unsigned char ready, buffer, bufsiz;
 	unsigned char mode, imexseq, impsseq;
-	unsigned int pkt_count;
-	unsigned char touch;
 };
 
 #define MOUSEDEV_SEQ_LEN	6
@@ -82,135 +89,157 @@
 static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
 static struct mousedev mousedev_mix;
 
-#define fx(i)  (list->old_x[(list->pkt_count - (i)) & 03])
-#define fy(i)  (list->old_y[(list->pkt_count - (i)) & 03])
+#define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
+#define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 
-static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
+static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
 {
-	int size;
-	int touchpad;
+	if (mousedev->touch) {
+		switch (code) {
+			case ABS_X:
+				fx(0) = value;
+				if (mousedev->pkt_count >= 2)
+					mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
+				break;
 
-	/* Ignore joysticks */
-	if (test_bit(BTN_TRIGGER, handle->dev->keybit))
-		return;
+			case ABS_Y:
+				fy(0) = value;
+				if (mousedev->pkt_count >= 2)
+					mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
+				break;
+		}
+	}
+}
 
-	touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
+static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
+{
+	int size;
 
 	switch (code) {
 		case ABS_X:
-			if (touchpad) {
-				if (list->touch) {
-					fx(0) = value;
-					if (list->pkt_count >= 2)
-						list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
-				}
-			} else {
-				size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
-				if (size == 0) size = xres;
-				list->dx += (value * xres - list->old_x[0]) / size;
-				list->old_x[0] += list->dx * size;
-			}
+			size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+			if (size == 0) size = xres;
+			mousedev->packet.dx = (value * xres - mousedev->old_x[0]) / size;
+			mousedev->old_x[0] = mousedev->packet.dx * size;
 			break;
+
 		case ABS_Y:
-			if (touchpad) {
-				if (list->touch) {
-					fy(0) = value;
-					if (list->pkt_count >= 2)
-						list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
-				}
-			} else {
-				size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-				if (size == 0) size = yres;
-				list->dy -= (value * yres - list->old_y[0]) / size;
-				list->old_y[0] -= list->dy * size;
-			}
+			size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
+			if (size == 0) size = yres;
+			mousedev->packet.dy = (value * yres - mousedev->old_y[0]) / size;
+			mousedev->old_y[0] = mousedev->packet.dy * size;
 			break;
 	}
 }
 
-static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+	switch (code) {
+		case REL_X:	mousedev->packet.dx += value; break;
+		case REL_Y:	mousedev->packet.dy -= value; break;
+		case REL_WHEEL:	mousedev->packet.dz -= value; break;
+	}
+}
+
+static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+	int index;
+
+	switch (code) {
+		case BTN_TOUCH:
+		case BTN_0:
+		case BTN_FORWARD:
+		case BTN_LEFT:		index = 0; break;
+		case BTN_STYLUS:
+		case BTN_1:
+		case BTN_RIGHT:		index = 1; break;
+		case BTN_2:
+		case BTN_STYLUS2:
+		case BTN_MIDDLE:	index = 2; break;
+		case BTN_3:
+		case BTN_BACK:
+		case BTN_SIDE:		index = 3; break;
+		case BTN_4:
+		case BTN_EXTRA:		index = 4; break;
+		default: 		return;
+	}
+
+	if (value) {
+		set_bit(index, &mousedev->buttons);
+		set_bit(index, &mousedev_mix.buttons);
+	} else {
+		clear_bit(index, &mousedev->buttons);
+		clear_bit(index, &mousedev_mix.buttons);
+	}
+}
+
+static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
 {
-	struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL };
-	struct mousedev **mousedev = mousedevs;
 	struct mousedev_list *list;
-	int index, wake;
 
-	while (*mousedev) {
+	list_for_each_entry(list, &mousedev->list, node) {
+		list->dx += packet->dx;
+		list->dy += packet->dy;
+		list->dz += packet->dz;
+		list->buttons = mousedev->buttons;
+		list->ready = 1;
+		kill_fasync(&list->fasync, SIGIO, POLL_IN);
+	}
+
+	wake_up_interruptible(&mousedev->wait);
+}
+
+static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+{
+	struct mousedev *mousedev = handle->private;
+
+	switch (type) {
+		case EV_ABS:
+			/* Ignore joysticks */
+			if (test_bit(BTN_TRIGGER, handle->dev->keybit))
+				return;
+
+			if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+				mousedev_touchpad_event(mousedev, code, value);
+			else
+				mousedev_abs_event(handle->dev, mousedev, code, value);
 
-		wake = 0;
+			break;
+
+		case EV_REL:
+			mousedev_rel_event(mousedev, code, value);
+			break;
 
-		list_for_each_entry(list, &(*mousedev)->list, node)
-			switch (type) {
-				case EV_ABS:
-					mousedev_abs_event(handle, list, code, value);
-					break;
-
-				case EV_REL:
-					switch (code) {
-						case REL_X:	list->dx += value; break;
-						case REL_Y:	list->dy -= value; break;
-						case REL_WHEEL:	if (list->mode) list->dz -= value; break;
-					}
-					break;
-
-				case EV_KEY:
-					if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
-						/* Handle touchpad data */
-						list->touch = value;
-						if (!list->touch)
-							list->pkt_count = 0;
-						break;
-					}
-
-					switch (code) {
-						case BTN_TOUCH:
-						case BTN_0:
-						case BTN_FORWARD:
-						case BTN_LEFT:   index = 0; break;
-						case BTN_4:
-						case BTN_EXTRA:  if (list->mode == 2) { index = 4; break; }
-						case BTN_STYLUS:
-						case BTN_1:
-						case BTN_RIGHT:  index = 1; break;
-						case BTN_3:
-						case BTN_BACK:
-						case BTN_SIDE:   if (list->mode == 2) { index = 3; break; }
-						case BTN_2:
-						case BTN_STYLUS2:
-						case BTN_MIDDLE: index = 2; break;
-						default: return;
-					}
-					switch (value) {
-						case 0: clear_bit(index, &list->buttons); break;
-						case 1: set_bit(index, &list->buttons); break;
-						case 2: return;
-					}
-					break;
-
-				case EV_SYN:
-					switch (code) {
-						case SYN_REPORT:
-							if (list->touch) {
-								list->pkt_count++;
-								/* Input system eats duplicate events,
-								 * but we need all of them to do correct
-								 * averaging so apply present one forward
-								 */
-								fx(0) = fx(1);
-								fy(0) = fy(1);
-							}
-
-							list->ready = 1;
-							kill_fasync(&list->fasync, SIGIO, POLL_IN);
-							wake = 1;
-							break;
-					}
+		case EV_KEY:
+			if (value != 2) {
+				if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
+					/* Handle touchpad data */
+					mousedev->touch = value;
+					if (!mousedev->touch)
+						mousedev->pkt_count = 0;
+				}
+				else
+					mousedev_key_event(mousedev, code, value);
 			}
+			break;
+
+		case EV_SYN:
+			if (code == SYN_REPORT) {
+				if (mousedev->touch) {
+					mousedev->pkt_count++;
+					/* Input system eats duplicate events, but we need all of them
+					 * to do correct averaging so apply present one forward
+			 		 */
+					fx(0) = fx(1);
+					fy(0) = fy(1);
+				}
 
-		if (wake)
-			wake_up_interruptible(&((*mousedev)->wait));
+				mousedev_notify_readers(mousedev, &mousedev->packet);
+				mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
 
-		mousedev++;
+				memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
+			}
+			break;
 	}
 }
 
@@ -326,6 +355,8 @@
 		list->dz -= list->ps2[off + 3];
 		list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
 		list->bufsiz++;
+	} else {
+		list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
 	}
 
 	if (list->mode == 1) {
@@ -553,6 +584,7 @@
 static struct miscdevice psaux_mouse = {
 	PSMOUSE_MINOR, "psaux", &mousedev_fops
 };
+static int psaux_registered;
 #endif
 
 static int __init mousedev_init(void)
@@ -572,7 +604,7 @@
 				NULL, "mice");
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-	if (!(mousedev_mix.misc = !misc_register(&psaux_mouse)))
+	if (!(psaux_registered = !misc_register(&psaux_mouse)))
 		printk(KERN_WARNING "mice: could not misc_register the device\n");
 #endif
 
@@ -584,7 +616,7 @@
 static void __exit mousedev_exit(void)
 {
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-	if (mousedev_mix.misc)
+	if (psaux_registered)
 		misc_deregister(&psaux_mouse);
 #endif
 	devfs_remove("input/mice");

  reply	other threads:[~2004-05-11  6:53 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200405110101.42805.dtor_core@ameritech.net>
2004-05-11  6:24 ` [PATCH 1/9] New set of input patches - 02-kbd98io-interrupt.patch Dmitry Torokhov
     [not found] ` <200405110103.27973.dtor_core@ameritech.net>
     [not found]   ` <200405110104.20283.dtor_core@ameritech.net>
2004-05-11  6:05     ` [PATCH 3/9] New set of input patches - 04-h3600-fixes.patch Dmitry Torokhov
2004-05-11  6:05       ` [PATCH 4/9] New set of input patches - 05-twidjoy-fixes.patch Dmitry Torokhov
2004-05-11  6:06         ` [PATCH 5/9] New set of input patches - 07-power-license.patch Dmitry Torokhov
2004-05-11  6:09           ` [PATCH 6/9] New set of input patches - 11-synaptics-reconnect.patch Dmitry Torokhov
2004-05-11  6:10             ` [PATCH 7/9] New set of input patches - 12-i8042-interrupt.patch Dmitry Torokhov
2004-05-11  6:10               ` [PATCH 8/9] New set of input patches - 13-i8042-unload.patch Dmitry Torokhov
2004-05-11  6:11                 ` Dmitry Torokhov [this message]
2004-05-11  6:24   ` [PATCH 2/9] New set of input patches - 03-kbd98-interrupt.patch Dmitry Torokhov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200405110111.45903.dtor_core@ameritech.net \
    --to=dtor_core@ameritech.net \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vojtech@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.