FreeBSD/DragonFly patches for xf86-video-ati, xf86-input-mouse, and xf86-video-intel

Thomas Klausner wiz at NetBSD.org
Sun Jul 26 16:20:29 PDT 2015


Hi!

David Shao reported some issues against pkgsrc, providing build/run
fixes for xorg software on DragonFly BSD and FreeBSD.

However, I'd like to avoid having pkgsrc-only patches. So I'm
wondering what your opinions are on getting (versions of) these
patches included.

He says that the patches are basically from FreeBSD ports.
Do we have a FreeBSD committer on this mailing list?

The patches are for xf86-video-ati (first one), xf86-input-mouse
(second), and xf86-video-intel (last).

Cheers,
 Thomas

(two FreeBSD X.org team members from https://wiki.freebsd.org/Graphics added to cc)

----- Forwarded message from davshao at gmail.com -----

Date: Mon, 20 Jul 2015 04:05:00 +0000 (UTC)
From: davshao at gmail.com
To: pkg-manager at netbsd.org, gnats-admin at netbsd.org, pkgsrc-bugs at netbsd.org
Cc: 
Subject: pkg/50067: x11/xf86-video-ati dports patch-src_radeon__kms.c for newer DragonFly and FreeBSD
Mail-Reply-To: davshao at gmail.com

>Number:         50067
>Category:       pkg
>Synopsis:       x11/xf86-video-ati dports patch-src_radeon__kms.c for newer DragonFly and FreeBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jul 20 04:05:00 +0000 2015
>Originator:     David Shao
>Release:        pkgsrc current cvs
>Organization:
>Environment:
DragonFly  4.3-DEVELOPMENT DragonFly v4.2.2.63.ga2b9b7-DEVELOPMENT #1: Sun Jul 19 19:22:57 PDT 2015     xxxxx@:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64
>Description:
x11/xf86-video-ati can be patched using a patch from DragonFly dports so that KMS and other capabilities from newer DragonFly and FreeBSD Oses can be activated.  Unlike say NetBSD or OpenBSD, for DragonFly and FreeBSD the Radeon drm kernel modules are not necessarily loaded before Xorg is started using say startx.  

The following patch is from DragonFly dports master as of commit 4f04bfe0ea83ce09 ..., 
file x11-drivers/xf86-video-ati/files/patch-src__radeon_kms.c:

It has been tested on DragonFly 4.3-DEVELOPMENT x86_64 and FreeBSD 10.1 release amd64, using openbox and a patched xf86-input-mouse.  It also at least compiled and built successfully on NetBSD 6.99.20 amd64 X11_type=modular, and should have no affect on it.  The result for DragonFly and FreeBSD is the desired activation, as can be seen from Xorg.0.log:

[    61.049] (II) [KMS] Kernel modesetting enabled.
...
[    63.244] (II) RADEON(0): KMS Color Tiling: enabled
[    63.244] (II) RADEON(0): KMS Color Tiling 2D: enabled
[    63.244] (II) RADEON(0): KMS Pageflipping: enabled
[    63.244] (II) RADEON(0): SwapBuffers wait for vsync: enabled
[    63.319] (II) RADEON(0): Output VGA-0 has no monitor section
[    63.319] (II) RADEON(0): Output HDMI-0 has no monitor section
[    63.326] (II) RADEON(0): Output DVI-0 has no monitor section
[    63.400] (II) RADEON(0): EDID for output VGA-0
[    63.400] (II) RADEON(0): Manufacturer: VSC  Model: d427  Serial#: 16843009
[    63.400] (II) RADEON(0): Year: 2010  Week: 44
...
[    63.425] (II) RADEON(0): [DRI2] Setup complete
[    63.425] (II) RADEON(0): [DRI2]   DRI driver: r600
[    63.425] (II) RADEON(0): [DRI2]   VDPAU driver: r600
[    63.425] (II) RADEON(0): Front buffer size: 5120K
[    63.425] (II) RADEON(0): VRAM usage limit set to 462384K
[    63.440] (==) RADEON(0): Backing store enabled
[    63.440] (II) RADEON(0): Direct rendering enabled
[    63.440] (II) EXA(0): Driver allocated offscreen pixmaps
[    63.440] (II) EXA(0): Driver registered support for the following operations:
[    63.440] (II)         Solid
[    63.440] (II)         Copy
[    63.440] (II)         Composite (RENDER acceleration)
[    63.440] (II)         UploadToScreen
[    63.440] (II)         DownloadFromScreen
[    63.440] (II) RADEON(0): Acceleration enabled
[    63.441] (==) RADEON(0): DPMS enabled
...
[    63.444] (--) RandR disabled
[    63.833] (II) AIGLX: enabled GLX_MESA_copy_sub_buffer
[    63.833] (II) AIGLX: enabled GLX_ARB_create_context
[    63.833] (II) AIGLX: enabled GLX_ARB_create_context_profile
[    63.833] (II) AIGLX: enabled GLX_EXT_create_context_es2_profile
[    63.833] (II) AIGLX: enabled GLX_INTEL_swap_event
[    63.833] (II) AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control
[    63.833] (II) AIGLX: enabled GLX_EXT_framebuffer_sRGB
[    63.833] (II) AIGLX: enabled GLX_ARB_fbconfig_float
[    63.833] (II) AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects
[    63.834] (II) AIGLX: Loaded and initialized r600






>How-To-Repeat:

>Fix:
The following is the patch:

$NetBSD$

--- src/radeon_kms.c.orig	2014-10-02 03:31:27.000000000 +0000
+++ src/radeon_kms.c
@@ -30,6 +30,12 @@
 
 #include <errno.h>
 #include <sys/ioctl.h>
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+#include <sys/param.h>
+#include <sys/linker.h>
+#endif
+
 /* Driver data structures */
 #include "radeon.h"
 #include "radeon_reg.h"
@@ -280,7 +286,7 @@ static void
 radeon_dirty_update(ScreenPtr screen)
 {
 	RegionPtr region;
-	PixmapDirtyUpdatePtr ent;
+	PixmapDirtyUpdatePtr ent = NULL;
 
 	if (xorg_list_is_empty(&screen->pixmap_dirty_list))
 		return;
@@ -589,7 +595,11 @@ static int radeon_get_drm_master_fd(Scrn
 #endif
     struct pci_device *dev = info->PciInfo;
     char *busid;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+    int fd, err;
+#else
     int fd;
+#endif
 
 #ifdef XF86_PDEV_SERVER_FD
     if (pRADEONEnt->platform_dev) {
@@ -608,6 +618,17 @@ static int radeon_get_drm_master_fd(Scrn
 		      dev->domain, dev->bus, dev->dev, dev->func);
 #endif
 
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+    err = kldload("radeonkms");
+    if (err == -1 && errno != EEXIST) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+        	"[drm] Failed to load kernel module for %s: %s\n",
+        	busid, strerror(errno));
+        free(busid);
+        return -1;
+    }
+#endif
+
     fd = drmOpen(NULL, busid);
     if (fd == -1)
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,


----- End forwarded message -----
----- Forwarded message from davshao at gmail.com -----

Date: Mon, 20 Jul 2015 04:45:00 +0000 (UTC)
From: davshao at gmail.com
To: pkg-manager at netbsd.org, gnats-admin at netbsd.org, pkgsrc-bugs at netbsd.org
Cc: 
Subject: pkg/50068: x11/xf86-input-mouse dports patches for DragonFly and FreeBSD
Mail-Reply-To: davshao at gmail.com

>Number:         50068
>Category:       pkg
>Synopsis:       x11/xf86-input-mouse dports patches for DragonFly and FreeBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jul 20 04:45:00 +0000 2015
>Originator:     David Shao
>Release:        pkgsrc current cvs
>Organization:
>Environment:
DragonFly  4.3-DEVELOPMENT DragonFly v4.2.2.63.ga2b9b7-DEVELOPMENT #1: Sun Jul 19 19:22:57 PDT 2015     xxxxx@:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64

>Description:
Patches from DragonFly dports to x11/xf86-input-mouse are needed for DragonFly and FreeBSD to use a USB mouse in newer Xorg.  (There is a workaround for DragonFly using moused called from /etc/rc.conf, but I can't get that workaround to succeed on FreeBSD 10.1.  Also the DragonFly rc.conf invocation of moused has been unreliable for use with pkgsrc in the past.)

There are some complications.  A new options.mk file seems to require 3 new options just to distinguish between three possible include paths for the usb header file depending on the OS.  (This problem applies to other ports.  It is fortunate that sysutils/hal is being phased out.)  Unfortunately older DragonFly, newer DragonFly, and FreeBSD have three different possible paths.  Also one of the patches is gigantic.  Apart from trying to understand such a large patch, it is quite possible I have made mistakes merging the patch from dports.

I have tried to enclose all of the new code in ifdefs on symbol FREEBSD_USB, and supplanted code in !defined(FREEBSD_USB) blocks.  The functionality should be completely unaffected on non-DragonFly and non-FreeBSD platforms.

The patch itself ask why some of the logic for detecting OS and OS version isn't performed by patching configure scripts, but offers no such solution.  
>How-To-Repeat:

>Fix:
A small patch to Makefile for the new options.mk:

--- Makefile.orig	2015-07-18 18:48:26.000000000 -0700
+++ Makefile	2015-07-18 22:40:51.000000000 -0700
@@ -20,6 +20,8 @@
 CONFIGURE_ENV+=	DRIVER_MAN_SUFFIX=4
 .endif
 
+.include "options.mk"
+
 .include "../../x11/randrproto/buildlink3.mk"
 .include "../../x11/inputproto/buildlink3.mk"
 .include "../../x11/kbproto/buildlink3.mk"

The new options.mk:

PKG_OPTIONS_VAR=        PKG_OPTIONS.xf86-input-mouse
# dflyu4b is for DragonFly BSD newer USB stack, ported from newer FreeBSD
#     #include <bus/u4b/usb.h>
# dflyusb is for DragonFly BSD older USB stack, OS version < 300703
#     #include <bus/usb/usb.h>
# fbsdusb is for FreeBSD USB stack 
#     #include <dev/usb/usb.h>
PKG_SUPPORTED_OPTIONS= dflyu4b dflyusb fbsdusb 
PKG_SUGGESTED_OPTIONS=

.if ${OPSYS} == "DragonFly"
.if !empty(OS_VERSION:M[0-2].*) || !empty(OS_VERSION:M3.0*)
PKG_SUGGESTED_OPTIONS+= dflyusb 
.else
# Assume Dragonfly 3.1 - 3.6 users built U4B stack
# 3.8 and after U4B is the default
PKG_SUGGESTED_OPTIONS+= dflyu4b 
.endif
.endif

.if ${OPSYS} == "FreeBSD"
PKG_SUGGESTED_OPTIONS+= fbsdusb
.endif

.include "../../mk/bsd.options.mk"

.if !empty(PKG_OPTIONS:Mdflyu4b) || !empty(PKG_OPTIONS:Mdflyusb) || !empty(PKG_OPTIONS:Mfbsdusb)
CPPFLAGS+=	-DFREEBSD_USB
.endif

.if !empty(PKG_OPTIONS:Mdflyu4b)
CPPFLAGS+=	-DDRAGONFLY_U4B
.endif

.if !empty(PKG_OPTIONS:Mdflyusb)
CPPFLAGS+=	-DDRAGONFLY_USB
.endif

.if !empty(PKG_OPTIONS:Mdflyu4b) || !empty(PKG_OPTIONS:Mdflyusb) || !empty(PKG_OPTIONS:Mfbsdusb)
SUBST_CLASSES+=                 freebsdusb 
SUBST_STAGE.freebsdusb=		post-extract
SUBST_MESSAGE.freebsdusb=	Patching src/Makefile.in for DragonFly or FreeBSD compatible USB 
SUBST_FILES.freebsdusb+=	src/Makefile.in
SUBST_SED.freebsdusb+=		-e 's|-module -avoid-version|-module -avoid-version -lusbhid|'
.endif

The patch to mouse.h:

$NetBSD$

--- src/mouse.h.orig	2014-08-12 06:36:34.000000000 +0000
+++ src/mouse.h
@@ -27,6 +27,14 @@
 
 /* Public interface to OS-specific mouse support. */
 
+/* PKGSRC note: To support newer versions of DragonFly and FreeBSD,
+ * this file is patched using DragonFly dports
+ * x11-drivers/xf86-input-mouse/files/patch-src_mouse.h
+ * as of master commit 4f04bfe0ea83 ... Tue Jul 14 22:56:44 2015 -0700
+ * The patch's code is enclosed in include defined(FREEBSD_USB) while the
+ * original code is enclosed in include !defined(FREEBSD_USB).
+ */
+
 #ifndef _XF86OSMOUSE_H_
 #define _XF86OSMOUSE_H_
 
@@ -220,10 +228,17 @@ typedef struct _MouseDevRec {
     Bool                emulate3ButtonsSoft;
     int                 emulate3Timeout;/* Timeout for 3 button emulation */
     Bool                chordMiddle;
+#if defined(FREEBSD_USB)
+    Bool		disableXY;
+#endif
     Bool                flipXY;
     int                 invX;
     int                 invY;
     int                 resolution;
+#if defined(FREEBSD_USB)
+    Bool		hasW;
+    Bool		hasZ;
+#endif
     int                 negativeZ;      /* button mask */
     int                 positiveZ;      /* button mask */
     int                 negativeW;      /* button mask */
@@ -262,6 +277,10 @@ typedef struct _MouseDevRec {
     int                 doubleClickOldSourceState;
     int                 lastMappedButtons;
     int                 buttonMap[MSE_MAXBUTTONS];
+#if defined(FREEBSD_USB)
+    float		fracdx, fracdy;
+    float		sensitivity;
+#endif
 } MouseDevRec, *MouseDevPtr;
 
 #endif /* _XF86OSMOUSE_H_ */

The patch to mousePriv.h:

$NetBSD$

--- src/mousePriv.h.orig	2014-08-12 06:36:34.000000000 +0000
+++ src/mousePriv.h
@@ -2,6 +2,14 @@
  * Copyright (c) 1997-1999 by The XFree86 Project, Inc.
  */
 
+/* PKGSRC note: To support newer versions of DragonFly and FreeBSD,
+ * this file is patched using DragonFly dports
+ * x11-drivers/xf86-input-mouse/files/patch-src_mousePriv.h
+ * as of master commit 4f04bfe0ea83 ... Tue Jul 14 22:56:44 2015 -0700
+ * The patch's code is enclosed in include defined(FREEBSD_USB) while the
+ * original code is enclosed in include !defined(FREEBSD_USB).
+ */
+
 #ifndef _X_MOUSEPRIV_H
 #define _X_MOUSEPRIV_H
 
@@ -63,8 +71,10 @@ typedef struct {
     int         acc;
     CARD32      pnpLast;
     Bool        disablePnPauto;
+#if !defined(FREEBSD_USB)
     float       fracdx,fracdy;
     float       sensitivity;
+#endif
 } mousePrivRec, *mousePrivPtr;
 
 /* mouse proto flags */

A somewhat large patch to mouse.c:

$NetBSD$

--- src/mouse.c.orig	2014-08-12 06:36:34.000000000 +0000
+++ src/mouse.c
@@ -43,6 +43,13 @@
  * and to help limited dexterity persons
  */
 
+/* PKGSRC note: To support newer versions of DragonFly and FreeBSD,
+ * this file is patched using DragonFly dports
+ * x11-drivers/xf86-input-mouse/files/patch-src_mouse.c
+ * as of master commit 4f04bfe0ea83 ... Tue Jul 14 22:56:44 2015 -0700
+ * The patch's code is enclosed in include defined(FREEBSD_USB) while the
+ * original code is enclosed in include !defined(FREEBSD_USB).
+ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -293,13 +300,45 @@ MouseCommonOptions(InputInfoPtr pInfo)
 
     pMse = pInfo->private;
 
+#if !defined(FREEBSD_USB)
     pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
+#else
+    i = xf86SetIntOption(pInfo->options, "Buttons", 0);
+    if (i != 0)
+        pMse->buttons = i;
+#endif
     if (!pMse->buttons) {
         pMse->buttons = MSE_DFLTBUTTONS;
         buttons_from = X_DEFAULT;
     }
     origButtons = pMse->buttons;
 
+#if defined(FREEBSD_USB)
+    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;
+    }
+#endif
+
     pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options,
                                               "Emulate3Buttons", FALSE);
     if (!xf86FindOptionValue(pInfo->options,"Emulate3Buttons")) {
@@ -311,6 +350,10 @@ MouseCommonOptions(InputInfoPtr pInfo)
                                              "Emulate3Timeout", 50);
     if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) {
         MessageType from = X_CONFIG;
+#if defined(FREEBSD_USB)
+       if (pMse->buttons < 3)
+            pMse->buttons = 3;
+#endif
         if (pMse->emulate3ButtonsSoft)
             from = X_DEFAULT;
         xf86Msg(from, "%s: Emulate3Buttons, Emulate3Timeout: %d\n",
@@ -318,6 +361,10 @@ MouseCommonOptions(InputInfoPtr pInfo)
     }
 
     pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE);
+#if defined(FREEBSD_USB)
+    if (pMse->chordMiddle && pMse->buttons < 3)
+           pMse->buttons = 3;
+#endif
     pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE);
     if (xf86SetBoolOption(pInfo->options, "InvX", FALSE)) {
         pMse->invX = -1;
@@ -328,7 +375,9 @@ MouseCommonOptions(InputInfoPtr pInfo)
     } else
         pMse->invY = 1;
     pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0);
-
+#if defined(FREEBSD_USB)
+    pMse->sensitivity = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
+#endif
 
     if (pMse->pDragLock)
         free(pMse->pDragLock);
@@ -438,14 +487,25 @@ MouseCommonOptions(InputInfoPtr pInfo)
         free(s);
     }
 
+#if !defined(FREEBSD_USB)
     s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5");
+#else
+    s = xf86SetStrOption(pInfo->options, "ZAxisMapping",
+        pMse->hasZ ? ( pMse->hasW ? "4 5 6 7" : "4 5" ) : "off");
+#endif
     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 !defined(FREEBSD_USB)
         if (!xf86NameCmp(s, "x")) {
+#else
+        if (!xf86NameCmp(s, "off")) {
+            msg = xstrdup("off");
+        } else if (!xf86NameCmp(s, "x")) {
+#endif
             pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
             msg = xstrdup("X axis");
         } else if (!xf86NameCmp(s, "y")) {
@@ -594,6 +654,7 @@ MouseCommonOptions(InputInfoPtr pInfo)
                 pInfo->name, wheelButton, pMse->wheelInertia,
                 pMse->wheelButtonTimeout);
     }
+#if !defined(FREEBSD_USB)
     s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL);
     if (s) {
        int b, n = 0;
@@ -617,6 +678,7 @@ MouseCommonOptions(InputInfoPtr pInfo)
         if (f > pMse->buttons)
             pMse->buttons = f;
     }
+#endif
     if (origButtons != pMse->buttons)
         buttons_from = X_CONFIG;
     xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons);
@@ -698,7 +760,9 @@ MouseHWOptions(InputInfoPtr pInfo)
     }
     pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0);
     pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0);
+#if !defined(FREEBSD_USB)
     mPriv->sensitivity = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
+#endif
 }
 
 static void
@@ -987,6 +1051,11 @@ MousePreInit(InputDriverPtr drv, InputIn
     for (i = 0; i < MSE_MAXBUTTONS; i++)
         pMse->buttonMap[i] = 1 << (i > 2 && i < MSE_MAXBUTTONS-4 ? i+4 : i);
 
+#if defined(FREEBSD_USB)
+    pMse->hasZ = 1;
+    pMse->hasW = 0;
+#endif
+
     protocol = MousePickProtocol(pInfo, device, protocol, &protocolID);
 
     if (!device)
@@ -2271,6 +2340,11 @@ MouseDoPostEvent(InputInfoPtr pInfo, int
                         }
                     }
                 }
+#if defined (FREEBSD_USB)
+            } else {
+                pMse->wheelXDistance = 0;
+                pMse->wheelYDistance = 0;
+#endif
             }
 
             /* Absorb the mouse movement while the wheel button is pressed. */
@@ -2288,7 +2362,11 @@ MouseDoPostEvent(InputInfoPtr pInfo, int
     if (pMse->emulate3ButtonsSoft && pMse->emulate3Pending && (dx || dy))
         buttonTimer(pInfo);
 
+#if !defined(FREEBSD_USB)
     if (dx || dy)
+#else
+    if ((dx || dy) && !pMse->disableXY)
+#endif
         xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
 
     if (change) {
@@ -2401,12 +2479,16 @@ MousePostEvent(InputInfoPtr pInfo, int t
                int dx, int dy, int dz, int dw)
 {
     MouseDevPtr pMse;
+#if !defined(FREEBSD_USB)
     mousePrivPtr mousepriv;
+#endif
     int zbutton = 0, wbutton = 0, zbuttoncount = 0, wbuttoncount = 0;
     int i, b, buttons = 0;
 
     pMse = pInfo->private;
+#if !defined(FREEBSD_USB)
     mousepriv = (mousePrivPtr)pMse->mousePriv;
+#endif
 
     if (pMse->protocolID == PROT_MMHIT)
         b = reverseBits(hitachMap, truebuttons);
@@ -2499,12 +2581,21 @@ MousePostEvent(InputInfoPtr pInfo, int t
 
     /* Accumulate the scaled dx, dy in the private variables
        fracdx,fracdy and return the integer number part */
+#if !defined(FREEBSD_USB)
     if (mousepriv) {
         mousepriv->fracdx += mousepriv->sensitivity*dx;
         mousepriv->fracdy += mousepriv->sensitivity*dy;
         mousepriv->fracdx -= ( dx=(int)(mousepriv->fracdx) );
         mousepriv->fracdy -= ( dy=(int)(mousepriv->fracdy) );
     }
+#else
+    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) );
+    }
+#endif
 
     /* If mouse wheel movement has to be mapped on a button, we need to
      * loop for button press and release events. */

The gigantic patch to bsd_mouse.c:

$NetBSD$

--- src/bsd_mouse.c.orig	2014-08-12 06:36:34.000000000 +0000
+++ src/bsd_mouse.c
@@ -26,6 +26,41 @@
  * authorization from the copyright holder(s) and author(s).
  */
 
+/* PKGSRC note: To support newer versions of DragonFly and FreeBSD,
+ * this file is patched using DragonFly dports
+ * x11-drivers/xf86-input-mouse/files/patch-src-bsd_mouse.c and
+ * x11-drivers/xf86-input-mouse/dragonfly/patch-src_bsd__mouse.c
+ * as of master commit 4f04bfe0ea83 ... Tue Jul 14 22:56:44 2015 -0700
+ * The patch's code is enclosed in include defined(FREEBSD_USB) while the
+ * original code is enclosed in include !defined(FREEBSD_USB).
+ */
+
+/* DRAGONFLY_U4B is the usb system after OS version 300703
+ * DRAGONFLY_USB is the usb system before OS version 300703
+ * FREEBSD_USB must be defined if either DRAGONFLY_U4B or DRAGONFLY_USB are.
+ */
+
+#if defined(FREEBSD_USB)
+
+/*
+ * 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__) */
+
+#endif /* defined(FREEBSD_USB) */
+
 #include <xorg-server.h>
 
 #include <X11/X.h>
@@ -33,12 +68,33 @@
 #include "xf86Priv.h"
 #include "xf86_OSlib.h"
 #include "xf86Xinput.h"
+#if defined(FREEBSD_USB)
+#include <exevents.h>
+#endif
 #include "mouse.h"
 #include "xisb.h"
 #include "mipointer.h"
+
+#if defined(FREEBSD_USB)
+#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
+#endif /* defined(FREEBSD_USB) */
+
 #ifdef WSCONS_SUPPORT
 #include <dev/wscons/wsconsio.h>
 #endif
+
 #ifdef USBMOUSE_SUPPORT
 #ifdef HAS_LIB_USB_HID
 #include <usbhid.h>
@@ -46,10 +102,25 @@
 #include "usb.h"
 #endif
 
+#if defined(FREEBSD_USB)
+
+#if defined(DRAGONFLY_U4B)
+#include <sys/param.h>
+#include <bus/u4b/usb.h>
+#elif defined(DRAGONFLY_USB)
+#include <sys/param.h>
+#include <bus/usb/usb.h>
+#else
 #include <dev/usb/usb.h>
+#endif
+
+#endif /* defined(FREEBSD_USB) */
+
+#if !defined(FREEBSD_USB)
 #ifdef USB_GET_REPORT_ID
 #define USB_NEW_HID
 #endif
+#endif /* !defined(FREEBSD_USB) */
 
 #define HUP_GENERIC_DESKTOP     0x0001
 #define HUP_BUTTON              0x0009
@@ -76,10 +147,17 @@ static const char *FindDevice(InputInfoP
 #define DEFAULT_SYSMOUSE_DEV            "/dev/sysmouse"
 #define DEFAULT_PS2_DEV                 "/dev/psm0"
 
+#if defined(FREEBSD_USB)
+#define DEFAULT_USB_DEV                 "/dev/ums0"
+#endif
+
 static const char *mouseDevs[] = {
         DEFAULT_MOUSE_DEV,
         DEFAULT_SYSMOUSE_DEV,
         DEFAULT_PS2_DEV,
+#if defined(FREEBSD_USB)
+        DEFAULT_USB_DEV,
+#endif
         NULL
 };
 #elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
@@ -97,11 +175,23 @@ static const char *mouseDevs[] = {
 static int
 SupportedInterfaces(void)
 {
+#if !defined(FREEBSD_USB)
+
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__NetBSD__)
     return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
 #else
     return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
 #endif
+
+#else /* defined(FREEBSD_USB) */
+
+#if defined(__NetBSD__)
+    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
+#else
+    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
+#endif
+
+#endif /* !defined(FREEBSD_USB) */
 }
 
 /* Names of protocols that are handled internally here. */
@@ -178,9 +268,34 @@ static struct {
         { MOUSE_PROTO_SYSMOUSE,         "SysMouse" }
 };
 
+#if defined(FREEBSD_USB)
+#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
+#endif /* defined(FREEBSD_USB) */
+
 static const char *
 SetupAuto(InputInfoPtr pInfo, int *protoPara)
 {
+#if defined(FREEBSD_USB)
+#ifdef XPS2_SUPPORT
+    const char *dev;
+#endif
+    const char *proto;
+#endif /* defined(FREEBSD_USB) */
     int i;
     mousehw_t hw;
     mousemode_t mode;
@@ -189,6 +304,14 @@ SetupAuto(InputInfoPtr pInfo, int *proto
         return NULL;
 
     /* set the driver operation level, if applicable */
+#if defined (FREEBSD_USB)
+#ifdef XPS2_SUPPORT
+    dev = xf86FindOptionValue(pInfo->options, "Device");
+    if (dev != NULL && !strncmp(dev, DEFAULT_PS2_DEV, 8))
+        i = 2;
+    else
+#endif
+#endif /* defined(FREEBSD_USB) */
     i = 1;
     ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
 
@@ -207,9 +330,27 @@ SetupAuto(InputInfoPtr pInfo, int *proto
                     protoPara[0] = mode.syncmask[0];
                     protoPara[1] = mode.syncmask[1];
                 }
+#if defined(FREEBSD_USB)
+                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
+#endif /* defined(FREEBSD_USB) */
+
+#if !defined(FREEBSD_USB)
                 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
                             pInfo->name, devproto[i].name);
                 return devproto[i].name;
+#else /* defined(FREEBSD_USB) */
+                xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
+                            pInfo->name, proto);
+                return proto;
+#endif /* !defined(FREEBSD_USB) */
             }
         }
     }
@@ -227,6 +368,9 @@ SetSysMouseRes(InputInfoPtr pInfo, const
     mode.rate = rate > 0 ? rate : -1;
     mode.resolution = res > 0 ? res : -1;
     mode.accelfactor = -1;
+
+#if !defined(FREEBSD_USB)
+
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
     if (pMse->autoProbe ||
         (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
@@ -241,13 +385,35 @@ SetSysMouseRes(InputInfoPtr pInfo, const
 #else
     mode.level = -1;
 #endif
+
+#else /* defined(FREEBSD_USB) */
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+    if (pMse->autoProbe ||
+        (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
+        /*
+         * As the FreeBSD sysmouse driver defaults to protocol level 0
+         * everytime it is closed we enforce protocol level 1 again at
+         * this point.
+         */
+        mode.level = 1;
+    } else
+#endif
+    mode.level = -1;
+
+#endif /* !defined(FREEBSD_USB) */
+
     ioctl(pInfo->fd, MOUSE_SETMODE, &mode);
 }
 #endif
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 
+#if !defined(FREEBSD_USB)
 #define MOUSED_PID_FILE "/var/run/moused.pid"
+#endif
+
+#if !defined(FREEBSD_USB)
 
 /*
  * Try to check if moused is running.  DEFAULT_SYSMOUSE_DEV is useless without
@@ -271,20 +437,66 @@ MousedRunning(void)
     return FALSE;
 }
 
+#else /* defined(FREEBSD_USB) */
+
+/*
+ * Try to check if moused is running.  DEFAULT_SYSMOUSE_DEV is useless without
+ * 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(const char *dev)
+{
+    char cmd[128];
+    FILE *f = NULL;
+    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;
+        }
+        pclose(f);
+    }
+    return FALSE;
+}
+
+#endif /* !defined(FREEBSD_USB) */
+
 static const char *
 FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
 {
+#if !defined(FREEBSD_USB)
     int fd = -1;
+#else
+    int ret = -1;
+#endif
     const char **pdev, *dev = NULL;
     Bool devMouse = FALSE;
     struct stat devMouseStat;
     struct stat sb;
 
     for (pdev = mouseDevs; *pdev; pdev++) {
+
+#if !defined(FREEBSD_USB)
         SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK));
         if (fd == -1) {
+#else
+        SYSCALL (ret = stat(*pdev, &sb));
+        if (ret == -1) {
+#endif /* !defined(FREEBSD_USB) */
+
 #ifdef DEBUG
+#if !defined(FREEBSD_USB)
             ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno));
+#else
+            ErrorF("Cannot stat %s (%s)\n", *pdev, strerror(errno));
+#endif /* !defined(FREEBSD_USB) */
 #endif
         } else {
             /*
@@ -293,28 +505,70 @@ FindDevice(InputInfoPtr pInfo, const cha
              * the test for whether /dev/sysmouse is usable can be made.
              */
             if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) {
+#if !defined(FREEBSD_USB)
                 if (fstat(fd, &devMouseStat) == 0)
                     devMouse = TRUE;
                 close(fd);
+#else
+                memcpy(&devMouseStat, &sb, sizeof(devMouseStat));
+                devMouse = TRUE;
+#endif /* !defined(FREEBSD_USB) */
                 continue;
             } else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) {
                 /* Check if /dev/mouse is the same as /dev/sysmouse. */
+#if !defined(FREEBSD_USB)
                 if (devMouse && fstat(fd, &sb) == 0 &&
                     devMouseStat.st_dev == sb.st_dev &&
                     devMouseStat.st_ino == sb.st_ino) {
+#else
+                if (devMouse && devMouseStat.st_dev == sb.st_dev &&
+                    devMouseStat.st_ino == sb.st_ino) {
+#endif /* !defined(FREEBSD_USB) */
                     /* If the same, use /dev/sysmouse. */
                     devMouse = FALSE;
                 }
+
+#if !defined(FREEBSD_USB)
                 close(fd);
                 if (MousedRunning())
+#else
+                if (MousedRunning(NULL))
+#endif /* !defined(FREEBSD_USB) */
+
                     break;
+
+#if !defined(FREEBSD_USB)
                 else {
 #ifdef DEBUG
                     ErrorF("moused isn't running\n");
 #endif
                 }
+#endif /* !defined(FREEBSD_USB) */
+
             } else {
+
+#if !defined(FREEBSD_USB)
+
                 close(fd);
+
+#else /* defined(FREEBSD_USB) */
+
+                /* 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;
+
+#endif /* !defined(FREEBSD_USB) */
+
                 break;
             }
         }
@@ -486,8 +740,17 @@ wsconsPreInit(InputInfoPtr pInfo, const
 
 #if defined(USBMOUSE_SUPPORT)
 
+#if defined(FREEBSD_USB)
+#define MAXRIDS		64
+#define MAXACOLS	8
+#define MAXLCOLS	16
+#endif
+
 typedef struct _UsbMseRec {
     int packetSize;
+
+#if !defined(FREEBSD_USB)
+
     int iid;
     hid_item_t loc_x;           /* x locator item */
     hid_item_t loc_y;           /* y locator item */
@@ -495,22 +758,92 @@ typedef struct _UsbMseRec {
     hid_item_t loc_w;           /* z (wheel) locator item */
     hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
    unsigned char *buffer;
+
+#else /* defined(FREEBSD_USB) */
+
+    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;
+
+#endif /* !defined(FREEBSD_USB) */
+
 } UsbMseRec, *UsbMsePtr;
 
+#if defined(FREEBSD_USB)
+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);
+}
+#endif /* defined(FREEBSD_USB) */
+
 static int
 usbMouseProc(DeviceIntPtr pPointer, int what)
 {
     InputInfoPtr pInfo;
     MouseDevPtr pMse;
     UsbMsePtr pUsbMse;
+#if defined(FREEBSD_USB)
+    struct UsbMseAcol *acol;
+#endif
     unsigned char map[MSE_MAXBUTTONS + 1];
+
+#if !defined(FREEBSD_USB)
     int nbuttons;
+#else /* defined (FREEBSD_USB) */
+    int nacol, nbuttons;
+#ifdef HAVE_LABELS
+    Atom btn_labels[MSE_MAXBUTTONS] = {0};
+    Atom axes_labels[3] = { 0, 0, 0 };
+#endif
+#endif /* !defined(FREEBSD_USB) */
 
     pInfo = pPointer->public.devicePrivate;
     pMse = pInfo->private;
     pMse->device = pPointer;
     pUsbMse = pMse->mousePriv;
 
+#if defined(FREEBSD_USB)
+    for (nacol = 0; nacol < (pUsbMse->nacols - 1); nacol++) {
+	if (pUsbMse->acols[nacol].pInfo == pInfo)
+	    break;
+    }
+    acol = &pUsbMse->acols[nacol];
+#endif
+
     switch (what) {
     case DEVICE_INIT:
         pPointer->public.on = FALSE;
@@ -518,23 +851,114 @@ usbMouseProc(DeviceIntPtr pPointer, int
         for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
             map[nbuttons + 1] = nbuttons + 1;
 
+#if !defined(FREEBSD_USB)
         InitPointerDeviceStruct((DevicePtr)pPointer,
                                 map,
                                 min(pMse->buttons, MSE_MAXBUTTONS),
                                 miPointerGetMotionEvents,
                                 pMse->Ctrl,
                                 miPointerGetMotionBufferSize());
+#else /* defined(FREEBSD_USB) */
+
+#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);
+
+#endif /* !defined(FREEBSD_USB) */
 
         /* X valuator */
+#if !defined(FREEBSD_USB)
+
         xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
         xf86InitValuatorDefaults(pPointer, 0);
+
+#else /* defined(FREEBSD_USB) */
+
+	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);
+
+#endif /* !defined(FREEBSD_USB) */
+
         /* Y valuator */
+
+#if !defined(FREEBSD_USB)
+
         xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
         xf86InitValuatorDefaults(pPointer, 1);
+
+#else /* defined(FREEBSD_USB) */
+
+	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);
+	}
+
+#endif /* !defined(FREEBSD_USB) */
+
         xf86MotionHistoryAllocate(pInfo);
         break;
 
     case DEVICE_ON:
+
+#if !defined(FREEBSD_USB)
+
         pInfo->fd = xf86OpenSerial(pInfo->options);
         if (pInfo->fd == -1)
             xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
@@ -551,6 +975,30 @@ usbMouseProc(DeviceIntPtr pPointer, int
                     AddEnabledDevice(pInfo->fd);
             }
         }
+
+#else /* defined(FREEBSD_USB) */
+
+	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);
+		    }
+		}
+        }
+
+#endif /* !defined(FREEBSD_USB) */
+
         pMse->lastButtons = 0;
         pMse->lastMappedButtons = 0;
         pMse->emulateState = 0;
