diff --git a/Documentation/components/drivers/character/touchscreen.rst b/Documentation/components/drivers/character/touchscreen.rst index 00448e30af..ce47444ed2 100644 --- a/Documentation/components/drivers/character/touchscreen.rst +++ b/Documentation/components/drivers/character/touchscreen.rst @@ -36,3 +36,31 @@ found in the following locations: ``boards////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 + +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. + + diff --git a/drivers/input/touchscreen_upper.c b/drivers/input/touchscreen_upper.c index b85930dab9..18e5471c22 100644 --- a/drivers/input/touchscreen_upper.c +++ b/drivers/input/touchscreen_upper.c @@ -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); diff --git a/include/nuttx/input/touchscreen.h b/include/nuttx/input/touchscreen.h index 7a191bb943..34801e11de 100644 --- a/include/nuttx/input/touchscreen.h +++ b/include/nuttx/input/touchscreen.h @@ -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 */