summaryrefslogtreecommitdiff
path: root/synaptics.c
diff options
context:
space:
mode:
Diffstat (limited to 'synaptics.c')
-rw-r--r--synaptics.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/synaptics.c b/synaptics.c
index ab134c0..c80ad5a 100644
--- a/synaptics.c
+++ b/synaptics.c
@@ -21,6 +21,11 @@
* absolute to relative translation code (from the gpm source)
* and some other ideas
*
+ * Synaptics Passthrough Support
+ * Copyright (c) 2002 Linuxcare Inc. David Kennedy <dkennedy@linuxcare.com>
+ * adapted to version 0.12.1
+ * Copyright (c) 2003 Fred Hucht <fred@thp.Uni-Duisburg.de>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -281,6 +286,7 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
priv->tapping_millis = now;
priv->button_delay_millis = now;
priv->touch_on.millis = now;
+ priv->hasGuest = FALSE;
/* install shared memory or normal memory for parameter */
priv->shm_config = FALSE;
@@ -793,6 +799,11 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState* hw)
para->down = hw->down;
for (i = 0; i < 8; i++)
para->multi[i] = hw->multi[i];
+ para->guest_left = hw->guest_left;
+ para->guest_mid = hw->guest_mid;
+ para->guest_right = hw->guest_right;
+ para->guest_dx = hw->guest_dx;
+ para->guest_dy = hw->guest_dy;
/* If touchpad is switched off, we skip the whole thing and return delay */
if (para->touchpad_off == TRUE)
@@ -1044,6 +1055,9 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState* hw)
buttons = ((hw->left ? 0x01 : 0) |
(mid ? 0x02 : 0) |
(hw->right ? 0x04 : 0) |
+ (hw->guest_left ? 0x01 : 0) |
+ (hw->guest_mid ? 0x02 : 0) |
+ (hw->guest_right ? 0x04 : 0) |
(hw->up ? 0x08 : 0) |
(hw->down ? 0x10 : 0) |
(hw->multi[2] ? 0x20 : 0) |
@@ -1056,6 +1070,10 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState* hw)
MOVE_HIST(0).y = hw->y;
MOVE_HIST(0).x = hw->x;
+ /* Add guest device movements */
+ dx += hw->guest_dx;
+ dy += hw->guest_dy;
+
/* Post events */
if (dx || dy)
xf86PostMotionEvent(local->dev, 0, 0, 2, dx, dy);
@@ -1230,6 +1248,21 @@ QueryHardware (LocalDevicePtr local)
if (synaptics_set_mode(local->fd, mode) != Success)
return !Success;
+ /* Check to see if the host mouse supports a guest */
+ if (SYN_CAP_PASSTHROUGH(priv->capabilities)) {
+ priv->hasGuest = TRUE;
+
+ /* Enable the guest mouse. Set it to relative mode, three byte
+ * packets */
+
+ /* Disable the host to talk to the guest */
+ SynapticsDisableDevice(local->fd);
+ /* Reset it, set defaults, streaming and enable it */
+ if ((SynapticsResetPassthrough(local->fd)) != Success) {
+ priv->hasGuest = FALSE;
+ }
+ }
+
SynapticsEnableDevice(local->fd);
PrintIdent(priv);
@@ -1422,6 +1455,21 @@ SynapticsParseRawPacket(LocalDevicePtr local, SynapticsPrivate *priv,
}
}
}
+
+ if (priv->hasGuest) {
+ static int guest_buttons = 0;
+ /* Check to see if w is 0x03. If it is, then it is a guest packet */
+ if (w == 0x03) {
+ guest_buttons = buf[1] & 0x07;
+ if (buf[4] != 0)
+ hw->guest_dx = buf[4] - ((buf[1] & 0x10) ? 256 : 0);
+ if (buf[5] != 0)
+ hw->guest_dy = -(buf[5] - ((buf[1] & 0x20) ? 256 : 0));
+ }
+ hw->guest_left = (guest_buttons & 0x01) ? TRUE : FALSE;
+ hw->guest_mid = (guest_buttons & 0x04) ? TRUE : FALSE;
+ hw->guest_right = (guest_buttons & 0x02) ? TRUE : FALSE;
+ }
} else { /* old proto...*/
DBG(7, ErrorF("using old protocol\n"));
hw->x = (((buf[1] & 0x1F) << 8) |
@@ -1610,5 +1658,7 @@ PrintIdent(SynapticsPrivate *priv)
xf86Msg(X_PROBED, " -> multifinger detection\n");
if (SYN_CAP_PALMDETECT(priv->capabilities))
xf86Msg(X_PROBED, " -> palm detection\n");
+ if (SYN_CAP_PASSTHROUGH(priv->capabilities))
+ xf86Msg(X_PROBED, " -> pass-through port\n");
}
}