]> mj.ucw.cz Git - osdd.git/commitdiff
New display code supports sliders and percentages
authorMartin Mares <mj@ucw.cz>
Thu, 23 Jan 2014 22:00:33 +0000 (23:00 +0100)
committerMartin Mares <mj@ucw.cz>
Thu, 23 Jan 2014 22:00:33 +0000 (23:00 +0100)
They come in two possible designs, selectable by compile-time switch
SLIDERS_WITH_BRACKETS in display.c. I yet have to decide which design
should be the default one and if it should be possible to switch
designs in run-time.

display.c
display.h
osdd.c

index 8bb79992af544751e46af69b79c6be9f1c38e457..8f82dca7b19b844197d58b2a9047bb3a646ab83a 100644 (file)
--- a/display.c
+++ b/display.c
@@ -1,7 +1,7 @@
 /*
  *     On-screen Display
  *
- *     (c) 2013 Martin Mares <mj@ucw.cz>
+ *     (c) 2013--2014 Martin Mares <mj@ucw.cz>
  *
  *     This code is heavily inspired by the libxosd library,
  *     which is (c) 2000, 2001 Andre Renaud <andre@ignavus.net>.
@@ -22,6 +22,8 @@
 #include "util.h"
 #include "display.h"
 
+#define SLIDERS_WITH_BRACKETS
+
 struct osd_state {
   // Basic characteristics of current display and screen
   Display *dpy;
@@ -55,6 +57,10 @@ struct osd_state {
   int line_height;
   int line_skip;
   bool visible;
+
+  // Used temporarily when drawing a line
+  XftColor fg_color;
+  XftColor mask_color;
 };
 
 static void
@@ -183,6 +189,10 @@ struct osd_line *osd_add_line(struct osd_state *osd, enum osd_line_type type)
     case OSD_TYPE_TEXT:
       l->u.text[0] = 0;
       break;
+    case OSD_TYPE_PERCENTAGE:
+    case OSD_TYPE_SLIDER:
+      l->u.percent = 0;
+      break;
     default:
       die("osd_add_line: unknown type %d", type);
     }
@@ -204,6 +214,27 @@ static void osd_prepare_line(struct osd_state *osd, int i)
        line->height = osd->line_distance + 2*line->outline_width;
        break;
       }
+    case OSD_TYPE_PERCENTAGE:
+    case OSD_TYPE_SLIDER:
+      {
+#ifdef SLIDERS_WITH_BRACKETS
+       line->slider_unit = osd->line_height / 5;
+       line->slider_space = osd->line_height / 5;
+#else
+       line->slider_unit = osd->line_height / 3;
+       line->slider_space = osd->line_height / 6;
+#endif
+       if (!line->slider_space)
+         line->slider_space = line->slider_unit = 1;
+       int use_width = osd->screen_width * 4 / 5;
+       int u = line->slider_unit + line->slider_space;
+       line->slider_units = (use_width + line->slider_space) / u;
+       if (line->slider_units < 3)
+         line->slider_units = 3;
+       line->width = line->slider_units*u - line->slider_space + 2*line->outline_width;
+       line->height = osd->line_height + 2*line->outline_width;
+       break;
+      }
     default:
       die("osd_recalc_line: unknown type %d", line->type);
     }
@@ -252,16 +283,24 @@ static void osd_prepare(struct osd_state *osd)
     }
 }
 
+static void osd_draw_box(struct osd_state *osd, struct osd_line *line, int x, int y, int w, int h)
+{
+  XftDrawRect(osd->mask_draw, &osd->mask_color,
+    x - line->outline_width, y - line->outline_width,
+    w + 2*line->outline_width, h + 2*line->outline_width);
+  XftDrawRect(osd->image_draw, &osd->fg_color, x, y, w, h);
+}
+
 static void osd_draw_line(struct osd_state *osd, int i)
 {
   struct osd_line *line = &osd->lines[i];
 
   // Allocate colors
-  XftColor fg_color, outline_color, mask_color;
+  XftColor outline_color;
   XRenderColor mask_rc = { .red = 0xffff, .green = 0xffff, .blue = 0xffff, .alpha = 0xffff };
-  if (!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->fg_color, &fg_color) ||
+  if (!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->fg_color, &osd->fg_color) ||
       !XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->outline_color, &outline_color) ||
-      !XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &mask_color))
+      !XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &osd->mask_color))
     die("Cannot allocate colors");
 
   // Draw background in outline color
@@ -276,24 +315,67 @@ static void osd_draw_line(struct osd_state *osd, int i)
 
        unsigned char *text = (unsigned char *) line->u.text;
        int text_len = strlen(line->u.text);
-       XftDrawStringUtf8(osd->image_draw, &fg_color, osd->font, x, y, text, text_len);
+       XftDrawStringUtf8(osd->image_draw, &osd->fg_color, osd->font, x, y, text, text_len);
 
        // This is slow, but unlike the method used by libxosd, the result isn't ugly.
        int outline = line->outline_width;
        for (int dx = -outline; dx <= outline; dx++)
          for (int dy = -outline; dy <= outline; dy++)
            if (dx*dx + dy*dy <= outline*outline)
-             XftDrawStringUtf8(osd->mask_draw, &mask_color, osd->font, x + dx, y + dy, text, text_len);
+             XftDrawStringUtf8(osd->mask_draw, &osd->mask_color, osd->font, x + dx, y + dy, text, text_len);
 
+       break;
+      }
+    case OSD_TYPE_PERCENTAGE:
+    case OSD_TYPE_SLIDER:
+      {
+       int x = line->x_pos + line->outline_width;
+       int y = line->y_pos + line->outline_width;
+       int su = line->slider_unit;
+       int advance = su + line->slider_space;
+       int units = line->slider_units;
+#ifdef SLIDERS_WITH_BRACKETS
+       units -= 2;
+       int hu = osd->line_height / 5;
+       int hd = 2*hu;
+       osd_draw_box(osd, line, x, y, su - su/3, 5*hu);
+       osd_draw_box(osd, line, x, y, su, hu);
+       osd_draw_box(osd, line, x, y + 4*hu, su, hu);
+       x += advance;
+#else
+       int hu = osd->line_height / 3;
+       int hd = hu;
+#endif
+       int min, max;
+       if (line->type == OSD_TYPE_PERCENTAGE)
+         {
+           min = 0;
+           max = (units+1) * line->u.percent / 100 - 1;
+         }
+       else
+         min = max = (units-1) * line->u.percent / 100;
+       for (int i=0; i < units; i++)
+         {
+           if (i >= min && i <= max)
+             osd_draw_box(osd, line, x, y, su, osd->line_height);
+           else
+             osd_draw_box(osd, line, x, y + hd, su, hu);
+           x += advance;
+         }
+#ifdef SLIDERS_WITH_BRACKETS
+       osd_draw_box(osd, line, x + su/3, y, su - su/3, 5*hu);
+       osd_draw_box(osd, line, x, y, su, hu);
+       osd_draw_box(osd, line, x, y + 4*hu, su, hu);
+#endif
        break;
       }
     default:
       die("osd_draw_line: unknown type %d", line->type);
     }
 
-  XftColorFree(osd->dpy, osd->visual, osd->cmap, &fg_color);
+  XftColorFree(osd->dpy, osd->visual, osd->cmap, &osd->fg_color);
   XftColorFree(osd->dpy, osd->visual, osd->cmap, &outline_color);
-  XftColorFree(osd->dpy, osd->visual, osd->cmap, &mask_color);
+  XftColorFree(osd->dpy, osd->visual, osd->cmap, &osd->mask_color);
 }
 
 void osd_show(struct osd_state *osd)
index 48ffb0be3783377ea26828d11e7d92bae0dd2d3f..953ef937664c04fc25a099a7407c99720c457c2c 100644 (file)
--- a/display.h
+++ b/display.h
@@ -1,7 +1,7 @@
 /*
  *     On-screen Display
  *
- *     (c) 2013 Martin Mares <mj@ucw.cz>
+ *     (c) 2013--2014 Martin Mares <mj@ucw.cz>
  */
 
 #include <stdbool.h>
