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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/* Copyright (C) 2025 awy <awy@awy.one>
stmpdup is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
stmpdup is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with stmpdup. If not, see
<https://www.gnu.org/licenses/>. */
/* cmd_idle and cmd_idleloop functions are taken from the
MPC <https://github.com/MusicPlayerDaemon/mpc> */
#define _POSIX_C_SOURCE 200112L
#include <ctype.h>
#include <mpd/client.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include "../lib/util.h"
int
find_pid_by_name(const char *process_name)
{
DIR *dir = opendir("/proc");
if (!dir) return -1;
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (!isdigit(entry->d_name[0])) continue;
char path[256], name[256];
snprintf(path, sizeof(path), "/proc/%s/comm", entry->d_name);
FILE *fp = fopen(path, "r");
if (!fp) continue;
if (fgets(name, sizeof(name), fp)) {
name[strcspn(name, "\n")] = 0;
if (strcmp(name, process_name) == 0) {
fclose(fp);
closedir(dir);
return atoi(entry->d_name);
}
}
fclose(fp);
}
closedir(dir);
return -1;
}
int cmd_idle(struct mpd_connection *connection)
{
enum mpd_idle idle = 0;
pid_t wbarpid;
idle = idle == 0 ? mpd_run_idle(connection)
: mpd_run_idle_mask(connection, idle);
if (idle == 0 &&
mpd_connection_get_error(connection) != MPD_ERROR_SUCCESS)
printf("error");
for (unsigned j = 0;; ++j) {
enum mpd_idle i = 1 << j;
const char *name = mpd_idle_name(i);
if (name == NULL)
break;
if (idle & i) {
wbarpid = find_pid_by_name("waybar");
if (wbarpid == -1)
die("no waybar running");
kill(wbarpid, SIGRTMIN+11);
}
}
return 0;
}
int
cmd_idleloop(struct mpd_connection *connection)
{
while (true) {
int ret = cmd_idle(connection);
fflush(stdout);
if (ret != 0)
return ret;
}
}
int
main(void)
{
struct mpd_connection *conn;
conn = mpd_connection_new(NULL, 0, 30000);
if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
fprintf(stderr, "MPD connection error: %s\n",
mpd_connection_get_error_message(conn));
return 1;
}
cmd_idleloop(conn);
return 0;
}
|