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 644d6d3f96Smrg/* The UMS mice 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 */ 751450c749Smrg#define DEFAULT_MOUSE_DEV "/dev/mouse" 761450c749Smrg#define DEFAULT_SYSMOUSE_DEV "/dev/sysmouse" 771450c749Smrg#define DEFAULT_PS2_DEV "/dev/psm0" 786aab59a7Smrg 796aab59a7Smrgstatic const char *mouseDevs[] = { 801450c749Smrg DEFAULT_MOUSE_DEV, 811450c749Smrg DEFAULT_SYSMOUSE_DEV, 821450c749Smrg DEFAULT_PS2_DEV, 831450c749Smrg NULL 846aab59a7Smrg}; 856aab59a7Smrg#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 864d6d3f96Smrg/* Only wsmouse mice are autoconfigured for now on OpenBSD */ 871450c749Smrg#define DEFAULT_WSMOUSE_DEV "/dev/wsmouse" 881450c749Smrg#define DEFAULT_WSMOUSE0_DEV "/dev/wsmouse0" 896aab59a7Smrg 906aab59a7Smrgstatic const char *mouseDevs[] = { 911450c749Smrg DEFAULT_WSMOUSE_DEV, 921450c749Smrg DEFAULT_WSMOUSE0_DEV, 931450c749Smrg NULL 946aab59a7Smrg}; 956aab59a7Smrg#endif 966aab59a7Smrg 976aab59a7Smrgstatic int 986aab59a7SmrgSupportedInterfaces(void) 996aab59a7Smrg{ 100352aa7aeSmrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__NetBSD__) 1016aab59a7Smrg return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC; 1026aab59a7Smrg#else 103bd3a1963Smrg return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC; 1046aab59a7Smrg#endif 1056aab59a7Smrg} 1066aab59a7Smrg 1076aab59a7Smrg/* Names of protocols that are handled internally here. */ 1086aab59a7Smrgstatic const char *internalNames[] = { 1096aab59a7Smrg#if defined(WSCONS_SUPPORT) 1101450c749Smrg "WSMouse", 1116aab59a7Smrg#endif 1126aab59a7Smrg#if defined(USBMOUSE_SUPPORT) 1131450c749Smrg "usb", 1146aab59a7Smrg#endif 1151450c749Smrg NULL 1166aab59a7Smrg}; 1176aab59a7Smrg 1186aab59a7Smrg/* 1196aab59a7Smrg * Names of MSC_MISC protocols that the OS supports. These are decoded by 1206aab59a7Smrg * main "mouse" driver. 1216aab59a7Smrg */ 1226aab59a7Smrgstatic const char *miscNames[] = { 1236aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 1241450c749Smrg "SysMouse", 1256aab59a7Smrg#endif 1261450c749Smrg NULL 1276aab59a7Smrg}; 1286aab59a7Smrg 1296aab59a7Smrgstatic const char ** 1306aab59a7SmrgBuiltinNames(void) 1316aab59a7Smrg{ 1326aab59a7Smrg return internalNames; 1336aab59a7Smrg} 1346aab59a7Smrg 1356aab59a7Smrgstatic Bool 1366aab59a7SmrgCheckProtocol(const char *protocol) 1376aab59a7Smrg{ 1386aab59a7Smrg int i; 1396aab59a7Smrg 1406aab59a7Smrg for (i = 0; internalNames[i]; i++) 1411450c749Smrg if (xf86NameCmp(protocol, internalNames[i]) == 0) 1421450c749Smrg return TRUE; 1436aab59a7Smrg for (i = 0; miscNames[i]; i++) 1441450c749Smrg if (xf86NameCmp(protocol, miscNames[i]) == 0) 1451450c749Smrg return TRUE; 1466aab59a7Smrg return FALSE; 1476aab59a7Smrg} 1486aab59a7Smrg 1496aab59a7Smrgstatic const char * 1506aab59a7SmrgDefaultProtocol(void) 1516aab59a7Smrg{ 1526aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 1536aab59a7Smrg return "Auto"; 1546aab59a7Smrg#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 1556aab59a7Smrg return "WSMouse"; 1566aab59a7Smrg#else 1576aab59a7Smrg return NULL; 1586aab59a7Smrg#endif 1596aab59a7Smrg} 1606aab59a7Smrg 1616aab59a7Smrg#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE) 1626aab59a7Smrgstatic struct { 1631450c749Smrg int dproto; 1641450c749Smrg const char *name; 1656aab59a7Smrg} devproto[] = { 1661450c749Smrg { MOUSE_PROTO_MS, "Microsoft" }, 1671450c749Smrg { MOUSE_PROTO_MSC, "MouseSystems" }, 1681450c749Smrg { MOUSE_PROTO_LOGI, "Logitech" }, 1691450c749Smrg { MOUSE_PROTO_MM, "MMSeries" }, 1701450c749Smrg { MOUSE_PROTO_LOGIMOUSEMAN, "MouseMan" }, 1711450c749Smrg { MOUSE_PROTO_BUS, "BusMouse" }, 1721450c749Smrg { MOUSE_PROTO_INPORT, "BusMouse" }, 1731450c749Smrg { MOUSE_PROTO_PS2, "PS/2" }, 1741450c749Smrg { MOUSE_PROTO_HITTAB, "MMHitTab" }, 1751450c749Smrg { MOUSE_PROTO_GLIDEPOINT, "GlidePoint" }, 1761450c749Smrg { MOUSE_PROTO_INTELLI, "Intellimouse" }, 1771450c749Smrg { MOUSE_PROTO_THINK, "ThinkingMouse" }, 1781450c749Smrg { MOUSE_PROTO_SYSMOUSE, "SysMouse" } 1796aab59a7Smrg}; 1801450c749Smrg 1816aab59a7Smrgstatic const char * 1826aab59a7SmrgSetupAuto(InputInfoPtr pInfo, int *protoPara) 1836aab59a7Smrg{ 1846aab59a7Smrg int i; 1856aab59a7Smrg mousehw_t hw; 1866aab59a7Smrg mousemode_t mode; 1876aab59a7Smrg 1886aab59a7Smrg if (pInfo->fd == -1) 1891450c749Smrg return NULL; 1906aab59a7Smrg 1916aab59a7Smrg /* set the driver operation level, if applicable */ 1926aab59a7Smrg i = 1; 1936aab59a7Smrg ioctl(pInfo->fd, MOUSE_SETLEVEL, &i); 1941450c749Smrg 1956aab59a7Smrg /* interrogate the driver and get some intelligence on the device. */ 1966aab59a7Smrg hw.iftype = MOUSE_IF_UNKNOWN; 1976aab59a7Smrg hw.model = MOUSE_MODEL_GENERIC; 1986aab59a7Smrg ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw); 1996aab59a7Smrg xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n", 2001450c749Smrg pInfo->name, hw.iftype, hw.model); 2016aab59a7Smrg if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) { 2021450c749Smrg for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) { 2031450c749Smrg if (mode.protocol == devproto[i].dproto) { 2041450c749Smrg /* override some parameters */ 2051450c749Smrg if (protoPara) { 2061450c749Smrg protoPara[4] = mode.packetsize; 2071450c749Smrg protoPara[0] = mode.syncmask[0]; 2081450c749Smrg protoPara[1] = mode.syncmask[1]; 2091450c749Smrg } 2101450c749Smrg xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n", 2111450c749Smrg pInfo->name, devproto[i].name); 2121450c749Smrg return devproto[i].name; 2131450c749Smrg } 2141450c749Smrg } 2156aab59a7Smrg } 2166aab59a7Smrg return NULL; 2176aab59a7Smrg} 2186aab59a7Smrg 2196aab59a7Smrgstatic void 2206aab59a7SmrgSetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res) 2216aab59a7Smrg{ 2226aab59a7Smrg mousemode_t mode; 2236aab59a7Smrg MouseDevPtr pMse; 2246aab59a7Smrg 2256aab59a7Smrg pMse = pInfo->private; 2266aab59a7Smrg 2276aab59a7Smrg mode.rate = rate > 0 ? rate : -1; 2286aab59a7Smrg mode.resolution = res > 0 ? res : -1; 2296aab59a7Smrg mode.accelfactor = -1; 2306aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 2316aab59a7Smrg if (pMse->autoProbe || 2321450c749Smrg (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) { 2331450c749Smrg /* 2341450c749Smrg * As the FreeBSD sysmouse driver defaults to protocol level 0 2354d6d3f96Smrg * every time it is opened we enforce protocol level 1 again at 2361450c749Smrg * this point. 2371450c749Smrg */ 2381450c749Smrg mode.level = 1; 2396aab59a7Smrg } else 2401450c749Smrg mode.level = -1; 2416aab59a7Smrg#else 2426aab59a7Smrg mode.level = -1; 2436aab59a7Smrg#endif 2446aab59a7Smrg ioctl(pInfo->fd, MOUSE_SETMODE, &mode); 2456aab59a7Smrg} 2466aab59a7Smrg#endif 2476aab59a7Smrg 2486aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 2496aab59a7Smrg 2506aab59a7Smrg#define MOUSED_PID_FILE "/var/run/moused.pid" 2516aab59a7Smrg 2526aab59a7Smrg/* 2536aab59a7Smrg * Try to check if moused is running. DEFAULT_SYSMOUSE_DEV is useless without 2546aab59a7Smrg * it. There doesn't seem to be a better way of checking. 2556aab59a7Smrg */ 2566aab59a7Smrgstatic Bool 2576aab59a7SmrgMousedRunning(void) 2586aab59a7Smrg{ 2596aab59a7Smrg FILE *f = NULL; 2606aab59a7Smrg unsigned int pid; 2616aab59a7Smrg 2626aab59a7Smrg if ((f = fopen(MOUSED_PID_FILE, "r")) != NULL) { 2631450c749Smrg if (fscanf(f, "%u", &pid) == 1 && pid > 0) { 2641450c749Smrg if (kill(pid, 0) == 0) { 2651450c749Smrg fclose(f); 2661450c749Smrg return TRUE; 2671450c749Smrg } 2681450c749Smrg } 2691450c749Smrg fclose(f); 2706aab59a7Smrg } 2716aab59a7Smrg return FALSE; 2726aab59a7Smrg} 2736aab59a7Smrg 2746aab59a7Smrgstatic const char * 2756aab59a7SmrgFindDevice(InputInfoPtr pInfo, const char *protocol, int flags) 2766aab59a7Smrg{ 2776aab59a7Smrg int fd = -1; 2786aab59a7Smrg const char **pdev, *dev = NULL; 2796aab59a7Smrg Bool devMouse = FALSE; 2806aab59a7Smrg struct stat devMouseStat; 2816aab59a7Smrg struct stat sb; 2826aab59a7Smrg 2836aab59a7Smrg for (pdev = mouseDevs; *pdev; pdev++) { 2841450c749Smrg SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK)); 2851450c749Smrg if (fd == -1) { 2866aab59a7Smrg#ifdef DEBUG 2871450c749Smrg ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno)); 2886aab59a7Smrg#endif 2891450c749Smrg } else { 2901450c749Smrg /* 2911450c749Smrg * /dev/mouse is held until checks for matches with other devices 2921450c749Smrg * are done. This is so that when it points to /dev/sysmouse, 2931450c749Smrg * the test for whether /dev/sysmouse is usable can be made. 2941450c749Smrg */ 2951450c749Smrg if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) { 2961450c749Smrg if (fstat(fd, &devMouseStat) == 0) 2971450c749Smrg devMouse = TRUE; 2981450c749Smrg close(fd); 2991450c749Smrg continue; 3001450c749Smrg } else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) { 3011450c749Smrg /* Check if /dev/mouse is the same as /dev/sysmouse. */ 3021450c749Smrg if (devMouse && fstat(fd, &sb) == 0 && 3031450c749Smrg devMouseStat.st_dev == sb.st_dev && 3041450c749Smrg devMouseStat.st_ino == sb.st_ino) { 3051450c749Smrg /* If the same, use /dev/sysmouse. */ 3061450c749Smrg devMouse = FALSE; 3071450c749Smrg } 3081450c749Smrg close(fd); 3091450c749Smrg if (MousedRunning()) 3101450c749Smrg break; 3111450c749Smrg else { 3126aab59a7Smrg#ifdef DEBUG 3131450c749Smrg ErrorF("moused isn't running\n"); 3146aab59a7Smrg#endif 3151450c749Smrg } 3161450c749Smrg } else { 3171450c749Smrg close(fd); 3181450c749Smrg break; 3191450c749Smrg } 3201450c749Smrg } 3216aab59a7Smrg } 3226aab59a7Smrg 3236aab59a7Smrg if (*pdev) 3241450c749Smrg dev = *pdev; 3256aab59a7Smrg else if (devMouse) 3261450c749Smrg dev = DEFAULT_MOUSE_DEV; 3276aab59a7Smrg 3286aab59a7Smrg if (dev) { 3291450c749Smrg /* Set the Device option. */ 3301450c749Smrg pInfo->options = 3311450c749Smrg xf86AddNewOption(pInfo->options, "Device", dev); 3321450c749Smrg xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n", 3331450c749Smrg pInfo->name, dev); 3346aab59a7Smrg } 3356aab59a7Smrg 3366aab59a7Smrg return *pdev; 3376aab59a7Smrg} 3386aab59a7Smrg#endif 3396aab59a7Smrg 3406aab59a7Smrg#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 3416aab59a7Smrg 3426aab59a7Smrg/* Only support wsmouse configuration for now */ 3436aab59a7Smrgstatic const char * 3446aab59a7SmrgSetupAuto(InputInfoPtr pInfo, int *protoPara) 3456aab59a7Smrg{ 3466aab59a7Smrg 3476aab59a7Smrg xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n", 3481450c749Smrg pInfo->name, "wsmouse"); 3496aab59a7Smrg return "wsmouse"; 3506aab59a7Smrg} 3516aab59a7Smrg 3526aab59a7Smrgstatic void 3536aab59a7SmrgSetMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res) 3546aab59a7Smrg{ 3556aab59a7Smrg 3566aab59a7Smrg xf86MsgVerb(X_INFO, 3, "%s: SetMouseRes: protocol %s rate %d res %d\n", 3571450c749Smrg pInfo->name, protocol, rate, res); 3586aab59a7Smrg} 3596aab59a7Smrg 3606aab59a7Smrgstatic const char * 3616aab59a7SmrgFindDevice(InputInfoPtr pInfo, const char *protocol, int flags) 3626aab59a7Smrg{ 3636aab59a7Smrg int fd = -1; 3646aab59a7Smrg const char **pdev; 3656aab59a7Smrg 3666aab59a7Smrg for (pdev = mouseDevs; *pdev; pdev++) { 3671450c749Smrg SYSCALL(fd = open(*pdev, O_RDWR | O_NONBLOCK)); 3681450c749Smrg if (fd != -1) { 3691450c749Smrg /* Set the Device option. */ 3701450c749Smrg pInfo->options = 3711450c749Smrg xf86AddNewOption(pInfo->options, 3721450c749Smrg "Device", *pdev); 3731450c749Smrg xf86Msg(X_INFO, "%s: found Device \"%s\"\n", 3741450c749Smrg pInfo->name, *pdev); 3751450c749Smrg close(fd); 3761450c749Smrg break; 3771450c749Smrg } 3786aab59a7Smrg } 3796aab59a7Smrg return *pdev; 3806aab59a7Smrg} 3816aab59a7Smrg#endif /* __OpenBSD__ || __NetBSD__ && WSCONS_SUPPORT */ 3826aab59a7Smrg 3836aab59a7Smrg#ifdef WSCONS_SUPPORT 3846aab59a7Smrg#define NUMEVENTS 64 3856aab59a7Smrg 386216a823bSjmcneillstatic void 387216a823bSjmcneillwsconsAutoCalibrate(InputInfoPtr pInfo) 388216a823bSjmcneill{ 389216a823bSjmcneill MouseDevPtr pMse; 390216a823bSjmcneill int width, height; 391216a823bSjmcneill struct wsmouse_calibcoords cal; 392216a823bSjmcneill 393216a823bSjmcneill pMse = pInfo->private; 394216a823bSjmcneill width = screenInfo.screens[pMse->screenNo]->width; 395216a823bSjmcneill height = screenInfo.screens[pMse->screenNo]->height; 396216a823bSjmcneill 397216a823bSjmcneill if (width != pMse->lastScreenWidth || height != pMse->lastScreenHeight) { 398216a823bSjmcneill if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &cal) == 0 && 399216a823bSjmcneill cal.minx != cal.maxy && cal.miny != cal.maxy) { 400216a823bSjmcneill 401216a823bSjmcneill xf86Msg(X_INFO, "%s: auto-calibrating abs pointer for %dx%d screen\n", 402216a823bSjmcneill pInfo->name, width, height); 403216a823bSjmcneill 404216a823bSjmcneill pMse->minX = cal.minx; 405216a823bSjmcneill pMse->minY = cal.miny; 406216a823bSjmcneill pMse->maxX = cal.maxx; 407216a823bSjmcneill pMse->maxY = cal.maxy; 408216a823bSjmcneill pMse->translateAbs = 409216a823bSjmcneill cal.samplelen == WSMOUSE_CALIBCOORDS_RESET; 410216a823bSjmcneill } 411216a823bSjmcneill pMse->lastScreenWidth = width; 412216a823bSjmcneill pMse->lastScreenHeight = height; 413216a823bSjmcneill } 414216a823bSjmcneill} 415216a823bSjmcneill 416216a823bSjmcneillstatic int 417216a823bSjmcneillwsconsTranslate(InputInfoPtr pInfo, int scrRange, int rawMin, int rawMax, int rawVal) 418216a823bSjmcneill{ 419216a823bSjmcneill return ((rawVal - rawMin) * scrRange) / (rawMax - rawMin); 420216a823bSjmcneill} 421216a823bSjmcneill 4226aab59a7Smrgstatic void 4236aab59a7SmrgwsconsReadInput(InputInfoPtr pInfo) 4246aab59a7Smrg{ 4256aab59a7Smrg MouseDevPtr pMse; 4266aab59a7Smrg static struct wscons_event eventList[NUMEVENTS]; 4271450c749Smrg int n, c; 4286aab59a7Smrg struct wscons_event *event = eventList; 4296aab59a7Smrg unsigned char *pBuf; 4306aab59a7Smrg 4316aab59a7Smrg pMse = pInfo->private; 4326aab59a7Smrg 433216a823bSjmcneill if (pMse->autoCalibrate) 434216a823bSjmcneill wsconsAutoCalibrate(pInfo); 435216a823bSjmcneill 4366aab59a7Smrg XisbBlockDuration(pMse->buffer, -1); 4376aab59a7Smrg pBuf = (unsigned char *)eventList; 4386aab59a7Smrg n = 0; 4396aab59a7Smrg while (n < sizeof(eventList) && (c = XisbRead(pMse->buffer)) >= 0) { 4401450c749Smrg pBuf[n++] = (unsigned char)c; 4416aab59a7Smrg } 4426aab59a7Smrg 4436aab59a7Smrg if (n == 0) 4441450c749Smrg return; 4456aab59a7Smrg 4466aab59a7Smrg n /= sizeof(struct wscons_event); 4476aab59a7Smrg while( n-- ) { 4481450c749Smrg int buttons = pMse->lastButtons; 4491450c749Smrg int dx = 0, dy = 0, dz = 0, dw = 0, x, y; 4501450c749Smrg switch (event->type) { 4511450c749Smrg case WSCONS_EVENT_MOUSE_UP: 4526aab59a7Smrg#define BUTBIT (1 << (event->value <= 2 ? 2 - event->value : event->value)) 4531450c749Smrg buttons &= ~BUTBIT; 4541450c749Smrg break; 4551450c749Smrg case WSCONS_EVENT_MOUSE_DOWN: 4561450c749Smrg buttons |= BUTBIT; 4571450c749Smrg break; 4581450c749Smrg case WSCONS_EVENT_MOUSE_DELTA_X: 4591450c749Smrg dx = event->value; 4601450c749Smrg break; 4611450c749Smrg case WSCONS_EVENT_MOUSE_DELTA_Y: 4621450c749Smrg dy = -event->value; 4631450c749Smrg break; 4646aab59a7Smrg#ifdef WSCONS_EVENT_MOUSE_DELTA_Z 4651450c749Smrg case WSCONS_EVENT_MOUSE_DELTA_Z: 4661450c749Smrg dz = event->value; 4671450c749Smrg break; 4686aab59a7Smrg#endif 4696aab59a7Smrg#ifdef WSCONS_EVENT_MOUSE_DELTA_W 4701450c749Smrg case WSCONS_EVENT_MOUSE_DELTA_W: 4711450c749Smrg dw = event->value; 4721450c749Smrg break; 473f3d19aa6Schristos#endif 474f3d19aa6Schristos case WSCONS_EVENT_MOUSE_ABSOLUTE_X: 475f3d19aa6Schristos x = event->value; 476216a823bSjmcneill if (pMse->translateAbs) 477216a823bSjmcneill x = wsconsTranslate(pInfo, pMse->lastScreenWidth, 478216a823bSjmcneill pMse->minX, pMse->maxX, x); 479352aa7aeSmrg xf86PostMotionEvent(pInfo->dev, TRUE, 0, 1, x); 480f3d19aa6Schristos ++event; 481f3d19aa6Schristos continue; 482f3d19aa6Schristos case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: 483f3d19aa6Schristos y = event->value; 484216a823bSjmcneill if (pMse->translateAbs) 485216a823bSjmcneill y = wsconsTranslate(pInfo, pMse->lastScreenWidth, 486216a823bSjmcneill pMse->minY, pMse->maxY, y); 487352aa7aeSmrg xf86PostMotionEvent(pInfo->dev, TRUE, 1, 1, y); 488f3d19aa6Schristos ++event; 489f3d19aa6Schristos continue; 490f3d19aa6Schristos#ifdef WSCONS_EVENT_MOUSE_ABSOLUTE_Z 491f3d19aa6Schristos case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: 492f3d19aa6Schristos ++event; 493f3d19aa6Schristos continue; 494f3d19aa6Schristos#endif 495f3d19aa6Schristos#ifdef WSCONS_EVENT_MOUSE_ABSOLUTE_W 496f3d19aa6Schristos case WSCONS_EVENT_MOUSE_ABSOLUTE_W: 497f3d19aa6Schristos ++event; 498f3d19aa6Schristos continue; 4996aab59a7Smrg#endif 5001450c749Smrg default: 5011450c749Smrg LogMessageVerbSigSafe(X_WARNING, -1, 5021450c749Smrg "%s: bad wsmouse event type=%d\n", pInfo->name, 5031450c749Smrg event->type); 5041450c749Smrg ++event; 5051450c749Smrg continue; 5061450c749Smrg } 5071450c749Smrg 5081450c749Smrg pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 5091450c749Smrg ++event; 5106aab59a7Smrg } 5116aab59a7Smrg return; 5126aab59a7Smrg} 5136aab59a7Smrg 5146aab59a7Smrg 5156aab59a7Smrg/* This function is called when the protocol is "wsmouse". */ 5166aab59a7Smrgstatic Bool 5176aab59a7SmrgwsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags) 5186aab59a7Smrg{ 5196aab59a7Smrg MouseDevPtr pMse = pInfo->private; 5206aab59a7Smrg 5216aab59a7Smrg /* Setup the local input proc. */ 5226aab59a7Smrg pInfo->read_input = wsconsReadInput; 5236aab59a7Smrg pMse->xisbscale = sizeof(struct wscons_event); 5246aab59a7Smrg 525bd3a1963Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 5266aab59a7Smrg pInfo->flags |= XI86_CONFIGURED; 527bd3a1963Smrg#endif 528216a823bSjmcneill 529216a823bSjmcneill pMse->autoCalibrate = xf86SetBoolOption(pInfo->options, "AutoCalibrate", TRUE); 530216a823bSjmcneill xf86Msg(X_CONFIG, "%s: auto calibration %sabled\n", 531216a823bSjmcneill pInfo->name, pMse->autoCalibrate ? "en" : "dis"); 532216a823bSjmcneill 533216a823bSjmcneill pMse->screenNo = xf86SetIntOption(pInfo->options, "ScreenNo", 0); 534216a823bSjmcneill if (pMse->screenNo >= screenInfo.numScreens || 535216a823bSjmcneill pMse->screenNo < 0) { 536216a823bSjmcneill pMse->screenNo = 0; 537216a823bSjmcneill } 538216a823bSjmcneill xf86Msg(X_CONFIG, "%s: associated screen: %d\n", 539216a823bSjmcneill pInfo->name, pMse->screenNo); 540216a823bSjmcneill 5416aab59a7Smrg return TRUE; 5426aab59a7Smrg} 5436aab59a7Smrg#endif 5446aab59a7Smrg 5456aab59a7Smrg#if defined(USBMOUSE_SUPPORT) 5466aab59a7Smrg 5476aab59a7Smrgtypedef struct _UsbMseRec { 5486aab59a7Smrg int packetSize; 5496aab59a7Smrg int iid; 5501450c749Smrg hid_item_t loc_x; /* x locator item */ 5511450c749Smrg hid_item_t loc_y; /* y locator item */ 5521450c749Smrg hid_item_t loc_z; /* z (wheel) locator item */ 5531450c749Smrg hid_item_t loc_w; /* z (wheel) locator item */ 5546aab59a7Smrg hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */ 5556aab59a7Smrg unsigned char *buffer; 5566aab59a7Smrg} UsbMseRec, *UsbMsePtr; 5576aab59a7Smrg 5586aab59a7Smrgstatic int 5596aab59a7SmrgusbMouseProc(DeviceIntPtr pPointer, int what) 5606aab59a7Smrg{ 5616aab59a7Smrg InputInfoPtr pInfo; 5626aab59a7Smrg MouseDevPtr pMse; 5636aab59a7Smrg UsbMsePtr pUsbMse; 5646aab59a7Smrg unsigned char map[MSE_MAXBUTTONS + 1]; 5656aab59a7Smrg int nbuttons; 5666aab59a7Smrg 5676aab59a7Smrg pInfo = pPointer->public.devicePrivate; 5686aab59a7Smrg pMse = pInfo->private; 5696aab59a7Smrg pMse->device = pPointer; 5706aab59a7Smrg pUsbMse = pMse->mousePriv; 5716aab59a7Smrg 5726aab59a7Smrg switch (what) { 5731450c749Smrg case DEVICE_INIT: 5741450c749Smrg pPointer->public.on = FALSE; 5751450c749Smrg 5761450c749Smrg for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons) 5771450c749Smrg map[nbuttons + 1] = nbuttons + 1; 5781450c749Smrg 5791450c749Smrg InitPointerDeviceStruct((DevicePtr)pPointer, 5801450c749Smrg map, 5811450c749Smrg min(pMse->buttons, MSE_MAXBUTTONS), 5821450c749Smrg miPointerGetMotionEvents, 5831450c749Smrg pMse->Ctrl, 5841450c749Smrg miPointerGetMotionBufferSize()); 5851450c749Smrg 5861450c749Smrg /* X valuator */ 5871450c749Smrg xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); 5881450c749Smrg xf86InitValuatorDefaults(pPointer, 0); 5891450c749Smrg /* Y valuator */ 5901450c749Smrg xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); 5911450c749Smrg xf86InitValuatorDefaults(pPointer, 1); 5921450c749Smrg xf86MotionHistoryAllocate(pInfo); 5931450c749Smrg break; 5946aab59a7Smrg 5956aab59a7Smrg case DEVICE_ON: 5961450c749Smrg pInfo->fd = xf86OpenSerial(pInfo->options); 5971450c749Smrg if (pInfo->fd == -1) 5981450c749Smrg xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 5991450c749Smrg else { 6001450c749Smrg pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize); 6011450c749Smrg if (!pMse->buffer) { 6021450c749Smrg free(pMse); 6031450c749Smrg xf86CloseSerial(pInfo->fd); 6041450c749Smrg pInfo->fd = -1; 6051450c749Smrg } else { 6061450c749Smrg xf86FlushInput(pInfo->fd); 6074d6d3f96Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 23 6081450c749Smrg if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput, 6091450c749Smrg pInfo)) 6104d6d3f96Smrg#endif 6111450c749Smrg AddEnabledDevice(pInfo->fd); 6121450c749Smrg } 6131450c749Smrg } 6141450c749Smrg pMse->lastButtons = 0; 6151450c749Smrg pMse->lastMappedButtons = 0; 6161450c749Smrg pMse->emulateState = 0; 6171450c749Smrg pPointer->public.on = TRUE; 6181450c749Smrg break; 6196aab59a7Smrg 6206aab59a7Smrg case DEVICE_OFF: 6216aab59a7Smrg case DEVICE_CLOSE: 6221450c749Smrg if (pInfo->fd != -1) { 6231450c749Smrg RemoveEnabledDevice(pInfo->fd); 6241450c749Smrg if (pUsbMse->packetSize > 8 && pUsbMse->buffer) { 6251450c749Smrg free(pUsbMse->buffer); 6261450c749Smrg } 6271450c749Smrg if (pMse->buffer) { 6281450c749Smrg XisbFree(pMse->buffer); 6291450c749Smrg pMse->buffer = NULL; 6301450c749Smrg } 6311450c749Smrg xf86CloseSerial(pInfo->fd); 6321450c749Smrg pInfo->fd = -1; 6331450c749Smrg } 6341450c749Smrg pPointer->public.on = FALSE; 6351450c749Smrg usleep(300000); 6361450c749Smrg break; 6371450c749Smrg 6381450c749Smrg default: 6391450c749Smrg return BadValue; 6406aab59a7Smrg } 6416aab59a7Smrg return Success; 6426aab59a7Smrg} 6436aab59a7Smrg 6446aab59a7Smrgstatic void 6456aab59a7SmrgusbReadInput(InputInfoPtr pInfo) 6466aab59a7Smrg{ 6476aab59a7Smrg MouseDevPtr pMse; 6486aab59a7Smrg UsbMsePtr pUsbMse; 6496aab59a7Smrg int buttons = pMse->lastButtons; 6506aab59a7Smrg int dx = 0, dy = 0, dz = 0, dw = 0; 6511450c749Smrg int n, c; 6526aab59a7Smrg unsigned char *pBuf; 6536aab59a7Smrg 6546aab59a7Smrg pMse = pInfo->private; 6556aab59a7Smrg pUsbMse = pMse->mousePriv; 6566aab59a7Smrg 6576aab59a7Smrg XisbBlockDuration(pMse->buffer, -1); 6586aab59a7Smrg pBuf = pUsbMse->buffer; 6596aab59a7Smrg n = 0; 6606aab59a7Smrg while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) { 6611450c749Smrg pBuf[n++] = (unsigned char)c; 6626aab59a7Smrg } 6636aab59a7Smrg if (n == 0) 6641450c749Smrg return; 6656aab59a7Smrg if (n != pUsbMse->packetSize) { 6661450c749Smrg LogMessageVerbSigSafe(X_WARNING, -1, 6671450c749Smrg "%s: incomplete packet, size %d\n", 6681450c749Smrg pInfo->name, n); 6696aab59a7Smrg } 6706aab59a7Smrg /* discard packets with an id that don't match the mouse */ 6716aab59a7Smrg /* XXX this is probably not the right thing */ 6726aab59a7Smrg if (pUsbMse->iid != 0) { 6731450c749Smrg if (*pBuf++ != pUsbMse->iid) 6741450c749Smrg return; 6756aab59a7Smrg } 6766aab59a7Smrg dx = hid_get_data(pBuf, &pUsbMse->loc_x); 6776aab59a7Smrg dy = hid_get_data(pBuf, &pUsbMse->loc_y); 6786aab59a7Smrg dz = hid_get_data(pBuf, &pUsbMse->loc_z); 6796aab59a7Smrg dw = hid_get_data(pBuf, &pUsbMse->loc_w); 6806aab59a7Smrg 6816aab59a7Smrg buttons = 0; 6826aab59a7Smrg for (n = 0; n < pMse->buttons; n++) { 6831450c749Smrg if (hid_get_data(pBuf, &pUsbMse->loc_btn[n])) 6841450c749Smrg buttons |= (1 << UMS_BUT(n)); 6856aab59a7Smrg } 6866aab59a7Smrg pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 6876aab59a7Smrg return; 6886aab59a7Smrg} 6896aab59a7Smrg 6906aab59a7Smrgstatic void 6916aab59a7SmrgusbSigioReadInput (int fd, void *closure) 6926aab59a7Smrg{ 6936aab59a7Smrg usbReadInput ((InputInfoPtr) closure); 6946aab59a7Smrg} 6956aab59a7Smrg 6966aab59a7Smrg/* This function is called when the protocol is "usb". */ 6976aab59a7Smrgstatic Bool 6986aab59a7SmrgusbPreInit(InputInfoPtr pInfo, const char *protocol, int flags) 6996aab59a7Smrg{ 7006aab59a7Smrg MouseDevPtr pMse = pInfo->private; 7016aab59a7Smrg UsbMsePtr pUsbMse; 7026aab59a7Smrg report_desc_t reportDesc; 7036aab59a7Smrg int i; 7046aab59a7Smrg 705bd3a1963Smrg pUsbMse = malloc(sizeof(UsbMseRec)); 7066aab59a7Smrg if (pUsbMse == NULL) { 7071450c749Smrg xf86Msg(X_ERROR, "%s: cannot allocate UsbMouseRec\n", pInfo->name); 7081450c749Smrg free(pMse); 7091450c749Smrg return FALSE; 7106aab59a7Smrg } 7116aab59a7Smrg 7126aab59a7Smrg pMse->protocol = protocol; 7136aab59a7Smrg xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); 7146aab59a7Smrg 7156aab59a7Smrg /* Collect the options, and process the common options. */ 716bd3a1963Smrg COLLECT_INPUT_OPTIONS(pInfo, NULL); 7176aab59a7Smrg xf86ProcessCommonOptions(pInfo, pInfo->options); 7186aab59a7Smrg 7196aab59a7Smrg /* Check if the device can be opened. */ 7206aab59a7Smrg pInfo->fd = xf86OpenSerial(pInfo->options); 7216aab59a7Smrg if (pInfo->fd == -1) { 7221450c749Smrg if (xf86GetAllowMouseOpenFail()) 7231450c749Smrg xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 7241450c749Smrg else { 7251450c749Smrg xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); 7261450c749Smrg free(pUsbMse); 7271450c749Smrg free(pMse); 7281450c749Smrg return FALSE; 7291450c749Smrg } 7306aab59a7Smrg } 7314d6d3f96Smrg /* Get USB information */ 7326aab59a7Smrg reportDesc = hid_get_report_desc(pInfo->fd); 7336aab59a7Smrg /* Get packet size & iid */ 7346aab59a7Smrg#ifdef USB_NEW_HID 7356aab59a7Smrg if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) { 7361450c749Smrg xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n", 7371450c749Smrg pInfo->name, strerror(errno)); 7381450c749Smrg return FALSE; 7396aab59a7Smrg } 7406aab59a7Smrg pUsbMse->packetSize = hid_report_size(reportDesc, hid_input, 7411450c749Smrg pUsbMse->iid); 7426aab59a7Smrg#else 7436aab59a7Smrg pUsbMse->packetSize = hid_report_size(reportDesc, hid_input, 7441450c749Smrg &pUsbMse->iid); 7456aab59a7Smrg#endif 7466aab59a7Smrg /* Allocate buffer */ 7476aab59a7Smrg if (pUsbMse->packetSize <= 8) { 7481450c749Smrg pUsbMse->buffer = pMse->protoBuf; 7496aab59a7Smrg } else { 7501450c749Smrg pUsbMse->buffer = malloc(pUsbMse->packetSize); 7516aab59a7Smrg } 7526aab59a7Smrg if (pUsbMse->buffer == NULL) { 7531450c749Smrg xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name); 7541450c749Smrg free(pUsbMse); 7551450c749Smrg free(pMse); 7561450c749Smrg xf86CloseSerial(pInfo->fd); 7571450c749Smrg return FALSE; 7586aab59a7Smrg } 7596aab59a7Smrg#ifdef USB_NEW_HID 7606aab59a7Smrg if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), 7611450c749Smrg hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) { 7621450c749Smrg xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name); 7636aab59a7Smrg } 7646aab59a7Smrg if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), 7651450c749Smrg hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) { 7661450c749Smrg xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name); 7676aab59a7Smrg } 7686aab59a7Smrg if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), 7691450c749Smrg hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) { 7706aab59a7Smrg } 7716aab59a7Smrg#else 7726aab59a7Smrg if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), 7731450c749Smrg hid_input, &pUsbMse->loc_x) < 0) { 7741450c749Smrg xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name); 7756aab59a7Smrg } 7766aab59a7Smrg if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), 7771450c749Smrg hid_input, &pUsbMse->loc_y) < 0) { 7781450c749Smrg xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name); 7796aab59a7Smrg } 7806aab59a7Smrg if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), 7811450c749Smrg hid_input, &pUsbMse->loc_z) < 0) { 7826aab59a7Smrg } 7836aab59a7Smrg#endif 7846aab59a7Smrg /* Probe for number of buttons */ 7856aab59a7Smrg for (i = 1; i <= MSE_MAXBUTTONS; i++) { 7861450c749Smrg if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i), 7871450c749Smrg hid_input, &pUsbMse->loc_btn[i-1] 7886aab59a7Smrg#ifdef USB_NEW_HID 7891450c749Smrg , pUsbMse->iid 7906aab59a7Smrg#endif 7911450c749Smrg )) 7921450c749Smrg break; 7936aab59a7Smrg } 7946aab59a7Smrg pMse->buttons = i-1; 7956aab59a7Smrg 7966aab59a7Smrg xf86CloseSerial(pInfo->fd); 7976aab59a7Smrg pInfo->fd = -1; 7986aab59a7Smrg 7996aab59a7Smrg /* Private structure */ 8006aab59a7Smrg pMse->mousePriv = pUsbMse; 8016aab59a7Smrg 8026aab59a7Smrg /* Process common mouse options (like Emulate3Buttons, etc). */ 8036aab59a7Smrg pMse->CommonOptions(pInfo); 8046aab59a7Smrg 8056aab59a7Smrg /* Setup the local procs. */ 8066aab59a7Smrg pInfo->device_control = usbMouseProc; 8076aab59a7Smrg pInfo->read_input = usbReadInput; 8086aab59a7Smrg 809bd3a1963Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 8106aab59a7Smrg pInfo->flags |= XI86_CONFIGURED; 811bd3a1963Smrg#endif 8126aab59a7Smrg return TRUE; 8136aab59a7Smrg} 8146aab59a7Smrg#endif /* USBMOUSE */ 8156aab59a7Smrg 8166aab59a7Smrgstatic Bool 8176aab59a7SmrgbsdMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) 8186aab59a7Smrg{ 8196aab59a7Smrg /* The protocol is guaranteed to be one of the internalNames[] */ 8206aab59a7Smrg#ifdef WSCONS_SUPPORT 8216aab59a7Smrg if (xf86NameCmp(protocol, "WSMouse") == 0) { 8221450c749Smrg return wsconsPreInit(pInfo, protocol, flags); 8236aab59a7Smrg } 8246aab59a7Smrg#endif 8256aab59a7Smrg#ifdef USBMOUSE_SUPPORT 8266aab59a7Smrg if (xf86NameCmp(protocol, "usb") == 0) { 8271450c749Smrg return usbPreInit(pInfo, protocol, flags); 8286aab59a7Smrg } 8296aab59a7Smrg#endif 8306aab59a7Smrg return TRUE; 8311450c749Smrg} 8326aab59a7Smrg 833bd3a1963SmrgOSMouseInfoPtr 834bd3a1963SmrgOSMouseInit(int flags) 8356aab59a7Smrg{ 8366aab59a7Smrg OSMouseInfoPtr p; 8376aab59a7Smrg 838bd3a1963Smrg p = calloc(sizeof(OSMouseInfoRec), 1); 8396aab59a7Smrg if (!p) 8401450c749Smrg return NULL; 8416aab59a7Smrg p->SupportedInterfaces = SupportedInterfaces; 8426aab59a7Smrg p->BuiltinNames = BuiltinNames; 8436aab59a7Smrg p->DefaultProtocol = DefaultProtocol; 8446aab59a7Smrg p->CheckProtocol = CheckProtocol; 8456aab59a7Smrg#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE) 8466aab59a7Smrg p->SetupAuto = SetupAuto; 8476aab59a7Smrg p->SetPS2Res = SetSysMouseRes; 8486aab59a7Smrg p->SetBMRes = SetSysMouseRes; 8496aab59a7Smrg p->SetMiscRes = SetSysMouseRes; 8506aab59a7Smrg#endif 8516aab59a7Smrg#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 8526aab59a7Smrg p->SetupAuto = SetupAuto; 8536aab59a7Smrg p->SetMiscRes = SetMouseRes; 8546aab59a7Smrg#endif 8556aab59a7Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__) 8566aab59a7Smrg p->FindDevice = FindDevice; 8576aab59a7Smrg#endif 8586aab59a7Smrg p->PreInit = bsdMousePreInit; 8596aab59a7Smrg return p; 8606aab59a7Smrg} 861