diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h index 0b8975c..aa0ed8b 100644 --- a/include/synaptics-properties.h +++ b/include/synaptics-properties.h @@ -142,4 +142,7 @@ /* 8 bit (BOOL) */ #define SYNAPTICS_PROP_GRAB "Synaptics Grab Event Device" +/* 32 bit, 2 values, vert, horiz */ +#define SYNAPTICS_PROP_RESOLUTION "Synaptics Pad Resolution" + #endif /* _SYNAPTICS_PROPERTIES_H_ */ diff --git a/src/eventcomm.c b/src/eventcomm.c index 5f712c4..f5f8ef8 100644 --- a/src/eventcomm.c +++ b/src/eventcomm.c @@ -175,6 +175,24 @@ event_query_axis_ranges(LocalDevicePtr local) priv->maxw = abs.maximum; } + SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_RX), &abs)); + if (rc >= 0) + { + xf86Msg(X_INFO, "%s: horizontal resolution %d units/mm\n", local->name, abs.maximum); + priv->resx = abs.maximum; + } else + xf86Msg(X_INFO, "%s: does not provide horizontal resolution (%s)\n", + local->name, strerror(errno)); + + SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_RY), &abs)); + if (rc >= 0) + { + xf86Msg(X_INFO, "%s: vertical resolution %d units/mm\n", local->name, abs.maximum); + priv->resy = abs.maximum; + } else + xf86Msg(X_INFO, "%s: does not provide vertical resolution (%s)\n", + local->name, strerror(errno)); + SYSCALL(rc = ioctl(local->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); if (rc >= 0) { diff --git a/src/properties.c b/src/properties.c index 2cf485a..ea42bf1 100644 --- a/src/properties.c +++ b/src/properties.c @@ -80,6 +80,7 @@ Atom prop_coastspeed = 0; Atom prop_pressuremotion = 0; Atom prop_pressuremotion_factor = 0; Atom prop_grab = 0; +Atom prop_resolution = 0; static Atom InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values) @@ -251,6 +252,10 @@ InitDeviceProperties(LocalDevicePtr local) prop_grab = InitAtom(local->dev, SYNAPTICS_PROP_GRAB, 8, 1, ¶->grab_event_device); + values[0] = para->resolution_vert; + values[1] = para->resolution_horiz; + prop_resolution = InitAtom(local->dev, SYNAPTICS_PROP_RESOLUTION, 32, 2, values); + } int @@ -588,6 +593,15 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, return BadMatch; para->grab_event_device = *(BOOL*)prop->data; + } else if (property == prop_resolution) + { + INT32 *dist; + if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER) + return BadMatch; + + dist = (INT32*)prop->data; + para->resolution_vert = dist[0]; + para->resolution_horiz = dist[1]; } return Success; diff --git a/src/synaptics.c b/src/synaptics.c index 5b932fd..0c87d8f 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -124,6 +124,7 @@ static Bool DeviceOff(DeviceIntPtr); static Bool DeviceClose(DeviceIntPtr); static Bool QueryHardware(LocalDevicePtr); static void ReadDevDimensions(LocalDevicePtr); +static void ScaleCoordinates(SynapticsPrivate *priv, struct SynapticsHwState *hw); #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 void InitDeviceProperties(LocalDevicePtr local); @@ -309,6 +310,7 @@ static void set_default_parameters(LocalDevicePtr local) int clickFinger1, clickFinger2, clickFinger3; Bool vertEdgeScroll, horizEdgeScroll; Bool vertTwoFingerScroll, horizTwoFingerScroll; + int horizResolution, vertResolution; /* read the parameters */ if (priv->synshm) @@ -413,6 +415,9 @@ static void set_default_parameters(LocalDevicePtr local) vertTwoFingerScroll = priv->has_double ? TRUE : FALSE; horizTwoFingerScroll = FALSE; + horizResolution = priv->resx ? priv->resx : 1; + vertResolution = priv->resy ? priv->resy : 1; + /* set the parameters */ pars->left_edge = xf86SetIntOption(opts, "LeftEdge", l); pars->right_edge = xf86SetIntOption(opts, "RightEdge", r); @@ -485,6 +490,8 @@ static void set_default_parameters(LocalDevicePtr local) pars->press_motion_min_factor = xf86SetRealOption(opts, "PressureMotionMinFactor", 1.0); pars->press_motion_max_factor = xf86SetRealOption(opts, "PressureMotionMaxFactor", 1.0); pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", TRUE); + pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", horizResolution); + pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", vertResolution); /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */ if (pars->top_edge > pars->bottom_edge) { @@ -1905,6 +1912,8 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw) int timeleft; int i; + ScaleCoordinates(priv, hw); + /* update hardware state in shared memory */ if (shm) { @@ -2200,3 +2209,27 @@ QueryHardware(LocalDevicePtr local) return TRUE; } +static void +ScaleCoordinates(SynapticsPrivate *priv, struct SynapticsHwState *hw) +{ + int minX = priv->synpara.left_edge; + int maxX = priv->synpara.right_edge; + int minY = priv->synpara.top_edge; + int maxY = priv->synpara.bottom_edge; + int vertRes = priv->synpara.resolution_vert; + int horizRes = priv->synpara.resolution_horiz; + int xCenter = (minX + maxX) / 2; + int yCenter = (minY + maxY) / 2; + double vertScale = 1; + double horizScale = 1; + + if ((horizRes > vertRes) && (vertRes > 0)) + horizScale = horizRes / (double)vertRes; + else if ((horizRes < vertRes) && (horizRes > 0)) { + vertScale = vertRes / (double)horizRes; + } + + hw->x = (hw->x - xCenter) / horizScale + xCenter; + hw->y = (hw->y - yCenter) / vertScale + yCenter; +} + diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 859e757..7abc3c3 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -139,6 +139,8 @@ typedef struct _SynapticsParameters double press_motion_min_factor; /* factor applied on speed when finger pressure is at minimum */ double press_motion_max_factor; /* factor applied on speed when finger pressure is at minimum */ Bool grab_event_device; /* grab event device for exclusive use? */ + int resolution_horiz; /* horizontal resolution of touchpad in units/mm */ + int resolution_vert; /* vertical resolution of touchpad in units/mm */ } SynapticsParameters; @@ -203,6 +205,7 @@ typedef struct _SynapticsPrivateRec int minx, maxx, miny, maxy; /* min/max dimensions as detected */ int minp, maxp, minw, maxw; /* min/max pressure and finger width as detected */ + int resx, resy; /* x and y resolution as detected */ Bool has_left; /* left button detected for this device */ Bool has_right; /* right button detected for this device */ Bool has_middle; /* middle button detected for this device */ diff --git a/tools/synclient.c b/tools/synclient.c index 3ea9c50..a4a3b82 100644 --- a/tools/synclient.c +++ b/tools/synclient.c @@ -138,6 +138,8 @@ static struct Parameter params[] = { {"PressureMotionMinFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 0}, {"PressureMotionMaxFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 1}, {"GrabEventDevice", PT_BOOL, 0, 1, SYNAPTICS_PROP_GRAB, 8, 0}, + {"VertResolution", PT_INT, 1, 255, SYNAPTICS_PROP_RESOLUTION, 32, 0}, + {"HorizResolution", PT_INT, 1, 255, SYNAPTICS_PROP_RESOLUTION, 32, 1}, { NULL, 0, 0, 0, 0 } };