Ravenports generated: 09 Jan 2022 18:36
[ravenports.git] / bucket_85 / xorg-driver-input-mouse
1 # Buildsheet autogenerated by ravenadm tool -- Do not edit.
2
3 NAMEBASE=               xorg-driver-input-mouse
4 VERSION=                1.9.3
5 KEYWORDS=               x11_drivers
6 VARIANTS=               standard
7 SDESC[standard]=        X.org mouse input driver
8 HOMEPAGE=               https://www.x.org/
9 CONTACT=                nobody
10
11 DOWNLOAD_GROUPS=        main
12 SITES[main]=            XORG/individual/driver
13 DISTFILE[1]=            xf86-input-mouse-1.9.3.tar.bz2:main
14 DF_INDEX=               1
15 SPKGS[standard]=        single
16
17 OPTIONS_AVAILABLE=      none
18 OPTIONS_STANDARD=       none
19
20 BUILDRUN_DEPENDS=       xorg-server:single:standard
21
22 USES=                   libtool
23 XORG_COMPONENTS=        xorgproto
24
25 DISTNAME=               xf86-input-mouse-1.9.3
26
27 LICENSE=                MIT:single
28 LICENSE_FILE=           MIT:{{WRKSRC}}/COPYING
29 LICENSE_SCHEME=         solo
30
31 FPC_EQUIVALENT=         x11-drivers/xf86-input-mouse
32
33 MUST_CONFIGURE=         gnu
34 CONFIGURE_ENV=          DRIVER_MAN_SUFFIX=4
35
36 INSTALL_TARGET=         install-strip
37
38 [FILE:57:descriptions/desc.single]
39 This package contains the X.Org xf86-input-mouse driver.
40
41
42 [FILE:109:distinfo]
43 93ecb350604d05be98b7d4e5db3b8155a44890069a7d8d6b800c0bea79c85cc5       382013 xf86-input-mouse-1.9.3.tar.bz2
44
45
46 [FILE:130:manifests/plist.single]
47 include/xorg/xf86-mouse-properties.h
48 lib/pkgconfig/xorg-mouse.pc
49 lib/xorg/modules/input/mouse_drv.so
50 share/man/man4/mousedrv.4.gz
51
52
53 [FILE:34218:patches/patch-src_bsd__mouse.c]
54 --- src/bsd_mouse.c.orig        2018-06-19 04:36:21 UTC
55 +++ src/bsd_mouse.c
56 @@ -26,6 +26,24 @@
57   * authorization from the copyright holder(s) and author(s).
58   */
59  
60 +
61 +/*
62 + * XXX - Should this be autoconf'd instead?
63 + */
64 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
65 +
66 +#if !defined(USBMOUSE_SUPPORT)
67 +#define USBMOUSE_SUPPORT
68 +#endif
69 +#if !defined(HAS_LIB_USB_HID)
70 +#define HAS_LIB_USB_HID
71 +#endif
72 +#if !defined(XPS2_SUPPORT)
73 +#define XPS2_SUPPORT
74 +#endif
75 +
76 +#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) */
77 +
78  #include <xorg-server.h>
79  
80  #include <X11/X.h>
81 @@ -33,9 +51,23 @@
82  #include "xf86Priv.h"
83  #include "xf86_OSlib.h"
84  #include "xf86Xinput.h"
85 +#include <exevents.h>
86  #include "mouse.h"
87  #include "xisb.h"
88  #include "mipointer.h"
89 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
90 +#define HAVE_PROPERTIES 1
91 +#endif
92 +#ifdef HAVE_PROPERTIES
93 +#include <X11/Xatom.h>
94 +#include <xserver-properties.h>
95 +/* 1.6 has properties, but no labels */
96 +#ifdef AXIS_LABEL_PROP
97 +#define HAVE_LABELS
98 +#else
99 +#undef HAVE_LABELS
100 +#endif
101 +#endif
102  #ifdef WSCONS_SUPPORT
103  #include <dev/wscons/wsconsio.h>
104  #endif
105 @@ -46,9 +78,10 @@
106  #include "usb.h"
107  #endif
108  
109 +#if defined __DragonFly__
110 +#include <bus/u4b/usb.h>
111 +#else
112  #include <dev/usb/usb.h>
113 -#ifdef USB_GET_REPORT_ID
114 -#define USB_NEW_HID
115  #endif
116  
117  #define HUP_GENERIC_DESKTOP     0x0001
118 @@ -75,11 +108,13 @@ static const char *FindDevice(InputInfoP
119  #define DEFAULT_MOUSE_DEV               "/dev/mouse"
120  #define DEFAULT_SYSMOUSE_DEV            "/dev/sysmouse"
121  #define DEFAULT_PS2_DEV                 "/dev/psm0"
122 +#define DEFAULT_USB_DEV                 "/dev/ums0"
123  
124  static const char *mouseDevs[] = {
125          DEFAULT_MOUSE_DEV,
126          DEFAULT_SYSMOUSE_DEV,
127          DEFAULT_PS2_DEV,
128 +        DEFAULT_USB_DEV,
129          NULL
130  };
131  #elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
132 @@ -97,7 +132,7 @@ static const char *mouseDevs[] = {
133  static int
134  SupportedInterfaces(void)
135  {
136 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__NetBSD__)
137 +#if defined(__NetBSD__)
138      return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
139  #else
140      return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
141 @@ -178,9 +213,30 @@ static struct {
142          { MOUSE_PROTO_SYSMOUSE,         "SysMouse" }
143  };
144  
145 +#ifdef XPS2_SUPPORT
146 +static struct {
147 +        int dmodel;
148 +        const char *name;
149 +} ps2proto[] = {
150 +        { MOUSE_MODEL_NETSCROLL,        "NetScrollPS/2" },
151 +        { MOUSE_MODEL_NET,              "NetMousePS/2" },
152 +        { MOUSE_MODEL_GLIDEPOINT,       "GlidePointPS/2" },
153 +        { MOUSE_MODEL_THINK,            "ThinkingMousePS/2" },
154 +        { MOUSE_MODEL_INTELLI,          "IMPS/2" },
155 +        { MOUSE_MODEL_MOUSEMANPLUS,     "MouseManPlusPS/2" },
156 +        { MOUSE_MODEL_EXPLORER,         "ExplorerPS/2" },
157 +        { MOUSE_MODEL_4D,               "IMPS/2" },
158 +        { MOUSE_MODEL_4DPLUS,           "IMPS/2" },
159 +};
160 +#endif
161 +
162  static const char *
163  SetupAuto(InputInfoPtr pInfo, int *protoPara)
164  {
165 +#ifdef XPS2_SUPPORT
166 +    const char *dev;
167 +#endif
168 +    const char *proto;
169      int i;
170      mousehw_t hw;
171      mousemode_t mode;
172 @@ -188,7 +244,13 @@ SetupAuto(InputInfoPtr pInfo, int *proto
173      if (pInfo->fd == -1)
174          return NULL;
175  
176 +#ifdef XPS2_SUPPORT
177      /* set the driver operation level, if applicable */
178 +    dev = xf86FindOptionValue(pInfo->options, "Device");
179 +    if (dev != NULL && !strncmp(dev, DEFAULT_PS2_DEV, 8))
180 +        i = 2;
181 +    else
182 +#endif
183      i = 1;
184      ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
185  
186 @@ -207,9 +269,18 @@ SetupAuto(InputInfoPtr pInfo, int *proto
187                      protoPara[0] = mode.syncmask[0];
188                      protoPara[1] = mode.syncmask[1];
189                  }
190 +                proto = devproto[i].name;
191 +#ifdef XPS2_SUPPORT
192 +                if (mode.protocol == MOUSE_PROTO_PS2)
193 +                    for (i = 0; i < sizeof(ps2proto)/sizeof(ps2proto[0]); ++i)
194 +                        if (hw.model == ps2proto[i].dmodel) {
195 +                           proto = ps2proto[i].name;
196 +                           break;
197 +                }
198 +#endif
199                  xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
200 -                            pInfo->name, devproto[i].name);
201 -                return devproto[i].name;
202 +                            pInfo->name, proto);
203 +                return proto;
204              }
205          }
206      }
207 @@ -232,41 +303,41 @@ SetSysMouseRes(InputInfoPtr pInfo, const
208          (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
209          /*
210           * As the FreeBSD sysmouse driver defaults to protocol level 0
211 -         * everytime it is opened we enforce protocol level 1 again at
212 +         * everytime it is closed we enforce protocol level 1 again at
213           * this point.
214           */
215          mode.level = 1;
216      } else
217 -        mode.level = -1;
218 -#else
219 -    mode.level = -1;
220  #endif
221 +    mode.level = -1;
222      ioctl(pInfo->fd, MOUSE_SETMODE, &mode);
223  }
224  #endif
225  
226  #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
227 -
228 -#define MOUSED_PID_FILE "/var/run/moused.pid"
229 -
230  /*
231   * Try to check if moused is running.  DEFAULT_SYSMOUSE_DEV is useless without
232 - * it.  There doesn't seem to be a better way of checking.
233 + * it.  Also, try to check if the device is used by moused.  If it is opened
234 + * by moused, we do not want to use it directly.  There doesn't seem to be
235 + * a better way of checking.
236   */
237  static Bool
238 -MousedRunning(void)
239 +MousedRunning(const char *dev)
240  {
241 +    char cmd[128];
242      FILE *f = NULL;
243 -    unsigned int pid;
244 +    unsigned int i;
245  
246 -    if ((f = fopen(MOUSED_PID_FILE, "r")) != NULL) {
247 -        if (fscanf(f, "%u", &pid) == 1 && pid > 0) {
248 -            if (kill(pid, 0) == 0) {
249 -                fclose(f);
250 -                return TRUE;
251 -            }
252 +    if (dev)
253 +        sprintf(cmd, "sh -c 'fstat %s | grep -c moused' 2>/dev/null", dev);
254 +    else
255 +        sprintf(cmd, "sh -c 'pgrep -nx moused' 2>/dev/null");
256 +    if ((f = popen(cmd, "r")) != NULL) {
257 +        if (fscanf(f, "%u", &i) == 1 && i > 0) {
258 +            pclose(f);
259 +            return TRUE;
260          }
261 -        fclose(f);
262 +        pclose(f);
263      }
264      return FALSE;
265  }
266 @@ -274,17 +345,17 @@ MousedRunning(void)
267  static const char *
268  FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
269  {
270 -    int fd = -1;
271 +    int ret = -1;
272      const char **pdev, *dev = NULL;
273      Bool devMouse = FALSE;
274      struct stat devMouseStat;
275      struct stat sb;
276  
277      for (pdev = mouseDevs; *pdev; pdev++) {
278 -        SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK));
279 -        if (fd == -1) {
280 +        SYSCALL (ret = stat(*pdev, &sb));
281 +        if (ret == -1) {
282  #ifdef DEBUG
283 -            ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno));
284 +            ErrorF("Cannot stat %s (%s)\n", *pdev, strerror(errno));
285  #endif
286          } else {
287              /*
288 @@ -293,28 +364,32 @@ FindDevice(InputInfoPtr pInfo, const cha
289               * the test for whether /dev/sysmouse is usable can be made.
290               */
291              if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) {
292 -                if (fstat(fd, &devMouseStat) == 0)
293 -                    devMouse = TRUE;
294 -                close(fd);
295 +                memcpy(&devMouseStat, &sb, sizeof(devMouseStat));
296 +                devMouse = TRUE;
297                  continue;
298              } else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) {
299                  /* Check if /dev/mouse is the same as /dev/sysmouse. */
300 -                if (devMouse && fstat(fd, &sb) == 0 &&
301 -                    devMouseStat.st_dev == sb.st_dev &&
302 +                if (devMouse && devMouseStat.st_dev == sb.st_dev &&
303                      devMouseStat.st_ino == sb.st_ino) {
304                      /* If the same, use /dev/sysmouse. */
305                      devMouse = FALSE;
306                  }
307 -                close(fd);
308 -                if (MousedRunning())
309 +                if (MousedRunning(NULL))
310                      break;
311 -                else {
312 -#ifdef DEBUG
313 -                    ErrorF("moused isn't running\n");
314 -#endif
315 -                }
316              } else {
317 -                close(fd);
318 +                /* Check if /dev/mouse is the same as this device. */
319 +                if (devMouse && devMouseStat.st_dev == sb.st_dev &&
320 +                    devMouseStat.st_ino == sb.st_ino) {
321 +                    /* If the same, use this device. */
322 +                    devMouse = FALSE;
323 +                }
324 +                if (MousedRunning(*pdev))
325 +                    continue;
326 +                /* ums(4) does not support anything but SysMouse protocol. */
327 +                if (!strncmp(*pdev, DEFAULT_USB_DEV, 8) && protocol &&
328 +                    xf86NameCmp(protocol, "auto") != 0 &&
329 +                    xf86NameCmp(protocol, "sysmouse") != 0)
330 +                    continue;
331                  break;
332              }
333          }
334 @@ -486,30 +561,78 @@ wsconsPreInit(InputInfoPtr pInfo, const
335  
336  #if defined(USBMOUSE_SUPPORT)
337  
338 +#define MAXRIDS                64
339 +#define MAXACOLS       8
340 +#define MAXLCOLS       16
341  typedef struct _UsbMseRec {
342      int packetSize;
343 -    int iid;
344 -    hid_item_t loc_x;           /* x locator item */
345 -    hid_item_t loc_y;           /* y locator item */
346 -    hid_item_t loc_z;           /* z (wheel) locator item */
347 -    hid_item_t loc_w;           /* z (wheel) locator item */
348 -    hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
349 -   unsigned char *buffer;
350 +    int iid, nrids, nacols, opened;
351 +    struct {
352 +       int32_t rid;
353 +       int size;
354 +    } rids[MAXRIDS];
355 +    struct UsbMseAcol {
356 +       InputInfoPtr pInfo;
357 +       int nlcols, nbuttons, hasZ, hasW;
358 +       int xmin, xmax, ymin, ymax, pmin, pmax, px, py;
359 +       int cxmin, cxmax, cymin, cymax, cpmin, cpmax;
360 +       struct UsbMseLcol {
361 +           hid_item_t loc_x;           /* x locator item */
362 +           hid_item_t loc_y;           /* y locator item */
363 +           hid_item_t loc_z;           /* z (wheel) locator item */
364 +           hid_item_t loc_w;           /* w (hwheel) locator item */
365 +           hid_item_t loc_p;           /* Tip Pressure */
366 +           hid_item_t loc_valid;               /* Touch Valid */
367 +           hid_item_t loc_in_range;    /* In Range */
368 +           hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
369 +       } lcols[MAXLCOLS];
370 +       hid_item_t loc_cc;              /* contact count */
371 +    } acols[MAXACOLS];
372 +    unsigned char *buffer;
373  } UsbMseRec, *UsbMsePtr;
374  
375 +static int *
376 +usbGetReportSizePtr(UsbMsePtr pUsbMse, int32_t rid)
377 +{
378 +    int i;
379 +
380 +    for (i = 0; i < pUsbMse->nrids; i++) {
381 +       if (pUsbMse->rids[i].rid == rid)
382 +           return (&pUsbMse->rids[i].size);
383 +    }
384 +    for (i = 0; i < MAXRIDS; i++) {
385 +       if (pUsbMse->rids[i].size == 0) {
386 +           pUsbMse->rids[i].rid = rid;
387 +           pUsbMse->nrids = max(pUsbMse->nrids, i + 1);
388 +           return (&pUsbMse->rids[i].size);
389 +       }
390 +    }
391 +    return (NULL);
392 +}
393 +
394  static int
395  usbMouseProc(DeviceIntPtr pPointer, int what)
396  {
397      InputInfoPtr pInfo;
398      MouseDevPtr pMse;
399      UsbMsePtr pUsbMse;
400 +    struct UsbMseAcol *acol;
401      unsigned char map[MSE_MAXBUTTONS + 1];
402 -    int nbuttons;
403 +    int nacol, nbuttons;
404 +#ifdef HAVE_LABELS
405 +    Atom btn_labels[MSE_MAXBUTTONS] = {0};
406 +    Atom axes_labels[3] = { 0, 0, 0 };
407 +#endif
408  
409      pInfo = pPointer->public.devicePrivate;
410      pMse = pInfo->private;
411      pMse->device = pPointer;
412      pUsbMse = pMse->mousePriv;
413 +    for (nacol = 0; nacol < (pUsbMse->nacols - 1); nacol++) {
414 +       if (pUsbMse->acols[nacol].pInfo == pInfo)
415 +           break;
416 +    }
417 +    acol = &pUsbMse->acols[nacol];
418  
419      switch (what) {
420      case DEVICE_INIT:
421 @@ -518,40 +641,96 @@ usbMouseProc(DeviceIntPtr pPointer, int
422          for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
423              map[nbuttons + 1] = nbuttons + 1;
424  
425 -        InitPointerDeviceStruct((DevicePtr)pPointer,
426 -                                map,
427 -                                min(pMse->buttons, MSE_MAXBUTTONS),
428 -                                miPointerGetMotionEvents,
429 -                                pMse->Ctrl,
430 -                                miPointerGetMotionBufferSize());
431 +#ifdef HAVE_LABELS
432 +       btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
433 +       btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
434 +       btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
435 +       axes_labels[0] = XIGetKnownProperty((acol->xmin != acol->xmax)
436 +           ? AXIS_LABEL_PROP_ABS_X : AXIS_LABEL_PROP_REL_X);
437 +       axes_labels[1] = XIGetKnownProperty((acol->xmin != acol->xmax)
438 +           ? AXIS_LABEL_PROP_ABS_Y : AXIS_LABEL_PROP_REL_Y);
439 +       axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
440 +#endif
441 +
442 +       InitButtonClassDeviceStruct(pPointer, min(pMse->buttons, MSE_MAXBUTTONS),
443 +#ifdef HAVE_LABELS
444 +           btn_labels,
445 +#endif
446 +           map);
447 +       InitValuatorClassDeviceStruct(pPointer, (acol->pmin != acol->pmax) ? 3 : 2,
448 +#ifdef HAVE_LABELS
449 +           axes_labels,
450 +#endif
451 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
452 +           miPointerGetMotionEvents,
453 +#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
454 +           GetMotionHistory,
455 +#endif
456 +           GetMotionHistorySize(),
457 +           (acol->xmin != acol->xmax || acol->ymin != acol->ymax) ?
458 +            Absolute : Relative);
459 +       InitPtrFeedbackClassDeviceStruct(pPointer, pMse->Ctrl);
460  
461          /* X valuator */
462 -        xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
463 +       xf86InitValuatorAxisStruct(pPointer, 0,
464 +#ifdef HAVE_LABELS
465 +           axes_labels[0],
466 +#endif
467 +           (acol->xmin != acol->xmax) ? acol->xmin : -1,
468 +           (acol->xmin != acol->xmax) ? acol->xmax : -1,
469 +           1, 0, 1
470 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
471 +           , (acol->xmin != acol->xmax) ? Absolute : Relative
472 +#endif
473 +           );
474          xf86InitValuatorDefaults(pPointer, 0);
475          /* Y valuator */
476 -        xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
477 +       xf86InitValuatorAxisStruct(pPointer, 1,
478 +#ifdef HAVE_LABELS
479 +           axes_labels[1],
480 +#endif
481 +           (acol->ymin != acol->ymax) ? acol->ymin : -1,
482 +           (acol->ymin != acol->ymax) ? acol->ymax : -1,
483 +           1, 0, 1
484 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
485 +           , (acol->ymin != acol->ymax) ? Absolute : Relative
486 +#endif
487 +           );
488          xf86InitValuatorDefaults(pPointer, 1);
489 +       /* Pressure valuator */
490 +       if (acol->pmin != acol->pmax) {
491 +           xf86InitValuatorAxisStruct(pPointer, 2,
492 +#ifdef HAVE_LABELS
493 +               axes_labels[2],
494 +#endif
495 +               acol->pmin, acol->pmax, 1, 0, 1
496 +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
497 +               , Absolute
498 +#endif
499 +               );
500 +           xf86InitValuatorDefaults(pPointer, 2);
501 +       }
502          xf86MotionHistoryAllocate(pInfo);
503          break;
504  
505      case DEVICE_ON:
506 -        pInfo->fd = xf86OpenSerial(pInfo->options);
507 -        if (pInfo->fd == -1)
508 -            xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
509 -        else {
510 -            pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize);
511 -            if (!pMse->buffer) {
512 -                free(pMse);
513 -                xf86CloseSerial(pInfo->fd);
514 -                pInfo->fd = -1;
515 -            } else {
516 -                xf86FlushInput(pInfo->fd);
517 -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 23
518 -                if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput,
519 -                                              pInfo))
520 -#endif
521 -                    AddEnabledDevice(pInfo->fd);
522 -            }
523 +       if (pUsbMse->opened++ == 0) {
524 +               pInfo->fd = xf86OpenSerial(pInfo->options);
525 +               if (pInfo->fd == -1)
526 +                   xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
527 +               else {
528 +                   pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize);
529 +                   if (!pMse->buffer) {
530 +                       free(pMse);
531 +                       xf86CloseSerial(pInfo->fd);
532 +                       pInfo->fd = -1;
533 +                   } else {
534 +                       xf86FlushInput(pInfo->fd);
535 +                       if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput, 
536 +                                                     pInfo))
537 +                           xf86AddEnabledDevice(pInfo);
538 +                   }
539 +               }
540          }
541          pMse->lastButtons = 0;
542          pMse->lastMappedButtons = 0;
543 @@ -562,7 +741,7 @@ usbMouseProc(DeviceIntPtr pPointer, int
544      case DEVICE_OFF:
545      case DEVICE_CLOSE:
546          if (pInfo->fd != -1) {
547 -            RemoveEnabledDevice(pInfo->fd);
548 +            xf86RemoveEnabledDevice(pInfo);
549              if (pUsbMse->packetSize > 8 && pUsbMse->buffer) {
550                  free(pUsbMse->buffer);
551              }
552 @@ -573,6 +752,7 @@ usbMouseProc(DeviceIntPtr pPointer, int
553              xf86CloseSerial(pInfo->fd);
554              pInfo->fd = -1;
555          }
556 +        pUsbMse->opened--;
557          pPointer->public.on = FALSE;
558          usleep(300000);
559          break;
560 @@ -588,45 +768,154 @@ usbReadInput(InputInfoPtr pInfo)
561  {
562      MouseDevPtr pMse;
563      UsbMsePtr pUsbMse;
564 -    int buttons = pMse->lastButtons;
565 -    int dx = 0, dy = 0, dz = 0, dw = 0;
566 -    int n, c;
567 +    int buttons, cc;
568 +    int dx, dy, dz, dw, dp, upd, v, nx, ny, np, in_range;
569 +    int n, c, rid, *sizep, nacol, nlcol;
570      unsigned char *pBuf;
571 +    struct UsbMseAcol *acol;
572 +    struct UsbMseLcol *lcol;
573  
574      pMse = pInfo->private;
575      pUsbMse = pMse->mousePriv;
576  
577      XisbBlockDuration(pMse->buffer, -1);
578 +next:
579      pBuf = pUsbMse->buffer;
580      n = 0;
581 -    while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) {
582 +    if (pUsbMse->iid) {
583 +       rid = XisbRead(pMse->buffer);
584 +       if (rid < 0)
585 +           return;
586 +       pBuf[n++] = (unsigned char)rid;
587 +    } else
588 +       rid = 0;
589 +    sizep = usbGetReportSizePtr(pUsbMse, rid);
590 +    if (sizep == NULL || *sizep == 0) {
591 +       xf86Msg(X_WARNING, "%s: unknown report ID %d\n", pInfo->name, rid);
592 +       goto next;
593 +    }
594 +    while (n < *sizep && (c = XisbRead(pMse->buffer)) >= 0) {
595          pBuf[n++] = (unsigned char)c;
596      }
597      if (n == 0)
598          return;
599 -    if (n != pUsbMse->packetSize) {
600 +//    xf86MsgVerb(X_INFO, 3, "pkt: %d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
601 +//     n, pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7], pBuf[8], pBuf[9]);
602 +    if (n != *sizep) {
603          LogMessageVerbSigSafe(X_WARNING, -1,
604                                "%s: incomplete packet, size %d\n",
605                                pInfo->name, n);
606      }
607 -    /* discard packets with an id that don't match the mouse */
608 -    /* XXX this is probably not the right thing */
609 -    if (pUsbMse->iid != 0) {
610 -        if (*pBuf++ != pUsbMse->iid)
611 -            return;
612 -    }
613 -    dx = hid_get_data(pBuf, &pUsbMse->loc_x);
614 -    dy = hid_get_data(pBuf, &pUsbMse->loc_y);
615 -    dz = hid_get_data(pBuf, &pUsbMse->loc_z);
616 -    dw = hid_get_data(pBuf, &pUsbMse->loc_w);
617 -
618 -    buttons = 0;
619 -    for (n = 0; n < pMse->buttons; n++) {
620 -        if (hid_get_data(pBuf, &pUsbMse->loc_btn[n]))
621 -            buttons |= (1 << UMS_BUT(n));
622 +    for (nacol = 0; nacol < pUsbMse->nacols; nacol++) {
623 +       acol = &pUsbMse->acols[nacol];
624 +       if (acol->pInfo == NULL)
625 +           continue;
626 +       nx = ny = np = upd = 0;
627 +       buttons = cc = 0;
628 +       dx = dy = dz = dw = dp = 0;
629 +       for (nlcol = 0; nlcol < pUsbMse->acols[nacol].nlcols; nlcol++) {
630 +           lcol = &acol->lcols[nlcol];
631 +
632 +           if (lcol->loc_valid.usage != 0 && rid == lcol->loc_valid.report_ID &&
633 +                   hid_get_data(pBuf, &lcol->loc_valid) == 0)
634 +               continue;
635 +           if (lcol->loc_in_range.usage != 0 && rid == lcol->loc_in_range.report_ID)
636 +               in_range = hid_get_data(pBuf, &lcol->loc_in_range);
637 +           else
638 +               in_range = 1;
639 +           if (in_range && lcol->loc_x.usage != 0 && rid == lcol->loc_x.report_ID && nx == 0) {
640 +               v = hid_get_data(pBuf, &lcol->loc_x);
641 +               if (acol->xmin != acol->xmax) {
642 +                   v = xf86ScaleAxis(v, acol->xmax, acol->xmin,
643 +                       lcol->loc_x.logical_maximum, lcol->loc_x.logical_minimum);
644 +                   if (acol->cxmin != acol->cxmax)
645 +                       v = xf86ScaleAxis(v, acol->xmax, acol->xmin,
646 +                           acol->cxmax, acol->cxmin);
647 +               }
648 +               dx += v;
649 +               nx++;
650 +           }
651 +           if (in_range && lcol->loc_y.usage != 0 && rid == lcol->loc_y.report_ID && ny == 0) {
652 +               v = hid_get_data(pBuf, &lcol->loc_y);
653 +               if (acol->xmin != acol->xmax) {
654 +                   v = xf86ScaleAxis(v, acol->ymax, acol->ymin,
655 +                       lcol->loc_y.logical_maximum, lcol->loc_y.logical_minimum);
656 +                   if (acol->cymin != acol->cymax)
657 +                       v = xf86ScaleAxis(v, acol->ymax, acol->ymin,
658 +                           acol->cymax, acol->cymin);
659 +               }
660 +               dy += v;
661 +               ny++;
662 +           }
663 +           if (lcol->loc_z.usage != 0 && rid == lcol->loc_z.report_ID) {
664 +               dz -= hid_get_data(pBuf, &lcol->loc_z);
665 +               upd = 1;
666 +           }
667 +           if (lcol->loc_w.usage != 0 && rid == lcol->loc_w.report_ID) {
668 +               dw += hid_get_data(pBuf, &lcol->loc_w);
669 +               upd = 1;
670 +           }
671 +           if (lcol->loc_p.usage != 0 && rid == lcol->loc_p.report_ID && np == 0) {
672 +               v = hid_get_data(pBuf, &lcol->loc_p);
673 +                   v = xf86ScaleAxis(v, acol->pmax, acol->pmin,
674 +                       lcol->loc_p.logical_maximum, lcol->loc_p.logical_minimum);
675 +                   if (acol->cpmin != acol->cpmax)
676 +                       v = xf86ScaleAxis(v, acol->pmax, acol->pmin,
677 +                           acol->cpmax, acol->cpmin);
678 +               dp += v;
679 +               np++;
680 +           }
681 +
682 +           for (n = 0; n < acol->nbuttons; n++) {
683 +               if (lcol->loc_btn[n].usage != 0 && rid == lcol->loc_btn[n].report_ID) {
684 +                   if (hid_get_data(pBuf, &lcol->loc_btn[n]))
685 +                       buttons |= (1 << UMS_BUT(n));
686 +                   upd = 1;
687 +               }
688 +           }
689 +       }
690 +       if (acol->loc_cc.usage != 0 && rid == acol->loc_cc.report_ID)
691 +           cc = hid_get_data(pBuf, &acol->loc_cc);
692 +       else
693 +           cc = (nx || ny) ? 1 : 0;
694 +       if (cc > 1)
695 +           buttons = (1 << UMS_BUT(1));
696 +       if (nx != 0 && acol->xmin != acol->xmax)
697 +           dx /= nx;
698 +       if (ny != 0 && acol->ymin != acol->ymax)
699 +           dy /= ny;
700 +       if (np != 0 && acol->pmin != acol->pmax)
701 +           dp /= np;
702 +//     if (upd || nx || ny || np)
703 +//         xf86MsgVerb(X_INFO, 3, "%d cc %d dx %d dy %d dz %d dw %d press %d buttons %02x\n",
704 +//             nacol, cc, dx, dy, dz, dw, dp, buttons);
705 +       if (nx != 0 || ny != 0) {
706 +           if (acol->pmin != acol->pmax) {
707 +               xf86PostMotionEvent(acol->pInfo->dev,
708 +                           /* is_absolute: */    TRUE,
709 +                           /* first_valuator: */ 0,
710 +                           /* num_valuators: */  3,
711 +                           dx, dy, dp);
712 +           } else if (acol->xmin != acol->xmax || acol->ymin != acol->ymax) {
713 +               xf86PostMotionEvent(acol->pInfo->dev,
714 +                           /* is_absolute: */    TRUE,
715 +                           /* first_valuator: */ 0,
716 +                           /* num_valuators: */  2,
717 +                           dx, dy);
718 +           }
719 +       }
720 +       if (upd || (nx != 0) || (ny != 0)) {
721 +           ((MouseDevPtr)acol->pInfo->private)->PostEvent(acol->pInfo, buttons,
722 +               ((acol->xmin != acol->xmax) ? dx - acol->px : dx),
723 +               ((acol->ymin != acol->ymax) ? dy - acol->py : dy),
724 +               dz, dw);
725 +       }
726 +       if (nx > 0)
727 +           acol->px = dx;
728 +       if (ny > 0)
729 +           acol->py = dy;
730      }
731 -    pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
732 -    return;
733 +    goto next;
734  }
735  
736  static void
737 @@ -635,14 +924,17 @@ usbSigioReadInput (int fd, void *closure
738      usbReadInput ((InputInfoPtr) closure);
739  }
740  
741 -/* This function is called when the protocol is "usb". */
742  static Bool
743 -usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
744 +usbInitFirst(InputInfoPtr pInfo)
745  {
746      MouseDevPtr pMse = pInfo->private;
747      UsbMsePtr pUsbMse;
748      report_desc_t reportDesc;
749 -    int i;
750 +    hid_data_t d;
751 +    hid_item_t h;
752 +    struct UsbMseAcol *acol;
753 +    struct UsbMseLcol *lcol;
754 +    int mdepth, rsize, *rsizep, acolused, lcolused, used;
755  
756      pUsbMse = malloc(sizeof(UsbMseRec));
757      if (pUsbMse == NULL) {
758 @@ -651,12 +943,7 @@ usbPreInit(InputInfoPtr pInfo, const cha
759          return FALSE;
760      }
761  
762 -    pMse->protocol = protocol;
763 -    xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
764 -
765 -    /* Collect the options, and process the common options. */
766 -    COLLECT_INPUT_OPTIONS(pInfo, NULL);
767 -    xf86ProcessCommonOptions(pInfo, pInfo->options);
768 +    bzero(pUsbMse, sizeof(UsbMseRec));
769  
770      /* Check if the device can be opened. */
771      pInfo->fd = xf86OpenSerial(pInfo->options);
772 @@ -672,19 +959,134 @@ usbPreInit(InputInfoPtr pInfo, const cha
773      }
774      /* Get USB informations */
775      reportDesc = hid_get_report_desc(pInfo->fd);
776 -    /* Get packet size & iid */
777 -#ifdef USB_NEW_HID
778 -    if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) {
779 -            xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n",
780 -                    pInfo->name, strerror(errno));
781 -            return FALSE;
782 -    }
783 -    pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
784 -                                              pUsbMse->iid);
785 -#else
786 -    pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
787 -                                              &pUsbMse->iid);
788 -#endif
789 +    mdepth = 0;
790 +    pUsbMse->nacols = 0;
791 +    acol = &pUsbMse->acols[pUsbMse->nacols];
792 +    lcol = &acol->lcols[acol->nlcols];
793 +    acolused = 0;
794 +    lcolused = 0;
795 +    d = hid_start_parse(reportDesc, (1 << hid_input) |
796 +       (1 << hid_collection) | (1 << hid_endcollection), -1);
797 +    while (hid_get_item(d, &h)) {
798 +       switch (h.kind) {
799 +       case hid_collection:
800 +           if (mdepth != 0)
801 +               mdepth++;
802 +           else if (h.collection == 1 &&
803 +                   (h.usage == 0x00010001 || h.usage == 0x00010002 ||
804 +                    (h.usage >= 0x000d0001 && h.usage <= 0x000d000d))) {
805 +               mdepth++;
806 +               if (acolused) {
807 +                   if (lcolused) {
808 +                       acol->nlcols++;
809 +                       lcolused = 0;
810 +                   }
811 +                   pUsbMse->nacols++;
812 +                   acolused = 0;
813 +                   acol = &pUsbMse->acols[pUsbMse->nacols];
814 +                   lcol = &acol->lcols[acol->nlcols];
815 +               }
816 +           }
817 +           if (lcolused && (h.collection == 0 ||
818 +                   h.collection == 2 || h.collection == 3)) {
819 +               acol->nlcols++;
820 +               lcolused = 0;
821 +               lcol = &acol->lcols[acol->nlcols];
822 +           }
823 +           break;
824 +       case hid_endcollection:
825 +           if (mdepth != 0)
826 +               mdepth--;
827 +           break;
828 +       case hid_input:
829 +           if (h.report_ID != 0)
830 +               pUsbMse->iid = 1;
831 +           rsize = pUsbMse->iid +
832 +               (h.pos + (h.report_size * h.report_count) + 7) / 8;
833 +           if ((rsizep = usbGetReportSizePtr(pUsbMse, h.report_ID)) != NULL)
834 +               *rsizep = max(*rsizep, rsize);
835 +           pUsbMse->packetSize = max(pUsbMse->packetSize, rsize);
836 +           if (mdepth == 0)
837 +               break;
838 +           used = 1;
839 +           if (h.usage == 0x00010030) { /* X */
840 +               lcol->loc_x = h;
841 +               if ((h.flags & 0x04) == 0) {
842 +                   if (acol->xmin == acol->xmax) {
843 +                       acol->xmin = h.logical_minimum;
844 +                       acol->xmax = h.logical_maximum;
845 +                   } else {
846 +                       acol->xmin = min(acol->xmin, h.logical_minimum);
847 +                       acol->xmax = max(acol->xmax, h.logical_maximum);
848 +                   }
849 +               }
850 +           } else if (h.usage == 0x00010031) { /* Y */
851 +               lcol->loc_y = h;
852 +               if ((h.flags & 0x04) == 0) {
853 +                   if (acol->ymin == acol->ymax) {
854 +                       acol->ymin = h.logical_minimum;
855 +                       acol->ymax = h.logical_maximum;
856 +                   } else {
857 +                       acol->ymin = min(acol->ymin, h.logical_minimum);
858 +                       acol->ymax = max(acol->ymax, h.logical_maximum);
859 +                   }
860 +               }
861 +           } else if (h.usage == 0x00010038) { /* Z */
862 +               lcol->loc_z = h;
863 +               acol->hasZ = 1;
864 +           } else if (h.usage == 0x000c0238) { /* W */
865 +               lcol->loc_w = h;
866 +               acol->hasW = 1;
867 +           } else if (h.usage == 0x000d0030) { /* Press */
868 +               lcol->loc_p = h;
869 +               if ((h.flags & 0x04) == 0) {
870 +                   if (acol->pmin == acol->pmax) {
871 +                       acol->pmin = h.logical_minimum;
872 +                       acol->pmax = h.logical_maximum;
873 +                   } else {
874 +                       acol->pmin = min(acol->pmin, h.logical_minimum);
875 +                       acol->pmax = max(acol->pmax, h.logical_maximum);
876 +                   }
877 +               }
878 +           } else if (h.usage == 0x000d0032) /* In Range */
879 +               lcol->loc_in_range = h;
880 +           else if (h.usage == 0x000d0047) /* Valid */
881 +               lcol->loc_valid = h;
882 +           else if (h.usage > 0x00090000 &&
883 +               h.usage <= 0x00090000 + MSE_MAXBUTTONS) { /* Buttons */
884 +                   lcol->loc_btn[(h.usage & 0xffff) - 1] = h;
885 +                   acol->nbuttons = max(acol->nbuttons, h.usage & 0xffff);
886 +           } else if (h.usage == 0x000d0042) { /* Tip Switch */
887 +               lcol->loc_btn[0] = h;
888 +               acol->nbuttons = max(acol->nbuttons, 1);
889 +           } else if (h.usage == 0x000d0044) { /* Barrel Switch */
890 +               lcol->loc_btn[1] = h;
891 +               acol->nbuttons = max(acol->nbuttons, 2);
892 +           } else if (h.usage == 0x000d0045) { /* Eraser */
893 +               lcol->loc_btn[3] = h;
894 +               acol->nbuttons = max(acol->nbuttons, 4);
895 +           } else if (h.usage == 0x000d0046) { /* Tablet Pick */
896 +               lcol->loc_btn[2] = h;
897 +               acol->nbuttons = max(acol->nbuttons, 3);
898 +           } else if (h.usage == 0x000d0054) /* Contact Count */
899 +               acol->loc_cc = h;
900 +           else
901 +               used = 0;
902 +           lcolused += used;
903 +           acolused += used;
904 +           break;
905 +       default:
906 +           break;
907 +       }
908 +    }
909 +    if (lcolused)
910 +       acol->nlcols++;
911 +    if (acolused)
912 +       pUsbMse->nacols++;
913 +    hid_end_parse(d);
914 +    xf86Msg(X_DEFAULT, "%s: Found %d usable logical collections\n",
915 +       pInfo->name, pUsbMse->nacols);
916 +
917      /* Allocate buffer */
918      if (pUsbMse->packetSize <= 8) {
919          pUsbMse->buffer = pMse->protoBuf;
920 @@ -694,56 +1096,129 @@ usbPreInit(InputInfoPtr pInfo, const cha
921      if (pUsbMse->buffer == NULL) {
922          xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
923          free(pUsbMse);
924 -        free(pMse);
925          xf86CloseSerial(pInfo->fd);
926          return FALSE;
927      }
928 -#ifdef USB_NEW_HID
929 -    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
930 -                   hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) {
931 -        xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
932 -    }
933 -    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
934 -                   hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) {
935 -        xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
936 -    }
937 -    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
938 -                   hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) {
939 -    }
940 -#else
941 -    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
942 -                   hid_input, &pUsbMse->loc_x) < 0) {
943 -        xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
944 -    }
945 -    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
946 -                   hid_input, &pUsbMse->loc_y) < 0) {
947 -        xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
948 -    }
949 -    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
950 -                   hid_input, &pUsbMse->loc_z) < 0) {
951 -    }
952 -#endif
953 -    /* Probe for number of buttons */
954 -    for (i = 1; i <= MSE_MAXBUTTONS; i++) {
955 -        if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i),
956 -                        hid_input, &pUsbMse->loc_btn[i-1]
957 -#ifdef USB_NEW_HID
958 -                        , pUsbMse->iid
959 -#endif
960 -                        ))
961 -            break;
962 -    }
963 -    pMse->buttons = i-1;
964  
965      xf86CloseSerial(pInfo->fd);
966      pInfo->fd = -1;
967  
968      /* Private structure */
969      pMse->mousePriv = pUsbMse;
970 +    return TRUE;
971 +}
972 +
973 +/* This function is called when the protocol is "usb". */
974 +static Bool
975 +usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
976 +{
977 +    InputInfoPtr pMatch;
978 +    MouseDevPtr pMse = pInfo->private;
979 +    UsbMsePtr pUsbMse;
980 +    struct UsbMseAcol *acol;
981 +    char *str;
982 +    int i, colopt;
983 +
984 +    pMse->protocol = protocol;
985 +    xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
986 +
987 +    /* Collect the options, and process the common options. */
988 +    COLLECT_INPUT_OPTIONS(pInfo, NULL);
989 +    xf86ProcessCommonOptions(pInfo, pInfo->options);
990 +
991 +    /* Check if this HID device is already opened. */
992 +    for (pMatch = xf86FirstLocalDevice(); pMatch != NULL; pMatch = pMatch->next) {
993 +       if ((pInfo != pMatch) && strstr(pMatch->drv->driverName, "mouse")) {
994 +           char *dev1, *dev2;
995 +
996 +           dev1 = xf86SetStrOption(pInfo->options, "Device", NULL);
997 +           dev2 = xf86SetStrOption(pMatch->options, "Device", NULL);
998 +           if (strcmp(dev1, dev2) == 0) {
999 +               free(dev1);
1000 +               free(dev2);
1001 +               break;
1002 +           }
1003 +           free(dev1);
1004 +           free(dev2);
1005 +       }
1006 +    }
1007 +    if (pMatch == NULL) {
1008 +       xf86Msg(X_DEFAULT, "%s: Opening new HID device\n", pInfo->name);
1009 +       if (!usbInitFirst(pInfo)) {
1010 +           free(pMse);
1011 +           return FALSE;
1012 +       }
1013 +    } else {
1014 +       pMse->mousePriv = ((MouseDevPtr)pMatch->private)->mousePriv;
1015 +       xf86Msg(X_DEFAULT, "%s: Attaching to already opened HID device\n",
1016 +           pInfo->name);
1017 +    }
1018 +    pUsbMse = pMse->mousePriv;
1019 +
1020 +    /* Attach to collection, respecting "Collection" option. */
1021 +    colopt = xf86SetIntOption(pInfo->options, "Collection", 0);
1022 +    for (i = 0; i < pUsbMse->nacols; i++) {
1023 +       if (pUsbMse->acols[i].pInfo == NULL &&
1024 +               (colopt == 0 || i == colopt - 1)) {
1025 +           pUsbMse->acols[i].pInfo = pInfo;
1026 +           break;
1027 +       }
1028 +    }
1029 +    xf86Msg(colopt == 0 ? X_DEFAULT : X_CONFIG,
1030 +       "%s: Collection: %d\n", pInfo->name,
1031 +       i == pUsbMse->nacols ? colopt : i + 1);
1032 +    if (i == pUsbMse->nacols) {
1033 +       xf86Msg(X_ERROR,
1034 +           "%s: Application collection not found or already handled\n",
1035 +           pInfo->name);
1036 +       free(pMse);
1037 +       return FALSE;
1038 +    }
1039 +
1040 +    acol = &pUsbMse->acols[i];
1041 +    pMse->buttons = acol->nbuttons;
1042 +    if (pMse->buttons == 2)
1043 +       pMse->buttons = 3;
1044 +    if (acol->xmin != acol->xmax || acol->ymin != acol->ymax)
1045 +       pMse->disableXY = TRUE;
1046 +    pMse->hasZ = acol->hasZ;
1047 +    pMse->hasW = acol->hasW;
1048  
1049      /* Process common mouse options (like Emulate3Buttons, etc). */
1050      pMse->CommonOptions(pInfo);
1051  
1052 +    /* Process "Calibration" option. */
1053 +    str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
1054 +    if (str != NULL && (acol->xmin != acol->xmax || acol->ymin != acol->ymax)) {
1055 +       int j, xmin, xmax, ymin, ymax, pmin, pmax;
1056 +
1057 +       j = sscanf(str, "%d %d %d %d %d %d", &xmin, &xmax, &ymin, &ymax, &pmin, &pmax);
1058 +       if (j == 4) {
1059 +           xf86Msg(X_CONFIG, "%s: Calibration: %d %d %d %d\n",
1060 +               pInfo->name, xmin, xmax, ymin, ymax);
1061 +           acol->cxmin = xmin;
1062 +           acol->cxmax = xmax;
1063 +           acol->cymin = ymin;
1064 +           acol->cymax = ymax;
1065 +       } else if (j == 6) {
1066 +           xf86Msg(X_CONFIG, "%s: Calibration: %d %d %d %d %d %d\n",
1067 +               pInfo->name, xmin, xmax, ymin, ymax, pmin, pmax);
1068 +           acol->cxmin = xmin;
1069 +           acol->cxmax = xmax;
1070 +           acol->cymin = ymin;
1071 +           acol->cymax = ymax;
1072 +           acol->cpmin = pmin;
1073 +           acol->cpmax = pmax;
1074 +       } else
1075 +           xf86Msg(X_WARNING, "%s: Calibration: Invalid arguments\n",
1076 +               pInfo->name);
1077 +       free(str);
1078 +    } else if (acol->xmin != acol->xmax || acol->ymin != acol->ymax) {
1079 +       xf86Msg(X_DEFAULT, "%s: Calibration: %d %d %d %d %d %d\n",
1080 +           pInfo->name, acol->xmin, acol->xmax, acol->ymin, acol->ymax,
1081 +           acol->pmin, acol->pmax);
1082 +    }
1083 +
1084      /* Setup the local procs. */
1085      pInfo->device_control = usbMouseProc;
1086      pInfo->read_input = usbReadInput;
1087 @@ -786,7 +1261,9 @@ OSMouseInit(int flags)
1088      p->CheckProtocol = CheckProtocol;
1089  #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
1090      p->SetupAuto = SetupAuto;
1091 +#ifndef XPS2_SUPPORT
1092      p->SetPS2Res = SetSysMouseRes;
1093 +#endif
1094      p->SetBMRes = SetSysMouseRes;
1095      p->SetMiscRes = SetSysMouseRes;
1096  #endif
1097
1098
1099 [FILE:7409:patches/patch-src_mouse.c]
1100 --- src/mouse.c.orig    2018-06-19 04:36:21 UTC
1101 +++ src/mouse.c
1102 @@ -304,13 +304,39 @@ MouseCommonOptions(InputInfoPtr pInfo)
1103  
1104      pMse = pInfo->private;
1105  
1106 -    pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
1107 +    i = xf86SetIntOption(pInfo->options, "Buttons", 0);
1108 +    if (i != 0)
1109 +        pMse->buttons = i;
1110      if (!pMse->buttons) {
1111          pMse->buttons = MSE_DFLTBUTTONS;
1112          buttons_from = X_DEFAULT;
1113      }
1114      origButtons = pMse->buttons;
1115  
1116 +    s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL);
1117 +    if (s) {
1118 +        int b, n = 0;
1119 +        char *s1 = s;
1120 +        /* keep getting numbers which are buttons */
1121 +        while (s1 && n < MSE_MAXBUTTONS && (b = strtol(s1, &s1, 10)) != 0) {
1122 +            /* check sanity for a button */
1123 +            if (b < 0 || b > MSE_MAXBUTTONS) {
1124 +                xf86Msg(X_WARNING,
1125 +                        "ButtonMapping: Invalid button number = %d\n", b);
1126 +                break;
1127 +           };
1128 +           pMse->buttonMap[n++] = 1 << (b-1);
1129 +           if (b > pMse->buttons) pMse->buttons = b;
1130 +        }
1131 +        free(s);
1132 +    }
1133 +    /* get maximum of mapped buttons */
1134 +    for (i = pMse->buttons-1; i >= 0; i--) {
1135 +        int f = ffs (pMse->buttonMap[i]);
1136 +        if (f > pMse->buttons)
1137 +            pMse->buttons = f;
1138 +    }
1139 +
1140      pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options,
1141                                                "Emulate3Buttons", FALSE);
1142      if (!xf86FindOptionValue(pInfo->options,"Emulate3Buttons")) {
1143 @@ -322,6 +348,8 @@ MouseCommonOptions(InputInfoPtr pInfo)
1144                                               "Emulate3Timeout", 50);
1145      if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) {
1146          MessageType from = X_CONFIG;
1147 +       if (pMse->buttons < 3)
1148 +            pMse->buttons = 3;
1149          if (pMse->emulate3ButtonsSoft)
1150              from = X_DEFAULT;
1151          xf86Msg(from, "%s: Emulate3Buttons, Emulate3Timeout: %d\n",
1152 @@ -329,6 +357,8 @@ MouseCommonOptions(InputInfoPtr pInfo)
1153      }
1154  
1155      pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE);
1156 +    if (pMse->chordMiddle && pMse->buttons < 3)
1157 +           pMse->buttons = 3;
1158      pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE);
1159      if (xf86SetBoolOption(pInfo->options, "InvX", FALSE)) {
1160          pMse->invX = -1;
1161 @@ -339,7 +369,7 @@ MouseCommonOptions(InputInfoPtr pInfo)
1162      } else
1163          pMse->invY = 1;
1164      pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0);
1165 -
1166 +    pMse->sensitivity = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
1167  
1168      if (pMse->pDragLock)
1169          free(pMse->pDragLock);
1170 @@ -449,14 +479,17 @@ MouseCommonOptions(InputInfoPtr pInfo)
1171          free(s);
1172      }
1173  
1174 -    s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5");
1175 +    s = xf86SetStrOption(pInfo->options, "ZAxisMapping",
1176 +        pMse->hasZ ? ( pMse->hasW ? "4 5 6 7" : "4 5" ) : "off");
1177      if (s) {
1178          int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
1179          char *msg = NULL;
1180  
1181          pMse->negativeZ = pMse->positiveZ = MSE_NOAXISMAP;
1182          pMse->negativeW = pMse->positiveW = MSE_NOAXISMAP;
1183 -        if (!xf86NameCmp(s, "x")) {
1184 +        if (!xf86NameCmp(s, "off")) {
1185 +            msg = xstrdup("off");
1186 +       } else if (!xf86NameCmp(s, "x")) {
1187              pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
1188              msg = xstrdup("X axis");
1189          } else if (!xf86NameCmp(s, "y")) {
1190 @@ -605,29 +638,6 @@ MouseCommonOptions(InputInfoPtr pInfo)
1191                  pInfo->name, wheelButton, pMse->wheelInertia,
1192                  pMse->wheelButtonTimeout);
1193      }
1194 -    s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL);
1195 -    if (s) {
1196 -       int b, n = 0;
1197 -       char *s1 = s;
1198 -       /* keep getting numbers which are buttons */
1199 -       while (s1 && n < MSE_MAXBUTTONS && (b = strtol(s1, &s1, 10)) != 0) {
1200 -           /* check sanity for a button */
1201 -           if (b < 0 || b > MSE_MAXBUTTONS) {
1202 -               xf86Msg(X_WARNING,
1203 -                       "ButtonMapping: Invalid button number = %d\n", b);
1204 -               break;
1205 -           };
1206 -           pMse->buttonMap[n++] = 1 << (b-1);
1207 -           if (b > pMse->buttons) pMse->buttons = b;
1208 -       }
1209 -       free(s);
1210 -    }
1211 -    /* get maximum of mapped buttons */
1212 -    for (i = pMse->buttons-1; i >= 0; i--) {
1213 -        int f = ffs (pMse->buttonMap[i]);
1214 -        if (f > pMse->buttons)
1215 -            pMse->buttons = f;
1216 -    }
1217      if (origButtons != pMse->buttons)
1218          buttons_from = X_CONFIG;
1219      xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons);
1220 @@ -709,7 +719,6 @@ MouseHWOptions(InputInfoPtr pInfo)
1221      }
1222      pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0);
1223      pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0);
1224 -    mPriv->sensitivity = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
1225  }
1226  
1227  static void
1228 @@ -996,6 +1005,8 @@ MousePreInit(InputDriverPtr drv, InputIn
1229      /* Default Mapping: 1 2 3 8 9 10 11 ... */
1230      for (i = 0; i < MSE_MAXBUTTONS; i++)
1231          pMse->buttonMap[i] = 1 << (i > 2 && i < MSE_MAXBUTTONS-4 ? i+4 : i);
1232 +    pMse->hasZ = 1;
1233 +    pMse->hasW = 0;
1234  
1235      protocol = MousePickProtocol(pInfo, device, protocol, &protocolID);
1236  
1237 @@ -2197,7 +2208,7 @@ MouseDoPostEvent(InputInfoPtr pInfo, int
1238  
1239      if (pMse->emulateWheel) {
1240          /* Emulate wheel button handling */
1241 -        if(pMse->wheelButton == 0)
1242 +        if (pMse->wheelButton == 0)
1243              wheelButtonMask = 0;
1244          else
1245              wheelButtonMask = 1 << (pMse->wheelButton - 1);
1246 @@ -2287,6 +2298,9 @@ MouseDoPostEvent(InputInfoPtr pInfo, int
1247                          }
1248                      }
1249                  }
1250 +            } else {
1251 +                pMse->wheelXDistance = 0;
1252 +                pMse->wheelYDistance = 0;
1253              }
1254  
1255              /* Absorb the mouse movement while the wheel button is pressed. */
1256 @@ -2304,7 +2318,7 @@ MouseDoPostEvent(InputInfoPtr pInfo, int
1257      if (pMse->emulate3ButtonsSoft && pMse->emulate3Pending && (dx || dy))
1258          buttonTimer(pInfo);
1259  
1260 -    if (dx || dy)
1261 +    if ((dx || dy) && !pMse->disableXY)
1262          xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
1263  
1264      if (change) {
1265 @@ -2417,12 +2431,10 @@ MousePostEvent(InputInfoPtr pInfo, int t
1266                 int dx, int dy, int dz, int dw)
1267  {
1268      MouseDevPtr pMse;
1269 -    mousePrivPtr mousepriv;
1270      int zbutton = 0, wbutton = 0, zbuttoncount = 0, wbuttoncount = 0;
1271      int i, b, buttons = 0;
1272  
1273      pMse = pInfo->private;
1274 -    mousepriv = (mousePrivPtr)pMse->mousePriv;
1275  
1276      if (pMse->protocolID == PROT_MMHIT)
1277          b = reverseBits(hitachMap, truebuttons);
1278 @@ -2515,11 +2527,11 @@ MousePostEvent(InputInfoPtr pInfo, int t
1279  
1280      /* Accumulate the scaled dx, dy in the private variables
1281         fracdx,fracdy and return the integer number part */
1282 -    if (mousepriv) {
1283 -        mousepriv->fracdx += mousepriv->sensitivity*dx;
1284 -        mousepriv->fracdy += mousepriv->sensitivity*dy;
1285 -        mousepriv->fracdx -= ( dx=(int)(mousepriv->fracdx) );
1286 -        mousepriv->fracdy -= ( dy=(int)(mousepriv->fracdy) );
1287 +    if (pMse->sensitivity != 0) {
1288 +        pMse->fracdx += pMse->sensitivity*dx;
1289 +        pMse->fracdy += pMse->sensitivity*dy;
1290 +        pMse->fracdx -= ( dx=(int)(pMse->fracdx) );
1291 +        pMse->fracdy -= ( dy=(int)(pMse->fracdy) );
1292      }
1293  
1294      /* If mouse wheel movement has to be mapped on a button, we need to
1295
1296
1297 [FILE:1020:patches/patch-src_mouse.h]
1298 --- src/mouse.h.orig    2018-06-19 04:36:21 UTC
1299 +++ src/mouse.h
1300 @@ -220,10 +220,13 @@ typedef struct _MouseDevRec {
1301      Bool                emulate3ButtonsSoft;
1302      int                 emulate3Timeout;/* Timeout for 3 button emulation */
1303      Bool                chordMiddle;
1304 +    Bool                disableXY;
1305      Bool                flipXY;
1306      int                 invX;
1307      int                 invY;
1308      int                 resolution;
1309 +    Bool                hasW;
1310 +    Bool                hasZ;
1311      int                 negativeZ;      /* button mask */
1312      int                 positiveZ;      /* button mask */
1313      int                 negativeW;      /* button mask */
1314 @@ -262,6 +265,8 @@ typedef struct _MouseDevRec {
1315      int                 doubleClickOldSourceState;
1316      int                 lastMappedButtons;
1317      int                 buttonMap[MSE_MAXBUTTONS];
1318 +    float               fracdx,fracdy;
1319 +    float               sensitivity;
1320  } MouseDevRec, *MouseDevPtr;
1321  
1322  #endif /* _XF86OSMOUSE_H_ */
1323
1324
1325 [FILE:306:patches/patch-src_mousePriv.h]
1326 --- src/mousePriv.h.orig        2018-06-19 04:36:21 UTC
1327 +++ src/mousePriv.h
1328 @@ -63,8 +63,6 @@ typedef struct {
1329      int         acc;
1330      CARD32      pnpLast;
1331      Bool        disablePnPauto;
1332 -    float       fracdx,fracdy;
1333 -    float       sensitivity;
1334  } mousePrivRec, *mousePrivPtr;
1335  
1336  /* mouse proto flags */
1337
1338
1339 [FILE:777:patches/patch-src_sun__mouse.c]
1340 $NetBSD: patch-src_sun__mouse.c,v 1.2 2016/11/17 08:06:52 wiz Exp $
1341
1342 rearrange includes to fix build on OmniOS. Include unistd.h for ioctl(2).
1343
1344 --- src/sun_mouse.c.orig        2018-06-19 04:36:21 UTC
1345 +++ src/sun_mouse.c
1346 @@ -51,6 +51,10 @@
1347  #include <xorg-config.h>
1348  #endif
1349  
1350 +#include <unistd.h> /* for ioctl(2) */
1351 +#include <sys/stropts.h>
1352 +#include <sys/vuid_event.h>
1353 +#include <sys/msio.h>
1354  #include "xorg-server.h"
1355  #include "xf86.h"
1356  #include "xf86_OSlib.h"
1357 @@ -58,9 +62,6 @@
1358  #include "xisb.h"
1359  #include "mipointer.h"
1360  #include "xf86Crtc.h"
1361 -#include <sys/stropts.h>
1362 -#include <sys/vuid_event.h>
1363 -#include <sys/msio.h>
1364  
1365  /* Wheel mouse support in VUID drivers in Solaris 9 updates & Solaris 10 */
1366  #ifdef WHEEL_DEVID /* Defined in vuid_event.h if VUID wheel support present */
1367
1368
1369 [FILE:577:dragonfly/patch-src_Makefile.in]
1370 --- src/Makefile.in.orig        2016-11-22 04:55:36 UTC
1371 +++ src/Makefile.in
1372 @@ -357,7 +357,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include $(
1373  # _ladir passes a dummy rpath to libtool so the thing will actually link
1374  # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
1375  @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
1376 -@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
1377 +@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version -lusbhid
1378  @DRIVER_NAME@_drv_ladir = @inputdir@
1379  
1380  # We have to list all the mouse drivers here, even if we don't build them, so
1381
1382
1383 [FILE:577:freebsd/patch-src_Makefile.in]
1384 --- src/Makefile.in.orig        2016-11-22 04:55:36 UTC
1385 +++ src/Makefile.in
1386 @@ -357,7 +357,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include $(
1387  # _ladir passes a dummy rpath to libtool so the thing will actually link
1388  # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
1389  @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
1390 -@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
1391 +@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version -lusbhid
1392  @DRIVER_NAME@_drv_ladir = @inputdir@
1393  
1394  # We have to list all the mouse drivers here, even if we don't build them, so
1395