mouse.c revision 2084a447d1acb619df7c393fac41b79d517e4b3d
3853N/A * Copyright (C) 2006-2007 Sun Microsystems, Inc. 3853N/A * This file is part of VirtualBox Open Source Edition (OSE), as 6983N/A * you can redistribute it and/or modify it under the terms of the GNU 3853N/A * General Public License (GPL) as published by the Free Software 3853N/A * Foundation, in version 2 as it comes in the "COPYING" file of the 3853N/A * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 3853N/A * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 6983N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa 6983N/A * additional information or have any questions. 3853N/A * -------------------------------------------------------------------- 3853N/A * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 4136N/A * Copyright 1993 by David Dawes <dawes@xfree86.org> 3853N/A * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich 3853N/A * Copyright 1994-2002 by The XFree86 Project, Inc. 3853N/A * Copyright 2002 by Paul Elliott 3853N/A * Permission to use, copy, modify, distribute, and sell this software and its 3853N/A * documentation for any purpose is hereby granted without fee, provided that 3853N/A * the above copyright notice appear in all copies and that both that 3853N/A * copyright notice and this permission notice appear in supporting 3853N/A * documentation, and that the names of copyright holders not be 3853N/A * used in advertising or publicity pertaining to distribution of the 3853N/A * software without specific, written prior permission. The copyright holders 3853N/A * make no representations about the suitability of this 3853N/A * software for any purpose. It is provided "as is" without express or 3853N/A * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 3853N/A * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 3853N/A * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 3853N/A * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 3853N/A * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 3853N/A * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 3853N/A * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3853N/A/* Patch for PS/2 Intellimouse - Tim Goodwin 1997-11-06. */ 3853N/A * [JCH-96/01/21] Added fourth button support for PROT_GLIDEPOINT mouse 3853N/A * [TVO-97/03/05] Added microsoft IntelliMouse support 3853N/A * [PME-02/08/11] Added suport for drag lock buttons 3853N/A * for use with 4 button trackballs for convenience 3853N/A * and to help limited dexterity persons 3853N/A /* number of bits in mapped nibble */ 3853N/A /* size of map of nibbles to bitmask */ 3853N/A /* number of maps to map all the buttons */ 3853N/A/*data to be used in implementing trackball drag locks.*/ 3853N/A /* Fields used to implement trackball drag locks. */ 3853N/A /* mask for those buttons that are ordinary drag lock buttons */ 3919N/A /* mask for the master drag lock button if any */ 3919N/A /* button state up/down from last time adjusted for drag locks */ 3919N/A * true if master lock state i.e. master drag lock 3919N/A * button has just been pressed 3853N/A /* simulate these buttons being down although they are not */ 3853N/A * data to map bits for drag lock buttons to corresponding 3853N/A * bits for the target buttons 3853N/A * Microsoft (all serial models), Logitech MouseMan, First Mouse, etc, 3853N/A * ALPS GlidePoint, Thinking Mouse. 3853N/A/* Logitech series 9 *//* same as msc: now mlDefaults */ 3853N/A /* Misc (usually OS-specific) */ 3919N/A/* Process options common to all mouse types. */ 3853N/A /* initial string to be taken apart */ 3853N/A /* keep getting numbers which are buttons */ 3853N/A /* check sanity for a button */ 4935N/A /* turn into a button mask */ 4935N/A /* try to get drag lock button */ 3853N/A /*if no target, must be a master drag lock button */ 3853N/A /* save master drag lock mask */ 3853N/A "DragLock button %d is master drag lock",
3853N/A /* have target button number*/ 3853N/A /* check target button number for sanity */ 3853N/A "DragLock: Invalid button number for target=%d\n",
3853N/A "DragLock: button %d is drag lock for button %d\n",
3853N/A /* initialize table that maps drag lock mask to target mask */ 3853N/A /* add new drag lock to mask of drag locks */ 3853N/A * fill out rest of map that maps sets of drag lock buttons 3853N/A * to sets of target buttons, in the form of masks 3853N/A /* for each possible set of bits for that nibble */ 3853N/A /* get first bit set in j*/ 3853N/A /* if 0 bits set nothing to do */ 3853N/A /* form mask for fist bit set */ 3853N/A /* mask off first bit set to get remaining bits set*/ 3853N/A * if otherbits =0 then only 1 bit set 3919N/A * nib_table[i][fM] already calculated if fM has 3853N/A * nib_table[i][j] has already been filled in 3853N/A * by previous loop. otherwise 3853N/A * otherbits < j so nibtable[i][otherbits] 3853N/A * has already been calculated. 3853N/A "EmulateWheelInertia",
10);
3853N/A "EmulateWheelTimeout",
200);
3853N/A "EmulateWheelInertia: %d, " 3853N/A "EmulateWheelTimeout: %d\n",
3853N/A /* keep getting numbers which are buttons */ 3853N/A /* check sanity for a button */ 3853N/A "ButtonMapping: Invalid button number = %d\n", b);
3853N/A /* get maximum of mapped buttons */ * map bits corresponding to lock buttons. * for each bit for a lock button, * turn on bit corresponding to button button that the lock * for each nibble group of bits, use * map for that group to get corresponding * if 4 or less buttons only first map will /* Mark unsupported interface classes. */ /* NetBSD uses PROT_BM for "PS/2". */ "VirtualBox guest additions mouse driver version " /* Initialise the InputInfoRec. */ /* Check if SendDragEvents has been disabled. */ /* Allocate the MouseDevRec and initialise it. */ * XXX This should be done by a function in the core server since the * MouseDevRec is defined in the os-support layer. /* Find the protocol type. */ /* Default Mapping: 1 2 3 8 9 10 11 ... */ /* Check for a builtin OS-specific protocol, * and call its PreInit. */ "%s: Protocol \"%s\" is not supported on this " /* Collect the options, and process the common options. */ /* XXX should handle this OS dependency elsewhere. */ /* OS/2 has a mouse handled by the OS - it cannot fail here */ /* Check if the device can be opened. */ * Set blocking to -1 on the first call because we know there is data to * read. Xisb automatically clears it after one successful read so that * succeeding reads are preceeded by a select with a 0 timeout to prevent * read from blocking indefinitely. ErrorF(
"mouse byte: %2.2x\n",u);
/* if we do autoprobing collect the data */ * Buffer contains a full packet, which has already been processed: * Empty the buffer and check for optional 4th byte, which will be * processed directly, without being put into the buffer first. * Hack for Logitech MouseMan Mouse - Middle button * Unfortunately this mouse has variable length packets: the * standard Microsoft 3 byte packet plus an optional 4th byte * whenever the middle button status changes. * We have already processed the standard packet with the * movement and button info. Now post an event message with * the old status of the left and right buttons and the * Even worse, different MouseMen and TrackMen differ in the * 4th byte: some will send 0x00/0x20, others 0x01/0x21, or * even 0x02/0x22, so I have to strip off the lower bits. * HACK for ALPS "fourth button". (It's bit 0x10 of the * "fourth byte" and it is activated by tapping the glidepad * with the finger! 8^) We map it to bit bit3, and the * reverse map in xf86Events just has to be extended so that * it is identified as Button 4. The lower half of the * reverse-map may remain unchanged. * Receive the fourth byte only when preceeding three bytes * have been detected (pBufP >= pMse->protoPara[4]). In the * previous versions, the test was pBufP == 0; we may have * mistakingly received a byte even if we didn't see anything ErrorF(
"mouse 4th byte %02x\n",u);
* IntelliMouse, NetMouse (including NetMouse Pro) and Mie * Mouse always send the fourth byte, whereas the fourth byte * is optional for GlidePoint and ThinkingMouse. The fourth * byte is also optional for MouseMan+ and FirstMouse+ in * their native mode. It is always sent if they are in the * IntelliMouse compatible mode. (u &
0x0f) -
16 : (u &
0x0f);
if ((
dz >=
7) || (
dz <= -
7))
buttons |= ((
int)(u &
0x20) >>
4) |
/* End of packet buffer flush and 4th byte hack. */ * Append next byte to buffer (which is empty or contains an * incomplete packet); iterate if packet (still) not complete. for ( i=0; i <
pBufP; i++)
* Hack for resyncing: We check here for a package that is: * a) illegal (detected by wrong data-package header) * b) invalid (0x80 == -128 and that might be wrong for MouseSystems) * NOTE: b) is a violation of the MouseSystems-Protocol, since values * of -128 are allowed, but since they are very seldom we can * easily use them as package-header with no button pressed. * NOTE/2: On a PS/2 mouse any byte is valid as a data byte. * Furthermore, 0x80 is not valid as a header byte. For a PS/2 * mouse we skip checking data bytes. For resyncing a PS/2 * mouse we require the two most significant bits in the header * byte to be 0. These are the overflow bits, and in case of * an overflow we actually lose sync. Overflows are very rare, * however, and we quickly gain sync again after an overflow * condition. This is the best we can do. (Actually, we could * use bit 0x08 in the header byte for resyncing, since that * bit is supposed to be always on, but nobody told Microsoft...) * The above hack is wrong! Because of b) above, we shall see * erroneous mouse events so often when the MouseSystem mouse is * moved quickly. As for the PS/2 and its variants, we don't need * to treat them as special cases, because protoPara[2] and * protoPara[3] are both 0x00 for them, thus, any data bytes will * never be discarded. 0x80 is rejected for MMSeries, Logitech * and MMHittab protocols, because protoPara[2] and protoPara[3] * are 0x80 and 0x00 respectively. The other protocols are 7-bit * protocols; there is no use checking 0x80. * All in all we should check the condition a) only. * Check packet for valid data: * If driver is in sync with datastream, the packet is considered * bad if any byte (header and/or data) contains an invalid value. * If packet is bad, we discard the first byte and shift the buffer. * Next iteration will then check the new situation for validity. * If flag MF_SAFE is set in proto[7] and the driver * is out of sync, the packet is also considered bad if * any of the data bytes contains a valid header byte value. * This situation could occur if the buffer contains * the tail of one packet and the header of the next. * Note: The driver starts in out-of-sync mode (pMse->inSync = 0). /* All databytes must be valid. */ for (j =
1; j <
pBufP; j++ )
/* If out of sync, don't mistake a header byte for data. */ for (j =
1; j <
pBufP; j++ )
/* Accept or reject the packet ? */ ErrorF(
"mouse driver lost sync\n");
/* Tell auto probe that we are out of sync */ for (j = 0; j <
pBufP; j++)
/* Tell auto probe that we were successful */ ErrorF(
"mouse driver back in sync\n");
* Packet complete and verified, now process it ... ((
int)(
pBuf[0] &
0x20) >>
3)
| ((
int)(
pBuf[0] &
0x10) >>
4);
| ((
int)(
pBuf[0] &
0x20) >>
3)
| ((
int)(
pBuf[0] &
0x10) >>
4);
dx = (
char)(((
pBuf[0] &
0x03) <<
6) | (
pBuf[
1] &
0x3F));
dy = (
char)(((
pBuf[0] &
0x0C) <<
4) | (
pBuf[
2] &
0x3F));
case PROT_IMSERIAL:
/* IntelliMouse, NetMouse, Mie Mouse, MouseMan+ */ | ((
int)(
pBuf[0] &
0x20) >>
3)
| ((
int)(
pBuf[0] &
0x10) >>
4);
dx = (
char)(((
pBuf[0] &
0x03) <<
6) | (
pBuf[
1] &
0x3F));
dy = (
char)(((
pBuf[0] &
0x0C) <<
4) | (
pBuf[
2] &
0x3F));
/* ACECAD is almost exactly like MM but the buttons are different */ (
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2;
/* Left */ /* PS/2 mouse variants */ (
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2 |
/* Left */ (
pBuf[0] &
0x40) >>
3 |
/* button 4 */ (
pBuf[0] &
0x80) >>
3;
/* button 5 */ * The next cast must be 'signed char' for platforms (like PPC) * where char defaults to unsigned. dz = (
signed char)(
pBuf[
3] | ((
pBuf[
3] &
0x08) ?
0xf8 : 0));
if ((
pBuf[
3] &
0xf8) && ((
pBuf[
3] &
0xf8) !=
0xf8)) {
"Mouse autoprobe: Changing protocol to %s\n",
(
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2 |
/* Left */ (
pBuf[
3] &
0x10) >>
1 |
/* button 4 */ (
pBuf[
3] &
0x20) >>
1;
/* button 5 */ (
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2;
/* Left */ if (((
pBuf[0] &
0x48) ==
0x48) &&
((((
pBuf[
2] &
0x03) <<
2) |
0x02) == (
pBuf[
1] &
0x0f))) {
/* extended data packet */ switch ((((
pBuf[0] &
0x30) >>
2) | ((
pBuf[
1] &
0x30) >>
4))) {
case 1:
/* wheel data packet */ buttons |= ((
pBuf[
2] &
0x10) ?
0x08 : 0) |
/* 4th button */ ((
pBuf[
2] &
0x20) ?
0x10 : 0);
/* 5th button */ case 2:
/* Logitech reserves this packet type */ * IBM ScrollPoint uses this packet to encode its dz = (
pBuf[
2] &
0x80) ? ((
pBuf[
2] >>
4) &
0x0f) -
16 :
case 0:
/* device type packet - shouldn't happen */ (
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2 |
/* Left */ ((
pBuf[0] &
0x08) ? 0 :
0x08);
/* fourth button */ (
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2 |
/* Left */ ((
pBuf[
3] &
0x02) ?
0x08 : 0) |
/* button 4 */ ((
pBuf[
3] &
0x01) ?
0x10 : 0);
/* button 5 */ (
pBuf[0] &
0x02) >>
1 |
/* Right */ (
pBuf[0] &
0x01) <<
2 |
/* Left */ ((
pBuf[0] &
0x08) ?
0x08 : 0);
/* fourth button */ pBuf[
1] |= (
pBuf[0] &
0x40) ?
0x80 :
0x00;
dx = (
signed char)(
pBuf[
1]) + (
signed char)(
pBuf[
3]);
dy = - ((
signed char)(
pBuf[
2]) + (
signed char)(
pBuf[
4]));
/* FreeBSD sysmouse sends additional data bytes */ * These casts must be 'signed char' for platforms (like PPC) * where char defaults to unsigned. dz = ((
signed char)(
pBuf[
5] <<
1) +
(
signed char)(
pBuf[
6] <<
1)) >>
1;
| ((
int)(
pBuf[0] &
0x10) >>
4)
| ((
int)(
pBuf[
3] &
0x10) >>
3);
dx = (
char)(((
pBuf[0] &
0x03) <<
6) | (
pBuf[
1] &
0x3F));
dy = (
char)(((
pBuf[0] &
0x0C) <<
4) | (
pBuf[
2] &
0x3F));
dz = (
pBuf[
3] &
0x08) ? ((
int)(
pBuf[
3] &
0x0F) -
0x10) :
default:
/* There's a table error */ ErrorF(
"mouse table error\n");
for ( j=0; j <
pBufP; j++)
/* When auto-probing check if data makes sense */ * We don't reset pBufP here yet, as there may be an additional data * byte in some protocols. See above. * Alter the control parameters for the mouse. Note that all special * protocol values are handled by dix. *************************************************************************** *************************************************************************** * [KAZU-241097] We don't know exactly how many buttons the * device has, so setup the map with the maximum number. xf86Msg(
X_CONFIG,
"VirtualBox Mouse Integration associated with screen %d\n",
*************************************************************************** * Convert valuators to X and Y. *************************************************************************** int v3,
int v4,
int v5,
int *x,
int *y)
/********************************************************************** * FlushButtons -- send button up events for sanity. **********************************************************************/ /* If no button down is pending xf86PostButtonEvent() * will discard them. So we are on the safe side. */ /********************************************************************** * Emulate3Button support code **********************************************************************/ * Lets create a simple finite-state machine for 3 button emulation: * We track buttons 1 and 3 (left and right). There are 11 states: * 0 ground - initial state * 1 delayed left - left pressed, waiting for right * 2 delayed right - right pressed, waiting for left * 3 pressed middle - right and left pressed, emulated middle sent * 4 pressed left - left pressed and sent * 5 pressed right - right pressed and sent * 6 released left - left released after emulated middle * 7 released right - right released after emulated middle * 8 repressed left - left pressed after released left * 9 repressed right - right pressed after released right * 10 pressed both - both pressed, not emulating middle * At each state, we need handlers for the following events * 4: emulate3Timeout passed without a button change * Note that button events are not deltas, they are the set of buttons being * pressed now. It's possible (ie, mouse hardware does it) to go from (eg) * left down to right down without anything in between, so all cases must be * a handler consists of three values: * action > 0: ButtonPress * action < 0: ButtonRelease * The comment preceeding each section is the current emulation state. * The comments to the right are of the form * <button state> (<events>) -> <new emulation state> * which should be read as * If the buttons are in <button state>, generate <events> then go to static signed char stateTab[
11][
5][
3] = {
{ 0, 0, 0 },
/* nothing -> ground (no change) */ { 0, 0,
1 },
/* left -> delayed left */ { 0, 0,
2 },
/* right -> delayed right */ {
2, 0,
3 },
/* left & right (middle press) -> pressed middle */ { 0, 0, -
1 }
/* timeout N/A */ {
1, -
1, 0 },
/* nothing (left event) -> ground */ { 0, 0,
1 },
/* left -> delayed left (no change) */ {
1, -
1,
2 },
/* right (left event) -> delayed right */ {
2, 0,
3 },
/* left & right (middle press) -> pressed middle */ {
1, 0,
4 },
/* timeout (left press) -> pressed left */ {
3, -
3, 0 },
/* nothing (right event) -> ground */ {
3, -
3,
1 },
/* left (right event) -> delayed left (no change) */ { 0, 0,
2 },
/* right -> delayed right (no change) */ {
2, 0,
3 },
/* left & right (middle press) -> pressed middle */ {
3, 0,
5 },
/* timeout (right press) -> pressed right */ { -
2, 0, 0 },
/* nothing (middle release) -> ground */ { 0, 0,
7 },
/* left -> released right */ { 0, 0,
6 },
/* right -> released left */ { 0, 0,
3 },
/* left & right -> pressed middle (no change) */ { 0, 0, -
1 },
/* timeout N/A */ { -
1, 0, 0 },
/* nothing (left release) -> ground */ { 0, 0,
4 },
/* left -> pressed left (no change) */ { -
1, 0,
2 },
/* right (left release) -> delayed right */ {
3, 0,
10 },
/* left & right (right press) -> pressed both */ { 0, 0, -
1 },
/* timeout N/A */ { -
3, 0, 0 },
/* nothing (right release) -> ground */ { -
3, 0,
1 },
/* left (right release) -> delayed left */ { 0, 0,
5 },
/* right -> pressed right (no change) */ {
1, 0,
10 },
/* left & right (left press) -> pressed both */ { 0, 0, -
1 },
/* timeout N/A */ { -
2, 0, 0 },
/* nothing (middle release) -> ground */ { -
2, 0,
1 },
/* left (middle release) -> delayed left */ { 0, 0,
6 },
/* right -> released left (no change) */ {
1, 0,
8 },
/* left & right (left press) -> repressed left */ { 0, 0, -
1 },
/* timeout N/A */ { -
2, 0, 0 },
/* nothing (middle release) -> ground */ { 0, 0,
7 },
/* left -> released right (no change) */ { -
2, 0,
2 },
/* right (middle release) -> delayed right */ {
3, 0,
9 },
/* left & right (right press) -> repressed right */ { 0, 0, -
1 },
/* timeout N/A */ { -
2, -
1, 0 },
/* nothing (middle release, left release) -> ground */ { -
2, 0,
4 },
/* left (middle release) -> pressed left */ { -
1, 0,
6 },
/* right (left release) -> released left */ { 0, 0,
8 },
/* left & right -> repressed left (no change) */ { 0, 0, -
1 },
/* timeout N/A */ { -
2, -
3, 0 },
/* nothing (middle release, right release) -> ground */ { -
3, 0,
7 },
/* left (right release) -> released right */ { -
2, 0,
5 },
/* right (middle release) -> pressed right */ { 0, 0,
9 },
/* left & right -> repressed right (no change) */ { 0, 0, -
1 },
/* timeout N/A */ { -
1, -
3, 0 },
/* nothing (left release, right release) -> ground */ { -
3, 0,
4 },
/* left (right release) -> pressed left */ { -
1, 0,
5 },
/* right (left release) -> pressed right */ { 0, 0,
10 },
/* left & right -> pressed both (no change) */ { 0, 0, -
1 },
/* timeout N/A */ * Table to allow quick reversal of natural button mapping to correct mapping * [JCH-96/01/21] The ALPS GlidePoint pad extends the MS protocol * with a fourth button activated by tapping the PAD. * The 2nd line corresponds to 4th button on; the drv sends * the buttons in the following map (MSBit described first) : * 0 | 4th | 1st | 2nd | 3rd * And we remap them (MSBit described first) : * 0 | 4th | 3rd | 2nd | 1st xf86Msg(
X_INFO,
"3rd Button detected: disabling emulate3Button\n");
/******************************************************************* *******************************************************************/ /* Do single button double click */ /* double-click button has just been pressed. Ignore it if target button /* Target button isn't down, so send a double-click */ /* Whatever happened, mask the double-click button so it doesn't get * processed as a normal button as well. /* Emulate wheel button handling */ /* Start timeout handling */ * If the button is released early enough emit the button /* Intercept wheel emulation. */ * Synthesize the press and release, but not when * the button to be synthesized is already pressed * Synthesize the press and release, but not when * the button to be synthesized is already pressed /* Absorb the mouse movement while the wheel button is pressed. */ * Button events for the wheel button are only emitted through /* convert to screen resolution */ /* send absolute movement */ /* send relative event */ /* send relative event */ * adjust buttons state for drag locks! /* get drag lock block */ /* state of drag lock buttons not seen always up */ * if lock buttons being depressed changes state of /* targets of drag locks down */ * when simulatedDown set and target pressed, * simulatedDown goes false * if master drag lock released * then master drag lock state on /* if master state, buttons going down are simulatedDown */ /* if any button pressed, no longer in master drag lock state */ /* if simulatedDown or drag lock down, simulate down */ /* master button not seen */ /* buttons changed since last time */ /* save this time for next last time. */ /* handle all but buttons 1 & 3 normally */ /* emulate the third button by the other two */ /* Remap mouse buttons */ /* Map the Z axis movement. */ /* XXX Could this go in the conversion_proc? */ else if (
dw > 0 ||
dz >
1)
* If dz has been mapped to a button `down' event, we need to cook up * a corresponding button `up' event. /****************************************************************** ******************************************************************/ * This array is indexed by the MouseProtocolID values, so the order of the * entries must match that of the MouseProtocolID enum in xf86OSmouse.h. /* --header-- ---data--- packet -4th-byte- mouse */ /* mask id mask id bytes mask id flags */ {
0x40,
0x40,
0x40,
0x00,
3, ~
0x23,
0x00,
MPF_NONE },
/* MicroSoft */ {
0xf8,
0x80,
0x00,
0x00,
5,
0x00,
0xff,
MPF_SAFE },
/* MouseSystems */ {
0xe0,
0x80,
0x80,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* MMSeries */ {
0xe0,
0x80,
0x80,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* Logitech */ {
0x40,
0x40,
0x40,
0x00,
3, ~
0x23,
0x00,
MPF_NONE },
/* MouseMan */ {
0xe0,
0x80,
0x80,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* MM_HitTablet */ {
0x40,
0x40,
0x40,
0x00,
3, ~
0x33,
0x00,
MPF_NONE },
/* GlidePoint */ {
0x40,
0x40,
0x40,
0x00,
3, ~
0x3f,
0x00,
MPF_NONE },
/* IntelliMouse */ {
0x40,
0x40,
0x40,
0x00,
3, ~
0x33,
0x00,
MPF_NONE },
/* ThinkingMouse */ {
0x80,
0x80,
0x80,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* ACECAD */ {
0x40,
0x40,
0x40,
0x00,
4,
0x00,
0xff,
MPF_NONE },
/* ValuMouseScroll */ {
0xc0,
0x00,
0x00,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* PS/2 mouse */ {
0xc8,
0x08,
0x00,
0x00,
3,
0x00,
0x00,
MPF_NONE },
/* genericPS/2 mouse*/ {
0x08,
0x08,
0x00,
0x00,
4,
0x00,
0xff,
MPF_NONE },
/* IntelliMouse */ {
0x08,
0x08,
0x00,
0x00,
4,
0x00,
0xff,
MPF_NONE },
/* Explorer */ {
0x80,
0x80,
0x00,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* ThinkingMouse */ {
0x08,
0x08,
0x00,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* MouseMan+ */ {
0xc0,
0x00,
0x00,
0x00,
3,
0x00,
0xff,
MPF_NONE },
/* GlidePoint */ {
0x08,
0x08,
0x00,
0x00,
4,
0x00,
0xff,
MPF_NONE },
/* NetMouse */ {
0xc0,
0x00,
0x00,
0x00,
6,
0x00,
0xff,
MPF_NONE },
/* NetScroll */ {
0xf8,
0x80,
0x00,
0x00,
5,
0x00,
0xff,
MPF_NONE },
/* BusMouse */ {
0xf8,
0x80,
0x00,
0x00,
5,
0x00,
0xff,
MPF_NONE },
/* Auto (dummy) */ {
0xf8,
0x80,
0x00,
0x00,
8,
0x00,
0xff,
MPF_NONE },
/* SysMouse */ * Sets up the mouse parameters int protoPara[
8] = {-
1, -
1, -
1, -
1, -
1, -
1, -
1, -
1};
/* Handle the "Auto" protocol. */ * We come here when user specifies protocol "auto" in * the configuration file or thru the xf86misc extensions. * So we initialize autoprobing here. * Probe for PnP/OS mouse first. If unsuccessful * try to guess protocol from incoming data. /* Possible protoPara overrides from SetupAuto. */ /* if we come here PnP/OS mouse probing was successful */ /* PnP/OS mouse probing wasn't successful; we look at data */ * If protocol has changed fetch the default options * If baudrate is set write it back to the option * list so that the serial interface code can access * the new value. Not set means default. /* Set the port parameters. */ /******************************************************************** ********************************************************************/ ** The following lines take care of the Logitech MouseMan protocols. ** The "Logitech" protocol is for the old "series 9" Logitech products. ** All products since then use the "MouseMan" protocol. Some models ** were programmable, but most (all?) of the current models are not. ** NOTE: There are different versions of both MouseMan and TrackMan! ** Hence I add another protocol PROT_LOGIMAN, which the user can ** specify as MouseMan in his XF86Config file. This entry was ** formerly handled as a special case of PROT_MS. However, people ** who don't have the middle button problem, can still specify ** Microsoft and use PROT_MS. ** By default, these mice should use a 3 byte Microsoft protocol ** plus a 4th byte for the middle button. However, the mouse might ** have switched to a different protocol before we use it, so I send ** the proper sequence just in case. ** NOTE: - all commands to (at least the European) MouseMan have to ** - each command starts with a '*'. ** - whenever the MouseMan receives a '*', it will switch back ** to 1200 Baud. Hence I have to select the desired protocol ** first, then select the baud rate. ** The protocols supported by the (European) MouseMan are: ** - 5 byte packed binary protocol, as with the Mouse Systems ** mouse. Selected by sequence "*U". ** - 2 button 3 byte MicroSoft compatible protocol. Selected ** - 3 button 3+1 byte MicroSoft compatible protocol (default). ** Selected by sequence "*X". ** The following baud rates are supported: ** - 1200 Baud (default). Selected by sequence "*n". ** - 9600 Baud. Selected by sequence "*q". ** Selecting a sample rate is no longer supported with the MouseMan! * Do a reset wrap mode before reset. * The baud rate selection command must be sent at the current * baud rate; try all likely settings. /* Select MM series data format. */ /* Set the parameters up for the MM series protocol. */ * Initialize Hitachi PUMA Plus - Model 1212E to desired settings. * The tablet must be configured to be in MM mode, NO parity, * Binary Format. pMse->sampleRate controls the sensitivity * of the tablet. We only use this tablet for it's 4-button puck * so we don't run in "Absolute Mode". * These sample rates translate to 'lines per inch' on the Hitachi /* This mouse may send a PnP ID string, ignore it. */ /* Send the command to initialize the beast. */ for (s =
"E5E5"; *s; ++s) {
/* A nul character resets. */ /* Stream out relative mode high resolution increments of 1. */ static unsigned char seq[] = {
243,
200,
243,
100,
243,
80 };
static unsigned char seq[] = {
243,
200,
243,
100,
243,
80,
243,
200,
243,
200,
243,
80 };
case PROT_NETPS2:
/* NetMouse, NetMouse Pro, Mie Mouse */ static unsigned char seq[] = {
232,
3,
230,
230,
230,
233 };
static unsigned char seq[] = {
230,
232, 0,
232,
3,
232,
2,
232,
1,
230,
232,
3,
232,
1,
232,
2,
232,
3 };
static unsigned char seq[] = {
243,
10,
232, 0,
243,
20,
243,
60,
243,
40,
243,
20,
243,
20,
243,
60,
243,
40,
243,
20,
243,
20 };
* If one part of the PS/2 mouse initialization fails * redo complete initialization. There are mice which * have occasional problems with initialization and * are in an unknown state. c =
0xE6;
/*230*/ /* 1:1 scaling */ c2[0] =
0xF3;
/*243*/ /* set sampling rate */ c2[0] =
0xE8;
/*232*/ /* set device resolution */ c2[
1] =
3;
/* used to be 2, W. uses 3 */ * The PS/2 reset handling needs to be rechecked. * We need to wait until after the 4.3 release. * We believe that the following is true: * When the mouse is replugged it will send a reset package * It takes several seconds to replug a mouse: We don't see * events for several seconds before we see the replug event package. * There is no significant delay between consecutive bytes * of a replug event package. * There are no bytes sent after the replug event package until /* here we put the mouse specific reset detction */ /* They need to do three things: */ /* Check if byte may be a reset byte */ /* If so: Set expectReset TRUE */ /* If convinced: Set inReset TRUE */ /* Register BlockAndWakeupHandler */ unsigned char seq[] = {
0xaa,
0x00 };
ErrorF(
"Found PS/2 Reset string\n");
"Got reinsert event: reinitializing PS/2 mouse\n");
#
endif /* SUPPORT_MOUSE_RESET *//************************************************************ ************************************************************/ #
define AP_DBG(x)
do {}
while (0)
#
define AP_DBGC(x)
do {}
while (0)
/* Check if the OS has a detection mechanism. */ /* Check for a builtin OS-specific protocol. */ /* We can only come here if the protocol has been * changed to auto thru the xf86misc extension * and we have detected an OS specific builtin * protocol. Currently we cannot handle this */ /* A PnP serial mouse? */ * createProtocolList() -- create a list of protocols which may * match on the incoming data stream. /* create a private copy first so we can write in the old list */ * Bail ot if number of bytes per package have * been tested for header. * Take bytes per package of leading garbage into /* check if remaining data matches protocol */ /* check and eat excess byte */ AP_DBG((
"excess byte found\n"));
/* validate next header */ AP_DBG((
"Complete set found\n"));
AP_DBG((
"Autoprobe: header bad\n"));
/* this is a matching protocol */ AP_DBG((
"Autoprobe: Adding protocol %s to list (entry %i)\n",
/* we have tested number of bytes per package for header */ /* we have not found anything that looks like a header */ AP_DBG((
"Looking for new header\n"));
/* This only needs to be done once */ * createSerialDefaultsLists() - create a list of the different default * settings for the serial interface of the known protocols. /* Probing threshold values */ /* we are sure to have found the correct protocol */ AP_DBG((
"%i successful rounds to go\n",
/* We are out of sync again */ /* We increase uncertainty of having the correct protocol */ /* We are not convinced yet to have the wrong protocol */ AP_DBG((
"Changing protocol after: %i rounds\n",
AP_DBG((
"State H_NOPROTO\n"));
AP_DBG((
"State H_SETPROTO\n"));
AP_DBG((
"Autoprobe: Trying Protocol: %s\n",
AP_DBG((
"State H_VALIDATE1\n"));
AP_DBG((
"State H_VALIDATE2\n"));
AP_DBG((
"State H_AUTODETECT\n"));
AP_DBG((
"State CREATE_PROTOLIST\n"));
AP_DBG((
"State AUTODETECT\n"));
AP_DBG((
"State VALIDATE1\n"));
AP_DBG((
"State VALIDATE2\n"));
AP_DBG((
"State SWITCHSERIAL\n"));
AP_DBG((
"Switching serial params\n"));
AP_DBG((
"State SWITCH_PROTOCOL\n"));
AP_DBG((
"Changing Protocol to %s\n",
* checkForErraticMovements() -- check if mouse 'jumps around'. AP_DBG((
"erratic1 behaviour\n"));
AP_DBG((
"erratic2 behaviour\n"));
* collectData() -- collect data bytes sent by mouse. /**************** end of autoprobe stuff *****************/ "Sun Microsystems, Inc.",
{0, 0, 0, 0}
/* signature, to be patched into the file by */ Look at hitachi device stuff. #
endif /* XFree86LOADER */