static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer, size_t len) { FAR struct inode *inode; FAR struct max11802_dev_s *priv; FAR struct touch_sample_s *report; struct max11802_sample_s sample; int ret; iinfo("buffer:%p len:%d\n", buffer, len); DEBUGASSERT(filep); inode = filep->f_inode; DEBUGASSERT(inode && inode->i_private); priv = (FAR struct max11802_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? */ ierr("ERROR: Unsupported read size: %d\n", len); return -ENOSYS; } /* Get exclusive access to the driver data structure */ ret = sem_wait(&priv->devsem); if (ret < 0) { /* This should only happen if the wait was cancelled by an signal */ ierr("ERROR: sem_wait: %d\n", errno); DEBUGASSERT(errno == EINTR); return -EINTR; } /* Try to read sample data. */ ret = max11802_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. */ iinfo("Sample data is not available\n"); if (filep->f_oflags & O_NONBLOCK) { ret = -EAGAIN; goto errout; } /* Wait for sample data */ ret = max11802_waitsample(priv, &sample); if (ret < 0) { /* We might have been awakened by a signal */ ierr("ERROR: max11802_waitsample: %d\n", ret); goto errout; } } /* In any event, we now have sampled MAX11802 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 = sample.id; report->point[0].x = sample.x; report->point[0].y = sample.y; /* Report the appropriate flags */ if (sample.contact == CONTACT_UP) { /* Pen is now up. Is the positional data valid? This is important to * know because the release will be sent to the window based on its * last positional data. */ if (sample.valid) { report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID; } else { 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; } else /* if (sample->contact == CONTACT_MOVE) */ { /* Movement of the same contact */ report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID; } iinfo(" id: %d\n", report->point[0].id); iinfo(" flags: %02x\n", report->point[0].flags); iinfo(" x: %d\n", report->point[0].x); iinfo(" y: %d\n", report->point[0].y); ret = SIZEOF_TOUCH_SAMPLE_S(1); errout: sem_post(&priv->devsem); iinfo("Returning: %d\n", ret); return ret; }
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; ivdbg("len=%d\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 = sem_wait(&priv->devsem); if (ret < 0) { /* This should only happen if the wait was canceled by an signal */ DEBUGASSERT(errno == EINTR); return -EINTR; } /* 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: ivdbg("Returning %d\n", ret); sem_post(&priv->devsem); return ret; }