X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=client.c;fp=client.c;h=8b439f316462a16352fcf4c3bed54696b5290a08;hb=0ab80500fd3a7e262417c707022dffbcd8655ba6;hp=0000000000000000000000000000000000000000;hpb=6b0069005ee1fc055a16983d675dc13db38170af;p=osdd.git diff --git a/client.c b/client.c new file mode 100644 index 0000000..8b439f3 --- /dev/null +++ b/client.c @@ -0,0 +1,110 @@ +/* + * On-screen Display -- Support Functions for Clients + * + * (c) 2010 Martin Mares + */ + +#include +#include +#include +#include +#include +#include +#include + +#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); + } + } +}