1*02424279STreehugger Robot /*
2*02424279STreehugger Robot * Copyright (C) 2012 Invensense, Inc.
3*02424279STreehugger Robot *
4*02424279STreehugger Robot * Licensed under the Apache License, Version 2.0 (the "License");
5*02424279STreehugger Robot * you may not use this file except in compliance with the License.
6*02424279STreehugger Robot * You may obtain a copy of the License at
7*02424279STreehugger Robot *
8*02424279STreehugger Robot * http://www.apache.org/licenses/LICENSE-2.0
9*02424279STreehugger Robot *
10*02424279STreehugger Robot * Unless required by applicable law or agreed to in writing, software
11*02424279STreehugger Robot * distributed under the License is distributed on an "AS IS" BASIS,
12*02424279STreehugger Robot * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*02424279STreehugger Robot * See the License for the specific language governing permissions and
14*02424279STreehugger Robot * limitations under the License.
15*02424279STreehugger Robot */
16*02424279STreehugger Robot
17*02424279STreehugger Robot #define LOG_NDEBUG 0
18*02424279STreehugger Robot
19*02424279STreehugger Robot #include <stdint.h>
20*02424279STreehugger Robot #include <errno.h>
21*02424279STreehugger Robot #include <unistd.h>
22*02424279STreehugger Robot #include <poll.h>
23*02424279STreehugger Robot #include <string.h>
24*02424279STreehugger Robot
25*02424279STreehugger Robot #include <sys/cdefs.h>
26*02424279STreehugger Robot #include <sys/types.h>
27*02424279STreehugger Robot
28*02424279STreehugger Robot #include <linux/input.h>
29*02424279STreehugger Robot
30*02424279STreehugger Robot #include <cutils/log.h>
31*02424279STreehugger Robot
32*02424279STreehugger Robot #include "InputEventReader.h"
33*02424279STreehugger Robot
34*02424279STreehugger Robot /*****************************************************************************/
35*02424279STreehugger Robot
36*02424279STreehugger Robot struct input_event;
37*02424279STreehugger Robot
InputEventCircularReader(size_t numEvents)38*02424279STreehugger Robot InputEventCircularReader::InputEventCircularReader(size_t numEvents)
39*02424279STreehugger Robot : mBuffer(new input_event[numEvents * 2]),
40*02424279STreehugger Robot mBufferEnd(mBuffer + numEvents),
41*02424279STreehugger Robot mHead(mBuffer),
42*02424279STreehugger Robot mCurr(mBuffer),
43*02424279STreehugger Robot mFreeSpace(numEvents)
44*02424279STreehugger Robot {
45*02424279STreehugger Robot mLastFd = -1;
46*02424279STreehugger Robot }
47*02424279STreehugger Robot
~InputEventCircularReader()48*02424279STreehugger Robot InputEventCircularReader::~InputEventCircularReader()
49*02424279STreehugger Robot {
50*02424279STreehugger Robot delete [] mBuffer;
51*02424279STreehugger Robot }
52*02424279STreehugger Robot
53*02424279STreehugger Robot #define INPUT_EVENT_DEBUG (0)
fill(int fd)54*02424279STreehugger Robot ssize_t InputEventCircularReader::fill(int fd)
55*02424279STreehugger Robot {
56*02424279STreehugger Robot size_t numEventsRead = 0;
57*02424279STreehugger Robot mLastFd = fd;
58*02424279STreehugger Robot
59*02424279STreehugger Robot LOGV_IF(INPUT_EVENT_DEBUG,
60*02424279STreehugger Robot "DEBUG:%s enter, fd=%d\n", __PRETTY_FUNCTION__, fd);
61*02424279STreehugger Robot if (mFreeSpace) {
62*02424279STreehugger Robot const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event));
63*02424279STreehugger Robot if (nread < 0 || nread % sizeof(input_event)) {
64*02424279STreehugger Robot //LOGE("Partial event received nread=%d, required=%d",
65*02424279STreehugger Robot // nread, sizeof(input_event));
66*02424279STreehugger Robot //LOGE("FD trying to read is: %d");
67*02424279STreehugger Robot // we got a partial event!!
68*02424279STreehugger Robot if (INPUT_EVENT_DEBUG) {
69*02424279STreehugger Robot LOGV_IF(nread < 0, "DEBUG:%s exit nread < 0\n",
70*02424279STreehugger Robot __PRETTY_FUNCTION__);
71*02424279STreehugger Robot LOGV_IF(nread % sizeof(input_event),
72*02424279STreehugger Robot "DEBUG:%s exit nread %% sizeof(input_event)\n",
73*02424279STreehugger Robot __PRETTY_FUNCTION__);
74*02424279STreehugger Robot }
75*02424279STreehugger Robot return (nread < 0 ? -errno : -EINVAL);
76*02424279STreehugger Robot }
77*02424279STreehugger Robot
78*02424279STreehugger Robot numEventsRead = nread / sizeof(input_event);
79*02424279STreehugger Robot if (numEventsRead) {
80*02424279STreehugger Robot mHead += numEventsRead;
81*02424279STreehugger Robot mFreeSpace -= numEventsRead;
82*02424279STreehugger Robot if (mHead > mBufferEnd) {
83*02424279STreehugger Robot size_t s = mHead - mBufferEnd;
84*02424279STreehugger Robot memcpy(mBuffer, mBufferEnd, s * sizeof(input_event));
85*02424279STreehugger Robot mHead = mBuffer + s;
86*02424279STreehugger Robot }
87*02424279STreehugger Robot }
88*02424279STreehugger Robot }
89*02424279STreehugger Robot
90*02424279STreehugger Robot LOGV_IF(INPUT_EVENT_DEBUG, "DEBUG:%s exit, numEventsRead:%d\n",
91*02424279STreehugger Robot __PRETTY_FUNCTION__, numEventsRead);
92*02424279STreehugger Robot return numEventsRead;
93*02424279STreehugger Robot }
94*02424279STreehugger Robot
readEvent(input_event const ** events)95*02424279STreehugger Robot ssize_t InputEventCircularReader::readEvent(input_event const** events)
96*02424279STreehugger Robot {
97*02424279STreehugger Robot *events = mCurr;
98*02424279STreehugger Robot ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;
99*02424279STreehugger Robot LOGV_IF(INPUT_EVENT_DEBUG, "DEBUG:%s fd:%d, available:%d\n",
100*02424279STreehugger Robot __PRETTY_FUNCTION__, mLastFd, (int)available);
101*02424279STreehugger Robot return (available ? 1 : 0);
102*02424279STreehugger Robot }
103*02424279STreehugger Robot
next()104*02424279STreehugger Robot void InputEventCircularReader::next()
105*02424279STreehugger Robot {
106*02424279STreehugger Robot mCurr++;
107*02424279STreehugger Robot mFreeSpace++;
108*02424279STreehugger Robot if (mCurr >= mBufferEnd) {
109*02424279STreehugger Robot mCurr = mBuffer;
110*02424279STreehugger Robot }
111*02424279STreehugger Robot ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;
112*02424279STreehugger Robot LOGV_IF(INPUT_EVENT_DEBUG, "DEBUG:%s fd:%d, still available:%d\n",
113*02424279STreehugger Robot __PRETTY_FUNCTION__, mLastFd, (int)available);
114*02424279STreehugger Robot }
115*02424279STreehugger Robot
116