sun_mouse.c revision fc27e79c
16aab59a7Smrg/* 26aab59a7Smrg * Copyright 1999-2001 The XFree86 Project, Inc. All Rights Reserved. 36aab59a7Smrg * 46aab59a7Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 56aab59a7Smrg * of this software and associated documentation files (the "Software"), to 66aab59a7Smrg * deal in the Software without restriction, including without limitation the 76aab59a7Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 86aab59a7Smrg * sell copies of the Software, and to permit persons to whom the Software is 96aab59a7Smrg * furnished to do so, subject to the following conditions: 106aab59a7Smrg * 116aab59a7Smrg * The above copyright notice and this permission notice shall be included in 126aab59a7Smrg * all copies or substantial portions of the Software. 136aab59a7Smrg * 146aab59a7Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156aab59a7Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166aab59a7Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 176aab59a7Smrg * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 186aab59a7Smrg * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 196aab59a7Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 206aab59a7Smrg * 216aab59a7Smrg * Except as contained in this notice, the name of the XFree86 Project shall 226aab59a7Smrg * not be used in advertising or otherwise to promote the sale, use or other 236aab59a7Smrg * dealings in this Software without prior written authorization from the 246aab59a7Smrg * XFree86 Project. 256aab59a7Smrg */ 26fc27e79cSmrg/* Copyright 2004-2005, 2008-2009 Sun Microsystems, Inc. All rights reserved. 276aab59a7Smrg * 286aab59a7Smrg * Permission is hereby granted, free of charge, to any person obtaining a 296aab59a7Smrg * copy of this software and associated documentation files (the 306aab59a7Smrg * "Software"), to deal in the Software without restriction, including 316aab59a7Smrg * without limitation the rights to use, copy, modify, merge, publish, 326aab59a7Smrg * distribute, and/or sell copies of the Software, and to permit persons 336aab59a7Smrg * to whom the Software is furnished to do so, provided that the above 346aab59a7Smrg * copyright notice(s) and this permission notice appear in all copies of 356aab59a7Smrg * the Software and that both the above copyright notice(s) and this 366aab59a7Smrg * permission notice appear in supporting documentation. 376aab59a7Smrg * 386aab59a7Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 396aab59a7Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 406aab59a7Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 416aab59a7Smrg * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 426aab59a7Smrg * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 436aab59a7Smrg * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 446aab59a7Smrg * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 456aab59a7Smrg * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 466aab59a7Smrg * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 476aab59a7Smrg * 486aab59a7Smrg * Except as contained in this notice, the name of a copyright holder 496aab59a7Smrg * shall not be used in advertising or otherwise to promote the sale, use 506aab59a7Smrg * or other dealings in this Software without prior written authorization 516aab59a7Smrg * of the copyright holder. 526aab59a7Smrg */ 536aab59a7Smrg 546aab59a7Smrg#ifdef HAVE_XORG_CONFIG_H 556aab59a7Smrg#include <xorg-config.h> 566aab59a7Smrg#endif 576aab59a7Smrg 586aab59a7Smrg#include "xorg-server.h" 596aab59a7Smrg#include "xf86.h" 606aab59a7Smrg#include "xf86_OSlib.h" 616aab59a7Smrg#include "xf86OSmouse.h" 626aab59a7Smrg#include "xisb.h" 636aab59a7Smrg#include "mipointer.h" 646aab59a7Smrg#include <sys/stropts.h> 656aab59a7Smrg#include <sys/vuid_event.h> 666aab59a7Smrg#include <sys/msio.h> 676aab59a7Smrg 686aab59a7Smrg/* Wheel mouse support in VUID drivers in Solaris 9 updates & Solaris 10 */ 696aab59a7Smrg#ifdef WHEEL_DEVID /* Defined in vuid_event.h if VUID wheel support present */ 706aab59a7Smrg# define HAVE_VUID_WHEEL 716aab59a7Smrg#endif 726aab59a7Smrg#ifdef HAVE_VUID_WHEEL 736aab59a7Smrg# include <sys/vuid_wheel.h> 746aab59a7Smrg#endif 756aab59a7Smrg 766aab59a7Smrg/* Support for scaling absolute coordinates to screen size in 776aab59a7Smrg * Solaris 10 updates and beyond */ 786aab59a7Smrg#if !defined(HAVE_ABSOLUTE_MOUSE_SCALING) 796aab59a7Smrg# ifdef MSIOSRESOLUTION /* Defined in msio.h if scaling support present */ 806aab59a7Smrg# define HAVE_ABSOLUTE_MOUSE_SCALING 816aab59a7Smrg# endif 826aab59a7Smrg#endif 836aab59a7Smrg 846aab59a7Smrg/* Names of protocols that are handled internally here. */ 856aab59a7Smrg 866aab59a7Smrgstatic const char *internalNames[] = { 876aab59a7Smrg "VUID", 886aab59a7Smrg NULL 896aab59a7Smrg}; 906aab59a7Smrg 916aab59a7Smrgstatic const char *solarisMouseDevs[] = { 926aab59a7Smrg /* Device file: Protocol: */ 936aab59a7Smrg "/dev/mouse", "VUID", /* USB or SPARC */ 946aab59a7Smrg#if defined(__i386) || defined(__x86) 956aab59a7Smrg "/dev/kdmouse", "PS/2", /* PS/2 */ 966aab59a7Smrg#endif 976aab59a7Smrg NULL 986aab59a7Smrg}; 996aab59a7Smrg 1006aab59a7Smrgtypedef struct _VuidMseRec { 1016aab59a7Smrg struct _VuidMseRec *next; 1026aab59a7Smrg InputInfoPtr pInfo; 1036aab59a7Smrg Firm_event event; 1046aab59a7Smrg unsigned char * buffer; 1056aab59a7Smrg char * strmod; 1066aab59a7Smrg Bool(*wrapped_device_control)(DeviceIntPtr device, int what); 1076aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 1086aab59a7Smrg Ms_screen_resolution absres; 1096aab59a7Smrg#endif 1106aab59a7Smrg} VuidMseRec, *VuidMsePtr; 1116aab59a7Smrg 1126aab59a7Smrgstatic VuidMsePtr vuidMouseList = NULL; 1136aab59a7Smrg 1146aab59a7Smrgstatic int vuidMouseProc(DeviceIntPtr pPointer, int what); 1156aab59a7Smrgstatic void vuidReadInput(InputInfoPtr pInfo); 1166aab59a7Smrg 1176aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 1186aab59a7Smrgstatic void vuidMouseSendScreenSize(ScreenPtr pScreen, VuidMsePtr pVuidMse); 1196aab59a7Smrgstatic void vuidMouseAdjustFrame(int index, int x, int y, int flags); 1206aab59a7Smrg 1216aab59a7Smrgstatic int vuidMouseGeneration = 0; 1226aab59a7Smrgstatic int vuidMouseScreenIndex; 1236aab59a7Smrg#define vuidMouseGetScreenPrivate(s) ( \ 1246aab59a7Smrg dixLookupPrivate(&(s)->devPrivates, &vuidMouseScreenIndex)) 1256aab59a7Smrg#define vuidMouseSetScreenPrivate(s,p) \ 1266aab59a7Smrg dixSetPrivate(&(s)->devPrivates, &vuidMouseScreenIndex, (void *) p) 1276aab59a7Smrg#endif /* HAVE_ABSOLUTE_MOUSE_SCALING */ 1286aab59a7Smrg 1296aab59a7Smrgstatic inline 1306aab59a7SmrgVuidMsePtr getVuidMsePriv(InputInfoPtr pInfo) 1316aab59a7Smrg{ 1326aab59a7Smrg VuidMsePtr m = vuidMouseList; 1336aab59a7Smrg 1346aab59a7Smrg while ((m != NULL) && (m->pInfo != pInfo)) { 1356aab59a7Smrg m = m->next; 1366aab59a7Smrg } 1376aab59a7Smrg 1386aab59a7Smrg return m; 1396aab59a7Smrg} 1406aab59a7Smrg 1416aab59a7Smrg 1426aab59a7Smrg/* 1436aab59a7Smrg * Initialize and enable the mouse wheel, if present. 1446aab59a7Smrg * 1456aab59a7Smrg * Returns 1 if mouse wheel was successfully enabled. 1466aab59a7Smrg * Returns 0 if an error occurred or if there is no mouse wheel. 1476aab59a7Smrg */ 1486aab59a7Smrgstatic int 1496aab59a7SmrgvuidMouseWheelInit(InputInfoPtr pInfo) 1506aab59a7Smrg{ 1516aab59a7Smrg#ifdef HAVE_VUID_WHEEL 1526aab59a7Smrg wheel_state wstate; 1536aab59a7Smrg int nwheel = -1; 1546aab59a7Smrg int i; 1556aab59a7Smrg 1566aab59a7Smrg wstate.vers = VUID_WHEEL_STATE_VERS; 1576aab59a7Smrg wstate.id = 0; 1586aab59a7Smrg wstate.stateflags = (uint32_t) -1; 1596aab59a7Smrg 1606aab59a7Smrg SYSCALL(i = ioctl(pInfo->fd, VUIDGWHEELCOUNT, &nwheel)); 1616aab59a7Smrg if (i != 0) 1626aab59a7Smrg return (0); 1636aab59a7Smrg 1646aab59a7Smrg SYSCALL(i = ioctl(pInfo->fd, VUIDGWHEELSTATE, &wstate)); 1656aab59a7Smrg if (i != 0) { 1666aab59a7Smrg xf86Msg(X_WARNING, "%s: couldn't get wheel state\n", pInfo->name); 1676aab59a7Smrg return (0); 1686aab59a7Smrg } 1696aab59a7Smrg 1706aab59a7Smrg wstate.stateflags |= VUID_WHEEL_STATE_ENABLED; 1716aab59a7Smrg 1726aab59a7Smrg SYSCALL(i = ioctl(pInfo->fd, VUIDSWHEELSTATE, &wstate)); 1736aab59a7Smrg if (i != 0) { 1746aab59a7Smrg xf86Msg(X_WARNING, "%s: couldn't enable wheel\n", pInfo->name); 1756aab59a7Smrg return (0); 1766aab59a7Smrg } 1776aab59a7Smrg 1786aab59a7Smrg return (1); 1796aab59a7Smrg#else 1806aab59a7Smrg return (0); 1816aab59a7Smrg#endif 1826aab59a7Smrg} 1836aab59a7Smrg 1846aab59a7Smrg 1856aab59a7Smrg/* This function is called when the protocol is "VUID". */ 1866aab59a7Smrgstatic Bool 1876aab59a7SmrgvuidPreInit(InputInfoPtr pInfo, const char *protocol, int flags) 1886aab59a7Smrg{ 1896aab59a7Smrg MouseDevPtr pMse = pInfo->private; 1906aab59a7Smrg VuidMsePtr pVuidMse; 1916aab59a7Smrg int buttons, i; 1926aab59a7Smrg 1936aab59a7Smrg pVuidMse = xcalloc(sizeof(VuidMseRec), 1); 1946aab59a7Smrg if (pVuidMse == NULL) { 1956aab59a7Smrg xf86Msg(X_ERROR, "%s: cannot allocate VuidMouseRec\n", pInfo->name); 1966aab59a7Smrg xfree(pMse); 1976aab59a7Smrg return FALSE; 1986aab59a7Smrg } 1996aab59a7Smrg 2006aab59a7Smrg pMse->protocol = protocol; 2016aab59a7Smrg xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); 2026aab59a7Smrg 2036aab59a7Smrg /* Collect the options, and process the common options. */ 2046aab59a7Smrg xf86CollectInputOptions(pInfo, NULL, NULL); 2056aab59a7Smrg xf86ProcessCommonOptions(pInfo, pInfo->options); 2066aab59a7Smrg 207fc27e79cSmrg pVuidMse->buffer = (unsigned char *)&pVuidMse->event; 208fc27e79cSmrg pVuidMse->strmod = xf86SetStrOption(pInfo->options, "StreamsModule", NULL); 209fc27e79cSmrg 2106aab59a7Smrg /* Check if the device can be opened. */ 2116aab59a7Smrg pInfo->fd = xf86OpenSerial(pInfo->options); 2126aab59a7Smrg if (pInfo->fd == -1) { 213fc27e79cSmrg if (xf86GetAllowMouseOpenFail()) { 2146aab59a7Smrg xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 215fc27e79cSmrg } else { 2166aab59a7Smrg xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); 217fc27e79cSmrg xfree(pVuidMse->strmod); 2186aab59a7Smrg xfree(pVuidMse); 2196aab59a7Smrg xfree(pMse); 2206aab59a7Smrg return FALSE; 2216aab59a7Smrg } 222fc27e79cSmrg } else { 223fc27e79cSmrg if (pVuidMse->strmod) { 224fc27e79cSmrg /* Check to see if module is already pushed */ 225fc27e79cSmrg SYSCALL(i = ioctl(pInfo->fd, I_FIND, pVuidMse->strmod)); 2266aab59a7Smrg 227fc27e79cSmrg if (i == 0) { /* Not already pushed */ 228fc27e79cSmrg SYSCALL(i = ioctl(pInfo->fd, I_PUSH, pVuidMse->strmod)); 229fc27e79cSmrg if (i < 0) { 230fc27e79cSmrg xf86Msg(X_ERROR, 231fc27e79cSmrg "%s: cannot push module '%s' onto mouse device: %s\n", 232fc27e79cSmrg pInfo->name, pVuidMse->strmod, strerror(errno)); 233fc27e79cSmrg xf86CloseSerial(pInfo->fd); 234fc27e79cSmrg pInfo->fd = -1; 235fc27e79cSmrg xfree(pVuidMse->strmod); 236fc27e79cSmrg xfree(pVuidMse); 237fc27e79cSmrg xfree(pMse); 238fc27e79cSmrg return FALSE; 239fc27e79cSmrg } 240fc27e79cSmrg } 2416aab59a7Smrg } 2426aab59a7Smrg 243fc27e79cSmrg buttons = xf86SetIntOption(pInfo->options, "Buttons", 0); 244fc27e79cSmrg if (buttons == 0) { 245fc27e79cSmrg SYSCALL(i = ioctl(pInfo->fd, MSIOBUTTONS, &buttons)); 246fc27e79cSmrg if (i == 0) { 247fc27e79cSmrg pInfo->conf_idev->commonOptions = 248fc27e79cSmrg xf86ReplaceIntOption(pInfo->conf_idev->commonOptions, 249fc27e79cSmrg "Buttons", buttons); 250fc27e79cSmrg xf86Msg(X_INFO, "%s: Setting Buttons option to \"%d\"\n", 251fc27e79cSmrg pInfo->name, buttons); 252fc27e79cSmrg } 2536aab59a7Smrg } 2546aab59a7Smrg 255fc27e79cSmrg if (pVuidMse->strmod) { 256fc27e79cSmrg SYSCALL(i = ioctl(pInfo->fd, I_POP, pVuidMse->strmod)); 257fc27e79cSmrg if (i == -1) { 258fc27e79cSmrg xf86Msg(X_WARNING, 259fc27e79cSmrg "%s: cannot pop module '%s' off mouse device: %s\n", 260fc27e79cSmrg pInfo->name, pVuidMse->strmod, strerror(errno)); 261fc27e79cSmrg } 2626aab59a7Smrg } 2636aab59a7Smrg 264fc27e79cSmrg xf86CloseSerial(pInfo->fd); 265fc27e79cSmrg pInfo->fd = -1; 266fc27e79cSmrg } 2676aab59a7Smrg 2686aab59a7Smrg /* Process common mouse options (like Emulate3Buttons, etc). */ 2696aab59a7Smrg pMse->CommonOptions(pInfo); 2706aab59a7Smrg 2716aab59a7Smrg /* Setup the local procs. */ 2726aab59a7Smrg pVuidMse->wrapped_device_control = pInfo->device_control; 2736aab59a7Smrg pInfo->device_control = vuidMouseProc; 2746aab59a7Smrg pInfo->read_input = vuidReadInput; 2756aab59a7Smrg 2766aab59a7Smrg pMse->xisbscale = sizeof(Firm_event); 2776aab59a7Smrg 2786aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 2796aab59a7Smrg pVuidMse->absres.height = pVuidMse->absres.width = 0; 2806aab59a7Smrg#endif 2816aab59a7Smrg pVuidMse->pInfo = pInfo; 2826aab59a7Smrg pVuidMse->next = vuidMouseList; 2836aab59a7Smrg vuidMouseList = pVuidMse; 2846aab59a7Smrg 2856aab59a7Smrg pInfo->flags |= XI86_CONFIGURED; 2866aab59a7Smrg return TRUE; 2876aab59a7Smrg} 2886aab59a7Smrg 2896aab59a7Smrgstatic void 2906aab59a7SmrgvuidFlushAbsEvents(InputInfoPtr pInfo, int absX, int absY, 2916aab59a7Smrg Bool *absXset, Bool *absYset) 2926aab59a7Smrg{ 2936aab59a7Smrg#ifdef DEBUG 2946aab59a7Smrg ErrorF("vuidFlushAbsEvents: %d,%d (set: %d, %d)\n", absX, absY, 2956aab59a7Smrg *absXset, *absYset); 2966aab59a7Smrg#endif 2976aab59a7Smrg if ((*absXset) && (*absYset)) { 2986aab59a7Smrg xf86PostMotionEvent(pInfo->dev, 2996aab59a7Smrg /* is_absolute: */ TRUE, 3006aab59a7Smrg /* first_valuator: */ 0, 3016aab59a7Smrg /* num_valuators: */ 2, 3026aab59a7Smrg absX, absY); 3036aab59a7Smrg } else if (*absXset) { 3046aab59a7Smrg xf86PostMotionEvent(pInfo->dev, 3056aab59a7Smrg /* is_absolute: */ TRUE, 3066aab59a7Smrg /* first_valuator: */ 0, 3076aab59a7Smrg /* num_valuators: */ 1, 3086aab59a7Smrg absX); 3096aab59a7Smrg } else if (*absYset) { 3106aab59a7Smrg xf86PostMotionEvent(pInfo->dev, 3116aab59a7Smrg /* is_absolute: */ TRUE, 3126aab59a7Smrg /* first_valuator: */ 1, 3136aab59a7Smrg /* num_valuators: */ 1, 3146aab59a7Smrg absY); 3156aab59a7Smrg } 3166aab59a7Smrg 3176aab59a7Smrg *absXset = FALSE; 3186aab59a7Smrg *absYset = FALSE; 3196aab59a7Smrg} 3206aab59a7Smrg 3216aab59a7Smrgstatic void 3226aab59a7SmrgvuidReadInput(InputInfoPtr pInfo) 3236aab59a7Smrg{ 3246aab59a7Smrg MouseDevPtr pMse; 3256aab59a7Smrg VuidMsePtr pVuidMse; 3266aab59a7Smrg int buttons; 3276aab59a7Smrg int dx = 0, dy = 0, dz = 0, dw = 0; 3286aab59a7Smrg unsigned int n; 3296aab59a7Smrg int c; 3306aab59a7Smrg unsigned char *pBuf; 3316aab59a7Smrg int absX = 0, absY = 0; 3326aab59a7Smrg Bool absXset = FALSE, absYset = FALSE; 3336aab59a7Smrg 3346aab59a7Smrg pMse = pInfo->private; 3356aab59a7Smrg pVuidMse = getVuidMsePriv(pInfo); 3366aab59a7Smrg buttons = pMse->lastButtons; 3376aab59a7Smrg XisbBlockDuration(pMse->buffer, -1); 3386aab59a7Smrg pBuf = pVuidMse->buffer; 3396aab59a7Smrg n = 0; 3406aab59a7Smrg 3416aab59a7Smrg do { 3426aab59a7Smrg while (n < sizeof(Firm_event) && (c = XisbRead(pMse->buffer)) >= 0) { 3436aab59a7Smrg pBuf[n++] = (unsigned char)c; 3446aab59a7Smrg } 3456aab59a7Smrg 3466aab59a7Smrg if (n == 0) 3476aab59a7Smrg return; 3486aab59a7Smrg 3496aab59a7Smrg if (n != sizeof(Firm_event)) { 3506aab59a7Smrg xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", 3516aab59a7Smrg pInfo->name, n); 3526aab59a7Smrg } 3536aab59a7Smrg 3546aab59a7Smrg#ifdef DEBUG 3556aab59a7Smrg ErrorF("vuidReadInput: event type: %3d value: %5d\n", 3566aab59a7Smrg pVuidMse->event.id, pVuidMse->event.value); 3576aab59a7Smrg#endif 3586aab59a7Smrg 3596aab59a7Smrg if (pVuidMse->event.id >= BUT_FIRST && pVuidMse->event.id <= BUT_LAST) { 3606aab59a7Smrg /* button */ 3616aab59a7Smrg int butnum = pVuidMse->event.id - BUT_FIRST; 3626aab59a7Smrg 3636aab59a7Smrg if (butnum < 3) 3646aab59a7Smrg butnum = 2 - butnum; 3656aab59a7Smrg if (!pVuidMse->event.value) 3666aab59a7Smrg buttons &= ~(1 << butnum); 3676aab59a7Smrg else 3686aab59a7Smrg buttons |= (1 << butnum); 3696aab59a7Smrg } else if (pVuidMse->event.id >= VLOC_FIRST && 3706aab59a7Smrg pVuidMse->event.id <= VLOC_LAST) { 3716aab59a7Smrg /* axis */ 3726aab59a7Smrg int delta = pVuidMse->event.value; 3736aab59a7Smrg switch(pVuidMse->event.id) { 3746aab59a7Smrg case LOC_X_DELTA: 3756aab59a7Smrg dx += delta; 3766aab59a7Smrg break; 3776aab59a7Smrg case LOC_Y_DELTA: 3786aab59a7Smrg dy -= delta; 3796aab59a7Smrg break; 3806aab59a7Smrg case LOC_X_ABSOLUTE: 3816aab59a7Smrg if (absXset) { 3826aab59a7Smrg vuidFlushAbsEvents(pInfo, absX, absY, &absXset, &absYset); 3836aab59a7Smrg } 3846aab59a7Smrg absX = delta; 3856aab59a7Smrg absXset = TRUE; 3866aab59a7Smrg break; 3876aab59a7Smrg case LOC_Y_ABSOLUTE: 3886aab59a7Smrg if (absYset) { 3896aab59a7Smrg vuidFlushAbsEvents(pInfo, absX, absY, &absXset, &absYset); 3906aab59a7Smrg } 3916aab59a7Smrg absY = delta; 3926aab59a7Smrg absYset = TRUE; 3936aab59a7Smrg break; 3946aab59a7Smrg } 3956aab59a7Smrg } 3966aab59a7Smrg#ifdef HAVE_VUID_WHEEL 3976aab59a7Smrg else if (vuid_in_range(VUID_WHEEL, pVuidMse->event.id)) { 3986aab59a7Smrg if (vuid_id_offset(pVuidMse->event.id) == 0) 3996aab59a7Smrg dz -= VUID_WHEEL_GETDELTA(pVuidMse->event.value); 4006aab59a7Smrg else 4016aab59a7Smrg dw -= VUID_WHEEL_GETDELTA(pVuidMse->event.value); 4026aab59a7Smrg } 4036aab59a7Smrg#endif 4046aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 4056aab59a7Smrg else if (pVuidMse->event.id == MOUSE_TYPE_ABSOLUTE) { 4066aab59a7Smrg ScreenPtr ptrCurScreen; 4076aab59a7Smrg 4086aab59a7Smrg /* force sending absolute resolution scaling ioctl */ 4096aab59a7Smrg pVuidMse->absres.height = pVuidMse->absres.width = 0; 4106aab59a7Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 4116aab59a7Smrg ptrCurScreen = miPointerCurrentScreen(); 4126aab59a7Smrg#else 4136aab59a7Smrg ptrCurScreen = miPointerGetScreen(pInfo->dev); 4146aab59a7Smrg#endif 4156aab59a7Smrg vuidMouseSendScreenSize(ptrCurScreen, pVuidMse); 4166aab59a7Smrg } 4176aab59a7Smrg#endif 4186aab59a7Smrg 4196aab59a7Smrg n = 0; 4206aab59a7Smrg if ((c = XisbRead(pMse->buffer)) >= 0) { 4216aab59a7Smrg /* Another packet. Handle it right away. */ 4226aab59a7Smrg pBuf[n++] = c; 4236aab59a7Smrg } 4246aab59a7Smrg } while (n != 0); 4256aab59a7Smrg 4266aab59a7Smrg if (absXset || absYset) { 4276aab59a7Smrg vuidFlushAbsEvents(pInfo, absX, absY, &absXset, &absYset); 4286aab59a7Smrg } 4296aab59a7Smrg 4306aab59a7Smrg pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 4316aab59a7Smrg return; 4326aab59a7Smrg} 4336aab59a7Smrg 4346aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 4356aab59a7Smrgstatic void vuidMouseSendScreenSize(ScreenPtr pScreen, VuidMsePtr pVuidMse) 4366aab59a7Smrg{ 4376aab59a7Smrg InputInfoPtr pInfo = pVuidMse->pInfo; 4386aab59a7Smrg ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); 4396aab59a7Smrg int result; 4406aab59a7Smrg 4416aab59a7Smrg if ((pVuidMse->absres.width != pScr->currentMode->HDisplay) || 4426aab59a7Smrg (pVuidMse->absres.height != pScr->currentMode->VDisplay)) 4436aab59a7Smrg { 4446aab59a7Smrg pVuidMse->absres.width = pScr->currentMode->HDisplay; 4456aab59a7Smrg pVuidMse->absres.height = pScr->currentMode->VDisplay; 4466aab59a7Smrg 4476aab59a7Smrg do { 4486aab59a7Smrg result = ioctl(pInfo->fd, MSIOSRESOLUTION, &(pVuidMse->absres)); 4496aab59a7Smrg } while ( (result != 0) && (errno == EINTR) ); 4506aab59a7Smrg 4516aab59a7Smrg if (result != 0) { 4526aab59a7Smrg xf86Msg(X_WARNING, 4536aab59a7Smrg "%s: couldn't set absolute mouse scaling resolution: %s\n", 4546aab59a7Smrg pInfo->name, strerror(errno)); 4556aab59a7Smrg#ifdef DEBUG 4566aab59a7Smrg } else { 4576aab59a7Smrg xf86Msg(X_INFO, 4586aab59a7Smrg "%s: absolute mouse scaling resolution set to %d x %d\n", 4596aab59a7Smrg pInfo->name, 4606aab59a7Smrg pVuidMse->absres.width, pVuidMse->absres.height); 4616aab59a7Smrg#endif 4626aab59a7Smrg } 4636aab59a7Smrg } 4646aab59a7Smrg} 4656aab59a7Smrg 4666aab59a7Smrgstatic void vuidMouseAdjustFrame(int index, int x, int y, int flags) 4676aab59a7Smrg{ 4686aab59a7Smrg ScrnInfoPtr pScrn = xf86Screens[index]; 4696aab59a7Smrg ScreenPtr pScreen = pScrn->pScreen; 4706aab59a7Smrg xf86AdjustFrameProc *wrappedAdjustFrame 4716aab59a7Smrg = (xf86AdjustFrameProc *) vuidMouseGetScreenPrivate(pScreen); 4726aab59a7Smrg VuidMsePtr m; 4736aab59a7Smrg ScreenPtr ptrCurScreen; 4746aab59a7Smrg 4756aab59a7Smrg if(wrappedAdjustFrame) { 4766aab59a7Smrg pScrn->AdjustFrame = wrappedAdjustFrame; 4776aab59a7Smrg (*pScrn->AdjustFrame)(index, x, y, flags); 4786aab59a7Smrg pScrn->AdjustFrame = vuidMouseAdjustFrame; 4796aab59a7Smrg } 4806aab59a7Smrg 4816aab59a7Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 4826aab59a7Smrg ptrCurScreen = miPointerCurrentScreen(); 4836aab59a7Smrg#endif 4846aab59a7Smrg 4856aab59a7Smrg for (m = vuidMouseList; m != NULL ; m = m->next) { 4866aab59a7Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 0 4876aab59a7Smrg ptrCurScreen = miPointerGetScreen(m->pInfo->dev); 4886aab59a7Smrg#endif 4896aab59a7Smrg if (ptrCurScreen == pScreen) 4906aab59a7Smrg { 4916aab59a7Smrg vuidMouseSendScreenSize(pScreen, m); 4926aab59a7Smrg } 4936aab59a7Smrg } 4946aab59a7Smrg} 4956aab59a7Smrg#endif /* HAVE_ABSOLUTE_MOUSE_SCALING */ 4966aab59a7Smrg 4976aab59a7Smrg 4986aab59a7Smrgstatic int 4996aab59a7SmrgvuidMouseProc(DeviceIntPtr pPointer, int what) 5006aab59a7Smrg{ 5016aab59a7Smrg InputInfoPtr pInfo; 5026aab59a7Smrg MouseDevPtr pMse; 5036aab59a7Smrg VuidMsePtr pVuidMse; 5046aab59a7Smrg int ret = Success; 5056aab59a7Smrg int i; 5066aab59a7Smrg 5076aab59a7Smrg pInfo = pPointer->public.devicePrivate; 5086aab59a7Smrg pMse = pInfo->private; 5096aab59a7Smrg pMse->device = pPointer; 5106aab59a7Smrg 5116aab59a7Smrg pVuidMse = getVuidMsePriv(pInfo); 5126aab59a7Smrg if (pVuidMse == NULL) { 5136aab59a7Smrg return BadImplementation; 5146aab59a7Smrg } 5156aab59a7Smrg 5166aab59a7Smrg switch (what) { 5176aab59a7Smrg 5186aab59a7Smrg case DEVICE_INIT: 5196aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 5206aab59a7Smrg if (vuidMouseGeneration != serverGeneration) { 5216aab59a7Smrg for (i = 0; i < screenInfo.numScreens; i++) { 5226aab59a7Smrg ScreenPtr pScreen = screenInfo.screens[i]; 5236aab59a7Smrg ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); 5246aab59a7Smrg vuidMouseSetScreenPrivate(pScreen, pScrn->AdjustFrame); 5256aab59a7Smrg pScrn->AdjustFrame = vuidMouseAdjustFrame; 5266aab59a7Smrg } 5276aab59a7Smrg vuidMouseGeneration = serverGeneration; 5286aab59a7Smrg } 5296aab59a7Smrg#endif 5306aab59a7Smrg ret = pVuidMse->wrapped_device_control(pPointer, what); 5316aab59a7Smrg break; 5326aab59a7Smrg 5336aab59a7Smrg case DEVICE_ON: 5346aab59a7Smrg ret = pVuidMse->wrapped_device_control(pPointer, DEVICE_ON); 5356aab59a7Smrg 5366aab59a7Smrg if ((ret == Success) && (pInfo->fd != -1)) { 5376aab59a7Smrg int fmt = VUID_FIRM_EVENT; 5386aab59a7Smrg 5396aab59a7Smrg if (pVuidMse->strmod) { 540fc27e79cSmrg /* Check to see if module is already pushed */ 541fc27e79cSmrg SYSCALL(i = ioctl(pInfo->fd, I_FIND, pVuidMse->strmod)); 542fc27e79cSmrg 543fc27e79cSmrg if (i == 0) { /* Not already pushed */ 544fc27e79cSmrg SYSCALL(i = ioctl(pInfo->fd, I_PUSH, pVuidMse->strmod)); 545fc27e79cSmrg if (i < 0) { 546fc27e79cSmrg xf86Msg(X_WARNING, "%s: cannot push module '%s' " 547fc27e79cSmrg "onto mouse device: %s\n", pInfo->name, 548fc27e79cSmrg pVuidMse->strmod, strerror(errno)); 549fc27e79cSmrg xfree(pVuidMse->strmod); 550fc27e79cSmrg pVuidMse->strmod = NULL; 551fc27e79cSmrg } 5526aab59a7Smrg } 5536aab59a7Smrg } 554fc27e79cSmrg 5556aab59a7Smrg SYSCALL(i = ioctl(pInfo->fd, VUIDSFORMAT, &fmt)); 5566aab59a7Smrg if (i < 0) { 5576aab59a7Smrg xf86Msg(X_WARNING, 5586aab59a7Smrg "%s: cannot set mouse device to VUID mode: %s\n", 5596aab59a7Smrg pInfo->name, strerror(errno)); 5606aab59a7Smrg } 5616aab59a7Smrg vuidMouseWheelInit(pInfo); 5626aab59a7Smrg#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 5636aab59a7Smrg vuidMouseSendScreenSize(screenInfo.screens[0], pVuidMse); 5646aab59a7Smrg#endif 5656aab59a7Smrg xf86FlushInput(pInfo->fd); 5666aab59a7Smrg } 5676aab59a7Smrg break; 5686aab59a7Smrg 5696aab59a7Smrg case DEVICE_OFF: 5706aab59a7Smrg case DEVICE_CLOSE: 5716aab59a7Smrg if (pInfo->fd != -1) { 5726aab59a7Smrg if (pVuidMse->strmod) { 5736aab59a7Smrg SYSCALL(i = ioctl(pInfo->fd, I_POP, pVuidMse->strmod)); 5746aab59a7Smrg if (i == -1) { 5756aab59a7Smrg xf86Msg(X_WARNING, 5766aab59a7Smrg "%s: cannot pop module '%s' off mouse device: %s\n", 5776aab59a7Smrg pInfo->name, pVuidMse->strmod, strerror(errno)); 5786aab59a7Smrg } 5796aab59a7Smrg } 5806aab59a7Smrg } 5816aab59a7Smrg ret = pVuidMse->wrapped_device_control(pPointer, what); 5826aab59a7Smrg break; 5836aab59a7Smrg 5846aab59a7Smrg default: /* Should never be called, but just in case */ 5856aab59a7Smrg ret = pVuidMse->wrapped_device_control(pPointer, what); 5866aab59a7Smrg break; 5876aab59a7Smrg } 5886aab59a7Smrg return ret; 5896aab59a7Smrg} 5906aab59a7Smrg 5916aab59a7Smrgstatic Bool 5926aab59a7SmrgsunMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) 5936aab59a7Smrg{ 5946aab59a7Smrg /* The protocol is guaranteed to be one of the internalNames[] */ 5956aab59a7Smrg if (xf86NameCmp(protocol, "VUID") == 0) { 5966aab59a7Smrg return vuidPreInit(pInfo, protocol, flags); 5976aab59a7Smrg } 5986aab59a7Smrg return TRUE; 5996aab59a7Smrg} 6006aab59a7Smrg 6016aab59a7Smrgstatic const char ** 6026aab59a7SmrgBuiltinNames(void) 6036aab59a7Smrg{ 6046aab59a7Smrg return internalNames; 6056aab59a7Smrg} 6066aab59a7Smrg 6076aab59a7Smrgstatic Bool 6086aab59a7SmrgCheckProtocol(const char *protocol) 6096aab59a7Smrg{ 6106aab59a7Smrg int i; 6116aab59a7Smrg 6126aab59a7Smrg for (i = 0; internalNames[i]; i++) 6136aab59a7Smrg if (xf86NameCmp(protocol, internalNames[i]) == 0) 6146aab59a7Smrg return TRUE; 6156aab59a7Smrg 6166aab59a7Smrg return FALSE; 6176aab59a7Smrg} 6186aab59a7Smrg 6196aab59a7Smrgstatic const char * 6206aab59a7SmrgDefaultProtocol(void) 6216aab59a7Smrg{ 6226aab59a7Smrg return "Auto"; 6236aab59a7Smrg} 6246aab59a7Smrg 6256aab59a7Smrgstatic Bool 6266aab59a7SmrgsolarisMouseAutoProbe(InputInfoPtr pInfo, const char **protocol, 6276aab59a7Smrg const char **device) 6286aab59a7Smrg{ 6296aab59a7Smrg const char **pdev, **pproto; 6306aab59a7Smrg int fd = -1; 6316aab59a7Smrg Bool found; 6326aab59a7Smrg char *strmod; 6336aab59a7Smrg 6346aab59a7Smrg if (*device == NULL) { 6356aab59a7Smrg /* Check to see if xorg.conf or HAL specified a device to use */ 6366aab59a7Smrg *device = xf86CheckStrOption(pInfo->options, "Device", NULL); 6376aab59a7Smrg if (*device == NULL) { 6386aab59a7Smrg *device = xf86CheckStrOption(pInfo->conf_idev->commonOptions, 6396aab59a7Smrg "Device", NULL); 6406aab59a7Smrg } 6416aab59a7Smrg } 6426aab59a7Smrg 6436aab59a7Smrg if (*device != NULL) { 6446aab59a7Smrg strmod = xf86CheckStrOption(pInfo->options, "StreamsModule", NULL); 6456aab59a7Smrg if (strmod == NULL) { 6466aab59a7Smrg strmod = xf86CheckStrOption(pInfo->conf_idev->commonOptions, 6476aab59a7Smrg "StreamsModule", NULL); 6486aab59a7Smrg } 6496aab59a7Smrg if (strmod) { 6506aab59a7Smrg /* if a device name is already known, and a StreamsModule is 6516aab59a7Smrg specified to convert events to VUID, then we don't need to 6526aab59a7Smrg probe further */ 6536aab59a7Smrg *protocol = "VUID"; 6546aab59a7Smrg return TRUE; 6556aab59a7Smrg } 6566aab59a7Smrg } 6576aab59a7Smrg 6586aab59a7Smrg 6596aab59a7Smrg for (pdev = solarisMouseDevs; *pdev; pdev += 2) { 6606aab59a7Smrg pproto = pdev + 1; 6616aab59a7Smrg if ((*protocol != NULL) && (strcmp(*protocol, "Auto") != 0) && 6626aab59a7Smrg (*pproto != NULL) && (strcmp(*pproto, *protocol) != 0)) { 6636aab59a7Smrg continue; 6646aab59a7Smrg } 6656aab59a7Smrg if ((*device != NULL) && (strcmp(*device, *pdev) != 0)) { 6666aab59a7Smrg continue; 6676aab59a7Smrg } 6686aab59a7Smrg SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK)); 6696aab59a7Smrg if (fd == -1) { 6706aab59a7Smrg#ifdef DEBUG 6716aab59a7Smrg ErrorF("Cannot open %s (%s)\n", pdev, strerror(errno)); 6726aab59a7Smrg#endif 6736aab59a7Smrg } else { 6746aab59a7Smrg found = TRUE; 6756aab59a7Smrg if ((*pproto != NULL) && (strcmp(*pproto, "VUID") == 0)) { 6766aab59a7Smrg int i, r; 6776aab59a7Smrg SYSCALL(r = ioctl(fd, VUIDGFORMAT, &i)); 6786aab59a7Smrg if (r < 0) { 6796aab59a7Smrg found = FALSE; 6806aab59a7Smrg } 6816aab59a7Smrg } 6826aab59a7Smrg close(fd); 6836aab59a7Smrg if (found == TRUE) { 6846aab59a7Smrg if (*pproto != NULL) { 6856aab59a7Smrg *protocol = *pproto; 6866aab59a7Smrg } 6876aab59a7Smrg *device = *pdev; 6886aab59a7Smrg return TRUE; 6896aab59a7Smrg } 6906aab59a7Smrg } 6916aab59a7Smrg } 6926aab59a7Smrg return FALSE; 6936aab59a7Smrg} 6946aab59a7Smrg 6956aab59a7Smrgstatic const char * 6966aab59a7SmrgSetupAuto(InputInfoPtr pInfo, int *protoPara) 6976aab59a7Smrg{ 6986aab59a7Smrg const char *pdev = NULL; 6996aab59a7Smrg const char *pproto = NULL; 7006aab59a7Smrg MouseDevPtr pMse = pInfo->private; 7016aab59a7Smrg 7026aab59a7Smrg if (pInfo->fd == -1) { 7036aab59a7Smrg /* probe to find device/protocol to use */ 7046aab59a7Smrg if (solarisMouseAutoProbe(pInfo, &pproto, &pdev) != FALSE) { 7056aab59a7Smrg /* Set the Device option. */ 7066aab59a7Smrg pInfo->conf_idev->commonOptions = 7076aab59a7Smrg xf86AddNewOption(pInfo->conf_idev->commonOptions, "Device", pdev); 7086aab59a7Smrg xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n", 7096aab59a7Smrg pInfo->name, pdev); 7106aab59a7Smrg } 7116aab59a7Smrg } else if (pMse->protocolID == PROT_AUTO) { 7126aab59a7Smrg pdev = xf86CheckStrOption(pInfo->conf_idev->commonOptions, 7136aab59a7Smrg "Device", NULL); 7146aab59a7Smrg solarisMouseAutoProbe(pInfo, &pproto, &pdev); 7156aab59a7Smrg } 7166aab59a7Smrg return pproto; 7176aab59a7Smrg} 7186aab59a7Smrg 7196aab59a7Smrgstatic const char * 7206aab59a7SmrgFindDevice(InputInfoPtr pInfo, const char *protocol, int flags) 7216aab59a7Smrg{ 7226aab59a7Smrg const char *pdev = NULL; 7236aab59a7Smrg const char *pproto = protocol; 7246aab59a7Smrg 7256aab59a7Smrg if (solarisMouseAutoProbe(pInfo, &pproto, &pdev) != FALSE) { 7266aab59a7Smrg /* Set the Device option. */ 7276aab59a7Smrg pInfo->conf_idev->commonOptions = 7286aab59a7Smrg xf86AddNewOption(pInfo->conf_idev->commonOptions, "Device", pdev); 7296aab59a7Smrg xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n", 7306aab59a7Smrg pInfo->name, pdev); 7316aab59a7Smrg } 7326aab59a7Smrg return pdev; 7336aab59a7Smrg} 7346aab59a7Smrg 7356aab59a7Smrgstatic int 7366aab59a7SmrgSupportedInterfaces(void) 7376aab59a7Smrg{ 7386aab59a7Smrg /* XXX This needs to be checked. */ 7396aab59a7Smrg return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_XPS2 | MSE_MISC; 7406aab59a7Smrg} 7416aab59a7Smrg 7426aab59a7Smrg_X_EXPORT OSMouseInfoPtr 7436aab59a7Smrgxf86OSMouseInit(int flags) 7446aab59a7Smrg{ 7456aab59a7Smrg OSMouseInfoPtr p; 7466aab59a7Smrg 7476aab59a7Smrg p = xcalloc(sizeof(OSMouseInfoRec), 1); 7486aab59a7Smrg if (!p) 7496aab59a7Smrg return NULL; 7506aab59a7Smrg p->SupportedInterfaces = SupportedInterfaces; 7516aab59a7Smrg p->BuiltinNames = BuiltinNames; 7526aab59a7Smrg p->CheckProtocol = CheckProtocol; 7536aab59a7Smrg p->PreInit = sunMousePreInit; 7546aab59a7Smrg p->DefaultProtocol = DefaultProtocol; 7556aab59a7Smrg p->SetupAuto = SetupAuto; 7566aab59a7Smrg p->FindDevice = FindDevice; 7576aab59a7Smrg 7586aab59a7Smrg return p; 7596aab59a7Smrg} 7606aab59a7Smrg 761