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:
parent
9cc25523b1
commit
bb29c39d50
@ -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.
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user