mirror of
https://github.com/apache/nuttx.git
synced 2026-05-29 04:19:37 +08:00
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:
@@ -36,3 +36,31 @@ found in the following locations:
|
|||||||
``boards/<arch>/<chip>/<board>/src/``
|
``boards/<arch>/<chip>/<board>/src/``
|
||||||
directory for boards that use an external touchscreen
|
directory for boards that use an external touchscreen
|
||||||
controller chip.
|
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 */
|
mutex_t lock; /* Manages exclusive access to this structure */
|
||||||
struct list_node head; /* Opened file buffer chain header node */
|
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_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,
|
static int touch_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||||
bool setup);
|
bool setup);
|
||||||
|
|
||||||
|
static void touch_event_notify(FAR struct touch_openpriv_s *openpriv,
|
||||||
|
FAR const struct touch_sample_s *sample);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -163,6 +167,11 @@ static int touch_close(FAR struct file *filep)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (upper->grab == openpriv)
|
||||||
|
{
|
||||||
|
upper->grab = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
list_delete(&openpriv->node);
|
list_delete(&openpriv->node);
|
||||||
circbuf_uninit(&openpriv->circbuf);
|
circbuf_uninit(&openpriv->circbuf);
|
||||||
nxsem_destroy(&openpriv->waitsem);
|
nxsem_destroy(&openpriv->waitsem);
|
||||||
@@ -250,9 +259,10 @@ out:
|
|||||||
|
|
||||||
static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct touch_openpriv_s *openpriv = filep->f_priv;
|
||||||
FAR struct touch_upperhalf_s *upper = inode->i_private;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct touch_lowerhalf_s *lower = upper->lower;
|
FAR struct touch_upperhalf_s *upper = inode->i_private;
|
||||||
|
FAR struct touch_lowerhalf_s *lower = upper->lower;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = nxmutex_lock(&upper->lock);
|
ret = nxmutex_lock(&upper->lock);
|
||||||
@@ -261,13 +271,48 @@ static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lower->control)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
ret = lower->control(lower, cmd, arg);
|
case TSIOC_GRAB:
|
||||||
}
|
{
|
||||||
else
|
int enable = (int)arg;
|
||||||
{
|
ret = OK;
|
||||||
ret = -ENOTTY;
|
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);
|
nxmutex_unlock(&upper->lock);
|
||||||
@@ -321,6 +366,27 @@ errout:
|
|||||||
return ret;
|
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
|
* 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_upperhalf_s *upper = priv;
|
||||||
FAR struct touch_openpriv_s *openpriv;
|
FAR struct touch_openpriv_s *openpriv;
|
||||||
int semcount;
|
|
||||||
|
|
||||||
if (nxmutex_lock(&upper->lock) < 0)
|
if (nxmutex_lock(&upper->lock) < 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_every_entry(&upper->head, openpriv, struct touch_openpriv_s, node)
|
if (upper->grab)
|
||||||
{
|
{
|
||||||
circbuf_overwrite(&openpriv->circbuf, sample,
|
touch_event_notify(upper->grab, sample);
|
||||||
SIZEOF_TOUCH_SAMPLE_S(sample->npoints));
|
}
|
||||||
|
else
|
||||||
nxsem_get_value(&openpriv->waitsem, &semcount);
|
{
|
||||||
if (semcount < 1)
|
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);
|
nxmutex_unlock(&upper->lock);
|
||||||
|
|||||||
@@ -89,8 +89,12 @@
|
|||||||
* int Y threshold value
|
* 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_FIRST 0x0001 /* First common command */
|
||||||
#define TSC_NCMDS 13 /* Thirteen common commands */
|
#define TSC_NCMDS 14 /* Fourteen common commands */
|
||||||
|
|
||||||
/* Backward compatible IOCTL */
|
/* Backward compatible IOCTL */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user