summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAapo Rantalainen <aapo.rantalainen@gmail.com>2011-03-09 21:32:36 +0100
committerChristoph Brill <egore911@egore911.de>2011-03-09 22:27:04 +0100
commit049d5fb6037b34d94b24cb8300849cf4e3b67437 (patch)
treeb93bdd5fe6e57131309050dca1ae6c83e92cb84c /src
parentd6fc5be2969b9eede3c0fdd6e03daec4100a8c9f (diff)
Add synaptics orientation support
This patch allows usage of "synclient Orientation=0" (values from 0 to 3). It will rotate the touchpad similar to "xrandr -o". Original patch was extended for alps and ps2. Signed-off-by: Christoph Brill <egore911@egore911.de>
Diffstat (limited to 'src')
-rw-r--r--src/alpscomm.c29
-rw-r--r--src/eventcomm.c22
-rw-r--r--src/properties.c8
-rw-r--r--src/ps2comm.c36
-rw-r--r--src/synaptics.c2
-rw-r--r--src/synapticsstr.h1
6 files changed, 85 insertions, 13 deletions
diff --git a/src/alpscomm.c b/src/alpscomm.c
index dc76655..7d5cda2 100644
--- a/src/alpscomm.c
+++ b/src/alpscomm.c
@@ -149,11 +149,12 @@ ALPS_get_packet(struct CommData *comm, InputInfoPtr pInfo)
* reflects left,right,down,up in lef1,rig1,mid1,up1.
*/
static void
-ALPS_process_packet(unsigned char *packet, struct SynapticsHwState *hw)
+ALPS_process_packet(SynapticsPrivate *priv, unsigned char *packet, struct SynapticsHwState *hw)
{
int x = 0, y = 0, z = 0;
int left = 0, right = 0, middle = 0;
int i;
+ SynapticsParameters *para = &priv->synpara;
x = (packet[1] & 0x7f) | ((packet[2] & 0x78) << (7-3));
y = (packet[4] & 0x7f) | ((packet[3] & 0x70) << (7-4));
@@ -172,8 +173,27 @@ ALPS_process_packet(unsigned char *packet, struct SynapticsHwState *hw)
hw->multi[i] = FALSE;
if (z > 0) {
- hw->x = x;
- hw->y = y;
+ if (para->orientation==0)
+ hw->x = x;
+ else if (para->orientation==2)
+ hw->x = priv->maxx + priv->minx - x;
+ else if (para->orientation==3)
+ hw->y = (priv->maxx - x) * (priv->maxy - priv->miny) / (priv->maxx - priv->minx) + priv->miny;
+ else if (para->orientation==1)
+ hw->y = (x - priv->minx) * (priv->maxy - priv->miny) / (priv->maxx - priv->minx) + priv->miny;
+ else
+ hw->x = x;
+
+ if (para->orientation==0)
+ hw->y = y;
+ else if (para->orientation==2)
+ hw->y = priv->maxy + priv->miny - y;
+ else if (para->orientation==3)
+ hw->x = (y - priv->miny) * (priv->maxx - priv->minx) / (priv->maxy - priv->miny) + priv->minx;
+ else if (para->orientation==1)
+ hw->x = (priv->maxy - y) * (priv->maxx - priv->minx) / (priv->maxy - priv->miny) + priv->minx;
+ else
+ hw->y = y;
}
hw->z = z;
hw->numFingers = (z > 0) ? 1 : 0;
@@ -210,11 +230,12 @@ ALPSReadHwState(InputInfoPtr pInfo,
{
unsigned char *buf = comm->protoBuf;
struct SynapticsHwState *hw = &(comm->hwState);
+ SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
if (!ALPS_get_packet(comm, pInfo))
return FALSE;
- ALPS_process_packet(buf, hw);
+ ALPS_process_packet(priv, buf, hw);
*hwRet = *hw;
return TRUE;
diff --git a/src/eventcomm.c b/src/eventcomm.c
index d394d3f..3d550f1 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -400,10 +400,28 @@ EventReadHwState(InputInfoPtr pInfo,
case EV_ABS:
switch (ev.code) {
case ABS_X:
- hw->x = ev.value;
+ if (para->orientation==0)
+ hw->x = ev.value;
+ else if (para->orientation==2)
+ hw->x = priv->maxx + priv->minx - ev.value;
+ else if (para->orientation==3)
+ hw->y = (priv->maxx - ev.value) * (priv->maxy - priv->miny) / (priv->maxx - priv->minx) + priv->miny;
+ else if (para->orientation==1)
+ hw->y = (ev.value - priv->minx) * (priv->maxy - priv->miny) / (priv->maxx - priv->minx) + priv->miny;
+ else
+ hw->x = ev.value;
break;
case ABS_Y:
- hw->y = ev.value;
+ if (para->orientation==0)
+ hw->y = ev.value;
+ else if (para->orientation==2)
+ hw->y = priv->maxy + priv->miny - ev.value;
+ else if (para->orientation==3)
+ hw->x = (ev.value - priv->miny) * (priv->maxx - priv->minx) / (priv->maxy - priv->miny) + priv->minx;
+ else if (para->orientation==1)
+ hw->x = (priv->maxy - ev.value) * (priv->maxx - priv->minx) / (priv->maxy - priv->miny) + priv->minx;
+ else
+ hw->y = ev.value;
break;
case ABS_PRESSURE:
hw->z = ev.value;
diff --git a/src/properties.c b/src/properties.c
index 23b5a6a..06909ed 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -83,6 +83,7 @@ Atom prop_capabilities = 0;
Atom prop_resolution = 0;
Atom prop_area = 0;
Atom prop_noise_cancellation = 0;
+Atom prop_orientation = 0;
static Atom
InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values)
@@ -285,6 +286,8 @@ InitDeviceProperties(InputInfoPtr pInfo)
prop_noise_cancellation = InitAtom(pInfo->dev,
SYNAPTICS_PROP_NOISE_CANCELLATION, 32, 2, values);
+ prop_orientation = InitAtom(pInfo->dev, SYNAPTICS_ORIENTATION, 32, 1, &para->orientation);
+
}
int
@@ -666,6 +669,11 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
return BadValue;
para->hyst_x = hyst[0];
para->hyst_y = hyst[1];
+ } else if (property == prop_orientation)
+ {
+ if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
+ return BadMatch;
+ para->orientation = *(INT32*)prop->data;
}
return Success;
diff --git a/src/ps2comm.c b/src/ps2comm.c
index 0e9b861..1c2bbc3 100644
--- a/src/ps2comm.c
+++ b/src/ps2comm.c
@@ -524,7 +524,7 @@ PS2ReadHwStateProto(InputInfoPtr pInfo,
SynapticsParameters *para = &priv->synpara;
struct PS2SynapticsHwInfo *synhw;
int newabs;
- int w, i;
+ int w, i, x, y;
synhw = (struct PS2SynapticsHwInfo*)priv->proto_data;
if (!synhw)
@@ -541,17 +541,17 @@ PS2ReadHwStateProto(InputInfoPtr pInfo,
return FALSE;
/* Handle normal packets */
- hw->x = hw->y = hw->z = hw->numFingers = hw->fingerWidth = 0;
+ hw->x = hw->y = hw->z = hw->numFingers = hw->fingerWidth = x = y = 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, "using new protocols\n");
- hw->x = (((buf[3] & 0x10) << 8) |
+ x = (((buf[3] & 0x10) << 8) |
((buf[1] & 0x0f) << 8) |
buf[4]);
- hw->y = (((buf[3] & 0x20) << 7) |
+ y = (((buf[3] & 0x20) << 7) |
((buf[1] & 0xf0) << 4) |
buf[5]);
@@ -598,9 +598,9 @@ PS2ReadHwStateProto(InputInfoPtr pInfo,
}
} else { /* old proto...*/
DBG(7, "using old protocol\n");
- hw->x = (((buf[1] & 0x1F) << 8) |
+ x = (((buf[1] & 0x1F) << 8) |
buf[2]);
- hw->y = (((buf[4] & 0x1F) << 8) |
+ y = (((buf[4] & 0x1F) << 8) |
buf[5]);
hw->z = (((buf[0] & 0x30) << 2) |
@@ -612,7 +612,29 @@ PS2ReadHwStateProto(InputInfoPtr pInfo,
hw->right = (buf[0] & 0x02) ? 1 : 0;
}
- hw->y = YMAX_NOMINAL + YMIN_NOMINAL - hw->y;
+ y = YMAX_NOMINAL + YMIN_NOMINAL - y;
+
+ if (para->orientation==0)
+ hw->x = x;
+ else if (para->orientation==2)
+ hw->x = priv->maxx + priv->minx - x;
+ else if (para->orientation==3)
+ hw->y = (priv->maxx - x) * (priv->maxy - priv->miny) / (priv->maxx - priv->minx) + priv->miny;
+ else if (para->orientation==1)
+ hw->y = (x - priv->minx) * (priv->maxy - priv->miny) / (priv->maxx - priv->minx) + priv->miny;
+ else
+ hw->x = x;
+
+ if (para->orientation==0)
+ hw->y = y;
+ else if (para->orientation==2)
+ hw->y = priv->maxy + priv->miny - y;
+ else if (para->orientation==3)
+ hw->x = (y - priv->miny) * (priv->maxx - priv->minx) / (priv->maxy - priv->miny) + priv->minx;
+ else if (para->orientation==1)
+ hw->x = (priv->maxy - y) * (priv->maxx - priv->minx) / (priv->maxy - priv->miny) + priv->minx;
+ else
+ hw->y = y;
if (hw->z >= para->finger_high) {
int w_ok = 0;
diff --git a/src/synaptics.c b/src/synaptics.c
index 1233917..03a9f60 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -574,6 +574,8 @@ static void set_default_parameters(InputInfoPtr pInfo)
pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", horizResolution);
pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", vertResolution);
+ pars->orientation = xf86SetIntOption(opts, "Orientation", 0);
+
/* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
if (pars->top_edge > pars->bottom_edge) {
int tmp = pars->top_edge;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 8f6593e..90640f7 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -161,6 +161,7 @@ typedef struct _SynapticsParameters
unsigned int resolution_vert; /* vertical resolution of touchpad in units/mm */
int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
int hyst_x, hyst_y; /* x and y width of hysteresis box */
+ int orientation; /* orientation of the touchpad */
} SynapticsParameters;