| /* |
| * Copyright (C) 2015 Intel Corp |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <errno.h> |
| #include <unistd.h> |
| #include <poll.h> |
| #include <sys/cdefs.h> |
| #include <sys/types.h> |
| #include <linux/input.h> |
| #include <cutils/log.h> |
| #include "InputEventReader.h" |
| |
| /*****************************************************************************/ |
| |
| struct input_event; |
| |
| InputEventCircularReader::InputEventCircularReader(size_t numEvents) |
| : mBuffer(new input_event[numEvents * 2]), |
| mBufferEnd(mBuffer + numEvents), |
| mHead(mBuffer), |
| mCurr(mBuffer), |
| mFreeSpace(numEvents) |
| { |
| FUNC_LOG; |
| mLastFd = -1; |
| } |
| |
| InputEventCircularReader::~InputEventCircularReader() |
| { |
| FUNC_LOG; |
| delete [] mBuffer; |
| } |
| |
| /* TODO: clear DEBUG flag on production builds, keep it during integration */ |
| #define INPUT_EVENT_DEBUG (0) |
| ssize_t InputEventCircularReader::fill(int fd) |
| { |
| FUNC_LOG; |
| size_t numEventsRead = 0; |
| mLastFd = fd; |
| |
| LOGV_IF(INPUT_EVENT_DEBUG, |
| "DEBUG:%s enter, fd=%d\n", __PRETTY_FUNCTION__, fd); |
| if (mFreeSpace) { |
| const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); |
| if (nread < 0 || nread % sizeof(input_event)) { |
| if (INPUT_EVENT_DEBUG) { |
| LOGV_IF(nread < 0, "DEBUG:%s exit nread < 0\n", |
| __PRETTY_FUNCTION__); |
| LOGV_IF(nread % sizeof(input_event), |
| "DEBUG:%s exit nread %% sizeof(input_event)\n", |
| __PRETTY_FUNCTION__); |
| } |
| return (nread < 0 ? -errno : -EINVAL); |
| } |
| |
| numEventsRead = nread / sizeof(input_event); |
| if (numEventsRead) { |
| mHead += numEventsRead; |
| mFreeSpace -= numEventsRead; |
| if (mHead > mBufferEnd) { |
| size_t s = mHead - mBufferEnd; |
| memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); |
| mHead = mBuffer + s; |
| } |
| } |
| } |
| |
| LOGV_IF(INPUT_EVENT_DEBUG, "DEBUG:%s exit, numEventsRead:%d\n", |
| __PRETTY_FUNCTION__, numEventsRead); |
| return numEventsRead; |
| } |
| |
| ssize_t InputEventCircularReader::readEvent(input_event const** events) |
| { |
| FUNC_LOG; |
| *events = mCurr; |
| ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; |
| LOGV_IF(INPUT_EVENT_DEBUG, "DEBUG:%s fd:%d, available:%d\n", |
| __PRETTY_FUNCTION__, mLastFd, (int)available); |
| return (available ? 1 : 0); |
| } |
| |
| void InputEventCircularReader::next() |
| { |
| FUNC_LOG; |
| mCurr++; |
| mFreeSpace++; |
| if (mCurr >= mBufferEnd) { |
| mCurr = mBuffer; |
| } |
| ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; |
| LOGV_IF(INPUT_EVENT_DEBUG, "DEBUG:%s fd:%d, still available:%d\n", |
| __PRETTY_FUNCTION__, mLastFd, (int)available); |
| } |
| |