A PS/2 mouse in FreeBSD behaves very badly when it is configured to run fast like can be done in any Windows NT operating system. To compare XFree86 with Windows NT, the Windows Registry can have this entered into it (with a reboot being done): [HKEY_CURRENT_USER\Control Panel\Mouse] "MouseSpeed"="2" "MouseThreshold1"="4" "MouseThreshold2"="0" XFree86 has more than one problem with its mouse deceleration algorithm. One problem is that it is too difficult to get the pointer positioned over any particular pixel, provided that it is also configured to be as fast as a sedately fast Windows NT mouse pointer. A look at the algorithm below shows that it could be the cause of the defects in the mouse's behaviour. I note that Hewlett Packard has produced computers where users can write their own program to control the mouse pointer. Xfree86 is different because it provides poor control of a bad algorithm, and the control being at the weakest in operating region where the algorithm is at its very worst, which is when the mouse pointer is made to be fast. In the algorithm below there is a 'raise to the power of' function. That has a circular influence. But the presence of "abs(dx) + abs(dy)) >= ...", is creating a region that has the shape of a diamond. That a power function is used shows there was not a concern with speed which is probably good enough. It is doubtful that a diamond shape is best. A thin horizontal rectangle for nearly horizontal movements could be better (and HP seems to have done that). This is possibly not the best that can be done too: if (device->ptrfeed->ctrl.threshold) { It means that users can get a different behaviour if the mouse is speeded from threshold 1 to threshold 0. If the mouse is greatly slowed down a lot then the XFree86 mouse seems OK to person familar with an excellent mouse algorithm, e.g. someone that has use Windows NT, 2000, or 95, etc. However they may expect that XFree86 mouse not show amazing jerkiness after installing an 1.2GHz CPU and after increasing the sample to at least 150 samples per second. Those changes lead to just about no improvement in Windows NT, and also XFree86. I was testing in FreeBSD and I did not perfectly rule out some FreeBSD problem, but it looks like no one need search further than "xf86PostMotionEvent()" to find the cause of why many Unix users have had a mouse that is difficult to position over a given pixel. In Windows, a mouse cursor can be rapidly moved over to a spot just as is desired. A major problem with the XFree86 pointer algorithm is this: the mouse pointer decelerates in a bad way. I described the problem with these words in a bug report to KDE.org: >That is described again: there was a problem with a ring around >the point being stopped onto, having the speed of the mouse cursor >be too slow. Around that ring, another ring shaped region was >exhibiting a mouse speed of the decelerating mouse cursor that >seemed to be too fast. http://bugs.kde.org/db/31/31701-b.html#m3 So as the pointer nears the final point, the user has to slow the physical mouse down too much. The XFree86 algorithm then slows the pointer even more with unexpected strength and the pointer and then the operator has to speed up the mouse. As that is happening, the XFree86 unexpectedly somewhat suddenly cuts in and speeds up the mouse even more, and the extra acceleration causes an overshoot. Added to that is a problem of huge jerky movements for a nearly stationary slightly moving mouse. It can take quite a while to get a fast mouse onto the final point it that user was trying to get it onto. In Windows NT, a rapid graceful straight line positioning of the mouse pointer over the desired end point, can be done quickly and efficiently. Even rewriting the offending XFree86 code inside of XFree86 would unpleasant and perhaps the top XFree86 developers would prefer to drop into Vim in console mode [well I would]. I have been quite certain that the console windows of FreeBSD provide a much more nicer more productive and friendly environment that is clearly advanced over what KDE has to offer because it is running over XFree86. Nevertheless the console windows with 60x132 characters seem inferior to the graphical user interfaces of Microsoft's Windows 95. (Also X-term defaults to having keys set wrongly). The FreeBSD console mouse is far too slow and not adjustable too. Users of XFree86 may need to pick the mouse off the pad a lot more often they ought need to. There is an opportunity to make a noise when bringing it down again but it is controversial to say that XFree86 ought bring such a freedom upon users who would prefer instead a far better mouse feedback pointer speed control algorithm. Another problem is that when XFree86 mouse is configured to be as fast as a good Windows NT mouse, then it can be found that extremely slow and extremely small movements of the mouse result will produce very big jerky jumpy movements that can be 1/2 cm or so, in length. That is a bug. The XFree86 algorithm could do just that. Here it is (from "xf86PostMotionEvent()"): Either (1) or (2) is run: If not (0 = threshold) then: valuator[0] = (dx * device->ptrfeed->ctrl.num) / device->ptrfeed->ctrl.den; otherwise this: when not (0 = dx): (2) local->dxremaind = mult * (float)dx + local->dxremaind; valuator[0] = (int)local->dxremaind; The Hewlett Packard "find_deviceintrec()" routine (in "/xc/programs/Xserver/hw/hp/input/x_hil.c") has this: if ( (c[i] - threshold) > 0) c[i] = threshold + (c[i] - threshold) * acceleration; The HP algorithm treats the x and y axis separately so we can expect that for a constant diagonal motion of the physical mouse would produce lines of different slope on the screen. That would be caused by one of dx or dy being inside of the threshold and the other outside. That is behaviour that the Microsoft mouse will show. Part of the problem with the XFree86 algorithm could be partly due to the mixing up of the axes with the dx*dx+dy*dy, in the code like this (from below): mult = pow((float)(dx*dx+dy*dy), ("accel" - 1.0)/2.0) / 2.0; --- A message at Slashdot said that the mouse in Linux's X-Windows has always been slower and it has always been like that. It is Unix and FreeBSD too, They have a problem with KDE: it has a non-resizable tool bar and an bad magnetic scheme for stopping windows from going over the edge. A better faster method for GUI pros is the Shove-It system. It has windows bounce back if they extend outside of the visible screen; code: http://www.phord.com/shoveit.html [in NT boot start from Registry] Some people could be wanting to run Windows NT/2000 inside of VMware inside of Linux (or FreeBSD if it VMware runs OK which may not be the case). But it could be too unsatisfactory when the mouse is controlled by XFree86 code. Until the problem is fixed somehow, the real Windows could be preferred. A group of possible future users (and VMware customers, etc.) would be avoiding the Unix operating systems. Maybe users of XFree86 ought be able to hook in their own mouse pointer feedback control algorithm. I am very sure that that is not currently the way XFree86 is coded. Thus it can be implemented without harming the functionality of existing software, i.e. it is solution that allows users the best. Increasing the sample rate of the mouse hardware seems to make about no difference to the usability of the mouse in FreeBSD and Windows NT. It's main effect is on smoothing up a fast moving mouse, which can be seen as easy to do without. So the XFree86 problem can't be explained by the mouse sampling rate. The Hewlett Packard algorithm for decelerating the mouse has the deceleration for each axis be calculated separately. In the XFree86 algorithm (in "xf86Xinput.c"), the multiplier is calculated from a radial distance. Persons attempting a quick guess on which is better might suppose that the HP algorithm is better, but it could be debatable. I presume the HP algorithm allows much preciser vertical positioning when the pointer is moving a lengthy distance but that path is nearly a horizontal path. Maybe a hybrid might be best. Users of KDE and GNOME get only 2 Real numbers with which they can configure the algorithm. The way it is done is quite bad, although it ought be possible to allow something far better with the 3 Integers. To get the mouse very fast, the speed is 0 or 1. But persons can't seriously consider that due to incorrect way in which deceleration is implemented. To correct the deceleration algorithm would uncover the bug of having a range of top speeds be selectable with the Integers, 0, 1 and maybe 2. The numbers could be rescaled so that what currently is reciprocal-speed "1" will later need to be selected using the number "100". It must be possible to allows to actually select a fast speed with a bit of precision. In Windows NT the ability to select the speed using the Registry seems quite limited but an attempt to speed up the mouse does not take effect until a reboot is done. It is possible to get a mouse faster than would be desired with it seeming to decelerate optimally, whereas in XFree86 world, the inadequacies in the deceleration algorithm in practice limit the speed that can be selected. A way to get XFree86 improved is to accurately copy the Microsoft deceleration algorithm. XFree86 can get out of the problem trivially. Once people can compile XFree86 and alter the algorithm, it would be hard for them to be unable to much improve the deceleration algorithm. There are sure to be programmers that can produce a far better algorithm and if they could hook it in, a near optimal algorithm could appear. It is presumably harming the popularity of KDE and GNOME to have a mouse that can't easily positioned over pixels and that will remain too slow no matter how fast the mouse and interrupts and CPU are. Once change the XFree86 maintainers could do is alter the word "acceleration" into "deceleration". A mouse need not be accurate when the motion is started and a diamond shaped region for acceleration would not be as significant as it is for the region where deceleration occurs. There are no arguments in the XFree86 "xf86Xinput.c" code suggesting the design should not be fixed. xc\programs\Xserver\hw\xfree86\common\xf86Xinput.c : http://cvsweb.xfree86.org/cvsweb/xc/programs/Xserver/hw/xfree86/common/xf86Xinput.c ---------------------------------------------------------------------------- void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute, int first_valuator, int num_valuators, ...) { va_list var; int loop; LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate; char *buff = 0; Time current; Bool is_core = xf86IsCorePointer(device); Bool is_shared = xf86ShareCorePointer(device); ValuatorClassPtr val = device->valuator; int valuator[6]; int *axisvals; AxisInfoPtr axes; int dx = 0, dy = 0; float mult; int loop_start; int num; ... DBG(5, ErrorF("xf86PostMotionEvent BEGIN 0x%x(%s) is_core=%s is_shared=%s is_absolute=%s\n", device, device->name, is_core ? "True" : "False", is_shared ? "True" : "False", is_absolute ? "True" : "False")); xf86Info.lastEventTime = xev->time = current = GetTimeInMillis(); if (!is_core) { if (HAS_MOTION_HISTORY(local)) { buff = ((char *)local->motion_history + (sizeof(INT32) * local->dev->valuator->numAxes + sizeof(Time)) * local->last); } } if (num_valuators && (!val || (first_valuator + num_valuators > val->numAxes))) { ErrorF("Bad valuators reported for device \"%s\"\n", device->name); return; } axisvals = val->axisVal; axes = val->axes; va_start(var, num_valuators); loop_start = first_valuator; for(loop=0; loop<num_valuators; loop++) { valuator[loop%6] = va_arg(var,int); if (loop % 6 == 5 || loop == num_valuators - 1) { num = loop % 6 + 1; /* * Adjust first two relative valuators */ if (!is_absolute && num_valuators >= 2 && loop_start == 0) { dx = valuator[0]; dy = valuator[1]; /* * Accelerate */ if (device->ptrfeed && device->ptrfeed->ctrl.num) { /* modeled from xf86Events.c */ if (device->ptrfeed->ctrl.threshold) { if ((abs(dx) + abs(dy)) >= device->ptrfeed->ctrl.threshold) { valuator[0] = (dx * device->ptrfeed->ctrl.num) / device->ptrfeed->ctrl.den; valuator[1] = (dy * device->ptrfeed->ctrl.num) / device->ptrfeed->ctrl.den; } } else if (dx || dy) { mult = pow((float)(dx*dx+dy*dy), ((float)(device->ptrfeed->ctrl.num) / (float)(device->ptrfeed->ctrl.den) - 1.0) / 2.0) / 2.0; if (dx) { local->dxremaind = mult * (float)dx + local->dxremaind; valuator[0] = (int)local->dxremaind; local->dxremaind = local->dxremaind - (float)valuator[0]; } if (dy) { local->dyremaind = mult * (float)dy + local->dyremaind; valuator[1] = (int)local->dyremaind; local->dyremaind = local->dyremaind - (float)valuator[1]; } } DBG(6, ErrorF("xf86PostMotionEvent acceleration v0=%d v1=%d\n", valuator[0], valuator[1])); } ... loop_start += 6; } } va_end(var); if (HAS_MOTION_HISTORY(local)) { local->last = (local->last + 1) % device->valuator->numMotionEvents; if (local->last == local->first) local->first = (local->first + 1) % device->valuator->numMotionEvents; } DBG(5, ErrorF("xf86PostMotionEvent END 0x%x(%s) is_core=%s is_shared=%s\n", device, device->name, is_core ? "True" : "False", is_shared ? "True" : "False")); } ---------------------------------------------------------------------------- Hewlett Packard's algorithm is very different and it creates a square with a diameter that is twice the threshold that has a quite linear behaviour inside an outside. [That can avoid a problem of a dead region where the mouse does nothing, which is well able to be something that the "raising to a power of" function in xf86PostMotionEvent() could produce.] http://cvsweb.xfree86.org/cvsweb/xc/programs/Xserver/hw/hp/input/x_hil.c -------------------------------------------------------------- DeviceIntPtr find_deviceintrec (indevice) { ... process_motion (dev, phys, log, c, timestamp) ... if (!playback_on) { if (!(phys->hpflags & ABSOLUTE_DATA) && (acceleration != DEF_ACCELERATION)) { for (i=0; i < (u_char) log->d.ax_num; i++) if ( (c[i] - threshold) > 0) c[i] = threshold + (c[i] - threshold) * acceleration; else if ( (c[i] + threshold) < 0) c[i] = (c[i] + threshold) * acceleration - threshold; } } ... -------------------------------------------------------------- None of the Kdrive Keith Packard "small Xserver" files have calls to "xf86PostMotionEvent(...)" and it has a different deceleration algorithm. http://cvsweb.xfree86.org/cvsweb/~checkout~/xc/programs/Xserver/hw/kdrive/kinput.c -------------------------------------------------------------- KdMouseAccelerate (DeviceIntPtr device, int delta) { ... -------------------------------------------------------------- Note: "xset.c" is an X-Windows program/feature allowing the deceleration to be set. The xset program calls XChangePointerControl (...). xset: http://cvsweb.xfree86.org/cvsweb/~checkout~/xc/programs/xset/xset.c The Unix/Linux communities that were going to complain eventually can instead produce a better mouse algorithm. A 3 piece linear (with x and y independent) method might turn out to be good enough under testing. If so then it could be found that the XFree86 "to the power of" function is not able to match that closely enough (perhaps). Craig Carey New Zealand _______________________________________________ Xpert mailing list [EMAIL PROTECTED] http://XFree86.Org/mailman/listinfo/xpert