⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 touchserial.c

📁 Linux下触摸屏的驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
      
    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 + -