diff -ruNp --exclude .libs --exclude .deps --exclude '*a' --exclude '*.orig' --exclude '*.log' /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/Makefile.am src/Makefile.am --- /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/Makefile.am 2010-03-23 03:43:43.000000000 +0200 +++ src/Makefile.am 2011-07-19 12:56:43.000000000 +0300 @@ -27,7 +27,7 @@ AM_CPPFLAGS = $(XORG_CFLAGS) # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la -@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version +@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version -lusbhid @DRIVER_NAME@_drv_ladir = @inputdir@ # We have to list all the mouse drivers here, even if we don't build them, so diff -ruNp --exclude .libs --exclude .deps --exclude '*a' --exclude '*.orig' --exclude '*.log' /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/Makefile.in src/Makefile.in --- /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/Makefile.in 2010-09-09 09:13:01.000000000 +0300 +++ src/Makefile.in 2011-07-19 12:56:43.000000000 +0300 @@ -276,7 +276,7 @@ AM_CPPFLAGS = $(XORG_CFLAGS) # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la -@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version +@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version -lusbhid @DRIVER_NAME@_drv_ladir = @inputdir@ # We have to list all the mouse drivers here, even if we don't build them, so diff -ruNp --exclude .libs --exclude .deps --exclude '*a' --exclude '*.orig' --exclude '*.log' /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/bsd_mouse.c src/bsd_mouse.c --- /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/bsd_mouse.c 2011-06-23 13:09:28.000000000 +0300 +++ src/bsd_mouse.c 2011-07-20 21:29:41.000000000 +0300 @@ -24,6 +24,8 @@ * the sale, use or other dealings in this Software without prior written * authorization from the copyright holder(s) and author(s). */ +#define USBMOUSE_SUPPORT 1 +#define HAS_LIB_USB_HID 1 #include @@ -32,9 +34,23 @@ #include "xf86Priv.h" #include "xf86_OSlib.h" #include "xf86Xinput.h" +#include #include "xf86OSmouse.h" #include "xisb.h" #include "mipointer.h" +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 +#define HAVE_PROPERTIES 1 +#endif +#ifdef HAVE_PROPERTIES +#include +#include +/* 1.6 has properties, but no labels */ +#ifdef AXIS_LABEL_PROP +#define HAVE_LABELS +#else +#undef HAVE_LABELS +#endif +#endif #ifdef WSCONS_SUPPORT #include #endif @@ -46,9 +62,6 @@ #endif #include -#ifdef USB_GET_REPORT_ID -#define USB_NEW_HID -#endif #define HUP_GENERIC_DESKTOP 0x0001 #define HUP_BUTTON 0x0009 @@ -538,30 +551,78 @@ wsconsPreInit(InputInfoPtr pInfo, const #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: @@ -570,38 +631,96 @@ usbMouseProc(DeviceIntPtr pPointer, int 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) { - xfree(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) { + xfree(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; @@ -623,6 +742,7 @@ usbMouseProc(DeviceIntPtr pPointer, int xf86CloseSerial(pInfo->fd); pInfo->fd = -1; } + pUsbMse->opened--; pPointer->public.on = FALSE; usleep(300000); break; @@ -635,43 +755,152 @@ 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) { - xf86Msg(X_WARNING, "%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; - } - 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)); +// 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) { + xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", pInfo->name, n); + } + 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; } - pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); + goto next; return; } @@ -681,14 +910,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 = xalloc(sizeof(UsbMseRec)); if (pUsbMse == NULL) { @@ -696,13 +928,7 @@ usbPreInit(InputInfoPtr pInfo, const cha xfree(pMse); return FALSE; } - - pMse->protocol = protocol; - xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); - - /* Collect the options, and process the common options. */ - xf86CollectInputOptions(pInfo, NULL, NULL); - xf86ProcessCommonOptions(pInfo, pInfo->options); + bzero(pUsbMse, sizeof(UsbMseRec)); /* Check if the device can be opened. */ pInfo->fd = xf86OpenSerial(pInfo->options); @@ -718,19 +944,134 @@ usbPreInit(InputInfoPtr pInfo, const cha } /* 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), 0); + 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; @@ -740,56 +1081,131 @@ usbPreInit(InputInfoPtr pInfo, const cha if (pUsbMse->buffer == NULL) { xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name); xfree(pUsbMse); - xfree(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; + MouseDevPtr pMseMatch; + 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. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + /* Check if this HID device is already opened. */ + for (pMatch = xf86FirstLocalDevice(); pMatch != NULL; pMatch = pMatch->next) { + pMseMatch = (MouseDevPtr)pMatch->private; + 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) { + xfree(dev1); + xfree(dev2); + break; + } + xfree(dev1); + xfree(dev2); + } + } + if (pMatch == NULL) { + xf86Msg(X_DEFAULT, "%s: Opening new HID device\n", pInfo->name); + if (!usbInitFirst(pInfo)) { + xfree(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); + xfree(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; diff -ruNp --exclude .libs --exclude .deps --exclude '*a' --exclude '*.orig' --exclude '*.log' /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/mouse.c src/mouse.c --- /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/mouse.c 2010-08-14 11:04:54.000000000 +0300 +++ src/mouse.c 2011-07-19 12:56:43.000000000 +0300 @@ -293,13 +293,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; + } + xfree(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")) { @@ -311,6 +337,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", @@ -318,8 +346,12 @@ MouseCommonOptions(InputInfoPtr pInfo) } pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE); - if (pMse->chordMiddle) + if (pMse->chordMiddle) { + if (pMse->buttons < 3) + pMse->buttons = 3; xf86Msg(X_CONFIG, "%s: ChordMiddle\n", pInfo->name); + } + pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE); if (pMse->flipXY) xf86Msg(X_CONFIG, "%s: FlipXY\n", pInfo->name); @@ -334,7 +366,12 @@ MouseCommonOptions(InputInfoPtr pInfo) } else pMse->invY = 1; pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0); - + + if ((pMse->sensitivity + = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0))) { + xf86Msg(X_CONFIG, "%s: Sensitivity: %g\n", pInfo->name, + pMse->sensitivity); + } if (pMse->pDragLock) xfree(pMse->pDragLock); @@ -444,14 +481,17 @@ MouseCommonOptions(InputInfoPtr pInfo) xfree(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")) { @@ -587,29 +627,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; - } - xfree(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); @@ -695,12 +712,6 @@ MouseHWOptions(InputInfoPtr pInfo) xf86Msg(X_CONFIG, "%s: Resolution: %d\n", pInfo->name, pMse->resolution); } - - if ((mPriv->sensitivity - = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0))) { - xf86Msg(X_CONFIG, "%s: Sensitivity: %g\n", pInfo->name, - mPriv->sensitivity); - } } static void @@ -921,6 +932,8 @@ MousePreInit(InputDriverPtr drv, IDevPtr /* 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; protocolID = ProtocolNameToID(protocol); do { @@ -2129,6 +2142,9 @@ MouseDoPostEvent(InputInfoPtr pInfo, int } } } + } else { + pMse->wheelXDistance = 0; + pMse->wheelYDistance = 0; } /* Absorb the mouse movement while the wheel button is pressed. */ @@ -2146,7 +2162,7 @@ MouseDoPostEvent(InputInfoPtr pInfo, int 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) { @@ -2356,13 +2372,13 @@ MousePostEvent(InputInfoPtr pInfo, int t /* 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 * loop for button press and release events. */ do { diff -ruNp --exclude .libs --exclude .deps --exclude '*a' --exclude '*.orig' --exclude '*.log' /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/mousePriv.h src/mousePriv.h --- /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/mousePriv.h 2009-10-17 00:40:45.000000000 +0300 +++ src/mousePriv.h 2011-07-19 12:56:43.000000000 +0300 @@ -63,8 +63,6 @@ typedef struct { int acc; CARD32 pnpLast; Bool disablePnPauto; - float fracdx,fracdy; - float sensitivity; } mousePrivRec, *mousePrivPtr; /* mouse proto flags */ diff -ruNp --exclude .libs --exclude .deps --exclude '*a' --exclude '*.orig' --exclude '*.log' /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/xf86OSmouse.h src/xf86OSmouse.h --- /usr/ports/x11-drivers/xf86-input-mouse/xf86-input-mouse-1.6.0.orig/src/xf86OSmouse.h 2010-08-14 11:04:54.000000000 +0300 +++ src/xf86OSmouse.h 2011-07-19 12:56:43.000000000 +0300 @@ -220,6 +220,7 @@ typedef struct _MouseDevRec { Bool emulate3ButtonsSoft; int emulate3Timeout;/* Timeout for 3 button emulation */ Bool chordMiddle; + Bool disableXY; Bool flipXY; int invX; int invY; @@ -229,6 +230,7 @@ typedef struct _MouseDevRec { * Arg to maintain before * emulate3buttons timer callback */ int resolution; + Bool hasZ, hasW; int negativeZ; /* button mask */ int positiveZ; /* button mask */ int negativeW; /* button mask */ @@ -269,6 +271,8 @@ typedef struct _MouseDevRec { int doubleClickOldSourceState; int lastMappedButtons; int buttonMap[MSE_MAXBUTTONS]; + float fracdx,fracdy; + float sensitivity; } MouseDevRec, *MouseDevPtr; #endif /* _XF86OSMOUSE_H_ */