This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new face051  touchscreen: update sim_touchscreen, using touch_upperhalf
face051 is described below

commit face0514b696221b5d7fc4fd1c7179c9fa62f183
Author: yinshengkai <yinsheng...@xiaomi.com>
AuthorDate: Wed Nov 10 22:27:50 2021 +0800

    touchscreen: update sim_touchscreen, using touch_upperhalf
    
    Signed-off-by: yinshengkai <yinsheng...@xiaomi.com>
---
 arch/sim/Kconfig                  |   1 +
 arch/sim/src/sim/up_touchscreen.c | 602 +++-----------------------------------
 2 files changed, 40 insertions(+), 563 deletions(-)

diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig
index 4ef4fc8..115f346 100644
--- a/arch/sim/Kconfig
+++ b/arch/sim/Kconfig
@@ -323,6 +323,7 @@ choice
 
 config SIM_TOUCHSCREEN
        bool "X11 mouse-based touchscreen emulation"
+       select INPUT_TOUCHSCREEN
        depends on SIM_X11FB
        ---help---
                Support an X11 mouse-based touchscreen emulation.  Also needs 
INPUT=y
diff --git a/arch/sim/src/sim/up_touchscreen.c 
b/arch/sim/src/sim/up_touchscreen.c
index 062906b..962a8be 100644
--- a/arch/sim/src/sim/up_touchscreen.c
+++ b/arch/sim/src/sim/up_touchscreen.c
@@ -28,22 +28,10 @@
 
 #include <stdbool.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <string.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <errno.h>
 #include <assert.h>
 #include <debug.h>
 
-#include <nuttx/irq.h>
-#include <nuttx/board.h>
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/semaphore.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/nx/nx.h>
-
 #include <nuttx/input/touchscreen.h>
 
 #include "up_internal.h"
@@ -52,12 +40,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_SIM_TCNWAITERS
-#  define CONFIG_SIM_TCNWAITERS 4
-#endif
-
 /* Driver support ***********************************************************/
 
 /* This format is used to construct the /dev/input[n] device driver path.  It
@@ -71,83 +53,21 @@
  * Private Types
  ****************************************************************************/
 
-/* This describes the state of one contact */
-
-enum up_contact_3
-{
-  CONTACT_NONE = 0,                    /* No contact */
-  CONTACT_DOWN,                        /* First contact */
-  CONTACT_MOVE,                        /* Same contact, possibly different 
position */
-  CONTACT_UP,                          /* Contact lost */
-};
-
-/* This structure describes the results of one touchscreen sample */
-
-struct up_sample_s
-{
-  uint8_t  id;                         /* Sampled touch point ID */
-  uint8_t  contact;                    /* Contact state (see enum 
up_contact_e) */
-  uint16_t x;                          /* Measured X position */
-  uint16_t y;                          /* Measured Y position */
-};
-
 /* This structure describes the state of one touchscreen driver instance */
 
 struct up_dev_s
 {
   int eventloop;
-  volatile uint8_t nwaiters;           /* Number of threads waiting for 
touchscreen data */
   uint8_t id;                          /* Current touch point ID */
+  uint8_t contact;                     /* Last contact state */
   uint8_t minor;                       /* Minor device number */
-  volatile bool penchange;             /* An unreported event is buffered */
-  sem_t devsem;                        /* Manages exclusive access to this 
structure */
-  sem_t waitsem;                       /* Used to wait for the availability of 
data */
-
-  struct up_sample_s sample;           /* Last sampled touch point data */
-
-  /* The following is a list if poll structures of threads waiting for
-   * driver events. The 'struct pollfd' reference for each open is also
-   * retained in the f_priv field of the 'struct file'.
-   */
-
-  struct pollfd *fds[CONFIG_SIM_TCNWAITERS];
+  struct touch_lowerhalf_s lower;      /* Touchsrceen lowerhalf */
 };
 
 /****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static void up_notify(FAR struct up_dev_s *priv);
-static int up_sample(FAR struct up_dev_s *priv,
-                     FAR struct up_sample_s *sample);
-static int up_waitsample(FAR struct up_dev_s *priv,
-                         FAR struct up_sample_s *sample);
-
-/* Character driver methods */
-
-static int up_open(FAR struct file *filep);
-static int up_close(FAR struct file *filep);
-static ssize_t up_read(FAR struct file *filep, FAR char *buffer, size_t len);
-static int up_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-static int up_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
-
-/****************************************************************************
  * Private Data
  ****************************************************************************/
 
