-static const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
- [HANDLE_IGNORE] = "ignore",
- [HANDLE_POWEROFF] = "poweroff",
- [HANDLE_REBOOT] = "reboot",
- [HANDLE_HALT] = "halt",
- [HANDLE_KEXEC] = "kexec",
- [HANDLE_SUSPEND] = "suspend",
- [HANDLE_HIBERNATE] = "hibernate"
-};
-DEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");
+int button_open(Button *b) {
+ char *p, name[256];
+ int r;
+
+ assert(b);
+
+ b->fd = safe_close(b->fd);
+
+ p = strjoina("/dev/input/", b->name);
+
+ b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+ if (b->fd < 0)
+ return log_warning_errno(errno, "Failed to open %s: %m", b->name);
+
+ if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
+ r = log_error_errno(errno, "Failed to get input name: %m");
+ goto fail;
+ }
+
+ r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
+ if (r < 0) {
+ log_error_errno(r, "Failed to add button event: %m");
+ goto fail;
+ }
+
+ log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);
+
+ return 0;
+
+fail:
+ b->fd = safe_close(b->fd);
+ return r;
+}
+
+int button_check_switches(Button *b) {
+ uint8_t switches[SW_MAX/8+1] = {};
+ assert(b);
+
+ if (b->fd < 0)
+ return -EINVAL;
+
+ if (ioctl(b->fd, EVIOCGSW(sizeof(switches)), switches) < 0)
+ return -errno;
+
+ b->lid_closed = (switches[SW_LID/8] >> (SW_LID % 8)) & 1;
+ b->docked = (switches[SW_DOCK/8] >> (SW_DOCK % 8)) & 1;
+
+ if (b->lid_closed)
+ button_install_check_event_source(b);
+
+ return 0;
+}