Merge "minui: add hall sensor event"
diff --git a/minui/events.cpp b/minui/events.cpp
index 863ac74..b307a49 100644
--- a/minui/events.cpp
+++ b/minui/events.cpp
@@ -267,6 +267,35 @@
   return -1;
 }
 
+int ev_sync_sw_state(const ev_set_sw_callback& set_sw_cb) {
+  // Use unsigned long to match ioctl's parameter type.
+  unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];  // NOLINT
+  unsigned long sw_bits[BITS_TO_LONGS(SW_MAX)];  // NOLINT
+
+  for (size_t i = 0; i < g_ev_dev_count; ++i) {
+    memset(ev_bits, 0, sizeof(ev_bits));
+    memset(sw_bits, 0, sizeof(sw_bits));
+
+    if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+      continue;
+    }
+    if (!test_bit(EV_SW, ev_bits)) {
+      continue;
+    }
+    if (ioctl(ev_fdinfo[i].fd, EVIOCGSW(sizeof(sw_bits)), sw_bits) == -1) {
+      continue;
+    }
+
+    for (int code = 0; code <= SW_MAX; code++) {
+      if (test_bit(code, sw_bits)) {
+        set_sw_cb(code, 1);
+      }
+    }
+  }
+
+  return 0;
+}
+
 int ev_sync_key_state(const ev_set_key_callback& set_key_cb) {
   // Use unsigned long to match ioctl's parameter type.
   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
diff --git a/minui/include/minui/minui.h b/minui/include/minui/minui.h
index 6a762b6..a2f62f0 100644
--- a/minui/include/minui/minui.h
+++ b/minui/include/minui/minui.h
@@ -162,6 +162,7 @@
 
 using ev_callback = std::function<int(int fd, uint32_t epevents)>;
 using ev_set_key_callback = std::function<int(int code, int value)>;
+using ev_set_sw_callback = std::function<int(int code, int value)>;
 
 int ev_init(ev_callback input_cb, bool allow_touch_inputs = false);
 void ev_exit();
@@ -169,6 +170,7 @@
 void ev_iterate_available_keys(const std::function<void(int)>& f);
 void ev_iterate_touch_inputs(const std::function<void(int)>& action);
 int ev_sync_key_state(const ev_set_key_callback& set_key_cb);
+int ev_sync_sw_state(const ev_set_sw_callback& set_sw_cb);
 
 // 'timeout' has the same semantics as poll(2).
 //    0 : don't block