/*
* 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>.
#include "util.h"
#include "display.h"
+#define SLIDERS_WITH_BRACKETS
+
struct osd_state {
// Basic characteristics of current display and screen
Display *dpy;
int line_height;
int line_skip;
bool visible;
+
+ // Used temporarily when drawing a line
+ XftColor fg_color;
+ XftColor mask_color;
};
static void
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);
}
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);
}
}
}
+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
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)