logind-button.c revision e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cd
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);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (!p) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Out of memory");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -ENOMEM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
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
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringstatic bool has_graphical_session(Manager *m, const char *seat) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering Seat *s;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(m);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(seat);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering s = hashmap_get(m->seats, seat);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (!s)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return false;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (!s->active)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return false;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return s->active->type == SESSION_X11;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringstatic int button_power_off(Button *b, HandleButton handle) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering DBusError error;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering int r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (handle == HANDLE_NO)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (handle != HANDLE_ALWAYS) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (hashmap_size(b->manager->sessions) > 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Refusing power-off, user is logged in.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering warn_melody();
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -EPERM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (manager_is_inhibited(b->manager, INHIBIT_SHUTDOWN, INHIBIT_BLOCK, NULL)) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Refusing power-off, shutdown is inhibited.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering warn_melody();
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -EPERM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Powering off...");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering dbus_error_init(&error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, SPECIAL_POWEROFF_TARGET, INHIBIT_SHUTDOWN, &error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (r < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Failed to power off: %s", bus_error_message(&error));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering dbus_error_free(&error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringstatic int button_suspend(Button *b, HandleButton handle) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering DBusError error;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering int r;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering assert(b);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (handle == HANDLE_NO)
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (handle != HANDLE_ALWAYS) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (hashmap_size(b->manager->sessions) > 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Refusing suspend, user is logged in.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering warn_melody();
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -EPERM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (manager_is_inhibited(b->manager, INHIBIT_SLEEP, INHIBIT_BLOCK, NULL)) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Refusing suspend, sleeping is inhibited.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering warn_melody();
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return -EPERM;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Suspending...");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering dbus_error_init(&error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, SPECIAL_SUSPEND_TARGET, INHIBIT_SLEEP, &error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (r < 0) {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_error("Failed to suspend: %s", bus_error_message(&error));
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering dbus_error_free(&error);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return r;
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 there's a graphical session on the seat this device
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering * belongs to we ignore events, it is job of the graphical
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering * session to handle the event. */
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering if (has_graphical_session(b->manager, b->seat))
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
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.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return button_power_off(b, b->manager->handle_power_key);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_SLEEP:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering case KEY_SUSPEND:
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering log_info("Sleep key pressed.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return button_suspend(b, b->manager->handle_sleep_key);
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.");
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return button_suspend(b, b->manager->handle_lid_switch);
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering }
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering return 0;
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering}
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poetteringstatic const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering [HANDLE_YES] = "yes",
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering [HANDLE_NO] = "no",
e9d21f240704f87c6bb5f7fca1c5e6d0f31c84cdLennart Poettering [HANDLE_ALWAYS] = "always"
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");