diff options
author | Peter Osterlund <petero2@telia.com> | 2004-04-12 21:48:48 +0200 |
---|---|---|
committer | Peter Osterlund <petero2@telia.com> | 2006-04-09 04:02:01 +0200 |
commit | 324421dd8683b09546312a6c09338a41cc65b235 (patch) | |
tree | 0c9d70c25d5110fbd70accd22d627dbae67c472a /synaptics.c | |
parent | 05011c8079c3fe515da7963f99be0d1c6a043272 (diff) |
Moved reading of hardware state to the protocol specific
files.
Diffstat (limited to 'synaptics.c')
-rw-r--r-- | synaptics.c | 410 |
1 files changed, 23 insertions, 387 deletions
diff --git a/synaptics.c b/synaptics.c index f77add6..913104c 100644 --- a/synaptics.c +++ b/synaptics.c @@ -85,20 +85,6 @@ * Local Variables and Types ****************************************************************************/ -/* - * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, - * section 2.3.2, which says that they should be valid regardless of the - * actual size of the sensor. - */ -#define XMIN_NOMINAL 1472 -#define XMAX_NOMINAL 5472 -#define YMIN_NOMINAL 1408 -#define YMAX_NOMINAL 4448 - -#define XMAX_VALID 6143 - -#define MAX_UNSYNC_PACKETS 10 /* i.e. 10 to 60 bytes */ - typedef enum { BOTTOM_EDGE = 1, TOP_EDGE = 2, @@ -126,8 +112,18 @@ typedef enum { /***************************************************************************** * Forward declaration ****************************************************************************/ -static InputInfoPtr -SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags); +static InputInfoPtr SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags); +static Bool DeviceControl(DeviceIntPtr, int); +static void ReadInput(LocalDevicePtr); +static int HandleState(LocalDevicePtr, struct SynapticsHwState*); +static int ControlProc(LocalDevicePtr, xDeviceCtl*); +static void CloseProc(LocalDevicePtr); +static int SwitchMode(ClientPtr, DeviceIntPtr, int); +static Bool ConvertProc(LocalDevicePtr, int, int, int, int, int, int, int, int, int*, int*); +static Bool DeviceInit(DeviceIntPtr); +static Bool DeviceOn(DeviceIntPtr); +static Bool DeviceOff(DeviceIntPtr); +static Bool DeviceInit(DeviceIntPtr); InputDriverRec SYNAPTICS = { @@ -178,11 +174,11 @@ SetDeviceAndProtocol(LocalDevicePtr local) { char *str_par; SynapticsPrivate *priv = local->private; + enum SynapticsProtocol proto = SYN_PROTO_PSAUX; - priv->proto = SYN_PROTO_PSAUX; str_par = xf86FindOptionValue(local->options, "Protocol"); if (str_par && !strcmp(str_par, "event")) { - priv->proto = SYN_PROTO_EVENT; + proto = SYN_PROTO_EVENT; } else if (str_par && !strcmp(str_par, "psaux")) { /* Already set up */ } else { /* default to auto-dev */ @@ -212,7 +208,7 @@ SetDeviceAndProtocol(LocalDevicePtr local) if ((id.bustype == BUS_I8042) && (id.vendor == 0x0002) && (id.product == PSMOUSE_SYNAPTICS)) { - priv->proto = SYN_PROTO_EVENT; + proto = SYN_PROTO_EVENT; xf86Msg(X_PROBED, "%s auto-dev sets Synaptics Device to %s\n", local->name, fname); xf86ReplaceStrOption(local->options, "Device", fname); @@ -221,7 +217,7 @@ SetDeviceAndProtocol(LocalDevicePtr local) } } } - switch (priv->proto) { + switch (proto) { case SYN_PROTO_PSAUX: priv->proto_ops = &psaux_proto_operations; break; @@ -682,6 +678,12 @@ static int clamp(int val, int min, int max) return max; } +static Bool +SynapticsGetHwState(LocalDevicePtr local, SynapticsPrivate *priv, + struct SynapticsHwState *hw) +{ + return priv->proto_ops->ReadHwState(local, priv, hw); +} /* * called for each full received packet from the touchpad @@ -1418,7 +1420,7 @@ ConvertProc(LocalDevicePtr local, } -static Bool +Bool QueryHardware(LocalDevicePtr local) { SynapticsPrivate *priv = (SynapticsPrivate *) local->private; @@ -1446,369 +1448,3 @@ QueryHardware(LocalDevicePtr local) return TRUE; } -static Bool -SynapticsGetHwState(LocalDevicePtr local, SynapticsPrivate *priv, - struct SynapticsHwState *hw) -{ - if (priv->proto == SYN_PROTO_PSAUX) { - return SynapticsParseRawPacket(local, priv, hw); - } else if (priv->proto == SYN_PROTO_EVENT) { - return SynapticsParseEventData(local, priv, hw); - } else { - return FALSE; - } -} - -static Bool -SynapticsParseEventData(LocalDevicePtr local, SynapticsPrivate *priv, - struct SynapticsHwState *hwRet) -{ - struct input_event ev; - Bool v; - struct SynapticsHwState *hw = &(priv->hwState); - - while (SynapticsReadEvent(priv, &ev)) { - switch (ev.type) { - case EV_SYN: - switch (ev.code) { - case SYN_REPORT: - if (priv->oneFinger) - hw->numFingers = 1; - else if (priv->twoFingers) - hw->numFingers = 2; - else if (priv->threeFingers) - hw->numFingers = 3; - else - hw->numFingers = 0; - *hwRet = *hw; - return TRUE; - } - case EV_KEY: - v = (ev.value ? TRUE : FALSE); - switch (ev.code) { - case BTN_LEFT: - hw->left = v; - break; - case BTN_RIGHT: - hw->right = v; - break; - case BTN_MIDDLE: - hw->middle = v; - break; - case BTN_FORWARD: - hw->up = v; - break; - case BTN_BACK: - hw->down = v; - break; - case BTN_0: - hw->multi[0] = v; - break; - case BTN_1: - hw->multi[1] = v; - break; - case BTN_2: - hw->multi[2] = v; - break; - case BTN_3: - hw->multi[3] = v; - break; - case BTN_4: - hw->multi[4] = v; - break; - case BTN_5: - hw->multi[5] = v; - break; - case BTN_6: - hw->multi[6] = v; - break; - case BTN_7: - hw->multi[7] = v; - break; - case BTN_TOOL_FINGER: - priv->oneFinger = v; - break; - case BTN_TOOL_DOUBLETAP: - priv->twoFingers = v; - break; - case BTN_TOOL_TRIPLETAP: - priv->threeFingers = v; - break; - } - break; - case EV_ABS: - switch (ev.code) { - case ABS_X: - hw->x = ev.value; - break; - case ABS_Y: - hw->y = ev.value; - break; - case ABS_PRESSURE: - hw->z = ev.value; - break; - case ABS_TOOL_WIDTH: - hw->fingerWidth = ev.value; - break; - } - break; - } - } - return FALSE; -} - -static Bool -SynapticsReadEvent(SynapticsPrivate *priv, struct input_event *ev) -{ - int i, c; - unsigned char *pBuf, u; - - for (i = 0; i < sizeof(struct input_event); i++) { - if ((c = XisbRead(priv->buffer)) < 0) - return FALSE; - u = (unsigned char)c; - pBuf = (unsigned char *)ev; - pBuf[i] = u; - } - return TRUE; -} - -static Bool -SynapticsParseRawPacket(LocalDevicePtr local, SynapticsPrivate *priv, - struct SynapticsHwState *hwRet) -{ - int newabs = SYN_MODEL_NEWABS(priv->synhw); - unsigned char *buf = priv->protoBuf; - struct SynapticsHwState *hw = &(priv->hwState); - int w, i; - - if (!SynapticsGetPacket(local, priv)) - return FALSE; - - /* Handle guest packets */ - hw->guest_dx = hw->guest_dy = 0; - if (newabs && priv->hasGuest) { - w = (((buf[0] & 0x30) >> 2) | - ((buf[0] & 0x04) >> 1) | - ((buf[3] & 0x04) >> 2)); - if (w == 3) { /* If w is 3, this is a guest packet */ - 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 = (buf[1] & 0x01) ? TRUE : FALSE; - hw->guest_mid = (buf[1] & 0x04) ? TRUE : FALSE; - hw->guest_right = (buf[1] & 0x02) ? TRUE : FALSE; - *hwRet = *hw; - return TRUE; - } - } - - /* Handle normal packets */ - hw->x = hw->y = hw->z = hw->numFingers = hw->fingerWidth = 0; - hw->left = hw->right = hw->up = hw->down = hw->middle = FALSE; - for (i = 0; i < 8; i++) - hw->multi[i] = FALSE; - - if (newabs) { /* 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]; - 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; - - if (SYN_CAP_EXTENDED(priv->synhw)) { - if (SYN_CAP_FOUR_BUTTON(priv->synhw)) { - 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->synhw)) { - if ((buf[3] & 2) ? !hw->right : hw->right) { - switch (SYN_CAP_MULTI_BUTTON_NO(priv->synhw) & ~0x01) { - default: - break; - case 8: - hw->multi[7] = ((buf[5] & 0x08)) ? 1 : 0; - hw->multi[6] = ((buf[4] & 0x08)) ? 1 : 0; - case 6: - hw->multi[5] = ((buf[5] & 0x04)) ? 1 : 0; - hw->multi[4] = ((buf[4] & 0x04)) ? 1 : 0; - case 4: - hw->multi[3] = ((buf[5] & 0x02)) ? 1 : 0; - hw->multi[2] = ((buf[4] & 0x02)) ? 1 : 0; - case 2: - hw->multi[1] = ((buf[5] & 0x01)) ? 1 : 0; - hw->multi[0] = ((buf[4] & 0x01)) ? 1 : 0; - } - } - } - } - } else { /* 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)); - w = (((buf[1] & 0x80) >> 4) | - ((buf[0] & 0x04) >> 1)); - - hw->left = (buf[0] & 0x01) ? 1 : 0; - hw->right = (buf[0] & 0x02) ? 1 : 0; - } - - hw->y = YMAX_NOMINAL + YMIN_NOMINAL - hw->y; - - if (hw->z > 0) { - int w_ok = 0; - /* - * Use capability bits to decide if the w value is valid. - * If not, set it to 5, which corresponds to a finger of - * normal width. - */ - if (SYN_CAP_EXTENDED(priv->synhw)) { - if ((w >= 0) && (w <= 1)) { - w_ok = SYN_CAP_MULTIFINGER(priv->synhw); - } else if (w == 2) { - w_ok = SYN_MODEL_PEN(priv->synhw); - } else if ((w >= 4) && (w <= 15)) { - w_ok = SYN_CAP_PALMDETECT(priv->synhw); - } - } - if (!w_ok) - w = 5; - - switch (w) { - case 0: - hw->numFingers = 2; - hw->fingerWidth = 5; - break; - case 1: - hw->numFingers = 3; - hw->fingerWidth = 5; - break; - default: - hw->numFingers = 1; - hw->fingerWidth = w; - break; - } - } - - *hwRet = *hw; - return TRUE; -} - -/* - * Decide if the current packet stored in priv->protoBuf is valid. - */ -static Bool -PacketOk(SynapticsPrivate *priv) -{ - unsigned char *buf = priv->protoBuf; - int newabs = SYN_MODEL_NEWABS(priv->synhw); - - if (newabs ? ((buf[0] & 0xC0) != 0x80) : ((buf[0] & 0xC0) != 0xC0)) { - DBG(4, ErrorF("Synaptics driver lost sync at 1st byte\n")); - return FALSE; - } - - if (!newabs && ((buf[1] & 0x60) != 0x00)) { - DBG(4, ErrorF("Synaptics driver lost sync at 2nd byte\n")); - return FALSE; - } - - if ((newabs ? ((buf[3] & 0xC0) != 0xC0) : ((buf[3] & 0xC0) != 0x80))) { - DBG(4, ErrorF("Synaptics driver lost sync at 4th byte\n")); - return FALSE; - } - - if (!newabs && ((buf[4] & 0x60) != 0x00)) { - DBG(4, ErrorF("Synaptics driver lost sync at 5th byte\n")); - return FALSE; - } - - return TRUE; -} - -static Bool -SynapticsGetPacket(LocalDevicePtr local, SynapticsPrivate *priv) -{ - int count = 0; - int c; - unsigned char u; - - while ((c = XisbRead(priv->buffer)) >= 0) { - u = (unsigned char)c; - - /* test if there is a reset sequence received */ - if ((c == 0x00) && (priv->lastByte == 0xAA)) { - if (xf86WaitForInput(local->fd, 50000) == 0) { - DBG(7, ErrorF("Reset received\n")); - QueryHardware(local); - } else - DBG(3, ErrorF("faked reset received\n")); - } - priv->lastByte = u; - - /* when there is no synaptics touchpad pipe the data to the repeater fifo */ - if (!priv->isSynaptics) { - xf86write(priv->fifofd, &u, 1); - if (++count >= 3) - return FALSE; - continue; - } - - /* to avoid endless loops */ - if (count++ > 30) { - ErrorF("Synaptics driver lost sync... got gigantic packet!\n"); - return FALSE; - } - - priv->protoBuf[priv->protoBufTail++] = u; - - /* Check that we have a valid packet. If not, we are out of sync, - so we throw away the first byte in the packet.*/ - if (priv->protoBufTail >= 6) { - if (!PacketOk(priv)) { - int i; - for (i = 0; i < priv->protoBufTail - 1; i++) - priv->protoBuf[i] = priv->protoBuf[i + 1]; - priv->protoBufTail--; - priv->outOfSync++; - if (priv->outOfSync > MAX_UNSYNC_PACKETS) { - priv->outOfSync = 0; - DBG(3, ErrorF("Synaptics synchronization lost too long -> reset touchpad.\n")); - QueryHardware(local); /* including a reset */ - continue; - } - } - } - - if (priv->protoBufTail >= 6) { /* Full packet received */ - if (priv->outOfSync > 0) { - priv->outOfSync = 0; - DBG(4, ErrorF("Synaptics driver resynced.\n")); - } - priv->protoBufTail = 0; - return TRUE; - } - } - - return FALSE; -} |