|
|
# include <xf86_OSproc.h> | # include <xf86_OSproc.h> |
# include <xf86Xinput.h> | # include <xf86Xinput.h> |
# include <exevents.h> | # include <exevents.h> |
|
# include <randrstr.h> |
| |
# include <xf86Module.h> | # include <xf86Module.h> |
| |
|
|
/* | /* |
*************************************************************************** | *************************************************************************** |
* | * |
|
* Screen orientation descriptors. |
|
* |
|
*************************************************************************** |
|
*/ |
|
|
|
typedef enum { |
|
FPIT_INVERT_X = 0x01, |
|
FPIT_INVERT_Y = 0x02, |
|
FPIT_THEN_SWAP_XY = 0x04 |
|
} FpitOrientation; |
|
|
|
/* |
|
*************************************************************************** |
|
* |
* Device private records. | * Device private records. |
* | * |
*************************************************************************** | *************************************************************************** |
|
|
char *fpitDev; /* device file name */ | char *fpitDev; /* device file name */ |
int screen_width; | int screen_width; |
int screen_height; | int screen_height; |
|
Rotation screen_rotation; |
int screen_no; | int screen_no; |
int fpitOldX; /* previous X position */ | int fpitOldX; /* previous X position */ |
int fpitOldY; /* previous Y position */ | int fpitOldY; /* previous Y position */ |
|
|
int fpitMinY; /* min Y value */ | int fpitMinY; /* min Y value */ |
int fpitMaxX; /* max X value */ | int fpitMaxX; /* max X value */ |
int fpitMaxY; /* max Y value */ | int fpitMaxY; /* max Y value */ |
int fpitInvX; /* Invert X axis */ |
|
int fpitInvY; /* Invert Y axis */ |
|
int fpitIndex; /* number of bytes read */ | int fpitIndex; /* number of bytes read */ |
unsigned char fpitData[BUFFER_SIZE]; /* data read on the 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 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; | } FpitPrivateRec, *FpitPrivatePtr; |
| |
| |
|
|
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) | 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; | FpitPrivatePtr priv = (FpitPrivatePtr) local->private; |
|
AxisInfoPtr axes = local->dev->valuator->axes; |
if (first != 0 || num != 2) { | if (first != 0 || num != 2) { |
return FALSE; | return FALSE; |
} | } |
| |
if (priv->fpitSwapXY != 0) { |
*x = xf86ScaleAxis(v0, 0, priv->screen_width, axes[0].min_value, axes[0].max_value); |
*x = xf86ScaleAxis(v1, 0, priv->screen_width, priv->fpitMinY, priv->fpitMaxY); |
*y = xf86ScaleAxis(v1, 0, priv->screen_height, axes[1].min_value, axes[1].max_value); |
*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); |
|
} |
|
return TRUE; | 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 | ** xf86FpitReadInput |
** Reads from the Fpit and posts any new events to the server. | ** Reads from the Fpit and posts any new events to the server. |
*/ | */ |
|
Lines 166-171
static void xf86FpitReadInput(LocalDevic
|
Link Here
|
|---|
|
DeviceIntPtr device; | DeviceIntPtr device; |
int conv_x, conv_y; | 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 */ | do { /* keep reading blocks until there are no more */ |
| |
/* Read data into buffer */ | /* Read data into buffer */ |
|
Lines 230-240
static void xf86FpitReadInput(LocalDevic
|
Link Here
|
|---|
|
| |
x = (int) (priv->fpitData[loop + 1] & 0x7f) + ((int) (priv->fpitData[loop + 2] & 0x7f) << 7); | 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); | y = (int) (priv->fpitData[loop + 3] & 0x7f) + ((int) (priv->fpitData[loop + 4] & 0x7f) << 7); |
/* Add in any offsets */ |
/* Adjust to orientation */ |
if (priv->fpitInvX) |
if (priv->fpitTotalOrientation & FPIT_INVERT_X) |
x = priv->fpitMaxX - x + priv->fpitMinX; | x = priv->fpitMaxX - x + priv->fpitMinX; |
if (priv->fpitInvY) |
if (priv->fpitTotalOrientation & FPIT_INVERT_Y) |
y = priv->fpitMaxY - y + priv->fpitMinY; | 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; | prox = (priv->fpitData[loop] & PROXIMITY_BIT) ? 0 : 1; |
buttons = (priv->fpitData[loop] & BUTTON_BITS); | buttons = (priv->fpitData[loop] & BUTTON_BITS); |
device = local->dev; | device = local->dev; |
|
Lines 334-341
static Bool xf86FpitControl(DeviceIntPtr
|
Link Here
|
|---|
|
if (priv->screen_no >= screenInfo.numScreens || priv->screen_no < 0) { | if (priv->screen_no >= screenInfo.numScreens || priv->screen_no < 0) { |
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. | * Device reports button press for up to 3 buttons. |
*/ | */ |
|
Lines 353-374
static Bool xf86FpitControl(DeviceIntPtr
|
Link Here
|
|---|
|
ErrorF("Unable to allocate PtrFeedBackClassDeviceStruct\n"); | 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) { | if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents, local->history_size, Absolute) == FALSE) { |
ErrorF("Unable to allocate Fpit touchscreen ValuatorClassDeviceStruct\n"); | ErrorF("Unable to allocate Fpit touchscreen ValuatorClassDeviceStruct\n"); |
return !Success; | 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) { | if (InitFocusClassDeviceStruct(dev) == FALSE) { |
ErrorF("Unable to allocate Fpit touchscreen FocusClassDeviceStruct\n"); | ErrorF("Unable to allocate Fpit touchscreen FocusClassDeviceStruct\n"); |
|
Lines 451-456
static LocalDevicePtr xf86FpitAllocate(I
|
Link Here
|
|---|
|
priv->screen_no = 0; | priv->screen_no = 0; |
priv->screen_width = -1; | priv->screen_width = -1; |
priv->screen_height = -1; | priv->screen_height = -1; |
|
priv->screen_rotation = RR_Rotate_0; |
priv->fpitMinX = FPIT_MIN_X; | priv->fpitMinX = FPIT_MIN_X; |
priv->fpitMaxX = FPIT_MAX_X; | priv->fpitMaxX = FPIT_MAX_X; |
priv->fpitMinY = FPIT_MIN_Y; | priv->fpitMinY = FPIT_MIN_Y; |
|
Lines 459-465
static LocalDevicePtr xf86FpitAllocate(I
|
Link Here
|
|---|
|
priv->fpitOldButtons = 0; | priv->fpitOldButtons = 0; |
priv->fpitOldProximity = 0; | priv->fpitOldProximity = 0; |
priv->fpitIndex = 0; | priv->fpitIndex = 0; |
priv->fpitSwapXY = 0; |
|
priv->fpitPassive = 0; | priv->fpitPassive = 0; |
local->name = XI_TOUCHSCREEN; | local->name = XI_TOUCHSCREEN; |
local->flags = 0 /* XI86_NO_OPEN_ON_INIT */ ; | local->flags = 0 /* XI86_NO_OPEN_ON_INIT */ ; |
|
Lines 533-561
static InputInfoPtr xf86FpitInit(InputDr
|
Link Here
|
|---|
|
xf86Msg(X_CONFIG, "FPIT maximum y position: %d\n", priv->fpitMaxY); | xf86Msg(X_CONFIG, "FPIT maximum y position: %d\n", priv->fpitMaxY); |
priv->fpitMinY = xf86SetIntOption(local->options, "MinimumYPosition", FPIT_MIN_Y); | priv->fpitMinY = xf86SetIntOption(local->options, "MinimumYPosition", FPIT_MIN_Y); |
xf86Msg(X_CONFIG, "FPIT minimum y position: %d\n", priv->fpitMinY); | 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->fpitBaseOrientation = 0; |
priv->fpitSwapXY = xf86SetBoolOption(local->options, "SwapXY", 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->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); | str = xf86SetStrOption(local->options, "Rotate", 0); |
if (!xf86NameCmp(str, "CW")) { |
if (!xf86NameCmp(str, "CW")) |
priv->fpitInvX = 1; |
priv->fpitBaseOrientation |= FPIT_INVERT_X | FPIT_INVERT_Y | FPIT_THEN_SWAP_XY; |
priv->fpitInvY = 1; |
else if (!xf86NameCmp(str, "CCW")) |
priv->fpitSwapXY = 1; |
priv->fpitBaseOrientation |= FPIT_THEN_SWAP_XY; |
} else if (!xf86NameCmp(str, "CCW")) { |
xf86Msg(X_CONFIG, "FPIT invert X axis: %s\n", priv->fpitBaseOrientation & FPIT_INVERT_X ? "Yes" : "No"); |
priv->fpitInvX = 0; |
xf86Msg(X_CONFIG, "FPIT invert Y axis: %s\n", priv->fpitBaseOrientation & FPIT_INVERT_Y ? "Yes" : "No"); |
priv->fpitInvY = 0; |
xf86Msg(X_CONFIG, "FPIT swap X and Y axis: %s\n", priv->fpitBaseOrientation & FPIT_THEN_SWAP_XY ? "Yes" : "No"); |
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"); |
|
xf86Msg(X_CONFIG, "FPIT Passive button mode: %s\n", priv->fpitPassive ? "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 */ | /* mark the device configured */ |
local->flags |= XI86_CONFIGURED; | local->flags |= XI86_CONFIGURED; |
return local; | return local; |
} | } |
| |
|
|
_X_EXPORT InputDriverRec FPIT = { | _X_EXPORT InputDriverRec FPIT = { |
1, /* driver version */ | 1, /* driver version */ |
"fpit", /* driver name */ | "fpit", /* driver name */ |