📄 touchserial.c
字号:
case MINX:
if (xf86GetToken(NULL) != NUMBER) {
xf86ConfigError("Elographics minimum x position expected");
}
priv->min_x = val->num;
if (xf86Verbose) {
ErrorF("%s Elographics minimum x position: %d\n",
XCONFIG_GIVEN, priv->min_x);
}
break;
case MINY:
if (xf86GetToken(NULL) != NUMBER) {
xf86ConfigError("Elographics minimum y position expected");
}
priv->min_y = val->num;
if (xf86Verbose) {
ErrorF("%s Elographics minimum y position: %d\n",
XCONFIG_GIVEN, priv->min_y);
}
break;
case DEBUG_LEVEL:
if (xf86GetToken(NULL) != NUMBER) {
xf86ConfigError("Elographics driver debug level expected");
}
debug_level = val->num;
if (xf86Verbose) {
#if DEBUG
ErrorF("%s Elographics debug level sets to %d\n", XCONFIG_GIVEN,
debug_level);
#else
ErrorF("%s Elographics debug not available\n",
XCONFIG_GIVEN, debug_level);
#endif
}
break;
case HISTORY_SIZE:
if (xf86GetToken(NULL) != NUMBER) {
xf86ConfigError("Elographics motion history size expected");
}
local->history_size = val->num;
if (xf86Verbose) {
ErrorF("%s EloGraphics motion history size is %d\n", XCONFIG_GIVEN,
local->history_size);
}
break;
case ALWAYS_CORE:
xf86AlwaysCore(local, TRUE);
if (xf86Verbose) {
ErrorF("%s Elographics device will always stays core pointer\n",
XCONFIG_GIVEN);
}
break;
case SWAP_AXES:
priv->swap_axes = 1;
if (xf86Verbose) {
ErrorF("%s Elographics device will work with X and Y axes swapped\n",
XCONFIG_GIVEN);
}
break;
case PORTRAIT_MODE:
if (xf86GetToken(NULL) != STRING) {
portrait_mode_err:
xf86ConfigError("Elographics portrait mode should be: Portrait, Landscape or PortraitCCW");
}
if (strcmp(val->str, "portrait") == 0) {
portrait = 1;
}
else if (strcmp(val->str, "portraitccw") == 0) {
portrait = -1;
}
else if (strcmp(val->str, "landscape") != 0) {
goto portrait_mode_err;
}
if (xf86Verbose) {
ErrorF("%s Elographics device will work in %s mode\n",
XCONFIG_GIVEN, val->str);
}
break;
case EOF:
FatalError("Unexpected EOF (missing EndSubSection)");
break;
default:
xf86ConfigError("Elographics subsection keyword expected");
break;
}
}
if (priv->max_x - priv->min_x <= 0) {
ErrorF("%s Elographics: reverse x mode (minimum x position >= maximum x position)\n",
XCONFIG_GIVEN);
}
if (priv->max_y - priv->min_y <= 0) {
ErrorF("%s Elographics: reverse y mode (minimum y position >= maximum y position)\n",
XCONFIG_GIVEN);
}
/*
* The portrait adjustments need to be done after axis reversing
* and axes swap. This way the driver can cope with deffective
* hardware and still do the correct processing depending on the
* actual display orientation.
*/
if (portrait == 1) {
/*
* Portrait Clockwise: reverse Y axis and exchange X and Y.
*/
int tmp;
tmp = priv->min_y;
priv->min_y = priv->max_y;
priv->max_y = tmp;
priv->swap_axes = (priv->swap_axes==0) ? 1 : 0;
}
else if (portrait == -1) {
/*
* Portrait Counter Clockwise: reverse X axis and exchange X and Y.
*/
int tmp;
tmp = priv->min_x;
priv->min_x = priv->max_x;
priv->max_x = tmp;
priv->swap_axes = (priv->swap_axes==0) ? 1 : 0;
}
DBG(2, ErrorF("xf86EloConfig port name=%s\n", priv->input_dev))
return Success;
}
#endif
#endif
/*
***************************************************************************
*
* xf86EloGetPacket --
* Read a packet from the port. Try to synchronize with start of
* packet and compute checksum.
* The packet structure read by this function is as follow:
* Byte 0 : ELO_SYNC_BYTE
* Byte 1
* ...
* Byte 8 : packet data
* Byte 9 : checksum of bytes 0 to 8
*
* This function returns if a valid packet has been assembled in
* buffer or if no more data is available.
*
* Returns Success if a packet is successfully assembled including
* testing checksum. If a packet checksum is incorrect, it is discarded.
* Bytes preceding the ELO_SYNC_BYTE are also discarded.
* Returns !Success if out of data while reading. The start of the
* partially assembled packet is left in buffer, buffer_p and
* checksum reflect the current state of assembly.
*
***************************************************************************
*/
static Bool
xf86EloGetPacket(unsigned char *buffer,
int *buffer_p,
int *checksum,
int fd)
{
int num_bytes;
Bool ok;
DBG(4, ErrorF("Entering xf86EloGetPacket with checksum == %d and buffer_p == %d\n",
*checksum, *buffer_p));
/*
* Try to read enough bytes to fill up the packet buffer.
*/
DBG(4, ErrorF("buffer_p is %d, Trying to read %d bytes from link\n",
*buffer_p, ELO_PACKET_SIZE - *buffer_p));
SYSCALL(num_bytes = read(fd,
(char *) (buffer + *buffer_p),
ELO_PACKET_SIZE - *buffer_p));
/*
* Okay, give up.
*/
if (num_bytes < 0) {
Error("System error while reading from Elographics touchscreen.");
return !Success;
}
DBG(4, ErrorF("Read %d bytes\n", num_bytes));
while (num_bytes) {
/*
* Sync with the start of a packet.
*/
if ((*buffer_p == 0) && (buffer[0] != ELO_SYNC_BYTE)) {
/*
* No match, shift data one byte toward the start of the buffer.
*/
ErrorF("Elographics: Dropping one byte in an attempt to synchronize: '%c' 0x%X\n",
buffer[0], buffer[0]);
memcpy(&buffer[0], &buffer[1], num_bytes-1);
}
else {
/*
* Compute checksum in assembly buffer.
*/
if (*buffer_p < ELO_PACKET_SIZE-1) {
*checksum = *checksum + buffer[*buffer_p];
*checksum = *checksum % 256;
DBG(4, ErrorF(" 0x%X-->0x%X ", buffer[*buffer_p], *checksum));
}
(*buffer_p)++;
}
num_bytes--;
}
if (*buffer_p == ELO_PACKET_SIZE) {
/*
* Got a packet, validate checksum and reset state.
*/
ok = (*checksum == buffer[ELO_PACKET_SIZE-1]);
DBG(3, ErrorF("Expecting checksum %d, got %d\n", *checksum, buffer[ELO_PACKET_SIZE-1]));
*checksum = ELO_INIT_CHECKSUM;
*buffer_p = 0;
if (!ok) {
ErrorF("Checksum error on Elographics touchscreen link\n");
return !Success;
}
/*
* Valid packet received report it.
*/
return Success;
}
else {
return !Success;
}
}
/*
***************************************************************************
*
* xf86EloConvert --
* Convert extended valuators to x and y suitable for core motion
* events. Return True if ok and False if the requested conversion
* can't be done for the specified valuators.
*
***************************************************************************
*/
static Bool
xf86EloConvert(LocalDevicePtr local,
int first,
int num,
int v0,
int v1,
int v2,
int v3,
int v4,
int v5,
int *x,
int *y)
{
EloPrivatePtr priv = (EloPrivatePtr) local->private;
int width = priv->max_x - priv->min_x;
int height = priv->max_y - priv->min_y;
int input_x, input_y;
if (first != 0 || num != 2) {
return FALSE;
}
DBG(3, ErrorF("EloConvert: v0(%d), v1(%d)\n", v0, v1));
if (priv->swap_axes) {
input_x = v1;
input_y = v0;
}
else {
input_x = v0;
input_y = v1;
}
*x = (priv->screen_width * (input_x - priv->min_x)) / width;
*y = (priv->screen_height -
(priv->screen_height * (input_y - priv->min_y)) / height);
#ifdef XFREE86_V4
/*
* Need to check if still on the correct screen.
* This call is here so that this work can be done after
* calib and before posting the event.
*/
xf86XInputSetScreen(local, priv->screen_no, *x, *y);
#endif
DBG(3, ErrorF("EloConvert: x(%d), y(%d)\n", *x, *y));
return TRUE;
}
/*
***************************************************************************
*
* xf86EloReadInput --
* Read all pending report packets from the touchscreen and enqueue
* them.
* If a packet is not fully received it is deferred until the next
* call to the function.
* Packets recognized by this function comply with the format:
*
* Byte 1 : ELO_TOUCH
* Byte 2 : Packet type
* Bit 2 : Pen Up (Release)
* Bit 1 : Position (Stream)
* Bit 0 : Pen Down (Press)
* Byte 3 : X coordinate (lower bits)
* Byte 4 : X coordinate (upper bits)
* Byte 5 : Y coordinate (lower bits)
* Byte 6 : Y coordinate (upper bits)
* Byte 7 : Z coordinate (lower bits)
* Byte 8 : Z coordinates (upper bits)
*
*
***************************************************************************
*/
static void
xf86EloReadInput(LocalDevicePtr local)
{
EloPrivatePtr priv = (EloPrivatePtr)(local->private);
int cur_x, cur_y;
int state;
DBG(4, ErrorF("Entering ReadInput\n"));
/*
* Try to get a packet.
*/
if (xf86EloGetPacket(priv->packet_buf,
&priv->packet_buf_p,
&priv->checksum,
local->fd) != Success) {
return;
}
/*
* Process only ELO_TOUCHs here.
*/
if (priv->packet_buf[1] == ELO_TOUCH) {
/*
* First stick together the various pieces.
*/
cur_x = WORD_ASSEMBLY(priv->packet_buf[3], priv->packet_buf[4]);
cur_y = WORD_ASSEMBLY(priv->packet_buf[5], priv->packet_buf[6]);
state = priv->packet_buf[2] & 0x07;
/*
* Send events.
*
* We *must* generate a motion before a button change if pointer
* location has changed as DIX assumes this. This is why we always
* emit a motion, regardless of the kind of packet processed.
*/
xf86PostMotionEvent(local->dev, TRUE, 0, 2, cur_x, cur_y);
/*
* Emit a button press or release.
*/
if (state == ELO_PRESS || state == ELO_RELEASE) {
xf86PostButtonEvent(local->dev, TRUE, 1, state == ELO_PRESS, 0, 2, cur_x, cur_y);
}
DBG(3, ErrorF("TouchScreen: x(%d), y(%d), %s\n",
cur_x, cur_y,
(state == ELO_PRESS) ? "Press" : ((state == ELO_RELEASE) ? "Release" : "Stream")));
}
}
/*
***************************************************************************
*
* xf86EloSendPacket --
* Emit an height bytes packet to the controller.
* The function expects a valid buffer containing the
* command to be sent to the controller. It fills it with the
* leading sync character an the trailing checksum byte.
*
***************************************************************************
*/
static Bool
xf86EloSendPacket(unsigned char *packet,
int fd)
{
int i, result;
int sum = ELO_INIT_CHECKSUM;
packet[0] = ELO_SYNC_BYTE;
for (i = 0; i < ELO_PACKET_SIZE-1; i++) {
sum += packet[i];
sum &= 0xFF;
}
packet[ELO_PACKET_SIZE-1] = sum;
DBG(4, ErrorF("Sending packet : 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X \n",
packet[0], packet[1], packet[2], packet[3], packet[4],
packet[5], packet[6], packet[7], packet[8], packet[9]));
SYSCALL(result = write(fd, packet, ELO_PACKET_SIZE));
if (result != ELO_PACKET_SIZE) {
DBG(5, ErrorF("System error while sending to Elographics touchscreen.\n"));
return !Success;
}
else {
return Success;
}
}
/*
***************************************************************************
*
* xf86EloWaitReply --
* It is assumed that the reply will be in the few next bytes
* read and will be available very soon after the query post. if
* these two asumptions are not met, there are chances that the server
* will be stuck for a while.
* The reply type need to match parameter 'type'.
* The reply is left in reply. The function returns Success if the
* reply is valid and !Success otherwise.
*
***************************************************************************
*/
#ifndef XFREE86_V4
static int
xf86WaitForInput(int fd,
int timeout)
{
fd_set readfds;
struct timeval to;
int r;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
to.tv_sec = 0;
to.tv_usec = timeout;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -