mouse.c revision 7022890b
1659607e0Smrg/* 2659607e0Smrg * 3659607e0Smrg * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 4659607e0Smrg * Copyright 1993 by David Dawes <dawes@xfree86.org> 5659607e0Smrg * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich 6659607e0Smrg * Copyright 1994-2002 by The XFree86 Project, Inc. 7659607e0Smrg * Copyright 2002 by Paul Elliott 8659607e0Smrg * 9659607e0Smrg * Permission to use, copy, modify, distribute, and sell this software and its 10659607e0Smrg * documentation for any purpose is hereby granted without fee, provided that 11659607e0Smrg * the above copyright notice appear in all copies and that both that 12659607e0Smrg * copyright notice and this permission notice appear in supporting 13659607e0Smrg * documentation, and that the names of copyright holders not be 14659607e0Smrg * used in advertising or publicity pertaining to distribution of the 15659607e0Smrg * software without specific, written prior permission. The copyright holders 16659607e0Smrg * make no representations about the suitability of this 17659607e0Smrg * software for any purpose. It is provided "as is" without express or 18659607e0Smrg * implied warranty. 19659607e0Smrg * 20659607e0Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 21659607e0Smrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 22659607e0Smrg * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 23659607e0Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 24659607e0Smrg * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 25659607e0Smrg * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 26659607e0Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 27659607e0Smrg * 28659607e0Smrg */ 29659607e0Smrg/* Patch for PS/2 Intellimouse - Tim Goodwin 1997-11-06. */ 30659607e0Smrg 31659607e0Smrg/* 32659607e0Smrg * [JCH-96/01/21] Added fourth button support for PROT_GLIDEPOINT mouse 33659607e0Smrg * protocol. 34659607e0Smrg */ 35659607e0Smrg 36659607e0Smrg/* 37659607e0Smrg * [TVO-97/03/05] Added microsoft IntelliMouse support 38659607e0Smrg */ 39659607e0Smrg 40659607e0Smrg/* 41659607e0Smrg * [PME-02/08/11] Added suport for drag lock buttons 42659607e0Smrg * for use with 4 button trackballs for convenience 43659607e0Smrg * and to help limited dexterity persons 44659607e0Smrg */ 45659607e0Smrg 46659607e0Smrg#ifdef HAVE_CONFIG_H 47659607e0Smrg#include "config.h" 48659607e0Smrg#endif 49659607e0Smrg 50659607e0Smrg#include <math.h> 51659607e0Smrg#include <string.h> 52659607e0Smrg#include <stdio.h> 53659607e0Smrg#include <stdlib.h> 54659607e0Smrg#define NEED_EVENTS 55659607e0Smrg#include <X11/X.h> 56659607e0Smrg#include <X11/Xproto.h> 57659607e0Smrg 58659607e0Smrg#include "xf86.h" 59659607e0Smrg 60659607e0Smrg#ifdef XINPUT 61659607e0Smrg#include <X11/extensions/XI.h> 62659607e0Smrg#include <X11/extensions/XIproto.h> 63659607e0Smrg#include "extnsionst.h" 64659607e0Smrg#include "extinit.h" 65659607e0Smrg#else 66659607e0Smrg#include "inputstr.h" 67659607e0Smrg#endif 68659607e0Smrg 69659607e0Smrg#include "xf86Xinput.h" 70659607e0Smrg#include "xf86_OSproc.h" 71659607e0Smrg#include "xf86OSmouse.h" 72659607e0Smrg 73659607e0Smrg#ifndef NEED_XF86_TYPES 74659607e0Smrg#define NEED_XF86_TYPES /* for xisb.h when !XFree86LOADER */ 75659607e0Smrg#endif 76659607e0Smrg 775ddc3750Smrg#ifdef __NetBSD__ 785ddc3750Smrg#include <time.h> 795ddc3750Smrg#include <dev/wscons/wsconsio.h> 805ddc3750Smrg#endif 815ddc3750Smrg 82659607e0Smrg#include "compiler.h" 83659607e0Smrg 84659607e0Smrg#include "xisb.h" 85659607e0Smrg#include "mouse.h" 86659607e0Smrg#include "mousePriv.h" 87659607e0Smrg#include "mipointer.h" 88659607e0Smrg 89659607e0Smrgenum { 90659607e0Smrg /* number of bits in mapped nibble */ 91659607e0Smrg NIB_BITS=4, 92659607e0Smrg /* size of map of nibbles to bitmask */ 93659607e0Smrg NIB_SIZE= (1 << NIB_BITS), 94659607e0Smrg /* mask for map */ 95659607e0Smrg NIB_MASK= (NIB_SIZE -1), 96659607e0Smrg /* number of maps to map all the buttons */ 97659607e0Smrg NIB_COUNT = ((MSE_MAXBUTTONS+NIB_BITS-1)/NIB_BITS) 98659607e0Smrg}; 99659607e0Smrg 100659607e0Smrg/*data to be used in implementing trackball drag locks.*/ 101659607e0Smrgtypedef struct _DragLockRec { 102659607e0Smrg 103659607e0Smrg /* Fields used to implement trackball drag locks. */ 104659607e0Smrg /* mask for those buttons that are ordinary drag lock buttons */ 105659607e0Smrg int lockButtonsM; 106659607e0Smrg 107659607e0Smrg /* mask for the master drag lock button if any */ 108659607e0Smrg int masterLockM; 109659607e0Smrg 110659607e0Smrg /* button state up/down from last time adjusted for drag locks */ 111659607e0Smrg int lockLastButtons; 112659607e0Smrg 113659607e0Smrg /* 114659607e0Smrg * true if master lock state i.e. master drag lock 115659607e0Smrg * button has just been pressed 116659607e0Smrg */ 117659607e0Smrg int masterTS; 118659607e0Smrg 119659607e0Smrg /* simulate these buttons being down although they are not */ 120659607e0Smrg int simulatedDown; 121659607e0Smrg 122659607e0Smrg /* 123659607e0Smrg * data to map bits for drag lock buttons to corresponding 124659607e0Smrg * bits for the target buttons 125659607e0Smrg */ 126659607e0Smrg int nib_table[NIB_COUNT][NIB_SIZE]; 127659607e0Smrg 128659607e0Smrg} DragLockRec, *DragLockPtr; 129659607e0Smrg 130659607e0Smrg 131afecbbc8Smrg 132659607e0Smrgstatic const OptionInfoRec *MouseAvailableOptions(void *unused); 133659607e0Smrgstatic InputInfoPtr MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags); 134659607e0Smrg#if 0 135659607e0Smrgstatic void MouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); 136659607e0Smrg#endif 137659607e0Smrg 138659607e0Smrgstatic int MouseProc(DeviceIntPtr device, int what); 139659607e0Smrgstatic Bool MouseConvert(LocalDevicePtr local, int first, int num, int v0, 140659607e0Smrg int v1, int v2, int v3, int v4, int v5, int *x, 141659607e0Smrg int *y); 142659607e0Smrg 143659607e0Smrgstatic void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl); 144659607e0Smrgstatic void MousePostEvent(InputInfoPtr pInfo, int buttons, 145659607e0Smrg int dx, int dy, int dz, int dw); 146659607e0Smrgstatic void MouseReadInput(InputInfoPtr pInfo); 147659607e0Smrgstatic void MouseBlockHandler(pointer data, struct timeval **waitTime, 148659607e0Smrg pointer LastSelectMask); 149659607e0Smrgstatic void MouseWakeupHandler(pointer data, int i, pointer LastSelectMask); 150659607e0Smrgstatic void FlushButtons(MouseDevPtr pMse); 151659607e0Smrg 152659607e0Smrgstatic Bool SetupMouse(InputInfoPtr pInfo); 153659607e0Smrgstatic Bool initMouseHW(InputInfoPtr pInfo); 154659607e0Smrg#ifdef SUPPORT_MOUSE_RESET 155659607e0Smrgstatic Bool mouseReset(InputInfoPtr pInfo, unsigned char val); 156659607e0Smrgstatic void ps2WakeupHandler(pointer data, int i, pointer LastSelectMask); 157659607e0Smrgstatic void ps2BlockHandler(pointer data, struct timeval **waitTime, 158659607e0Smrg pointer LastSelectMask); 159659607e0Smrg#endif 160659607e0Smrg 161659607e0Smrg/* mouse autoprobe stuff */ 162659607e0Smrgstatic const char *autoOSProtocol(InputInfoPtr pInfo, int *protoPara); 163659607e0Smrgstatic void autoProbeMouse(InputInfoPtr pInfo, Bool inSync, Bool lostSync); 164659607e0Smrgstatic void checkForErraticMovements(InputInfoPtr pInfo, int dx, int dy); 165659607e0Smrgstatic Bool collectData(MouseDevPtr pMse, unsigned char u); 166659607e0Smrgstatic void SetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID); 167659607e0Smrgstatic Bool autoGood(MouseDevPtr pMse); 168659607e0Smrg 169659607e0Smrg#undef MOUSE 170659607e0Smrg_X_EXPORT InputDriverRec MOUSE = { 171659607e0Smrg 1, 172659607e0Smrg "mouse", 173659607e0Smrg NULL, 174659607e0Smrg MousePreInit, 175659607e0Smrg /*MouseUnInit,*/NULL, 176659607e0Smrg NULL, 177659607e0Smrg 0 178659607e0Smrg}; 179659607e0Smrg 180659607e0Smrgtypedef enum { 181659607e0Smrg OPTION_ALWAYS_CORE, 182659607e0Smrg OPTION_SEND_CORE_EVENTS, 183659607e0Smrg OPTION_CORE_POINTER, 184659607e0Smrg OPTION_SEND_DRAG_EVENTS, 185659607e0Smrg OPTION_HISTORY_SIZE, 186659607e0Smrg OPTION_DEVICE, 187659607e0Smrg OPTION_PROTOCOL, 188659607e0Smrg OPTION_BUTTONS, 189659607e0Smrg OPTION_EMULATE_3_BUTTONS, 190659607e0Smrg OPTION_EMULATE_3_TIMEOUT, 191659607e0Smrg OPTION_CHORD_MIDDLE, 192659607e0Smrg OPTION_FLIP_XY, 193659607e0Smrg OPTION_INV_X, 194659607e0Smrg OPTION_INV_Y, 195659607e0Smrg OPTION_ANGLE_OFFSET, 196659607e0Smrg OPTION_Z_AXIS_MAPPING, 197659607e0Smrg OPTION_SAMPLE_RATE, 198659607e0Smrg OPTION_RESOLUTION, 199659607e0Smrg OPTION_EMULATE_WHEEL, 200659607e0Smrg OPTION_EMU_WHEEL_BUTTON, 201659607e0Smrg OPTION_EMU_WHEEL_INERTIA, 202659607e0Smrg OPTION_EMU_WHEEL_TIMEOUT, 203659607e0Smrg OPTION_X_AXIS_MAPPING, 204659607e0Smrg OPTION_Y_AXIS_MAPPING, 205659607e0Smrg OPTION_AUTO_SOFT, 206659607e0Smrg OPTION_CLEAR_DTR, 207659607e0Smrg OPTION_CLEAR_RTS, 208659607e0Smrg OPTION_BAUD_RATE, 209659607e0Smrg OPTION_DATA_BITS, 210659607e0Smrg OPTION_STOP_BITS, 211659607e0Smrg OPTION_PARITY, 212659607e0Smrg OPTION_FLOW_CONTROL, 213659607e0Smrg OPTION_VTIME, 214659607e0Smrg OPTION_VMIN, 215659607e0Smrg OPTION_DRAGLOCKBUTTONS, 216659607e0Smrg OPTION_DOUBLECLICK_BUTTONS, 217659607e0Smrg OPTION_BUTTON_MAPPING, 218659607e0Smrg OPTION_SENSITIVITY 219659607e0Smrg} MouseOpts; 220659607e0Smrg 221659607e0Smrgstatic const OptionInfoRec mouseOptions[] = { 222659607e0Smrg { OPTION_ALWAYS_CORE, "AlwaysCore", OPTV_BOOLEAN, {0}, FALSE }, 223659607e0Smrg { OPTION_SEND_CORE_EVENTS, "SendCoreEvents", OPTV_BOOLEAN, {0}, FALSE }, 224659607e0Smrg { OPTION_CORE_POINTER, "CorePointer", OPTV_BOOLEAN, {0}, FALSE }, 225659607e0Smrg { OPTION_SEND_DRAG_EVENTS, "SendDragEvents", OPTV_BOOLEAN, {0}, FALSE }, 226659607e0Smrg { OPTION_HISTORY_SIZE, "HistorySize", OPTV_INTEGER, {0}, FALSE }, 227659607e0Smrg { OPTION_DEVICE, "Device", OPTV_STRING, {0}, FALSE }, 228659607e0Smrg { OPTION_PROTOCOL, "Protocol", OPTV_STRING, {0}, FALSE }, 229659607e0Smrg { OPTION_BUTTONS, "Buttons", OPTV_INTEGER, {0}, FALSE }, 230659607e0Smrg { OPTION_EMULATE_3_BUTTONS, "Emulate3Buttons",OPTV_BOOLEAN, {0}, FALSE }, 231659607e0Smrg { OPTION_EMULATE_3_TIMEOUT, "Emulate3Timeout",OPTV_INTEGER, {0}, FALSE }, 232659607e0Smrg { OPTION_CHORD_MIDDLE, "ChordMiddle", OPTV_BOOLEAN, {0}, FALSE }, 233659607e0Smrg { OPTION_FLIP_XY, "FlipXY", OPTV_BOOLEAN, {0}, FALSE }, 234659607e0Smrg { OPTION_INV_X, "InvX", OPTV_BOOLEAN, {0}, FALSE }, 235659607e0Smrg { OPTION_INV_Y, "InvY", OPTV_BOOLEAN, {0}, FALSE }, 236659607e0Smrg { OPTION_ANGLE_OFFSET, "AngleOffset", OPTV_INTEGER, {0}, FALSE }, 237659607e0Smrg { OPTION_Z_AXIS_MAPPING, "ZAxisMapping", OPTV_STRING, {0}, FALSE }, 238659607e0Smrg { OPTION_SAMPLE_RATE, "SampleRate", OPTV_INTEGER, {0}, FALSE }, 239659607e0Smrg { OPTION_RESOLUTION, "Resolution", OPTV_INTEGER, {0}, FALSE }, 240659607e0Smrg { OPTION_EMULATE_WHEEL, "EmulateWheel", OPTV_BOOLEAN, {0}, FALSE }, 241659607e0Smrg { OPTION_EMU_WHEEL_BUTTON, "EmulateWheelButton", OPTV_INTEGER, {0}, FALSE }, 242659607e0Smrg { OPTION_EMU_WHEEL_INERTIA, "EmulateWheelInertia", OPTV_INTEGER, {0}, FALSE }, 243659607e0Smrg { OPTION_EMU_WHEEL_TIMEOUT, "EmulateWheelTimeout", OPTV_INTEGER, {0}, FALSE }, 244659607e0Smrg { OPTION_X_AXIS_MAPPING, "XAxisMapping", OPTV_STRING, {0}, FALSE }, 245659607e0Smrg { OPTION_Y_AXIS_MAPPING, "YAxisMapping", OPTV_STRING, {0}, FALSE }, 246659607e0Smrg { OPTION_AUTO_SOFT, "AutoSoft", OPTV_BOOLEAN, {0}, FALSE }, 247659607e0Smrg /* serial options */ 248659607e0Smrg { OPTION_CLEAR_DTR, "ClearDTR", OPTV_BOOLEAN, {0}, FALSE }, 249659607e0Smrg { OPTION_CLEAR_RTS, "ClearRTS", OPTV_BOOLEAN, {0}, FALSE }, 250659607e0Smrg { OPTION_BAUD_RATE, "BaudRate", OPTV_INTEGER, {0}, FALSE }, 251659607e0Smrg { OPTION_DATA_BITS, "DataBits", OPTV_INTEGER, {0}, FALSE }, 252659607e0Smrg { OPTION_STOP_BITS, "StopBits", OPTV_INTEGER, {0}, FALSE }, 253659607e0Smrg { OPTION_PARITY, "Parity", OPTV_STRING, {0}, FALSE }, 254659607e0Smrg { OPTION_FLOW_CONTROL, "FlowControl", OPTV_STRING, {0}, FALSE }, 255659607e0Smrg { OPTION_VTIME, "VTime", OPTV_INTEGER, {0}, FALSE }, 256659607e0Smrg { OPTION_VMIN, "VMin", OPTV_INTEGER, {0}, FALSE }, 257659607e0Smrg /* end serial options */ 258659607e0Smrg { OPTION_DRAGLOCKBUTTONS, "DragLockButtons",OPTV_STRING, {0}, FALSE }, 259659607e0Smrg { OPTION_DOUBLECLICK_BUTTONS,"DoubleClickButtons", OPTV_STRING, {0}, FALSE }, 260659607e0Smrg { OPTION_BUTTON_MAPPING, "ButtonMapping", OPTV_STRING, {0}, FALSE }, 261659607e0Smrg { OPTION_SENSITIVITY, "Sensitivity", OPTV_REAL, {0}, FALSE }, 262659607e0Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 263659607e0Smrg}; 264659607e0Smrg 265659607e0Smrg#define RETRY_COUNT 4 266659607e0Smrg 267659607e0Smrg/* 268659607e0Smrg * Microsoft (all serial models), Logitech MouseMan, First Mouse, etc, 269659607e0Smrg * ALPS GlidePoint, Thinking Mouse. 270659607e0Smrg */ 271659607e0Smrgstatic const char *msDefaults[] = { 272659607e0Smrg "BaudRate", "1200", 273659607e0Smrg "DataBits", "7", 274659607e0Smrg "StopBits", "1", 275659607e0Smrg "Parity", "None", 276659607e0Smrg "FlowControl", "None", 277659607e0Smrg "VTime", "0", 278659607e0Smrg "VMin", "1", 279659607e0Smrg NULL 280659607e0Smrg}; 281659607e0Smrg/* MouseSystems */ 282659607e0Smrgstatic const char *mlDefaults[] = { 283659607e0Smrg "BaudRate", "1200", 284659607e0Smrg "DataBits", "8", 285659607e0Smrg "StopBits", "2", 286659607e0Smrg "Parity", "None", 287659607e0Smrg "FlowControl", "None", 288659607e0Smrg "VTime", "0", 289659607e0Smrg "VMin", "1", 290659607e0Smrg NULL 291659607e0Smrg}; 292659607e0Smrg/* MMSeries */ 293659607e0Smrgstatic const char *mmDefaults[] = { 294659607e0Smrg "BaudRate", "1200", 295659607e0Smrg "DataBits", "8", 296659607e0Smrg "StopBits", "1", 297659607e0Smrg "Parity", "Odd", 298659607e0Smrg "FlowControl", "None", 299659607e0Smrg "VTime", "0", 300659607e0Smrg "VMin", "1", 301659607e0Smrg NULL 302659607e0Smrg}; 303659607e0Smrg#if 0 304659607e0Smrg/* Logitech series 9 *//* same as msc: now mlDefaults */ 305659607e0Smrgstatic const char *logiDefaults[] = { 306659607e0Smrg "BaudRate", "1200", 307659607e0Smrg "DataBits", "8", 308659607e0Smrg "StopBits", "2", 309659607e0Smrg "Parity", "None", 310659607e0Smrg "FlowControl", "None", 311659607e0Smrg "VTime", "0", 312659607e0Smrg "VMin", "1", 313659607e0Smrg NULL 314659607e0Smrg}; 315659607e0Smrg#endif 316659607e0Smrg/* Hitachi Tablet */ 317659607e0Smrgstatic const char *mmhitDefaults[] = { 318659607e0Smrg "BaudRate", "1200", 319659607e0Smrg "DataBits", "8", 320659607e0Smrg "StopBits", "1", 321659607e0Smrg "Parity", "None", 322659607e0Smrg "FlowControl", "None", 323659607e0Smrg "VTime", "0", 324659607e0Smrg "VMin", "1", 325659607e0Smrg NULL 326659607e0Smrg}; 327659607e0Smrg/* AceCad Tablet */ 328659607e0Smrgstatic const char *acecadDefaults[] = { 329659607e0Smrg "BaudRate", "9600", 330659607e0Smrg "DataBits", "8", 331659607e0Smrg "StopBits", "1", 332659607e0Smrg "Parity", "Odd", 333659607e0Smrg "FlowControl", "None", 334659607e0Smrg "VTime", "0", 335659607e0Smrg "VMin", "1", 336659607e0Smrg NULL 337659607e0Smrg}; 338659607e0Smrg 339659607e0Smrgstatic MouseProtocolRec mouseProtocols[] = { 340659607e0Smrg 341659607e0Smrg /* Serial protocols */ 342659607e0Smrg { "Microsoft", MSE_SERIAL, msDefaults, PROT_MS }, 343659607e0Smrg { "MouseSystems", MSE_SERIAL, mlDefaults, PROT_MSC }, 344659607e0Smrg { "MMSeries", MSE_SERIAL, mmDefaults, PROT_MM }, 345659607e0Smrg { "Logitech", MSE_SERIAL, mlDefaults, PROT_LOGI }, 346659607e0Smrg { "MouseMan", MSE_SERIAL, msDefaults, PROT_LOGIMAN }, 347659607e0Smrg { "MMHitTab", MSE_SERIAL, mmhitDefaults, PROT_MMHIT }, 348659607e0Smrg { "GlidePoint", MSE_SERIAL, msDefaults, PROT_GLIDE }, 349659607e0Smrg { "IntelliMouse", MSE_SERIAL, msDefaults, PROT_IMSERIAL }, 350659607e0Smrg { "ThinkingMouse", MSE_SERIAL, msDefaults, PROT_THINKING }, 351659607e0Smrg { "AceCad", MSE_SERIAL, acecadDefaults, PROT_ACECAD }, 352659607e0Smrg { "ValuMouseScroll", MSE_SERIAL, msDefaults, PROT_VALUMOUSESCROLL }, 353659607e0Smrg 354659607e0Smrg /* Standard PS/2 */ 355659607e0Smrg { "PS/2", MSE_PS2, NULL, PROT_PS2 }, 356659607e0Smrg { "GenericPS/2", MSE_PS2, NULL, PROT_GENPS2 }, 357659607e0Smrg 358659607e0Smrg /* Extended PS/2 */ 359659607e0Smrg { "ImPS/2", MSE_XPS2, NULL, PROT_IMPS2 }, 360659607e0Smrg { "ExplorerPS/2", MSE_XPS2, NULL, PROT_EXPPS2 }, 361659607e0Smrg { "ThinkingMousePS/2", MSE_XPS2, NULL, PROT_THINKPS2 }, 362659607e0Smrg { "MouseManPlusPS/2", MSE_XPS2, NULL, PROT_MMPS2 }, 363659607e0Smrg { "GlidePointPS/2", MSE_XPS2, NULL, PROT_GLIDEPS2 }, 364659607e0Smrg { "NetMousePS/2", MSE_XPS2, NULL, PROT_NETPS2 }, 365659607e0Smrg { "NetScrollPS/2", MSE_XPS2, NULL, PROT_NETSCPS2 }, 366659607e0Smrg 367659607e0Smrg /* Bus Mouse */ 368659607e0Smrg { "BusMouse", MSE_BUS, NULL, PROT_BM }, 369659607e0Smrg 370659607e0Smrg /* Auto-detect (PnP) */ 371659607e0Smrg { "Auto", MSE_AUTO, NULL, PROT_AUTO }, 372659607e0Smrg 373659607e0Smrg /* Misc (usually OS-specific) */ 374659607e0Smrg { "SysMouse", MSE_MISC, mlDefaults, PROT_SYSMOUSE }, 375659607e0Smrg 376659607e0Smrg /* end of list */ 377659607e0Smrg { NULL, MSE_NONE, NULL, PROT_UNKNOWN } 378659607e0Smrg}; 379659607e0Smrg 380659607e0Smrg/*ARGSUSED*/ 381659607e0Smrgstatic const OptionInfoRec * 382659607e0SmrgMouseAvailableOptions(void *unused) 383659607e0Smrg{ 384659607e0Smrg return (mouseOptions); 385659607e0Smrg} 386659607e0Smrg 387659607e0Smrg/* Process options common to all mouse types. */ 388659607e0Smrgstatic void 389659607e0SmrgMouseCommonOptions(InputInfoPtr pInfo) 390659607e0Smrg{ 391659607e0Smrg MouseDevPtr pMse; 392659607e0Smrg MessageType buttons_from = X_CONFIG; 393659607e0Smrg char *s; 394659607e0Smrg int origButtons; 395659607e0Smrg int i; 396659607e0Smrg 397659607e0Smrg pMse = pInfo->private; 398659607e0Smrg 399659607e0Smrg pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0); 400659607e0Smrg if (!pMse->buttons) { 401659607e0Smrg pMse->buttons = MSE_DFLTBUTTONS; 402659607e0Smrg buttons_from = X_DEFAULT; 403659607e0Smrg } 404659607e0Smrg origButtons = pMse->buttons; 405659607e0Smrg 406659607e0Smrg pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options, 407659607e0Smrg "Emulate3Buttons", FALSE); 408659607e0Smrg if (!xf86FindOptionValue(pInfo->options,"Emulate3Buttons")) { 409659607e0Smrg pMse->emulate3ButtonsSoft = TRUE; 410659607e0Smrg pMse->emulate3Buttons = TRUE; 411659607e0Smrg } 412659607e0Smrg 413659607e0Smrg pMse->emulate3Timeout = xf86SetIntOption(pInfo->options, 414659607e0Smrg "Emulate3Timeout", 50); 415659607e0Smrg if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) { 416659607e0Smrg MessageType from = X_CONFIG; 417659607e0Smrg if (pMse->emulate3ButtonsSoft) 418659607e0Smrg from = X_DEFAULT; 419659607e0Smrg xf86Msg(from, "%s: Emulate3Buttons, Emulate3Timeout: %d\n", 420659607e0Smrg pInfo->name, pMse->emulate3Timeout); 421659607e0Smrg } 422659607e0Smrg 423659607e0Smrg pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE); 424659607e0Smrg if (pMse->chordMiddle) 425659607e0Smrg xf86Msg(X_CONFIG, "%s: ChordMiddle\n", pInfo->name); 426659607e0Smrg pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE); 427659607e0Smrg if (pMse->flipXY) 428659607e0Smrg xf86Msg(X_CONFIG, "%s: FlipXY\n", pInfo->name); 429659607e0Smrg if (xf86SetBoolOption(pInfo->options, "InvX", FALSE)) { 430659607e0Smrg pMse->invX = -1; 431659607e0Smrg xf86Msg(X_CONFIG, "%s: InvX\n", pInfo->name); 432659607e0Smrg } else 433659607e0Smrg pMse->invX = 1; 434659607e0Smrg if (xf86SetBoolOption(pInfo->options, "InvY", FALSE)) { 435659607e0Smrg pMse->invY = -1; 436659607e0Smrg xf86Msg(X_CONFIG, "%s: InvY\n", pInfo->name); 437659607e0Smrg } else 438659607e0Smrg pMse->invY = 1; 439659607e0Smrg pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0); 440659607e0Smrg 441659607e0Smrg 442659607e0Smrg if (pMse->pDragLock) 443659607e0Smrg xfree(pMse->pDragLock); 444659607e0Smrg pMse->pDragLock = NULL; 445659607e0Smrg 446659607e0Smrg s = xf86SetStrOption(pInfo->options, "DragLockButtons", NULL); 447659607e0Smrg 448659607e0Smrg if (s) { 449659607e0Smrg int lock; /* lock button */ 450659607e0Smrg int target; /* target button */ 451659607e0Smrg int lockM,targetM; /* bitmasks for drag lock, target */ 452659607e0Smrg int i, j; /* indexes */ 453659607e0Smrg char *s1; /* parse input string */ 454659607e0Smrg DragLockPtr pLock; 455659607e0Smrg 456659607e0Smrg pLock = pMse->pDragLock = xcalloc(1, sizeof(DragLockRec)); 457659607e0Smrg /* init code */ 458659607e0Smrg 459659607e0Smrg /* initial string to be taken apart */ 460659607e0Smrg s1 = s; 461659607e0Smrg 462659607e0Smrg /* keep getting numbers which are buttons */ 463659607e0Smrg while ((s1 != NULL) && (lock = strtol(s1, &s1, 10)) != 0) { 464659607e0Smrg 465659607e0Smrg /* check sanity for a button */ 466659607e0Smrg if ((lock < 0) || (lock > MSE_MAXBUTTONS)) { 467659607e0Smrg xf86Msg(X_WARNING, "DragLock: Invalid button number = %d\n", 468659607e0Smrg lock); 469659607e0Smrg break; 470659607e0Smrg }; 471659607e0Smrg /* turn into a button mask */ 472659607e0Smrg lockM = 1 << (lock - 1); 473659607e0Smrg 474659607e0Smrg /* try to get drag lock button */ 475659607e0Smrg if ((s1 == NULL) || ((target=strtol(s1, &s1, 10)) == 0)) { 476659607e0Smrg /*if no target, must be a master drag lock button */ 477659607e0Smrg /* save master drag lock mask */ 478659607e0Smrg pLock->masterLockM = lockM; 479659607e0Smrg xf86Msg(X_CONFIG, 480659607e0Smrg "DragLock button %d is master drag lock", 481659607e0Smrg lock); 482659607e0Smrg } else { 483659607e0Smrg /* have target button number*/ 484659607e0Smrg /* check target button number for sanity */ 485659607e0Smrg if ((target < 0) || (target > MSE_MAXBUTTONS)) { 486659607e0Smrg xf86Msg(X_WARNING, 487659607e0Smrg "DragLock: Invalid button number for target=%d\n", 488659607e0Smrg target); 489659607e0Smrg break; 490659607e0Smrg } 491659607e0Smrg 492659607e0Smrg /* target button mask */ 493659607e0Smrg targetM = 1 << (target - 1); 494659607e0Smrg 495659607e0Smrg xf86Msg(X_CONFIG, 496659607e0Smrg "DragLock: button %d is drag lock for button %d\n", 497659607e0Smrg lock,target); 498659607e0Smrg lock--; 499659607e0Smrg 500659607e0Smrg /* initialize table that maps drag lock mask to target mask */ 501659607e0Smrg pLock->nib_table[lock / NIB_BITS][1 << (lock % NIB_BITS)] = 502659607e0Smrg targetM; 503659607e0Smrg 504659607e0Smrg /* add new drag lock to mask of drag locks */ 505659607e0Smrg pLock->lockButtonsM |= lockM; 506659607e0Smrg } 507659607e0Smrg 508659607e0Smrg } 509659607e0Smrg 510659607e0Smrg /* 511659607e0Smrg * fill out rest of map that maps sets of drag lock buttons 512659607e0Smrg * to sets of target buttons, in the form of masks 513659607e0Smrg */ 514659607e0Smrg 515659607e0Smrg /* for each nibble */ 516659607e0Smrg for (i = 0; i < NIB_COUNT; i++) { 517659607e0Smrg /* for each possible set of bits for that nibble */ 518659607e0Smrg for (j = 0; j < NIB_SIZE; j++) { 519659607e0Smrg int ff, fM, otherbits; 520659607e0Smrg 521659607e0Smrg /* get first bit set in j*/ 522659607e0Smrg ff = ffs(j) - 1; 523659607e0Smrg /* if 0 bits set nothing to do */ 524659607e0Smrg if (ff >= 0) { 525659607e0Smrg /* form mask for fist bit set */ 526659607e0Smrg fM = 1 << ff; 527659607e0Smrg /* mask off first bit set to get remaining bits set*/ 528659607e0Smrg otherbits = j & ~fM; 529659607e0Smrg /* 530659607e0Smrg * if otherbits =0 then only 1 bit set 531659607e0Smrg * so j=fM 532659607e0Smrg * nib_table[i][fM] already calculated if fM has 533659607e0Smrg * only 1 bit set. 534659607e0Smrg * nib_table[i][j] has already been filled in 535659607e0Smrg * by previous loop. otherwise 536659607e0Smrg * otherbits < j so nibtable[i][otherbits] 537659607e0Smrg * has already been calculated. 538659607e0Smrg */ 539659607e0Smrg if (otherbits) 540659607e0Smrg pLock->nib_table[i][j] = 541659607e0Smrg pLock->nib_table[i][fM] | 542659607e0Smrg pLock->nib_table[i][otherbits]; 543659607e0Smrg 544659607e0Smrg } 545659607e0Smrg } 546659607e0Smrg } 547659607e0Smrg xfree(s); 548659607e0Smrg } 549659607e0Smrg 550659607e0Smrg s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5"); 551659607e0Smrg if (s) { 552659607e0Smrg int b1 = 0, b2 = 0, b3 = 0, b4 = 0; 553659607e0Smrg char *msg = NULL; 554659607e0Smrg 555659607e0Smrg pMse->negativeZ = pMse->positiveZ = MSE_NOAXISMAP; 556659607e0Smrg pMse->negativeW = pMse->positiveW = MSE_NOAXISMAP; 557659607e0Smrg if (!xf86NameCmp(s, "x")) { 558659607e0Smrg pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX; 559659607e0Smrg msg = xstrdup("X axis"); 560659607e0Smrg } else if (!xf86NameCmp(s, "y")) { 561659607e0Smrg pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY; 562659607e0Smrg msg = xstrdup("Y axis"); 563659607e0Smrg } else if (sscanf(s, "%d %d %d %d", &b1, &b2, &b3, &b4) >= 2 && 564659607e0Smrg b1 > 0 && b1 <= MSE_MAXBUTTONS && 565659607e0Smrg b2 > 0 && b2 <= MSE_MAXBUTTONS) { 566659607e0Smrg msg = xstrdup("buttons XX and YY"); 567659607e0Smrg if (msg) 568659607e0Smrg sprintf(msg, "buttons %d and %d", b1, b2); 569659607e0Smrg pMse->negativeZ = 1 << (b1-1); 570659607e0Smrg pMse->positiveZ = 1 << (b2-1); 571659607e0Smrg if (b3 > 0 && b3 <= MSE_MAXBUTTONS && 572659607e0Smrg b4 > 0 && b4 <= MSE_MAXBUTTONS) { 573659607e0Smrg if (msg) 574659607e0Smrg xfree(msg); 575659607e0Smrg msg = xstrdup("buttons XX, YY, ZZ and WW"); 576659607e0Smrg if (msg) 577659607e0Smrg sprintf(msg, "buttons %d, %d, %d and %d", b1, b2, b3, b4); 578659607e0Smrg pMse->negativeW = 1 << (b3-1); 579659607e0Smrg pMse->positiveW = 1 << (b4-1); 580659607e0Smrg } 581659607e0Smrg if (b1 > pMse->buttons) pMse->buttons = b1; 582659607e0Smrg if (b2 > pMse->buttons) pMse->buttons = b2; 583659607e0Smrg if (b3 > pMse->buttons) pMse->buttons = b3; 584659607e0Smrg if (b4 > pMse->buttons) pMse->buttons = b4; 585659607e0Smrg } 586659607e0Smrg if (msg) { 587659607e0Smrg xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg); 588659607e0Smrg xfree(msg); 589659607e0Smrg } else { 590659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n", 591659607e0Smrg pInfo->name, s); 592659607e0Smrg } 593659607e0Smrg xfree(s); 594659607e0Smrg } 595659607e0Smrg if (xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE)) { 596659607e0Smrg Bool yFromConfig = FALSE; 597659607e0Smrg int wheelButton; 598659607e0Smrg 599659607e0Smrg pMse->emulateWheel = TRUE; 600659607e0Smrg wheelButton = xf86SetIntOption(pInfo->options, 601659607e0Smrg "EmulateWheelButton", 4); 602659607e0Smrg if (wheelButton < 0 || wheelButton > MSE_MAXBUTTONS) { 603659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid EmulateWheelButton value: %d\n", 604659607e0Smrg pInfo->name, wheelButton); 605659607e0Smrg wheelButton = 4; 606659607e0Smrg } 607659607e0Smrg pMse->wheelButton = wheelButton; 608659607e0Smrg 609659607e0Smrg pMse->wheelInertia = xf86SetIntOption(pInfo->options, 610659607e0Smrg "EmulateWheelInertia", 10); 611659607e0Smrg if (pMse->wheelInertia <= 0) { 612659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid EmulateWheelInertia value: %d\n", 613659607e0Smrg pInfo->name, pMse->wheelInertia); 614659607e0Smrg pMse->wheelInertia = 10; 615659607e0Smrg } 616659607e0Smrg pMse->wheelButtonTimeout = xf86SetIntOption(pInfo->options, 617659607e0Smrg "EmulateWheelTimeout", 200); 618659607e0Smrg if (pMse->wheelButtonTimeout <= 0) { 619659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid EmulateWheelTimeout value: %d\n", 620659607e0Smrg pInfo->name, pMse->wheelButtonTimeout); 621659607e0Smrg pMse->wheelButtonTimeout = 200; 622659607e0Smrg } 623659607e0Smrg 624659607e0Smrg pMse->negativeX = MSE_NOAXISMAP; 625659607e0Smrg pMse->positiveX = MSE_NOAXISMAP; 626659607e0Smrg s = xf86SetStrOption(pInfo->options, "XAxisMapping", NULL); 627659607e0Smrg if (s) { 628659607e0Smrg int b1 = 0, b2 = 0; 629659607e0Smrg char *msg = NULL; 630659607e0Smrg 631659607e0Smrg if ((sscanf(s, "%d %d", &b1, &b2) == 2) && 632659607e0Smrg b1 > 0 && b1 <= MSE_MAXBUTTONS && 633659607e0Smrg b2 > 0 && b2 <= MSE_MAXBUTTONS) { 634659607e0Smrg msg = xstrdup("buttons XX and YY"); 635659607e0Smrg if (msg) 636659607e0Smrg sprintf(msg, "buttons %d and %d", b1, b2); 637659607e0Smrg pMse->negativeX = b1; 638659607e0Smrg pMse->positiveX = b2; 639659607e0Smrg if (b1 > pMse->buttons) pMse->buttons = b1; 640659607e0Smrg if (b2 > pMse->buttons) pMse->buttons = b2; 641659607e0Smrg } else { 642659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid XAxisMapping value: \"%s\"\n", 643659607e0Smrg pInfo->name, s); 644659607e0Smrg } 645659607e0Smrg if (msg) { 646659607e0Smrg xf86Msg(X_CONFIG, "%s: XAxisMapping: %s\n", pInfo->name, msg); 647659607e0Smrg xfree(msg); 648659607e0Smrg } 649659607e0Smrg xfree(s); 650659607e0Smrg } 651659607e0Smrg s = xf86SetStrOption(pInfo->options, "YAxisMapping", NULL); 652659607e0Smrg if (s) { 653659607e0Smrg int b1 = 0, b2 = 0; 654659607e0Smrg char *msg = NULL; 655659607e0Smrg 656659607e0Smrg if ((sscanf(s, "%d %d", &b1, &b2) == 2) && 657659607e0Smrg b1 > 0 && b1 <= MSE_MAXBUTTONS && 658659607e0Smrg b2 > 0 && b2 <= MSE_MAXBUTTONS) { 659659607e0Smrg msg = xstrdup("buttons XX and YY"); 660659607e0Smrg if (msg) 661659607e0Smrg sprintf(msg, "buttons %d and %d", b1, b2); 662659607e0Smrg pMse->negativeY = b1; 663659607e0Smrg pMse->positiveY = b2; 664659607e0Smrg if (b1 > pMse->buttons) pMse->buttons = b1; 665659607e0Smrg if (b2 > pMse->buttons) pMse->buttons = b2; 666659607e0Smrg yFromConfig = TRUE; 667659607e0Smrg } else { 668659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid YAxisMapping value: \"%s\"\n", 669659607e0Smrg pInfo->name, s); 670659607e0Smrg } 671659607e0Smrg if (msg) { 672659607e0Smrg xf86Msg(X_CONFIG, "%s: YAxisMapping: %s\n", pInfo->name, msg); 673659607e0Smrg xfree(msg); 674659607e0Smrg } 675659607e0Smrg xfree(s); 676659607e0Smrg } 677659607e0Smrg if (!yFromConfig) { 678659607e0Smrg pMse->negativeY = 4; 679659607e0Smrg pMse->positiveY = 5; 680659607e0Smrg if (pMse->negativeY > pMse->buttons) 681659607e0Smrg pMse->buttons = pMse->negativeY; 682659607e0Smrg if (pMse->positiveY > pMse->buttons) 683659607e0Smrg pMse->buttons = pMse->positiveY; 684659607e0Smrg xf86Msg(X_DEFAULT, "%s: YAxisMapping: buttons %d and %d\n", 685659607e0Smrg pInfo->name, pMse->negativeY, pMse->positiveY); 686659607e0Smrg } 687659607e0Smrg xf86Msg(X_CONFIG, "%s: EmulateWheel, EmulateWheelButton: %d, " 688659607e0Smrg "EmulateWheelInertia: %d, " 689659607e0Smrg "EmulateWheelTimeout: %d\n", 690659607e0Smrg pInfo->name, wheelButton, pMse->wheelInertia, 691659607e0Smrg pMse->wheelButtonTimeout); 692659607e0Smrg } 693659607e0Smrg s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL); 694659607e0Smrg if (s) { 695659607e0Smrg int b, n = 0; 696659607e0Smrg char *s1 = s; 697659607e0Smrg /* keep getting numbers which are buttons */ 698659607e0Smrg while (s1 && n < MSE_MAXBUTTONS && (b = strtol(s1, &s1, 10)) != 0) { 699659607e0Smrg /* check sanity for a button */ 700659607e0Smrg if (b < 0 || b > MSE_MAXBUTTONS) { 701659607e0Smrg xf86Msg(X_WARNING, 702659607e0Smrg "ButtonMapping: Invalid button number = %d\n", b); 703659607e0Smrg break; 704659607e0Smrg }; 705659607e0Smrg pMse->buttonMap[n++] = 1 << (b-1); 706659607e0Smrg if (b > pMse->buttons) pMse->buttons = b; 707659607e0Smrg } 708659607e0Smrg xfree(s); 709659607e0Smrg } 710659607e0Smrg /* get maximum of mapped buttons */ 711659607e0Smrg for (i = pMse->buttons-1; i >= 0; i--) { 712659607e0Smrg int f = ffs (pMse->buttonMap[i]); 713659607e0Smrg if (f > pMse->buttons) 714659607e0Smrg pMse->buttons = f; 715659607e0Smrg } 716659607e0Smrg if (origButtons != pMse->buttons) 717659607e0Smrg buttons_from = X_CONFIG; 718659607e0Smrg xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons); 719659607e0Smrg 720659607e0Smrg pMse->doubleClickSourceButtonMask = 0; 721659607e0Smrg pMse->doubleClickTargetButtonMask = 0; 722659607e0Smrg pMse->doubleClickTargetButton = 0; 723659607e0Smrg s = xf86SetStrOption(pInfo->options, "DoubleClickButtons", NULL); 724659607e0Smrg if (s) { 725659607e0Smrg int b1 = 0, b2 = 0; 726659607e0Smrg char *msg = NULL; 727659607e0Smrg 728659607e0Smrg if ((sscanf(s, "%d %d", &b1, &b2) == 2) && 729659607e0Smrg (b1 > 0) && (b1 <= MSE_MAXBUTTONS) && (b2 > 0) && (b2 <= MSE_MAXBUTTONS)) { 730659607e0Smrg msg = xstrdup("buttons XX and YY"); 731659607e0Smrg if (msg) 732659607e0Smrg sprintf(msg, "buttons %d and %d", b1, b2); 733659607e0Smrg pMse->doubleClickTargetButton = b1; 734659607e0Smrg pMse->doubleClickTargetButtonMask = 1 << (b1 - 1); 735659607e0Smrg pMse->doubleClickSourceButtonMask = 1 << (b2 - 1); 736659607e0Smrg if (b1 > pMse->buttons) pMse->buttons = b1; 737659607e0Smrg if (b2 > pMse->buttons) pMse->buttons = b2; 738659607e0Smrg } else { 739659607e0Smrg xf86Msg(X_WARNING, "%s: Invalid DoubleClickButtons value: \"%s\"\n", 740659607e0Smrg pInfo->name, s); 741659607e0Smrg } 742659607e0Smrg if (msg) { 743659607e0Smrg xf86Msg(X_CONFIG, "%s: DoubleClickButtons: %s\n", pInfo->name, msg); 744659607e0Smrg xfree(msg); 745659607e0Smrg } 746659607e0Smrg xfree(s); 747659607e0Smrg } 748659607e0Smrg} 749659607e0Smrg/* 750659607e0Smrg * map bits corresponding to lock buttons. 751659607e0Smrg * for each bit for a lock button, 752659607e0Smrg * turn on bit corresponding to button button that the lock 753659607e0Smrg * button services. 754659607e0Smrg */ 755659607e0Smrg 756659607e0Smrgstatic int 757659607e0Smrglock2targetMap(DragLockPtr pLock, int lockMask) 758659607e0Smrg{ 759659607e0Smrg int result,i; 760659607e0Smrg result = 0; 761659607e0Smrg 762659607e0Smrg /* 763659607e0Smrg * for each nibble group of bits, use 764659607e0Smrg * map for that group to get corresponding 765659607e0Smrg * bits, turn them on. 766659607e0Smrg * if 4 or less buttons only first map will 767659607e0Smrg * need to be used. 768659607e0Smrg */ 769659607e0Smrg for (i = 0; (i < NIB_COUNT) && lockMask; i++) { 770659607e0Smrg result |= pLock->nib_table[i][lockMask& NIB_MASK]; 771659607e0Smrg 772659607e0Smrg lockMask &= ~NIB_MASK; 773659607e0Smrg lockMask >>= NIB_BITS; 774659607e0Smrg } 775659607e0Smrg return result; 776659607e0Smrg} 777659607e0Smrg 778659607e0Smrgstatic void 779659607e0SmrgMouseHWOptions(InputInfoPtr pInfo) 780659607e0Smrg{ 781659607e0Smrg MouseDevPtr pMse = pInfo->private; 782659607e0Smrg mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 783659607e0Smrg 784659607e0Smrg if (mPriv == NULL) 785659607e0Smrg return; 786659607e0Smrg 787659607e0Smrg if ((mPriv->soft 788659607e0Smrg = xf86SetBoolOption(pInfo->options, "AutoSoft", FALSE))) { 789659607e0Smrg xf86Msg(X_CONFIG, "Don't initialize mouse when auto-probing\n"); 790659607e0Smrg } 791659607e0Smrg pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0); 792659607e0Smrg if (pMse->sampleRate) { 793659607e0Smrg xf86Msg(X_CONFIG, "%s: SampleRate: %d\n", pInfo->name, 794659607e0Smrg pMse->sampleRate); 795659607e0Smrg } 796659607e0Smrg pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0); 797659607e0Smrg if (pMse->resolution) { 798659607e0Smrg xf86Msg(X_CONFIG, "%s: Resolution: %d\n", pInfo->name, 799659607e0Smrg pMse->resolution); 800659607e0Smrg } 801659607e0Smrg 802eeaac534Smrg if ((mPriv->sensitivity 803eeaac534Smrg = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0))) { 804659607e0Smrg xf86Msg(X_CONFIG, "%s: Sensitivity: %g\n", pInfo->name, 805659607e0Smrg mPriv->sensitivity); 806659607e0Smrg } 807659607e0Smrg} 808659607e0Smrg 809659607e0Smrgstatic void 810659607e0SmrgMouseSerialOptions(InputInfoPtr pInfo) 811659607e0Smrg{ 812659607e0Smrg MouseDevPtr pMse = pInfo->private; 813659607e0Smrg Bool clearDTR, clearRTS; 814659607e0Smrg 815659607e0Smrg 816659607e0Smrg pMse->baudRate = xf86SetIntOption(pInfo->options, "BaudRate", 0); 817659607e0Smrg if (pMse->baudRate) { 818659607e0Smrg xf86Msg(X_CONFIG, "%s: BaudRate: %d\n", pInfo->name, 819659607e0Smrg pMse->baudRate); 820659607e0Smrg } 821659607e0Smrg 822659607e0Smrg if ((clearDTR = xf86SetBoolOption(pInfo->options, "ClearDTR",FALSE))) 823659607e0Smrg pMse->mouseFlags |= MF_CLEAR_DTR; 824659607e0Smrg 825659607e0Smrg 826659607e0Smrg if ((clearRTS = xf86SetBoolOption(pInfo->options, "ClearRTS",FALSE))) 827659607e0Smrg pMse->mouseFlags |= MF_CLEAR_RTS; 828659607e0Smrg 829659607e0Smrg if (clearDTR || clearRTS) { 830659607e0Smrg xf86Msg(X_CONFIG, "%s: ", pInfo->name); 831659607e0Smrg if (clearDTR) { 832659607e0Smrg xf86ErrorF("ClearDTR"); 833659607e0Smrg if (clearRTS) 834659607e0Smrg xf86ErrorF(", "); 835659607e0Smrg } 836659607e0Smrg if (clearRTS) { 837659607e0Smrg xf86ErrorF("ClearRTS"); 838659607e0Smrg } 839659607e0Smrg xf86ErrorF("\n"); 840659607e0Smrg } 841659607e0Smrg} 842659607e0Smrg 843659607e0Smrgstatic MouseProtocolID 844659607e0SmrgProtocolNameToID(const char *name) 845659607e0Smrg{ 846659607e0Smrg int i; 847659607e0Smrg 848659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 849659607e0Smrg if (xf86NameCmp(name, mouseProtocols[i].name) == 0) 850659607e0Smrg return mouseProtocols[i].id; 851659607e0Smrg return PROT_UNKNOWN; 852659607e0Smrg} 853659607e0Smrg 854659607e0Smrgstatic const char * 855659607e0SmrgProtocolIDToName(MouseProtocolID id) 856659607e0Smrg{ 857659607e0Smrg int i; 858659607e0Smrg 859659607e0Smrg switch (id) { 860659607e0Smrg case PROT_UNKNOWN: 861659607e0Smrg return "Unknown"; 862659607e0Smrg break; 863659607e0Smrg case PROT_UNSUP: 864659607e0Smrg return "Unsupported"; 865659607e0Smrg break; 866659607e0Smrg default: 867659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 868659607e0Smrg if (id == mouseProtocols[i].id) 869659607e0Smrg return mouseProtocols[i].name; 870659607e0Smrg return "Invalid"; 871659607e0Smrg } 872659607e0Smrg} 873659607e0Smrg 874eeaac534Smrg_X_EXPORT const char * 875659607e0Smrgxf86MouseProtocolIDToName(MouseProtocolID id) 876659607e0Smrg{ 877659607e0Smrg return ProtocolIDToName(id); 878659607e0Smrg} 879659607e0Smrg 880659607e0SmrgMouseProtocolID 881659607e0Smrgxf86MouseProtocolNameToID(const char *name) 882659607e0Smrg{ 883659607e0Smrg return ProtocolNameToID(name); 884659607e0Smrg} 885659607e0Smrg 886659607e0Smrgstatic int 887659607e0SmrgProtocolIDToClass(MouseProtocolID id) 888659607e0Smrg{ 889659607e0Smrg int i; 890659607e0Smrg 891659607e0Smrg switch (id) { 892659607e0Smrg case PROT_UNKNOWN: 893659607e0Smrg case PROT_UNSUP: 894659607e0Smrg return MSE_NONE; 895659607e0Smrg break; 896659607e0Smrg default: 897659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 898659607e0Smrg if (id == mouseProtocols[i].id) 899659607e0Smrg return mouseProtocols[i].class; 900659607e0Smrg return MSE_NONE; 901659607e0Smrg } 902659607e0Smrg} 903659607e0Smrg 904659607e0Smrgstatic MouseProtocolPtr 905659607e0SmrgGetProtocol(MouseProtocolID id) { 906659607e0Smrg int i; 907659607e0Smrg 908659607e0Smrg switch (id) { 909659607e0Smrg case PROT_UNKNOWN: 910659607e0Smrg case PROT_UNSUP: 911659607e0Smrg return NULL; 912659607e0Smrg break; 913659607e0Smrg default: 914659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 915659607e0Smrg if (id == mouseProtocols[i].id) { 916659607e0Smrg return &mouseProtocols[i]; 917659607e0Smrg } 918659607e0Smrg return NULL; 919659607e0Smrg } 920659607e0Smrg} 921659607e0Smrg 922659607e0Smrgstatic OSMouseInfoPtr osInfo = NULL; 923659607e0Smrg 924659607e0Smrgstatic Bool 925659607e0SmrgInitProtocols(void) 926659607e0Smrg{ 927659607e0Smrg int classes; 928659607e0Smrg int i; 929659607e0Smrg const char *osname = NULL; 930659607e0Smrg 931659607e0Smrg if (osInfo) 932659607e0Smrg return TRUE; 933659607e0Smrg 934659607e0Smrg osInfo = xf86OSMouseInit(0); 935659607e0Smrg if (!osInfo) 936659607e0Smrg return FALSE; 937659607e0Smrg if (!osInfo->SupportedInterfaces) 938659607e0Smrg return FALSE; 939659607e0Smrg 940659607e0Smrg classes = osInfo->SupportedInterfaces(); 941659607e0Smrg if (!classes) 942659607e0Smrg return FALSE; 943659607e0Smrg 944659607e0Smrg /* Mark unsupported interface classes. */ 945659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 946659607e0Smrg if (!(mouseProtocols[i].class & classes)) 947659607e0Smrg mouseProtocols[i].id = PROT_UNSUP; 948659607e0Smrg 949659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 950659607e0Smrg if (mouseProtocols[i].class & MSE_MISC) 951659607e0Smrg if (!osInfo->CheckProtocol || 952659607e0Smrg !osInfo->CheckProtocol(mouseProtocols[i].name)) 953659607e0Smrg mouseProtocols[i].id = PROT_UNSUP; 954659607e0Smrg 955659607e0Smrg /* NetBSD uses PROT_BM for "PS/2". */ 956659607e0Smrg xf86GetOS(&osname, NULL, NULL, NULL); 957659607e0Smrg if (osname && xf86NameCmp(osname, "netbsd") == 0) 958659607e0Smrg for (i = 0; mouseProtocols[i].name; i++) 959659607e0Smrg if (mouseProtocols[i].id == PROT_PS2) 960659607e0Smrg mouseProtocols[i].id = PROT_BM; 961659607e0Smrg 962659607e0Smrg return TRUE; 963659607e0Smrg} 964659607e0Smrg 965659607e0Smrgstatic InputInfoPtr 966659607e0SmrgMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags) 967659607e0Smrg{ 968659607e0Smrg InputInfoPtr pInfo; 969659607e0Smrg MouseDevPtr pMse; 970659607e0Smrg mousePrivPtr mPriv; 971659607e0Smrg MessageType protocolFrom = X_DEFAULT, deviceFrom = X_CONFIG; 972659607e0Smrg const char *protocol, *osProt = NULL; 973659607e0Smrg const char *device; 974659607e0Smrg MouseProtocolID protocolID; 975659607e0Smrg MouseProtocolPtr pProto; 976659607e0Smrg Bool detected; 977659607e0Smrg int i; 978659607e0Smrg 979659607e0Smrg if (!InitProtocols()) 980659607e0Smrg return NULL; 981659607e0Smrg 982659607e0Smrg if (!(pInfo = xf86AllocateInput(drv, 0))) 983659607e0Smrg return NULL; 984659607e0Smrg 985659607e0Smrg /* Initialise the InputInfoRec. */ 986659607e0Smrg pInfo->name = dev->identifier; 987659607e0Smrg pInfo->type_name = XI_MOUSE; 988659607e0Smrg pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; 989659607e0Smrg pInfo->device_control = MouseProc; 990659607e0Smrg pInfo->read_input = MouseReadInput; 991659607e0Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 992659607e0Smrg pInfo->motion_history_proc = xf86GetMotionEvents; 993659607e0Smrg pInfo->history_size = 0; 994659607e0Smrg#endif 995659607e0Smrg pInfo->control_proc = NULL; 996659607e0Smrg pInfo->close_proc = NULL; 997659607e0Smrg pInfo->switch_mode = NULL; 998659607e0Smrg pInfo->conversion_proc = MouseConvert; 999659607e0Smrg pInfo->reverse_conversion_proc = NULL; 1000659607e0Smrg pInfo->fd = -1; 1001659607e0Smrg pInfo->dev = NULL; 1002659607e0Smrg pInfo->private_flags = 0; 1003eeaac534Smrg pInfo->always_core_feedback = NULL; 1004659607e0Smrg pInfo->conf_idev = dev; 1005659607e0Smrg 1006659607e0Smrg /* Check if SendDragEvents has been disabled. */ 1007659607e0Smrg if (!xf86SetBoolOption(dev->commonOptions, "SendDragEvents", TRUE)) { 1008659607e0Smrg pInfo->flags &= ~XI86_SEND_DRAG_EVENTS; 1009659607e0Smrg } 1010659607e0Smrg 1011659607e0Smrg /* Allocate the MouseDevRec and initialise it. */ 1012659607e0Smrg /* 1013659607e0Smrg * XXX This should be done by a function in the core server since the 1014659607e0Smrg * MouseDevRec is defined in the os-support layer. 1015659607e0Smrg */ 1016659607e0Smrg if (!(pMse = xcalloc(sizeof(MouseDevRec), 1))) 1017659607e0Smrg return pInfo; 1018659607e0Smrg pInfo->private = pMse; 1019659607e0Smrg pMse->Ctrl = MouseCtrl; 1020659607e0Smrg pMse->PostEvent = MousePostEvent; 1021659607e0Smrg pMse->CommonOptions = MouseCommonOptions; 1022659607e0Smrg 1023659607e0Smrg /* Find the protocol type. */ 1024659607e0Smrg protocol = xf86SetStrOption(dev->commonOptions, "Protocol", NULL); 1025659607e0Smrg if (protocol) { 1026659607e0Smrg protocolFrom = X_CONFIG; 1027659607e0Smrg } else if (osInfo->DefaultProtocol) { 1028659607e0Smrg protocol = osInfo->DefaultProtocol(); 1029659607e0Smrg protocolFrom = X_DEFAULT; 1030659607e0Smrg } 1031659607e0Smrg if (!protocol) { 1032659607e0Smrg xf86Msg(X_ERROR, "%s: No Protocol specified\n", pInfo->name); 1033659607e0Smrg return pInfo; 1034659607e0Smrg } 1035659607e0Smrg 1036659607e0Smrg /* Default Mapping: 1 2 3 8 9 10 11 ... */ 1037659607e0Smrg for (i = 0; i < MSE_MAXBUTTONS; i++) 1038659607e0Smrg pMse->buttonMap[i] = 1 << (i > 2 && i < MSE_MAXBUTTONS-4 ? i+4 : i); 1039659607e0Smrg 1040659607e0Smrg protocolID = ProtocolNameToID(protocol); 1041659607e0Smrg do { 1042659607e0Smrg detected = TRUE; 1043659607e0Smrg switch (protocolID) { 1044659607e0Smrg case PROT_AUTO: 1045659607e0Smrg if (osInfo->SetupAuto) { 1046659607e0Smrg if ((osProt = osInfo->SetupAuto(pInfo,NULL))) { 1047659607e0Smrg MouseProtocolID id = ProtocolNameToID(osProt); 1048659607e0Smrg if (id == PROT_UNKNOWN || id == PROT_UNSUP) { 1049659607e0Smrg protocolID = id; 1050659607e0Smrg protocol = osProt; 1051659607e0Smrg detected = FALSE; 1052659607e0Smrg } 1053659607e0Smrg } 1054659607e0Smrg } 1055659607e0Smrg break; 1056659607e0Smrg case PROT_UNKNOWN: 1057659607e0Smrg /* Check for a builtin OS-specific protocol, 1058659607e0Smrg * and call its PreInit. */ 1059659607e0Smrg if (osInfo->CheckProtocol 1060659607e0Smrg && osInfo->CheckProtocol(protocol)) { 1061659607e0Smrg if (!xf86CheckStrOption(dev->commonOptions, "Device", NULL) && 1062eeaac534Smrg osInfo->FindDevice) { 1063659607e0Smrg xf86Msg(X_WARNING, "%s: No Device specified, " 1064659607e0Smrg "looking for one...\n", pInfo->name); 1065659607e0Smrg if (!osInfo->FindDevice(pInfo, protocol, 0)) { 1066659607e0Smrg xf86Msg(X_ERROR, "%s: Cannot find which device " 1067659607e0Smrg "to use.\n", pInfo->name); 1068659607e0Smrg } else 1069659607e0Smrg deviceFrom = X_PROBED; 1070659607e0Smrg } 1071659607e0Smrg if (osInfo->PreInit) { 1072659607e0Smrg osInfo->PreInit(pInfo, protocol, 0); 1073659607e0Smrg } 1074659607e0Smrg return pInfo; 1075659607e0Smrg } 1076659607e0Smrg xf86Msg(X_ERROR, "%s: Unknown protocol \"%s\"\n", 1077659607e0Smrg pInfo->name, protocol); 1078659607e0Smrg return pInfo; 1079659607e0Smrg break; 1080659607e0Smrg case PROT_UNSUP: 1081659607e0Smrg xf86Msg(X_ERROR, 1082659607e0Smrg "%s: Protocol \"%s\" is not supported on this " 1083659607e0Smrg "platform\n", pInfo->name, protocol); 1084659607e0Smrg return pInfo; 1085659607e0Smrg break; 1086659607e0Smrg default: 1087659607e0Smrg break; 1088659607e0Smrg 1089659607e0Smrg } 1090659607e0Smrg } while (!detected); 1091659607e0Smrg 1092659607e0Smrg if (!xf86CheckStrOption(dev->commonOptions, "Device", NULL) && 1093eeaac534Smrg osInfo->FindDevice) { 1094659607e0Smrg xf86Msg(X_WARNING, "%s: No Device specified, looking for one...\n", 1095659607e0Smrg pInfo->name); 1096659607e0Smrg if (!osInfo->FindDevice(pInfo, protocol, 0)) { 1097659607e0Smrg xf86Msg(X_ERROR, "%s: Cannot find which device to use.\n", 1098659607e0Smrg pInfo->name); 1099659607e0Smrg } else { 1100659607e0Smrg deviceFrom = X_PROBED; 1101659607e0Smrg xf86MarkOptionUsedByName(dev->commonOptions, "Device"); 1102659607e0Smrg } 1103659607e0Smrg } 1104659607e0Smrg 1105659607e0Smrg device = xf86CheckStrOption(dev->commonOptions, "Device", NULL); 1106659607e0Smrg if (device) 1107659607e0Smrg xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device); 1108659607e0Smrg 1109659607e0Smrg xf86Msg(protocolFrom, "%s: Protocol: \"%s\"\n", pInfo->name, protocol); 1110659607e0Smrg if (!(pProto = GetProtocol(protocolID))) 1111659607e0Smrg return pInfo; 1112659607e0Smrg 1113659607e0Smrg pMse->protocolID = protocolID; 1114659607e0Smrg pMse->oldProtocolID = protocolID; /* hack */ 1115659607e0Smrg 1116659607e0Smrg pMse->autoProbe = FALSE; 1117659607e0Smrg /* Collect the options, and process the common options. */ 1118659607e0Smrg xf86CollectInputOptions(pInfo, pProto->defaults, NULL); 1119659607e0Smrg xf86ProcessCommonOptions(pInfo, pInfo->options); 1120659607e0Smrg 1121659607e0Smrg /* XXX should handle this OS dependency elsewhere. */ 1122659607e0Smrg#ifndef __OS2ELF__ 1123659607e0Smrg /* OS/2 has a mouse handled by the OS - it cannot fail here */ 1124659607e0Smrg 1125659607e0Smrg /* Check if the device can be opened. */ 1126659607e0Smrg pInfo->fd = xf86OpenSerial(pInfo->options); 1127659607e0Smrg if (pInfo->fd == -1) { 1128659607e0Smrg if (xf86GetAllowMouseOpenFail()) 1129659607e0Smrg xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 1130659607e0Smrg else { 1131659607e0Smrg xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); 1132659607e0Smrg if (pMse->mousePriv) 1133659607e0Smrg xfree(pMse->mousePriv); 1134659607e0Smrg xfree(pMse); 1135659607e0Smrg pInfo->private = NULL; 1136659607e0Smrg return pInfo; 1137659607e0Smrg } 1138659607e0Smrg } 1139659607e0Smrg xf86CloseSerial(pInfo->fd); 1140659607e0Smrg#endif 1141659607e0Smrg pInfo->fd = -1; 1142659607e0Smrg 1143659607e0Smrg if (!(mPriv = (pointer) xcalloc(sizeof(mousePrivRec), 1))) 1144659607e0Smrg return pInfo; 1145659607e0Smrg pMse->mousePriv = mPriv; 1146659607e0Smrg pMse->CommonOptions(pInfo); 1147659607e0Smrg pMse->checkMovements = checkForErraticMovements; 1148659607e0Smrg pMse->autoProbeMouse = autoProbeMouse; 1149659607e0Smrg pMse->collectData = collectData; 1150659607e0Smrg pMse->dataGood = autoGood; 1151659607e0Smrg 1152659607e0Smrg MouseHWOptions(pInfo); 1153659607e0Smrg MouseSerialOptions(pInfo); 1154659607e0Smrg 1155659607e0Smrg pInfo->flags |= XI86_CONFIGURED; 1156659607e0Smrg return pInfo; 1157659607e0Smrg} 1158659607e0Smrg 1159659607e0Smrg 1160659607e0Smrgstatic void 1161659607e0SmrgMouseReadInput(InputInfoPtr pInfo) 1162659607e0Smrg{ 1163659607e0Smrg MouseDevPtr pMse; 1164659607e0Smrg int j, buttons, dx, dy, dz, dw, baddata; 1165659607e0Smrg int pBufP; 1166659607e0Smrg int c; 1167659607e0Smrg unsigned char *pBuf, u; 1168659607e0Smrg 1169659607e0Smrg 1170659607e0Smrg pMse = pInfo->private; 1171659607e0Smrg pBufP = pMse->protoBufTail; 1172659607e0Smrg pBuf = pMse->protoBuf; 1173659607e0Smrg 1174659607e0Smrg if (pInfo->fd == -1) 1175659607e0Smrg return; 1176659607e0Smrg 1177659607e0Smrg /* 1178659607e0Smrg * Set blocking to -1 on the first call because we know there is data to 1179659607e0Smrg * read. Xisb automatically clears it after one successful read so that 1180659607e0Smrg * succeeding reads are preceeded by a select with a 0 timeout to prevent 1181659607e0Smrg * read from blocking indefinitely. 1182659607e0Smrg */ 1183659607e0Smrg XisbBlockDuration(pMse->buffer, -1); 1184659607e0Smrg 1185659607e0Smrg while ((c = XisbRead(pMse->buffer)) >= 0) { 1186659607e0Smrg u = (unsigned char)c; 1187659607e0Smrg 1188659607e0Smrg#if defined (EXTMOUSEDEBUG) || defined (MOUSEDATADEBUG) 1189659607e0Smrg ErrorF("mouse byte: %2.2x\n",u); 1190659607e0Smrg#endif 1191659607e0Smrg 1192659607e0Smrg /* if we do autoprobing collect the data */ 1193659607e0Smrg if (pMse->collectData && pMse->autoProbe) 1194659607e0Smrg if (pMse->collectData(pMse,u)) 1195659607e0Smrg continue; 1196eeaac534Smrg 1197659607e0Smrg#ifdef SUPPORT_MOUSE_RESET 1198659607e0Smrg if (mouseReset(pInfo,u)) { 1199659607e0Smrg pBufP = 0; 1200659607e0Smrg continue; 1201659607e0Smrg } 1202659607e0Smrg#endif 1203659607e0Smrg if (pBufP >= pMse->protoPara[4]) { 1204659607e0Smrg /* 1205659607e0Smrg * Buffer contains a full packet, which has already been processed: 1206659607e0Smrg * Empty the buffer and check for optional 4th byte, which will be 1207659607e0Smrg * processed directly, without being put into the buffer first. 1208659607e0Smrg */ 1209659607e0Smrg pBufP = 0; 1210659607e0Smrg if ((u & pMse->protoPara[0]) != pMse->protoPara[1] && 1211659607e0Smrg (u & pMse->protoPara[5]) == pMse->protoPara[6]) { 1212659607e0Smrg /* 1213659607e0Smrg * Hack for Logitech MouseMan Mouse - Middle button 1214659607e0Smrg * 1215659607e0Smrg * Unfortunately this mouse has variable length packets: the 1216659607e0Smrg * standard Microsoft 3 byte packet plus an optional 4th byte 1217659607e0Smrg * whenever the middle button status changes. 1218659607e0Smrg * 1219659607e0Smrg * We have already processed the standard packet with the 1220659607e0Smrg * movement and button info. Now post an event message with 1221659607e0Smrg * the old status of the left and right buttons and the 1222659607e0Smrg * updated middle button. 1223659607e0Smrg */ 1224659607e0Smrg /* 1225659607e0Smrg * Even worse, different MouseMen and TrackMen differ in the 1226659607e0Smrg * 4th byte: some will send 0x00/0x20, others 0x01/0x21, or 1227659607e0Smrg * even 0x02/0x22, so I have to strip off the lower bits. 1228659607e0Smrg * [CHRIS-211092] 1229659607e0Smrg * 1230659607e0Smrg * [JCH-96/01/21] 1231659607e0Smrg * HACK for ALPS "fourth button". (It's bit 0x10 of the 1232659607e0Smrg * "fourth byte" and it is activated by tapping the glidepad 1233659607e0Smrg * with the finger! 8^) We map it to bit bit3, and the 1234659607e0Smrg * reverse map in xf86Events just has to be extended so that 1235659607e0Smrg * it is identified as Button 4. The lower half of the 1236659607e0Smrg * reverse-map may remain unchanged. 1237659607e0Smrg */ 1238659607e0Smrg /* 1239659607e0Smrg * [KAZU-030897] 1240659607e0Smrg * Receive the fourth byte only when preceeding three bytes 1241659607e0Smrg * have been detected (pBufP >= pMse->protoPara[4]). In the 1242659607e0Smrg * previous versions, the test was pBufP == 0; we may have 1243659607e0Smrg * mistakingly received a byte even if we didn't see anything 1244659607e0Smrg * preceeding the byte. 1245659607e0Smrg */ 1246659607e0Smrg#ifdef EXTMOUSEDEBUG 1247659607e0Smrg ErrorF("mouse 4th byte %02x\n",u); 1248659607e0Smrg#endif 1249659607e0Smrg dx = dy = dz = dw = 0; 1250659607e0Smrg buttons = 0; 1251659607e0Smrg switch (pMse->protocolID) { 1252659607e0Smrg 1253659607e0Smrg /* 1254659607e0Smrg * [KAZU-221197] 1255659607e0Smrg * IntelliMouse, NetMouse (including NetMouse Pro) and Mie 1256659607e0Smrg * Mouse always send the fourth byte, whereas the fourth byte 1257659607e0Smrg * is optional for GlidePoint and ThinkingMouse. The fourth 1258659607e0Smrg * byte is also optional for MouseMan+ and FirstMouse+ in 1259659607e0Smrg * their native mode. It is always sent if they are in the 1260659607e0Smrg * IntelliMouse compatible mode. 1261659607e0Smrg */ 1262659607e0Smrg case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse, 1263659607e0Smrg MouseMan+ */ 1264659607e0Smrg dz = (u & 0x08) ? 1265659607e0Smrg (u & 0x0f) - 16 : (u & 0x0f); 1266659607e0Smrg if ((dz >= 7) || (dz <= -7)) 1267659607e0Smrg dz = 0; 1268659607e0Smrg buttons |= ((int)(u & 0x10) >> 3) 1269659607e0Smrg | ((int)(u & 0x20) >> 2) 1270659607e0Smrg | (pMse->lastButtons & 0x05); 1271659607e0Smrg break; 1272659607e0Smrg 1273659607e0Smrg case PROT_GLIDE: 1274659607e0Smrg case PROT_THINKING: 1275659607e0Smrg buttons |= ((int)(u & 0x10) >> 1); 1276659607e0Smrg /* fall through */ 1277659607e0Smrg 1278659607e0Smrg default: 1279659607e0Smrg buttons |= ((int)(u & 0x20) >> 4) | 1280659607e0Smrg (pMse->lastButtons & 0x05); 1281659607e0Smrg break; 1282659607e0Smrg } 1283659607e0Smrg goto post_event; 1284659607e0Smrg } 1285659607e0Smrg } 1286659607e0Smrg /* End of packet buffer flush and 4th byte hack. */ 1287659607e0Smrg 1288659607e0Smrg /* 1289659607e0Smrg * Append next byte to buffer (which is empty or contains an 1290659607e0Smrg * incomplete packet); iterate if packet (still) not complete. 1291659607e0Smrg */ 1292659607e0Smrg pBuf[pBufP++] = u; 1293659607e0Smrg if (pBufP != pMse->protoPara[4]) continue; 1294659607e0Smrg#ifdef EXTMOUSEDEBUG2 1295659607e0Smrg { 1296659607e0Smrg int i; 1297659607e0Smrg ErrorF("received %d bytes",pBufP); 1298659607e0Smrg for ( i=0; i < pBufP; i++) 1299659607e0Smrg ErrorF(" %02x",pBuf[i]); 1300659607e0Smrg ErrorF("\n"); 1301659607e0Smrg } 1302659607e0Smrg#endif 1303659607e0Smrg 1304659607e0Smrg /* 1305659607e0Smrg * Hack for resyncing: We check here for a package that is: 1306659607e0Smrg * a) illegal (detected by wrong data-package header) 1307659607e0Smrg * b) invalid (0x80 == -128 and that might be wrong for MouseSystems) 1308659607e0Smrg * c) bad header-package 1309659607e0Smrg * 1310659607e0Smrg * NOTE: b) is a violation of the MouseSystems-Protocol, since values 1311659607e0Smrg * of -128 are allowed, but since they are very seldom we can 1312659607e0Smrg * easily use them as package-header with no button pressed. 1313659607e0Smrg * NOTE/2: On a PS/2 mouse any byte is valid as a data byte. 1314659607e0Smrg * Furthermore, 0x80 is not valid as a header byte. For a PS/2 1315659607e0Smrg * mouse we skip checking data bytes. For resyncing a PS/2 1316659607e0Smrg * mouse we require the two most significant bits in the header 1317659607e0Smrg * byte to be 0. These are the overflow bits, and in case of 1318659607e0Smrg * an overflow we actually lose sync. Overflows are very rare, 1319659607e0Smrg * however, and we quickly gain sync again after an overflow 1320659607e0Smrg * condition. This is the best we can do. (Actually, we could 1321659607e0Smrg * use bit 0x08 in the header byte for resyncing, since that 1322659607e0Smrg * bit is supposed to be always on, but nobody told Microsoft...) 1323659607e0Smrg */ 1324659607e0Smrg 1325659607e0Smrg /* 1326659607e0Smrg * [KAZU,OYVIND-120398] 1327659607e0Smrg * The above hack is wrong! Because of b) above, we shall see 1328659607e0Smrg * erroneous mouse events so often when the MouseSystem mouse is 1329659607e0Smrg * moved quickly. As for the PS/2 and its variants, we don't need 1330659607e0Smrg * to treat them as special cases, because protoPara[2] and 1331659607e0Smrg * protoPara[3] are both 0x00 for them, thus, any data bytes will 1332659607e0Smrg * never be discarded. 0x80 is rejected for MMSeries, Logitech 1333659607e0Smrg * and MMHittab protocols, because protoPara[2] and protoPara[3] 1334659607e0Smrg * are 0x80 and 0x00 respectively. The other protocols are 7-bit 1335659607e0Smrg * protocols; there is no use checking 0x80. 1336659607e0Smrg * 1337659607e0Smrg * All in all we should check the condition a) only. 1338659607e0Smrg */ 1339659607e0Smrg 1340659607e0Smrg /* 1341659607e0Smrg * [OYVIND-120498] 1342659607e0Smrg * Check packet for valid data: 1343659607e0Smrg * If driver is in sync with datastream, the packet is considered 1344659607e0Smrg * bad if any byte (header and/or data) contains an invalid value. 1345659607e0Smrg * 1346659607e0Smrg * If packet is bad, we discard the first byte and shift the buffer. 1347659607e0Smrg * Next iteration will then check the new situation for validity. 1348659607e0Smrg * 1349659607e0Smrg * If flag MF_SAFE is set in proto[7] and the driver 1350659607e0Smrg * is out of sync, the packet is also considered bad if 1351659607e0Smrg * any of the data bytes contains a valid header byte value. 1352659607e0Smrg * This situation could occur if the buffer contains 1353659607e0Smrg * the tail of one packet and the header of the next. 1354659607e0Smrg * 1355659607e0Smrg * Note: The driver starts in out-of-sync mode (pMse->inSync = 0). 1356659607e0Smrg */ 1357659607e0Smrg 1358659607e0Smrg baddata = 0; 1359659607e0Smrg 1360659607e0Smrg /* All databytes must be valid. */ 1361659607e0Smrg for (j = 1; j < pBufP; j++ ) 1362659607e0Smrg if ((pBuf[j] & pMse->protoPara[2]) != pMse->protoPara[3]) 1363659607e0Smrg baddata = 1; 1364659607e0Smrg 1365659607e0Smrg /* If out of sync, don't mistake a header byte for data. */ 1366659607e0Smrg if ((pMse->protoPara[7] & MPF_SAFE) && !pMse->inSync) 1367659607e0Smrg for (j = 1; j < pBufP; j++ ) 1368659607e0Smrg if ((pBuf[j] & pMse->protoPara[0]) == pMse->protoPara[1]) 1369659607e0Smrg baddata = 1; 1370659607e0Smrg 1371659607e0Smrg /* Accept or reject the packet ? */ 1372659607e0Smrg if ((pBuf[0] & pMse->protoPara[0]) != pMse->protoPara[1] || baddata) { 1373659607e0Smrg if (pMse->inSync) { 1374659607e0Smrg#ifdef EXTMOUSEDEBUG 1375659607e0Smrg ErrorF("mouse driver lost sync\n"); 1376659607e0Smrg#endif 1377659607e0Smrg } 1378659607e0Smrg#ifdef EXTMOUSEDEBUG 1379659607e0Smrg ErrorF("skipping byte %02x\n",*pBuf); 1380659607e0Smrg#endif 1381659607e0Smrg /* Tell auto probe that we are out of sync */ 1382659607e0Smrg if (pMse->autoProbeMouse && pMse->autoProbe) 1383659607e0Smrg pMse->autoProbeMouse(pInfo, FALSE, pMse->inSync); 1384659607e0Smrg pMse->protoBufTail = --pBufP; 1385659607e0Smrg for (j = 0; j < pBufP; j++) 1386659607e0Smrg pBuf[j] = pBuf[j+1]; 1387659607e0Smrg pMse->inSync = 0; 1388659607e0Smrg continue; 1389659607e0Smrg } 1390659607e0Smrg /* Tell auto probe that we were successful */ 1391659607e0Smrg if (pMse->autoProbeMouse && pMse->autoProbe) 1392659607e0Smrg pMse->autoProbeMouse(pInfo, TRUE, FALSE); 1393659607e0Smrg 1394659607e0Smrg if (!pMse->inSync) { 1395659607e0Smrg#ifdef EXTMOUSEDEBUG 1396659607e0Smrg ErrorF("mouse driver back in sync\n"); 1397659607e0Smrg#endif 1398659607e0Smrg pMse->inSync = 1; 1399659607e0Smrg } 1400659607e0Smrg 1401659607e0Smrg if (!pMse->dataGood(pMse)) 1402659607e0Smrg continue; 1403659607e0Smrg 1404659607e0Smrg /* 1405659607e0Smrg * Packet complete and verified, now process it ... 1406659607e0Smrg */ 1407659607e0Smrg REDO_INTERPRET: 1408659607e0Smrg dz = dw = 0; 1409659607e0Smrg switch (pMse->protocolID) { 1410659607e0Smrg case PROT_LOGIMAN: /* MouseMan / TrackMan [CHRIS-211092] */ 1411659607e0Smrg case PROT_MS: /* Microsoft */ 1412659607e0Smrg if (pMse->chordMiddle) 1413659607e0Smrg buttons = (((int) pBuf[0] & 0x30) == 0x30) ? 2 : 1414659607e0Smrg ((int)(pBuf[0] & 0x20) >> 3) 1415659607e0Smrg | ((int)(pBuf[0] & 0x10) >> 4); 1416659607e0Smrg else 1417659607e0Smrg buttons = (pMse->lastButtons & 2) 1418659607e0Smrg | ((int)(pBuf[0] & 0x20) >> 3) 1419659607e0Smrg | ((int)(pBuf[0] & 0x10) >> 4); 1420659607e0Smrg dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); 1421659607e0Smrg dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); 1422659607e0Smrg break; 1423659607e0Smrg 1424659607e0Smrg case PROT_GLIDE: /* ALPS GlidePoint */ 1425659607e0Smrg case PROT_THINKING: /* ThinkingMouse */ 1426659607e0Smrg case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse, MouseMan+ */ 1427659607e0Smrg buttons = (pMse->lastButtons & (8 + 2)) 1428659607e0Smrg | ((int)(pBuf[0] & 0x20) >> 3) 1429659607e0Smrg | ((int)(pBuf[0] & 0x10) >> 4); 1430659607e0Smrg dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); 1431659607e0Smrg dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); 1432659607e0Smrg break; 1433659607e0Smrg 1434659607e0Smrg case PROT_MSC: /* Mouse Systems Corp */ 1435659607e0Smrg buttons = (~pBuf[0]) & 0x07; 1436659607e0Smrg dx = (char)(pBuf[1]) + (char)(pBuf[3]); 1437659607e0Smrg dy = - ((char)(pBuf[2]) + (char)(pBuf[4])); 1438659607e0Smrg break; 1439659607e0Smrg 1440659607e0Smrg case PROT_MMHIT: /* MM_HitTablet */ 1441659607e0Smrg buttons = pBuf[0] & 0x07; 1442659607e0Smrg if (buttons != 0) 1443659607e0Smrg buttons = 1 << (buttons - 1); 1444659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1]; 1445659607e0Smrg dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2]; 1446659607e0Smrg break; 1447659607e0Smrg 1448659607e0Smrg case PROT_ACECAD: /* ACECAD */ 1449659607e0Smrg /* ACECAD is almost exactly like MM but the buttons are different */ 1450659607e0Smrg buttons = (pBuf[0] & 0x02) | ((pBuf[0] & 0x04) >> 2) | 1451659607e0Smrg ((pBuf[0] & 1) << 2); 1452659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1]; 1453659607e0Smrg dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2]; 1454659607e0Smrg break; 1455659607e0Smrg 1456659607e0Smrg case PROT_MM: /* MM Series */ 1457659607e0Smrg case PROT_LOGI: /* Logitech Mice */ 1458659607e0Smrg buttons = pBuf[0] & 0x07; 1459659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1]; 1460659607e0Smrg dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2]; 1461659607e0Smrg break; 1462659607e0Smrg 1463659607e0Smrg case PROT_BM: /* BusMouse */ 1464659607e0Smrg buttons = (~pBuf[0]) & 0x07; 1465659607e0Smrg dx = (char)pBuf[1]; 1466659607e0Smrg dy = - (char)pBuf[2]; 1467659607e0Smrg break; 1468659607e0Smrg 1469659607e0Smrg case PROT_PS2: /* PS/2 mouse */ 1470659607e0Smrg case PROT_GENPS2: /* generic PS/2 mouse */ 1471659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1472659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1473659607e0Smrg (pBuf[0] & 0x01) << 2; /* Left */ 1474659607e0Smrg dx = (pBuf[0] & 0x10) ? (int)pBuf[1]-256 : (int)pBuf[1]; 1475659607e0Smrg dy = (pBuf[0] & 0x20) ? -((int)pBuf[2]-256) : -(int)pBuf[2]; 1476659607e0Smrg break; 1477659607e0Smrg 1478659607e0Smrg /* PS/2 mouse variants */ 1479659607e0Smrg case PROT_IMPS2: /* IntelliMouse PS/2 */ 1480659607e0Smrg case PROT_NETPS2: /* NetMouse PS/2 */ 1481659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1482659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1483659607e0Smrg (pBuf[0] & 0x01) << 2 | /* Left */ 1484659607e0Smrg (pBuf[0] & 0x40) >> 3 | /* button 4 */ 1485659607e0Smrg (pBuf[0] & 0x80) >> 3; /* button 5 */ 1486659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1487659607e0Smrg dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1488659607e0Smrg /* 1489659607e0Smrg * The next cast must be 'signed char' for platforms (like PPC) 1490659607e0Smrg * where char defaults to unsigned. 1491659607e0Smrg */ 1492659607e0Smrg dz = (signed char)(pBuf[3] | ((pBuf[3] & 0x08) ? 0xf8 : 0)); 1493659607e0Smrg if ((pBuf[3] & 0xf8) && ((pBuf[3] & 0xf8) != 0xf8)) { 1494659607e0Smrg if (pMse->autoProbe) { 1495659607e0Smrg SetMouseProto(pMse, PROT_EXPPS2); 1496659607e0Smrg xf86Msg(X_INFO, 1497659607e0Smrg "Mouse autoprobe: Changing protocol to %s\n", 1498659607e0Smrg pMse->protocol); 1499659607e0Smrg 1500659607e0Smrg goto REDO_INTERPRET; 1501659607e0Smrg } else 1502659607e0Smrg dz = 0; 1503659607e0Smrg } 1504659607e0Smrg break; 1505659607e0Smrg 1506659607e0Smrg case PROT_EXPPS2: /* IntelliMouse Explorer PS/2 */ 1507659607e0Smrg if (pMse->autoProbe && (pBuf[3] & 0xC0)) { 1508659607e0Smrg SetMouseProto(pMse, PROT_IMPS2); 1509659607e0Smrg xf86Msg(X_INFO,"Mouse autoprobe: Changing protocol to %s\n", 1510659607e0Smrg pMse->protocol); 1511659607e0Smrg goto REDO_INTERPRET; 1512659607e0Smrg } 1513659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1514659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1515659607e0Smrg (pBuf[0] & 0x01) << 2 | /* Left */ 1516659607e0Smrg (pBuf[3] & 0x10) >> 1 | /* button 4 */ 1517659607e0Smrg (pBuf[3] & 0x20) >> 1; /* button 5 */ 1518659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1519659607e0Smrg dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1520659607e0Smrg if (pMse->negativeW != MSE_NOAXISMAP) { 1521659607e0Smrg switch (pBuf[3] & 0x0f) { 1522659607e0Smrg case 0x00: break; 1523659607e0Smrg case 0x01: dz = 1; break; 1524659607e0Smrg case 0x02: dw = 1; break; 1525659607e0Smrg case 0x0e: dw = -1; break; 1526659607e0Smrg case 0x0f: dz = -1; break; 1527659607e0Smrg default: 1528659607e0Smrg xf86Msg(X_INFO, 1529659607e0Smrg "Mouse autoprobe: Disabling secondary wheel\n"); 1530659607e0Smrg pMse->negativeW = pMse->positiveW = MSE_NOAXISMAP; 1531659607e0Smrg } 1532659607e0Smrg } 1533659607e0Smrg if (pMse->negativeW == MSE_NOAXISMAP) 1534659607e0Smrg dz = (pBuf[3]&0x08) ? (pBuf[3]&0x0f) - 16 : (pBuf[3]&0x0f); 1535659607e0Smrg break; 1536659607e0Smrg 1537659607e0Smrg case PROT_MMPS2: /* MouseMan+ PS/2 */ 1538659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1539659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1540659607e0Smrg (pBuf[0] & 0x01) << 2; /* Left */ 1541659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1] - 256 : pBuf[1]; 1542659607e0Smrg if (((pBuf[0] & 0x48) == 0x48) && 1543659607e0Smrg (abs(dx) > 191) && 1544659607e0Smrg ((((pBuf[2] & 0x03) << 2) | 0x02) == (pBuf[1] & 0x0f))) { 1545659607e0Smrg /* extended data packet */ 1546659607e0Smrg switch ((((pBuf[0] & 0x30) >> 2) | ((pBuf[1] & 0x30) >> 4))) { 1547659607e0Smrg case 1: /* wheel data packet */ 1548659607e0Smrg buttons |= ((pBuf[2] & 0x10) ? 0x08 : 0) | /* 4th button */ 1549659607e0Smrg ((pBuf[2] & 0x20) ? 0x10 : 0); /* 5th button */ 1550659607e0Smrg dx = dy = 0; 1551659607e0Smrg dz = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 : 1552659607e0Smrg (pBuf[2] & 0x0f); 1553659607e0Smrg break; 1554659607e0Smrg case 2: /* Logitech reserves this packet type */ 1555659607e0Smrg /* 1556659607e0Smrg * IBM ScrollPoint uses this packet to encode its 1557659607e0Smrg * stick movement. 1558659607e0Smrg */ 1559659607e0Smrg buttons |= (pMse->lastButtons & ~0x07); 1560659607e0Smrg dx = dy = 0; 1561659607e0Smrg dz = (pBuf[2] & 0x80) ? ((pBuf[2] >> 4) & 0x0f) - 16 : 1562659607e0Smrg ((pBuf[2] >> 4) & 0x0f); 1563659607e0Smrg dw = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 : 1564659607e0Smrg (pBuf[2] & 0x0f); 1565659607e0Smrg break; 1566659607e0Smrg case 0: /* device type packet - shouldn't happen */ 1567659607e0Smrg default: 1568659607e0Smrg buttons |= (pMse->lastButtons & ~0x07); 1569659607e0Smrg dx = dy = 0; 1570659607e0Smrg dz = 0; 1571659607e0Smrg break; 1572659607e0Smrg } 1573659607e0Smrg } else { 1574659607e0Smrg buttons |= (pMse->lastButtons & ~0x07); 1575659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1576659607e0Smrg dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1577659607e0Smrg } 1578659607e0Smrg break; 1579659607e0Smrg 1580659607e0Smrg case PROT_GLIDEPS2: /* GlidePoint PS/2 */ 1581659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1582659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1583659607e0Smrg (pBuf[0] & 0x01) << 2 | /* Left */ 1584659607e0Smrg ((pBuf[0] & 0x08) ? 0 : 0x08);/* fourth button */ 1585659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1586659607e0Smrg dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1587659607e0Smrg break; 1588659607e0Smrg 1589659607e0Smrg case PROT_NETSCPS2: /* NetScroll PS/2 */ 1590659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1591659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1592659607e0Smrg (pBuf[0] & 0x01) << 2 | /* Left */ 1593659607e0Smrg ((pBuf[3] & 0x02) ? 0x08 : 0) | /* button 4 */ 1594659607e0Smrg ((pBuf[3] & 0x01) ? 0x10 : 0); /* button 5 */ 1595659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1596659607e0Smrg dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1597659607e0Smrg dz = (pBuf[3] & 0x10) ? pBuf[4] - 256 : pBuf[4]; 1598659607e0Smrg break; 1599659607e0Smrg 1600659607e0Smrg case PROT_THINKPS2: /* ThinkingMouse PS/2 */ 1601659607e0Smrg buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1602659607e0Smrg (pBuf[0] & 0x02) >> 1 | /* Right */ 1603659607e0Smrg (pBuf[0] & 0x01) << 2 | /* Left */ 1604659607e0Smrg ((pBuf[0] & 0x08) ? 0x08 : 0);/* fourth button */ 1605659607e0Smrg pBuf[1] |= (pBuf[0] & 0x40) ? 0x80 : 0x00; 1606659607e0Smrg dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1607659607e0Smrg dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1608659607e0Smrg break; 1609659607e0Smrg 1610659607e0Smrg case PROT_SYSMOUSE: /* sysmouse */ 1611659607e0Smrg buttons = (~pBuf[0]) & 0x07; 1612659607e0Smrg dx = (signed char)(pBuf[1]) + (signed char)(pBuf[3]); 1613659607e0Smrg dy = - ((signed char)(pBuf[2]) + (signed char)(pBuf[4])); 1614659607e0Smrg /* FreeBSD sysmouse sends additional data bytes */ 1615659607e0Smrg if (pMse->protoPara[4] >= 8) { 1616659607e0Smrg /* 1617659607e0Smrg * These casts must be 'signed char' for platforms (like PPC) 1618659607e0Smrg * where char defaults to unsigned. 1619659607e0Smrg */ 1620659607e0Smrg dz = ((signed char)(pBuf[5] << 1) + 1621659607e0Smrg (signed char)(pBuf[6] << 1)) >> 1; 1622659607e0Smrg buttons |= (int)(~pBuf[7] & 0x7f) << 3; 1623659607e0Smrg } 1624659607e0Smrg break; 1625659607e0Smrg 1626659607e0Smrg case PROT_VALUMOUSESCROLL: /* Kensington ValuMouseScroll */ 1627659607e0Smrg buttons = ((int)(pBuf[0] & 0x20) >> 3) 1628659607e0Smrg | ((int)(pBuf[0] & 0x10) >> 4) 1629659607e0Smrg | ((int)(pBuf[3] & 0x10) >> 3); 1630659607e0Smrg dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); 1631659607e0Smrg dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); 1632659607e0Smrg dz = (pBuf[3] & 0x08) ? ((int)(pBuf[3] & 0x0F) - 0x10) : 1633659607e0Smrg ((int)(pBuf[3] & 0x0F)); 1634659607e0Smrg break; 1635659607e0Smrg 1636659607e0Smrg default: /* There's a table error */ 1637659607e0Smrg#ifdef EXTMOUSEDEBUG 1638659607e0Smrg ErrorF("mouse table error\n"); 1639659607e0Smrg#endif 1640659607e0Smrg continue; 1641659607e0Smrg } 1642659607e0Smrg#ifdef EXTMOUSEDEBUG 1643659607e0Smrg ErrorF("packet"); 1644659607e0Smrg for ( j=0; j < pBufP; j++) 1645659607e0Smrg ErrorF(" %02x",pBuf[j]); 1646659607e0Smrg ErrorF("\n"); 1647659607e0Smrg#endif 1648659607e0Smrg 1649659607e0Smrgpost_event: 1650659607e0Smrg#ifdef EXTMOUSEDEBUG 1651659607e0Smrg ErrorF("dx=%i dy=%i dz=%i dw=%i buttons=%x\n",dx,dy,dz,dw,buttons); 1652659607e0Smrg#endif 1653659607e0Smrg /* When auto-probing check if data makes sense */ 1654659607e0Smrg if (pMse->checkMovements && pMse->autoProbe) 1655659607e0Smrg pMse->checkMovements(pInfo,dx,dy); 1656659607e0Smrg /* post an event */ 1657659607e0Smrg pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 1658659607e0Smrg 1659659607e0Smrg /* 1660659607e0Smrg * We don't reset pBufP here yet, as there may be an additional data 1661659607e0Smrg * byte in some protocols. See above. 1662659607e0Smrg */ 1663659607e0Smrg } 1664659607e0Smrg pMse->protoBufTail = pBufP; 1665659607e0Smrg} 1666659607e0Smrg 1667659607e0Smrg/* 1668659607e0Smrg * MouseCtrl -- 1669659607e0Smrg * Alter the control parameters for the mouse. Note that all special 1670659607e0Smrg * protocol values are handled by dix. 1671659607e0Smrg */ 1672659607e0Smrg 1673659607e0Smrgstatic void 1674659607e0SmrgMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl) 1675659607e0Smrg{ 1676659607e0Smrg InputInfoPtr pInfo; 1677659607e0Smrg MouseDevPtr pMse; 1678659607e0Smrg 1679659607e0Smrg pInfo = device->public.devicePrivate; 1680659607e0Smrg pMse = pInfo->private; 1681659607e0Smrg 1682659607e0Smrg#ifdef EXTMOUSEDEBUG 1683659607e0Smrg ErrorF("MouseCtrl pMse=%p\n", pMse); 1684659607e0Smrg#endif 1685659607e0Smrg 1686659607e0Smrg pMse->num = ctrl->num; 1687659607e0Smrg pMse->den = ctrl->den; 1688659607e0Smrg pMse->threshold = ctrl->threshold; 1689659607e0Smrg} 1690659607e0Smrg 1691659607e0Smrg/* 1692659607e0Smrg *************************************************************************** 1693659607e0Smrg * 1694659607e0Smrg * MouseProc -- 1695659607e0Smrg * 1696659607e0Smrg *************************************************************************** 1697659607e0Smrg */ 1698659607e0Smrg 1699659607e0Smrgstatic int 1700659607e0SmrgMouseProc(DeviceIntPtr device, int what) 1701659607e0Smrg{ 1702659607e0Smrg InputInfoPtr pInfo; 1703659607e0Smrg MouseDevPtr pMse; 1704659607e0Smrg mousePrivPtr mPriv; 1705659607e0Smrg unsigned char map[MSE_MAXBUTTONS + 1]; 1706659607e0Smrg int i; 1707659607e0Smrg 1708659607e0Smrg pInfo = device->public.devicePrivate; 1709659607e0Smrg pMse = pInfo->private; 1710659607e0Smrg pMse->device = device; 1711659607e0Smrg 1712659607e0Smrg switch (what) 1713659607e0Smrg { 1714659607e0Smrg case DEVICE_INIT: 1715659607e0Smrg device->public.on = FALSE; 1716659607e0Smrg /* 1717659607e0Smrg * [KAZU-241097] We don't know exactly how many buttons the 1718659607e0Smrg * device has, so setup the map with the maximum number. 1719659607e0Smrg */ 1720659607e0Smrg for (i = 0; i < MSE_MAXBUTTONS; i++) 1721659607e0Smrg map[i + 1] = i + 1; 1722659607e0Smrg 1723659607e0Smrg InitPointerDeviceStruct((DevicePtr)device, map, 1724659607e0Smrg min(pMse->buttons, MSE_MAXBUTTONS), 1725659607e0Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 1726659607e0Smrg miPointerGetMotionEvents, 1727eeaac534Smrg#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 1728659607e0Smrg GetMotionHistory, 1729659607e0Smrg#endif 1730659607e0Smrg pMse->Ctrl, 1731659607e0Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 1732659607e0Smrg miPointerGetMotionBufferSize() 1733659607e0Smrg#else 1734659607e0Smrg GetMotionHistorySize(), 2 1735659607e0Smrg#endif 1736659607e0Smrg ); 1737659607e0Smrg 1738659607e0Smrg /* X valuator */ 1739659607e0Smrg xf86InitValuatorAxisStruct(device, 0, -1, -1, 1, 0, 1); 1740659607e0Smrg xf86InitValuatorDefaults(device, 0); 1741659607e0Smrg /* Y valuator */ 1742659607e0Smrg xf86InitValuatorAxisStruct(device, 1, -1, -1, 1, 0, 1); 1743659607e0Smrg xf86InitValuatorDefaults(device, 1); 1744659607e0Smrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 1745659607e0Smrg xf86MotionHistoryAllocate(pInfo); 1746659607e0Smrg#endif 1747659607e0Smrg 1748659607e0Smrg#ifdef EXTMOUSEDEBUG 1749659607e0Smrg ErrorF("assigning %p atom=%d name=%s\n", device, pInfo->atom, 1750659607e0Smrg pInfo->name); 1751659607e0Smrg#endif 1752659607e0Smrg break; 1753659607e0Smrg 1754659607e0Smrg case DEVICE_ON: 1755659607e0Smrg pInfo->fd = xf86OpenSerial(pInfo->options); 1756659607e0Smrg if (pInfo->fd == -1) 1757659607e0Smrg xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 1758659607e0Smrg else { 17595ddc3750Smrg#if defined(__NetBSD__) && defined(WSCONS_SUPPORT) && defined(WSMOUSEIO_SETVERSION) 1760afecbbc8Smrg int version = WSMOUSE_EVENT_VERSION; 1761afecbbc8Smrg if (ioctl(pInfo->fd, WSMOUSEIO_SETVERSION, &version) == -1) 1762afecbbc8Smrg xf86Msg(X_WARNING, "%s: cannot set version\n", pInfo->name); 17635ddc3750Smrg#endif 1764659607e0Smrg if (pMse->xisbscale) 1765659607e0Smrg pMse->buffer = XisbNew(pInfo->fd, pMse->xisbscale * 4); 1766659607e0Smrg else 1767659607e0Smrg pMse->buffer = XisbNew(pInfo->fd, 64); 1768659607e0Smrg if (!pMse->buffer) { 1769659607e0Smrg xf86CloseSerial(pInfo->fd); 1770659607e0Smrg pInfo->fd = -1; 1771659607e0Smrg } else { 1772659607e0Smrg if (!SetupMouse(pInfo)) { 1773659607e0Smrg xf86CloseSerial(pInfo->fd); 1774659607e0Smrg pInfo->fd = -1; 1775659607e0Smrg XisbFree(pMse->buffer); 1776659607e0Smrg pMse->buffer = NULL; 1777659607e0Smrg } else { 1778659607e0Smrg mPriv = (mousePrivPtr)pMse->mousePriv; 1779659607e0Smrg if (mPriv != NULL) { 1780659607e0Smrg if ( pMse->protocolID != PROT_AUTO) { 1781659607e0Smrg pMse->inSync = TRUE; /* @@@ */ 1782659607e0Smrg if (mPriv->soft) 1783659607e0Smrg mPriv->autoState = AUTOPROBE_GOOD; 1784659607e0Smrg else 1785659607e0Smrg mPriv->autoState = AUTOPROBE_H_GOOD; 1786659607e0Smrg } else { 1787659607e0Smrg if (mPriv->soft) 1788659607e0Smrg mPriv->autoState = AUTOPROBE_NOPROTO; 1789659607e0Smrg else 1790659607e0Smrg mPriv->autoState = AUTOPROBE_H_NOPROTO; 1791659607e0Smrg } 1792659607e0Smrg } 1793659607e0Smrg xf86FlushInput(pInfo->fd); 1794659607e0Smrg xf86AddEnabledDevice(pInfo); 1795659607e0Smrg } 1796659607e0Smrg } 1797659607e0Smrg } 1798659607e0Smrg pMse->lastButtons = 0; 1799659607e0Smrg pMse->lastMappedButtons = 0; 1800659607e0Smrg pMse->emulateState = 0; 1801659607e0Smrg pMse->emulate3Pending = FALSE; 1802659607e0Smrg pMse->wheelButtonExpires = GetTimeInMillis (); 1803659607e0Smrg device->public.on = TRUE; 1804659607e0Smrg FlushButtons(pMse); 1805659607e0Smrg if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) 1806659607e0Smrg { 1807659607e0Smrg RegisterBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, 1808659607e0Smrg (pointer) pInfo); 1809659607e0Smrg } 1810659607e0Smrg break; 1811659607e0Smrg 1812659607e0Smrg case DEVICE_OFF: 1813659607e0Smrg case DEVICE_CLOSE: 1814659607e0Smrg if (pInfo->fd != -1) { 1815659607e0Smrg xf86RemoveEnabledDevice(pInfo); 1816659607e0Smrg if (pMse->buffer) { 1817659607e0Smrg XisbFree(pMse->buffer); 1818659607e0Smrg pMse->buffer = NULL; 1819659607e0Smrg } 1820659607e0Smrg xf86CloseSerial(pInfo->fd); 1821659607e0Smrg pInfo->fd = -1; 1822659607e0Smrg if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) 1823659607e0Smrg { 1824659607e0Smrg RemoveBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, 1825659607e0Smrg (pointer) pInfo); 1826659607e0Smrg } 1827659607e0Smrg } 1828659607e0Smrg device->public.on = FALSE; 1829659607e0Smrg break; 1830659607e0Smrg } 1831659607e0Smrg return Success; 1832659607e0Smrg} 1833659607e0Smrg 1834659607e0Smrg/* 1835659607e0Smrg *************************************************************************** 1836659607e0Smrg * 1837659607e0Smrg * MouseConvert -- 1838659607e0Smrg * Convert valuators to X and Y. 1839659607e0Smrg * 1840659607e0Smrg *************************************************************************** 1841659607e0Smrg */ 1842659607e0Smrgstatic Bool 1843659607e0SmrgMouseConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2, 1844659607e0Smrg int v3, int v4, int v5, int *x, int *y) 1845659607e0Smrg{ 1846659607e0Smrg if (first != 0 || num != 2) 1847659607e0Smrg return FALSE; 1848659607e0Smrg 1849659607e0Smrg *x = v0; 1850659607e0Smrg *y = v1; 1851659607e0Smrg 1852659607e0Smrg return TRUE; 1853659607e0Smrg} 1854659607e0Smrg 1855659607e0Smrg/********************************************************************** 1856659607e0Smrg * 1857659607e0Smrg * FlushButtons -- reset button states. 1858659607e0Smrg * 1859659607e0Smrg **********************************************************************/ 1860659607e0Smrg 1861659607e0Smrgstatic void 1862659607e0SmrgFlushButtons(MouseDevPtr pMse) 1863659607e0Smrg{ 1864659607e0Smrg pMse->lastButtons = 0; 1865659607e0Smrg pMse->lastMappedButtons = 0; 1866659607e0Smrg} 1867659607e0Smrg 1868659607e0Smrg/********************************************************************** 1869659607e0Smrg * 1870659607e0Smrg * Emulate3Button support code 1871659607e0Smrg * 1872659607e0Smrg **********************************************************************/ 1873659607e0Smrg 1874659607e0Smrg 1875659607e0Smrg/* 1876659607e0Smrg * Lets create a simple finite-state machine for 3 button emulation: 1877659607e0Smrg * 1878659607e0Smrg * We track buttons 1 and 3 (left and right). There are 11 states: 1879659607e0Smrg * 0 ground - initial state 1880659607e0Smrg * 1 delayed left - left pressed, waiting for right 1881659607e0Smrg * 2 delayed right - right pressed, waiting for left 1882659607e0Smrg * 3 pressed middle - right and left pressed, emulated middle sent 1883659607e0Smrg * 4 pressed left - left pressed and sent 1884659607e0Smrg * 5 pressed right - right pressed and sent 1885659607e0Smrg * 6 released left - left released after emulated middle 1886659607e0Smrg * 7 released right - right released after emulated middle 1887659607e0Smrg * 8 repressed left - left pressed after released left 1888659607e0Smrg * 9 repressed right - right pressed after released right 1889659607e0Smrg * 10 pressed both - both pressed, not emulating middle 1890659607e0Smrg * 1891659607e0Smrg * At each state, we need handlers for the following events 1892659607e0Smrg * 0: no buttons down 1893659607e0Smrg * 1: left button down 1894659607e0Smrg * 2: right button down 1895659607e0Smrg * 3: both buttons down 1896659607e0Smrg * 4: emulate3Timeout passed without a button change 1897659607e0Smrg * Note that button events are not deltas, they are the set of buttons being 1898659607e0Smrg * pressed now. It's possible (ie, mouse hardware does it) to go from (eg) 1899659607e0Smrg * left down to right down without anything in between, so all cases must be 1900659607e0Smrg * handled. 1901659607e0Smrg * 1902659607e0Smrg * a handler consists of three values: 1903659607e0Smrg * 0: action1 1904659607e0Smrg * 1: action2 1905659607e0Smrg * 2: new emulation state 1906659607e0Smrg * 1907659607e0Smrg * action > 0: ButtonPress 1908659607e0Smrg * action = 0: nothing 1909659607e0Smrg * action < 0: ButtonRelease 1910659607e0Smrg * 1911659607e0Smrg * The comment preceeding each section is the current emulation state. 1912659607e0Smrg * The comments to the right are of the form 1913659607e0Smrg * <button state> (<events>) -> <new emulation state> 1914659607e0Smrg * which should be read as 1915659607e0Smrg * If the buttons are in <button state>, generate <events> then go to 1916659607e0Smrg * <new emulation state>. 1917659607e0Smrg */ 1918659607e0Smrgstatic signed char stateTab[11][5][3] = { 1919659607e0Smrg/* 0 ground */ 1920659607e0Smrg { 1921659607e0Smrg { 0, 0, 0 }, /* nothing -> ground (no change) */ 1922659607e0Smrg { 0, 0, 1 }, /* left -> delayed left */ 1923659607e0Smrg { 0, 0, 2 }, /* right -> delayed right */ 1924659607e0Smrg { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ 1925659607e0Smrg { 0, 0, -1 } /* timeout N/A */ 1926659607e0Smrg }, 1927659607e0Smrg/* 1 delayed left */ 1928659607e0Smrg { 1929659607e0Smrg { 1, -1, 0 }, /* nothing (left event) -> ground */ 1930659607e0Smrg { 0, 0, 1 }, /* left -> delayed left (no change) */ 1931659607e0Smrg { 1, -1, 2 }, /* right (left event) -> delayed right */ 1932659607e0Smrg { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ 1933659607e0Smrg { 1, 0, 4 }, /* timeout (left press) -> pressed left */ 1934659607e0Smrg }, 1935659607e0Smrg/* 2 delayed right */ 1936659607e0Smrg { 1937659607e0Smrg { 3, -3, 0 }, /* nothing (right event) -> ground */ 1938659607e0Smrg { 3, -3, 1 }, /* left (right event) -> delayed left (no change) */ 1939659607e0Smrg { 0, 0, 2 }, /* right -> delayed right (no change) */ 1940659607e0Smrg { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ 1941659607e0Smrg { 3, 0, 5 }, /* timeout (right press) -> pressed right */ 1942659607e0Smrg }, 1943659607e0Smrg/* 3 pressed middle */ 1944659607e0Smrg { 1945659607e0Smrg { -2, 0, 0 }, /* nothing (middle release) -> ground */ 1946659607e0Smrg { 0, 0, 7 }, /* left -> released right */ 1947659607e0Smrg { 0, 0, 6 }, /* right -> released left */ 1948659607e0Smrg { 0, 0, 3 }, /* left & right -> pressed middle (no change) */ 1949659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1950659607e0Smrg }, 1951659607e0Smrg/* 4 pressed left */ 1952659607e0Smrg { 1953659607e0Smrg { -1, 0, 0 }, /* nothing (left release) -> ground */ 1954659607e0Smrg { 0, 0, 4 }, /* left -> pressed left (no change) */ 1955659607e0Smrg { -1, 0, 2 }, /* right (left release) -> delayed right */ 1956659607e0Smrg { 3, 0, 10 }, /* left & right (right press) -> pressed both */ 1957659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1958659607e0Smrg }, 1959659607e0Smrg/* 5 pressed right */ 1960659607e0Smrg { 1961659607e0Smrg { -3, 0, 0 }, /* nothing (right release) -> ground */ 1962659607e0Smrg { -3, 0, 1 }, /* left (right release) -> delayed left */ 1963659607e0Smrg { 0, 0, 5 }, /* right -> pressed right (no change) */ 1964659607e0Smrg { 1, 0, 10 }, /* left & right (left press) -> pressed both */ 1965659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1966659607e0Smrg }, 1967659607e0Smrg/* 6 released left */ 1968659607e0Smrg { 1969659607e0Smrg { -2, 0, 0 }, /* nothing (middle release) -> ground */ 1970659607e0Smrg { -2, 0, 1 }, /* left (middle release) -> delayed left */ 1971659607e0Smrg { 0, 0, 6 }, /* right -> released left (no change) */ 1972659607e0Smrg { 1, 0, 8 }, /* left & right (left press) -> repressed left */ 1973659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1974659607e0Smrg }, 1975659607e0Smrg/* 7 released right */ 1976659607e0Smrg { 1977659607e0Smrg { -2, 0, 0 }, /* nothing (middle release) -> ground */ 1978659607e0Smrg { 0, 0, 7 }, /* left -> released right (no change) */ 1979659607e0Smrg { -2, 0, 2 }, /* right (middle release) -> delayed right */ 1980659607e0Smrg { 3, 0, 9 }, /* left & right (right press) -> repressed right */ 1981659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1982659607e0Smrg }, 1983659607e0Smrg/* 8 repressed left */ 1984659607e0Smrg { 1985659607e0Smrg { -2, -1, 0 }, /* nothing (middle release, left release) -> ground */ 1986659607e0Smrg { -2, 0, 4 }, /* left (middle release) -> pressed left */ 1987659607e0Smrg { -1, 0, 6 }, /* right (left release) -> released left */ 1988659607e0Smrg { 0, 0, 8 }, /* left & right -> repressed left (no change) */ 1989659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1990659607e0Smrg }, 1991659607e0Smrg/* 9 repressed right */ 1992659607e0Smrg { 1993659607e0Smrg { -2, -3, 0 }, /* nothing (middle release, right release) -> ground */ 1994659607e0Smrg { -3, 0, 7 }, /* left (right release) -> released right */ 1995659607e0Smrg { -2, 0, 5 }, /* right (middle release) -> pressed right */ 1996659607e0Smrg { 0, 0, 9 }, /* left & right -> repressed right (no change) */ 1997659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 1998659607e0Smrg }, 1999659607e0Smrg/* 10 pressed both */ 2000659607e0Smrg { 2001659607e0Smrg { -1, -3, 0 }, /* nothing (left release, right release) -> ground */ 2002659607e0Smrg { -3, 0, 4 }, /* left (right release) -> pressed left */ 2003659607e0Smrg { -1, 0, 5 }, /* right (left release) -> pressed right */ 2004659607e0Smrg { 0, 0, 10 }, /* left & right -> pressed both (no change) */ 2005659607e0Smrg { 0, 0, -1 }, /* timeout N/A */ 2006659607e0Smrg }, 2007659607e0Smrg}; 2008659607e0Smrg 2009659607e0Smrg/* 2010659607e0Smrg * Table to allow quick reversal of natural button mapping to correct mapping 2011659607e0Smrg */ 2012659607e0Smrg 2013659607e0Smrg/* 2014659607e0Smrg * [JCH-96/01/21] The ALPS GlidePoint pad extends the MS protocol 2015659607e0Smrg * with a fourth button activated by tapping the PAD. 2016659607e0Smrg * The 2nd line corresponds to 4th button on; the drv sends 2017659607e0Smrg * the buttons in the following map (MSBit described first) : 2018659607e0Smrg * 0 | 4th | 1st | 2nd | 3rd 2019659607e0Smrg * And we remap them (MSBit described first) : 2020659607e0Smrg * 0 | 4th | 3rd | 2nd | 1st 2021659607e0Smrg */ 2022659607e0Smrgstatic char reverseMap[16] = { 0, 4, 2, 6, 2023659607e0Smrg 1, 5, 3, 7, 2024659607e0Smrg 8, 12, 10, 14, 2025659607e0Smrg 9, 13, 11, 15 }; 2026659607e0Smrg 2027659607e0Smrgstatic char hitachMap[16] = { 0, 2, 1, 3, 2028659607e0Smrg 8, 10, 9, 11, 2029659607e0Smrg 4, 6, 5, 7, 2030659607e0Smrg 12, 14, 13, 15 }; 2031659607e0Smrg 2032659607e0Smrg#define reverseBits(map, b) (((b) & ~0x0f) | map[(b) & 0x0f]) 2033659607e0Smrg 2034659607e0Smrgstatic CARD32 2035659607e0SmrgbuttonTimer(InputInfoPtr pInfo) 2036659607e0Smrg{ 2037659607e0Smrg MouseDevPtr pMse; 2038659607e0Smrg int sigstate; 2039659607e0Smrg int id; 2040659607e0Smrg 2041659607e0Smrg pMse = pInfo->private; 2042659607e0Smrg 2043659607e0Smrg sigstate = xf86BlockSIGIO (); 2044659607e0Smrg 2045659607e0Smrg pMse->emulate3Pending = FALSE; 2046659607e0Smrg if ((id = stateTab[pMse->emulateState][4][0]) != 0) { 2047659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); 2048659607e0Smrg pMse->emulateState = stateTab[pMse->emulateState][4][2]; 2049659607e0Smrg } else { 2050659607e0Smrg ErrorF("Got unexpected buttonTimer in state %d\n", pMse->emulateState); 2051659607e0Smrg } 2052659607e0Smrg 2053659607e0Smrg xf86UnblockSIGIO (sigstate); 2054659607e0Smrg return 0; 2055659607e0Smrg} 2056659607e0Smrg 2057659607e0Smrgstatic Bool 2058659607e0SmrgEmulate3ButtonsSoft(InputInfoPtr pInfo) 2059659607e0Smrg{ 2060659607e0Smrg MouseDevPtr pMse = pInfo->private; 2061659607e0Smrg 2062659607e0Smrg if (!pMse->emulate3ButtonsSoft) 2063659607e0Smrg return TRUE; 2064659607e0Smrg 20657022890bSmartin#if defined(__NetBSD__) && defined(WSCONS_SUPPORT) 20667022890bSmartin /* 20677022890bSmartin * XXXX - check for pMse->protocolID being wsmouse? Why doesn't it 20687022890bSmartin * have it's own ID? 20697022890bSmartin * On NetBSD a wsmouse is a multiplexed device. Imagine a notebook 20707022890bSmartin * with two-button mousepad, and an external USB mouse plugged in 20717022890bSmartin * temporarily. After using button 3 on the external mouse and 20727022890bSmartin * unplugging it again, the mousepad will still need to emulate 20737022890bSmartin * 3 buttons. 20747022890bSmartin */ 20757022890bSmartin return TRUE; 20767022890bSmartin#endif 20777022890bSmartin 2078659607e0Smrg pMse->emulate3Buttons = FALSE; 2079659607e0Smrg 2080659607e0Smrg if (pMse->emulate3Pending) 2081659607e0Smrg buttonTimer(pInfo); 2082659607e0Smrg 2083659607e0Smrg xf86Msg(X_INFO,"3rd Button detected: disabling emulate3Button\n"); 2084659607e0Smrg 2085659607e0Smrg return FALSE; 2086659607e0Smrg} 2087659607e0Smrg 2088659607e0Smrgstatic void MouseBlockHandler(pointer data, 2089659607e0Smrg struct timeval **waitTime, 2090659607e0Smrg pointer LastSelectMask) 2091659607e0Smrg{ 2092659607e0Smrg InputInfoPtr pInfo = (InputInfoPtr) data; 2093659607e0Smrg MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 2094659607e0Smrg int ms; 2095659607e0Smrg 2096659607e0Smrg if (pMse->emulate3Pending) 2097659607e0Smrg { 2098659607e0Smrg ms = pMse->emulate3Expires - GetTimeInMillis (); 2099659607e0Smrg if (ms <= 0) 2100659607e0Smrg ms = 0; 2101659607e0Smrg AdjustWaitForDelay (waitTime, ms); 2102659607e0Smrg } 2103659607e0Smrg} 2104659607e0Smrg 2105659607e0Smrgstatic void MouseWakeupHandler(pointer data, 2106659607e0Smrg int i, 2107659607e0Smrg pointer LastSelectMask) 2108659607e0Smrg{ 2109659607e0Smrg InputInfoPtr pInfo = (InputInfoPtr) data; 2110659607e0Smrg MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 2111659607e0Smrg int ms; 2112659607e0Smrg 2113659607e0Smrg if (pMse->emulate3Pending) 2114659607e0Smrg { 2115659607e0Smrg ms = pMse->emulate3Expires - GetTimeInMillis (); 2116659607e0Smrg if (ms <= 0) 2117659607e0Smrg buttonTimer (pInfo); 2118659607e0Smrg } 2119659607e0Smrg} 2120659607e0Smrg 2121659607e0Smrg/******************************************************************* 2122659607e0Smrg * 2123659607e0Smrg * Post mouse events 2124659607e0Smrg * 2125659607e0Smrg *******************************************************************/ 2126659607e0Smrg 2127659607e0Smrgstatic void 2128659607e0SmrgMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy) 2129659607e0Smrg{ 2130659607e0Smrg MouseDevPtr pMse; 2131659607e0Smrg int emulateButtons; 2132659607e0Smrg int id, change; 2133659607e0Smrg int emuWheelDelta, emuWheelButton, emuWheelButtonMask; 2134659607e0Smrg int wheelButtonMask; 2135659607e0Smrg int ms; 2136659607e0Smrg 2137659607e0Smrg pMse = pInfo->private; 2138659607e0Smrg 2139659607e0Smrg change = buttons ^ pMse->lastMappedButtons; 2140659607e0Smrg pMse->lastMappedButtons = buttons; 2141659607e0Smrg 2142659607e0Smrg /* Do single button double click */ 2143659607e0Smrg if (pMse->doubleClickSourceButtonMask) { 2144659607e0Smrg if (buttons & pMse->doubleClickSourceButtonMask) { 2145659607e0Smrg if (!(pMse->doubleClickOldSourceState)) { 2146659607e0Smrg /* double-click button has just been pressed. Ignore it if target button 2147659607e0Smrg * is already down. 2148659607e0Smrg */ 2149659607e0Smrg if (!(buttons & pMse->doubleClickTargetButtonMask)) { 2150659607e0Smrg /* Target button isn't down, so send a double-click */ 2151659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 1, 0, 0); 2152659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 0, 0, 0); 2153659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 1, 0, 0); 2154659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 0, 0, 0); 2155659607e0Smrg } 2156659607e0Smrg } 2157659607e0Smrg pMse->doubleClickOldSourceState = 1; 2158659607e0Smrg } 2159659607e0Smrg else 2160659607e0Smrg pMse->doubleClickOldSourceState = 0; 2161659607e0Smrg 2162659607e0Smrg /* Whatever happened, mask the double-click button so it doesn't get 2163659607e0Smrg * processed as a normal button as well. 2164659607e0Smrg */ 2165659607e0Smrg buttons &= ~(pMse->doubleClickSourceButtonMask); 2166659607e0Smrg change &= ~(pMse->doubleClickSourceButtonMask); 2167659607e0Smrg } 2168659607e0Smrg 2169659607e0Smrg if (pMse->emulateWheel) { 2170659607e0Smrg /* Emulate wheel button handling */ 2171659607e0Smrg wheelButtonMask = 1 << (pMse->wheelButton - 1); 2172659607e0Smrg 2173659607e0Smrg if (change & wheelButtonMask) { 2174659607e0Smrg if (buttons & wheelButtonMask) { 2175659607e0Smrg /* Start timeout handling */ 2176659607e0Smrg pMse->wheelButtonExpires = GetTimeInMillis () + pMse->wheelButtonTimeout; 2177659607e0Smrg ms = - pMse->wheelButtonTimeout; 2178659607e0Smrg } else { 2179659607e0Smrg ms = pMse->wheelButtonExpires - GetTimeInMillis (); 2180659607e0Smrg 2181659607e0Smrg if (0 < ms) { 2182659607e0Smrg /* 2183659607e0Smrg * If the button is released early enough emit the button 2184659607e0Smrg * press/release events 2185659607e0Smrg */ 2186659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, pMse->wheelButton, 1, 0, 0); 2187659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, pMse->wheelButton, 0, 0, 0); 2188659607e0Smrg } 2189659607e0Smrg } 2190659607e0Smrg } else 2191659607e0Smrg ms = pMse->wheelButtonExpires - GetTimeInMillis (); 2192659607e0Smrg 2193659607e0Smrg /* Intercept wheel emulation. */ 2194659607e0Smrg if (buttons & wheelButtonMask) { 2195659607e0Smrg if (ms <= 0) { 2196659607e0Smrg /* Y axis movement */ 2197659607e0Smrg if (pMse->negativeY != MSE_NOAXISMAP) { 2198659607e0Smrg pMse->wheelYDistance += dy; 2199659607e0Smrg if (pMse->wheelYDistance < 0) { 2200659607e0Smrg emuWheelDelta = -pMse->wheelInertia; 2201659607e0Smrg emuWheelButton = pMse->negativeY; 2202659607e0Smrg } else { 2203659607e0Smrg emuWheelDelta = pMse->wheelInertia; 2204659607e0Smrg emuWheelButton = pMse->positiveY; 2205659607e0Smrg } 2206659607e0Smrg emuWheelButtonMask = 1 << (emuWheelButton - 1); 2207659607e0Smrg while (abs(pMse->wheelYDistance) > pMse->wheelInertia) { 2208659607e0Smrg pMse->wheelYDistance -= emuWheelDelta; 2209659607e0Smrg 2210659607e0Smrg /* 2211659607e0Smrg * Synthesize the press and release, but not when 2212659607e0Smrg * the button to be synthesized is already pressed 2213659607e0Smrg * "for real". 2214659607e0Smrg */ 2215659607e0Smrg if (!(emuWheelButtonMask & buttons) || 2216659607e0Smrg (emuWheelButtonMask & wheelButtonMask)) { 2217659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 1, 0, 0); 2218659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 0, 0, 0); 2219659607e0Smrg } 2220659607e0Smrg } 2221659607e0Smrg } 2222659607e0Smrg 2223659607e0Smrg /* X axis movement */ 2224659607e0Smrg if (pMse->negativeX != MSE_NOAXISMAP) { 2225659607e0Smrg pMse->wheelXDistance += dx; 2226659607e0Smrg if (pMse->wheelXDistance < 0) { 2227659607e0Smrg emuWheelDelta = -pMse->wheelInertia; 2228659607e0Smrg emuWheelButton = pMse->negativeX; 2229659607e0Smrg } else { 2230659607e0Smrg emuWheelDelta = pMse->wheelInertia; 2231659607e0Smrg emuWheelButton = pMse->positiveX; 2232659607e0Smrg } 2233659607e0Smrg emuWheelButtonMask = 1 << (emuWheelButton - 1); 2234659607e0Smrg while (abs(pMse->wheelXDistance) > pMse->wheelInertia) { 2235659607e0Smrg pMse->wheelXDistance -= emuWheelDelta; 2236659607e0Smrg 2237659607e0Smrg /* 2238659607e0Smrg * Synthesize the press and release, but not when 2239659607e0Smrg * the button to be synthesized is already pressed 2240659607e0Smrg * "for real". 2241659607e0Smrg */ 2242659607e0Smrg if (!(emuWheelButtonMask & buttons) || 2243659607e0Smrg (emuWheelButtonMask & wheelButtonMask)) { 2244659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 1, 0, 0); 2245659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 0, 0, 0); 2246659607e0Smrg } 2247659607e0Smrg } 2248659607e0Smrg } 2249659607e0Smrg } 2250659607e0Smrg 2251659607e0Smrg /* Absorb the mouse movement while the wheel button is pressed. */ 2252659607e0Smrg dx = 0; 2253659607e0Smrg dy = 0; 2254659607e0Smrg } 2255659607e0Smrg /* 2256659607e0Smrg * Button events for the wheel button are only emitted through 2257659607e0Smrg * the timeout code. 2258659607e0Smrg */ 2259659607e0Smrg buttons &= ~wheelButtonMask; 2260659607e0Smrg change &= ~wheelButtonMask; 2261659607e0Smrg } 2262659607e0Smrg 2263659607e0Smrg if (pMse->emulate3ButtonsSoft && pMse->emulate3Pending && (dx || dy)) 2264659607e0Smrg buttonTimer(pInfo); 2265659607e0Smrg 2266659607e0Smrg if (dx || dy) 2267659607e0Smrg xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy); 2268659607e0Smrg 2269659607e0Smrg if (change) { 2270659607e0Smrg 2271659607e0Smrg /* 2272659607e0Smrg * adjust buttons state for drag locks! 2273659607e0Smrg * if there is drag locks 2274659607e0Smrg */ 2275659607e0Smrg if (pMse->pDragLock) { 2276659607e0Smrg DragLockPtr pLock; 2277659607e0Smrg int tarOfGoingDown, tarOfDown; 2278659607e0Smrg int realbuttons; 2279659607e0Smrg 2280659607e0Smrg /* get drag lock block */ 2281659607e0Smrg pLock = pMse->pDragLock; 2282659607e0Smrg /* save real buttons */ 2283659607e0Smrg realbuttons = buttons; 2284659607e0Smrg 2285659607e0Smrg /* if drag lock used */ 2286659607e0Smrg 2287659607e0Smrg /* state of drag lock buttons not seen always up */ 2288659607e0Smrg 2289659607e0Smrg buttons &= ~pLock->lockButtonsM; 2290659607e0Smrg 2291659607e0Smrg /* 2292659607e0Smrg * if lock buttons being depressed changes state of 2293659607e0Smrg * targets simulatedDown. 2294659607e0Smrg */ 2295659607e0Smrg tarOfGoingDown = lock2targetMap(pLock, 2296659607e0Smrg realbuttons & change & pLock->lockButtonsM); 2297659607e0Smrg pLock->simulatedDown ^= tarOfGoingDown; 2298659607e0Smrg 2299659607e0Smrg /* targets of drag locks down */ 2300659607e0Smrg tarOfDown = lock2targetMap(pLock, 2301659607e0Smrg realbuttons & pLock->lockButtonsM); 2302659607e0Smrg 2303659607e0Smrg /* 2304659607e0Smrg * when simulatedDown set and target pressed, 2305659607e0Smrg * simulatedDown goes false 2306659607e0Smrg */ 2307659607e0Smrg pLock->simulatedDown &= ~(realbuttons & change); 2308659607e0Smrg 2309659607e0Smrg /* 2310659607e0Smrg * if master drag lock released 2311659607e0Smrg * then master drag lock state on 2312659607e0Smrg */ 2313659607e0Smrg pLock->masterTS |= (~realbuttons & change) & pLock->masterLockM; 2314659607e0Smrg 2315659607e0Smrg /* if master state, buttons going down are simulatedDown */ 2316659607e0Smrg if (pLock->masterTS) 2317659607e0Smrg pLock->simulatedDown |= (realbuttons & change); 2318659607e0Smrg 2319659607e0Smrg /* if any button pressed, no longer in master drag lock state */ 2320659607e0Smrg if (realbuttons & change) 2321659607e0Smrg pLock->masterTS = 0; 2322659607e0Smrg 2323659607e0Smrg /* if simulatedDown or drag lock down, simulate down */ 2324659607e0Smrg buttons |= (pLock->simulatedDown | tarOfDown); 2325659607e0Smrg 2326659607e0Smrg /* master button not seen */ 2327659607e0Smrg buttons &= ~(pLock->masterLockM); 2328659607e0Smrg 2329659607e0Smrg /* buttons changed since last time */ 2330659607e0Smrg change = buttons ^ pLock->lockLastButtons; 2331659607e0Smrg 2332659607e0Smrg /* save this time for next last time. */ 2333659607e0Smrg pLock->lockLastButtons = buttons; 2334659607e0Smrg } 2335659607e0Smrg 2336659607e0Smrg if (pMse->emulate3Buttons 2337659607e0Smrg && (!(buttons & 0x02) || Emulate3ButtonsSoft(pInfo))) { 2338659607e0Smrg 2339659607e0Smrg /* handle all but buttons 1 & 3 normally */ 2340659607e0Smrg 2341659607e0Smrg change &= ~05; 2342659607e0Smrg 2343659607e0Smrg /* emulate the third button by the other two */ 2344659607e0Smrg 2345659607e0Smrg emulateButtons = (buttons & 01) | ((buttons &04) >> 1); 2346659607e0Smrg 2347659607e0Smrg if ((id = stateTab[pMse->emulateState][emulateButtons][0]) != 0) 2348659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); 2349659607e0Smrg if ((id = stateTab[pMse->emulateState][emulateButtons][1]) != 0) 2350659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); 2351659607e0Smrg 2352659607e0Smrg pMse->emulateState = 2353659607e0Smrg stateTab[pMse->emulateState][emulateButtons][2]; 2354659607e0Smrg 2355659607e0Smrg if (stateTab[pMse->emulateState][4][0] != 0) { 2356659607e0Smrg pMse->emulate3Expires = GetTimeInMillis () + pMse->emulate3Timeout; 2357659607e0Smrg pMse->emulate3Pending = TRUE; 2358659607e0Smrg } else { 2359659607e0Smrg pMse->emulate3Pending = FALSE; 2360659607e0Smrg } 2361659607e0Smrg } 2362659607e0Smrg 2363659607e0Smrg while (change) { 2364659607e0Smrg id = ffs(change); 2365659607e0Smrg change &= ~(1 << (id - 1)); 2366659607e0Smrg xf86PostButtonEvent(pInfo->dev, 0, id, 2367659607e0Smrg (buttons & (1 << (id - 1))), 0, 0); 2368659607e0Smrg } 2369659607e0Smrg 2370659607e0Smrg } 2371659607e0Smrg} 2372659607e0Smrg 2373659607e0Smrgstatic void 2374659607e0SmrgMousePostEvent(InputInfoPtr pInfo, int truebuttons, 2375659607e0Smrg int dx, int dy, int dz, int dw) 2376659607e0Smrg{ 2377659607e0Smrg MouseDevPtr pMse; 2378659607e0Smrg mousePrivPtr mousepriv; 2379659607e0Smrg int zbutton = 0, wbutton = 0, zbuttoncount = 0, wbuttoncount = 0; 2380659607e0Smrg int i, b, buttons = 0; 2381659607e0Smrg 2382659607e0Smrg pMse = pInfo->private; 2383659607e0Smrg mousepriv = (mousePrivPtr)pMse->mousePriv; 2384659607e0Smrg 2385659607e0Smrg if (pMse->protocolID == PROT_MMHIT) 2386659607e0Smrg b = reverseBits(hitachMap, truebuttons); 2387659607e0Smrg else 2388659607e0Smrg b = reverseBits(reverseMap, truebuttons); 2389659607e0Smrg 2390659607e0Smrg /* Remap mouse buttons */ 2391659607e0Smrg b &= (1<<MSE_MAXBUTTONS)-1; 2392659607e0Smrg for (i = 0; b; i++) { 2393659607e0Smrg if (b & 1) 2394659607e0Smrg buttons |= pMse->buttonMap[i]; 2395659607e0Smrg b >>= 1; 2396659607e0Smrg } 2397659607e0Smrg 2398659607e0Smrg /* Map the Z axis movement. */ 2399659607e0Smrg /* XXX Could this go in the conversion_proc? */ 2400659607e0Smrg switch (pMse->negativeZ) { 2401659607e0Smrg case MSE_NOZMAP: /* do nothing */ 2402659607e0Smrg dz = 0; 2403659607e0Smrg break; 2404659607e0Smrg case MSE_MAPTOX: 2405659607e0Smrg if (dz != 0) { 2406659607e0Smrg dx = dz; 2407659607e0Smrg dz = 0; 2408659607e0Smrg } 2409659607e0Smrg break; 2410659607e0Smrg case MSE_MAPTOY: 2411659607e0Smrg if (dz != 0) { 2412659607e0Smrg dy = dz; 2413659607e0Smrg dz = 0; 2414659607e0Smrg } 2415659607e0Smrg break; 2416659607e0Smrg default: /* buttons */ 2417659607e0Smrg buttons &= ~(pMse->negativeZ | pMse->positiveZ); 2418659607e0Smrg if (dz < 0) { 2419659607e0Smrg zbutton = pMse->negativeZ; 2420659607e0Smrg zbuttoncount = -dz; 2421659607e0Smrg } else if (dz > 0) { 2422659607e0Smrg zbutton = pMse->positiveZ; 2423659607e0Smrg zbuttoncount = dz; 2424659607e0Smrg } 2425659607e0Smrg dz = 0; 2426659607e0Smrg break; 2427659607e0Smrg } 2428659607e0Smrg switch (pMse->negativeW) { 2429659607e0Smrg case MSE_NOZMAP: /* do nothing */ 2430659607e0Smrg dw = 0; 2431659607e0Smrg break; 2432659607e0Smrg case MSE_MAPTOX: 2433659607e0Smrg if (dw != 0) { 2434659607e0Smrg dx = dw; 2435659607e0Smrg dw = 0; 2436659607e0Smrg } 2437659607e0Smrg break; 2438659607e0Smrg case MSE_MAPTOY: 2439659607e0Smrg if (dw != 0) { 2440659607e0Smrg dy = dw; 2441659607e0Smrg dw = 0; 2442659607e0Smrg } 2443659607e0Smrg break; 2444659607e0Smrg default: /* buttons */ 2445659607e0Smrg buttons &= ~(pMse->negativeW | pMse->positiveW); 2446659607e0Smrg if (dw < 0) { 2447659607e0Smrg wbutton = pMse->negativeW; 2448659607e0Smrg wbuttoncount = -dw; 2449659607e0Smrg } else if (dw > 0) { 2450659607e0Smrg wbutton = pMse->positiveW; 2451659607e0Smrg wbuttoncount = dw; 2452659607e0Smrg } 2453659607e0Smrg dw = 0; 2454659607e0Smrg break; 2455659607e0Smrg } 2456659607e0Smrg 2457659607e0Smrg 2458659607e0Smrg /* Apply angle offset */ 2459659607e0Smrg if (pMse->angleOffset != 0) { 2460659607e0Smrg double rad = 3.141592653 * pMse->angleOffset / 180.0; 2461659607e0Smrg int ndx = dx; 2462659607e0Smrg dx = (int)((dx * cos(rad)) + (dy * sin(rad)) + 0.5); 2463659607e0Smrg dy = (int)((dy * cos(rad)) - (ndx * sin(rad)) + 0.5); 2464659607e0Smrg } 2465659607e0Smrg 2466659607e0Smrg dx = pMse->invX * dx; 2467659607e0Smrg dy = pMse->invY * dy; 2468659607e0Smrg if (pMse->flipXY) { 2469659607e0Smrg int tmp = dx; 2470659607e0Smrg dx = dy; 2471659607e0Smrg dy = tmp; 2472659607e0Smrg } 2473659607e0Smrg 2474659607e0Smrg /* Accumulate the scaled dx, dy in the private variables 2475659607e0Smrg fracdx,fracdy and return the integer number part */ 2476659607e0Smrg if (mousepriv) { 2477659607e0Smrg mousepriv->fracdx += mousepriv->sensitivity*dx; 2478659607e0Smrg mousepriv->fracdy += mousepriv->sensitivity*dy; 2479659607e0Smrg mousepriv->fracdx -= ( dx=(int)(mousepriv->fracdx) ); 2480659607e0Smrg mousepriv->fracdy -= ( dy=(int)(mousepriv->fracdy) ); 2481659607e0Smrg } 2482659607e0Smrg 2483659607e0Smrg /* If mouse wheel movement has to be mapped on a button, we need to 2484659607e0Smrg * loop for button press and release events. */ 2485659607e0Smrg do { 2486659607e0Smrg MouseDoPostEvent(pInfo, buttons | zbutton | wbutton, dx, dy); 2487659607e0Smrg dx = dy = 0; 2488659607e0Smrg if (zbutton || wbutton) 2489659607e0Smrg MouseDoPostEvent(pInfo, buttons, 0, 0); 2490659607e0Smrg if (--zbuttoncount <= 0) 2491659607e0Smrg zbutton = 0; 2492659607e0Smrg if (--wbuttoncount <= 0) 2493659607e0Smrg wbutton = 0; 2494659607e0Smrg } while (zbutton || wbutton); 2495659607e0Smrg 2496659607e0Smrg pMse->lastButtons = truebuttons; 2497659607e0Smrg} 2498659607e0Smrg/****************************************************************** 2499659607e0Smrg * 2500659607e0Smrg * Mouse Setup Code 2501659607e0Smrg * 2502659607e0Smrg ******************************************************************/ 2503659607e0Smrg/* 2504659607e0Smrg * This array is indexed by the MouseProtocolID values, so the order of the 2505659607e0Smrg * entries must match that of the MouseProtocolID enum in xf86OSmouse.h. 2506659607e0Smrg */ 2507659607e0Smrgstatic unsigned char proto[PROT_NUMPROTOS][8] = { 2508659607e0Smrg /* --header-- ---data--- packet -4th-byte- mouse */ 2509659607e0Smrg /* mask id mask id bytes mask id flags */ 2510659607e0Smrg /* Serial mice */ 2511659607e0Smrg { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MicroSoft */ 2512659607e0Smrg { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_SAFE }, /* MouseSystems */ 2513659607e0Smrg { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MMSeries */ 2514659607e0Smrg { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* Logitech */ 2515659607e0Smrg { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MouseMan */ 2516659607e0Smrg { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MM_HitTablet */ 2517659607e0Smrg { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* GlidePoint */ 2518659607e0Smrg { 0x40, 0x40, 0x40, 0x00, 3, ~0x3f, 0x00, MPF_NONE }, /* IntelliMouse */ 2519659607e0Smrg { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* ThinkingMouse */ 2520659607e0Smrg { 0x80, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ACECAD */ 2521659607e0Smrg { 0x40, 0x40, 0x40, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* ValuMouseScroll */ 2522659607e0Smrg /* PS/2 variants */ 2523659607e0Smrg { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* PS/2 mouse */ 2524659607e0Smrg { 0xc8, 0x08, 0x00, 0x00, 3, 0x00, 0x00, MPF_NONE }, /* genericPS/2 mouse*/ 2525659607e0Smrg { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* IntelliMouse */ 2526659607e0Smrg { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* Explorer */ 2527659607e0Smrg { 0x80, 0x80, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ThinkingMouse */ 2528659607e0Smrg { 0x08, 0x08, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MouseMan+ */ 2529659607e0Smrg { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* GlidePoint */ 2530659607e0Smrg { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* NetMouse */ 2531659607e0Smrg { 0xc0, 0x00, 0x00, 0x00, 6, 0x00, 0xff, MPF_NONE }, /* NetScroll */ 2532659607e0Smrg /* Bus Mouse */ 2533659607e0Smrg { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* BusMouse */ 2534659607e0Smrg { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* Auto (dummy) */ 2535659607e0Smrg { 0xf8, 0x80, 0x00, 0x00, 8, 0x00, 0xff, MPF_NONE }, /* SysMouse */ 2536659607e0Smrg}; 2537659607e0Smrg 2538659607e0Smrg 2539659607e0Smrg/* 2540659607e0Smrg * SetupMouse -- 2541659607e0Smrg * Sets up the mouse parameters 2542659607e0Smrg */ 2543659607e0Smrgstatic Bool 2544659607e0SmrgSetupMouse(InputInfoPtr pInfo) 2545659607e0Smrg{ 2546659607e0Smrg MouseDevPtr pMse; 2547659607e0Smrg int i; 2548659607e0Smrg int protoPara[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; 2549659607e0Smrg const char *name = NULL; 2550659607e0Smrg Bool automatic = FALSE; 2551659607e0Smrg 2552659607e0Smrg pMse = pInfo->private; 2553659607e0Smrg 2554659607e0Smrg /* Handle the "Auto" protocol. */ 2555659607e0Smrg if (pMse->protocolID == PROT_AUTO) { 2556659607e0Smrg /* 2557659607e0Smrg * We come here when user specifies protocol "auto" in 2558659607e0Smrg * the configuration file or thru the xf86misc extensions. 2559659607e0Smrg * So we initialize autoprobing here. 2560659607e0Smrg * Probe for PnP/OS mouse first. If unsuccessful 2561659607e0Smrg * try to guess protocol from incoming data. 2562659607e0Smrg */ 2563659607e0Smrg automatic = TRUE; 2564659607e0Smrg pMse->autoProbe = TRUE; 2565659607e0Smrg name = autoOSProtocol(pInfo,protoPara); 2566659607e0Smrg if (name) { 2567659607e0Smrg#ifdef EXTMOUSEDEBUG 2568659607e0Smrg ErrorF("PnP/OS Mouse detected: %s\n",name); 2569659607e0Smrg#endif 2570659607e0Smrg } 2571659607e0Smrg } 2572659607e0Smrg 2573659607e0Smrg SetMouseProto(pMse, pMse->protocolID); 2574659607e0Smrg 2575659607e0Smrg if (automatic) { 2576659607e0Smrg if (name) { 2577659607e0Smrg /* Possible protoPara overrides from SetupAuto. */ 2578659607e0Smrg for (i = 0; i < sizeof(pMse->protoPara); i++) 2579659607e0Smrg if (protoPara[i] != -1) 2580659607e0Smrg pMse->protoPara[i] = protoPara[i]; 2581659607e0Smrg /* if we come here PnP/OS mouse probing was successful */ 2582659607e0Smrg } else { 2583659607e0Smrg#if 1 2584659607e0Smrg /* PnP/OS mouse probing wasn't successful; we look at data */ 2585659607e0Smrg#else 2586659607e0Smrg xf86Msg(X_ERROR, "%s: cannot determine the mouse protocol\n", 2587659607e0Smrg pInfo->name); 2588659607e0Smrg return FALSE; 2589659607e0Smrg#endif 2590659607e0Smrg } 2591659607e0Smrg } 2592659607e0Smrg 2593659607e0Smrg /* 2594659607e0Smrg * If protocol has changed fetch the default options 2595659607e0Smrg * for the new protocol. 2596659607e0Smrg */ 2597659607e0Smrg if (pMse->oldProtocolID != pMse->protocolID) { 2598659607e0Smrg pointer tmp = NULL; 2599659607e0Smrg if ((pMse->protocolID >= 0) 2600659607e0Smrg && (pMse->protocolID < PROT_NUMPROTOS) 2601659607e0Smrg && mouseProtocols[pMse->protocolID].defaults) 2602659607e0Smrg tmp = xf86OptionListCreate( 2603659607e0Smrg mouseProtocols[pMse->protocolID].defaults, -1, 0); 2604659607e0Smrg pInfo->options = xf86OptionListMerge(pInfo->options, tmp); 2605659607e0Smrg /* 2606659607e0Smrg * If baudrate is set write it back to the option 2607659607e0Smrg * list so that the serial interface code can access 2608659607e0Smrg * the new value. Not set means default. 2609659607e0Smrg */ 2610659607e0Smrg if (pMse->baudRate) 2611659607e0Smrg xf86ReplaceIntOption(pInfo->options, "BaudRate", pMse->baudRate); 2612659607e0Smrg pMse->oldProtocolID = pMse->protocolID; /* hack */ 2613659607e0Smrg } 2614659607e0Smrg 2615659607e0Smrg 2616659607e0Smrg /* Set the port parameters. */ 2617659607e0Smrg if (!automatic) 2618659607e0Smrg xf86SetSerial(pInfo->fd, pInfo->options); 2619659607e0Smrg 2620659607e0Smrg if (!initMouseHW(pInfo)) 2621659607e0Smrg return FALSE; 2622659607e0Smrg 2623659607e0Smrg pMse->protoBufTail = 0; 2624659607e0Smrg pMse->inSync = 0; 2625659607e0Smrg 2626659607e0Smrg return TRUE; 2627659607e0Smrg} 2628659607e0Smrg 2629659607e0Smrg/******************************************************************** 2630659607e0Smrg * 2631659607e0Smrg * Mouse HW setup code 2632659607e0Smrg * 2633659607e0Smrg ********************************************************************/ 2634659607e0Smrg 2635659607e0Smrg/* 2636659607e0Smrg** The following lines take care of the Logitech MouseMan protocols. 2637659607e0Smrg** The "Logitech" protocol is for the old "series 9" Logitech products. 2638659607e0Smrg** All products since then use the "MouseMan" protocol. Some models 2639659607e0Smrg** were programmable, but most (all?) of the current models are not. 2640659607e0Smrg** 2641659607e0Smrg** NOTE: There are different versions of both MouseMan and TrackMan! 2642659607e0Smrg** Hence I add another protocol PROT_LOGIMAN, which the user can 2643659607e0Smrg** specify as MouseMan in his XF86Config file. This entry was 2644659607e0Smrg** formerly handled as a special case of PROT_MS. However, people 2645659607e0Smrg** who don't have the middle button problem, can still specify 2646659607e0Smrg** Microsoft and use PROT_MS. 2647659607e0Smrg** 2648659607e0Smrg** By default, these mice should use a 3 byte Microsoft protocol 2649659607e0Smrg** plus a 4th byte for the middle button. However, the mouse might 2650659607e0Smrg** have switched to a different protocol before we use it, so I send 2651659607e0Smrg** the proper sequence just in case. 2652659607e0Smrg** 2653659607e0Smrg** NOTE: - all commands to (at least the European) MouseMan have to 2654659607e0Smrg** be sent at 1200 Baud. 2655659607e0Smrg** - each command starts with a '*'. 2656659607e0Smrg** - whenever the MouseMan receives a '*', it will switch back 2657659607e0Smrg** to 1200 Baud. Hence I have to select the desired protocol 2658659607e0Smrg** first, then select the baud rate. 2659659607e0Smrg** 2660659607e0Smrg** The protocols supported by the (European) MouseMan are: 2661659607e0Smrg** - 5 byte packed binary protocol, as with the Mouse Systems 2662659607e0Smrg** mouse. Selected by sequence "*U". 2663659607e0Smrg** - 2 button 3 byte MicroSoft compatible protocol. Selected 2664659607e0Smrg** by sequence "*V". 2665659607e0Smrg** - 3 button 3+1 byte MicroSoft compatible protocol (default). 2666659607e0Smrg** Selected by sequence "*X". 2667659607e0Smrg** 2668659607e0Smrg** The following baud rates are supported: 2669659607e0Smrg** - 1200 Baud (default). Selected by sequence "*n". 2670659607e0Smrg** - 9600 Baud. Selected by sequence "*q". 2671659607e0Smrg** 2672659607e0Smrg** Selecting a sample rate is no longer supported with the MouseMan! 2673659607e0Smrg** [CHRIS-211092] 2674659607e0Smrg*/ 2675659607e0Smrg 2676659607e0Smrg/* 2677659607e0Smrg * Do a reset wrap mode before reset. 2678659607e0Smrg */ 2679659607e0Smrg#define do_ps2Reset(x) { \ 2680659607e0Smrg int i = RETRY_COUNT;\ 2681659607e0Smrg while (i-- > 0) { \ 2682659607e0Smrg xf86FlushInput(x->fd); \ 2683659607e0Smrg if (ps2Reset(x)) break; \ 2684659607e0Smrg } \ 2685659607e0Smrg } 2686659607e0Smrg 2687659607e0Smrg 2688659607e0Smrgstatic Bool 2689659607e0SmrginitMouseHW(InputInfoPtr pInfo) 2690659607e0Smrg{ 2691659607e0Smrg MouseDevPtr pMse = pInfo->private; 2692659607e0Smrg const char *s; 2693659607e0Smrg unsigned char c; 2694659607e0Smrg int speed; 2695659607e0Smrg pointer options; 2696659607e0Smrg unsigned char *param = NULL; 2697659607e0Smrg int paramlen = 0; 2698659607e0Smrg int count = RETRY_COUNT; 2699659607e0Smrg Bool ps2Init = TRUE; 2700659607e0Smrg 2701659607e0Smrg switch (pMse->protocolID) { 2702659607e0Smrg case PROT_LOGI: /* Logitech Mice */ 2703659607e0Smrg /* 2704659607e0Smrg * The baud rate selection command must be sent at the current 2705659607e0Smrg * baud rate; try all likely settings. 2706659607e0Smrg */ 2707659607e0Smrg speed = pMse->baudRate; 2708659607e0Smrg switch (speed) { 2709659607e0Smrg case 9600: 2710659607e0Smrg s = "*q"; 2711659607e0Smrg break; 2712659607e0Smrg case 4800: 2713659607e0Smrg s = "*p"; 2714659607e0Smrg break; 2715659607e0Smrg case 2400: 2716659607e0Smrg s = "*o"; 2717659607e0Smrg break; 2718659607e0Smrg case 1200: 2719659607e0Smrg s = "*n"; 2720659607e0Smrg break; 2721659607e0Smrg default: 2722659607e0Smrg /* Fallback value */ 2723659607e0Smrg speed = 1200; 2724659607e0Smrg s = "*n"; 2725659607e0Smrg } 2726659607e0Smrg xf86SetSerialSpeed(pInfo->fd, 9600); 2727659607e0Smrg xf86WriteSerial(pInfo->fd, s, 2); 2728659607e0Smrg usleep(100000); 2729659607e0Smrg xf86SetSerialSpeed(pInfo->fd, 4800); 2730659607e0Smrg xf86WriteSerial(pInfo->fd, s, 2); 2731659607e0Smrg usleep(100000); 2732659607e0Smrg xf86SetSerialSpeed(pInfo->fd, 2400); 2733659607e0Smrg xf86WriteSerial(pInfo->fd, s, 2); 2734659607e0Smrg usleep(100000); 2735659607e0Smrg xf86SetSerialSpeed(pInfo->fd, 1200); 2736659607e0Smrg xf86WriteSerial(pInfo->fd, s, 2); 2737659607e0Smrg usleep(100000); 2738659607e0Smrg xf86SetSerialSpeed(pInfo->fd, speed); 2739659607e0Smrg 2740659607e0Smrg /* Select MM series data format. */ 2741659607e0Smrg xf86WriteSerial(pInfo->fd, "S", 1); 2742659607e0Smrg usleep(100000); 2743659607e0Smrg /* Set the parameters up for the MM series protocol. */ 2744659607e0Smrg options = pInfo->options; 2745659607e0Smrg xf86CollectInputOptions(pInfo, mmDefaults, NULL); 2746659607e0Smrg xf86SetSerial(pInfo->fd, pInfo->options); 2747659607e0Smrg pInfo->options = options; 2748659607e0Smrg 2749659607e0Smrg /* Select report rate/frequency. */ 2750659607e0Smrg if (pMse->sampleRate <= 0) c = 'O'; /* 100 */ 2751659607e0Smrg else if (pMse->sampleRate <= 15) c = 'J'; /* 10 */ 2752659607e0Smrg else if (pMse->sampleRate <= 27) c = 'K'; /* 20 */ 2753659607e0Smrg else if (pMse->sampleRate <= 42) c = 'L'; /* 35 */ 2754659607e0Smrg else if (pMse->sampleRate <= 60) c = 'R'; /* 50 */ 2755659607e0Smrg else if (pMse->sampleRate <= 85) c = 'M'; /* 67 */ 2756659607e0Smrg else if (pMse->sampleRate <= 125) c = 'Q'; /* 100 */ 2757659607e0Smrg else c = 'N'; /* 150 */ 2758659607e0Smrg xf86WriteSerial(pInfo->fd, &c, 1); 2759659607e0Smrg break; 2760659607e0Smrg 2761659607e0Smrg case PROT_LOGIMAN: 2762659607e0Smrg speed = pMse->baudRate; 2763659607e0Smrg switch (speed) { 2764659607e0Smrg case 9600: 2765659607e0Smrg s = "*q"; 2766659607e0Smrg break; 2767659607e0Smrg case 1200: 2768659607e0Smrg s = "*n"; 2769659607e0Smrg break; 2770659607e0Smrg default: 2771659607e0Smrg /* Fallback value */ 2772659607e0Smrg speed = 1200; 2773659607e0Smrg s = "*n"; 2774659607e0Smrg } 2775659607e0Smrg xf86SetSerialSpeed(pInfo->fd, 1200); 2776659607e0Smrg xf86WriteSerial(pInfo->fd, "*n", 2); 2777659607e0Smrg xf86WriteSerial(pInfo->fd, "*X", 2); 2778659607e0Smrg xf86WriteSerial(pInfo->fd, s, 2); 2779659607e0Smrg usleep(100000); 2780659607e0Smrg xf86SetSerialSpeed(pInfo->fd, speed); 2781659607e0Smrg break; 2782659607e0Smrg 2783659607e0Smrg case PROT_MMHIT: /* MM_HitTablet */ 2784659607e0Smrg /* 2785659607e0Smrg * Initialize Hitachi PUMA Plus - Model 1212E to desired settings. 2786659607e0Smrg * The tablet must be configured to be in MM mode, NO parity, 2787659607e0Smrg * Binary Format. pMse->sampleRate controls the sensitivity 2788659607e0Smrg * of the tablet. We only use this tablet for it's 4-button puck 2789659607e0Smrg * so we don't run in "Absolute Mode". 2790659607e0Smrg */ 2791659607e0Smrg xf86WriteSerial(pInfo->fd, "z8", 2); /* Set Parity = "NONE" */ 2792659607e0Smrg usleep(50000); 2793659607e0Smrg xf86WriteSerial(pInfo->fd, "zb", 2); /* Set Format = "Binary" */ 2794659607e0Smrg usleep(50000); 2795659607e0Smrg xf86WriteSerial(pInfo->fd, "@", 1); /* Set Report Mode = "Stream" */ 2796659607e0Smrg usleep(50000); 2797659607e0Smrg xf86WriteSerial(pInfo->fd, "R", 1); /* Set Output Rate = "45 rps" */ 2798659607e0Smrg usleep(50000); 2799659607e0Smrg xf86WriteSerial(pInfo->fd, "I\x20", 2); /* Set Incrememtal Mode "20" */ 2800659607e0Smrg usleep(50000); 2801659607e0Smrg xf86WriteSerial(pInfo->fd, "E", 1); /* Set Data Type = "Relative */ 2802659607e0Smrg usleep(50000); 2803659607e0Smrg /* 2804659607e0Smrg * These sample rates translate to 'lines per inch' on the Hitachi 2805659607e0Smrg * tablet. 2806659607e0Smrg */ 2807659607e0Smrg if (pMse->sampleRate <= 40) c = 'g'; 2808659607e0Smrg else if (pMse->sampleRate <= 100) c = 'd'; 2809659607e0Smrg else if (pMse->sampleRate <= 200) c = 'e'; 2810659607e0Smrg else if (pMse->sampleRate <= 500) c = 'h'; 2811659607e0Smrg else if (pMse->sampleRate <= 1000) c = 'j'; 2812659607e0Smrg else c = 'd'; 2813659607e0Smrg xf86WriteSerial(pInfo->fd, &c, 1); 2814659607e0Smrg usleep(50000); 2815659607e0Smrg xf86WriteSerial(pInfo->fd, "\021", 1); /* Resume DATA output */ 2816659607e0Smrg break; 2817659607e0Smrg 2818659607e0Smrg case PROT_THINKING: /* ThinkingMouse */ 2819659607e0Smrg /* This mouse may send a PnP ID string, ignore it. */ 2820659607e0Smrg usleep(200000); 2821659607e0Smrg xf86FlushInput(pInfo->fd); 2822659607e0Smrg /* Send the command to initialize the beast. */ 2823659607e0Smrg for (s = "E5E5"; *s; ++s) { 2824659607e0Smrg xf86WriteSerial(pInfo->fd, s, 1); 2825659607e0Smrg if ((xf86WaitForInput(pInfo->fd, 1000000) <= 0)) 2826659607e0Smrg break; 2827659607e0Smrg xf86ReadSerial(pInfo->fd, &c, 1); 2828659607e0Smrg if (c != *s) 2829659607e0Smrg break; 2830659607e0Smrg } 2831659607e0Smrg break; 2832659607e0Smrg 2833659607e0Smrg case PROT_MSC: /* MouseSystems Corp */ 2834659607e0Smrg usleep(100000); 2835659607e0Smrg xf86FlushInput(pInfo->fd); 2836659607e0Smrg break; 2837659607e0Smrg 2838659607e0Smrg case PROT_ACECAD: 2839659607e0Smrg /* initialize */ 2840659607e0Smrg /* A nul character resets. */ 2841659607e0Smrg xf86WriteSerial(pInfo->fd, "", 1); 2842659607e0Smrg usleep(50000); 2843659607e0Smrg /* Stream out relative mode high resolution increments of 1. */ 2844659607e0Smrg xf86WriteSerial(pInfo->fd, "@EeI!", 5); 2845659607e0Smrg break; 2846659607e0Smrg 2847659607e0Smrg case PROT_BM: /* bus/InPort mouse */ 2848659607e0Smrg if (osInfo->SetBMRes) 2849659607e0Smrg osInfo->SetBMRes(pInfo, pMse->protocol, pMse->sampleRate, 2850659607e0Smrg pMse->resolution); 2851659607e0Smrg break; 2852659607e0Smrg 2853659607e0Smrg case PROT_GENPS2: 2854659607e0Smrg ps2Init = FALSE; 2855659607e0Smrg break; 2856659607e0Smrg 2857659607e0Smrg case PROT_PS2: 2858659607e0Smrg case PROT_GLIDEPS2: 2859659607e0Smrg break; 2860659607e0Smrg 2861659607e0Smrg case PROT_IMPS2: /* IntelliMouse */ 2862659607e0Smrg { 2863659607e0Smrg static unsigned char seq[] = { 243, 200, 243, 100, 243, 80 }; 2864659607e0Smrg param = seq; 2865659607e0Smrg paramlen = sizeof(seq); 2866659607e0Smrg } 2867659607e0Smrg break; 2868659607e0Smrg 2869659607e0Smrg case PROT_EXPPS2: /* IntelliMouse Explorer */ 2870659607e0Smrg { 2871659607e0Smrg static unsigned char seq[] = { 243, 200, 243, 100, 243, 80, 2872659607e0Smrg 243, 200, 243, 200, 243, 80 }; 2873659607e0Smrg 2874659607e0Smrg param = seq; 2875659607e0Smrg paramlen = sizeof(seq); 2876659607e0Smrg } 2877659607e0Smrg break; 2878659607e0Smrg 2879659607e0Smrg case PROT_NETPS2: /* NetMouse, NetMouse Pro, Mie Mouse */ 2880659607e0Smrg case PROT_NETSCPS2: /* NetScroll */ 2881659607e0Smrg { 2882659607e0Smrg static unsigned char seq[] = { 232, 3, 230, 230, 230, 233 }; 2883659607e0Smrg 2884659607e0Smrg param = seq; 2885659607e0Smrg paramlen = sizeof(seq); 2886659607e0Smrg } 2887659607e0Smrg break; 2888659607e0Smrg 2889659607e0Smrg case PROT_MMPS2: /* MouseMan+, FirstMouse+ */ 2890659607e0Smrg { 2891659607e0Smrg static unsigned char seq[] = { 230, 232, 0, 232, 3, 232, 2, 232, 1, 2892659607e0Smrg 230, 232, 3, 232, 1, 232, 2, 232, 3 }; 2893659607e0Smrg param = seq; 2894659607e0Smrg paramlen = sizeof(seq); 2895659607e0Smrg } 2896659607e0Smrg break; 2897659607e0Smrg 2898659607e0Smrg case PROT_THINKPS2: /* ThinkingMouse */ 2899659607e0Smrg { 2900659607e0Smrg static unsigned char seq[] = { 243, 10, 232, 0, 243, 20, 243, 60, 2901659607e0Smrg 243, 40, 243, 20, 243, 20, 243, 60, 2902659607e0Smrg 243, 40, 243, 20, 243, 20 }; 2903659607e0Smrg param = seq; 2904659607e0Smrg paramlen = sizeof(seq); 2905659607e0Smrg } 2906659607e0Smrg break; 2907659607e0Smrg case PROT_SYSMOUSE: 2908659607e0Smrg if (osInfo->SetMiscRes) 2909659607e0Smrg osInfo->SetMiscRes(pInfo, pMse->protocol, pMse->sampleRate, 2910659607e0Smrg pMse->resolution); 2911659607e0Smrg break; 2912659607e0Smrg 2913659607e0Smrg default: 2914659607e0Smrg /* Nothing to do. */ 2915659607e0Smrg break; 2916659607e0Smrg } 2917659607e0Smrg 2918659607e0Smrg if (pMse->class & (MSE_PS2 | MSE_XPS2)) { 2919659607e0Smrg /* 2920659607e0Smrg * If one part of the PS/2 mouse initialization fails 2921659607e0Smrg * redo complete initialization. There are mice which 2922659607e0Smrg * have occasional problems with initialization and 2923659607e0Smrg * are in an unknown state. 2924659607e0Smrg */ 2925659607e0Smrg if (ps2Init) { 2926659607e0Smrg REDO: 2927659607e0Smrg do_ps2Reset(pInfo); 2928659607e0Smrg if (paramlen > 0) { 2929659607e0Smrg if (!ps2SendPacket(pInfo,param,paramlen)) { 2930659607e0Smrg usleep(30000); 2931659607e0Smrg xf86FlushInput(pInfo->fd); 2932659607e0Smrg if (!count--) 2933659607e0Smrg return TRUE; 2934659607e0Smrg goto REDO; 2935659607e0Smrg } 2936659607e0Smrg ps2GetDeviceID(pInfo); 2937659607e0Smrg usleep(30000); 2938659607e0Smrg xf86FlushInput(pInfo->fd); 2939659607e0Smrg } 2940659607e0Smrg 2941659607e0Smrg if (osInfo->SetPS2Res) { 2942659607e0Smrg osInfo->SetPS2Res(pInfo, pMse->protocol, pMse->sampleRate, 2943659607e0Smrg pMse->resolution); 2944659607e0Smrg } else { 2945659607e0Smrg unsigned char c2[2]; 2946659607e0Smrg 2947659607e0Smrg c = 0xE6; /*230*/ /* 1:1 scaling */ 2948659607e0Smrg if (!ps2SendPacket(pInfo,&c,1)) { 2949659607e0Smrg if (!count--) 2950659607e0Smrg return TRUE; 2951659607e0Smrg goto REDO; 2952659607e0Smrg } 2953659607e0Smrg c2[0] = 0xF3; /*243*/ /* set sampling rate */ 2954659607e0Smrg if (pMse->sampleRate > 0) { 2955659607e0Smrg if (pMse->sampleRate >= 200) 2956659607e0Smrg c2[1] = 200; 2957659607e0Smrg else if (pMse->sampleRate >= 100) 2958659607e0Smrg c2[1] = 100; 2959659607e0Smrg else if (pMse->sampleRate >= 80) 2960659607e0Smrg c2[1] = 80; 2961659607e0Smrg else if (pMse->sampleRate >= 60) 2962659607e0Smrg c2[1] = 60; 2963659607e0Smrg else if (pMse->sampleRate >= 40) 2964659607e0Smrg c2[1] = 40; 2965659607e0Smrg else 2966659607e0Smrg c2[1] = 20; 2967659607e0Smrg } else { 2968659607e0Smrg c2[1] = 100; 2969659607e0Smrg } 2970659607e0Smrg if (!ps2SendPacket(pInfo,c2,2)) { 2971659607e0Smrg if (!count--) 2972659607e0Smrg return TRUE; 2973659607e0Smrg goto REDO; 2974659607e0Smrg } 2975659607e0Smrg c2[0] = 0xE8; /*232*/ /* set device resolution */ 2976659607e0Smrg if (pMse->resolution > 0) { 2977659607e0Smrg if (pMse->resolution >= 200) 2978659607e0Smrg c2[1] = 3; 2979659607e0Smrg else if (pMse->resolution >= 100) 2980659607e0Smrg c2[1] = 2; 2981659607e0Smrg else if (pMse->resolution >= 50) 2982659607e0Smrg c2[1] = 1; 2983659607e0Smrg else 2984659607e0Smrg c2[1] = 0; 2985659607e0Smrg } else { 2986659607e0Smrg c2[1] = 3; /* used to be 2, W. uses 3 */ 2987659607e0Smrg } 2988659607e0Smrg if (!ps2SendPacket(pInfo,c2,2)) { 2989659607e0Smrg if (!count--) 2990659607e0Smrg return TRUE; 2991659607e0Smrg goto REDO; 2992659607e0Smrg } 2993659607e0Smrg usleep(30000); 2994659607e0Smrg xf86FlushInput(pInfo->fd); 2995659607e0Smrg if (!ps2EnableDataReporting(pInfo)) { 2996659607e0Smrg xf86Msg(X_INFO, "%s: ps2EnableDataReporting: failed\n", 2997659607e0Smrg pInfo->name); 2998659607e0Smrg xf86FlushInput(pInfo->fd); 2999659607e0Smrg if (!count--) 3000659607e0Smrg return TRUE; 3001659607e0Smrg goto REDO; 3002659607e0Smrg } else { 3003659607e0Smrg xf86Msg(X_INFO, "%s: ps2EnableDataReporting: succeeded\n", 3004659607e0Smrg pInfo->name); 3005659607e0Smrg } 3006659607e0Smrg } 3007659607e0Smrg /* 3008659607e0Smrg * The PS/2 reset handling needs to be rechecked. 3009659607e0Smrg * We need to wait until after the 4.3 release. 3010659607e0Smrg */ 3011659607e0Smrg } 3012659607e0Smrg } else { 3013659607e0Smrg if (paramlen > 0) { 3014659607e0Smrg if (xf86WriteSerial(pInfo->fd, param, paramlen) != paramlen) 3015659607e0Smrg xf86Msg(X_ERROR, "%s: Mouse initialization failed\n", 3016659607e0Smrg pInfo->name); 3017659607e0Smrg usleep(30000); 3018659607e0Smrg xf86FlushInput(pInfo->fd); 3019659607e0Smrg } 3020659607e0Smrg } 3021659607e0Smrg 3022659607e0Smrg return TRUE; 3023659607e0Smrg} 3024659607e0Smrg 3025659607e0Smrg#ifdef SUPPORT_MOUSE_RESET 3026659607e0Smrgstatic Bool 3027659607e0SmrgmouseReset(InputInfoPtr pInfo, unsigned char val) 3028659607e0Smrg{ 3029659607e0Smrg MouseDevPtr pMse = pInfo->private; 3030659607e0Smrg mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv; 3031659607e0Smrg CARD32 prevEvent = mousepriv->lastEvent; 3032659607e0Smrg Bool expectReset = FALSE; 3033659607e0Smrg Bool ret = FALSE; 3034659607e0Smrg 3035659607e0Smrg mousepriv->lastEvent = GetTimeInMillis(); 3036659607e0Smrg 3037659607e0Smrg#ifdef EXTMOUSEDEBUG 3038659607e0Smrg ErrorF("byte: 0x%x time: %li\n",val,mousepriv->lastEvent); 3039659607e0Smrg#endif 3040659607e0Smrg /* 3041659607e0Smrg * We believe that the following is true: 3042659607e0Smrg * When the mouse is replugged it will send a reset package 3043659607e0Smrg * It takes several seconds to replug a mouse: We don't see 3044659607e0Smrg * events for several seconds before we see the replug event package. 3045659607e0Smrg * There is no significant delay between consecutive bytes 3046659607e0Smrg * of a replug event package. 3047659607e0Smrg * There are no bytes sent after the replug event package until 3048659607e0Smrg * the mouse is reset. 3049659607e0Smrg */ 3050659607e0Smrg 3051659607e0Smrg if (mousepriv->current == 0 3052659607e0Smrg && (mousepriv->lastEvent - prevEvent) < 4000) 3053659607e0Smrg return FALSE; 3054659607e0Smrg 3055659607e0Smrg if (mousepriv->current > 0 3056659607e0Smrg && (mousepriv->lastEvent - prevEvent) >= 1000) { 3057659607e0Smrg mousepriv->inReset = FALSE; 3058659607e0Smrg mousepriv->current = 0; 3059659607e0Smrg return FALSE; 3060659607e0Smrg } 3061659607e0Smrg 3062659607e0Smrg if (mousepriv->inReset) 3063659607e0Smrg mousepriv->inReset = FALSE; 3064659607e0Smrg 3065659607e0Smrg#ifdef EXTMOUSEDEBUG 3066659607e0Smrg ErrorF("Mouse Current: %i 0x%x\n",mousepriv->current, val); 3067659607e0Smrg#endif 3068659607e0Smrg 3069eeaac534Smrg /* here we put the mouse specific reset detection */ 3070659607e0Smrg /* They need to do three things: */ 3071659607e0Smrg /* Check if byte may be a reset byte */ 3072659607e0Smrg /* If so: Set expectReset TRUE */ 3073659607e0Smrg /* If convinced: Set inReset TRUE */ 3074659607e0Smrg /* Register BlockAndWakeupHandler */ 3075659607e0Smrg 3076659607e0Smrg /* PS/2 */ 3077659607e0Smrg { 3078659607e0Smrg unsigned char seq[] = { 0xaa, 0x00 }; 3079659607e0Smrg int len = sizeof(seq); 3080659607e0Smrg 3081659607e0Smrg if (seq[mousepriv->current] == val) 3082659607e0Smrg expectReset = TRUE; 3083659607e0Smrg 3084659607e0Smrg if (len == mousepriv->current + 1) { 3085659607e0Smrg mousepriv->inReset = TRUE; 3086659607e0Smrg mousepriv->expires = GetTimeInMillis() + 1000; 3087659607e0Smrg 3088659607e0Smrg#ifdef EXTMOUSEDEBUG 3089659607e0Smrg ErrorF("Found PS/2 Reset string\n"); 3090659607e0Smrg#endif 3091659607e0Smrg RegisterBlockAndWakeupHandlers (ps2BlockHandler, 3092659607e0Smrg ps2WakeupHandler, (pointer) pInfo); 3093659607e0Smrg ret = TRUE; 3094659607e0Smrg } 3095659607e0Smrg } 3096659607e0Smrg 3097659607e0Smrg if (!expectReset) 3098659607e0Smrg mousepriv->current = 0; 3099659607e0Smrg else 3100659607e0Smrg mousepriv->current++; 3101659607e0Smrg return ret; 3102659607e0Smrg} 3103659607e0Smrg 3104659607e0Smrgstatic void 3105659607e0Smrgps2BlockHandler(pointer data, struct timeval **waitTime, 3106659607e0Smrg pointer LastSelectMask) 3107659607e0Smrg{ 3108659607e0Smrg InputInfoPtr pInfo = (InputInfoPtr) data; 3109659607e0Smrg MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 3110659607e0Smrg mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv; 3111659607e0Smrg int ms; 3112659607e0Smrg 3113659607e0Smrg if (mousepriv->inReset) { 3114659607e0Smrg ms = mousepriv->expires - GetTimeInMillis (); 3115659607e0Smrg if (ms <= 0) 3116659607e0Smrg ms = 0; 3117659607e0Smrg AdjustWaitForDelay (waitTime, ms); 3118659607e0Smrg } else 3119659607e0Smrg RemoveBlockAndWakeupHandlers (ps2BlockHandler, ps2WakeupHandler, 3120659607e0Smrg (pointer) pInfo); 3121659607e0Smrg} 3122659607e0Smrg 3123659607e0Smrgstatic void 3124659607e0Smrgps2WakeupHandler(pointer data, int i, pointer LastSelectMask) 3125659607e0Smrg{ 3126659607e0Smrg InputInfoPtr pInfo = (InputInfoPtr) data; 3127659607e0Smrg MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 3128659607e0Smrg mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv; 3129659607e0Smrg int ms; 3130659607e0Smrg 3131659607e0Smrg if (mousepriv->inReset) { 3132659607e0Smrg unsigned char val; 3133659607e0Smrg int blocked; 3134659607e0Smrg 3135659607e0Smrg ms = mousepriv->expires - GetTimeInMillis(); 3136659607e0Smrg if (ms > 0) 3137659607e0Smrg return; 3138659607e0Smrg 3139659607e0Smrg blocked = xf86BlockSIGIO (); 3140659607e0Smrg 3141659607e0Smrg xf86MsgVerb(X_INFO,3, 3142659607e0Smrg "Got reinsert event: reinitializing PS/2 mouse\n"); 3143659607e0Smrg val = 0xf4; 3144659607e0Smrg if (xf86WriteSerial(pInfo->fd, &val, 1) != 1) 3145659607e0Smrg xf86Msg(X_ERROR, "%s: Write to mouse failed\n", 3146659607e0Smrg pInfo->name); 3147659607e0Smrg xf86UnblockSIGIO(blocked); 3148659607e0Smrg } 3149659607e0Smrg RemoveBlockAndWakeupHandlers (ps2BlockHandler, ps2WakeupHandler, 3150659607e0Smrg (pointer) pInfo); 3151659607e0Smrg} 3152659607e0Smrg#endif /* SUPPORT_MOUSE_RESET */ 3153659607e0Smrg 3154659607e0Smrg/************************************************************ 3155659607e0Smrg * 3156659607e0Smrg * Autoprobe stuff 3157659607e0Smrg * 3158659607e0Smrg ************************************************************/ 3159659607e0Smrg#ifdef EXTMOUSEDEBUG 3160659607e0Smrg# define AP_DBG(x) { ErrorF("Autoprobe: "); ErrorF x; } 3161659607e0Smrg# define AP_DBGC(x) ErrorF x ; 3162659607e0Smrg# else 3163659607e0Smrg# define AP_DBG(x) 3164659607e0Smrg# define AP_DBGC(x) 3165659607e0Smrg#endif 3166659607e0Smrg 3167eeaac534Smrgstatic 3168659607e0SmrgMouseProtocolID hardProtocolList[] = { PROT_MSC, PROT_MM, PROT_LOGI, 3169659607e0Smrg PROT_LOGIMAN, PROT_MMHIT, 3170659607e0Smrg PROT_GLIDE, PROT_IMSERIAL, 3171659607e0Smrg PROT_THINKING, PROT_ACECAD, 3172659607e0Smrg PROT_THINKPS2, PROT_MMPS2, 3173659607e0Smrg PROT_GLIDEPS2, 3174659607e0Smrg PROT_NETSCPS2, PROT_EXPPS2,PROT_IMPS2, 3175659607e0Smrg PROT_GENPS2, PROT_NETPS2, 3176659607e0Smrg PROT_MS, 3177659607e0Smrg PROT_UNKNOWN 3178659607e0Smrg}; 3179659607e0Smrg 3180eeaac534Smrgstatic 3181659607e0SmrgMouseProtocolID softProtocolList[] = { PROT_MSC, PROT_MM, PROT_LOGI, 3182659607e0Smrg PROT_LOGIMAN, PROT_MMHIT, 3183659607e0Smrg PROT_GLIDE, PROT_IMSERIAL, 3184659607e0Smrg PROT_THINKING, PROT_ACECAD, 3185659607e0Smrg PROT_THINKPS2, PROT_MMPS2, 3186659607e0Smrg PROT_GLIDEPS2, 3187659607e0Smrg PROT_NETSCPS2 ,PROT_IMPS2, 3188659607e0Smrg PROT_GENPS2, 3189659607e0Smrg PROT_MS, 3190659607e0Smrg PROT_UNKNOWN 3191659607e0Smrg}; 3192659607e0Smrg 3193659607e0Smrgstatic const char * 3194659607e0SmrgautoOSProtocol(InputInfoPtr pInfo, int *protoPara) 3195659607e0Smrg{ 3196659607e0Smrg MouseDevPtr pMse = pInfo->private; 3197659607e0Smrg const char *name = NULL; 3198659607e0Smrg MouseProtocolID protocolID = PROT_UNKNOWN; 3199659607e0Smrg 3200659607e0Smrg /* Check if the OS has a detection mechanism. */ 3201659607e0Smrg if (osInfo->SetupAuto) { 3202659607e0Smrg name = osInfo->SetupAuto(pInfo, protoPara); 3203659607e0Smrg if (name) { 3204659607e0Smrg protocolID = ProtocolNameToID(name); 3205659607e0Smrg switch (protocolID) { 3206659607e0Smrg case PROT_UNKNOWN: 3207659607e0Smrg /* Check for a builtin OS-specific protocol. */ 3208659607e0Smrg if (osInfo->CheckProtocol && osInfo->CheckProtocol(name)) { 3209659607e0Smrg /* We can only come here if the protocol has been 3210659607e0Smrg * changed to auto thru the xf86misc extension 3211659607e0Smrg * and we have detected an OS specific builtin 3212659607e0Smrg * protocol. Currently we cannot handle this */ 3213659607e0Smrg name = NULL; 3214659607e0Smrg } else 3215659607e0Smrg name = NULL; 3216659607e0Smrg break; 3217659607e0Smrg case PROT_UNSUP: 3218659607e0Smrg name = NULL; 3219659607e0Smrg break; 3220659607e0Smrg default: 3221659607e0Smrg break; 3222659607e0Smrg } 3223659607e0Smrg } 3224659607e0Smrg } 3225659607e0Smrg if (!name) { 3226659607e0Smrg /* A PnP serial mouse? */ 3227659607e0Smrg protocolID = MouseGetPnpProtocol(pInfo); 3228659607e0Smrg if (protocolID >= 0 && protocolID < PROT_NUMPROTOS) { 3229659607e0Smrg name = ProtocolIDToName(protocolID); 3230659607e0Smrg xf86Msg(X_PROBED, "%s: PnP-detected protocol: \"%s\"\n", 3231659607e0Smrg pInfo->name, name); 3232659607e0Smrg } 3233659607e0Smrg } 3234eeaac534Smrg if (!name && osInfo->GuessProtocol) { 3235659607e0Smrg name = osInfo->GuessProtocol(pInfo, 0); 3236659607e0Smrg if (name) 3237659607e0Smrg protocolID = ProtocolNameToID(name); 3238659607e0Smrg } 3239659607e0Smrg 3240659607e0Smrg if (name) { 3241659607e0Smrg pMse->protocolID = protocolID; 3242659607e0Smrg } 3243659607e0Smrg 3244659607e0Smrg return name; 3245659607e0Smrg} 3246659607e0Smrg 3247659607e0Smrg/* 3248659607e0Smrg * createProtocolList() -- create a list of protocols which may 3249659607e0Smrg * match on the incoming data stream. 3250659607e0Smrg */ 3251659607e0Smrgstatic void 3252659607e0SmrgcreateProtoList(MouseDevPtr pMse, MouseProtocolID *protoList) 3253659607e0Smrg{ 3254659607e0Smrg int i, j, k = 0; 3255659607e0Smrg MouseProtocolID prot; 3256659607e0Smrg unsigned char *para; 3257659607e0Smrg mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3258659607e0Smrg MouseProtocolID *tmplist = NULL; 3259659607e0Smrg int blocked; 3260659607e0Smrg 3261659607e0Smrg AP_DBGC(("Autoprobe: ")); 3262659607e0Smrg for (i = 0; i < mPriv->count; i++) 3263659607e0Smrg AP_DBGC(("%2.2x ", (unsigned char) mPriv->data[i])); 3264659607e0Smrg AP_DBGC(("\n")); 3265659607e0Smrg 3266659607e0Smrg blocked = xf86BlockSIGIO (); 3267659607e0Smrg 3268659607e0Smrg /* create a private copy first so we can write in the old list */ 3269659607e0Smrg if ((tmplist = xalloc(sizeof(MouseProtocolID) * NUM_AUTOPROBE_PROTOS))){ 3270659607e0Smrg for (i = 0; protoList[i] != PROT_UNKNOWN; i++) { 3271659607e0Smrg tmplist[i] = protoList[i]; 3272659607e0Smrg } 3273659607e0Smrg tmplist[i] = PROT_UNKNOWN; 3274659607e0Smrg protoList = tmplist; 3275659607e0Smrg } else 3276659607e0Smrg return; 3277659607e0Smrg 3278659607e0Smrg for (i = 0; ((prot = protoList[i]) != PROT_UNKNOWN 3279659607e0Smrg && (k < NUM_AUTOPROBE_PROTOS - 1)) ; i++) { 3280659607e0Smrg Bool bad = TRUE; 3281659607e0Smrg unsigned char byte = 0; 3282659607e0Smrg int count = 0; 3283659607e0Smrg int next_header_candidate = 0; 3284659607e0Smrg int header_count = 0; 3285659607e0Smrg 3286659607e0Smrg if (!GetProtocol(prot)) 3287659607e0Smrg continue; 3288659607e0Smrg para = proto[prot]; 3289659607e0Smrg 3290659607e0Smrg AP_DBG(("Protocol: %s ", ProtocolIDToName(prot))); 3291659607e0Smrg 3292659607e0Smrg#ifdef EXTMOUSEDEBUG 3293659607e0Smrg for (j = 0; j < 7; j++) 3294659607e0Smrg AP_DBGC(("%2.2x ", (unsigned char) para[j])); 3295659607e0Smrg AP_DBGC(("\n")); 3296659607e0Smrg#endif 3297659607e0Smrg j = 0; 3298659607e0Smrg while (1) { 3299659607e0Smrg /* look for header */ 3300659607e0Smrg while (j < mPriv->count) { 3301659607e0Smrg if (((byte = mPriv->data[j++]) & para[0]) == para[1]){ 3302659607e0Smrg AP_DBG(("found header %2.2x\n",byte)); 3303659607e0Smrg next_header_candidate = j; 3304659607e0Smrg count = 1; 3305659607e0Smrg break; 3306659607e0Smrg } else { 3307659607e0Smrg /* 3308eeaac534Smrg * Bail out if number of bytes per package have 3309659607e0Smrg * been tested for header. 3310659607e0Smrg * Take bytes per package of leading garbage into 3311659607e0Smrg * account. 3312659607e0Smrg */ 3313659607e0Smrg if (j > para[4] && ++header_count > para[4]) { 3314659607e0Smrg j = mPriv->count; 3315659607e0Smrg break; 3316659607e0Smrg } 3317659607e0Smrg } 3318659607e0Smrg } 3319659607e0Smrg /* check if remaining data matches protocol */ 3320659607e0Smrg while (j < mPriv->count) { 3321659607e0Smrg byte = mPriv->data[j++]; 3322659607e0Smrg if (count == para[4]) { 3323659607e0Smrg count = 0; 3324659607e0Smrg /* check and eat excess byte */ 3325659607e0Smrg if (((byte & para[0]) != para[1]) 3326659607e0Smrg && ((byte & para[5]) == para[6])) { 3327659607e0Smrg AP_DBG(("excess byte found\n")); 3328659607e0Smrg continue; 3329659607e0Smrg } 3330659607e0Smrg } 3331659607e0Smrg if (count == 0) { 3332659607e0Smrg /* validate next header */ 3333659607e0Smrg bad = FALSE; 3334659607e0Smrg AP_DBG(("Complete set found\n")); 3335659607e0Smrg if ((byte & para[0]) != para[1]) { 3336659607e0Smrg AP_DBG(("Autoprobe: header bad\n")); 3337659607e0Smrg bad = TRUE; 3338659607e0Smrg break; 3339659607e0Smrg } else { 3340659607e0Smrg count++; 3341659607e0Smrg continue; 3342659607e0Smrg } 3343659607e0Smrg } 3344659607e0Smrg /* validate data */ 3345659607e0Smrg else if (((byte & para[2]) != para[3]) 3346659607e0Smrg || ((para[7] & MPF_SAFE) 3347659607e0Smrg && ((byte & para[0]) == para[1]))) { 3348659607e0Smrg AP_DBG(("data bad\n")); 3349659607e0Smrg bad = TRUE; 3350659607e0Smrg break; 3351659607e0Smrg } else { 3352659607e0Smrg count ++; 3353659607e0Smrg continue; 3354659607e0Smrg } 3355659607e0Smrg } 3356659607e0Smrg if (!bad) { 3357659607e0Smrg /* this is a matching protocol */ 3358659607e0Smrg mPriv->protoList[k++] = prot; 3359659607e0Smrg AP_DBG(("Autoprobe: Adding protocol %s to list (entry %i)\n", 3360659607e0Smrg ProtocolIDToName(prot),k-1)); 3361659607e0Smrg break; 3362659607e0Smrg } 3363659607e0Smrg j = next_header_candidate; 3364659607e0Smrg next_header_candidate = 0; 3365659607e0Smrg /* we have tested number of bytes per package for header */ 3366659607e0Smrg if (j > para[4] && ++header_count > para[4]) 3367659607e0Smrg break; 3368659607e0Smrg /* we have not found anything that looks like a header */ 3369659607e0Smrg if (!next_header_candidate) 3370659607e0Smrg break; 3371659607e0Smrg AP_DBG(("Looking for new header\n")); 3372659607e0Smrg } 3373659607e0Smrg } 3374659607e0Smrg 3375659607e0Smrg xf86UnblockSIGIO(blocked); 3376659607e0Smrg 3377659607e0Smrg mPriv->protoList[k] = PROT_UNKNOWN; 3378659607e0Smrg 3379659607e0Smrg xfree(tmplist); 3380659607e0Smrg} 3381659607e0Smrg 3382659607e0Smrg 3383659607e0Smrg/* This only needs to be done once */ 3384eeaac534Smrgstatic void **serialDefaultsList = NULL; 3385659607e0Smrg 3386659607e0Smrg/* 3387659607e0Smrg * createSerialDefaultsLists() - create a list of the different default 3388659607e0Smrg * settings for the serial interface of the known protocols. 3389659607e0Smrg */ 3390659607e0Smrgstatic void 3391659607e0SmrgcreateSerialDefaultsList(void) 3392659607e0Smrg{ 3393659607e0Smrg int i = 0, j, k; 3394659607e0Smrg 3395659607e0Smrg serialDefaultsList = (void **)xnfalloc(sizeof(void*)); 3396659607e0Smrg serialDefaultsList[0] = NULL; 3397659607e0Smrg 3398659607e0Smrg for (j = 0; mouseProtocols[j].name; j++) { 3399659607e0Smrg if (!mouseProtocols[j].defaults) 3400659607e0Smrg continue; 3401659607e0Smrg for (k = 0; k < i; k++) 3402659607e0Smrg if (mouseProtocols[j].defaults == serialDefaultsList[k]) 3403659607e0Smrg continue; 3404659607e0Smrg i++; 3405659607e0Smrg serialDefaultsList = (void**)xnfrealloc(serialDefaultsList, 3406659607e0Smrg sizeof(void*)*(i+1)); 3407659607e0Smrg serialDefaultsList[i-1] = mouseProtocols[j].defaults; 3408659607e0Smrg serialDefaultsList[i] = NULL; 3409659607e0Smrg } 3410659607e0Smrg} 3411659607e0Smrg 3412659607e0Smrgtypedef enum { 3413659607e0Smrg STATE_INVALID, 3414659607e0Smrg STATE_UNCERTAIN, 3415659607e0Smrg STATE_VALID 3416659607e0Smrg} validState; 3417659607e0Smrg 3418659607e0Smrg/* Probing threshold values */ 3419659607e0Smrg#define PROBE_UNCERTAINTY 50 3420659607e0Smrg#define BAD_CERTAINTY 6 3421659607e0Smrg#define BAD_INC_CERTAINTY 1 3422659607e0Smrg#define BAD_INC_CERTAINTY_WHEN_SYNC_LOST 2 3423659607e0Smrg 3424659607e0Smrgstatic validState 3425659607e0SmrgvalidCount(mousePrivPtr mPriv, Bool inSync, Bool lostSync) 3426659607e0Smrg{ 3427659607e0Smrg if (inSync) { 3428659607e0Smrg if (!--mPriv->goodCount) { 3429659607e0Smrg /* we are sure to have found the correct protocol */ 3430659607e0Smrg mPriv->badCount = 0; 3431659607e0Smrg return STATE_VALID; 3432659607e0Smrg } 3433659607e0Smrg AP_DBG(("%i successful rounds to go\n", 3434659607e0Smrg mPriv->goodCount)); 3435659607e0Smrg return STATE_UNCERTAIN; 3436659607e0Smrg } 3437659607e0Smrg 3438659607e0Smrg 3439659607e0Smrg /* We are out of sync again */ 3440659607e0Smrg mPriv->goodCount = PROBE_UNCERTAINTY; 3441659607e0Smrg /* We increase uncertainty of having the correct protocol */ 3442659607e0Smrg mPriv->badCount+= lostSync ? BAD_INC_CERTAINTY_WHEN_SYNC_LOST 3443659607e0Smrg : BAD_INC_CERTAINTY; 3444659607e0Smrg 3445659607e0Smrg if (mPriv->badCount < BAD_CERTAINTY) { 3446659607e0Smrg /* We are not convinced yet to have the wrong protocol */ 3447659607e0Smrg AP_DBG(("Changing protocol after: %i rounds\n", 3448659607e0Smrg BAD_CERTAINTY - mPriv->badCount)); 3449659607e0Smrg return STATE_UNCERTAIN; 3450659607e0Smrg } 3451659607e0Smrg return STATE_INVALID; 3452659607e0Smrg} 3453659607e0Smrg 3454659607e0Smrg#define RESET_VALIDATION mPriv->goodCount = PROBE_UNCERTAINTY;\ 3455659607e0Smrg mPriv->badCount = 0;\ 3456659607e0Smrg mPriv->prevDx = 0;\ 3457659607e0Smrg mPriv->prevDy = 0;\ 3458659607e0Smrg mPriv->accDx = 0;\ 3459659607e0Smrg mPriv->accDy = 0;\ 3460659607e0Smrg mPriv->acc = 0; 3461659607e0Smrg 3462659607e0Smrgstatic void 3463659607e0SmrgautoProbeMouse(InputInfoPtr pInfo, Bool inSync, Bool lostSync) 3464659607e0Smrg{ 3465659607e0Smrg MouseDevPtr pMse = pInfo->private; 3466659607e0Smrg mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3467659607e0Smrg 3468659607e0Smrg MouseProtocolID *protocolList = NULL; 3469659607e0Smrg 3470659607e0Smrg while (1) { 3471659607e0Smrg switch (mPriv->autoState) { 3472659607e0Smrg case AUTOPROBE_GOOD: 3473659607e0Smrg if (inSync) 3474659607e0Smrg return; 3475659607e0Smrg AP_DBG(("State GOOD\n")); 3476659607e0Smrg RESET_VALIDATION; 3477659607e0Smrg mPriv->autoState = AUTOPROBE_VALIDATE1; 3478659607e0Smrg return; 3479659607e0Smrg case AUTOPROBE_H_GOOD: 3480659607e0Smrg if (inSync) 3481659607e0Smrg return; 3482659607e0Smrg AP_DBG(("State H_GOOD\n")); 3483659607e0Smrg RESET_VALIDATION; 3484659607e0Smrg mPriv->autoState = AUTOPROBE_H_VALIDATE2; 3485659607e0Smrg return; 3486659607e0Smrg case AUTOPROBE_H_NOPROTO: 3487659607e0Smrg AP_DBG(("State H_NOPROTO\n")); 3488659607e0Smrg mPriv->protocolID = 0; 3489659607e0Smrg mPriv->autoState = AUTOPROBE_H_SETPROTO; 3490659607e0Smrg break; 3491659607e0Smrg case AUTOPROBE_H_SETPROTO: 3492659607e0Smrg AP_DBG(("State H_SETPROTO\n")); 3493659607e0Smrg if ((pMse->protocolID = hardProtocolList[mPriv->protocolID++]) 3494659607e0Smrg == PROT_UNKNOWN) { 3495659607e0Smrg mPriv->protocolID = 0; 3496659607e0Smrg break; 3497659607e0Smrg } else if (GetProtocol(pMse->protocolID) && SetupMouse(pInfo)) { 3498659607e0Smrg FlushButtons(pMse); 3499659607e0Smrg RESET_VALIDATION; 3500659607e0Smrg AP_DBG(("Autoprobe: Trying Protocol: %s\n", 3501659607e0Smrg ProtocolIDToName(pMse->protocolID))); 3502659607e0Smrg mPriv->autoState = AUTOPROBE_H_VALIDATE1; 3503659607e0Smrg return; 3504659607e0Smrg } 3505659607e0Smrg break; 3506659607e0Smrg case AUTOPROBE_H_VALIDATE1: 3507659607e0Smrg AP_DBG(("State H_VALIDATE1\n")); 3508659607e0Smrg switch (validCount(mPriv,inSync,lostSync)) { 3509659607e0Smrg case STATE_INVALID: 3510659607e0Smrg mPriv->autoState = AUTOPROBE_H_SETPROTO; 3511659607e0Smrg break; 3512659607e0Smrg case STATE_VALID: 3513659607e0Smrg xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3514659607e0Smrg ProtocolIDToName(pMse->protocolID)); 3515659607e0Smrg mPriv->autoState = AUTOPROBE_H_GOOD; 3516659607e0Smrg return; 3517659607e0Smrg case STATE_UNCERTAIN: 3518659607e0Smrg return; 3519659607e0Smrg default: 3520659607e0Smrg break; 3521659607e0Smrg } 3522659607e0Smrg break; 3523659607e0Smrg case AUTOPROBE_H_VALIDATE2: 3524659607e0Smrg AP_DBG(("State H_VALIDATE2\n")); 3525659607e0Smrg switch (validCount(mPriv,inSync,lostSync)) { 3526659607e0Smrg case STATE_INVALID: 3527659607e0Smrg mPriv->autoState = AUTOPROBE_H_AUTODETECT; 3528659607e0Smrg break; 3529659607e0Smrg case STATE_VALID: 3530659607e0Smrg xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3531659607e0Smrg ProtocolIDToName(pMse->protocolID)); 3532659607e0Smrg mPriv->autoState = AUTOPROBE_H_GOOD; 3533659607e0Smrg return; 3534659607e0Smrg case STATE_UNCERTAIN: 3535659607e0Smrg return; 3536659607e0Smrg } 3537659607e0Smrg break; 3538659607e0Smrg case AUTOPROBE_H_AUTODETECT: 3539659607e0Smrg AP_DBG(("State H_AUTODETECT\n")); 3540659607e0Smrg pMse->protocolID = PROT_AUTO; 3541659607e0Smrg AP_DBG(("Looking for PnP/OS mouse\n")); 3542659607e0Smrg mPriv->count = 0; 3543659607e0Smrg SetupMouse(pInfo); 3544659607e0Smrg if (pMse->protocolID != PROT_AUTO) 3545659607e0Smrg mPriv->autoState = AUTOPROBE_H_GOOD; 3546659607e0Smrg else 3547659607e0Smrg mPriv->autoState = AUTOPROBE_H_NOPROTO; 3548659607e0Smrg break; 3549659607e0Smrg case AUTOPROBE_NOPROTO: 3550659607e0Smrg AP_DBG(("State NOPROTO\n")); 3551659607e0Smrg mPriv->count = 0; 3552659607e0Smrg mPriv->serialDefaultsNum = -1; 3553659607e0Smrg mPriv->autoState = AUTOPROBE_COLLECT; 3554659607e0Smrg break; 3555659607e0Smrg case AUTOPROBE_COLLECT: 3556659607e0Smrg AP_DBG(("State COLLECT\n")); 3557659607e0Smrg if (mPriv->count <= NUM_MSE_AUTOPROBE_BYTES) 3558659607e0Smrg return; 3559659607e0Smrg protocolList = softProtocolList; 3560659607e0Smrg mPriv->autoState = AUTOPROBE_CREATE_PROTOLIST; 3561659607e0Smrg break; 3562659607e0Smrg case AUTOPROBE_CREATE_PROTOLIST: 3563659607e0Smrg AP_DBG(("State CREATE_PROTOLIST\n")); 3564659607e0Smrg createProtoList(pMse, protocolList); 3565659607e0Smrg mPriv->protocolID = 0; 3566659607e0Smrg mPriv->autoState = AUTOPROBE_SWITCH_PROTOCOL; 3567659607e0Smrg break; 3568659607e0Smrg case AUTOPROBE_AUTODETECT: 3569659607e0Smrg AP_DBG(("State AUTODETECT\n")); 3570659607e0Smrg pMse->protocolID = PROT_AUTO; 3571659607e0Smrg AP_DBG(("Looking for PnP/OS mouse\n")); 3572659607e0Smrg mPriv->count = 0; 3573659607e0Smrg SetupMouse(pInfo); 3574659607e0Smrg if (pMse->protocolID != PROT_AUTO) 3575659607e0Smrg mPriv->autoState = AUTOPROBE_GOOD; 3576659607e0Smrg else 3577659607e0Smrg mPriv->autoState = AUTOPROBE_NOPROTO; 3578659607e0Smrg break; 3579659607e0Smrg case AUTOPROBE_VALIDATE1: 3580659607e0Smrg AP_DBG(("State VALIDATE1\n")); 3581659607e0Smrg switch (validCount(mPriv,inSync,lostSync)) { 3582659607e0Smrg case STATE_INVALID: 3583659607e0Smrg mPriv->autoState = AUTOPROBE_AUTODETECT; 3584659607e0Smrg break; 3585659607e0Smrg case STATE_VALID: 3586659607e0Smrg xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3587659607e0Smrg ProtocolIDToName(pMse->protocolID)); 3588659607e0Smrg mPriv->autoState = AUTOPROBE_GOOD; 3589659607e0Smrg break; 3590659607e0Smrg case STATE_UNCERTAIN: 3591659607e0Smrg return; 3592659607e0Smrg } 3593659607e0Smrg break; 3594659607e0Smrg case AUTOPROBE_VALIDATE2: 3595659607e0Smrg AP_DBG(("State VALIDATE2\n")); 3596659607e0Smrg switch (validCount(mPriv,inSync,lostSync)) { 3597659607e0Smrg case STATE_INVALID: 3598659607e0Smrg protocolList = &mPriv->protoList[mPriv->protocolID]; 3599659607e0Smrg mPriv->autoState = AUTOPROBE_CREATE_PROTOLIST; 3600659607e0Smrg break; 3601659607e0Smrg case STATE_VALID: 3602659607e0Smrg xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3603659607e0Smrg ProtocolIDToName(pMse->protocolID)); 3604659607e0Smrg mPriv->autoState = AUTOPROBE_GOOD; 3605659607e0Smrg break; 3606659607e0Smrg case STATE_UNCERTAIN: 3607659607e0Smrg return; 3608659607e0Smrg } 3609659607e0Smrg break; 3610659607e0Smrg case AUTOPROBE_SWITCHSERIAL: 3611659607e0Smrg { 3612659607e0Smrg pointer serialDefaults; 3613659607e0Smrg AP_DBG(("State SWITCHSERIAL\n")); 3614659607e0Smrg 3615659607e0Smrg if (!serialDefaultsList) 3616659607e0Smrg createSerialDefaultsList(); 3617659607e0Smrg 3618659607e0Smrg AP_DBG(("Switching serial params\n")); 3619659607e0Smrg if ((serialDefaults = 3620659607e0Smrg serialDefaultsList[++mPriv->serialDefaultsNum]) == NULL) { 3621659607e0Smrg mPriv->serialDefaultsNum = 0; 3622659607e0Smrg } else { 3623659607e0Smrg pointer tmp = xf86OptionListCreate(serialDefaults, -1, 0); 3624659607e0Smrg xf86SetSerial(pInfo->fd, tmp); 3625659607e0Smrg xf86OptionListFree(tmp); 3626659607e0Smrg mPriv->count = 0; 3627659607e0Smrg mPriv->autoState = AUTOPROBE_COLLECT; 3628659607e0Smrg } 3629659607e0Smrg break; 3630659607e0Smrg } 3631659607e0Smrg case AUTOPROBE_SWITCH_PROTOCOL: 3632659607e0Smrg { 3633659607e0Smrg MouseProtocolID proto; 3634659607e0Smrg void *defaults; 3635659607e0Smrg AP_DBG(("State SWITCH_PROTOCOL\n")); 3636659607e0Smrg proto = mPriv->protoList[mPriv->protocolID++]; 3637659607e0Smrg if (proto == PROT_UNKNOWN) 3638659607e0Smrg mPriv->autoState = AUTOPROBE_SWITCHSERIAL; 3639659607e0Smrg else if (!(defaults = GetProtocol(proto)->defaults) 3640659607e0Smrg || (mPriv->serialDefaultsNum == -1 3641659607e0Smrg && (defaults == msDefaults)) 3642659607e0Smrg || (mPriv->serialDefaultsNum != -1 3643659607e0Smrg && serialDefaultsList[mPriv->serialDefaultsNum] 3644659607e0Smrg == defaults)) { 3645659607e0Smrg AP_DBG(("Changing Protocol to %s\n", 3646659607e0Smrg ProtocolIDToName(proto))); 3647659607e0Smrg SetMouseProto(pMse,proto); 3648659607e0Smrg FlushButtons(pMse); 3649659607e0Smrg RESET_VALIDATION; 3650659607e0Smrg mPriv->autoState = AUTOPROBE_VALIDATE2; 3651659607e0Smrg return; 3652659607e0Smrg } 3653659607e0Smrg break; 3654659607e0Smrg } 3655659607e0Smrg } 3656659607e0Smrg } 3657659607e0Smrg} 3658659607e0Smrg 3659659607e0Smrgstatic Bool 3660659607e0SmrgautoGood(MouseDevPtr pMse) 3661659607e0Smrg{ 3662659607e0Smrg mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3663659607e0Smrg 3664659607e0Smrg if (!pMse->autoProbe) 3665659607e0Smrg return TRUE; 3666659607e0Smrg 3667659607e0Smrg switch (mPriv->autoState) { 3668659607e0Smrg case AUTOPROBE_GOOD: 3669659607e0Smrg case AUTOPROBE_H_GOOD: 3670659607e0Smrg return TRUE; 3671659607e0Smrg case AUTOPROBE_VALIDATE1: /* @@@ */ 3672659607e0Smrg case AUTOPROBE_H_VALIDATE1: /* @@@ */ 3673659607e0Smrg case AUTOPROBE_VALIDATE2: 3674659607e0Smrg case AUTOPROBE_H_VALIDATE2: 3675659607e0Smrg if (mPriv->goodCount < PROBE_UNCERTAINTY/2) 3676659607e0Smrg return TRUE; 3677659607e0Smrg default: 3678659607e0Smrg return FALSE; 3679659607e0Smrg } 3680659607e0Smrg} 3681659607e0Smrg 3682659607e0Smrg 3683659607e0Smrg#define TOT_THRESHOLD 3000 3684659607e0Smrg#define VAL_THRESHOLD 40 3685659607e0Smrg 3686659607e0Smrg/* 3687659607e0Smrg * checkForErraticMovements() -- check if mouse 'jumps around'. 3688659607e0Smrg */ 3689659607e0Smrgstatic void 3690659607e0SmrgcheckForErraticMovements(InputInfoPtr pInfo, int dx, int dy) 3691659607e0Smrg{ 3692659607e0Smrg MouseDevPtr pMse = pInfo->private; 3693659607e0Smrg mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3694eeaac534Smrg 3695659607e0Smrg if (!mPriv->goodCount) 3696659607e0Smrg return; 3697eeaac534Smrg 3698659607e0Smrg#if 0 3699659607e0Smrg if (abs(dx - mPriv->prevDx) > 300 3700659607e0Smrg || abs(dy - mPriv->prevDy) > 300) 3701659607e0Smrg AP_DBG(("erratic1 behaviour\n")); 3702659607e0Smrg#endif 3703659607e0Smrg if (abs(dx) > VAL_THRESHOLD) { 3704659607e0Smrg if (sign(dx) == sign(mPriv->prevDx)) { 3705659607e0Smrg mPriv->accDx += dx; 3706659607e0Smrg if (abs(mPriv->accDx) > mPriv->acc) { 3707659607e0Smrg mPriv->acc = abs(mPriv->accDx); 3708659607e0Smrg AP_DBG(("acc=%i\n",mPriv->acc)); 3709659607e0Smrg } 3710659607e0Smrg else 3711659607e0Smrg AP_DBG(("accDx=%i\n",mPriv->accDx)); 3712659607e0Smrg } else { 3713659607e0Smrg mPriv->accDx = 0; 3714659607e0Smrg } 3715659607e0Smrg } 3716659607e0Smrg 3717659607e0Smrg if (abs(dy) > VAL_THRESHOLD) { 3718659607e0Smrg if (sign(dy) == sign(mPriv->prevDy)) { 3719659607e0Smrg mPriv->accDy += dy; 3720659607e0Smrg if (abs(mPriv->accDy) > mPriv->acc) { 3721659607e0Smrg mPriv->acc = abs(mPriv->accDy); 3722659607e0Smrg AP_DBG(("acc: %i\n",mPriv->acc)); 3723659607e0Smrg } else 3724659607e0Smrg AP_DBG(("accDy=%i\n",mPriv->accDy)); 3725659607e0Smrg } else { 3726659607e0Smrg mPriv->accDy = 0; 3727659607e0Smrg } 3728659607e0Smrg } 3729659607e0Smrg mPriv->prevDx = dx; 3730659607e0Smrg mPriv->prevDy = dy; 3731659607e0Smrg if (mPriv->acc > TOT_THRESHOLD) { 3732659607e0Smrg mPriv->goodCount = PROBE_UNCERTAINTY; 3733659607e0Smrg mPriv->prevDx = 0; 3734659607e0Smrg mPriv->prevDy = 0; 3735659607e0Smrg mPriv->accDx = 0; 3736659607e0Smrg mPriv->accDy = 0; 3737659607e0Smrg mPriv->acc = 0; 3738659607e0Smrg AP_DBG(("erratic2 behaviour\n")); 3739659607e0Smrg autoProbeMouse(pInfo, FALSE,TRUE); 3740659607e0Smrg } 3741659607e0Smrg} 3742659607e0Smrg 3743659607e0Smrgstatic void 3744659607e0SmrgSetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID) 3745659607e0Smrg{ 3746659607e0Smrg pMse->protocolID = protocolID; 3747659607e0Smrg pMse->protocol = ProtocolIDToName(pMse->protocolID); 3748659607e0Smrg pMse->class = ProtocolIDToClass(pMse->protocolID); 3749659607e0Smrg if ((pMse->protocolID >= 0) && (pMse->protocolID < PROT_NUMPROTOS)) 3750659607e0Smrg memcpy(pMse->protoPara, proto[pMse->protocolID], 3751659607e0Smrg sizeof(pMse->protoPara)); 3752659607e0Smrg 3753659607e0Smrg if (pMse->emulate3ButtonsSoft) 3754659607e0Smrg pMse->emulate3Buttons = TRUE; 3755659607e0Smrg} 3756659607e0Smrg 3757659607e0Smrg/* 3758659607e0Smrg * collectData() -- collect data bytes sent by mouse. 3759659607e0Smrg */ 3760659607e0Smrgstatic Bool 3761659607e0SmrgcollectData(MouseDevPtr pMse, unsigned char u) 3762659607e0Smrg{ 3763659607e0Smrg mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3764659607e0Smrg if (mPriv->count < NUM_MSE_AUTOPROBE_TOTAL) { 3765659607e0Smrg mPriv->data[mPriv->count++] = u; 3766659607e0Smrg if (mPriv->count <= NUM_MSE_AUTOPROBE_BYTES) { 3767659607e0Smrg return TRUE; 3768659607e0Smrg } 3769659607e0Smrg } 3770659607e0Smrg return FALSE; 3771659607e0Smrg} 3772659607e0Smrg 3773659607e0Smrg/**************** end of autoprobe stuff *****************/ 3774659607e0Smrg 3775659607e0Smrg 3776afecbbc8Smrg 3777659607e0SmrgModuleInfoRec MouseInfo = { 3778659607e0Smrg 1, 3779659607e0Smrg "MOUSE", 3780659607e0Smrg NULL, 3781659607e0Smrg 0, 3782659607e0Smrg MouseAvailableOptions, 3783659607e0Smrg}; 3784659607e0Smrg 3785659607e0Smrgstatic void 3786659607e0Smrgxf86MouseUnplug(pointer p) 3787659607e0Smrg{ 3788659607e0Smrg} 3789659607e0Smrgstatic pointer 3790659607e0Smrgxf86MousePlug(pointer module, 3791659607e0Smrg pointer options, 3792659607e0Smrg int *errmaj, 3793659607e0Smrg int *errmin) 3794659607e0Smrg{ 3795659607e0Smrg static Bool Initialised = FALSE; 3796659607e0Smrg 3797eeaac534Smrg if (!Initialised) 3798659607e0Smrg Initialised = TRUE; 3799659607e0Smrg 3800659607e0Smrg xf86AddInputDriver(&MOUSE, module, 0); 3801659607e0Smrg 3802659607e0Smrg return module; 3803659607e0Smrg} 3804659607e0Smrg 3805659607e0Smrgstatic XF86ModuleVersionInfo xf86MouseVersionRec = 3806659607e0Smrg{ 3807659607e0Smrg "mouse", 3808659607e0Smrg MODULEVENDORSTRING, 3809659607e0Smrg MODINFOSTRING1, 3810659607e0Smrg MODINFOSTRING2, 3811659607e0Smrg XORG_VERSION_CURRENT, 3812659607e0Smrg PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 3813659607e0Smrg ABI_CLASS_XINPUT, 3814659607e0Smrg ABI_XINPUT_VERSION, 3815659607e0Smrg MOD_CLASS_XINPUT, 3816659607e0Smrg {0, 0, 0, 0} /* signature, to be patched into the file by */ 3817659607e0Smrg /* a tool */ 3818659607e0Smrg}; 3819659607e0Smrg 3820659607e0Smrg_X_EXPORT XF86ModuleData mouseModuleData = { 3821659607e0Smrg &xf86MouseVersionRec, 3822659607e0Smrg xf86MousePlug, 3823659607e0Smrg xf86MouseUnplug 3824659607e0Smrg}; 3825659607e0Smrg 3826659607e0Smrg/* 3827659607e0Smrg Look at hitachi device stuff. 3828659607e0Smrg*/ 3829