-/* This the vtable that supports the character driver interface */
-
-static const struct file_operations up_fops =
-{
-  up_open,    /* open */
-  up_close,   /* close */
-  up_read,    /* read */
-  NULL,       /* write */
-  NULL,       /* seek */
-  up_ioctl,   /* ioctl */
-  up_poll     /* poll */
-};
-
 /* Only one simulated touchscreen is supported so the driver state
  * structure may as well be pre-allocated.
  */
@@ -155,431 +75,6 @@ static const struct file_operations up_fops =
 static struct up_dev_s g_simtouchscreen;
 
 /****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_notify
- ****************************************************************************/
-
-static void up_notify(FAR struct up_dev_s *priv)
-{
-  int i;
-
-  /* If there are threads waiting on poll() for touchscreen data to become
-   * available, then wake them up now.  NOTE: we wake up all waiting threads
-   * because we do not know what they are going to do.  If they all try to
-   * read the data then some make end up blocking after all.
-   */
-
-  for (i = 0; i < CONFIG_SIM_TCNWAITERS; i++)
-    {
-      struct pollfd *fds = priv->fds[i];
-      if (fds)
-        {
-          fds->revents |= POLLIN;
-          iinfo("Report events: %02x\n", fds->revents);
-          nxsem_post(fds->sem);
-        }
-    }
-
-  /* If there are threads waiting for read data, then signal one of them
-   * that the read data is available.
-   */
-
-  iinfo("contact=%d nwaiters=%d\n", priv->sample.contact, priv->nwaiters);
-  if (priv->nwaiters > 0)
-    {
-      /* After posting this semaphore, we need to exit because
-       * the touchscreen is no longer available.
-       */
-
-      nxsem_post(&priv->waitsem);
-    }
-}
-
-/****************************************************************************
- * Name: up_sample
- ****************************************************************************/
-
-static int up_sample(FAR struct up_dev_s *priv,
-                     FAR struct up_sample_s *sample)
-{
-  int ret = -EAGAIN;
-
-  /* Is there new touchscreen sample data available? */
-
-  iinfo("penchange=%d contact=%d id=%d\n",
-        priv->penchange, sample->contact, priv->id);
-
-  if (priv->penchange)
-    {
-      /* Yes.. the state has changed in some way.  Return a copy of the
-       * sampled data.
-       */
-
-      memcpy(sample, &priv->sample, sizeof(struct up_sample_s));
-
-      /* Now manage state transitions */
-
-      if (sample->contact == CONTACT_UP)
-        {
-          /* Next.. no contract.  Increment the ID so that next contact ID
-           * will be unique
-           */
-
-          priv->sample.contact = CONTACT_NONE;
-          priv->id++;
-        }
-      else if (sample->contact == CONTACT_DOWN)
-        {
-          /* First report -- next report will be a movement */
-
-          priv->sample.contact = CONTACT_MOVE;
-        }
-
-      priv->penchange = false;
-      iinfo("penchange=%d contact=%d id=%d\n",
-             priv->penchange, priv->sample.contact, priv->id);
-
-      ret = OK;
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: up_waitsample
- ****************************************************************************/
-
-static int up_waitsample(FAR struct up_dev_s *priv,
-                         FAR struct up_sample_s *sample)
-{
-  irqstate_t flags;
-  int ret;
-
-  /* Interrupts me be disabled when this is called to (1) prevent posting
-   * of semphores from interrupt handlers, and (2) to prevent sampled data
-   * from changing until it has been reported.
-   *
-   * In addition, we will also disable pre-emption to prevent other threads
-   * from getting control while we muck with the semaphores.
-   */
-
-  sched_lock();
-  flags = enter_critical_section();
-
-  /* Now release the semaphore that manages mutually exclusive access to
-   * the device structure.  This may cause other tasks to become ready to
-   * run, but they cannot run yet because pre-emption is disabled.
-   */
-
-  nxsem_post(&priv->devsem);
-
-  /* Try to get the a sample... if we cannot, then wait on the semaphore
-   * that is posted when new sample data is available.
-   */
-
-  while (up_sample(priv, sample) < 0)
-    {
-      /* Wait for a change in the touchscreen state */
-
-      iinfo("Waiting...\n");
-      priv->nwaiters++;
-      ret = nxsem_wait(&priv->waitsem);
-      priv->nwaiters--;
-      iinfo("Awakened...\n");
-
-      if (ret < 0)
-        {
-          goto errout;
-        }
-    }
-
-  /* Re-acquire the semaphore that manages mutually exclusive access to the
-   * device structure.  We may have to wait here.  But we have our sample.
-   * Interrupts and pre-emption will be re-enabled while we wait.
-   */
-
-  ret = nxsem_wait(&priv->devsem);
-
-errout:
-  /* Then re-enable interrupts.  We might get interrupt here and there
-   * could be a new sample.  But no new threads will run because we still
-   * have pre-emption disabled.
-   */
-
-  leave_critical_section(flags);
-
-  /* Restore pre-emption.  We might get suspended here but that is okay
-   * because we already have our sample.  Note:  this means that if there
-   * were two threads reading from the touchscreen for some reason, the data
-   * might be read out of order.
-   */
-
-  sched_unlock();
-  return ret;
-}
-
-/****************************************************************************
- * Name: up_open
- ****************************************************************************/
-
-static int up_open(FAR struct file *filep)
-{
-  iinfo("Opening...\n");
-  return OK;
-}
-
-/****************************************************************************
- * Name: up_close
- ****************************************************************************/
-
-static int up_close(FAR struct file *filep)
-{
-  iinfo("Closing...\n");
-  return OK;
-}
-
-/****************************************************************************
- * Name: up_read
- ****************************************************************************/
-
-static ssize_t up_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
-  FAR struct inode          *inode;
-  FAR struct up_dev_s       *priv;
-  FAR struct touch_sample_s *report;
-  struct up_sample_s         sample;
-  int                        ret;
-
-  iinfo("len=%zd\n", len);
-
-  DEBUGASSERT(filep);
-  inode = filep->f_inode;
-
-  DEBUGASSERT(inode && inode->i_private);
-  priv  = (FAR struct up_dev_s *)inode->i_private;
-
-  /* Verify that the caller has provided a buffer large enough to receive
-   * the touch data.
-   */
-
-  if (len < SIZEOF_TOUCH_SAMPLE_S(1))
-    {
-      /* We could provide logic to break up a touch report into segments and
-       * handle smaller reads... but why?
-       */
-
-      return -ENOSYS;
-    }
-
-  /* Get exclusive access to the driver data structure */
-
-  ret = nxsem_wait(&priv->devsem);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Try to read sample data. */
-
-  ret = up_sample(priv, &sample);
-  if (ret < 0)
-    {
-      /* Sample data is not available now.  We would ave to wait to get
-       * receive sample data.  If the user has specified the O_NONBLOCK
-       * option, then just return an error.
-       */
-
-      if (filep->f_oflags & O_NONBLOCK)
-        {
-          ret = -EAGAIN;
-          goto errout;
-        }
-
-      /* Wait for sample data */
-
-      ret = up_waitsample(priv, &sample);
-      if (ret < 0)
-        {
-          /* We might have been awakened by a signal */
-
-          goto errout;
-        }
-    }
-
-  /* In any event, we now have sampled touchscreen data that we can report
-   * to the caller.
-   */
-
-  report = (FAR struct touch_sample_s *)buffer;
-  memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
-  report->npoints            = 1;
-  report->point[0].id        = priv->id;
-  report->point[0].x         = sample.x;
-  report->point[0].y         = sample.y;
-  report->point[0].h         = 1;
-  report->point[0].w         = 1;
-  report->point[0].pressure  = 42;
-
-  /* Report the appropriate flags */
-
-  if (sample.contact == CONTACT_UP)
-    {
-      /* Pen is now up */
-
-      report->point[0].flags  = TOUCH_UP | TOUCH_ID_VALID;
-    }
-  else if (sample.contact == CONTACT_DOWN)
-    {
-      /* First contact */
-
-      report->point[0].flags  = TOUCH_DOWN | TOUCH_ID_VALID |
-                                TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
-    }
-  else /* if (sample->contact == CONTACT_MOVE) */
-    {
-      /* Movement of the same contact */
-
-      report->point[0].flags  = TOUCH_MOVE | TOUCH_ID_VALID |
-                                TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
-    }
-
-  ret = SIZEOF_TOUCH_SAMPLE_S(1);
-
-errout:
-  iinfo("Returning %d\n", ret);
-  nxsem_post(&priv->devsem);
-  return ret;
-}
-
-/****************************************************************************
- * Name: up_ioctl
- ****************************************************************************/
-
-static int up_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
-  FAR struct inode         *inode;
-  FAR struct up_dev_s *priv;
-  int                       ret;
-
-  iinfo("cmd: %d arg: %ld\n", cmd, arg);
-  DEBUGASSERT(filep);
-  inode = filep->f_inode;
-
-  DEBUGASSERT(inode && inode->i_private);
-  priv  = (FAR struct up_dev_s *)inode->i_private;
-
-  /* Get exclusive access to the driver data structure */
-
-  ret = nxsem_wait(&priv->devsem);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Process the IOCTL by command */
-
-  switch (cmd)
-    {
-      default:
-        ret = -ENOTTY;
-        break;
-    }
-
-  nxsem_post(&priv->devsem);
-  return ret;
-}
-
-/****************************************************************************
- * Name: up_poll
- ****************************************************************************/
-
-static int up_poll(FAR struct file *filep, FAR struct pollfd *fds,
-                   bool setup)
-{
-  FAR struct inode    *inode;
-  FAR struct up_dev_s *priv;
-  int                  ret;
-  int                  i;
-
-  iinfo("setup: %d\n", (int)setup);
-  DEBUGASSERT(filep && fds);
-  inode = filep->f_inode;
-
-  DEBUGASSERT(inode && inode->i_private);
-  priv  = (FAR struct up_dev_s *)inode->i_private;
-
-  /* Are we setting up the poll?  Or tearing it down? */
-
-  ret = nxsem_wait(&priv->devsem);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  if (setup)
-    {
-      /* Ignore waits that do not include POLLIN */
-
-      if ((fds->revents & POLLIN) == 0)
-        {
-          ret = -EDEADLK;
-          goto errout;
-        }
-
-      /* This is a request to set up the poll.  Find an available
-       * slot for the poll structure reference
-       */
-
-      for (i = 0; i < CONFIG_SIM_TCNWAITERS; i++)
-        {
-          /* Find an available slot */
-
-          if (!priv->fds[i])
-            {
-              /* Bind the poll structure and this slot */
-
-              priv->fds[i] = fds;
-              fds->priv    = &priv->fds[i];
-              break;
-            }
-        }
-
-      if (i >= CONFIG_SIM_TCNWAITERS)
-        {
-          fds->priv    = NULL;
-          ret          = -EBUSY;
-          goto errout;
-        }
-
-      /* Should we immediately notify on any of the requested events? */
-
-      if (priv->penchange)
-        {
-          up_notify(priv);
-        }
-    }
-  else if (fds->priv)
-    {
-      /* This is a request to tear down the poll. */
-
-      struct pollfd **slot = (struct pollfd **)fds->priv;
-      DEBUGASSERT(slot != NULL);
-
-      /* Remove all memory of the poll setup */
-
-      *slot                = NULL;
-      fds->priv            = NULL;
-    }
-
-errout:
-  nxsem_post(&priv->devsem);
-  return ret;
-}
-
-/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -615,29 +110,19 @@ int sim_tsc_initialize(int minor)
 
   memset(priv, 0, sizeof(struct up_dev_s));
 
