bsd_mouse.c revision f3d19aa6
16aab59a7Smrg
26aab59a7Smrg/*
36aab59a7Smrg * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
46aab59a7Smrg *
56aab59a7Smrg * Permission is hereby granted, free of charge, to any person obtaining a
66aab59a7Smrg * copy of this software and associated documentation files (the "Software"),
76aab59a7Smrg * to deal in the Software without restriction, including without limitation
86aab59a7Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
96aab59a7Smrg * and/or sell copies of the Software, and to permit persons to whom the
106aab59a7Smrg * Software is furnished to do so, subject to the following conditions:
116aab59a7Smrg *
126aab59a7Smrg * The above copyright notice and this permission notice shall be included in
136aab59a7Smrg * all copies or substantial portions of the Software.
146aab59a7Smrg *
156aab59a7Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166aab59a7Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176aab59a7Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186aab59a7Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
196aab59a7Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
206aab59a7Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
216aab59a7Smrg * OTHER DEALINGS IN THE SOFTWARE.
226aab59a7Smrg *
236aab59a7Smrg * Except as contained in this notice, the name of the copyright holder(s)
246aab59a7Smrg * and author(s) shall not be used in advertising or otherwise to promote
256aab59a7Smrg * the sale, use or other dealings in this Software without prior written
266aab59a7Smrg * authorization from the copyright holder(s) and author(s).
276aab59a7Smrg */
286aab59a7Smrg
296aab59a7Smrg#include <xorg-server.h>
306aab59a7Smrg
316aab59a7Smrg#include <X11/X.h>
326aab59a7Smrg#include "xf86.h"
336aab59a7Smrg#include "xf86Priv.h"
346aab59a7Smrg#include "xf86_OSlib.h"
356aab59a7Smrg#include "xf86Xinput.h"
36bd3a1963Smrg#include "mouse.h"
376aab59a7Smrg#include "xisb.h"
386aab59a7Smrg#include "mipointer.h"
396aab59a7Smrg#ifdef WSCONS_SUPPORT
406aab59a7Smrg#include <dev/wscons/wsconsio.h>
416aab59a7Smrg#endif
426aab59a7Smrg#ifdef USBMOUSE_SUPPORT
436aab59a7Smrg#ifdef HAS_LIB_USB_HID
446aab59a7Smrg#include <usbhid.h>
456aab59a7Smrg#else
466aab59a7Smrg#include "usb.h"
476aab59a7Smrg#endif
486aab59a7Smrg
496aab59a7Smrg#include <dev/usb/usb.h>
506aab59a7Smrg#ifdef USB_GET_REPORT_ID
516aab59a7Smrg#define USB_NEW_HID
526aab59a7Smrg#endif
536aab59a7Smrg
546aab59a7Smrg#define HUP_GENERIC_DESKTOP     0x0001
556aab59a7Smrg#define HUP_BUTTON              0x0009
566aab59a7Smrg
576aab59a7Smrg#define HUG_X                   0x0030
586aab59a7Smrg#define HUG_Y                   0x0031
596aab59a7Smrg#define HUG_Z                   0x0032
606aab59a7Smrg#define HUG_WHEEL               0x0038
616aab59a7Smrg
626aab59a7Smrg#define HID_USAGE2(p,u) (((p) << 16) | u)
636aab59a7Smrg
646aab59a7Smrg/* The UMS mices have middle button as number 3 */
656aab59a7Smrg#define UMS_BUT(i) ((i) == 0 ? 2 : (i) == 1 ? 0 : (i) == 2 ? 1 : (i))
666aab59a7Smrg#endif /* USBMOUSE_SUPPORT */
676aab59a7Smrg
686aab59a7Smrg#ifdef USBMOUSE_SUPPORT
696aab59a7Smrgstatic void usbSigioReadInput (int fd, void *closure);
706aab59a7Smrg#endif
716aab59a7Smrgstatic const char *FindDevice(InputInfoPtr, const char *, int);
726aab59a7Smrg
736aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
746aab59a7Smrg/* These are for FreeBSD and DragonFly */
756aab59a7Smrg#define DEFAULT_MOUSE_DEV		"/dev/mouse"
766aab59a7Smrg#define DEFAULT_SYSMOUSE_DEV		"/dev/sysmouse"
776aab59a7Smrg#define DEFAULT_PS2_DEV			"/dev/psm0"
786aab59a7Smrg
796aab59a7Smrgstatic const char *mouseDevs[] = {
806aab59a7Smrg	DEFAULT_MOUSE_DEV,
816aab59a7Smrg	DEFAULT_SYSMOUSE_DEV,
826aab59a7Smrg	DEFAULT_PS2_DEV,
836aab59a7Smrg	NULL
846aab59a7Smrg};
856aab59a7Smrg#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
866aab59a7Smrg/* Only wsmouse mices are autoconfigured for now on OpenBSD */
876aab59a7Smrg#define DEFAULT_WSMOUSE_DEV		"/dev/wsmouse"
886aab59a7Smrg#define DEFAULT_WSMOUSE0_DEV		"/dev/wsmouse0"
896aab59a7Smrg
906aab59a7Smrgstatic const char *mouseDevs[] = {
916aab59a7Smrg	DEFAULT_WSMOUSE_DEV,
926aab59a7Smrg	DEFAULT_WSMOUSE0_DEV,
936aab59a7Smrg	NULL
946aab59a7Smrg};
956aab59a7Smrg#endif
966aab59a7Smrg
976aab59a7Smrgstatic int
986aab59a7SmrgSupportedInterfaces(void)
996aab59a7Smrg{
1006aab59a7Smrg#if defined(__NetBSD__)
10141ed76f1Smrg    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
1026aab59a7Smrg#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1036aab59a7Smrg    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
1046aab59a7Smrg#else
105bd3a1963Smrg    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
1066aab59a7Smrg#endif
1076aab59a7Smrg}
1086aab59a7Smrg
1096aab59a7Smrg/* Names of protocols that are handled internally here. */
1106aab59a7Smrgstatic const char *internalNames[] = {
1116aab59a7Smrg#if defined(WSCONS_SUPPORT)
1126aab59a7Smrg	"WSMouse",
1136aab59a7Smrg#endif
1146aab59a7Smrg#if defined(USBMOUSE_SUPPORT)
1156aab59a7Smrg	"usb",
1166aab59a7Smrg#endif
1176aab59a7Smrg	NULL
1186aab59a7Smrg};
1196aab59a7Smrg
1206aab59a7Smrg/*
1216aab59a7Smrg * Names of MSC_MISC protocols that the OS supports.  These are decoded by
1226aab59a7Smrg * main "mouse" driver.
1236aab59a7Smrg */
1246aab59a7Smrgstatic const char *miscNames[] = {
1256aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1266aab59a7Smrg	"SysMouse",
1276aab59a7Smrg#endif
1286aab59a7Smrg	NULL
1296aab59a7Smrg};
1306aab59a7Smrg
1316aab59a7Smrgstatic const char **
1326aab59a7SmrgBuiltinNames(void)
1336aab59a7Smrg{
1346aab59a7Smrg    return internalNames;
1356aab59a7Smrg}
1366aab59a7Smrg
1376aab59a7Smrgstatic Bool
1386aab59a7SmrgCheckProtocol(const char *protocol)
1396aab59a7Smrg{
1406aab59a7Smrg    int i;
1416aab59a7Smrg
1426aab59a7Smrg    for (i = 0; internalNames[i]; i++)
1436aab59a7Smrg	if (xf86NameCmp(protocol, internalNames[i]) == 0)
1446aab59a7Smrg	    return TRUE;
1456aab59a7Smrg    for (i = 0; miscNames[i]; i++)
1466aab59a7Smrg	if (xf86NameCmp(protocol, miscNames[i]) == 0)
1476aab59a7Smrg	    return TRUE;
1486aab59a7Smrg    return FALSE;
1496aab59a7Smrg}
1506aab59a7Smrg
1516aab59a7Smrgstatic const char *
1526aab59a7SmrgDefaultProtocol(void)
1536aab59a7Smrg{
1546aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1556aab59a7Smrg    return "Auto";
1566aab59a7Smrg#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
1576aab59a7Smrg    return "WSMouse";
1586aab59a7Smrg#else
1596aab59a7Smrg    return NULL;
1606aab59a7Smrg#endif
1616aab59a7Smrg}
1626aab59a7Smrg
1636aab59a7Smrg#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
1646aab59a7Smrgstatic struct {
1656aab59a7Smrg	int dproto;
1666aab59a7Smrg	const char *name;
1676aab59a7Smrg} devproto[] = {
1686aab59a7Smrg	{ MOUSE_PROTO_MS,		"Microsoft" },
1696aab59a7Smrg	{ MOUSE_PROTO_MSC,		"MouseSystems" },
1706aab59a7Smrg	{ MOUSE_PROTO_LOGI,		"Logitech" },
1716aab59a7Smrg	{ MOUSE_PROTO_MM,		"MMSeries" },
1726aab59a7Smrg	{ MOUSE_PROTO_LOGIMOUSEMAN,	"MouseMan" },
1736aab59a7Smrg	{ MOUSE_PROTO_BUS,		"BusMouse" },
1746aab59a7Smrg	{ MOUSE_PROTO_INPORT,		"BusMouse" },
1756aab59a7Smrg	{ MOUSE_PROTO_PS2,		"PS/2" },
1766aab59a7Smrg	{ MOUSE_PROTO_HITTAB,		"MMHitTab" },
1776aab59a7Smrg	{ MOUSE_PROTO_GLIDEPOINT,	"GlidePoint" },
1786aab59a7Smrg	{ MOUSE_PROTO_INTELLI,		"Intellimouse" },
1796aab59a7Smrg	{ MOUSE_PROTO_THINK,		"ThinkingMouse" },
1806aab59a7Smrg	{ MOUSE_PROTO_SYSMOUSE,		"SysMouse" }
1816aab59a7Smrg};
1826aab59a7Smrg
1836aab59a7Smrgstatic const char *
1846aab59a7SmrgSetupAuto(InputInfoPtr pInfo, int *protoPara)
1856aab59a7Smrg{
1866aab59a7Smrg    int i;
1876aab59a7Smrg    mousehw_t hw;
1886aab59a7Smrg    mousemode_t mode;
1896aab59a7Smrg
1906aab59a7Smrg    if (pInfo->fd == -1)
1916aab59a7Smrg	return NULL;
1926aab59a7Smrg
1936aab59a7Smrg    /* set the driver operation level, if applicable */
1946aab59a7Smrg    i = 1;
1956aab59a7Smrg    ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
1966aab59a7Smrg
1976aab59a7Smrg    /* interrogate the driver and get some intelligence on the device. */
1986aab59a7Smrg    hw.iftype = MOUSE_IF_UNKNOWN;
1996aab59a7Smrg    hw.model = MOUSE_MODEL_GENERIC;
2006aab59a7Smrg    ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw);
2016aab59a7Smrg    xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n",
2026aab59a7Smrg		pInfo->name, hw.iftype, hw.model);
2036aab59a7Smrg    if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) {
2046aab59a7Smrg	for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) {
2056aab59a7Smrg	    if (mode.protocol == devproto[i].dproto) {
2066aab59a7Smrg		/* override some parameters */
2076aab59a7Smrg		if (protoPara) {
2086aab59a7Smrg		    protoPara[4] = mode.packetsize;
2096aab59a7Smrg		    protoPara[0] = mode.syncmask[0];
2106aab59a7Smrg		    protoPara[1] = mode.syncmask[1];
2116aab59a7Smrg		}
2126aab59a7Smrg		xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
2136aab59a7Smrg			    pInfo->name, devproto[i].name);
2146aab59a7Smrg		return devproto[i].name;
2156aab59a7Smrg	    }
2166aab59a7Smrg	}
2176aab59a7Smrg    }
2186aab59a7Smrg    return NULL;
2196aab59a7Smrg}
2206aab59a7Smrg
2216aab59a7Smrgstatic void
2226aab59a7SmrgSetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res)
2236aab59a7Smrg{
2246aab59a7Smrg    mousemode_t mode;
2256aab59a7Smrg    MouseDevPtr pMse;
2266aab59a7Smrg
2276aab59a7Smrg    pMse = pInfo->private;
2286aab59a7Smrg
2296aab59a7Smrg    mode.rate = rate > 0 ? rate : -1;
2306aab59a7Smrg    mode.resolution = res > 0 ? res : -1;
2316aab59a7Smrg    mode.accelfactor = -1;
2326aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
2336aab59a7Smrg    if (pMse->autoProbe ||
2346aab59a7Smrg	(protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
2356aab59a7Smrg	/*
2366aab59a7Smrg	 * As the FreeBSD sysmouse driver defaults to protocol level 0
2376aab59a7Smrg	 * everytime it is opened we enforce protocol level 1 again at
2386aab59a7Smrg	 * this point.
2396aab59a7Smrg	 */
2406aab59a7Smrg	mode.level = 1;
2416aab59a7Smrg    } else
2426aab59a7Smrg	mode.level = -1;
2436aab59a7Smrg#else
2446aab59a7Smrg    mode.level = -1;
2456aab59a7Smrg#endif
2466aab59a7Smrg    ioctl(pInfo->fd, MOUSE_SETMODE, &mode);
2476aab59a7Smrg}
2486aab59a7Smrg#endif
2496aab59a7Smrg
2506aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
2516aab59a7Smrg
2526aab59a7Smrg#define MOUSED_PID_FILE "/var/run/moused.pid"
2536aab59a7Smrg
2546aab59a7Smrg/*
2556aab59a7Smrg * Try to check if moused is running.  DEFAULT_SYSMOUSE_DEV is useless without
2566aab59a7Smrg * it.  There doesn't seem to be a better way of checking.
2576aab59a7Smrg */
2586aab59a7Smrgstatic Bool
2596aab59a7SmrgMousedRunning(void)
2606aab59a7Smrg{
2616aab59a7Smrg    FILE *f = NULL;
2626aab59a7Smrg    unsigned int pid;
2636aab59a7Smrg
2646aab59a7Smrg    if ((f = fopen(MOUSED_PID_FILE, "r")) != NULL) {
2656aab59a7Smrg	if (fscanf(f, "%u", &pid) == 1 && pid > 0) {
2666aab59a7Smrg	    if (kill(pid, 0) == 0) {
2676aab59a7Smrg		fclose(f);
2686aab59a7Smrg		return TRUE;
2696aab59a7Smrg	    }
2706aab59a7Smrg	}
2716aab59a7Smrg	fclose(f);
2726aab59a7Smrg    }
2736aab59a7Smrg    return FALSE;
2746aab59a7Smrg}
2756aab59a7Smrg
2766aab59a7Smrgstatic const char *
2776aab59a7SmrgFindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
2786aab59a7Smrg{
2796aab59a7Smrg    int fd = -1;
2806aab59a7Smrg    const char **pdev, *dev = NULL;
2816aab59a7Smrg    Bool devMouse = FALSE;
2826aab59a7Smrg    struct stat devMouseStat;
2836aab59a7Smrg    struct stat sb;
2846aab59a7Smrg
2856aab59a7Smrg    for (pdev = mouseDevs; *pdev; pdev++) {
2866aab59a7Smrg	SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK));
2876aab59a7Smrg	if (fd == -1) {
2886aab59a7Smrg#ifdef DEBUG
2896aab59a7Smrg	    ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno));
2906aab59a7Smrg#endif
2916aab59a7Smrg	} else {
2926aab59a7Smrg	    /*
2936aab59a7Smrg	     * /dev/mouse is held until checks for matches with other devices
2946aab59a7Smrg	     * are done.  This is so that when it points to /dev/sysmouse,
2956aab59a7Smrg	     * the test for whether /dev/sysmouse is usable can be made.
2966aab59a7Smrg	     */
2976aab59a7Smrg	    if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) {
2986aab59a7Smrg		if (fstat(fd, &devMouseStat) == 0)
2996aab59a7Smrg		    devMouse = TRUE;
3006aab59a7Smrg		close(fd);
3016aab59a7Smrg		continue;
3026aab59a7Smrg	    } else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) {
3036aab59a7Smrg		/* Check if /dev/mouse is the same as /dev/sysmouse. */
3046aab59a7Smrg		if (devMouse && fstat(fd, &sb) == 0 &&
3056aab59a7Smrg		    devMouseStat.st_dev == sb.st_dev &&
3066aab59a7Smrg		    devMouseStat.st_ino == sb.st_ino) {
3076aab59a7Smrg		    /* If the same, use /dev/sysmouse. */
3086aab59a7Smrg		    devMouse = FALSE;
3096aab59a7Smrg		}
3106aab59a7Smrg		close(fd);
3116aab59a7Smrg		if (MousedRunning())
3126aab59a7Smrg		    break;
3136aab59a7Smrg		else {
3146aab59a7Smrg#ifdef DEBUG
3156aab59a7Smrg	    	    ErrorF("moused isn't running\n");
3166aab59a7Smrg#endif
3176aab59a7Smrg		}
3186aab59a7Smrg	    } else {
3196aab59a7Smrg		close(fd);
3206aab59a7Smrg		break;
3216aab59a7Smrg	    }
3226aab59a7Smrg	}
3236aab59a7Smrg    }
3246aab59a7Smrg
3256aab59a7Smrg    if (*pdev)
3266aab59a7Smrg	dev = *pdev;
3276aab59a7Smrg    else if (devMouse)
3286aab59a7Smrg	dev = DEFAULT_MOUSE_DEV;
3296aab59a7Smrg
3306aab59a7Smrg    if (dev) {
3316aab59a7Smrg	/* Set the Device option. */
332bd3a1963Smrg	pInfo->options =
333bd3a1963Smrg	    xf86AddNewOption(pInfo->options, "Device", dev);
3346aab59a7Smrg	xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n",
3356aab59a7Smrg		pInfo->name, dev);
3366aab59a7Smrg    }
3376aab59a7Smrg
3386aab59a7Smrg    return *pdev;
3396aab59a7Smrg}
3406aab59a7Smrg#endif
3416aab59a7Smrg
3426aab59a7Smrg#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
3436aab59a7Smrg
3446aab59a7Smrg/* Only support wsmouse configuration for now */
3456aab59a7Smrgstatic const char *
3466aab59a7SmrgSetupAuto(InputInfoPtr pInfo, int *protoPara)
3476aab59a7Smrg{
3486aab59a7Smrg
3496aab59a7Smrg    xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
3506aab59a7Smrg		pInfo->name, "wsmouse");
3516aab59a7Smrg    return "wsmouse";
3526aab59a7Smrg}
3536aab59a7Smrg
3546aab59a7Smrgstatic void
3556aab59a7SmrgSetMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res)
3566aab59a7Smrg{
3576aab59a7Smrg
3586aab59a7Smrg    xf86MsgVerb(X_INFO, 3, "%s: SetMouseRes: protocol %s rate %d res %d\n",
3596aab59a7Smrg	    pInfo->name, protocol, rate, res);
3606aab59a7Smrg}
3616aab59a7Smrg
3626aab59a7Smrgstatic const char *
3636aab59a7SmrgFindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
3646aab59a7Smrg{
3656aab59a7Smrg    int fd = -1;
3666aab59a7Smrg    const char **pdev;
3676aab59a7Smrg
3686aab59a7Smrg    for (pdev = mouseDevs; *pdev; pdev++) {
3696aab59a7Smrg	SYSCALL(fd = open(*pdev, O_RDWR | O_NONBLOCK));
3706aab59a7Smrg	if (fd != -1) {
3716aab59a7Smrg	    /* Set the Device option. */
372bd3a1963Smrg	    pInfo->options =
373bd3a1963Smrg		xf86AddNewOption(pInfo->options,
3746aab59a7Smrg				 "Device", *pdev);
3756aab59a7Smrg	    xf86Msg(X_INFO, "%s: found Device \"%s\"\n",
3766aab59a7Smrg		    pInfo->name, *pdev);
3776aab59a7Smrg	    close(fd);
3786aab59a7Smrg	    break;
3796aab59a7Smrg	}
3806aab59a7Smrg    }
3816aab59a7Smrg    return *pdev;
3826aab59a7Smrg}
3836aab59a7Smrg#endif /* __OpenBSD__ || __NetBSD__ && WSCONS_SUPPORT */
3846aab59a7Smrg
3856aab59a7Smrg#ifdef WSCONS_SUPPORT
3866aab59a7Smrg#define NUMEVENTS 64
3876aab59a7Smrg
3886aab59a7Smrgstatic void
3896aab59a7SmrgwsconsReadInput(InputInfoPtr pInfo)
3906aab59a7Smrg{
3916aab59a7Smrg    MouseDevPtr pMse;
3926aab59a7Smrg    static struct wscons_event eventList[NUMEVENTS];
3936aab59a7Smrg    int n, c;
3946aab59a7Smrg    struct wscons_event *event = eventList;
3956aab59a7Smrg    unsigned char *pBuf;
3966aab59a7Smrg
3976aab59a7Smrg    pMse = pInfo->private;
3986aab59a7Smrg
3996aab59a7Smrg    XisbBlockDuration(pMse->buffer, -1);
4006aab59a7Smrg    pBuf = (unsigned char *)eventList;
4016aab59a7Smrg    n = 0;
4026aab59a7Smrg    while (n < sizeof(eventList) && (c = XisbRead(pMse->buffer)) >= 0) {
4036aab59a7Smrg	pBuf[n++] = (unsigned char)c;
4046aab59a7Smrg    }
4056aab59a7Smrg
4066aab59a7Smrg    if (n == 0)
4076aab59a7Smrg	return;
4086aab59a7Smrg
4096aab59a7Smrg    n /= sizeof(struct wscons_event);
4106aab59a7Smrg    while( n-- ) {
4116aab59a7Smrg	int buttons = pMse->lastButtons;
412f3d19aa6Schristos	int dx = 0, dy = 0, dz = 0, dw = 0, x, y;
4136aab59a7Smrg	switch (event->type) {
4146aab59a7Smrg	case WSCONS_EVENT_MOUSE_UP:
4156aab59a7Smrg#define BUTBIT (1 << (event->value <= 2 ? 2 - event->value : event->value))
4166aab59a7Smrg	    buttons &= ~BUTBIT;
4176aab59a7Smrg	    break;
4186aab59a7Smrg	case WSCONS_EVENT_MOUSE_DOWN:
4196aab59a7Smrg	    buttons |= BUTBIT;
4206aab59a7Smrg	    break;
4216aab59a7Smrg	case WSCONS_EVENT_MOUSE_DELTA_X:
4226aab59a7Smrg	    dx = event->value;
4236aab59a7Smrg	    break;
4246aab59a7Smrg	case WSCONS_EVENT_MOUSE_DELTA_Y:
4256aab59a7Smrg	    dy = -event->value;
4266aab59a7Smrg	    break;
4276aab59a7Smrg#ifdef WSCONS_EVENT_MOUSE_DELTA_Z
4286aab59a7Smrg	case WSCONS_EVENT_MOUSE_DELTA_Z:
4296aab59a7Smrg	    dz = event->value;
4306aab59a7Smrg	    break;
4316aab59a7Smrg#endif
4326aab59a7Smrg#ifdef WSCONS_EVENT_MOUSE_DELTA_W
4336aab59a7Smrg	case WSCONS_EVENT_MOUSE_DELTA_W:
4346aab59a7Smrg	    dw = event->value;
4356aab59a7Smrg	    break;
436f3d19aa6Schristos#endif
437f3d19aa6Schristos	case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
438f3d19aa6Schristos	    miPointerGetPosition (pInfo->dev, &x, &y);
439f3d19aa6Schristos	    x = event->value;
440f3d19aa6Schristos	    miPointerSetPosition (pInfo->dev, &x, &y);
441f3d19aa6Schristos	    xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, x, y);
442f3d19aa6Schristos	    ++event;
443f3d19aa6Schristos	    continue;
444f3d19aa6Schristos	case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
445f3d19aa6Schristos	    miPointerGetPosition (pInfo->dev, &x, &y);
446f3d19aa6Schristos	    y = event->value;
447f3d19aa6Schristos	    miPointerSetPosition (pInfo->dev, &x, &y);
448f3d19aa6Schristos	    xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, x, y);
449f3d19aa6Schristos	    ++event;
450f3d19aa6Schristos	    continue;
451f3d19aa6Schristos#ifdef WSCONS_EVENT_MOUSE_ABSOLUTE_Z
452f3d19aa6Schristos	case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
453f3d19aa6Schristos	    ++event;
454f3d19aa6Schristos	    continue;
455f3d19aa6Schristos#endif
456f3d19aa6Schristos#ifdef WSCONS_EVENT_MOUSE_ABSOLUTE_W
457f3d19aa6Schristos	case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
458f3d19aa6Schristos	    ++event;
459f3d19aa6Schristos	    continue;
4606aab59a7Smrg#endif
4616aab59a7Smrg	default:
4626aab59a7Smrg	    xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n", pInfo->name,
4636aab59a7Smrg		    event->type);
4646aab59a7Smrg	    ++event;
4656aab59a7Smrg	    continue;
4666aab59a7Smrg	}
4676aab59a7Smrg
4686aab59a7Smrg	pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
4696aab59a7Smrg	++event;
4706aab59a7Smrg    }
4716aab59a7Smrg    return;
4726aab59a7Smrg}
4736aab59a7Smrg
4746aab59a7Smrg
4756aab59a7Smrg/* This function is called when the protocol is "wsmouse". */
4766aab59a7Smrgstatic Bool
4776aab59a7SmrgwsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
4786aab59a7Smrg{
4796aab59a7Smrg    MouseDevPtr pMse = pInfo->private;
4806aab59a7Smrg
4816aab59a7Smrg    /* Setup the local input proc. */
4826aab59a7Smrg    pInfo->read_input = wsconsReadInput;
4836aab59a7Smrg    pMse->xisbscale = sizeof(struct wscons_event);
4846aab59a7Smrg
485bd3a1963Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
4866aab59a7Smrg    pInfo->flags |= XI86_CONFIGURED;
487bd3a1963Smrg#endif
4886aab59a7Smrg    return TRUE;
4896aab59a7Smrg}
4906aab59a7Smrg#endif
4916aab59a7Smrg
4926aab59a7Smrg#if defined(USBMOUSE_SUPPORT)
4936aab59a7Smrg
4946aab59a7Smrgtypedef struct _UsbMseRec {
4956aab59a7Smrg    int packetSize;
4966aab59a7Smrg    int iid;
4976aab59a7Smrg    hid_item_t loc_x;		/* x locator item */
4986aab59a7Smrg    hid_item_t loc_y;		/* y locator item */
4996aab59a7Smrg    hid_item_t loc_z;		/* z (wheel) locator item */
5006aab59a7Smrg    hid_item_t loc_w;		/* z (wheel) locator item */
5016aab59a7Smrg    hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
5026aab59a7Smrg   unsigned char *buffer;
5036aab59a7Smrg} UsbMseRec, *UsbMsePtr;
5046aab59a7Smrg
5056aab59a7Smrgstatic int
5066aab59a7SmrgusbMouseProc(DeviceIntPtr pPointer, int what)
5076aab59a7Smrg{
5086aab59a7Smrg    InputInfoPtr pInfo;
5096aab59a7Smrg    MouseDevPtr pMse;
5106aab59a7Smrg    UsbMsePtr pUsbMse;
5116aab59a7Smrg    unsigned char map[MSE_MAXBUTTONS + 1];
5126aab59a7Smrg    int nbuttons;
5136aab59a7Smrg
5146aab59a7Smrg    pInfo = pPointer->public.devicePrivate;
5156aab59a7Smrg    pMse = pInfo->private;
5166aab59a7Smrg    pMse->device = pPointer;
5176aab59a7Smrg    pUsbMse = pMse->mousePriv;
5186aab59a7Smrg
5196aab59a7Smrg    switch (what) {
5206aab59a7Smrg    case DEVICE_INIT:
5216aab59a7Smrg	pPointer->public.on = FALSE;
5226aab59a7Smrg
5236aab59a7Smrg	for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
5246aab59a7Smrg	    map[nbuttons + 1] = nbuttons + 1;
5256aab59a7Smrg
5266aab59a7Smrg	InitPointerDeviceStruct((DevicePtr)pPointer,
5276aab59a7Smrg				map,
5286aab59a7Smrg				min(pMse->buttons, MSE_MAXBUTTONS),
5296aab59a7Smrg				miPointerGetMotionEvents,
5306aab59a7Smrg				pMse->Ctrl,
5316aab59a7Smrg				miPointerGetMotionBufferSize());
5326aab59a7Smrg
5336aab59a7Smrg	/* X valuator */
5346aab59a7Smrg	xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
5356aab59a7Smrg	xf86InitValuatorDefaults(pPointer, 0);
5366aab59a7Smrg	/* Y valuator */
5376aab59a7Smrg	xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
5386aab59a7Smrg	xf86InitValuatorDefaults(pPointer, 1);
5396aab59a7Smrg	xf86MotionHistoryAllocate(pInfo);
5406aab59a7Smrg	break;
5416aab59a7Smrg
5426aab59a7Smrg    case DEVICE_ON:
5436aab59a7Smrg	pInfo->fd = xf86OpenSerial(pInfo->options);
5446aab59a7Smrg	if (pInfo->fd == -1)
5456aab59a7Smrg	    xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
5466aab59a7Smrg	else {
5476aab59a7Smrg	    pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize);
5486aab59a7Smrg	    if (!pMse->buffer) {
549bd3a1963Smrg		free(pMse);
5506aab59a7Smrg		xf86CloseSerial(pInfo->fd);
5516aab59a7Smrg		pInfo->fd = -1;
5526aab59a7Smrg	    } else {
5536aab59a7Smrg		xf86FlushInput(pInfo->fd);
5546aab59a7Smrg		if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput,
5556aab59a7Smrg					      pInfo))
5566aab59a7Smrg		    AddEnabledDevice(pInfo->fd);
5576aab59a7Smrg	    }
5586aab59a7Smrg	}
5596aab59a7Smrg	pMse->lastButtons = 0;
5606aab59a7Smrg	pMse->lastMappedButtons = 0;
5616aab59a7Smrg	pMse->emulateState = 0;
5626aab59a7Smrg	pPointer->public.on = TRUE;
5636aab59a7Smrg	break;
5646aab59a7Smrg
5656aab59a7Smrg    case DEVICE_OFF:
5666aab59a7Smrg    case DEVICE_CLOSE:
5676aab59a7Smrg	if (pInfo->fd != -1) {
5686aab59a7Smrg	    RemoveEnabledDevice(pInfo->fd);
5696aab59a7Smrg	    if (pUsbMse->packetSize > 8 && pUsbMse->buffer) {
570bd3a1963Smrg		free(pUsbMse->buffer);
5716aab59a7Smrg	    }
5726aab59a7Smrg	    if (pMse->buffer) {
5736aab59a7Smrg		XisbFree(pMse->buffer);
5746aab59a7Smrg		pMse->buffer = NULL;
5756aab59a7Smrg	    }
5766aab59a7Smrg	    xf86CloseSerial(pInfo->fd);
5776aab59a7Smrg	    pInfo->fd = -1;
5786aab59a7Smrg	}
5796aab59a7Smrg	pPointer->public.on = FALSE;
5806aab59a7Smrg	usleep(300000);
5816aab59a7Smrg	break;
5826aab59a7Smrg    }
5836aab59a7Smrg    return Success;
5846aab59a7Smrg}
5856aab59a7Smrg
5866aab59a7Smrgstatic void
5876aab59a7SmrgusbReadInput(InputInfoPtr pInfo)
5886aab59a7Smrg{
5896aab59a7Smrg    MouseDevPtr pMse;
5906aab59a7Smrg    UsbMsePtr pUsbMse;
5916aab59a7Smrg    int buttons = pMse->lastButtons;
5926aab59a7Smrg    int dx = 0, dy = 0, dz = 0, dw = 0;
5936aab59a7Smrg    int n, c;
5946aab59a7Smrg    unsigned char *pBuf;
5956aab59a7Smrg
5966aab59a7Smrg    pMse = pInfo->private;
5976aab59a7Smrg    pUsbMse = pMse->mousePriv;
5986aab59a7Smrg
5996aab59a7Smrg    XisbBlockDuration(pMse->buffer, -1);
6006aab59a7Smrg    pBuf = pUsbMse->buffer;
6016aab59a7Smrg    n = 0;
6026aab59a7Smrg    while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) {
6036aab59a7Smrg	pBuf[n++] = (unsigned char)c;
6046aab59a7Smrg    }
6056aab59a7Smrg    if (n == 0)
6066aab59a7Smrg	return;
6076aab59a7Smrg    if (n != pUsbMse->packetSize) {
6086aab59a7Smrg	xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", pInfo->name,
6096aab59a7Smrg		n);
6106aab59a7Smrg    }
6116aab59a7Smrg    /* discard packets with an id that don't match the mouse */
6126aab59a7Smrg    /* XXX this is probably not the right thing */
6136aab59a7Smrg    if (pUsbMse->iid != 0) {
6146aab59a7Smrg	if (*pBuf++ != pUsbMse->iid)
6156aab59a7Smrg	    return;
6166aab59a7Smrg    }
6176aab59a7Smrg    dx = hid_get_data(pBuf, &pUsbMse->loc_x);
6186aab59a7Smrg    dy = hid_get_data(pBuf, &pUsbMse->loc_y);
6196aab59a7Smrg    dz = hid_get_data(pBuf, &pUsbMse->loc_z);
6206aab59a7Smrg    dw = hid_get_data(pBuf, &pUsbMse->loc_w);
6216aab59a7Smrg
6226aab59a7Smrg    buttons = 0;
6236aab59a7Smrg    for (n = 0; n < pMse->buttons; n++) {
6246aab59a7Smrg	if (hid_get_data(pBuf, &pUsbMse->loc_btn[n]))
6256aab59a7Smrg	    buttons |= (1 << UMS_BUT(n));
6266aab59a7Smrg    }
6276aab59a7Smrg    pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
6286aab59a7Smrg    return;
6296aab59a7Smrg}
6306aab59a7Smrg
6316aab59a7Smrgstatic void
6326aab59a7SmrgusbSigioReadInput (int fd, void *closure)
6336aab59a7Smrg{
6346aab59a7Smrg    usbReadInput ((InputInfoPtr) closure);
6356aab59a7Smrg}
6366aab59a7Smrg
6376aab59a7Smrg/* This function is called when the protocol is "usb". */
6386aab59a7Smrgstatic Bool
6396aab59a7SmrgusbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
6406aab59a7Smrg{
6416aab59a7Smrg    MouseDevPtr pMse = pInfo->private;
6426aab59a7Smrg    UsbMsePtr pUsbMse;
6436aab59a7Smrg    report_desc_t reportDesc;
6446aab59a7Smrg    int i;
6456aab59a7Smrg
646bd3a1963Smrg    pUsbMse = malloc(sizeof(UsbMseRec));
6476aab59a7Smrg    if (pUsbMse == NULL) {
6486aab59a7Smrg	xf86Msg(X_ERROR, "%s: cannot allocate UsbMouseRec\n", pInfo->name);
649bd3a1963Smrg	free(pMse);
6506aab59a7Smrg	return FALSE;
6516aab59a7Smrg    }
6526aab59a7Smrg
6536aab59a7Smrg    pMse->protocol = protocol;
6546aab59a7Smrg    xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
6556aab59a7Smrg
6566aab59a7Smrg    /* Collect the options, and process the common options. */
657bd3a1963Smrg    COLLECT_INPUT_OPTIONS(pInfo, NULL);
6586aab59a7Smrg    xf86ProcessCommonOptions(pInfo, pInfo->options);
6596aab59a7Smrg
6606aab59a7Smrg    /* Check if the device can be opened. */
6616aab59a7Smrg    pInfo->fd = xf86OpenSerial(pInfo->options);
6626aab59a7Smrg    if (pInfo->fd == -1) {
6636aab59a7Smrg	if (xf86GetAllowMouseOpenFail())
6646aab59a7Smrg	    xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
6656aab59a7Smrg	else {
6666aab59a7Smrg	    xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
667bd3a1963Smrg	    free(pUsbMse);
668bd3a1963Smrg	    free(pMse);
6696aab59a7Smrg	    return FALSE;
6706aab59a7Smrg	}
6716aab59a7Smrg    }
6726aab59a7Smrg    /* Get USB informations */
6736aab59a7Smrg    reportDesc = hid_get_report_desc(pInfo->fd);
6746aab59a7Smrg    /* Get packet size & iid */
6756aab59a7Smrg#ifdef USB_NEW_HID
6766aab59a7Smrg    if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) {
6776aab59a7Smrg	    xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n",
6786aab59a7Smrg		    pInfo->name, strerror(errno));
6796aab59a7Smrg	    return FALSE;
6806aab59a7Smrg    }
6816aab59a7Smrg    pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
6826aab59a7Smrg					      pUsbMse->iid);
6836aab59a7Smrg#else
6846aab59a7Smrg    pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
6856aab59a7Smrg					      &pUsbMse->iid);
6866aab59a7Smrg#endif
6876aab59a7Smrg    /* Allocate buffer */
6886aab59a7Smrg    if (pUsbMse->packetSize <= 8) {
6896aab59a7Smrg	pUsbMse->buffer = pMse->protoBuf;
6906aab59a7Smrg    } else {
691bd3a1963Smrg	pUsbMse->buffer = malloc(pUsbMse->packetSize);
6926aab59a7Smrg    }
6936aab59a7Smrg    if (pUsbMse->buffer == NULL) {
6946aab59a7Smrg	xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
695bd3a1963Smrg	free(pUsbMse);
696bd3a1963Smrg	free(pMse);
6976aab59a7Smrg	xf86CloseSerial(pInfo->fd);
6986aab59a7Smrg	return FALSE;
6996aab59a7Smrg    }
7006aab59a7Smrg#ifdef USB_NEW_HID
7016aab59a7Smrg    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
7026aab59a7Smrg		   hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) {
7036aab59a7Smrg	xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
7046aab59a7Smrg    }
7056aab59a7Smrg    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
7066aab59a7Smrg		   hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) {
7076aab59a7Smrg	xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
7086aab59a7Smrg    }
7096aab59a7Smrg    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
7106aab59a7Smrg		   hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) {
7116aab59a7Smrg    }
7126aab59a7Smrg#else
7136aab59a7Smrg    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
7146aab59a7Smrg		   hid_input, &pUsbMse->loc_x) < 0) {
7156aab59a7Smrg	xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
7166aab59a7Smrg    }
7176aab59a7Smrg    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
7186aab59a7Smrg		   hid_input, &pUsbMse->loc_y) < 0) {
7196aab59a7Smrg	xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
7206aab59a7Smrg    }
7216aab59a7Smrg    if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
7226aab59a7Smrg		   hid_input, &pUsbMse->loc_z) < 0) {
7236aab59a7Smrg    }
7246aab59a7Smrg#endif
7256aab59a7Smrg    /* Probe for number of buttons */
7266aab59a7Smrg    for (i = 1; i <= MSE_MAXBUTTONS; i++) {
7276aab59a7Smrg	if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i),
7286aab59a7Smrg			hid_input, &pUsbMse->loc_btn[i-1]
7296aab59a7Smrg#ifdef USB_NEW_HID
7306aab59a7Smrg			, pUsbMse->iid
7316aab59a7Smrg#endif
7326aab59a7Smrg			))
7336aab59a7Smrg	    break;
7346aab59a7Smrg    }
7356aab59a7Smrg    pMse->buttons = i-1;
7366aab59a7Smrg
7376aab59a7Smrg    xf86CloseSerial(pInfo->fd);
7386aab59a7Smrg    pInfo->fd = -1;
7396aab59a7Smrg
7406aab59a7Smrg    /* Private structure */
7416aab59a7Smrg    pMse->mousePriv = pUsbMse;
7426aab59a7Smrg
7436aab59a7Smrg    /* Process common mouse options (like Emulate3Buttons, etc). */
7446aab59a7Smrg    pMse->CommonOptions(pInfo);
7456aab59a7Smrg
7466aab59a7Smrg    /* Setup the local procs. */
7476aab59a7Smrg    pInfo->device_control = usbMouseProc;
7486aab59a7Smrg    pInfo->read_input = usbReadInput;
7496aab59a7Smrg
750bd3a1963Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
7516aab59a7Smrg    pInfo->flags |= XI86_CONFIGURED;
752bd3a1963Smrg#endif
7536aab59a7Smrg    return TRUE;
7546aab59a7Smrg}
7556aab59a7Smrg#endif /* USBMOUSE */
7566aab59a7Smrg
7576aab59a7Smrgstatic Bool
7586aab59a7SmrgbsdMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
7596aab59a7Smrg{
7606aab59a7Smrg    /* The protocol is guaranteed to be one of the internalNames[] */
7616aab59a7Smrg#ifdef WSCONS_SUPPORT
7626aab59a7Smrg    if (xf86NameCmp(protocol, "WSMouse") == 0) {
7636aab59a7Smrg	return wsconsPreInit(pInfo, protocol, flags);
7646aab59a7Smrg    }
7656aab59a7Smrg#endif
7666aab59a7Smrg#ifdef USBMOUSE_SUPPORT
7676aab59a7Smrg    if (xf86NameCmp(protocol, "usb") == 0) {
7686aab59a7Smrg	return usbPreInit(pInfo, protocol, flags);
7696aab59a7Smrg    }
7706aab59a7Smrg#endif
7716aab59a7Smrg    return TRUE;
7726aab59a7Smrg}
7736aab59a7Smrg
774bd3a1963SmrgOSMouseInfoPtr
775bd3a1963SmrgOSMouseInit(int flags)
7766aab59a7Smrg{
7776aab59a7Smrg    OSMouseInfoPtr p;
7786aab59a7Smrg
779bd3a1963Smrg    p = calloc(sizeof(OSMouseInfoRec), 1);
7806aab59a7Smrg    if (!p)
7816aab59a7Smrg	return NULL;
7826aab59a7Smrg    p->SupportedInterfaces = SupportedInterfaces;
7836aab59a7Smrg    p->BuiltinNames = BuiltinNames;
7846aab59a7Smrg    p->DefaultProtocol = DefaultProtocol;
7856aab59a7Smrg    p->CheckProtocol = CheckProtocol;
7866aab59a7Smrg#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
7876aab59a7Smrg    p->SetupAuto = SetupAuto;
7886aab59a7Smrg    p->SetPS2Res = SetSysMouseRes;
7896aab59a7Smrg    p->SetBMRes = SetSysMouseRes;
7906aab59a7Smrg    p->SetMiscRes = SetSysMouseRes;
7916aab59a7Smrg#endif
7926aab59a7Smrg#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT)
7936aab59a7Smrg    p->SetupAuto = SetupAuto;
7946aab59a7Smrg    p->SetMiscRes = SetMouseRes;
7956aab59a7Smrg#endif
7966aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
7976aab59a7Smrg    p->FindDevice = FindDevice;
7986aab59a7Smrg#endif
7996aab59a7Smrg    p->PreInit = bsdMousePreInit;
8006aab59a7Smrg    return p;
8016aab59a7Smrg}
802