logind-button.c revision 65b5116220a8ebf8a260716152409aa05377aacc
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
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 <assert.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <string.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <errno.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <fcntl.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <sys/ioctl.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <unistd.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <linux/input.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include <sys/epoll.h>
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include "conf-parser.h"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include "util.h"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include "logind-button.h"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include "special.h"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering#include "dbus-common.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
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (b->fd >= 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering hashmap_remove(b->manager->button_fds, INT_TO_PTR(b->fd + 1));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering close_nointr_nofail(b->fd);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
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
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringint button_open(Button *b) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering char name[256], *p;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering struct epoll_event ev;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering int r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (b->fd >= 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering close_nointr_nofail(b->fd);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->fd = -1;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering p = strappend("/dev/input/", b->name);
0d0f0c50d3a1d90f03972a6abb82e6413daaa583Shawn Landden if (!p)
0d0f0c50d3a1d90f03972a6abb82e6413daaa583Shawn Landden return log_oom();
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering free(p);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (b->fd < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_warning("Failed to open %s: %m", b->name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -errno;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Failed to get input name: %m");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering r = -errno;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering goto fail;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering zero(ev);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering ev.events = EPOLLIN;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering ev.data.u32 = FD_OTHER_BASE + b->fd;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_ADD, b->fd, &ev) < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Failed to add to epoll: %m");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering r = -errno;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering goto fail;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering r = hashmap_put(b->manager->button_fds, INT_TO_PTR(b->fd + 1), b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (r < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Failed to add to hash map: %s", strerror(-r));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering goto fail;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringfail:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering close_nointr_nofail(b->fd);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering b->fd = -1;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poetteringstatic int button_handle(
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering Button *b,
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering InhibitWhat inhibit_key,
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering HandleButton handle,
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering bool ignore_inhibited,
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering bool is_edge) {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering static const char * const message_table[_HANDLE_BUTTON_MAX] = {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_POWEROFF] = "Powering Off...",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_REBOOT] = "Rebooting...",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_HALT] = "Halting...",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_KEXEC] = "Rebooting via kexec...",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_SUSPEND] = "Suspending...",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_HIBERNATE] = "Hibernating..."
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering };
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering static const char * const target_table[_HANDLE_BUTTON_MAX] = {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_POWEROFF] = "poweroff.target",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_REBOOT] = "reboot.target",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_HALT] = "halt.target",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_KEXEC] = "kexec.target",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_SUSPEND] = "suspend.target",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_HIBERNATE] = "hibernate.target"
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering };
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering DBusError error;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering int r;
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering InhibitWhat inhibit_operation;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering /* If the key handling is turned off, don't do anything */
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering if (handle == HANDLE_IGNORE) {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering log_debug("Refusing key handling, as it is turned off.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering /* If the key handling is inhibited, don't do anything */
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering if (manager_is_inhibited(b->manager, inhibit_key, INHIBIT_BLOCK, NULL, true)) {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering log_debug("Refusing key handling, %s is inhibited.", inhibit_what_to_string(inhibit_key));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
6de0e0e500d9d534c6e4baab242fc2a146f021faLennart Poettering }
6de0e0e500d9d534c6e4baab242fc2a146f021faLennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering /* If the actual operation is inhibited, warn and fail */
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering if (!ignore_inhibited &&
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering manager_is_inhibited(b->manager, inhibit_operation, INHIBIT_BLOCK, NULL, false)) {
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering /* If this is just a recheck of the lid switch then don't warn about anything */
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering if (!is_edge) {
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return 0;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering }
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering log_error("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering warn_melody();
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering return -EPERM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering log_info("%s", message_table[handle]);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering /* We are executing the operation, so make sure we don't
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering * execute another one until the lid is opened/closed again */
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering b->lid_close_queued = false;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering dbus_error_init(&error);
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, target_table[handle], inhibit_operation, &error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (r < 0) {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering log_error("Failed to execute operation: %s", bus_error_message(&error));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering dbus_error_free(&error);
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return 1;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringint button_process(Button *b) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering struct input_event ev;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering ssize_t l;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
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:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Power key pressed.");
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_SLEEP:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_SUSPEND:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Sleep key pressed.");
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return button_handle(b, INHIBIT_HANDLE_SLEEP_KEY, b->manager->handle_sleep_key, b->manager->sleep_key_ignore_inhibited, true);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering } else if (ev.type == EV_SW && ev.value > 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering switch (ev.code) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case SW_LID:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Lid closed.");
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering b->lid_close_queued = true;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering }
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering } else if (ev.type == EV_SW && ev.value == 0) {
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering switch (ev.code) {
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering case SW_LID:
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering log_info("Lid opened.");
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering b->lid_close_queued = false;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering break;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poetteringint button_recheck(Button *b) {
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering assert(b);
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering if (!b->lid_close_queued)
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return 0;
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, false);
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering}
65b5116220a8ebf8a260716152409aa05377aaccLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringstatic const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_IGNORE] = "ignore",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_POWEROFF] = "poweroff",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_REBOOT] = "reboot",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_HALT] = "halt",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_KEXEC] = "kexec",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_SUSPEND] = "suspend",
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering [HANDLE_HIBERNATE] = "hibernate"
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering};
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");