logind-button.c revision 6de0e0e500d9d534c6e4baab242fc2a146f021fa
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering This file is part of systemd.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Copyright 2012 Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering systemd is free software; you can redistribute it and/or modify it
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering under the terms of the GNU Lesser General Public License as published by
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering (at your option) any later version.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering systemd is distributed in the hope that it will be useful, but
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Lesser General Public License for more details.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering You should have received a copy of the GNU Lesser General Public License
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart PoetteringButton* button_new(Manager *m, const char *name) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (hashmap_put(m->buttons, b->name, b) < 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering hashmap_remove(b->manager->buttons, b->name);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (b->fd >= 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering hashmap_remove(b->manager->button_fds, INT_TO_PTR(b->fd + 1));
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringint button_set_seat(Button *b, const char *sn) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (b->fd >= 0) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (b->fd < 0) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering log_warning("Failed to open %s: %m", b->name);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering log_error("Failed to get input name: %m");
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_ADD, b->fd, &ev) < 0) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = hashmap_put(b->manager->button_fds, INT_TO_PTR(b->fd + 1), b);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering log_error("Failed to add to hash map: %s", strerror(-r));
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic Session *button_get_session(Button *b) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering seat = hashmap_get(b->manager->seats, b->seat);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int button_power_off(Button *b, HandleButton handle) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (hashmap_size(b->manager->sessions) > 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Refusing power-off, user is logged in.");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering } else if (handle == HANDLE_TTY_SESSION ||
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering /* Silently ignore events of graphical sessions */
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Refusing power-off, other user is logged in.");
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (manager_is_inhibited(b->manager, INHIBIT_SHUTDOWN, INHIBIT_BLOCK, NULL)) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Refusing power-off, shutdown is inhibited.");
636db02d54b64fb5bbad86c8015a9ef51299693bTom Gundersen r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, SPECIAL_POWEROFF_TARGET, INHIBIT_SHUTDOWN, &error);
df3fb561b2df486a495a5f0bcc83168bd1860533Lennart Poettering log_error("Failed to power off: %s", bus_error_message(&error));
636db02d54b64fb5bbad86c8015a9ef51299693bTom Gundersenstatic int button_suspend(Button *b, HandleButton handle) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (hashmap_size(b->manager->sessions) > 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Refusing suspend, user is logged in.");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering } else if (handle == HANDLE_TTY_SESSION ||
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering /* Silently ignore events of graphical sessions */
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Refusing suspend, other user is logged in.");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (manager_is_inhibited(b->manager, INHIBIT_SLEEP, INHIBIT_BLOCK, NULL)) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Refusing suspend, sleeping is inhibited.");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, SPECIAL_SUSPEND_TARGET, INHIBIT_SLEEP, &error);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering log_error("Failed to suspend: %s", bus_error_message(&error));
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return button_power_off(b, b->manager->handle_power_key);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return button_suspend(b, b->manager->handle_sleep_key);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering } else if (ev.type == EV_SW && ev.value > 0) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return button_suspend(b, b->manager->handle_lid_switch);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poetteringstatic const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");