-
Notifications
You must be signed in to change notification settings - Fork 0
/
powerbuttond.c
92 lines (83 loc) · 1.9 KB
/
powerbuttond.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// SPDX-License-Identifier: BSD-2-Clause
//
// Copyright (c) 2023 Valve Software
// Maintainer: Vicki Pfau <[email protected]>
#include <errno.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#include <limits.h>
#include <signal.h>
#include <spawn.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
extern char** environ;
void signal_handler(int) {
}
struct libevdev* find_dev(void) {
int fd = open("/dev/input/by-path/platform-i8042-serio-0-event-kbd", O_RDONLY);
if (fd < 0) {
return NULL;
}
struct libevdev* dev;
if (libevdev_new_from_fd(fd, &dev) < 0) {
close(fd);
return NULL;
}
return dev;
}
void do_press(const char* type) {
char steam[PATH_MAX];
char press[32];
char* home = getenv("HOME");
char* const args[] = {steam, "-ifrunning", press, NULL};
snprintf(steam, sizeof(steam), "%s/.steam/root/ubuntu12_32/steam", home);
snprintf(press, sizeof(press), "steam://%spowerpress", type);
pid_t pid;
if (posix_spawn(&pid, steam, NULL, NULL, args, environ) < 0) {
return;
}
while (true) {
if (waitpid(pid, NULL, 0) > 0) {
break;
}
if (errno != EINTR && errno != EAGAIN) {
break;
}
}
}
int main() {
struct sigaction sa = {
.sa_handler = signal_handler,
.sa_flags = SA_NOCLDSTOP,
};
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM, &sa, NULL);
struct libevdev* dev = find_dev();
if (!dev) {
return 1;
}
bool press_active = false;
while (true) {
struct input_event ev;
int res = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_BLOCKING, &ev);
if (res == LIBEVDEV_READ_STATUS_SUCCESS) {
if (ev.type == EV_KEY && ev.code == KEY_POWER) {
if (ev.value == 1) {
press_active = true;
alarm(1);
} else if (press_active) {
press_active = false;
alarm(0);
do_press("short");
}
}
} else if (res == -EINTR && press_active) {
press_active = false;
alarm(0);
do_press("long");
}
}
}