[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#290020: kernel-source-2.6.8: wacom driver is not seen by mousedev



Package: kernel-source-2.6.8
Version: 2.6.8-11
Severity: normal
Tags: patch

support for wacom in mousedev.c is broken. when using the stylus in X
the pointer seem to be stuck in the upper right corner.

this bug is fixed in 2.6.9, and the following patch corrects the problem
on 2.6.8.

the patch comes from gentoo sources via:
https://bugzilla.ubuntu.com/show_bug.cgi?id=2396

ciao, piem


-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: powerpc (ppc)
Kernel: Linux 2.6.9-powerpc
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)

Versions of packages kernel-source-2.6.8 depends on:
ii  binutils                      2.15-5     The GNU assembler, linker and bina
ii  bzip2                         1.0.2-1    A high-quality block-sorting file 
ii  coreutils [fileutils]         5.2.1-2    The GNU core utilities

-- no debconf information
--- 1.40/drivers/input/mousedev.c	2004-06-11 16:04:02 -05:00
+++ edited/drivers/input/mousedev.c	2004-06-28 01:10:14 -05:00
@@ -104,6 +104,9 @@
 static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
 static struct mousedev mousedev_mix;
 
+static int last_x, last_y;
+static spinlock_t last_pos_lock = SPIN_LOCK_UNLOCKED;
+
 #define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
 #define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 
@@ -128,21 +131,24 @@
 
 static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
 {
+	unsigned long flags;
 	int size;
 
 	switch (code) {
 		case ABS_X:
 			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;
+			spin_lock_irqsave(&last_pos_lock, flags);
+			mousedev->packet.dx = (value - dev->absmin[ABS_X]) * xres / size  - last_x;
+			spin_unlock_irqrestore(&last_pos_lock, flags);
 			break;
 
 		case ABS_Y:
 			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;
+			spin_lock_irqsave(&last_pos_lock, flags);
+			mousedev->packet.dy = -((value - dev->absmin[ABS_Y]) * yres / size - last_y);
+			spin_unlock_irqrestore(&last_pos_lock, flags);
 			break;
 	}
 }
@@ -188,6 +194,18 @@
 	}
 }
 
+static void mousedev_adjust_lastpos(struct mousedev_motion *packet)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&last_pos_lock, flags);
+	last_x += packet->dx;
+	last_x = last_x < 0 ?  0 : (last_x < xres ? last_x : xres);
+	last_y -= packet->dy;
+	last_y = last_y < 0 ?  0 : (last_y < yres ? last_y : yres);
+	spin_unlock_irqrestore(&last_pos_lock, flags);
+}
+
 static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
 {
 	struct mousedev_list *list;
@@ -288,6 +306,7 @@
 				mousedev_notify_readers(mousedev, &mousedev->packet);
 				mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
 
+				mousedev_adjust_lastpos(&mousedev->packet);
 				memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
 			}
 			break;
@@ -669,6 +688,9 @@
 
 static int __init mousedev_init(void)
 {
+	last_x = xres / 2;
+	last_y = yres / 2;
+
 	input_register_handler(&mousedev_handler);
 
 	memset(&mousedev_mix, 0, sizeof(struct mousedev));


Reply to: