📄 touchserial.c
字号:
SYSCALL(r = select(FD_SETSIZE, &readfds, NULL, NULL, &to));
return r;
}
#endif
static Bool
xf86EloWaitReply(unsigned char type,
unsigned char *reply,
int fd)
{
Bool ok;
int i, result;
int reply_p = 0;
int sum = ELO_INIT_CHECKSUM;
DBG(4, ErrorF("Waiting a '%c' reply\n", type));
i = ELO_MAX_TRIALS;
do {
ok = !Success;
/*
* Wait half a second for the reply. The fuse counts down each
* timeout and each wrong packet.
*/
DBG(4, ErrorF("Waiting %d ms for data from port\n", ELO_MAX_WAIT / 1000));
result = xf86WaitForInput(fd, ELO_MAX_WAIT);
if (result > 0) {
ok = xf86EloGetPacket(reply, &reply_p, &sum, fd);
/*
* Do not report an error on a 'P' query as the controller
* might be a 2310.
*/
if (ok == Success && reply[1] != type && type != ELO_PARAMETER) {
DBG(3, ErrorF("Wrong reply received\n"));
ok = !Success;
}
}
else {
DBG(3, ErrorF("No answer from link : %d\n", result));
}
if (result == 0) {
i--;
}
} while(ok != Success && i);
return ok;
}
/*
***************************************************************************
*
* xf86EloWaitAck --
* Wait for an acknowledge from the controller. Returns Success if
* acknowledge received and reported no errors.
*
***************************************************************************
*/
static Bool
xf86EloWaitAck(int fd)
{
unsigned char packet[ELO_PACKET_SIZE];
int i, nb_errors;
if (xf86EloWaitReply(ELO_ACK, packet, fd) == Success) {
for (i = 0, nb_errors = 0; i < 4; i++) {
if (packet[2 + i] != '0') {
nb_errors++;
}
}
if (nb_errors != 0) {
DBG(2, ErrorF("Elographics acknowledge packet reports %d errors\n",
nb_errors));
}
return Success;
/* return (nb_errors < 4) ? Success : !Success;*/
}
else {
return !Success;
}
}
/*
***************************************************************************
*
* xf86EloSendQuery --
* Emit a query to the controller and blocks until the reply and
* the acknowledge are read.
*
* The reply is left in reply. The function returns Success if the
* reply is valid and !Success otherwise.
*
***************************************************************************
*/
static Bool
xf86EloSendQuery(unsigned char *request,
unsigned char *reply,
int fd)
{
Bool ok;
if (xf86EloSendPacket(request, fd) == Success) {
ok = xf86EloWaitReply(toupper(request[1]), reply, fd);
if (ok == Success) {
ok = xf86EloWaitAck(fd);
}
return ok;
}
else {
return !Success;
}
}
/*
***************************************************************************
*
* xf86EloSendControl --
* Emit a control command to the controller and wait for acknowledge.
*
* Returns Success if acknowledge received and reported no error.
*
***************************************************************************
*/
static Bool
xf86EloSendControl(unsigned char *control,
int fd)
{
if (xf86EloSendPacket(control, fd) == Success) {
return xf86EloWaitAck(fd);
}
else {
return !Success;
}
}
/*
***************************************************************************
*
* xf86EloPrintIdent --
* Print type of touchscreen and features on controller board.
*
***************************************************************************
*/
static void
xf86EloPrintIdent(unsigned char *packet,
EloPrivatePtr priv)
{
#ifdef XFREE86_V4
xf86Msg(X_PROBED, "Elographics touchscreen is a ");
switch(packet[2]) {
case '0':
xf86Msg(X_NONE, "AccuTouch");
break;
case '1':
xf86Msg(X_NONE, "DuraTouch");
break;
case '2':
xf86Msg(X_NONE, "Intellitouch");
break;
}
xf86Msg(X_NONE, ", connected through a ");
switch(packet[3]) {
case '0':
xf86Msg(X_NONE, "serial link.\n");
break;
case '1':
xf86Msg(X_NONE, "PC-Bus port.\n");
break;
case '2':
xf86Msg(X_NONE, "Micro Channel port.\n");
break;
}
xf86Msg(X_PROBED, "The controller is a model ");
if (packet[8] & 1) {
if (priv->is_a_2310) {
xf86Msg(X_NONE, "E281-2310");
}
else {
xf86Msg(X_NONE, "E271-2210");
}
}
else {
xf86Msg(X_NONE, "E271-2200");
}
xf86Msg(X_NONE, ", firmware revision %d.%d.\n", packet[6], packet[5]);
if (packet[4]) {
xf86Msg(X_PROBED, " Additional features:\n");
if (packet[4] & 0x10) {
xf86Msg(X_PROBED, " External A/D converter\n");
}
if (packet[4] & 0x20) {
xf86Msg(X_PROBED, " 32Ko RAM\n");
}
if (packet[4] & 0x40) {
xf86Msg(X_PROBED, " RAM onboard\n");
}
if (packet[4] & 0x80) {
xf86Msg(X_PROBED, " Z axis active\n");
}
xf86Msg(X_NONE, "\n");
}
#else
ErrorF("%s Elographics touchscreen is a ", XCONFIG_PROBED);
switch(packet[2]) {
case '0':
ErrorF("AccuTouch");
break;
case '1':
ErrorF("DuraTouch");
break;
case '2':
ErrorF("Intellitouch");
break;
}
ErrorF(", connected through a ");
switch(packet[3]) {
case '0':
ErrorF("serial link.\n");
break;
case '1':
ErrorF("PC-Bus port.\n");
break;
case '2':
ErrorF("Micro Channel port.\n");
break;
}
ErrorF("%s The controller is a model ", XCONFIG_PROBED);
if (packet[8] & 1) {
if (priv->is_a_2310) {
ErrorF("E281-2310");
}
else {
ErrorF("E271-2210");
}
}
else {
ErrorF("E271-2200");
}
ErrorF(", firmware revision %d.%d.\n", packet[6], packet[5]);
if (packet[4]) {
ErrorF("%s Additional features:\n", XCONFIG_PROBED);
if (packet[4] & 0x10) {
ErrorF("%s External A/D converter\n", XCONFIG_PROBED);
}
if (packet[4] & 0x20) {
ErrorF("%s 32Ko RAM\n", XCONFIG_PROBED);
}
if (packet[4] & 0x40) {
ErrorF("%s RAM onboard\n", XCONFIG_PROBED);
}
if (packet[4] & 0x80) {
ErrorF("%s Z axis active\n", XCONFIG_PROBED);
}
ErrorF("\n");
}
#endif
}
/*
***************************************************************************
*
* xf86EloPtrControl --
*
***************************************************************************
*/
#if 0
static void
xf86EloPtrControl(DeviceIntPtr dev,
PtrCtrl *ctrl)
{
}
#endif
/*
***************************************************************************
*
* xf86EloControl --
*
***************************************************************************
*/
static Bool
xf86EloControl(DeviceIntPtr dev,
int mode)
{
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
EloPrivatePtr priv = (EloPrivatePtr)(local->private);
unsigned char map[] = { 0, 1 };
unsigned char req[ELO_PACKET_SIZE];
unsigned char reply[ELO_PACKET_SIZE];
switch(mode) {
case DEVICE_INIT:
{
#if defined(sun) && !defined(i386)
char *name = (char *) getenv("ELO_DEV");
char *calib = (char *) getenv("ELO_CALIB");
char *speed = (char *) getenv("ELO_SPEED");
char *delays = (char *) getenv("ELO_DELAYS");
#endif
DBG(2, ErrorF("Elographics touchscreen init...\n"));
#if defined(sun) && !defined(i386)
if (name) {
priv->input_dev = strdup(name);
ErrorF("Elographics touchscreen port changed to '%s'\n",
priv->input_dev);
}
if (calib) {
if (sscanf(calib, "%d %d %d %d",
&priv->min_x, &priv->max_x,
&priv->min_y, &priv->max_y) != 4) {
ErrorF("Incorrect syntax in ELO_CALIB\n");
return !Success;
}
else if (priv->max_x <= priv->min_x ||
priv->max_y <= priv->min_y) {
ErrorF("Bogus calibration data in ELO_CALIB\n");
return !Success;
}
else {
ErrorF("Calibration will be done with:\n");
ErrorF("x_min=%d, x_max=%d, y_min=%d, y_max=%d\n",
priv->min_x, priv->max_x, priv->min_y, priv->max_y);
}
}
if (speed) {
/* These tests should be kept in sync with the LinkSpeedValues
* array. */
if (strcmp(speed, "B9600") == 0) {
priv->link_speed = B9600;
}
else if (strcmp(speed, "B19200") == 0) {
priv->link_speed = B19200;
}
else if (strcmp(speed, "B2400") == 0) {
priv->link_speed = B2400;
}
else if (strcmp(speed, "B1200") == 0) {
priv->link_speed = B1200;
}
else if (strcmp(speed, "B300") == 0) {
priv->link_speed = B300;
}
else {
ErrorF("Bogus speed value in ELO_SPEED\n");
return !Success;
}
}
if (delays) {
if (sscanf(delays, "%d %d",
&priv->untouch_delay,
&priv->report_delay) != 2) {
ErrorF("Bogus delays data in ELO_DELAYS\n");
}
else {
ErrorF("Untouch delay will be: %d\n", priv->untouch_delay);
ErrorF("Report delay will be: %d\n", priv->report_delay);
}
}
#endif
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 1 button.
*/
if (InitButtonClassDeviceStruct(dev, 1, map) == FALSE) {
ErrorF("Unable to allocate Elographics touchscreen ButtonClassDeviceStruct\n");
return !Success;
}
if (InitFocusClassDeviceStruct(dev) == FALSE) {
ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n");
return !Success;
}
/*
* 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");
return !Success;
}
else {
InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x,
9500,
0 /* min_res */,
9500 /* max_res */);
InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y,
10500,
0 /* min_res */,
10500 /* max_res */);
}
if (InitFocusClassDeviceStruct(dev) == FALSE) {
ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n");
}
/*
* Allocate the motion events buffer.
*/
xf86MotionHistoryAllocate(local);
/*
* This once has caused the server to crash after doing an xalloc & strcpy ??
*/
#ifndef XFREE86_V4
AssignTypeAndName(dev, local->atom, local->name);
#endif
DBG(2, ErrorF("Done.\n"));
return Success;
}
case DEVICE_ON:
DBG(2, ErrorF("Elographics touchscreen on...\n"));
if (local->fd < 0) {
#ifndef XFREE86_V4
struct termios termios_tty;
int i, result;
#endif
DBG(2, ErrorF("Elographics touchscreen opening : %s\n", priv->input_dev));
#ifdef XFREE86_V4
local->fd = xf86OpenSerial(local->options);
if (local->fd < 0) {
Error("Unable to open Elographics touchscreen device");
return !Success;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -