1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 #include "sd-messages.h"
10 #include "alloc-util.h"
13 #include "logind-button.h"
14 #include "logind-dbus.h"
15 #include "missing_input.h"
16 #include "string-util.h"
18 #define CONST_MAX5(a, b, c, d, e) CONST_MAX(CONST_MAX(a, b), CONST_MAX(CONST_MAX(c, d), e))
20 #define ULONG_BITS (sizeof(unsigned long)*8)
22 #define LONG_PRESS_DURATION (5 * USEC_PER_SEC)
24 static bool bitset_get(const unsigned long *bits
, unsigned i
) {
25 return (bits
[i
/ ULONG_BITS
] >> (i
% ULONG_BITS
)) & 1UL;
28 static void bitset_put(unsigned long *bits
, unsigned i
) {
29 bits
[i
/ ULONG_BITS
] |= (unsigned long) 1 << (i
% ULONG_BITS
);
32 Button
* button_new(Manager
*m
, const char *name
) {
42 b
->name
= strdup(name
);
46 if (hashmap_put(m
->buttons
, b
->name
, b
) < 0) {
57 Button
*button_free(Button
*b
) {
61 hashmap_remove(b
->manager
->buttons
, b
->name
);
63 sd_event_source_unref(b
->io_event_source
);
64 sd_event_source_unref(b
->check_event_source
);
66 asynchronous_close(b
->fd
);
74 int button_set_seat(Button
*b
, const char *sn
) {
77 return free_and_strdup(&b
->seat
, sn
);
80 static void button_lid_switch_handle_action(Manager
*manager
, bool is_edge
) {
81 HandleAction handle_action
;
85 /* If we are docked or on external power, handle the lid switch
87 if (manager_is_docked_or_external_displays(manager
))
88 handle_action
= manager
->handle_lid_switch_docked
;
89 else if (handle_action_valid(manager
->handle_lid_switch_ep
) && manager_is_on_external_power())
90 handle_action
= manager
->handle_lid_switch_ep
;
92 handle_action
= manager
->handle_lid_switch
;
94 manager_handle_action(manager
, INHIBIT_HANDLE_LID_SWITCH
, handle_action
, manager
->lid_switch_ignore_inhibited
, is_edge
);
97 static int button_recheck(sd_event_source
*e
, void *userdata
) {
98 Button
*b
= ASSERT_PTR(userdata
);
100 assert(b
->lid_closed
);
102 button_lid_switch_handle_action(b
->manager
, false);
106 static int button_install_check_event_source(Button
*b
) {
110 /* Install a post handler, so that we keep rechecking as long as the lid is closed. */
112 if (b
->check_event_source
)
115 r
= sd_event_add_post(b
->manager
->event
, &b
->check_event_source
, button_recheck
, b
);
119 return sd_event_source_set_priority(b
->check_event_source
, SD_EVENT_PRIORITY_IDLE
+1);
122 static int long_press_of_power_key_handler(sd_event_source
*e
, uint64_t usec
, void *userdata
) {
123 Manager
*m
= ASSERT_PTR(userdata
);
127 m
->power_key_long_press_event_source
= sd_event_source_unref(m
->power_key_long_press_event_source
);
130 LOG_MESSAGE("Power key pressed long."),
131 "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_LONG_PRESS_STR
);
133 manager_handle_action(m
, INHIBIT_HANDLE_POWER_KEY
, m
->handle_power_key_long_press
, m
->power_key_ignore_inhibited
, true);
137 static int long_press_of_reboot_key_handler(sd_event_source
*e
, uint64_t usec
, void *userdata
) {
138 Manager
*m
= ASSERT_PTR(userdata
);
142 m
->reboot_key_long_press_event_source
= sd_event_source_unref(m
->reboot_key_long_press_event_source
);
145 LOG_MESSAGE("Reboot key pressed long."),
146 "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_LONG_PRESS_STR
);
148 manager_handle_action(m
, INHIBIT_HANDLE_REBOOT_KEY
, m
->handle_reboot_key_long_press
, m
->reboot_key_ignore_inhibited
, true);
152 static int long_press_of_suspend_key_handler(sd_event_source
*e
, uint64_t usec
, void *userdata
) {
153 Manager
*m
= ASSERT_PTR(userdata
);
157 m
->suspend_key_long_press_event_source
= sd_event_source_unref(m
->suspend_key_long_press_event_source
);
160 LOG_MESSAGE("Suspend key pressed long."),
161 "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_LONG_PRESS_STR
);
163 manager_handle_action(m
, INHIBIT_HANDLE_SUSPEND_KEY
, m
->handle_suspend_key_long_press
, m
->suspend_key_ignore_inhibited
, true);
167 static int long_press_of_hibernate_key_handler(sd_event_source
*e
, uint64_t usec
, void *userdata
) {
168 Manager
*m
= ASSERT_PTR(userdata
);
172 m
->hibernate_key_long_press_event_source
= sd_event_source_unref(m
->hibernate_key_long_press_event_source
);
175 LOG_MESSAGE("Hibernate key pressed long."),
176 "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS_STR
);
178 manager_handle_action(m
, INHIBIT_HANDLE_HIBERNATE_KEY
, m
->handle_hibernate_key_long_press
, m
->hibernate_key_ignore_inhibited
, true);
182 static void start_long_press(Manager
*m
, sd_event_source
**e
, sd_event_time_handler_t callback
) {
191 r
= sd_event_add_time_relative(
195 LONG_PRESS_DURATION
, 0,
198 log_warning_errno(r
, "Failed to add long press timer event, ignoring: %m");
201 static int button_dispatch(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
202 Button
*b
= ASSERT_PTR(userdata
);
203 struct input_event ev
;
209 l
= read(b
->fd
, &ev
, sizeof(ev
));
211 return errno
!= EAGAIN
? -errno
: 0;
212 if ((size_t) l
< sizeof(ev
))
215 if (ev
.type
== EV_KEY
&& ev
.value
> 0) {
221 if (b
->manager
->handle_power_key_long_press
!= HANDLE_IGNORE
&& b
->manager
->handle_power_key_long_press
!= b
->manager
->handle_power_key
) {
222 log_debug("Power key pressed. Further action depends on the key press duration.");
223 start_long_press(b
->manager
, &b
->manager
->power_key_long_press_event_source
, long_press_of_power_key_handler
);
226 LOG_MESSAGE("Power key pressed short."),
227 "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR
);
228 manager_handle_action(b
->manager
, INHIBIT_HANDLE_POWER_KEY
, b
->manager
->handle_power_key
, b
->manager
->power_key_ignore_inhibited
, true);
232 /* The kernel naming is a bit confusing here:
233 KEY_RESTART was probably introduced for media playback purposes, but
234 is now being predominantly used to indicate device reboot.
238 if (b
->manager
->handle_reboot_key_long_press
!= HANDLE_IGNORE
&& b
->manager
->handle_reboot_key_long_press
!= b
->manager
->handle_reboot_key
) {
239 log_debug("Reboot key pressed. Further action depends on the key press duration.");
240 start_long_press(b
->manager
, &b
->manager
->reboot_key_long_press_event_source
, long_press_of_reboot_key_handler
);
243 LOG_MESSAGE("Reboot key pressed short."),
244 "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR
);
245 manager_handle_action(b
->manager
, INHIBIT_HANDLE_REBOOT_KEY
, b
->manager
->handle_reboot_key
, b
->manager
->reboot_key_ignore_inhibited
, true);
249 /* The kernel naming is a bit confusing here:
251 KEY_SLEEP = suspend-to-ram, which everybody else calls "suspend"
252 KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
256 if (b
->manager
->handle_suspend_key_long_press
!= HANDLE_IGNORE
&& b
->manager
->handle_suspend_key_long_press
!= b
->manager
->handle_suspend_key
) {
257 log_debug("Suspend key pressed. Further action depends on the key press duration.");
258 start_long_press(b
->manager
, &b
->manager
->suspend_key_long_press_event_source
, long_press_of_suspend_key_handler
);
261 LOG_MESSAGE("Suspend key pressed short."),
262 "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR
);
263 manager_handle_action(b
->manager
, INHIBIT_HANDLE_SUSPEND_KEY
, b
->manager
->handle_suspend_key
, b
->manager
->suspend_key_ignore_inhibited
, true);
268 if (b
->manager
->handle_hibernate_key_long_press
!= HANDLE_IGNORE
&& b
->manager
->handle_hibernate_key_long_press
!= b
->manager
->handle_hibernate_key
) {
269 log_debug("Hibernate key pressed. Further action depends on the key press duration.");
270 start_long_press(b
->manager
, &b
->manager
->hibernate_key_long_press_event_source
, long_press_of_hibernate_key_handler
);
273 LOG_MESSAGE("Hibernate key pressed short."),
274 "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR
);
275 manager_handle_action(b
->manager
, INHIBIT_HANDLE_HIBERNATE_KEY
, b
->manager
->handle_hibernate_key
, b
->manager
->hibernate_key_ignore_inhibited
, true);
280 } else if (ev
.type
== EV_KEY
&& ev
.value
== 0) {
286 if (b
->manager
->power_key_long_press_event_source
) {
287 /* Long press event timer is still pending and key release
288 event happened. This means that key press duration was
289 insufficient to trigger a long press event
292 LOG_MESSAGE("Power key pressed short."),
293 "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR
);
295 b
->manager
->power_key_long_press_event_source
= sd_event_source_unref(b
->manager
->power_key_long_press_event_source
);
297 manager_handle_action(b
->manager
, INHIBIT_HANDLE_POWER_KEY
, b
->manager
->handle_power_key
, b
->manager
->power_key_ignore_inhibited
, true);
302 if (b
->manager
->reboot_key_long_press_event_source
) {
304 LOG_MESSAGE("Reboot key pressed short."),
305 "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR
);
307 b
->manager
->reboot_key_long_press_event_source
= sd_event_source_unref(b
->manager
->reboot_key_long_press_event_source
);
309 manager_handle_action(b
->manager
, INHIBIT_HANDLE_REBOOT_KEY
, b
->manager
->handle_reboot_key
, b
->manager
->reboot_key_ignore_inhibited
, true);
314 if (b
->manager
->suspend_key_long_press_event_source
) {
316 LOG_MESSAGE("Suspend key pressed short."),
317 "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR
);
319 b
->manager
->suspend_key_long_press_event_source
= sd_event_source_unref(b
->manager
->suspend_key_long_press_event_source
);
321 manager_handle_action(b
->manager
, INHIBIT_HANDLE_SUSPEND_KEY
, b
->manager
->handle_suspend_key
, b
->manager
->suspend_key_ignore_inhibited
, true);
325 if (b
->manager
->hibernate_key_long_press_event_source
) {
327 LOG_MESSAGE("Hibernate key pressed short."),
328 "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR
);
330 b
->manager
->hibernate_key_long_press_event_source
= sd_event_source_unref(b
->manager
->hibernate_key_long_press_event_source
);
332 manager_handle_action(b
->manager
, INHIBIT_HANDLE_HIBERNATE_KEY
, b
->manager
->handle_hibernate_key
, b
->manager
->hibernate_key_ignore_inhibited
, true);
337 } else if (ev
.type
== EV_SW
&& ev
.value
> 0) {
339 if (ev
.code
== SW_LID
) {
341 LOG_MESSAGE("Lid closed."),
342 "MESSAGE_ID=" SD_MESSAGE_LID_CLOSED_STR
);
344 b
->lid_closed
= true;
345 button_lid_switch_handle_action(b
->manager
, true);
346 button_install_check_event_source(b
);
347 manager_send_changed(b
->manager
, "LidClosed", NULL
);
349 } else if (ev
.code
== SW_DOCK
) {
351 LOG_MESSAGE("System docked."),
352 "MESSAGE_ID=" SD_MESSAGE_SYSTEM_DOCKED_STR
);
357 } else if (ev
.type
== EV_SW
&& ev
.value
== 0) {
359 if (ev
.code
== SW_LID
) {
361 LOG_MESSAGE("Lid opened."),
362 "MESSAGE_ID=" SD_MESSAGE_LID_OPENED_STR
);
364 b
->lid_closed
= false;
365 b
->check_event_source
= sd_event_source_unref(b
->check_event_source
);
366 manager_send_changed(b
->manager
, "LidClosed", NULL
);
368 } else if (ev
.code
== SW_DOCK
) {
370 LOG_MESSAGE("System undocked."),
371 "MESSAGE_ID=" SD_MESSAGE_SYSTEM_UNDOCKED_STR
);
380 static int button_suitable(int fd
) {
381 unsigned long types
[CONST_MAX(EV_KEY
, EV_SW
)/ULONG_BITS
+1];
385 if (ioctl(fd
, EVIOCGBIT(EV_SYN
, sizeof types
), types
) < 0)
388 if (bitset_get(types
, EV_KEY
)) {
389 unsigned long keys
[CONST_MAX5(KEY_POWER
, KEY_POWER2
, KEY_SLEEP
, KEY_SUSPEND
, KEY_RESTART
)/ULONG_BITS
+1];
391 if (ioctl(fd
, EVIOCGBIT(EV_KEY
, sizeof keys
), keys
) < 0)
394 if (bitset_get(keys
, KEY_POWER
) ||
395 bitset_get(keys
, KEY_POWER2
) ||
396 bitset_get(keys
, KEY_SLEEP
) ||
397 bitset_get(keys
, KEY_SUSPEND
) ||
398 bitset_get(keys
, KEY_RESTART
))
402 if (bitset_get(types
, EV_SW
)) {
403 unsigned long switches
[CONST_MAX(SW_LID
, SW_DOCK
)/ULONG_BITS
+1];
405 if (ioctl(fd
, EVIOCGBIT(EV_SW
, sizeof switches
), switches
) < 0)
408 if (bitset_get(switches
, SW_LID
) ||
409 bitset_get(switches
, SW_DOCK
))
416 static int button_set_mask(const char *name
, int fd
) {
418 types
[CONST_MAX(EV_KEY
, EV_SW
)/ULONG_BITS
+1] = {},
419 keys
[CONST_MAX5(KEY_POWER
, KEY_POWER2
, KEY_SLEEP
, KEY_SUSPEND
, KEY_RESTART
)/ULONG_BITS
+1] = {},
420 switches
[CONST_MAX(SW_LID
, SW_DOCK
)/ULONG_BITS
+1] = {};
421 struct input_mask mask
;
426 bitset_put(types
, EV_KEY
);
427 bitset_put(types
, EV_SW
);
429 mask
= (struct input_mask
) {
431 .codes_size
= sizeof(types
),
432 .codes_ptr
= PTR_TO_UINT64(types
),
435 if (ioctl(fd
, EVIOCSMASK
, &mask
) < 0)
436 /* Log only at debug level if the kernel doesn't do EVIOCSMASK yet */
437 return log_full_errno(IN_SET(errno
, ENOTTY
, EOPNOTSUPP
, EINVAL
) ? LOG_DEBUG
: LOG_WARNING
,
438 errno
, "Failed to set EV_SYN event mask on /dev/input/%s: %m", name
);
440 bitset_put(keys
, KEY_POWER
);
441 bitset_put(keys
, KEY_POWER2
);
442 bitset_put(keys
, KEY_SLEEP
);
443 bitset_put(keys
, KEY_SUSPEND
);
444 bitset_put(keys
, KEY_RESTART
);
446 mask
= (struct input_mask
) {
448 .codes_size
= sizeof(keys
),
449 .codes_ptr
= PTR_TO_UINT64(keys
),
452 if (ioctl(fd
, EVIOCSMASK
, &mask
) < 0)
453 return log_warning_errno(errno
, "Failed to set EV_KEY event mask on /dev/input/%s: %m", name
);
455 bitset_put(switches
, SW_LID
);
456 bitset_put(switches
, SW_DOCK
);
458 mask
= (struct input_mask
) {
460 .codes_size
= sizeof(switches
),
461 .codes_ptr
= PTR_TO_UINT64(switches
),
464 if (ioctl(fd
, EVIOCSMASK
, &mask
) < 0)
465 return log_warning_errno(errno
, "Failed to set EV_SW event mask on /dev/input/%s: %m", name
);
470 int button_open(Button
*b
) {
471 _cleanup_(asynchronous_closep
) int fd
= -EBADF
;
478 b
->fd
= asynchronous_close(b
->fd
);
480 p
= strjoina("/dev/input/", b
->name
);
482 fd
= open(p
, O_RDWR
|O_CLOEXEC
|O_NOCTTY
|O_NONBLOCK
);
484 return log_warning_errno(errno
, "Failed to open %s: %m", p
);
486 r
= button_suitable(fd
);
488 return log_warning_errno(r
, "Failed to determine whether input device %s is relevant to us: %m", p
);
490 return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL
),
491 "Device %s does not expose keys or switches relevant to us, ignoring.", p
);
493 if (ioctl(fd
, EVIOCGNAME(sizeof name
), name
) < 0)
494 return log_error_errno(errno
, "Failed to get input name for %s: %m", p
);
496 (void) button_set_mask(b
->name
, fd
);
498 b
->io_event_source
= sd_event_source_unref(b
->io_event_source
);
499 r
= sd_event_add_io(b
->manager
->event
, &b
->io_event_source
, fd
, EPOLLIN
, button_dispatch
, b
);
501 return log_error_errno(r
, "Failed to add button event for %s: %m", p
);
504 log_info("Watching system buttons on %s (%s)", p
, name
);
508 int button_check_switches(Button
*b
) {
509 unsigned long switches
[CONST_MAX(SW_LID
, SW_DOCK
)/ULONG_BITS
+1] = {};
515 if (ioctl(b
->fd
, EVIOCGSW(sizeof(switches
)), switches
) < 0)
518 b
->lid_closed
= bitset_get(switches
, SW_LID
);
519 b
->docked
= bitset_get(switches
, SW_DOCK
);
520 manager_send_changed(b
->manager
, "LidClosed", NULL
);
523 button_install_check_event_source(b
);