[ Please CC me, I'm not subscribed]
Hi! Attached is a patch which incorporates local patches for FreeBSD that has been floating around in our package repository (the ports tree) for quite some time. I'd like a review and help to get these upstream. I have not made the patches myself, but from what I can tell they resolve two different issues. The first part is native PS/2 support on FreeBSD, and the second is making absolute pointer devices work. The latter fix also needs the driver to link against libusbhid (BSD library related to USB HID devices). My idea to resolve this was to add a configure check for this lib, and compile the code and link against it if it exists, but I'm unsure on how to accomplish this, especially since this check probably only should be done on BSDs, not Linux (that doesn't use this code at all). The code is available in a git branch, where it might be clearer which code belongs to which issue, but I have nowhere to push this where it is publicly visible currently. It would be great if I could get a code review as well as help with and suggestions on the autoconf issues, so that this has a chance of making it upstream. Best regards! -- Niclas Zeising FreeBSD ports committer FreeBSD x11 team
diff --git a/src/bsd_mouse.c b/src/bsd_mouse.c
index ca4c9d0..7c4edec 100644
--- a/src/bsd_mouse.c
+++ b/src/bsd_mouse.c
@@ -26,6 +26,24 @@
* authorization from the copyright holder(s) and author(s).
*/
+
+/*
+ * XXX - Should this be autoconf'd instead?
+ */
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+
+#if !defined(USBMOUSE_SUPPORT)
+#define USBMOUSE_SUPPORT
+#endif
+#if !defined(HAS_LIB_USB_HID)
+#define HAS_LIB_USB_HID
+#endif
+#if !defined(XPS2_SUPPORT)
+#define XPS2_SUPPORT
+#endif
+
+#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) */
+
#include <xorg-server.h>
#include <X11/X.h>
@@ -33,9 +51,23 @@
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "xf86Xinput.h"
+#include <exevents.h>
#include "mouse.h"
#include "xisb.h"
#include "mipointer.h"
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
+#define HAVE_PROPERTIES 1
+#endif
+#ifdef HAVE_PROPERTIES
+#include <X11/Xatom.h>
+#include <xserver-properties.h>
+/* 1.6 has properties, but no labels */
+#ifdef AXIS_LABEL_PROP
+#define HAVE_LABELS
+#else
+#undef HAVE_LABELS
+#endif
+#endif
#ifdef WSCONS_SUPPORT
#include <dev/wscons/wsconsio.h>
#endif
@@ -47,9 +79,6 @@
#endif
#include <dev/usb/usb.h>
-#ifdef USB_GET_REPORT_ID
-#define USB_NEW_HID
-#endif
#define HUP_GENERIC_DESKTOP 0x0001
#define HUP_BUTTON 0x0009
@@ -75,11 +104,13 @@ static const char *FindDevice(InputInfoPtr, const char *, int);
#define DEFAULT_MOUSE_DEV "/dev/mouse"
#define DEFAULT_SYSMOUSE_DEV "/dev/sysmouse"
#define DEFAULT_PS2_DEV "/dev/psm0"
+#define DEFAULT_USB_DEV "/dev/ums0"
static const char *mouseDevs[] = {
DEFAULT_MOUSE_DEV,
DEFAULT_SYSMOUSE_DEV,
DEFAULT_PS2_DEV,
+ DEFAULT_USB_DEV,
NULL
};
#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
@@ -100,7 +131,11 @@ SupportedInterfaces(void)
#if defined(__NetBSD__)
return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
- return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 |
+#ifdef XPS2_SUPPORT
+ MSE_XPS2 |
+#endif
+ MSE_AUTO | MSE_MISC;
#else
return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
#endif
@@ -180,9 +215,30 @@ static struct {
{ MOUSE_PROTO_SYSMOUSE, "SysMouse" }
};
+#ifdef XPS2_SUPPORT
+static struct {
+ int dmodel;
+ const char *name;
+} ps2proto[] = {
+ { MOUSE_MODEL_NETSCROLL, "NetScrollPS/2" },
+ { MOUSE_MODEL_NET, "NetMousePS/2" },
+ { MOUSE_MODEL_GLIDEPOINT, "GlidePointPS/2" },
+ { MOUSE_MODEL_THINK, "ThinkingMousePS/2" },
+ { MOUSE_MODEL_INTELLI, "IMPS/2" },
+ { MOUSE_MODEL_MOUSEMANPLUS, "MouseManPlusPS/2" },
+ { MOUSE_MODEL_EXPLORER, "ExplorerPS/2" },
+ { MOUSE_MODEL_4D, "IMPS/2" },
+ { MOUSE_MODEL_4DPLUS, "IMPS/2" },
+};
+#endif
+
static const char *
SetupAuto(InputInfoPtr pInfo, int *protoPara)
{
+#ifdef XPS2_SUPPORT
+ const char *dev;
+#endif
+ const char *proto;
int i;
mousehw_t hw;
mousemode_t mode;
@@ -190,7 +246,13 @@ SetupAuto(InputInfoPtr pInfo, int *protoPara)
if (pInfo->fd == -1)
return NULL;
+#ifdef XPS2_SUPPORT
/* set the driver operation level, if applicable */
+ dev = xf86FindOptionValue(pInfo->options, "Device");
+ if (dev != NULL && !strncmp(dev, DEFAULT_PS2_DEV, 8))
+ i = 2;
+ else
+#endif
i = 1;
ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
@@ -209,9 +271,18 @@ SetupAuto(InputInfoPtr pInfo, int *protoPara)
protoPara[0] = mode.syncmask[0];
protoPara[1] = mode.syncmask[1];
}
+ proto = devproto[i].name;
+#ifdef XPS2_SUPPORT
+ if (mode.protocol == MOUSE_PROTO_PS2)
+ for (i = 0; i < sizeof(ps2proto)/sizeof(ps2proto[0]); ++i)
+ if (hw.model == ps2proto[i].dmodel) {
+ proto = ps2proto[i].name;
+ break;
+ }
+#endif
xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
- pInfo->name, devproto[i].name);
- return devproto[i].name;
+ pInfo->name, proto);
+ return proto;
}
}
}
@@ -234,41 +305,41 @@ SetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res)
(protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
/*
* As the FreeBSD sysmouse driver defaults to protocol level 0
- * everytime it is opened we enforce protocol level 1 again at
+ * everytime it is closed we enforce protocol level 1 again at
* this point.
*/
mode.level = 1;
} else
- mode.level = -1;
-#else
- mode.level = -1;
#endif
+ mode.level = -1;
ioctl(pInfo->fd, MOUSE_SETMODE, &mode);
}
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-
-#define MOUSED_PID_FILE "/var/run/moused.pid"
-
/*
* Try to check if moused is running. DEFAULT_SYSMOUSE_DEV is useless without
- * it. There doesn't seem to be a better way of checking.
+ * it. Also, try to check if the device is used by moused. If it is opened
+ * by moused, we do not want to use it directly. There doesn't seem to be
+ * a better way of checking.
*/
static Bool
-MousedRunning(void)
+MousedRunning(const char *dev)
{
+ char cmd[128];
FILE *f = NULL;
- unsigned int pid;
-
- if ((f = fopen(MOUSED_PID_FILE, "r")) != NULL) {
- if (fscanf(f, "%u", &pid) == 1 && pid > 0) {
- if (kill(pid, 0) == 0) {
- fclose(f);
- return TRUE;
- }
+ unsigned int i;
+
+ if (dev)
+ sprintf(cmd, "sh -c 'fstat %s | grep -c moused' 2>/dev/null", dev);
+ else
+ sprintf(cmd, "sh -c 'pgrep -nx moused' 2>/dev/null");
+ if ((f = popen(cmd, "r")) != NULL) {
+ if (fscanf(f, "%u", &i) == 1 && i > 0) {
+ pclose(f);
+ return TRUE;
}
- fclose(f);
+ pclose(f);
}
return FALSE;
}
@@ -276,17 +347,17 @@ MousedRunning(void)
static const char *
FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
{
- int fd = -1;
+ int ret = -1;
const char **pdev, *dev = NULL;
Bool devMouse = FALSE;
struct stat devMouseStat;
struct stat sb;
for (pdev = mouseDevs; *pdev; pdev++) {
- SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK));
- if (fd == -1) {
+ SYSCALL (ret = stat(*pdev, &sb));
+ if (ret == -1) {
#ifdef DEBUG
- ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno));
+ ErrorF("Cannot stat %s (%s)\n", *pdev, strerror(errno));
#endif
} else {
/*
@@ -295,28 +366,32 @@ FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
* the test for whether /dev/sysmouse is usable can be made.
*/
if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) {
- if (fstat(fd, &devMouseStat) == 0)
- devMouse = TRUE;
- close(fd);
+ memcpy(&devMouseStat, &sb, sizeof(devMouseStat));
+ devMouse = TRUE;
continue;
} else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) {
/* Check if /dev/mouse is the same as /dev/sysmouse. */
- if (devMouse && fstat(fd, &sb) == 0 &&
- devMouseStat.st_dev == sb.st_dev &&
+ if (devMouse && devMouseStat.st_dev == sb.st_dev &&
devMouseStat.st_ino == sb.st_ino) {
/* If the same, use /dev/sysmouse. */
devMouse = FALSE;
}
- close(fd);
- if (MousedRunning())
+ if (MousedRunning(NULL))
break;
- else {
-#ifdef DEBUG
- ErrorF("moused isn't running\n");
-#endif
- }
} else {
- close(fd);
+ /* Check if /dev/mouse is the same as this device. */
+ if (devMouse && devMouseStat.st_dev == sb.st_dev &&
+ devMouseStat.st_ino == sb.st_ino) {
+ /* If the same, use this device. */
+ devMouse = FALSE;
+ }
+ if (MousedRunning(*pdev))
+ continue;
+ /* ums(4) does not support anything but SysMouse protocol. */
+ if (!strncmp(*pdev, DEFAULT_USB_DEV, 8) && protocol &&
+ xf86NameCmp(protocol, "auto") != 0 &&
+ xf86NameCmp(protocol, "sysmouse") != 0)
+ continue;
break;
}
}
@@ -468,30 +543,78 @@ wsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
#if defined(USBMOUSE_SUPPORT)
+#define MAXRIDS 64
+#define MAXACOLS 8
+#define MAXLCOLS 16
typedef struct _UsbMseRec {
int packetSize;
- int iid;
- hid_item_t loc_x; /* x locator item */
- hid_item_t loc_y; /* y locator item */
- hid_item_t loc_z; /* z (wheel) locator item */
- hid_item_t loc_w; /* z (wheel) locator item */
- hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
- unsigned char *buffer;
+ int iid, nrids, nacols, opened;
+ struct {
+ int32_t rid;
+ int size;
+ } rids[MAXRIDS];
+ struct UsbMseAcol {
+ InputInfoPtr pInfo;
+ int nlcols, nbuttons, hasZ, hasW;
+ int xmin, xmax, ymin, ymax, pmin, pmax, px, py;
+ int cxmin, cxmax, cymin, cymax, cpmin, cpmax;
+ struct UsbMseLcol {
+ hid_item_t loc_x; /* x locator item */
+ hid_item_t loc_y; /* y locator item */
+ hid_item_t loc_z; /* z (wheel) locator item */
+ hid_item_t loc_w; /* w (hwheel) locator item */
+ hid_item_t loc_p; /* Tip Pressure */
+ hid_item_t loc_valid; /* Touch Valid */
+ hid_item_t loc_in_range; /* In Range */
+ hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
+ } lcols[MAXLCOLS];
+ hid_item_t loc_cc; /* contact count */
+ } acols[MAXACOLS];
+ unsigned char *buffer;
} UsbMseRec, *UsbMsePtr;
+static int *
+usbGetReportSizePtr(UsbMsePtr pUsbMse, int32_t rid)
+{
+ int i;
+
+ for (i = 0; i < pUsbMse->nrids; i++) {
+ if (pUsbMse->rids[i].rid == rid)
+ return (&pUsbMse->rids[i].size);
+ }
+ for (i = 0; i < MAXRIDS; i++) {
+ if (pUsbMse->rids[i].size == 0) {
+ pUsbMse->rids[i].rid = rid;
+ pUsbMse->nrids = max(pUsbMse->nrids, i + 1);
+ return (&pUsbMse->rids[i].size);
+ }
+ }
+ return (NULL);
+}
+
static int
usbMouseProc(DeviceIntPtr pPointer, int what)
{
InputInfoPtr pInfo;
MouseDevPtr pMse;
UsbMsePtr pUsbMse;
+ struct UsbMseAcol *acol;
unsigned char map[MSE_MAXBUTTONS + 1];
- int nbuttons;
+ int nacol, nbuttons;
+#ifdef HAVE_LABELS
+ Atom btn_labels[MSE_MAXBUTTONS] = {0};
+ Atom axes_labels[3] = { 0, 0, 0 };
+#endif
pInfo = pPointer->public.devicePrivate;
pMse = pInfo->private;
pMse->device = pPointer;
pUsbMse = pMse->mousePriv;
+ for (nacol = 0; nacol < (pUsbMse->nacols - 1); nacol++) {
+ if (pUsbMse->acols[nacol].pInfo == pInfo)
+ break;
+ }
+ acol = &pUsbMse->acols[nacol];
switch (what) {
case DEVICE_INIT:
@@ -500,38 +623,96 @@ usbMouseProc(DeviceIntPtr pPointer, int what)
for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
map[nbuttons + 1] = nbuttons + 1;
- InitPointerDeviceStruct((DevicePtr)pPointer,
- map,
- min(pMse->buttons, MSE_MAXBUTTONS),
- miPointerGetMotionEvents,
- pMse->Ctrl,
- miPointerGetMotionBufferSize());
+#ifdef HAVE_LABELS
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+ axes_labels[0] = XIGetKnownProperty((acol->xmin != acol->xmax)
+ ? AXIS_LABEL_PROP_ABS_X : AXIS_LABEL_PROP_REL_X);
+ axes_labels[1] = XIGetKnownProperty((acol->xmin != acol->xmax)
+ ? AXIS_LABEL_PROP_ABS_Y : AXIS_LABEL_PROP_REL_Y);
+ axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
+#endif
+
+ InitButtonClassDeviceStruct(pPointer, min(pMse->buttons, MSE_MAXBUTTONS),
+#ifdef HAVE_LABELS
+ btn_labels,
+#endif
+ map);
+ InitValuatorClassDeviceStruct(pPointer, (acol->pmin != acol->pmax) ? 3 : 2,
+#ifdef HAVE_LABELS
+ axes_labels,
+#endif
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
+ miPointerGetMotionEvents,
+#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
+ GetMotionHistory,
+#endif
+ GetMotionHistorySize(),
+ (acol->xmin != acol->xmax || acol->ymin != acol->ymax) ?
+ Absolute : Relative);
+ InitPtrFeedbackClassDeviceStruct(pPointer, pMse->Ctrl);
/* X valuator */
- xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorAxisStruct(pPointer, 0,
+#ifdef HAVE_LABELS
+ axes_labels[0],
+#endif
+ (acol->xmin != acol->xmax) ? acol->xmin : -1,
+ (acol->xmin != acol->xmax) ? acol->xmax : -1,
+ 1, 0, 1
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , (acol->xmin != acol->xmax) ? Absolute : Relative
+#endif
+ );
xf86InitValuatorDefaults(pPointer, 0);
/* Y valuator */
- xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorAxisStruct(pPointer, 1,
+#ifdef HAVE_LABELS
+ axes_labels[1],
+#endif
+ (acol->ymin != acol->ymax) ? acol->ymin : -1,
+ (acol->ymin != acol->ymax) ? acol->ymax : -1,
+ 1, 0, 1
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , (acol->ymin != acol->ymax) ? Absolute : Relative
+#endif
+ );
xf86InitValuatorDefaults(pPointer, 1);
+ /* Pressure valuator */
+ if (acol->pmin != acol->pmax) {
+ xf86InitValuatorAxisStruct(pPointer, 2,
+#ifdef HAVE_LABELS
+ axes_labels[2],
+#endif
+ acol->pmin, acol->pmax, 1, 0, 1
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , Absolute
+#endif
+ );
+ xf86InitValuatorDefaults(pPointer, 2);
+ }
xf86MotionHistoryAllocate(pInfo);
break;
case DEVICE_ON:
- pInfo->fd = xf86OpenSerial(pInfo->options);
- if (pInfo->fd == -1)
- xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
- else {
- pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize);
- if (!pMse->buffer) {
- free(pMse);
- xf86CloseSerial(pInfo->fd);
- pInfo->fd = -1;
- } else {
- xf86FlushInput(pInfo->fd);
- if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput,
- pInfo))
- AddEnabledDevice(pInfo->fd);
- }
+ if (pUsbMse->opened++ == 0) {
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize);
+ if (!pMse->buffer) {
+ free(pMse);
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ } else {
+ xf86FlushInput(pInfo->fd);
+ if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput,
+ pInfo))
+ AddEnabledDevice(pInfo->fd);
+ }
+ }
}
pMse->lastButtons = 0;
pMse->lastMappedButtons = 0;
@@ -553,6 +734,7 @@ usbMouseProc(DeviceIntPtr pPointer, int what)
xf86CloseSerial(pInfo->fd);
pInfo->fd = -1;
}
+ pUsbMse->opened--;
pPointer->public.on = FALSE;
usleep(300000);
break;
@@ -568,45 +750,154 @@ usbReadInput(InputInfoPtr pInfo)
{
MouseDevPtr pMse;
UsbMsePtr pUsbMse;
- int buttons = pMse->lastButtons;
- int dx = 0, dy = 0, dz = 0, dw = 0;
- int n, c;
+ int buttons, cc;
+ int dx, dy, dz, dw, dp, upd, v, nx, ny, np, in_range;
+ int n, c, rid, *sizep, nacol, nlcol;
unsigned char *pBuf;
+ struct UsbMseAcol *acol;
+ struct UsbMseLcol *lcol;
pMse = pInfo->private;
pUsbMse = pMse->mousePriv;
XisbBlockDuration(pMse->buffer, -1);
+next:
pBuf = pUsbMse->buffer;
n = 0;
- while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) {
+ if (pUsbMse->iid) {
+ rid = XisbRead(pMse->buffer);
+ if (rid < 0)
+ return;
+ pBuf[n++] = (unsigned char)rid;
+ } else
+ rid = 0;
+ sizep = usbGetReportSizePtr(pUsbMse, rid);
+ if (sizep == NULL || *sizep == 0) {
+ xf86Msg(X_WARNING, "%s: unknown report ID %d\n", pInfo->name, rid);
+ goto next;
+ }
+ while (n < *sizep && (c = XisbRead(pMse->buffer)) >= 0) {
pBuf[n++] = (unsigned char)c;
}
if (n == 0)
return;
- if (n != pUsbMse->packetSize) {
+// xf86MsgVerb(X_INFO, 3, "pkt: %d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+// n, pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7], pBuf[8], pBuf[9]);
+ if (n != *sizep) {
LogMessageVerbSigSafe(X_WARNING, -1,
"%s: incomplete packet, size %d\n",
pInfo->name, n);
}
- /* discard packets with an id that don't match the mouse */
- /* XXX this is probably not the right thing */
- if (pUsbMse->iid != 0) {
- if (*pBuf++ != pUsbMse->iid)
- return;
+ for (nacol = 0; nacol < pUsbMse->nacols; nacol++) {
+ acol = &pUsbMse->acols[nacol];
+ if (acol->pInfo == NULL)
+ continue;
+ nx = ny = np = upd = 0;
+ buttons = cc = 0;
+ dx = dy = dz = dw = dp = 0;
+ for (nlcol = 0; nlcol < pUsbMse->acols[nacol].nlcols; nlcol++) {
+ lcol = &acol->lcols[nlcol];
+
+ if (lcol->loc_valid.usage != 0 && rid == lcol->loc_valid.report_ID &&
+ hid_get_data(pBuf, &lcol->loc_valid) == 0)
+ continue;
+ if (lcol->loc_in_range.usage != 0 && rid == lcol->loc_in_range.report_ID)
+ in_range = hid_get_data(pBuf, &lcol->loc_in_range);
+ else
+ in_range = 1;
+ if (in_range && lcol->loc_x.usage != 0 && rid == lcol->loc_x.report_ID && nx == 0) {
+ v = hid_get_data(pBuf, &lcol->loc_x);
+ if (acol->xmin != acol->xmax) {
+ v = xf86ScaleAxis(v, acol->xmax, acol->xmin,
+ lcol->loc_x.logical_maximum, lcol->loc_x.logical_minimum);
+ if (acol->cxmin != acol->cxmax)
+ v = xf86ScaleAxis(v, acol->xmax, acol->xmin,
+ acol->cxmax, acol->cxmin);
+ }
+ dx += v;
+ nx++;
+ }
+ if (in_range && lcol->loc_y.usage != 0 && rid == lcol->loc_y.report_ID && ny == 0) {
+ v = hid_get_data(pBuf, &lcol->loc_y);
+ if (acol->xmin != acol->xmax) {
+ v = xf86ScaleAxis(v, acol->ymax, acol->ymin,
+ lcol->loc_y.logical_maximum, lcol->loc_y.logical_minimum);
+ if (acol->cymin != acol->cymax)
+ v = xf86ScaleAxis(v, acol->ymax, acol->ymin,
+ acol->cymax, acol->cymin);
+ }
+ dy += v;
+ ny++;
+ }
+ if (lcol->loc_z.usage != 0 && rid == lcol->loc_z.report_ID) {
+ dz -= hid_get_data(pBuf, &lcol->loc_z);
+ upd = 1;
+ }
+ if (lcol->loc_w.usage != 0 && rid == lcol->loc_w.report_ID) {
+ dw += hid_get_data(pBuf, &lcol->loc_w);
+ upd = 1;
+ }
+ if (lcol->loc_p.usage != 0 && rid == lcol->loc_p.report_ID && np == 0) {
+ v = hid_get_data(pBuf, &lcol->loc_p);
+ v = xf86ScaleAxis(v, acol->pmax, acol->pmin,
+ lcol->loc_p.logical_maximum, lcol->loc_p.logical_minimum);
+ if (acol->cpmin != acol->cpmax)
+ v = xf86ScaleAxis(v, acol->pmax, acol->pmin,
+ acol->cpmax, acol->cpmin);
+ dp += v;
+ np++;
+ }
+
+ for (n = 0; n < acol->nbuttons; n++) {
+ if (lcol->loc_btn[n].usage != 0 && rid == lcol->loc_btn[n].report_ID) {
+ if (hid_get_data(pBuf, &lcol->loc_btn[n]))
+ buttons |= (1 << UMS_BUT(n));
+ upd = 1;
+ }
+ }
+ }
+ if (acol->loc_cc.usage != 0 && rid == acol->loc_cc.report_ID)
+ cc = hid_get_data(pBuf, &acol->loc_cc);
+ else
+ cc = (nx || ny) ? 1 : 0;
+ if (cc > 1)
+ buttons = (1 << UMS_BUT(1));
+ if (nx != 0 && acol->xmin != acol->xmax)
+ dx /= nx;
+ if (ny != 0 && acol->ymin != acol->ymax)
+ dy /= ny;
+ if (np != 0 && acol->pmin != acol->pmax)
+ dp /= np;
+// if (upd || nx || ny || np)
+// xf86MsgVerb(X_INFO, 3, "%d cc %d dx %d dy %d dz %d dw %d press %d buttons %02x\n",
+// nacol, cc, dx, dy, dz, dw, dp, buttons);
+ if (nx != 0 || ny != 0) {
+ if (acol->pmin != acol->pmax) {
+ xf86PostMotionEvent(acol->pInfo->dev,
+ /* is_absolute: */ TRUE,
+ /* first_valuator: */ 0,
+ /* num_valuators: */ 3,
+ dx, dy, dp);
+ } else if (acol->xmin != acol->xmax || acol->ymin != acol->ymax) {
+ xf86PostMotionEvent(acol->pInfo->dev,
+ /* is_absolute: */ TRUE,
+ /* first_valuator: */ 0,
+ /* num_valuators: */ 2,
+ dx, dy);
+ }
+ }
+ if (upd || (nx != 0) || (ny != 0)) {
+ ((MouseDevPtr)acol->pInfo->private)->PostEvent(acol->pInfo, buttons,
+ ((acol->xmin != acol->xmax) ? dx - acol->px : dx),
+ ((acol->ymin != acol->ymax) ? dy - acol->py : dy),
+ dz, dw);
+ }
+ if (nx > 0)
+ acol->px = dx;
+ if (ny > 0)
+ acol->py = dy;
}
- dx = hid_get_data(pBuf, &pUsbMse->loc_x);
- dy = hid_get_data(pBuf, &pUsbMse->loc_y);
- dz = hid_get_data(pBuf, &pUsbMse->loc_z);
- dw = hid_get_data(pBuf, &pUsbMse->loc_w);
-
- buttons = 0;
- for (n = 0; n < pMse->buttons; n++) {
- if (hid_get_data(pBuf, &pUsbMse->loc_btn[n]))
- buttons |= (1 << UMS_BUT(n));
- }
- pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
- return;
+ goto next;
}
static void
@@ -615,14 +906,17 @@ usbSigioReadInput (int fd, void *closure)
usbReadInput ((InputInfoPtr) closure);
}
-/* This function is called when the protocol is "usb". */
static Bool
-usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+usbInitFirst(InputInfoPtr pInfo)
{
MouseDevPtr pMse = pInfo->private;
UsbMsePtr pUsbMse;
report_desc_t reportDesc;
- int i;
+ hid_data_t d;
+ hid_item_t h;
+ struct UsbMseAcol *acol;
+ struct UsbMseLcol *lcol;
+ int mdepth, rsize, *rsizep, acolused, lcolused, used;
pUsbMse = malloc(sizeof(UsbMseRec));
if (pUsbMse == NULL) {
@@ -631,12 +925,7 @@ usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
return FALSE;
}
- pMse->protocol = protocol;
- xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
-
- /* Collect the options, and process the common options. */
- COLLECT_INPUT_OPTIONS(pInfo, NULL);
- xf86ProcessCommonOptions(pInfo, pInfo->options);
+ bzero(pUsbMse, sizeof(UsbMseRec));
/* Check if the device can be opened. */
pInfo->fd = xf86OpenSerial(pInfo->options);
@@ -652,19 +941,134 @@ usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
}
/* Get USB informations */
reportDesc = hid_get_report_desc(pInfo->fd);
- /* Get packet size & iid */
-#ifdef USB_NEW_HID
- if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) {
- xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n",
- pInfo->name, strerror(errno));
- return FALSE;
+ mdepth = 0;
+ pUsbMse->nacols = 0;
+ acol = &pUsbMse->acols[pUsbMse->nacols];
+ lcol = &acol->lcols[acol->nlcols];
+ acolused = 0;
+ lcolused = 0;
+ d = hid_start_parse(reportDesc, (1 << hid_input) |
+ (1 << hid_collection) | (1 << hid_endcollection), -1);
+ while (hid_get_item(d, &h)) {
+ switch (h.kind) {
+ case hid_collection:
+ if (mdepth != 0)
+ mdepth++;
+ else if (h.collection == 1 &&
+ (h.usage == 0x00010001 || h.usage == 0x00010002 ||
+ (h.usage >= 0x000d0001 && h.usage <= 0x000d000d))) {
+ mdepth++;
+ if (acolused) {
+ if (lcolused) {
+ acol->nlcols++;
+ lcolused = 0;
+ }
+ pUsbMse->nacols++;
+ acolused = 0;
+ acol = &pUsbMse->acols[pUsbMse->nacols];
+ lcol = &acol->lcols[acol->nlcols];
+ }
+ }
+ if (lcolused && (h.collection == 0 ||
+ h.collection == 2 || h.collection == 3)) {
+ acol->nlcols++;
+ lcolused = 0;
+ lcol = &acol->lcols[acol->nlcols];
+ }
+ break;
+ case hid_endcollection:
+ if (mdepth != 0)
+ mdepth--;
+ break;
+ case hid_input:
+ if (h.report_ID != 0)
+ pUsbMse->iid = 1;
+ rsize = pUsbMse->iid +
+ (h.pos + (h.report_size * h.report_count) + 7) / 8;
+ if ((rsizep = usbGetReportSizePtr(pUsbMse, h.report_ID)) != NULL)
+ *rsizep = max(*rsizep, rsize);
+ pUsbMse->packetSize = max(pUsbMse->packetSize, rsize);
+ if (mdepth == 0)
+ break;
+ used = 1;
+ if (h.usage == 0x00010030) { /* X */
+ lcol->loc_x = h;
+ if ((h.flags & 0x04) == 0) {
+ if (acol->xmin == acol->xmax) {
+ acol->xmin = h.logical_minimum;
+ acol->xmax = h.logical_maximum;
+ } else {
+ acol->xmin = min(acol->xmin, h.logical_minimum);
+ acol->xmax = max(acol->xmax, h.logical_maximum);
+ }
+ }
+ } else if (h.usage == 0x00010031) { /* Y */
+ lcol->loc_y = h;
+ if ((h.flags & 0x04) == 0) {
+ if (acol->ymin == acol->ymax) {
+ acol->ymin = h.logical_minimum;
+ acol->ymax = h.logical_maximum;
+ } else {
+ acol->ymin = min(acol->ymin, h.logical_minimum);
+ acol->ymax = max(acol->ymax, h.logical_maximum);
+ }
+ }
+ } else if (h.usage == 0x00010038) { /* Z */
+ lcol->loc_z = h;
+ acol->hasZ = 1;
+ } else if (h.usage == 0x000c0238) { /* W */
+ lcol->loc_w = h;
+ acol->hasW = 1;
+ } else if (h.usage == 0x000d0030) { /* Press */
+ lcol->loc_p = h;
+ if ((h.flags & 0x04) == 0) {
+ if (acol->pmin == acol->pmax) {
+ acol->pmin = h.logical_minimum;
+ acol->pmax = h.logical_maximum;
+ } else {
+ acol->pmin = min(acol->pmin, h.logical_minimum);
+ acol->pmax = max(acol->pmax, h.logical_maximum);
+ }
+ }
+ } else if (h.usage == 0x000d0032) /* In Range */
+ lcol->loc_in_range = h;
+ else if (h.usage == 0x000d0047) /* Valid */
+ lcol->loc_valid = h;
+ else if (h.usage > 0x00090000 &&
+ h.usage <= 0x00090000 + MSE_MAXBUTTONS) { /* Buttons */
+ lcol->loc_btn[(h.usage & 0xffff) - 1] = h;
+ acol->nbuttons = max(acol->nbuttons, h.usage & 0xffff);
+ } else if (h.usage == 0x000d0042) { /* Tip Switch */
+ lcol->loc_btn[0] = h;
+ acol->nbuttons = max(acol->nbuttons, 1);
+ } else if (h.usage == 0x000d0044) { /* Barrel Switch */
+ lcol->loc_btn[1] = h;
+ acol->nbuttons = max(acol->nbuttons, 2);
+ } else if (h.usage == 0x000d0045) { /* Eraser */
+ lcol->loc_btn[3] = h;
+ acol->nbuttons = max(acol->nbuttons, 4);
+ } else if (h.usage == 0x000d0046) { /* Tablet Pick */
+ lcol->loc_btn[2] = h;
+ acol->nbuttons = max(acol->nbuttons, 3);
+ } else if (h.usage == 0x000d0054) /* Contact Count */
+ acol->loc_cc = h;
+ else
+ used = 0;
+ lcolused += used;
+ acolused += used;
+ break;
+ default:
+ break;
+ }
}
- pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
- pUsbMse->iid);
-#else
- pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
- &pUsbMse->iid);
-#endif
+ if (lcolused)
+ acol->nlcols++;
+ if (acolused)
+ pUsbMse->nacols++;
+ hid_end_parse(d);
+ xf86Msg(X_DEFAULT, "%s: Found %d usable logical collections\n",
+ pInfo->name, pUsbMse->nacols);
+
/* Allocate buffer */
if (pUsbMse->packetSize <= 8) {
pUsbMse->buffer = pMse->protoBuf;
@@ -674,56 +1078,129 @@ usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
if (pUsbMse->buffer == NULL) {
xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
free(pUsbMse);
- free(pMse);
xf86CloseSerial(pInfo->fd);
return FALSE;
}
-#ifdef USB_NEW_HID
- if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) {
- xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
- }
- if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) {
- xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
- }
- if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
- hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) {
- }
-#else
- if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- hid_input, &pUsbMse->loc_x) < 0) {
- xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
- }
- if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- hid_input, &pUsbMse->loc_y) < 0) {
- xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
- }
- if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
- hid_input, &pUsbMse->loc_z) < 0) {
- }
-#endif
- /* Probe for number of buttons */
- for (i = 1; i <= MSE_MAXBUTTONS; i++) {
- if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &pUsbMse->loc_btn[i-1]
-#ifdef USB_NEW_HID
- , pUsbMse->iid
-#endif
- ))
- break;
- }
- pMse->buttons = i-1;
xf86CloseSerial(pInfo->fd);
pInfo->fd = -1;
/* Private structure */
pMse->mousePriv = pUsbMse;
+ return TRUE;
+}
+
+/* This function is called when the protocol is "usb". */
+static Bool
+usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ InputInfoPtr pMatch;
+ MouseDevPtr pMse = pInfo->private;
+ UsbMsePtr pUsbMse;
+ struct UsbMseAcol *acol;
+ char *str;
+ int i, colopt;
+
+ pMse->protocol = protocol;
+ xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
+
+ /* Collect the options, and process the common options. */
+ COLLECT_INPUT_OPTIONS(pInfo, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ /* Check if this HID device is already opened. */
+ for (pMatch = xf86FirstLocalDevice(); pMatch != NULL; pMatch = pMatch->next) {
+ if ((pInfo != pMatch) && strstr(pMatch->drv->driverName, "mouse")) {
+ char *dev1, *dev2;
+
+ dev1 = xf86SetStrOption(pInfo->options, "Device", NULL);
+ dev2 = xf86SetStrOption(pMatch->options, "Device", NULL);
+ if (strcmp(dev1, dev2) == 0) {
+ free(dev1);
+ free(dev2);
+ break;
+ }
+ free(dev1);
+ free(dev2);
+ }
+ }
+ if (pMatch == NULL) {
+ xf86Msg(X_DEFAULT, "%s: Opening new HID device\n", pInfo->name);
+ if (!usbInitFirst(pInfo)) {
+ free(pMse);
+ return FALSE;
+ }
+ } else {
+ pMse->mousePriv = ((MouseDevPtr)pMatch->private)->mousePriv;
+ xf86Msg(X_DEFAULT, "%s: Attaching to already opened HID device\n",
+ pInfo->name);
+ }
+ pUsbMse = pMse->mousePriv;
+
+ /* Attach to collection, respecting "Collection" option. */
+ colopt = xf86SetIntOption(pInfo->options, "Collection", 0);
+ for (i = 0; i < pUsbMse->nacols; i++) {
+ if (pUsbMse->acols[i].pInfo == NULL &&
+ (colopt == 0 || i == colopt - 1)) {
+ pUsbMse->acols[i].pInfo = pInfo;
+ break;
+ }
+ }
+ xf86Msg(colopt == 0 ? X_DEFAULT : X_CONFIG,
+ "%s: Collection: %d\n", pInfo->name,
+ i == pUsbMse->nacols ? colopt : i + 1);
+ if (i == pUsbMse->nacols) {
+ xf86Msg(X_ERROR,
+ "%s: Application collection not found or already handled\n",
+ pInfo->name);
+ free(pMse);
+ return FALSE;
+ }
+
+ acol = &pUsbMse->acols[i];
+ pMse->buttons = acol->nbuttons;
+ if (pMse->buttons == 2)
+ pMse->buttons = 3;
+ if (acol->xmin != acol->xmax || acol->ymin != acol->ymax)
+ pMse->disableXY = TRUE;
+ pMse->hasZ = acol->hasZ;
+ pMse->hasW = acol->hasW;
/* Process common mouse options (like Emulate3Buttons, etc). */
pMse->CommonOptions(pInfo);
+ /* Process "Calibration" option. */
+ str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
+ if (str != NULL && (acol->xmin != acol->xmax || acol->ymin != acol->ymax)) {
+ int j, xmin, xmax, ymin, ymax, pmin, pmax;
+
+ j = sscanf(str, "%d %d %d %d %d %d", &xmin, &xmax, &ymin, &ymax, &pmin, &pmax);
+ if (j == 4) {
+ xf86Msg(X_CONFIG, "%s: Calibration: %d %d %d %d\n",
+ pInfo->name, xmin, xmax, ymin, ymax);
+ acol->cxmin = xmin;
+ acol->cxmax = xmax;
+ acol->cymin = ymin;
+ acol->cymax = ymax;
+ } else if (j == 6) {
+ xf86Msg(X_CONFIG, "%s: Calibration: %d %d %d %d %d %d\n",
+ pInfo->name, xmin, xmax, ymin, ymax, pmin, pmax);
+ acol->cxmin = xmin;
+ acol->cxmax = xmax;
+ acol->cymin = ymin;
+ acol->cymax = ymax;
+ acol->cpmin = pmin;
+ acol->cpmax = pmax;
+ } else
+ xf86Msg(X_WARNING, "%s: Calibration: Invalid arguments\n",
+ pInfo->name);
+ free(str);
+ } else if (acol->xmin != acol->xmax || acol->ymin != acol->ymax) {
+ xf86Msg(X_DEFAULT, "%s: Calibration: %d %d %d %d %d %d\n",
+ pInfo->name, acol->xmin, acol->xmax, acol->ymin, acol->ymax,
+ acol->pmin, acol->pmax);
+ }
+
/* Setup the local procs. */
pInfo->device_control = usbMouseProc;
pInfo->read_input = usbReadInput;
@@ -766,7 +1243,9 @@ OSMouseInit(int flags)
p->CheckProtocol = CheckProtocol;
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
p->SetupAuto = SetupAuto;
+#ifndef XPS2_SUPPORT
p->SetPS2Res = SetSysMouseRes;
+#endif
p->SetBMRes = SetSysMouseRes;
p->SetMiscRes = SetSysMouseRes;
#endif
diff --git a/src/mouse.c b/src/mouse.c
index 0487067..bf56db9 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -280,13 +280,39 @@ MouseCommonOptions(InputInfoPtr pInfo)
pMse = pInfo->private;
- pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
+ i = xf86SetIntOption(pInfo->options, "Buttons", 0);
+ if (i != 0)
+ pMse->buttons = i;
if (!pMse->buttons) {
pMse->buttons = MSE_DFLTBUTTONS;
buttons_from = X_DEFAULT;
}
origButtons = pMse->buttons;
+ s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL);
+ if (s) {
+ int b, n = 0;
+ char *s1 = s;
+ /* keep getting numbers which are buttons */
+ while (s1 && n < MSE_MAXBUTTONS && (b = strtol(s1, &s1, 10)) != 0) {
+ /* check sanity for a button */
+ if (b < 0 || b > MSE_MAXBUTTONS) {
+ xf86Msg(X_WARNING,
+ "ButtonMapping: Invalid button number = %d\n", b);
+ break;
+ };
+ pMse->buttonMap[n++] = 1 << (b-1);
+ if (b > pMse->buttons) pMse->buttons = b;
+ }
+ free(s);
+ }
+ /* get maximum of mapped buttons */
+ for (i = pMse->buttons-1; i >= 0; i--) {
+ int f = ffs (pMse->buttonMap[i]);
+ if (f > pMse->buttons)
+ pMse->buttons = f;
+ }
+
pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options,
"Emulate3Buttons", FALSE);
if (!xf86FindOptionValue(pInfo->options,"Emulate3Buttons")) {
@@ -298,6 +324,8 @@ MouseCommonOptions(InputInfoPtr pInfo)
"Emulate3Timeout", 50);
if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) {
MessageType from = X_CONFIG;
+ if (pMse->buttons < 3)
+ pMse->buttons = 3;
if (pMse->emulate3ButtonsSoft)
from = X_DEFAULT;
xf86Msg(from, "%s: Emulate3Buttons, Emulate3Timeout: %d\n",
@@ -305,6 +333,8 @@ MouseCommonOptions(InputInfoPtr pInfo)
}
pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE);
+ if (pMse->chordMiddle && pMse->buttons < 3)
+ pMse->buttons = 3;
pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE);
if (xf86SetBoolOption(pInfo->options, "InvX", FALSE)) {
pMse->invX = -1;
@@ -315,7 +345,7 @@ MouseCommonOptions(InputInfoPtr pInfo)
} else
pMse->invY = 1;
pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0);
-
+ pMse->sensitivity = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
if (pMse->pDragLock)
free(pMse->pDragLock);
@@ -425,14 +455,17 @@ MouseCommonOptions(InputInfoPtr pInfo)
free(s);
}
- s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5");
+ s = xf86SetStrOption(pInfo->options, "ZAxisMapping",
+ pMse->hasZ ? ( pMse->hasW ? "4 5 6 7" : "4 5" ) : "off");
if (s) {
int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
char *msg = NULL;
pMse->negativeZ = pMse->positiveZ = MSE_NOAXISMAP;
pMse->negativeW = pMse->positiveW = MSE_NOAXISMAP;
- if (!xf86NameCmp(s, "x")) {
+ if (!xf86NameCmp(s, "off")) {
+ msg = xstrdup("off");
+ } else if (!xf86NameCmp(s, "x")) {
pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
msg = xstrdup("X axis");
} else if (!xf86NameCmp(s, "y")) {
@@ -568,29 +601,6 @@ MouseCommonOptions(InputInfoPtr pInfo)
pInfo->name, wheelButton, pMse->wheelInertia,
pMse->wheelButtonTimeout);
}
- s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL);
- if (s) {
- int b, n = 0;
- char *s1 = s;
- /* keep getting numbers which are buttons */
- while (s1 && n < MSE_MAXBUTTONS && (b = strtol(s1, &s1, 10)) != 0) {
- /* check sanity for a button */
- if (b < 0 || b > MSE_MAXBUTTONS) {
- xf86Msg(X_WARNING,
- "ButtonMapping: Invalid button number = %d\n", b);
- break;
- };
- pMse->buttonMap[n++] = 1 << (b-1);
- if (b > pMse->buttons) pMse->buttons = b;
- }
- free(s);
- }
- /* get maximum of mapped buttons */
- for (i = pMse->buttons-1; i >= 0; i--) {
- int f = ffs (pMse->buttonMap[i]);
- if (f > pMse->buttons)
- pMse->buttons = f;
- }
if (origButtons != pMse->buttons)
buttons_from = X_CONFIG;
xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons);
@@ -668,7 +678,6 @@ MouseHWOptions(InputInfoPtr pInfo)
}
pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0);
pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0);
- mPriv->sensitivity = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
}
static void
@@ -959,6 +968,8 @@ MousePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
/* Default Mapping: 1 2 3 8 9 10 11 ... */
for (i = 0; i < MSE_MAXBUTTONS; i++)
pMse->buttonMap[i] = 1 << (i > 2 && i < MSE_MAXBUTTONS-4 ? i+4 : i);
+ pMse->hasZ = 1;
+ pMse->hasW = 0;
protocol = MousePickProtocol(pInfo, device, protocol, &protocolID);
@@ -2136,7 +2147,7 @@ MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
if (pMse->emulateWheel) {
/* Emulate wheel button handling */
- if(pMse->wheelButton == 0)
+ if (pMse->wheelButton == 0)
wheelButtonMask = 0;
else
wheelButtonMask = 1 << (pMse->wheelButton - 1);
@@ -2220,6 +2231,9 @@ MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
}
}
}
+ } else {
+ pMse->wheelXDistance = 0;
+ pMse->wheelYDistance = 0;
}
/* Absorb the mouse movement while the wheel button is pressed. */
@@ -2237,7 +2251,7 @@ MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
if (pMse->emulate3ButtonsSoft && pMse->emulate3Pending && (dx || dy))
buttonTimer(pInfo);
- if (dx || dy)
+ if ((dx || dy) && !pMse->disableXY)
xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
if (change) {
@@ -2349,12 +2363,10 @@ MousePostEvent(InputInfoPtr pInfo, int truebuttons,
int dx, int dy, int dz, int dw)
{
MouseDevPtr pMse;
- mousePrivPtr mousepriv;
int zbutton = 0, wbutton = 0, zbuttoncount = 0, wbuttoncount = 0;
int i, b, buttons = 0;
pMse = pInfo->private;
- mousepriv = (mousePrivPtr)pMse->mousePriv;
if (pMse->protocolID == PROT_MMHIT)
b = reverseBits(hitachMap, truebuttons);
@@ -2447,11 +2459,11 @@ MousePostEvent(InputInfoPtr pInfo, int truebuttons,
/* Accumulate the scaled dx, dy in the private variables
fracdx,fracdy and return the integer number part */
- if (mousepriv) {
- mousepriv->fracdx += mousepriv->sensitivity*dx;
- mousepriv->fracdy += mousepriv->sensitivity*dy;
- mousepriv->fracdx -= ( dx=(int)(mousepriv->fracdx) );
- mousepriv->fracdy -= ( dy=(int)(mousepriv->fracdy) );
+ if (pMse->sensitivity != 0) {
+ pMse->fracdx += pMse->sensitivity*dx;
+ pMse->fracdy += pMse->sensitivity*dy;
+ pMse->fracdx -= ( dx=(int)(pMse->fracdx) );
+ pMse->fracdy -= ( dy=(int)(pMse->fracdy) );
}
/* If mouse wheel movement has to be mapped on a button, we need to
diff --git a/src/mouse.h b/src/mouse.h
index e1165f2..f14403a 100644
--- a/src/mouse.h
+++ b/src/mouse.h
@@ -220,10 +220,13 @@ typedef struct _MouseDevRec {
Bool emulate3ButtonsSoft;
int emulate3Timeout;/* Timeout for 3 button emulation */
Bool chordMiddle;
+ Bool disableXY;
Bool flipXY;
int invX;
int invY;
int resolution;
+ Bool hasW;
+ Bool hasZ;
int negativeZ; /* button mask */
int positiveZ; /* button mask */
int negativeW; /* button mask */
@@ -262,6 +265,8 @@ typedef struct _MouseDevRec {
int doubleClickOldSourceState;
int lastMappedButtons;
int buttonMap[MSE_MAXBUTTONS];
+ float fracdx,fracdy;
+ float sensitivity;
} MouseDevRec, *MouseDevPtr;
#endif /* _XF86OSMOUSE_H_ */
diff --git a/src/mousePriv.h b/src/mousePriv.h
index b15e461..ad96eb9 100644
--- a/src/mousePriv.h
+++ b/src/mousePriv.h
@@ -63,8 +63,6 @@ typedef struct {
int acc;
CARD32 pnpLast;
Bool disablePnPauto;
- float fracdx,fracdy;
- float sensitivity;
} mousePrivRec, *mousePrivPtr;
/* mouse proto flags */
signature.asc
Description: OpenPGP digital signature
_______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
