e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering/***
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering This file is part of systemd.
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering Copyright 2012 Lennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering systemd is free software; you can redistribute it and/or modify it
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering under the terms of the GNU Lesser General Public License as published by
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering (at your option) any later version.
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering systemd is distributed in the hope that it will be useful, but
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering Lesser General Public License for more details.
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering You should have received a copy of the GNU Lesser General Public License
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering***/
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <errno.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <fcntl.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <string.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <sys/ioctl.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <unistd.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <linux/input.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering#include "sd-messages.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "logind-button.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include "util.h"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart PoetteringButton* button_new(Manager *m, const char *name) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering Button *b;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(m);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b = new0(Button, 1);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (!b)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return NULL;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->name = strdup(name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (!b->name) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return NULL;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (hashmap_put(m->buttons, b->name, b) < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b->name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return NULL;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->manager = m;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->fd = -1;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return b;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringvoid button_free(Button *b) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering hashmap_remove(b->manager->buttons, b->name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering sd_event_source_unref(b->io_event_source);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering sd_event_source_unref(b->check_event_source);
c30a0c62fdbf6f11902be9db64ade99fb508adfdLennart Poettering
ece174c5439021e32ebcc858842de9586072c006Lennart Poettering if (b->fd >= 0)
c30a0c62fdbf6f11902be9db64ade99fb508adfdLennart Poettering /* If the device has been unplugged close() returns
c30a0c62fdbf6f11902be9db64ade99fb508adfdLennart Poettering * ENODEV, let's ignore this, hence we don't use
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering * safe_close() */
4fba57963b8c83085c58d59c1bfc03633df22baeLennart Poettering (void) close(b->fd);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b->name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b->seat);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringint button_set_seat(Button *b, const char *sn) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering char *s;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(sn);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering s = strdup(sn);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (!s)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -ENOMEM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(b->seat);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->seat = s;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsiefferstatic void button_lid_switch_handle_action(Manager *manager, bool is_edge) {
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer HandleAction handle_action;
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer assert(manager);
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer /* If we are docked, handle the lid switch differently */
602a41c22ac2df33b4b5e5083719c1cfaf58acf9Lennart Poettering if (manager_is_docked_or_external_displays(manager))
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer handle_action = manager->handle_lid_switch_docked;
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer else
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer handle_action = manager->handle_lid_switch;
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer manager_handle_action(manager, INHIBIT_HANDLE_LID_SWITCH, handle_action, manager->lid_switch_ignore_inhibited, is_edge);
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer}
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poetteringstatic int button_recheck(sd_event_source *e, void *userdata) {
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering Button *b = userdata;
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering assert(b);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering assert(b->lid_closed);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer button_lid_switch_handle_action(b->manager, false);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return 1;
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poetteringstatic int button_install_check_event_source(Button *b) {
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering int r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering /* Install a post handler, so that we keep rechecking as long as the lid is closed. */
6de0e0e500d9d534c6e4baab242fc2a146f021faLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering if (b->check_event_source)
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return 0;
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering r = sd_event_add_post(b->manager->event, &b->check_event_source, button_recheck, b);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering if (r < 0)
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return r;
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return sd_event_source_set_priority(b->check_event_source, SD_EVENT_PRIORITY_IDLE+1);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poetteringstatic int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering Button *b = userdata;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering struct input_event ev;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering ssize_t l;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering assert(s);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering assert(fd == b->fd);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering l = read(b->fd, &ev, sizeof(ev));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (l < 0)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return errno != EAGAIN ? -errno : 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if ((size_t) l < sizeof(ev))
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -EIO;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (ev.type == EV_KEY && ev.value > 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering switch (ev.code) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_POWER:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_POWER2:
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("Power key pressed."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_POWER_KEY),
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek NULL);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering break;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering /* The kernel is a bit confused here:
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering KEY_SLEEP = suspend-to-ram, which everybody else calls "suspend"
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering */
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_SLEEP:
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("Suspend key pressed."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_SUSPEND_KEY),
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek NULL);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering break;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering case KEY_SUSPEND:
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("Hibernate key pressed."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_HIBERNATE_KEY),
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek NULL);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering break;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
8e7fd6ade44ce5dde0867ba748c7978ed1206865Lennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering } else if (ev.type == EV_SW && ev.value > 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering if (ev.code == SW_LID) {
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("Lid closed."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_LID_CLOSED),
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek NULL);
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering b->lid_closed = true;
3c56cab44150ad47323970cfadfb0257c6305a74Ben Wolsieffer button_lid_switch_handle_action(b->manager, true);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering button_install_check_event_source(b);
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering } else if (ev.code == SW_DOCK) {
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("System docked."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_SYSTEM_DOCKED),
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering NULL);
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering b->docked = true;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering }
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering } else if (ev.type == EV_SW && ev.value == 0) {
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering if (ev.code == SW_LID) {
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("Lid opened."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_LID_OPENED),
c485437f50450c0087bae3df4aed462e4a86ee83Zbigniew Jędrzejewski-Szmek NULL);
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering b->lid_closed = false;
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering b->check_event_source = sd_event_source_unref(b->check_event_source);
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering } else if (ev.code == SW_DOCK) {
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering log_struct(LOG_INFO,
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE("System undocked."),
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering LOG_MESSAGE_ID(SD_MESSAGE_SYSTEM_UNDOCKED),
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering NULL);
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering b->docked = false;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poetteringint button_open(Button *b) {
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering char *p, name[256];
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering int r;
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering assert(b);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
7f6e12b03300ba3e473ce6b85d823fc0375b335eLennart Poettering b->fd = safe_close(b->fd);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering p = strjoina("/dev/input/", b->name);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (b->fd < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_warning_errno(errno, "Failed to open %s: %m", b->name);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
76ef789d264f9eb7d7624b994aa6eead1dacfac4Lennart Poettering r = log_error_errno(errno, "Failed to get input name: %m");
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering goto fail;
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering }
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to add button event: %m");
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering goto fail;
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering }
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering return 0;
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
cc3773810855956bad92337cee8fa193584ab62eLennart Poetteringfail:
66e405837bf250f50472c886f9c7452634ca3776Lennart Poettering b->fd = safe_close(b->fd);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering return r;
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering}
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poetteringint button_check_switches(Button *b) {
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering uint8_t switches[SW_MAX/8+1] = {};
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering assert(b);
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering if (b->fd < 0)
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return -EINVAL;
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering if (ioctl(b->fd, EVIOCGSW(sizeof(switches)), switches) < 0)
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return -errno;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering b->lid_closed = (switches[SW_LID/8] >> (SW_LID % 8)) & 1;
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering b->docked = (switches[SW_DOCK/8] >> (SW_DOCK % 8)) & 1;
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering
2d62c530d2b4c2730abff715b7342f1402114513Lennart Poettering if (b->lid_closed)
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering button_install_check_event_source(b);
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering
ed4ba7e4f652150310d062ffbdfefb4521ce1054Lennart Poettering return 0;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering}