input_event_reader.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #ifndef _FY_INPUT_EVENT_READER_HPP_
  2. #define _FY_INPUT_EVENT_READER_HPP_
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/select.h>
  6. #include <linux/input.h>
  7. #include <fcntl.h>
  8. #include <string>
  9. #include <vector>
  10. #include <fy/mutex.hpp>
  11. namespace fy {
  12. class input_event_reader {
  13. private:
  14. struct input_source {
  15. std::string name;
  16. std::string path;
  17. int fd;
  18. };
  19. public:
  20. explicit input_event_reader() {
  21. }
  22. virtual ~input_event_reader() {
  23. lock_guard<fy::mutex> lock(mutex_);
  24. for (std::vector<input_source>::iterator it = input_sources_.begin(); it != input_sources_.end(); ++it) {
  25. if (it->fd >= 0) {
  26. close(it->fd);
  27. }
  28. }
  29. }
  30. int add_input(const std::string& name, const std::string& input_path) {
  31. lock_guard<fy::mutex> lock(mutex_);
  32. int fd = open(input_path.c_str(), O_RDONLY);
  33. if (fd < 0) {
  34. return -1;
  35. }
  36. struct input_source source;
  37. source.name = name;
  38. source.path = input_path;
  39. source.fd = fd;
  40. input_sources_.push_back(source);
  41. return 0;
  42. }
  43. void remove_input(const std::string& name) {
  44. lock_guard<fy::mutex> lock(mutex_);
  45. for (std::vector<input_source>::iterator it = input_sources_.begin(); it != input_sources_.end(); ++it) {
  46. if (name.compare(it->name) == 0) {
  47. if(it->fd >= 0) {
  48. close(it->fd);
  49. }
  50. input_sources_.erase(it);
  51. return;
  52. }
  53. }
  54. }
  55. /**
  56. * On success > 0
  57. * Timeout 0
  58. * Failed < 0
  59. */
  60. int read(std::string* name, input_event* event, int timeout_millis) {
  61. fd_set read_fds;
  62. int max_fd = setup_fdset(&read_fds);
  63. if (max_fd < 0) {
  64. return -1;
  65. }
  66. struct timeval tv;
  67. tv.tv_sec = timeout_millis / 1000;
  68. tv.tv_usec = timeout_millis % 1000;
  69. int ret = select(max_fd + 1, &read_fds, NULL, NULL, &tv);
  70. if (ret < 0) {
  71. //LOGD("error");
  72. return -2;
  73. } else if (ret == 0) {
  74. //timeout
  75. return 0;
  76. } else {
  77. for (std::vector<input_source>::iterator it = input_sources_.begin(); it != input_sources_.end(); ++it) {
  78. if (it->fd < 0) {
  79. continue;
  80. }
  81. *name = it->name;
  82. if(FD_ISSET(it->fd, &read_fds)) {
  83. int rs = ::read(it->fd, event, sizeof(input_event));
  84. if (rs == sizeof(input_event)) {
  85. return 1;
  86. } else {
  87. //LOGD("read exception");
  88. return -3;
  89. }
  90. }
  91. }
  92. }
  93. return 0;
  94. }
  95. protected:
  96. int setup_fdset(fd_set* set) {
  97. FD_ZERO(set);
  98. int max_fd = -1;
  99. for (std::vector<input_source>::iterator it = input_sources_.begin(); it != input_sources_.end(); ++it) {
  100. int fd = it->fd;
  101. if (fd >= 0) {
  102. FD_SET(fd, set);
  103. if (fd > max_fd) {
  104. max_fd = fd;
  105. }
  106. }
  107. }
  108. if (max_fd < 0) {
  109. return -1;
  110. }
  111. return max_fd;
  112. }
  113. private:
  114. std::vector<input_source> input_sources_;
  115. fy::mutex mutex_;
  116. };
  117. } /* namespace fy */
  118. #endif /* _FY_INPUT_EVENT_READER_HPP_ */