-  /* Initialize semaphores */
-
-  nxsem_init(&priv->devsem,  0, 1); /* Initialize device structure semaphore */
-  nxsem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */
-
-  /* The waitsem semaphore is used for signaling and, hence, should not have
-   * priority inheritance enabled.
-   */
-
-  nxsem_set_protocol(&priv->waitsem, SEM_PRIO_NONE);
-
   priv->minor = minor;
+  priv->lower.maxpoint = 1;
 
   /* Register the device as an input device */
 
   snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
   iinfo("Registering %s\n", devname);
 
-  ret = register_driver(devname, &up_fops, 0666, priv);
+  ret = touch_register(&priv->lower, devname, 1);
   if (ret < 0)
     {
-      ierr("ERROR: register_driver() failed: %d\n", ret);
-      goto errout_with_priv;
+      ierr("ERROR: touch_register() failed: %d\n", ret);
+      return ret;
     }
 
   /* Enable X11 event processing from the IDLE loop */
@@ -647,11 +132,6 @@ int sim_tsc_initialize(int minor)
   /* And return success */
 
   return OK;
-
-errout_with_priv:
-  nxsem_destroy(&priv->waitsem);
-  nxsem_destroy(&priv->devsem);
-  return ret;
 }
 
 /****************************************************************************
@@ -672,15 +152,6 @@ int sim_tsc_uninitialize(void)
 {
   FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen;
   char devname[DEV_NAMELEN];
-  int ret = OK;
-
-  /* Get exclusive access */
-
-  ret = nxsem_wait_uninterruptible(&priv->devsem);
-  if (ret < 0)
-    {
-      return ret;
-    }
 
   /* Stop the event loop (Hmm.. the caller must be sure that there are no
    * open references to the touchscreen driver.  This might better be
@@ -694,18 +165,9 @@ int sim_tsc_uninitialize(void)
   snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->minor);
   iinfo("Un-registering %s\n", devname);
 
-  ret = unregister_driver(devname);
-  if (ret < 0)
-    {
-      ierr("ERROR: uregister_driver() failed: %d\n", ret);
-    }
-
-  /* Clean up any resources.  Ouch!  While we are holding the semaphore? */
+  touch_unregister(&priv->lower, devname);
 