@@ -571,6 +1019,9 @@ usbMouseProc(DeviceIntPtr pPointer, int
             xf86CloseSerial(pInfo->fd);
             pInfo->fd = -1;
         }
+#if defined(FREEBSD_USB)
+        pUsbMse->opened--;
+#endif
         pPointer->public.on = FALSE;
         usleep(300000);
         break;
@@ -586,27 +1037,86 @@ usbReadInput(InputInfoPtr pInfo)
 {
     MouseDevPtr pMse;
     UsbMsePtr pUsbMse;
+
+#if !defined(FREEBSD_USB)
     int buttons = pMse->lastButtons;
     int dx = 0, dy = 0, dz = 0, dw = 0;
     int n, c;
+#else
+    int buttons, cc;
+    int dx, dy, dz, dw, dp, upd, v, nx, ny, np, in_range;
+    int n, c, rid, *sizep, nacol, nlcol;
+#endif /* !defined(FREEBSD_USB) */
+
     unsigned char *pBuf;
 
+#if defined(FREEBSD_USB)
+    struct UsbMseAcol *acol;
+    struct UsbMseLcol *lcol;
+#endif
     pMse = pInfo->private;
     pUsbMse = pMse->mousePriv;
 
     XisbBlockDuration(pMse->buffer, -1);
+#if defined(FREEBSD_USB)
+next:
+#endif
     pBuf = pUsbMse->buffer;
     n = 0;
+
+#if !defined(FREEBSD_USB)
+
     while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) {
         pBuf[n++] = (unsigned char)c;
+
+    }
+#else /* defined(FREEBSD_USB) */
+
+    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;
+    }
+
+#endif /* !defined(FREEBSD_USB) */
+
     if (n == 0)
         return;