@@ -24,6 +24,7 @@ struct osd_line {
   int outline_width;
   union {                                      // Data dependent on type
     char text[OSD_MAX_LINE_LEN];               // in UTF-8
+    unsigned int percent;                      // 0..100 for percentages and slider
   } u;
 
   // Used internally
@@ -31,6 +32,9 @@ struct osd_line {
   int height;
   int x_pos;
   int y_pos;
+  int slider_unit;
+  int slider_space;
+  int slider_units;
 };
 
 struct osd_state *osd_new(Display *dpy);
diff --git a/osdd.c b/osdd.c
index 2bfb8c35e60ec0baa5131f67925d5efa281411f9..ee34ded9bc769a3cd2af2c1fd50d2de697eea0c8 100644 (file)
--- a/osdd.c
+++ b/osdd.c
@@ -1,7 +1,7 @@
 /*
  *     On-screen Display Daemon
  *
- *     (c) 2010--2013 Martin Mares <mj@ucw.cz>
+ *     (c) 2010--2014 Martin Mares <mj@ucw.cz>
  */
 
 #include <stdio.h>
@@ -25,7 +25,7 @@ static timestamp_t now;
 
 /*** Options ***/
 
-static char *font_name = "times-64";
+static char *font_name = "times-64:bold";
 static char *default_color = "green";
 static char *default_outline_color = "black";
 static int default_outline_width = 2;
@@ -161,13 +161,13 @@ display_msg(struct msg *msg)
        }
       else if (!strcmp(key, "percentage") || !strcmp(key, "percent"))
        {
-         // FIXME
-         // 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"))
        {
-         // FIXME
-         // 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);