-  nxsem_destroy(&priv->waitsem);
-  nxsem_destroy(&priv->devsem);
-
-  return ret;
+  return OK;
 }
 
 /****************************************************************************
@@ -714,8 +176,9 @@ int sim_tsc_uninitialize(void)
 
 void up_buttonevent(int x, int y, int buttons)
 {
-  FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen;
-  bool                 pendown;  /* true: pen is down */
+  FAR struct up_dev_s  *priv = (FAR struct up_dev_s *)&g_simtouchscreen;
+  struct touch_sample_s sample;   /* Sampled touch point data */
+  bool                  pendown;  /* true: pen is down */
 
   if (priv->eventloop == 0)
     {
@@ -723,7 +186,6 @@ void up_buttonevent(int x, int y, int buttons)
     }
 
   iinfo("x=%d y=%d buttons=%02x\n", x, y, buttons);
-  iinfo("contact=%d nwaiters=%d\n", priv->sample.contact, priv->nwaiters);
 
   /* Any button press will count as pendown. */
 
@@ -738,42 +200,56 @@ void up_buttonevent(int x, int y, int buttons)
        *  CONTACT_UP == pen up, but not reported)
        */
 
-      if (priv->sample.contact == CONTACT_NONE)
+      if (priv->contact == TOUCH_UP)
         {
           return;
         }
 
       /* Not yet reported */
 
