diff options
author | Peter Osterlund <petero2@telia.com> | 2003-07-29 02:30:19 +0200 |
---|---|---|
committer | Peter Osterlund <petero2@telia.com> | 2006-04-09 04:01:05 +0200 |
commit | eef92f7889619ab2730f7f930528398d7708ff0c (patch) | |
tree | 72920692165948b9ca2ef4eee20448e95c548f69 /synaptics.c | |
parent | fb54b61a1a4beede088e57b92c9277c23cfde350 (diff) |
Added support for the old synaptics protocol. By Hartwig
Felger.
Diffstat (limited to 'synaptics.c')
-rw-r--r-- | synaptics.c | 140 |
1 files changed, 98 insertions, 42 deletions
diff --git a/synaptics.c b/synaptics.c index 3afbe80..161b932 100644 --- a/synaptics.c +++ b/synaptics.c @@ -1415,48 +1415,77 @@ SynapticsParseRawPacket(LocalDevicePtr local, SynapticsPrivatePtr priv, return ret; buf = priv->protoBuf; + if (((buf[0] & 0xC0) == 0xC0) && ((buf[1] & 0x60) == 0) && + ((buf[3] & 0xC0) == 0x80) && ((buf[4] & 0x60) == 0)) /* old proto...*/ + { + DBG(7, ErrorF("using old protocol\n")); + hw->x = (((buf[1] & 0x1F) << 8) | + buf[2]); + hw->y = (((buf[4] & 0x1F) << 8) | + buf[5]); + + hw->z = (((buf[0] & 0x30) << 2) | + (buf[3] & 0x3F)); + hw->w = (((buf[1] & 0x80) >> 4) | + ((buf[0] & 0x04) >> 1)); + + hw->left = (buf[0] & 0x01) ? 1 : 0; + hw->right = (buf[0] & 0x02) ? 1 : 0; + hw->up = 0; + hw->down = 0; + hw->cbLeft = hw->cbRight = hw->up = hw->down = FALSE; + } + else if (((buf[0] & 0xC8) == 0x80) && ((buf[3] & 0xC8) == 0xC0)) /* newer protos...*/ + { + DBG(7, ErrorF("using new protocols\n")); + hw->x = (((buf[3] & 0x10) << 8) | + ((buf[1] & 0x0f) << 8) | + buf[4]); + hw->y = (((buf[3] & 0x20) << 7) | + ((buf[1] & 0xf0) << 4) | + buf[5]); + + hw->z = buf[2]; + hw->w = (((buf[0] & 0x30) >> 2) | + ((buf[0] & 0x04) >> 1) | + ((buf[3] & 0x04) >> 2)); + + hw->left = (buf[0] & 0x01) ? 1 : 0; + hw->right = (buf[0] & 0x02) ? 1 : 0; + hw->up = 0; + hw->down = 0; - hw->x = (((buf[3] & 0x10) << 8) | - ((buf[1] & 0x0f) << 8) | - buf[4]); - hw->y = (((buf[3] & 0x20) << 7) | - ((buf[1] & 0xf0) << 4) | - buf[5]); - - hw->z = buf[2]; - hw->w = (((buf[0] & 0x30) >> 2) | - ((buf[0] & 0x04) >> 1) | - ((buf[3] & 0x04) >> 2)); - - hw->left = (buf[0] & 0x01) ? 1 : 0; - hw->right = (buf[0] & 0x02) ? 1 : 0; - hw->up = 0; - hw->down = 0; - - if (SYN_CAP_EXTENDED(priv->capabilities)) { - if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { - hw->up = ((buf[3] & 0x01)) ? 1 : 0; - if (hw->left) - hw->up = !hw->up; - hw->down = ((buf[3] & 0x02)) ? 1 : 0; - if (hw->right) - hw->down = !hw->down; - } - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) { - /* aka. type with 6 buttons */ - if (buf[3] == 0xC2) { - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 2) { - hw->cbLeft = (buf[4] & 0x02) ? TRUE : FALSE; - hw->cbRight = (buf[5] & 0x02) ? TRUE : FALSE; + if (SYN_CAP_EXTENDED(priv->capabilities)) { + if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { + hw->up = ((buf[3] & 0x01)) ? 1 : 0; + if (hw->left) + hw->up = !hw->up; + hw->down = ((buf[3] & 0x02)) ? 1 : 0; + if (hw->right) + hw->down = !hw->down; + } + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) { + /* aka. type with 6 buttons */ + if ((buf[3]&2) ? !hw->right : hw->right) { + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 2) { + hw->cbLeft = (buf[4] & 0x02) ? TRUE : FALSE; + hw->cbRight = (buf[5] & 0x02) ? TRUE : FALSE; + } + hw->up = (buf[4] & 0x01) ? TRUE : FALSE; + hw->down = (buf[5] & 0x01) ? TRUE : FALSE; + } else { + hw->cbLeft = hw->cbRight = hw->up = hw->down = FALSE; } - hw->up = (buf[4] & 0x01) ? TRUE : FALSE; - hw->down = (buf[5] & 0x01) ? TRUE : FALSE; - } else { - hw->cbLeft = hw->cbRight = hw->up = hw->down = FALSE; } } } - + else + { + xf86Msg(X_ERROR, "Wrong protocol version, not recognized by synaptics driver: " + "%x %x %x %x %x %x.\n", (int)buf[0], (int)buf[1], (int)buf[2], + (int)buf[3], (int)buf[4], (int)buf[5]); + return !Success; + } if (hw->z > 0) { int w_ok = 0; /* @@ -1487,6 +1516,7 @@ SynapticsGetPacket(LocalDevicePtr local, SynapticsPrivatePtr priv) { int count = 0; int c; + int old_proto = 0; unsigned char u; while((c = XisbRead(priv->buffer)) >= 0) { @@ -1514,7 +1544,7 @@ SynapticsGetPacket(LocalDevicePtr local, SynapticsPrivatePtr priv) } /* to avoid endless loops */ - if(count++ > 100) + if(count++ > 30) { ErrorF("Synaptics driver lost sync... got gigantic packet!\n"); return (!Success); @@ -1523,16 +1553,42 @@ SynapticsGetPacket(LocalDevicePtr local, SynapticsPrivatePtr priv) priv->protoBuf[priv->protoBufTail++] = u; /* check first byte */ - if((priv->protoBufTail == 1) && ((u & 0xC8) != 0x80)) + if(priv->protoBufTail == 1) + { + old_proto = 0; + if((u & 0xC8) != 0x80) /* newer protocols need this...*/ + { + if((u & 0xC0) != 0xC0) /* old protocol needs this...*/ + { + priv->inSync = FALSE; + priv->protoBufTail = 0; + DBG(4, ErrorF("Synaptics driver lost sync at 1st byte\n")); + continue; + } + else + old_proto = 1; + } + } + /* for old protocol check 2nd and 5th byte */ + if (old_proto && ((priv->protoBufTail == 2) || (priv->protoBufTail == 5)) && + ((u & 0x60) != 0x00)) { priv->inSync = FALSE; priv->protoBufTail = 0; - DBG(4, ErrorF("Synaptics driver lost sync at 1st byte\n")); + if (priv->protoBufTail == 2) + { + DBG(4, ErrorF("Synaptics driver lost sync at 2nd byte\n")); + } + else + { + DBG(4, ErrorF("Synaptics driver lost sync at 5th byte\n")); + } continue; } - /* check 4th byte */ - if((priv->protoBufTail == 4) && ((u & 0xc8) != 0xc0)) + if((priv->protoBufTail == 4) && + ((((u & 0xc8) != 0xc0) && !old_proto) || + (((u & 0xc0) != 0x80) && old_proto))) { priv->inSync = FALSE; priv->protoBufTail = 0; |