all: osdd osdc osd-batt
osdd: osdd.o util.o
-osdc: osdc.o util.o send.o
-osd-batt: osd-batt.o util.o send.o
+osdc: osdc.o util.o client.o
+osd-batt: osd-batt.o util.o client.o loop.o
osdd.o: CFLAGS+=$(shell xosd-config --cflags)
osdd: LDFLAGS+=$(shell xosd-config --libs)
--- /dev/null
+/*
+ * On-screen Display -- Support Functions for Clients
+ *
+ * (c) 2010 Martin Mares <mj@ucw.cz>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <poll.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#undef DEBUG
+#include "osd.h"
+
+static Display *dpy;
+static Atom pty;
+
+#define MAX_MSG_SIZE 1024
+
+struct osd_msg {
+ int cnt;
+ char buf[MAX_MSG_SIZE];
+};
+
+void
+osd_init(void)
+{
+ if (dpy)
+ return;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy)
+ die("Cannot open display");
+
+ pty = XInternAtom(dpy, "OSD_QUEUE", False);
+ if (!pty)
+ die("Cannot intern OSD_QUEUE atom");
+}
+
+struct osd_msg *
+osd_new_msg(void)
+{
+ struct osd_msg *msg = xmalloc(sizeof(*msg));
+ msg->cnt = 0;
+ return msg;
+}
+
+void
+osd_add_line(struct osd_msg *msg, char *key, char *val)
+{
+ if (!key)
+ key = "";
+ msg->cnt += snprintf(msg->buf + msg->cnt, MAX_MSG_SIZE - msg->cnt - 1, "%s:%s\n", key, val);
+ if (msg->cnt > MAX_MSG_SIZE - 1)
+ die("OSD message too long (at most %d bytes)", MAX_MSG_SIZE);
+}
+
+void
+osd_send(struct osd_msg *msg)
+{
+ osd_init();
+ msg->buf[msg->cnt++] = '\n';
+ if (!XChangeProperty(dpy, DefaultRootWindow(dpy), pty, XA_STRING, 8, PropModeAppend, (unsigned char *) msg->buf, msg->cnt))
+ die("XChangeProperty failed");
+ XFlush(dpy);
+ free(msg);
+}
+
+void
+osd_fork(void)
+{
+ osd_init();
+ pid_t pid = fork();
+ if (pid < 0)
+ die("Cannot fork: %m");
+ if (pid > 0)
+ exit(0);
+ setsid();
+}
+
+void
+osd_wait(int delay)
+{
+ DBG("Waiting for %d seconds\n", delay);
+ timestamp_t wait_until = get_current_time() + delay*1000;
+
+ struct pollfd pfd = {
+ .fd = ConnectionNumber(dpy),
+ .events = POLLIN,
+ };
+
+ for (;;)
+ {
+ timestamp_t now = get_current_time();
+ if (now >= wait_until)
+ return;
+
+ DBG("... waiting for %d ms\n", (int)(wait_until - now));
+ poll(&pfd, 1, wait_until - now);
+ if (pfd.revents & POLLIN)
+ {
+ XEvent ev;
+ while (XPending(dpy))
+ XNextEvent(dpy, &ev);
+ }
+ }
+}
#include <dirent.h>
#include <getopt.h>
-#include "util.h"
-#include "send.h"
+#include "osd.h"
static int check_mode;
+static int check_every;
static int warn_threshold = 600;
static int total_full, total_capa, discharge_rate;
osd_send(msg);
}
+static void show_if_warn(void)
+{
+ if (discharge_mask && discharge_time < warn_threshold)
+ show();
+}
+
static void NONRET
usage(void)
{
\n\
Options:\n\
-c, --check\t\tDisplay status only if battery is low\n\
+-e, --check-every=<sec>\tRun on background and check every <sec> seconds\n\
-w, --warn=<sec>\tBattery is low if less than <sec> seconds remain (default: 600)\n\
");
exit(1);
}
-static const char short_opts[] = "cw:";
+static const char short_opts[] = "ce:w:";
static const struct option long_opts[] = {
{ "check", no_argument, NULL, 'c' },
+ { "check-every", required_argument, NULL, 'e' },
{ "warn", required_argument, NULL, 'w' },
{ NULL, 0, NULL, 0 },
};
case 'c':
check_mode++;
break;
+ case 'e':
+ check_every = atoi(optarg);
+ break;
case 'w':
warn_threshold = atoi(optarg);
break;
if (optind < argc)
usage();
+ if (check_every)
+ {
+ osd_fork();
+ for (;;)
+ {
+ scan();
+ show_if_warn();
+ osd_wait(check_every);
+ }
+ }
+
scan();
- if (!check_mode || (discharge_mask && discharge_time < warn_threshold))
+ if (check_mode)
+ show_if_warn();
+ else
show();
return 0;
--- /dev/null
+/*
+ * On-screen Display Daemon -- Utility Functions
+ *
+ * (c) 2010 Martin Mares <mj@ucw.cz>
+ */
+
+#include <inttypes.h>
+
+#define NONRET __attribute__((noreturn))
+#define FORMAT_CHECK(func,i,j) __attribute__((format(func,i,j)))
+
+typedef uint64_t timestamp_t;
+
+/* util.c */
+
+void NONRET FORMAT_CHECK(printf,1,2) die(char *fmt, ...);
+
+#ifdef DEBUG
+#define DBG(f...) printf(f)
+#else
+#define DBG(f...) do { } while(0)
+#endif
+
+void *xmalloc(int size);
+
+timestamp_t get_current_time(void);
+
+/* client.c */
+
+void osd_init(void);
+
+struct osd_msg;
+struct osd_msg *osd_new_msg(void);
+void osd_add_line(struct osd_msg *msg, char *key, char *val);
+void osd_send(struct osd_msg *msg);
+
+void osd_fork(void);
+void osd_wait(int seconds);
#include <X11/Xlib.h>
#include <X11/Xatom.h>
-#include "util.h"
-#include "send.h"
+#include "osd.h"
static struct osd_msg *msg;
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <inttypes.h>
#include <poll.h>
#include <getopt.h>
-#include <sys/time.h>
#include <xosd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#undef DEBUG
-#include "util.h"
+#include "osd.h"
static xosd *osd;
-typedef uint64_t timestamp_t;
static timestamp_t now;
/*** Options ***/
{
pid_t pid = fork();
if (pid < 0)
- {
- fprintf(stderr, "batt: Cannot fork: %m\n");
- return 1;
- }
+ die("Cannot fork: %m");
if (pid > 0)
return 0;
setsid();
for (;;)
{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- now = (timestamp_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ now = get_current_time();
timestamp_t wait_until = now - 1;
if (!current_msg && first_msg)
+++ /dev/null
-/*
- * On-screen Display Client -- Sending Messages
- *
- * (c) 2010 Martin Mares <mj@ucw.cz>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-#include "util.h"
-#include "send.h"
-
-static Display *dpy;
-static Atom pty;
-
-#define MAX_MSG_SIZE 1024
-
-struct osd_msg {
- int cnt;
- char buf[MAX_MSG_SIZE];
-};
-
-void
-osd_init(void)
-{
- dpy = XOpenDisplay(NULL);
- if (!dpy)
- die("Cannot open display");
-
- pty = XInternAtom(dpy, "OSD_QUEUE", False);
- if (!pty)
- die("Cannot intern OSD_QUEUE atom");
-}
-
-struct osd_msg *
-osd_new_msg(void)
-{
- struct osd_msg *msg = xmalloc(sizeof(*msg));
- msg->cnt = 0;
- return msg;
-}
-
-void
-osd_add_line(struct osd_msg *msg, char *key, char *val)
-{
- if (!key)
- key = "";
- msg->cnt += snprintf(msg->buf + msg->cnt, MAX_MSG_SIZE - msg->cnt - 1, "%s:%s\n", key, val);
- if (msg->cnt > MAX_MSG_SIZE - 1)
- die("OSD message too long (at most %d bytes)", MAX_MSG_SIZE);
-}
-
-void
-osd_send(struct osd_msg *msg)
-{
- if (!dpy)
- osd_init();
-
- msg->buf[msg->cnt++] = '\n';
- if (!XChangeProperty(dpy, DefaultRootWindow(dpy), pty, XA_STRING, 8, PropModeAppend, (unsigned char *) msg->buf, msg->cnt))
- die("XChangeProperty failed");
- XFlush(dpy);
- free(msg);
-}
+++ /dev/null
-/*
- * On-screen Display Client -- Sending Messages
- *
- * (c) 2010 Martin Mares <mj@ucw.cz>
- */
-
-void osd_init(void);
-
-struct osd_msg;
-struct osd_msg *osd_new_msg(void);
-void osd_add_line(struct osd_msg *msg, char *key, char *val);
-void osd_send(struct osd_msg *msg);
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <sys/time.h>
-#include "util.h"
+#include "osd.h"
void __attribute__((noreturn)) __attribute__((format(printf,1,2)))
die(char *fmt, ...)
die("Failed to allocate %d bytes of memory", size);
return p;
}
+
+timestamp_t
+get_current_time(void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (timestamp_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+++ /dev/null
-/*
- * On-screen Display Daemon -- Utility Functions
- *
- * (c) 2010 Martin Mares <mj@ucw.cz>
- */
-
-#define NONRET __attribute__((noreturn))
-#define FORMAT_CHECK(func,i,j) __attribute__((format(func,i,j)))
-
-void NONRET FORMAT_CHECK(printf,1,2) die(char *fmt, ...);
-
-#ifdef DEBUG
-#define DBG(f...) printf(f)
-#else
-#define DBG(f...) do { } while(0)
-#endif
-
-void *xmalloc(int size);