167 lines
3.1 KiB
C
167 lines
3.1 KiB
C
#include <errno.h>
|
|
#include <getopt.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <sys/poll.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/un.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "log.h"
|
|
#include "led.h"
|
|
#include "wayland.h"
|
|
#include "acpi.h"
|
|
#include "utils.h"
|
|
|
|
#include "config.h"
|
|
|
|
#define MAX_BUFLEN 1024
|
|
|
|
char
|
|
*battery_percent(void)
|
|
{
|
|
char *r, c, *d;
|
|
int i;
|
|
FILE *f;
|
|
|
|
/* open up the battery capacity for reading */
|
|
d = concat(battery_dir, "/capacity");
|
|
f = fopen(d, "r");
|
|
free(d);
|
|
|
|
/* create enough space for the battery percentage */
|
|
r = calloc(4, sizeof(char));
|
|
|
|
/* read in the battery percentage */
|
|
i = 0;
|
|
while ((c = getc(f)) && i < 4) {
|
|
/* make sure to replace the newline with a string terminator */
|
|
if (c == '\n') {
|
|
r[i] = '\0';
|
|
break;
|
|
}
|
|
r[i] = c;
|
|
i++;
|
|
}
|
|
|
|
fclose(f);
|
|
return r;
|
|
}
|
|
|
|
bool
|
|
plugged_in(char *fn)
|
|
{
|
|
FILE *f;
|
|
char buf[1];
|
|
|
|
f = fopen(fn, "r");
|
|
if (read(fileno(f), buf, 1) < 0) {
|
|
return -1;
|
|
}
|
|
fclose(f);
|
|
|
|
return buf[0] - '0';
|
|
}
|
|
|
|
void
|
|
on_battery_event(char *percent, bool plugged)
|
|
{
|
|
char *ep;
|
|
int res;
|
|
double rate;
|
|
|
|
if (!plugged) {
|
|
/* convert battery percentage to an int */
|
|
res = strtol(percent, &ep, 10);
|
|
|
|
if (res <= blink_start) {
|
|
rate = blink_formula(res);
|
|
if (rate >= 1) {
|
|
led_set_rate(rate);
|
|
}
|
|
} else {
|
|
led_set_rate(0);
|
|
}
|
|
|
|
wayland_set_idle_lock(false);
|
|
} else {
|
|
led_set_rate(0);
|
|
wayland_set_idle_lock(true);
|
|
}
|
|
|
|
free(percent);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
bool plugged = plugged_in((char *)linefile);
|
|
char buffer[MAX_BUFLEN], *out[4];
|
|
int sock_fd;
|
|
|
|
/* set the logging level */
|
|
log_set_level(LOG_DEBUG);
|
|
|
|
/* open up socket address */
|
|
sock_fd = acpi_create_socket((char *)acpid_sock);
|
|
|
|
/* create the led thread */
|
|
led_create_thread((char *)ledfile);
|
|
|
|
/* create the wayland thread */
|
|
wayland_create_thread();
|
|
|
|
/* run events that need to be run on start to ensure that the current state
|
|
* inside the program reflects that that is outside the program
|
|
*/
|
|
on_battery_event(battery_percent(), plugged);
|
|
|
|
/* zero buffer */
|
|
memset(out, 0, sizeof(out));
|
|
|
|
for (;;) {
|
|
/* read input */
|
|
memset(buffer, 0, MAX_BUFLEN);
|
|
if (read(sock_fd, buffer, MAX_BUFLEN) < 0) {
|
|
log_fatal("read: %s", strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
/* parse */
|
|
if (acpi_parse(buffer, out) != 0) {
|
|
continue;
|
|
}
|
|
|
|
/* rules */
|
|
if (strcmp(out[0], "ac_adapter") == 0) {
|
|
char *s = get_substring(out[1], 0, 2);
|
|
|
|
if (strcmp(s, "AC") == 0) {
|
|
plugged = plugged_in((char *)linefile);
|
|
}
|
|
|
|
free(s);
|
|
} else if (strcmp(out[0], "battery") == 0) {
|
|
char *s = get_substring(out[1], 0, 3);
|
|
|
|
if (strcmp(s, "PNP") == 0) {
|
|
if (strcmp(out[2], "00000080") == 0) {
|
|
if (strcmp(out[3], "00000001") == 0) {
|
|
on_battery_event(battery_percent(), plugged);
|
|
}
|
|
}
|
|
}
|
|
free(s);
|
|
}
|
|
|
|
acpi_clean_parse(out);
|
|
}
|
|
|
|
acpi_close_socket(sock_fd);
|
|
}
|