summaryrefslogtreecommitdiff
path: root/driver/xf86-input-fpit/src/xf86Fpit.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2008-08-23 13:57:33 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2008-08-23 13:57:33 +0000
commitf7aada0ce9558debf8cf41effa2719baf6667229 (patch)
tree1e4aae001dbf92548796be54fba821a7f1983d62 /driver/xf86-input-fpit/src/xf86Fpit.c
parent867ebe79520e4326f34aeb17a7226bd61f7fe0eb (diff)
xf86-input-fpit 1.2.0
Diffstat (limited to 'driver/xf86-input-fpit/src/xf86Fpit.c')
-rw-r--r--driver/xf86-input-fpit/src/xf86Fpit.c267
1 files changed, 166 insertions, 101 deletions
diff --git a/driver/xf86-input-fpit/src/xf86Fpit.c b/driver/xf86-input-fpit/src/xf86Fpit.c
index b7a9a6057..0378e373d 100644
--- a/driver/xf86-input-fpit/src/xf86Fpit.c
+++ b/driver/xf86-input-fpit/src/xf86Fpit.c
@@ -63,11 +63,10 @@
# include <misc.h>
# include <xf86.h>
-# if !defined(DGUX)
-# endif
# include <xf86_OSproc.h>
# include <xf86Xinput.h>
# include <exevents.h>
+# include <randrstr.h>
# include <xf86Module.h>
@@ -79,7 +78,6 @@
*
***************************************************************************
*/
-#define FPIT_LINK_SPEED B19200 /* 19200 Baud */
#define FPIT_PORT "/dev/ttyS3"
#define FPIT_MAX_X 4100
@@ -87,19 +85,6 @@
#define FPIT_MAX_Y 4100
#define FPIT_MIN_Y 0
-#define PHASING_BIT 0x80
-#define PROXIMITY_BIT 0x20 /* DMC: This was 0x40 but the chart says its bit 5 which is 0x20 */
-/*#define TABID_BIT 0x20 */
-#define XSIGN_BIT 0x10
-#define YSIGN_BIT 0x08
-#define BUTTON_BITS 0x07
-#define COORD_BITS 0x7f
-
-/* DMC: Added these */
-#define SW1 0x01
-#define SW2 0x02
-#define SW3 0x04
-
/*
***************************************************************************
@@ -114,6 +99,20 @@
/*
***************************************************************************
*
+ * Screen orientation descriptors.
+ *
+ ***************************************************************************
+ */
+
+typedef enum {
+ FPIT_INVERT_X = 0x01,
+ FPIT_INVERT_Y = 0x02,
+ FPIT_THEN_SWAP_XY = 0x04
+} FpitOrientation;
+
+/*
+ ***************************************************************************
+ *
* Device private records.
*
***************************************************************************
@@ -122,9 +121,8 @@ typedef struct {
char *fpitDev; /* device file name */
int screen_width;
int screen_height;
+ Rotation screen_rotation;
int screen_no;
- int fpitInc; /* increment between transmits */
- int fpitButTrans; /* button translation flags */
int fpitOldX; /* previous X position */
int fpitOldY; /* previous Y position */
int fpitOldProximity; /* previous proximity */
@@ -133,15 +131,14 @@ typedef struct {
int fpitMinY; /* min Y value */
int fpitMaxX; /* max X value */
int fpitMaxY; /* max Y value */
- int fpitInvX; /* Invert X axis */
- int fpitInvY; /* Invert Y axis */
- int fpitRes; /* resolution in lines per inch */
- int flags; /* various flags */
int fpitIndex; /* number of bytes read */
- int fpitBaud; /* Baud rate of device */
unsigned char fpitData[BUFFER_SIZE]; /* data read on the device */
- int fpitSwapXY; /* swap X and Y values */
+ FpitOrientation fpitBaseOrientation; /* read from X config */
+ FpitOrientation fpitTotalOrientation; /* above + RandR */
int fpitPassive; /* translate passive buttons */
+ int fpitTrackRandR; /* check for, react to screen rotate/resize */
+ /* XXX when this last option is unset, we provide "compatibly stupid"
+ * behavior. */
} FpitPrivateRec, *FpitPrivatePtr;
@@ -160,21 +157,73 @@ typedef struct {
static Bool xf86FpitConvert(LocalDevicePtr local, int first, int num, int v0, int v1, int v2, int v3, int v4, int v5, int *x, int *y)
{
FpitPrivatePtr priv = (FpitPrivatePtr) local->private;
+ AxisInfoPtr axes = local->dev->valuator->axes;
if (first != 0 || num != 2) {
return FALSE;
}
- if (priv->fpitSwapXY != 0) {
- *x = xf86ScaleAxis(v1, 0, priv->screen_width, priv->fpitMinY, priv->fpitMaxY);
- *y = xf86ScaleAxis(v0, 0, priv->screen_height, priv->fpitMinX, priv->fpitMaxX);
- } else {
- *x = xf86ScaleAxis(v0, 0, priv->screen_width, priv->fpitMinX, priv->fpitMaxX);
- *y = xf86ScaleAxis(v1, 0, priv->screen_height, priv->fpitMinY, priv->fpitMaxY);
- }
+ *x = xf86ScaleAxis(v0, 0, priv->screen_width, axes[0].min_value, axes[0].max_value);
+ *y = xf86ScaleAxis(v1, 0, priv->screen_height, axes[1].min_value, axes[1].max_value);
+
return TRUE;
}
/*
+ ***************************************************************************
+ *
+ * xf86FpitSetUpAxes --
+ * Based on current screen resolution and, if RandR support is enabled,
+ * current rotation state, set up the XInput axes and orientation info.
+ *
+ ***************************************************************************
+ */
+
+static void xf86FpitSetUpAxes(DeviceIntPtr dev, FpitPrivatePtr priv)
+{
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Axes min and max values are reported in raw coordinates.
+ * Resolution is computed roughly by the difference between
+ * max and min values scaled from the approximate size of the
+ * screen to fit one meter.
+ */
+ int quarter_turns;
+
+ priv->screen_width = screenInfo.screens[priv->screen_no]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_no]->height;
+
+ priv->fpitTotalOrientation = priv->fpitBaseOrientation;
+ if (!priv->fpitTrackRandR)
+ return;
+
+ /* now apply transforms specified by RandR:
+ * slightly complicated because invertX/Y and swapXY don't commute. */
+ priv->screen_rotation = RRGetRotation(screenInfo.screens[priv->screen_no]);
+ quarter_turns = (
+ (priv->screen_rotation & RR_Rotate_90 ? 1 : 0) +
+ (priv->screen_rotation & RR_Rotate_180 ? 2 : 0) +
+ (priv->screen_rotation & RR_Rotate_270 ? 3 : 0) ) % 4;
+ if (quarter_turns / 2 != 0)
+ priv->fpitTotalOrientation ^= FPIT_INVERT_X | FPIT_INVERT_Y;
+ if (quarter_turns % 2 != 0) {
+ priv->fpitTotalOrientation ^=
+ (priv->fpitTotalOrientation & FPIT_THEN_SWAP_XY ? FPIT_INVERT_X : FPIT_INVERT_Y)
+ | FPIT_THEN_SWAP_XY;
+ }
+
+ if (priv->fpitTotalOrientation & FPIT_THEN_SWAP_XY) {
+ InitValuatorAxisStruct(dev, 1, priv->fpitMinX, priv->fpitMaxX, 9500, 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct(dev, 0, priv->fpitMinY, priv->fpitMaxY, 10500, 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ } else {
+ InitValuatorAxisStruct(dev, 0, priv->fpitMinX, priv->fpitMaxX, 9500, 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct(dev, 1, priv->fpitMinY, priv->fpitMaxY, 10500, 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ }
+}
+/*
** xf86FpitReadInput
** Reads from the Fpit and posts any new events to the server.
*/
@@ -182,11 +231,17 @@ static void xf86FpitReadInput(LocalDevicePtr local)
{
FpitPrivatePtr priv = (FpitPrivatePtr) local->private;
int len, loop;
- int is_core_pointer;
int x, y, buttons, prox;
DeviceIntPtr device;
int conv_x, conv_y;
+ if (priv->fpitTrackRandR && (
+ priv->screen_width != screenInfo.screens[priv->screen_no]->width ||
+ priv->screen_height != screenInfo.screens[priv->screen_no]->height ||
+ priv->screen_rotation != RRGetRotation(screenInfo.screens[priv->screen_no])
+ ))
+ xf86FpitSetUpAxes(local->dev, priv);
+
do { /* keep reading blocks until there are no more */
/* Read data into buffer */
@@ -209,57 +264,72 @@ static void xf86FpitReadInput(LocalDevicePtr local)
priv->fpitIndex += len;
- /* process each packet in this block */
- for (loop=0;loop+FPIT_PACKET_SIZE<=priv->fpitIndex;loop++) {
- if (!(priv->fpitData[loop] & 0x80)) continue; /* we don't have a start bit yet */
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x20
+#define BUTTON_BITS 0x07
+#define SW1 0x01
+#define SW2 0x02
+#define SW3 0x04
+
+ /* process each packet in this block */
/* Format of 5 bytes data packet for Fpit Tablets
Byte 1
- bit 7 Phasing bit always 1
- bit 6 Switch status change
- bit 5 Proximity
- bit 4 Always 0
- bit 3 Test data
- bit 2 Sw3 (2nd side sw)
- bit 1 Sw2 (1st side sw)
- bit 0 Sw1 (Pen tip sw)
+ bit 7 (0x80) Phasing bit always 1
+ bit 6 (0x40) Switch status change
+ bit 5 (0x20) Proximity
+ bit 4 (0x10) Always 0
+ bit 3 (0x08) Test data
+ bits 2-0 (0x07) Buttons:
+ bit 2 (0x04) Sw3 (2nd side sw)
+ bit 1 (0x02) Sw2 (1st side sw)
+ bit 0 (0x01) Sw1 (Pen tip sw)
Byte 2
- bit 7 Always 0
- bits 6-0 = X6 - X0
+ bit 7 (0x80) Always 0
+ bits 6-0 (0x7f) X6 - X0
Byte 3
- bit 7 Always 0
- bits 6-0 = X13 - X7
+ bit 7 (0x80) Always 0
+ bits 6-0 (0x7f) X13 - X7
Byte 4
- bit 7 Always 0
- bits 6-0 = Y6 - Y0
+ bit 7 (0x80) Always 0
+ bits 6-0 (0x7f) Y6 - Y0
Byte 5
- bit 7 Always 0
- bits 6-0 = Y13 - Y7
+ bit 7 (0x80) Always 0
+ bits 6-0 (0x7f) Y13 - Y7
*/
+ for (loop=0;loop+FPIT_PACKET_SIZE<=priv->fpitIndex;loop++) {
+ if (!(priv->fpitData[loop] & PHASING_BIT)) continue; /* we don't have a start bit yet */
x = (int) (priv->fpitData[loop + 1] & 0x7f) + ((int) (priv->fpitData[loop + 2] & 0x7f) << 7);
y = (int) (priv->fpitData[loop + 3] & 0x7f) + ((int) (priv->fpitData[loop + 4] & 0x7f) << 7);
- /* Add in any offsets */
- if (priv->fpitInvX)
+ /* Adjust to orientation */
+ if (priv->fpitTotalOrientation & FPIT_INVERT_X)
x = priv->fpitMaxX - x + priv->fpitMinX;
- if (priv->fpitInvY)
+ if (priv->fpitTotalOrientation & FPIT_INVERT_Y)
y = priv->fpitMaxY - y + priv->fpitMinY;
+ if (priv->fpitTotalOrientation & FPIT_THEN_SWAP_XY) {
+ int z = x; x = y; y = z;
+ }
+
prox = (priv->fpitData[loop] & PROXIMITY_BIT) ? 0 : 1;
buttons = (priv->fpitData[loop] & BUTTON_BITS);
device = local->dev;
- is_core_pointer = xf86IsCorePointer(device);
xf86FpitConvert(local, 0, 2, x, y, 0, 0, 0, 0, &conv_x, &conv_y);
xf86XInputSetScreen(local, priv->screen_no, conv_x, conv_y);
- /* coordonates are ready we can send events */
+ /* coordinates are ready we can send events */
- if (prox!=priv->fpitOldProximity) /* proximity changed */
- if (!is_core_pointer) xf86PostProximityEvent(device, prox, 0, 2, x, y);
+ if (prox!=priv->fpitOldProximity) { /* proximity changed */
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
+ if (xf86IsCorePointer(device) == 0)
+#endif
+ xf86PostProximityEvent(device, prox, 0, 2, x, y);
+ }
if (priv->fpitOldX != x || priv->fpitOldY != y) /* position changed */
xf86PostMotionEvent(device, 1, 0, 2, x, y);
@@ -268,20 +338,16 @@ static void xf86FpitReadInput(LocalDevicePtr local)
/*
For passive pen (Stylistic 3400, et al.):
sw1 = 1 if pen is moving
- sw1 = 0 if pen is not moving
- sw2 = 0 if pen is contacting the pad
- sw2 = 1 if pen was lifted from the pad
+ sw2 = 1 if pen was lifted from the pad / isn't in contact
sw3 = 1 if right mouse-button icon was chosen
*/
/* convert the pen button bits to actual mouse buttons */
if (buttons & SW2) buttons=0; /* the pen was lifted, so no buttons are pressed */
else if (buttons & SW3) buttons=SW3; /* the "right mouse" button was pressed, so send down event */
else if (prox) buttons=SW1; /* the "left mouse" button was pressed and we are not hovering, so send down event */
- else buttons=0; /* We are in hover mode, so no buttons */
- }
- else { /* the active pen's buttons map directly to the mouse buttons */
- if (!prox) buttons=0; /* We are in hover mode, so no buttons */
+ else buttons=0; /* We are in hover mode, so not left-clicking. */
}
+ /* the active pen's buttons map directly to the mouse buttons. Right-click may happen even in hover mode. */
/* DBG(2, ErrorF("%02d/%02d Prox=%d SW:%x Buttons:%x->%x (%d, %d)\n",
loop,priv->fpitIndex,prox,priv->fpitData[loop]&BUTTON_BITS,priv->fpitOldButtons,buttons,x,y));*/
@@ -351,8 +417,6 @@ static Bool xf86FpitControl(DeviceIntPtr dev, int mode)
if (priv->screen_no >= screenInfo.numScreens || priv->screen_no < 0) {
priv->screen_no = 0;
}
- priv->screen_width = screenInfo.screens[priv->screen_no]->width;
- priv->screen_height = screenInfo.screens[priv->screen_no]->height;
/*
* Device reports button press for up to 3 buttons.
*/
@@ -370,22 +434,11 @@ static Bool xf86FpitControl(DeviceIntPtr dev, int mode)
ErrorF("Unable to allocate PtrFeedBackClassDeviceStruct\n");
}
- /*
- * Device reports motions on 2 axes in absolute coordinates.
- * Axes min and max values are reported in raw coordinates.
- * Resolution is computed roughly by the difference between
- * max and min values scaled from the approximate size of the
- * screen to fit one meter.
- */
if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents, local->history_size, Absolute) == FALSE) {
- ErrorF("Unable to allocate Elographics touchscreen ValuatorClassDeviceStruct\n");
+ ErrorF("Unable to allocate Fpit touchscreen ValuatorClassDeviceStruct\n");
return !Success;
- } else {
- InitValuatorAxisStruct(dev, 0, priv->fpitMinX, priv->fpitMaxX, 9500, 0 /* min_res */ ,
- 9500 /* max_res */ );
- InitValuatorAxisStruct(dev, 1, priv->fpitMinY, priv->fpitMaxY, 10500, 0 /* min_res */ ,
- 10500 /* max_res */ );
}
+ xf86FpitSetUpAxes(dev, priv);
if (InitFocusClassDeviceStruct(dev) == FALSE) {
ErrorF("Unable to allocate Fpit touchscreen FocusClassDeviceStruct\n");
@@ -468,6 +521,7 @@ static LocalDevicePtr xf86FpitAllocate(InputDriverPtr drv)
priv->screen_no = 0;
priv->screen_width = -1;
priv->screen_height = -1;
+ priv->screen_rotation = RR_Rotate_0;
priv->fpitMinX = FPIT_MIN_X;
priv->fpitMaxX = FPIT_MAX_X;
priv->fpitMinY = FPIT_MIN_Y;
@@ -476,7 +530,6 @@ static LocalDevicePtr xf86FpitAllocate(InputDriverPtr drv)
priv->fpitOldButtons = 0;
priv->fpitOldProximity = 0;
priv->fpitIndex = 0;
- priv->fpitSwapXY = 0;
priv->fpitPassive = 0;
local->name = XI_TOUCHSCREEN;
local->flags = 0 /* XI86_NO_OPEN_ON_INIT */ ;
@@ -542,37 +595,41 @@ static InputInfoPtr xf86FpitInit(InputDriverPtr drv, IDevPtr dev, int flags)
xf86Msg(X_CONFIG, "FPIT device name: %s\n", local->name);
priv->screen_no = xf86SetIntOption(local->options, "ScreenNo", 0);
xf86Msg(X_CONFIG, "Fpit associated screen: %d\n", priv->screen_no);
- priv->fpitMaxX = xf86SetIntOption(local->options, "MaximumXPosition", 4100);
+ priv->fpitMaxX = xf86SetIntOption(local->options, "MaximumXPosition", FPIT_MAX_X);
xf86Msg(X_CONFIG, "FPIT maximum x position: %d\n", priv->fpitMaxX);
- priv->fpitMinX = xf86SetIntOption(local->options, "MinimumXPosition", 0);
+ priv->fpitMinX = xf86SetIntOption(local->options, "MinimumXPosition", FPIT_MIN_X);
xf86Msg(X_CONFIG, "FPIT minimum x position: %d\n", priv->fpitMinX);
- priv->fpitMaxY = xf86SetIntOption(local->options, "MaximumYPosition", 4100);
+ priv->fpitMaxY = xf86SetIntOption(local->options, "MaximumYPosition", FPIT_MAX_Y);
xf86Msg(X_CONFIG, "FPIT maximum y position: %d\n", priv->fpitMaxY);
- priv->fpitMinY = xf86SetIntOption(local->options, "MinimumYPosition", 0);
+ priv->fpitMinY = xf86SetIntOption(local->options, "MinimumYPosition", FPIT_MIN_Y);
xf86Msg(X_CONFIG, "FPIT minimum y position: %d\n", priv->fpitMinY);
- priv->fpitInvX = xf86SetBoolOption(local->options, "InvertX", 0);
- priv->fpitInvY = xf86SetBoolOption(local->options, "InvertY", 0);
- priv->fpitSwapXY = xf86SetBoolOption(local->options, "SwapXY", 0);
+
+ priv->fpitBaseOrientation = 0;
+ if (xf86SetBoolOption(local->options, "InvertX", 0))
+ priv->fpitBaseOrientation |= FPIT_INVERT_X;
+ if (xf86SetBoolOption(local->options, "InvertY", 0))
+ priv->fpitBaseOrientation |= FPIT_INVERT_Y;
+ if (xf86SetBoolOption(local->options, "SwapXY", 0))
+ priv->fpitBaseOrientation |= FPIT_THEN_SWAP_XY;
priv->fpitPassive = xf86SetBoolOption(local->options, "Passive", 0);
+ priv->fpitTrackRandR = xf86SetBoolOption(local->options, "TrackRandR", 0);
+ /* XXX "Rotate" option provides compatibly stupid behavior. JEB. */
str = xf86SetStrOption(local->options, "Rotate", 0);
- if (!xf86NameCmp(str, "CW")) {
- priv->fpitInvX = 1;
- priv->fpitInvY = 1;
- priv->fpitSwapXY = 1;
- } else if (!xf86NameCmp(str, "CCW")) {
- priv->fpitInvX = 0;
- priv->fpitInvY = 0;
- priv->fpitSwapXY = 1;
- }
- xf86Msg(X_CONFIG, "FPIT invert X axis: %s\n", priv->fpitInvX ? "Yes" : "No");
- xf86Msg(X_CONFIG, "FPIT invert Y axis: %s\n", priv->fpitInvY ? "Yes" : "No");
- xf86Msg(X_CONFIG, "FPIT swap X and Y axis: %s\n", priv->fpitSwapXY ? "Yes" : "No");
+ if (!xf86NameCmp(str, "CW"))
+ priv->fpitBaseOrientation |= FPIT_INVERT_X | FPIT_INVERT_Y | FPIT_THEN_SWAP_XY;
+ else if (!xf86NameCmp(str, "CCW"))
+ priv->fpitBaseOrientation |= FPIT_THEN_SWAP_XY;
+ xf86Msg(X_CONFIG, "FPIT invert X axis: %s\n", priv->fpitBaseOrientation & FPIT_INVERT_X ? "Yes" : "No");
+ xf86Msg(X_CONFIG, "FPIT invert Y axis: %s\n", priv->fpitBaseOrientation & FPIT_INVERT_Y ? "Yes" : "No");
+ xf86Msg(X_CONFIG, "FPIT swap X and Y axis: %s\n", priv->fpitBaseOrientation & FPIT_THEN_SWAP_XY ? "Yes" : "No");
xf86Msg(X_CONFIG, "FPIT Passive button mode: %s\n", priv->fpitPassive ? "Yes" : "No");
+ xf86Msg(X_CONFIG, "FPIT RandR tracking: %s\n", priv->fpitTrackRandR ? "Yes" : "No");
/* mark the device configured */
local->flags |= XI86_CONFIGURED;
return local;
}
+
_X_EXPORT InputDriverRec FPIT = {
1, /* driver version */
"fpit", /* driver name */
@@ -595,7 +652,15 @@ static void Unplug(pointer p)
}
static XF86ModuleVersionInfo version_rec = {
- "fpit", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, 1, 1, 0, ABI_CLASS_XINPUT, ABI_XINPUT_VERSION, MOD_CLASS_XINPUT,
+ "fpit",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
{0, 0, 0, 0}
};