X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=osdd.c;h=a3364fc8526306a91996b5fdd65a551b3d78a9cf;hb=7a1095480979e4500f62b74c67941512941b9c57;hp=15836ea51b7d36377197c5a94fd307bdb16b64e1;hpb=845e5d4b6ac0a561a0ee55f6a11bdb4380d4e014;p=osdd.git diff --git a/osdd.c b/osdd.c index 15836ea..a3364fc 100644 --- a/osdd.c +++ b/osdd.c @@ -1,49 +1,55 @@ /* * On-screen Display Daemon * - * (c) 2010 Martin Mares + * (c) 2010--2014 Martin Mares */ #include #include #include #include -#include #include #include -#include -#include +#include #include #include #undef DEBUG #include "util.h" +#include "display.h" -static xosd *osd; +static struct osd_state *osd; -typedef uint64_t timestamp_t; static timestamp_t now; /*** Options ***/ -static int num_lines = 4; -static char *font_name = "-bitstream-bitstream vera sans-bold-r-normal-*-*-320-*-*-p-*-*"; +static char *font_name = "times-64:bold"; static char *default_color = "green"; static char *default_outline_color = "black"; +static int default_outline_width = 2; static int default_duration = 1000; -static int default_min_duration = 1000; +static int default_min_duration = 250; static int debug_mode; +static int test_mode; +static double line_spacing = 0.2; -static const char short_opts[] = "c:d:Df:l:m:o:"; +static const char short_opts[] = "c:d:Df:m:o:O:s:"; + +enum long_opt { + OPT_TEST = 256, +}; static const struct option long_opts[] = { { "color", required_argument, NULL, 'c' }, { "debug", no_argument, NULL, 'D' }, { "duration", required_argument, NULL, 'd' }, { "font", required_argument, NULL, 'f' }, - { "lines", required_argument, NULL, 'l' }, { "min-duration", required_argument, NULL, 'm' }, { "outline-color", required_argument, NULL, 'o' }, + { "outline-width", required_argument, NULL, 'O' }, + { "line-spacing", required_argument, NULL, 's' }, + { "test", no_argument, NULL, OPT_TEST }, // Undocumented test mode { NULL, 0, NULL, 0 }, }; @@ -56,9 +62,10 @@ Options:\n\ -D, --debug\t\tDebugging mode (do not detach from the terminal)\n\ -d, --duration=\tDefault message duration in milliseconds\n\ -f, --font=\t\tFont to use for the OSD\n\ --l, --lines=\t\tNumber of lines of the OSD\n\ -m, --min-duration=\tDefault minimum message duration in milliseconds\n\ -o, --outline-color=\tDefault outline color\n\ +-O, --outline-width=\tDefault outline width (default=2)\n\ +-s, --line-spacing=\tSet line spacing factor (decimal fraction, default=0.2)\n\ "); exit(1); } @@ -83,9 +90,7 @@ parse_opts(int argc, char **argv) font_name = optarg; break; case 'l': - num_lines = atoi(optarg); - if (num_lines < 1) - usage(); + line_spacing = atof(optarg); break; case 'm': default_min_duration = atoi(optarg); @@ -93,6 +98,13 @@ parse_opts(int argc, char **argv) case 'o': default_outline_color = optarg; break; + case 'O': + default_outline_width = atoi(optarg); + break; + case OPT_TEST: + test_mode = 1; + debug_mode = 1; + break; default: usage(); } @@ -115,11 +127,11 @@ display_msg(struct msg *msg) DBG("## Displaying message\n"); msg->min_light = now + default_min_duration; msg->max_light = now + default_duration; - xosd_set_colour(osd, default_color); - xosd_set_outline_colour(osd, default_outline_color); + char *fg_color = default_color; + char *outline_color = default_outline_color; + int outline_width = default_outline_width; char *line = msg->text; - int row = 0; while (*line) { // The parser it destructive, but it does not do any harm, since we display each message only once. @@ -140,46 +152,54 @@ display_msg(struct msg *msg) } DBG("\t%s:%s\n", key, val); + struct osd_line *l = NULL; if (!key[0]) { - if (row < num_lines) - xosd_display(osd, row++, XOSD_string, val); + l = osd_add_line(osd, OSD_TYPE_TEXT); + sprintf(l->u.text, "%.*s", OSD_MAX_LINE_LEN, val); } else if (!strcmp(key, "percentage") || !strcmp(key, "percent")) { - if (row < num_lines) - xosd_display(osd, row++, XOSD_percentage, atoi(val)); + l = osd_add_line(osd, OSD_TYPE_PERCENTAGE); + l->u.percent = atoi(val); } else if (!strcmp(key, "slider")) { - if (row < num_lines) - xosd_display(osd, row++, XOSD_slider, atoi(val)); + l = osd_add_line(osd, OSD_TYPE_SLIDER); + l->u.percent = atoi(val); } else if (!strcmp(key, "duration")) msg->max_light = now + atoi(val); else if (!strcmp(key, "min-duration")) msg->min_light = now + atoi(val); else if (!strcmp(key, "color")) - xosd_set_colour(osd, val); + fg_color = val; else if (!strcmp(key, "outline-color")) - xosd_set_outline_colour(osd, val); - else - xosd_display(osd, (row < num_lines ? row++ : num_lines-1), XOSD_string, "PARSE ERROR"); + outline_color = val; + else if (!strcmp(key, "outline-width")) + outline_width = atoi(val); + + if (l) + { + l->fg_color = fg_color; + l->outline_color = outline_color; + l->outline_width = outline_width; + } line = nl; } if (msg->min_light > msg->max_light) msg->min_light = msg->max_light; + + osd_show(osd); } static void hide_msg(struct msg *msg) { DBG("## Hiding message\n"); - for (int i=0; i 0) + len += c; + if (len) + enqueue_msg(buf, len); +} + /*** Main loop ***/ int main(int argc, char **argv) { parse_opts(argc, argv); + setlocale(LC_CTYPE, ""); XInitThreads(); Display *dpy = XOpenDisplay(NULL); @@ -246,26 +280,26 @@ main(int argc, char **argv) { 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(); } - XSelectInput(dpy, win, PropertyChangeMask); - XDeleteProperty(dpy, win, pty); - XFlush(dpy); + if (test_mode) + { + do_test(); + pty = 0; + } + else + { + XSelectInput(dpy, win, PropertyChangeMask); + XDeleteProperty(dpy, win, pty); + XFlush(dpy); + } - osd = xosd_create(num_lines); - if (!osd) - die("Cannot initialize OSD"); - xosd_set_font(osd, font_name); - xosd_set_outline_offset(osd, 2); - xosd_set_pos(osd, XOSD_middle); - xosd_set_align(osd, XOSD_center); + osd = osd_new(dpy); + osd_set_font(osd, font_name, line_spacing); struct pollfd pfd = { .fd = ConnectionNumber(dpy), @@ -274,9 +308,7 @@ main(int argc, char **argv) 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) @@ -298,6 +330,8 @@ main(int argc, char **argv) continue; } } + if (test_mode && !current_msg) + break; DBG("... waiting for %d ms\n", (int)(wait_until - now)); poll(&pfd, 1, wait_until - now); @@ -307,6 +341,8 @@ main(int argc, char **argv) { XEvent ev; XNextEvent(dpy, &ev); + if (osd_handle_event(osd, &ev)) + continue; if (ev.type != PropertyNotify) continue; XPropertyEvent *p = &ev.xproperty;