Browse Source

First commit

master
Santificado 3 months ago
commit
48d89b4086
Signed by: Santificado <santificado@national.shitposting.agency> GPG Key ID: 83B9AD06C3519724
4 changed files with 283 additions and 0 deletions
  1. +16
    -0
      Makefile
  2. +94
    -0
      dwmstatus-pulse.c
  3. +10
    -0
      dwmstatus-repeat
  4. +163
    -0
      dwmstatus.c

+ 16
- 0
Makefile View File

@@ -0,0 +1,16 @@
PREFIX=/usr/local

all: dwmstatus dwmstatus-pulse

clean:
rm -f dwmstatus dwmstatus-pulse

install:
cp dwmstatus $(PREFIX)/bin
cp dwmstatus-pulse $(PREFIX)/bin

dwmstatus-pulse: dwmstatus-pulse.c
$(CC) $< `pkg-config --libs libpulse-mainloop-glib` -o $@

%: %.c
$(CC) $< -o $@

+ 94
- 0
dwmstatus-pulse.c View File

@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pulse/pulseaudio.h>
#include <unistd.h>

static char *default_label = "";
static char *label = NULL;
static char *device_name = NULL;

static void
sinkcbk(pa_context *ctx, const pa_sink_info *i, int eol, void *userdata)
{
if(!i)
return;

float volume = (float)pa_cvolume_avg(&i->volume) / (float)PA_VOLUME_NORM;
if(i->mute)
printf("MUTE\n");
else
printf("%s%0.0f\n", label, volume * 100);
fflush(stdout);
}

static void
eventcbk(pa_context *ctx, pa_subscription_event_type_t t, uint32_t idx, void *data)
{
pa_operation *op = NULL;
if((t & (PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE)))
op = pa_context_get_sink_info_by_name(ctx, device_name, sinkcbk, data);

if(op)
pa_operation_unref(op);
}

static void
servercbk(pa_context *ctx, const pa_server_info *i, void *user)
{
device_name = strdup(i->default_sink_name);
}

int
main(int argc, char *argv[])
{
int c;
pa_mainloop *mloop;
pa_mainloop_api *mloopapi;
pa_context *ctx;
pa_context_state_t state;
pa_operation *op;

label = default_label;
while((c = getopt(argc, argv, "d:l:")) > 0) {
switch(c) {
case 'd':
device_name = strdup(optarg);
break;
case 'l':
label = strdup(optarg);
break;
}
}

mloop = pa_mainloop_new();
mloopapi = pa_mainloop_get_api(mloop);
ctx = pa_context_new(mloopapi, "DWMstatus audio");
pa_context_connect(ctx, NULL, 0, NULL);

/* wait until ready */
while((state = pa_context_get_state(ctx)) != PA_CONTEXT_READY) {
switch(state) {
case PA_CONTEXT_FAILED:
case PA_CONTEXT_TERMINATED:
goto end;
default: ;/* do nothing */
}
pa_mainloop_iterate(mloop, 1, NULL);
}

op = pa_context_get_server_info(ctx, servercbk, NULL);
pa_operation_unref(op);

pa_context_set_subscribe_callback(ctx, eventcbk, NULL);
pa_context_subscribe(ctx, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, NULL, NULL);
eventcbk(ctx, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, 0, NULL);
pa_mainloop_run(mloop, NULL);

end:
pa_context_disconnect(ctx);
pa_context_unref(ctx);
pa_mainloop_free(mloop);

return 0;
}

+ 10
- 0
dwmstatus-repeat View File

@@ -0,0 +1,10 @@
#!/bin/sh

TIME=$1
shift

while true
do
$@
sleep $TIME
done

+ 163
- 0
dwmstatus.c View File

@@ -0,0 +1,163 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <errno.h>

#include <unistd.h>
#include <sys/select.h>
#include <sys/fcntl.h>
#include <sys/wait.h>

typedef struct Process Process;
struct Process {
pid_t pid;
int fd;
char str[64];
Process *next;
};
static Process *list = NULL;

int
max(int a, int b)
{
return (a > b ? a : b);
}

Process *
newproc(const char *command)
{
Process *p;
int pipes[2];
pid_t pid;
if(pipe(pipes) < 0) {
perror("pipe()");
exit(EXIT_FAILURE);
}

switch((pid = fork())) {
case -1:
perror("fork()");
exit(EXIT_FAILURE);
case 0:
close(0);
close(1);
dup2(pipes[1], 1);
close(pipes[0]);
close(pipes[1]);
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
exit(EXIT_SUCCESS);
return NULL;
default:
close(pipes[1]);
p = malloc(sizeof *p);
if(!p) {
perror("malloc()");
exit(EXIT_FAILURE);
}
memset(p, 0, sizeof *p);
p->pid = pid;
p->fd = pipes[0];
return p;
}
}

static void
sigtrap(int sig)
{
if(sig != SIGINT)
return;

for(Process *p = list; p; p = p->next) {
killpg(p->pid, sig);
}
while(wait(NULL) != -1 || errno == EINTR);

/* let the operating take care of the memory leak, fuck it */
exit(EXIT_SUCCESS);
}

int
linerd(int fd, char *line, int linesize)
{
int i;
for(i = 0; i < linesize; i++) {
char c;
if(read(fd, &c, sizeof c) <= 0) {
break;
}

if(c == '\n') {
line[i] = 0;
break;
}
line[i] = c;
}
line[linesize - 1] = 0;
return i;
}

int
main(int argc, char *argv[])
{
int maxfd = 0, i, c;
fd_set rdset;
Process *p;

signal(SIGINT, sigtrap);
signal(SIGTERM, sigtrap);
signal(SIGKILL, sigtrap);

FD_ZERO(&rdset);

while((c = getopt(argc, argv, "c:")) > 0) {
switch(c) {
case 'c':
p = newproc(optarg);
FD_SET(p->fd, &rdset);
maxfd = max(maxfd, p->fd);
p->next = list;
list = p;
break;
default:
fprintf(stderr, "Unknown option: %c\n", c);
exit(EXIT_FAILURE);
}
}

if(!list) {
fprintf(stderr, "usage: %s -c command [-c command2 ]...\n", argv[0]);
exit(EXIT_FAILURE);
}
for(;;) {
int n;
fd_set copy;
FD_ZERO(&copy);
memcpy(&copy, &rdset, sizeof rdset);
n = select(maxfd + 1, &copy, NULL, NULL, NULL);
if(n < 0) {
perror("select()");
continue;
}

for(Process *p = list; p; p = p->next)
if(FD_ISSET(p->fd, &copy)) {
if(linerd(p->fd, p->str, sizeof p->str) <= 0) {
FD_CLR(p->fd, &rdset);
close(p->fd);
}
}

for(Process *p = list; p; p = p->next)
printf("%s%s", p->str, p->next ? " | " : "");

printf("\n");
fflush(stdout);
}
return 0;
}

Loading…
Cancel
Save