+
+#if !defined(FREEBSD_USB)
+
     if (n != pUsbMse->packetSize) {
         LogMessageVerbSigSafe(X_WARNING, -1,
                               "%s: incomplete packet, size %d\n",
                               pInfo->name, n);
     }
+
+#else /* defined(FREEBSD_USB) */
+
+    if (n == 0)
+        return;
+//    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);
+    }
+
+#endif /* !defined(FREEBSD_USB) */
+
+#if !defined(FREEBSD_USB)
+
     /* discard packets with an id that don't match the mouse */
     /* XXX this is probably not the right thing */
     if (pUsbMse->iid != 0) {
@@ -625,6 +1135,122 @@ usbReadInput(InputInfoPtr pInfo)
     }
     pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
     return;
+
+#else /* defined(FREEBSD_USB) */
+
+    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;
+    }
+    goto next;
+
+#endif /* !defined(FREEBSD_USB) */
+
 }
 
 static void
@@ -633,15 +1259,27 @@ usbSigioReadInput (int fd, void *closure
     usbReadInput ((InputInfoPtr) closure);
 }
 
+#if !defined(FREEBSD_USB)
 /* This function is called when the protocol is "usb". */
 static Bool
 usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+#else
+static Bool
+usbInitFirst(InputInfoPtr pInfo)
+#endif /* !defined(FREEBSD_USB) */
 {
     MouseDevPtr pMse = pInfo->private;
     UsbMsePtr pUsbMse;
     report_desc_t reportDesc;
+#if !defined(FREEBSD_USB)
     int i;
-
+#else
+    hid_data_t d;
+    hid_item_t h;
+    struct UsbMseAcol *acol;
+    struct UsbMseLcol *lcol;
+    int mdepth, rsize, *rsizep, acolused, lcolused, used;
+#endif /* !defined(FREEBSD_USB) */
     pUsbMse = malloc(sizeof(UsbMseRec));
     if (pUsbMse == NULL) {
         xf86Msg(X_ERROR, "%s: cannot allocate UsbMouseRec\n", pInfo->name);
@@ -649,12 +1287,16 @@ usbPreInit(InputInfoPtr pInfo, const cha
         return FALSE;
     }
 
+#if !defined(FREEBSD_USB)
     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);
+#else
+    bzero(pUsbMse, sizeof(UsbMseRec));
+#endif /* !defined(FREEBSD_USB) */
 
     /* Check if the device can be opened. */
     pInfo->fd = xf86OpenSerial(pInfo->options);
@@ -670,6 +1312,9 @@ usbPreInit(InputInfoPtr pInfo, const cha
     }
     /* Get USB informations */
     reportDesc = hid_get_report_desc(pInfo->fd);
+
+#if !defined(FREEBSD_USB)
+
     /* Get packet size & iid */
 #ifdef USB_NEW_HID
     if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) {
@@ -683,6 +1328,139 @@ usbPreInit(InputInfoPtr pInfo, const cha
     pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
                                               &pUsbMse->iid);
 #endif
+
+#else /* defined(FREEBSD_USB) */
+
+    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;
+	}
+    }
+    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);
+
+#endif /* !defined(FREEBSD_USB) */
+
     /* Allocate buffer */
     if (pUsbMse->packetSize <= 8) {
         pUsbMse->buffer = pMse->protoBuf;
@@ -692,10 +1470,15 @@ usbPreInit(InputInfoPtr pInfo, const cha
     if (pUsbMse->buffer == NULL) {
         xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
         free(pUsbMse);
+#if !defined(FREEBSD_USB)
         free(pMse);
+#endif
         xf86CloseSerial(pInfo->fd);
         return FALSE;
     }
+
+#if !defined(FREEBSD_USB)
+
 #ifdef USB_NEW_HID
     if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
                    hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) {
@@ -733,12 +1516,15 @@ usbPreInit(InputInfoPtr pInfo, const cha
     }
     pMse->buttons = i-1;
 
+#endif /* !defined(FREEBSD_USB) */
+
     xf86CloseSerial(pInfo->fd);
     pInfo->fd = -1;
 
     /* Private structure */
     pMse->mousePriv = pUsbMse;
 
+#if !defined(FREEBSD_USB)
     /* Process common mouse options (like Emulate3Buttons, etc). */
     pMse->CommonOptions(pInfo);
 
@@ -749,8 +1535,137 @@ usbPreInit(InputInfoPtr pInfo, const cha
 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
     pInfo->flags |= XI86_CONFIGURED;
 #endif
+
+#endif /* !defined(FREEBSD_USB) */
+
     return TRUE;
 }
+
+#if defined(FREEBSD_USB)
+
+/* 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;
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
+    pInfo->flags |= XI86_CONFIGURED;
+#endif
+    return TRUE;
+}
+
+#endif /* defined(FREEBSD_USB) */
+
 #endif /* USBMOUSE */
 
 static Bool
@@ -784,7 +1699,15 @@ OSMouseInit(int flags)
     p->CheckProtocol = CheckProtocol;
 #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
     p->SetupAuto = SetupAuto;
+
+#if !defined(FREEBSD_USB)
+    p->SetPS2Res = SetSysMouseRes;
+#else
+#ifndef XPS2_SUPPORT
     p->SetPS2Res = SetSysMouseRes;
+#endif
+#endif
+
     p->SetBMRes = SetSysMouseRes;
     p->SetMiscRes = SetSysMouseRes;
 #endif





----- End forwarded message -----
----- Forwarded message from davshao at gmail.com -----

Date: Sat, 25 Jul 2015 23:25:00 +0000 (UTC)
From: davshao at gmail.com
To: pkg-manager at netbsd.org, gnats-admin at netbsd.org, pkgsrc-bugs at netbsd.org
Cc: 
Subject: pkg/50090: x11/xf86-video-intel fix build and enable functionality on newer DragonFly and FreeBSD
Mail-Reply-To: davshao at gmail.com

>Number:         50090
>Category:       pkg
>Synopsis:       x11/xf86-video-intel fix build and enable functionality on newer DragonFly and FreeBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 25 23:25:00 +0000 2015
>Originator:     David Shao
>Release:        pkgsrc current
>Organization:
>Environment:
DragonFly  4.3-DEVELOPMENT DragonFly v4.2.2.123.g14929-DEVELOPMENT #10: Sat Jul 25 07:24:55 PDT 2015     xxxxx@:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64

>Description:
On at least newer DragonFly and FreeBSD, and possibly maybe none of them, x11/xf86-video-intel cannot build due to a problem finding getline() in src/sna/kgem.c

kgem.c: In function 'cpu_cache_size':
kgem.c:996:10: error: implicit declaration of function 'getline' [-Werror=implicit-function-declaration]
   while (getline(&line, &len, file) != -1) {

Fortunately this has a fix in the Makefile that does not touch the original source code.

Unfortunately to actually make xf86-video-intel functional on newer DragonFly and probably FreeBSD, there is yet another patch from DragonFly dports / FreeBSD ports that will never be accepted by upstream.


>How-To-Repeat:

>Fix:
--- Makefile.orig	2015-05-28 19:59:23.000000000 -0700
+++ Makefile	2015-07-22 14:03:32.000000000 -0700
@@ -24,6 +24,10 @@
 CONFIGURE_ENV+=	DRIVER_MAN_SUFFIX=4
 .endif
 
+.if ${OPSYS} == "FreeBSD" || ${OPSYS} == "DragonFly"
+CFLAGS+=	-D_WITH_GETLINE=1
+.endif
+
 BUILDLINK_API_DEPENDS.libdrm+=	libdrm>=2.4.7
 
 .include "../../x11/modular-xorg-server/buildlink3.mk"

$NetBSD$

--- src/intel_device.c.orig	2015-07-23 00:34:18.755727000 +0000
+++ src/intel_device.c
@@ -398,8 +398,13 @@ static int __intel_open_device__legacy(c
 		 pci->domain, pci->bus, pci->dev, pci->func);
 
 	ret = drmCheckModesettingSupported(id);
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+	if (ret || 1) {
+		if (xf86LoadKernelModule("i915kms"))
+#else
 	if (ret) {
 		if (xf86LoadKernelModule("i915"))
+#endif
 			ret = drmCheckModesettingSupported(id);
 		if (ret)
 			return -1;


----- End forwarded message -----


More information about the xorg-devel mailing list