-      priv->sample.contact = CONTACT_UP;
+      priv->contact = TOUCH_UP;
+      sample.point[0].flags = TOUCH_UP | TOUCH_ID_VALID;
     }
   else
     {
       /* Save the measurements */
 
-      priv->sample.x = x;
-      priv->sample.y = y;
+      sample.point[0].x = x;
+      sample.point[0].y = y;
 
       /* Note the availability of new measurements:
        * If this is the first (acknowledged) pen down report, then report
-       * this as the first contact.  If contact == CONTACT_DOWN, it will be
-       * set to set to CONTACT_MOVE after the contact is first sampled.
+       * this as the first contact.  If flags == TOUCH_DOWN, it will be
+       * set to set to TOUCH_MOVE after the contact is first sampled.
        */
 
-      if (priv->sample.contact != CONTACT_MOVE)
+      if (priv->contact == TOUCH_UP)
         {
           /* First contact */
 
-          priv->sample.contact = CONTACT_DOWN;
+          priv->contact = TOUCH_DOWN;
+          sample.point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID |
+                                  TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
+
+          /* Indicate the availability of new sample data for this ID */
+
+          priv->id++;
+        }
+      else
+        {
+           priv->contact = TOUCH_MOVE;
+           sample.point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID |
+                                   TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
         }
     }
 
-  /* Indicate the availability of new sample data for this ID */
-
-  priv->sample.id = priv->id;
-  priv->penchange = true;
+  sample.npoints            = 1;
+  sample.point[0].h         = 1;
+  sample.point[0].w         = 1;
+  sample.point[0].pressure  = 42;
+  sample.point[0].id        = priv->id;
 
-  /* Notify any waiters that new touchscreen data is available */
+  /* Report data changes */
 
-  up_notify(priv);
+  touch_event(priv->lower.priv, &sample);
 }

Reply via email to