drivers/touchscreen: add grab for touchscreen

Providing the capability for applications to exclusively
handle touch events

Signed-off-by: rongyichang <rongyichang@xiaomi.com>
This commit is contained in:
rongyichang 2024-07-24 20:09:25 +08:00 committed by Xiang Xiao
parent 9cc25523b1
commit bb29c39d50
3 changed files with 116 additions and 20 deletions

View File

@ -36,3 +36,31 @@ found in the following locations:
``boards/<arch>/<chip>/<board>/src/``
directory for boards that use an external touchscreen
controller chip.
Application Programming Interface
=================================
The first thing to be done in order to use the touchscreen driver from an
application is to include the correct header filer. It contains the
Application Programming Interface to the driver. To do so, include
.. code-block:: c
#include <nuttx/input/touchscreen.h>
Touchscreen driver is registered as a POSIX character device file into
``/dev`` namespace. It is necessary to open the device to get a file descriptor
for further operations. This can be done with standard POSIX ``open()`` call.
The driver is accessed through ``read``, ``write``, ``poll`` and ``ioctl``
interface, Following ``ioctl`` commands are available:
* :c:macro:`TSIOC_GRAB`
.. c:macro:: TSIOC_GRAB
This command let the current handle has the device grabbed. When a handle grabs
a device it becomes sole recipient for all touchscreen events coming from the
device. An argument is an ``int32_t`` variable to enable or disable the grab.

View File

@ -61,6 +61,7 @@ struct touch_upperhalf_s
mutex_t lock; /* Manages exclusive access to this structure */
struct list_node head; /* Opened file buffer chain header node */
FAR struct touch_lowerhalf_s *lower; /* A pointer of lower half instance */
FAR struct touch_openpriv_s *grab; /* A pointer of grab file */
};
/****************************************************************************
@ -78,6 +79,9 @@ static int touch_ioctl(FAR struct file *filep, int cmd,
static int touch_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup);
static void touch_event_notify(FAR struct touch_openpriv_s *openpriv,
FAR const struct touch_sample_s *sample);
/****************************************************************************
* Private Data
****************************************************************************/
@ -163,6 +167,11 @@ static int touch_close(FAR struct file *filep)
return ret;
}
if (upper->grab == openpriv)
{
upper->grab = NULL;
}
list_delete(&openpriv->node);
circbuf_uninit(&openpriv->circbuf);
nxsem_destroy(&openpriv->waitsem);
@ -250,9 +259,10 @@ out:
static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode = filep->f_inode;
FAR struct touch_upperhalf_s *upper = inode->i_private;
FAR struct touch_lowerhalf_s *lower = upper->lower;
FAR struct touch_openpriv_s *openpriv = filep->f_priv;
FAR struct inode *inode = filep->f_inode;
FAR struct touch_upperhalf_s *upper = inode->i_private;
FAR struct touch_lowerhalf_s *lower = upper->lower;
int ret;
ret = nxmutex_lock(&upper->lock);
@ -261,13 +271,48 @@ static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
return ret;
}
if (lower->control)
switch (cmd)
{
ret = lower->control(lower, cmd, arg);
}
else
{
ret = -ENOTTY;
case TSIOC_GRAB:
{
int enable = (int)arg;
ret = OK;
if (enable)
{
if (upper->grab != NULL)
{
ret = -EBUSY;
}
else
{
upper->grab = openpriv;
}
}
else
{
if (upper->grab != openpriv)
{
ret = -EINVAL;
}
else
{
upper->grab = NULL;
}
}
}
break;
default:
{
if (lower->control)
{
ret = lower->control(lower, cmd, arg);
}
else
{
ret = -ENOTTY;
}
}
break;
}
nxmutex_unlock(&upper->lock);
@ -321,6 +366,27 @@ errout:
return ret;
}
/****************************************************************************
* Name: touch_event_notify
****************************************************************************/
static void touch_event_notify(FAR struct touch_openpriv_s *openpriv,
FAR const struct touch_sample_s *sample)
{
int semcount;
circbuf_overwrite(&openpriv->circbuf, sample,
SIZEOF_TOUCH_SAMPLE_S(sample->npoints));
nxsem_get_value(&openpriv->waitsem, &semcount);
if (semcount < 1)
{
nxsem_post(&openpriv->waitsem);
}
poll_notify(&openpriv->fds, 1, POLLIN);
}
/****************************************************************************
* Public Function
****************************************************************************/
@ -333,25 +399,23 @@ void touch_event(FAR void *priv, FAR const struct touch_sample_s *sample)
{
FAR struct touch_upperhalf_s *upper = priv;
FAR struct touch_openpriv_s *openpriv;
int semcount;
if (nxmutex_lock(&upper->lock) < 0)
{
return;
}
list_for_every_entry(&upper->head, openpriv, struct touch_openpriv_s, node)
if (upper->grab)
{
circbuf_overwrite(&openpriv->circbuf, sample,
SIZEOF_TOUCH_SAMPLE_S(sample->npoints));
nxsem_get_value(&openpriv->waitsem, &semcount);
if (semcount < 1)
touch_event_notify(upper->grab, sample);
}
else
{
list_for_every_entry(&upper->head, openpriv,
struct touch_openpriv_s, node)
{
nxsem_post(&openpriv->waitsem);
touch_event_notify(openpriv, sample);
}
poll_notify(&openpriv->fds, 1, POLLIN);
}
nxmutex_unlock(&upper->lock);

View File

@ -89,8 +89,12 @@
* int Y threshold value
*/
#define TSIOC_GRAB _TSIOC(0x000e) /* arg: Pointer to
* int for enable grab
*/
#define TSC_FIRST 0x0001 /* First common command */
#define TSC_NCMDS 13 /* Thirteen common commands */
#define TSC_NCMDS 14 /* Fourteen common commands */
/* Backward compatible IOCTL */