You are not logged in.
I have only been using linux as my main OS for 6 months and i have mostly loved it, except for the absolutely horrid xorg mouse acceleration. The discontinuous acceleration curve in my opinion is really annoying and unusable.
In the linux spirit i wrote a simple program to improve it.
The program takes as arguments the PS2 compatible mouse device (eg /dev/mouse), a named pipe and the coefficients for a 3rd order polynomial. The program filters the mouse data according to the polynomial and writes the new data to the named pipe to be used by xorg.
If someone wants to try it
step 1.
turn off all other x mouse acceleration.
step 2.
gcc mouse.c -lm -o mousefilter
mkfifo fifo
step 3.
setup xorg.conf to use "fifo" as the mouse device
step 4.
run the program in startup script
eg
sudo mousefilter /dev/input/mice fifo 1 0.15 0
these arguments modulate the mouse coordinates with x + 0.15x^2 + 0*x.^3.
this is what i have been using all week and it works great.
I have only tested it on my current xubuntu system (I am about to install arch, when i get the time). So if it works
for you or doesn't i would be interested to hear.
/* mouse.c - PS2 mouse acceleration filter *****************************************************************
* This program reads packets from a specfied PS/2 compatible mouse device, decodes them
* scales the x and y movement according to a user specified polynomial, repacks
* and writes to a fifo used as the mouse device.
*
* Author: Lyndon Whaite 2009
*************************************************************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
int fifo, mouse;
char is_4byte=0;
float poly_curve[] = {1,0,0};
/* evaluate user specified polynomial */
float evaluate_curve(float delta, float poly[])
{
return poly[0]*delta + poly[1]*pow(delta,2) + poly[2]*pow(delta,3);
}
/* filter mouse data */
void filter_mouse(void)
{
unsigned char in[4], out[4];
int xsign,ysign;
float dx=0;
float dy=0;
float ndx=0;
float ndy=0;
float speed=0;
float pspeed=0;
float mouse_speed=0;
float smooth_factor = 0.1;
unsigned char mask = 1;
while (1)
{
/* read 4th byte if it is an intellimouse */
if(is_4byte)
{
read(mouse,in,4);
}
else
{
read(mouse,in,3);
}
/* unpack mouse movement */
xsign = (in[0]>>4)&mask;
ysign = (in[0]>>5)&mask;
dx=(in[1]-256*xsign);
dy=(in[2]-256*ysign);
mouse_speed = sqrt(dy*dy+dx*dx);
speed = 0;
ndx=0;
ndy=0;
/* evaluate scaling function if mouse is moving */
if(mouse_speed > 0)
{
ndx = (float)(dx)/mouse_speed;
ndy = (float)(dy)/mouse_speed;
pspeed = speed;
speed = evaluate_curve(mouse_speed,poly_curve)*(1.0-smooth_factor*0.5)
+ (smooth_factor*0.5)*smooth_factor*pspeed;
}
/* put transformed data back in packets */
dy = ndy*speed;
dx = ndx*speed;
out[0] = in[0];
out[1] = floor(dx)+256*xsign;
out[2] = floor(dy)+256*ysign;
out[3] = in[3];
/* write transformed packet to fifo */
if(is_4byte)
{
write(fifo, out,4);
}
else
{
write(fifo, out,3);
}
}
}
int main(int argc, char **argv)
{
int i=0;
unsigned char temp_read=0;
unsigned char imps23_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
unsigned char imps24_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
unsigned char get_id = 0xf2;
if (argc < 4)
{
printf("usage: %s <mouse dev> <fifo> <poly coefficients (1-3 numbers)> <\n", argv[0]);
exit(1);
}
/* open fifo file */
fifo = open(argv[2], O_RDWR);
if (fifo < 0)
{
printf("error opening fifo\n");
exit(1);
}
/* open mouse file */
mouse = open(argv[1], O_RDWR);
if (mouse < 0)
{
printf("error opening mouse\n");
close(fifo);
exit(1);
}
for(i=0; i<argc-3; i++)
{
poly_curve[i] = atof(argv[i+3]);
}
printf("f(x) = %fx + %fx^2 + %fx^3\n", poly_curve[0],poly_curve[1], poly_curve[2]);
/* initially assume normal ps/2 */
is_4byte=0;
/* write magic sequence */
write(mouse,imps23_seq,6);
write(mouse,&get_id,1);
read(mouse, &temp_read, 1);
read(mouse, &temp_read, 1);
/* if device id == 3 it is a ps2 mouse with a wheel */
if(temp_read==3)
{
printf("mouse has wheel\n");
is_4byte=1;
}
/* write magic sequence */
write(mouse,imps24_seq,6);
write(mouse,&get_id,1);
read(mouse, &temp_read, 1);
read(mouse, &temp_read, 1);
/* if device id == 3 it is a ps2 mouse with a wheel and extra buttons*/
if(temp_read==4)
{
printf("mouse has wheel and extra buttons\n");
is_4byte=1;
}
/* try to set sample rate to 200 */
write(mouse,imps23_seq,2);
read(mouse, &temp_read, 1);
/* infinite loop to filter mouse data */
filter_mouse();
close(fifo);
close(mouse);
}
Lyndon
Last edited by lyndonwhaite (2009-02-18 22:55:40)
Offline
wow! cool, definitely gonna try that!
is my mouse with more than the standard buttons gonna work?
cheers Barde
Offline
This is very cool eventhough I'm not even using a PS/2 mouse. I think you'll like Arch Linux.
Offline
Thanks for the feedback guys.
This is very cool eventhough I'm not even using a PS/2 mouse. I think you'll like Arch Linux.
Ashren it doesn't matter so much whether it is a PS2 mouse but whether it uses the PS2 protocol, yours might. I am using a USB intellimouse but it uses the PS2 protocol.
wow! cool, definitely gonna try that!
is my mouse with more than the standard buttons gonna work?cheers Barde
I have got an MS Intellimouse with 5 buttons and that works. This is the reference i used for the mouse data. I think a lot of ps2 compatible mice with extra buttons use the intellimouse packet so it should work.
http://www.computer-engineering.org/ps2mouse/
I would like to extend the program to work with a reasonable subset of mice so let us know how it goes if you try it.
Lyndon
Offline
Is predictable pointer acc in new xserver going to fix this? (btw i have no idea what the issue is ) Because if not maybe you could help the xorg guys out instead and get it in tree(unless you will screw with my acc in fps's)!
KISS = "It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience." - Albert Einstein
Offline
Is predictable pointer acc in new xserver going to fix this? (btw i have no idea what the issue is
) Because if not maybe you could help the xorg guys out instead and get it in tree(unless you will screw with my acc in fps's)!
Yeah i am pretty sure they are intending to solve the problem in the next version of xserver, i am not sure when that is going to be out though. I needed a solution now
A lot of people don't seem to mind the standard mouse acceleration, i find it really annoying. The issue is basically that the standard mouse acceleration has only two speeds, the slow and the fast, the new xserver will have an infinite number of different speeds (ie a smooth nonlinear scaling function).
Offline