diff --git a/Makefile b/Makefile
index b59e213912acc071d50d498b86d22756e8659c05..530473cc3a49041e2cf39b44af8124fb7c82d233 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,17 @@
 VERSION=1.1
 ARCHIVE=osdd-$(VERSION).tar.gz
 
-CFLAGS=-g3 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -std=gnu99
+CFLAGS=-g3 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -std=gnu99 -fsanitize=address 
 
 all: osdd osdc osd-batt osd-alsa
 
-osdd: osdd.o util.o display.o
+osdd: osdd.o util.o display.o osdd-set.o
 osdc: osdc.o util.o client.o
 osd-batt: osd-batt.o util.o client.o
 osd-alsa: osd-alsa.o util.o client.o
 
-osdd: LDLIBS+=$(shell pkg-config --libs xft) -lXext -lX11
+osdd: LDLIBS+=$(shell pkg-config --libs xft) -lXext -lX11 
+LDLIBS += -fsanitize=address
 
 osdc: LDLIBS+=-lX11
 osd-batt: LDLIBS+=-lX11
diff --git a/display.c b/display.c
index 08a680b84bf695b4417b87f5efc46ae571c3ec6c..ed8c57c3029d1f4d341ff9d49823e000064e8e96 100644
--- a/display.c
+++ b/display.c
@@ -19,13 +19,18 @@
 #include <X11/extensions/render.h>
 #include <X11/Xft/Xft.h>
 
-#undef DEBUG
-#include "util.h"
+#define DEBUG
 #include "display.h"
+#include "util.h"
 
 #define SLIDERS_WITH_BRACKETS
 
-struct osd_state {
+static char *font_name = "times-64:bold";
+static double line_spacing = 0.2;
+
+
+
+struct display_state {
   // Basic characteristics of current display and screen
 
   Display *dpy;
@@ -54,7 +59,7 @@ struct osd_state {
   XftDraw *image_draw;
 
   // Contents of the display
-  struct osd_line *lines;
+  struct display_line *lines;
   int num_lines;
   int max_lines;
   int line_distance;
@@ -68,7 +73,7 @@ struct osd_state {
 };
 
 static void
-stay_on_top(struct osd_state *osd)
+stay_on_top(struct display_state *display)
 {
   int format;
   unsigned long nitems, bytes_after;
@@ -76,8 +81,8 @@ stay_on_top(struct osd_state *osd)
   Atom type;
 
   // Gnome-compliant way
-  Atom gnome = XInternAtom(osd->dpy, "_WIN_SUPPORTING_WM_CHECK", False);
-  if (XGetWindowProperty(osd->dpy, osd->root, gnome, 0, 16384, False, AnyPropertyType,
+  Atom gnome = XInternAtom(display->dpy, "_WIN_SUPPORTING_WM_CHECK", False);
+  if (XGetWindowProperty(display->dpy, display->root, gnome, 0, 16384, False, AnyPropertyType,
 			 &type, &format, &nitems, &bytes_after, &prop) == Success &&
       nitems > 0)
     {
@@ -86,18 +91,18 @@ stay_on_top(struct osd_state *osd)
       XClientMessageEvent e;
       memset(&e, 0, sizeof(e));
       e.type = ClientMessage;
-      e.window = osd->win;
-      e.message_type = XInternAtom(osd->dpy, "_WIN_LAYER", False);
+      e.window = display->win;
+      e.message_type = XInternAtom(display->dpy, "_WIN_LAYER", False);
       e.format = 32;
       e.data.l[0] = 6;	// WIN_LAYER_ONTOP */
-      XSendEvent(osd->dpy, osd->root, False, SubstructureNotifyMask, (XEvent *) &e);
+      XSendEvent(display->dpy, display->root, False, SubstructureNotifyMask, (XEvent *) &e);
       XFree(prop);
       return;
     }
 
   // NetWM-compliant way
-  Atom net_wm = XInternAtom(osd->dpy, "_NET_SUPPORTED", False);
-  if (XGetWindowProperty(osd->dpy, osd->root, net_wm, 0, 16384, False, AnyPropertyType,
+  Atom net_wm = XInternAtom(display->dpy, "_NET_SUPPORTED", False);
+  if (XGetWindowProperty(display->dpy, display->root, net_wm, 0, 16384, False, AnyPropertyType,
 			 &type, &format, &nitems, &bytes_after, &prop) == Success &&
       nitems > 0)
     {
@@ -105,13 +110,13 @@ stay_on_top(struct osd_state *osd)
       XEvent e;
       memset(&e, 0, sizeof(e));
       e.xclient.type = ClientMessage;
-      e.xclient.message_type = XInternAtom(osd->dpy, "_NET_WM_STATE", False);
-      e.xclient.display = osd->dpy;
-      e.xclient.window = osd->win;
+      e.xclient.message_type = XInternAtom(display->dpy, "_NET_WM_STATE", False);
+      e.xclient.display = display->dpy;
+      e.xclient.window = display->win;
       e.xclient.format = 32;
       e.xclient.data.l[0] = 1;	// _NET_WM_STATE_ADD
-      e.xclient.data.l[1] = XInternAtom(osd->dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);
-      XSendEvent(osd->dpy, osd->root, False, SubstructureRedirectMask, &e);
+      e.xclient.data.l[1] = XInternAtom(display->dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);
+      XSendEvent(display->dpy, display->root, False, SubstructureRedirectMask, &e);
       XFree(prop);
       return;
     }
@@ -119,292 +124,266 @@ stay_on_top(struct osd_state *osd)
   DBG("stay_on_top: WM does not support any known protocol\n");
 }
 
-struct osd_set osd_set_new(Display *dpy)
+struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,int y)
 {
-  struct osd_set set;
-  set.len=0;
-
-  FILE * f = popen("xrandr | grep \\ connected","r");
-  char line[1000];
-  while(fscanf(f," %1000[^\n]",line)==1)
-  {
-	    int width,height,x,y;
-            char *l = line;
-            while(*l && !(*l==' ')) l++;
-            while(*l && !('0'<=*l&&*l<='9')) l++;
-            if(sscanf(l,"%dx%d+%d+%d",&width,&height,&x,&y)==4)
-		    if(set.len < OSD_MAX_SET_LEN)
-		    {
-			    DBG("ADD screen %dx%d on %d,%d\n",width,height,x,y);
-			    set.state[set.len++] = osd_state_new(dpy,width,height,x,y);
-		    }
-  }
-  return set;
-}
-
-struct osd_state *osd_state_new(Display *dpy,int width,int height,int x,int y)
-{
-  struct osd_state *osd = xmalloc(sizeof(*osd));
-  memset(osd, 0, sizeof(*osd));
+  struct display_state *display = xmalloc(sizeof(*display));
+  memset(display, 0, sizeof(*display));
 
-  osd->dpy = dpy;
-  osd->screen = XDefaultScreen(osd->dpy);
-  osd->visual = XDefaultVisual(osd->dpy, osd->screen);
-  osd->cmap = DefaultColormap(osd->dpy, osd->screen);
-  osd->root = DefaultRootWindow(osd->dpy);
+  display->dpy = dpy;
+  display->screen = XDefaultScreen(display->dpy);
+  display->visual = XDefaultVisual(display->dpy, display->screen);
+  display->cmap = DefaultColormap(display->dpy, display->screen);
+  display->root = DefaultRootWindow(display->dpy);
 
   // FIXME: These can change. And what about Xinerama?
-  osd->depth = XDefaultDepth(osd->dpy, osd->screen);
-  osd->screen_width = width;
-  osd->screen_height = height;
-  osd->screen_x = x;
-  osd->screen_y = y;
-  DBG("Screen: %dx%d depth %d\n", osd->screen_width, osd->screen_height, osd->depth);
+  display->depth = XDefaultDepth(display->dpy, display->screen);
+  display->screen_width = width;
+  display->screen_height = height;
+  display->screen_x = x;
+  display->screen_y = y;
+  DBG("Screen: %dx%d depth %d\n", display->screen_width, display->screen_height, display->depth);
 
   int event_basep, error_basep;
-  if (!XShapeQueryExtension(osd->dpy, &event_basep, &error_basep))
+  if (!XShapeQueryExtension(display->dpy, &event_basep, &error_basep))
     die("XShape extension not supported by X server, giving up");
 
-  osd->max_lines = 4;
-  osd->lines = xmalloc(sizeof(struct osd_line) * osd->max_lines);
-
-  return osd;
+  display->max_lines = 4;
+  display->num_lines = 0;
+  display->lines = xmalloc(sizeof(struct display_line) * display->max_lines);
+
+  display_set_font(display, font_name, line_spacing);
+
+  struct osd_abstract r;
+  memset(&r, 0, sizeof(r));
+  r.context = display;
+  void (*show)(struct display_state*, struct osd_line*, int) = display_show;
+  r.show = (void (*)(void*, struct osd_line*, int)) show;
+  void (*clear)(struct display_state*) = display_clear;
+  r.clear = (void (*)(void*)) clear;
+  bool (*handle_event)(struct display_state*, XEvent *) = display_handle_event;
+  r.handle_event = (bool (*)(void*, XEvent *)) handle_event;
+  return r;
 }
 
-void osd_free(struct osd_state *osd)
+void display_free(struct display_state *display)
 {
-  osd_hide(osd);
+  display_hide(display);
 
-  if (osd->font)
-    XftFontClose(osd->dpy, osd->font);
+  if (display->font)
+    XftFontClose(display->dpy, display->font);
 
-  free(osd->lines);
-  free(osd);
+  free(display->lines);
+  free(display);
 }
 
-void osd_set_font(struct osd_state *osd, char *font_name, double line_spacing)
+void display_set_font(struct display_state *display, char *font_name, double line_spacing)
 {
-  if (osd->font)
-    XftFontClose(osd->dpy, osd->font);
+  if (display->font)
+    XftFontClose(display->dpy, display->font);
 
   DBG("Using font %s\n", font_name);
-  osd->font = XftFontOpenName(osd->dpy, osd->screen, font_name);
-  if (!osd->font)
+  display->font = XftFontOpenName(display->dpy, display->screen, font_name);
+  if (!display->font)
     die("Cannot open font %s", font_name);
-  DBG("Font: asc=%d desc=%d ht=%d\n", osd->font->ascent, osd->font->descent, osd->font->height);
+  DBG("Font: asc=%d desc=%d ht=%d\n", display->font->ascent, display->font->descent, display->font->height);
 
-  osd->line_distance = osd->font->height;
-  osd->line_height = osd->font->ascent;
-  osd->line_skip = osd->line_distance * line_spacing;
-  DBG("Line: distance=%d height=%d skip=%d\n", osd->line_distance, osd->line_height, osd->line_skip);
+  display->line_distance = display->font->height;
+  display->line_height = display->font->ascent;
+  display->line_skip = display->line_distance * line_spacing;
+  DBG("Line: distance=%d height=%d skip=%d\n", display->line_distance, display->line_height, display->line_skip);
 }
 
-struct osd_line *osd_add_line(struct osd_state *osd, enum osd_line_type type)
+struct display_line *display_add_line(struct display_state *display, struct osd_line * line)
 {
-  if (osd->num_lines >= osd->max_lines)
+  if (display->num_lines >= display->max_lines)
     {
-      osd->max_lines = 2 * osd->max_lines;
-      osd->lines = xrealloc(osd->lines, sizeof(struct osd_line) * osd->max_lines);
+      display->max_lines = 2 * display->max_lines;
+      display->lines = xrealloc(display->lines, sizeof(struct display_line) * display->max_lines);
     }
 
-  struct osd_line *l = &osd->lines[osd->num_lines++];
-  l->type = type;
-  l->fg_color = "green";
-  l->outline_color = "black";
-  l->outline_width = 0;
-
-  switch (l->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);
-    }
+  struct display_line *l = &display->lines[display->num_lines++];
+  fprintf(stderr,"EZD %lld\n",(long long)display);
+  l->line = line;
 
   return l;
 }
 
-static void osd_prepare_line(struct osd_state *osd, int i)
+static void display_prepare_line(struct display_state *display, int i)
 {
-  struct osd_line *line = &osd->lines[i];
-  switch (line->type)
+  struct display_line *line = &display->lines[i];
+  switch (line->line->type)
     {
     case OSD_TYPE_TEXT:
       {
 	XGlyphInfo gi;
-	XftTextExtentsUtf8(osd->dpy, osd->font, (unsigned char *) line->u.text, strlen(line->u.text), &gi);
+	XftTextExtentsUtf8(display->dpy, display->font, (unsigned char *) line->line->u.text, strlen(line->line->u.text), &gi);
 	DBG("Line #%d: Glyph info: (%d,%d)+(%d,%d) off (%d,%d)\n", i, gi.x, gi.y, gi.width, gi.height, gi.xOff, gi.yOff);
-	line->width = gi.width + 2*line->outline_width;
-	line->height = osd->line_distance + 2*line->outline_width;
+	line->width = gi.width + 2*line->line->outline_width;
+	line->height = display->line_distance + 2*line->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;
+	line->slider_unit = display->line_height / 5;
+	line->slider_space = display->line_height / 5;
 #else
-	line->slider_unit = osd->line_height / 3;
-	line->slider_space = osd->line_height / 6;
+	line->slider_unit = display->line_height / 3;
+	line->slider_space = display->line_height / 6;
 #endif
 	if (!line->slider_space)
 	  line->slider_space = line->slider_unit = 1;
-	int use_width = osd->screen_width * 4 / 5;
+	int use_width = display->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;
+	line->width = line->slider_units*u - line->slider_space + 2*line->line->outline_width;
+	line->height = display->line_height + 2*line->line->outline_width;
 	break;
       }
     default:
-      die("osd_recalc_line: unknown type %d", line->type);
+      die("display_recalc_line: unknown type %d", line->line->type);
     }
 
-  DBG("Line #%d: Width %d (outline %d)\n", i, line->width, line->outline_width);
+  DBG("Line #%d: Width %d (outline %d)\n", i, line->width, line->line->outline_width);
 }
 
-static void osd_justify_line(struct osd_state *osd, int i)
+static void display_justify_line(struct display_state *display, int i)
 {
   // FIXME: Support more modes of justification
-  struct osd_line *line = &osd->lines[i];
-  line->x_pos = (osd->win_width - line->width) / 2;
+  struct display_line *line = &display->lines[i];
+  line->x_pos = (display->win_width - line->width) / 2;
   DBG("Line #%d: Position (%d,%d)\n", i, line->x_pos, line->y_pos);
 }
 
-static void osd_prepare(struct osd_state *osd)
+static void display_prepare(struct display_state *display)
 {
-  osd->win_width = 0;
-  osd->win_height = 0;
-  for (int i=0; i < osd->num_lines; i++)
+  display->win_width = 0;
+  display->win_height = 0;
+  for (int i=0; i < display->num_lines; i++)
     {
-      struct osd_line *line = &osd->lines[i];
-      osd_prepare_line(osd, i);
-      if (line->width > osd->win_width)
-	osd->win_width = line->width;
-      osd->win_height += line->height;
+      struct display_line *line = &display->lines[i];
+      display_prepare_line(display, i);
+      if (line->width > display->win_width)
+	display->win_width = line->width;
+      display->win_height += line->height;
       if (i)
-	osd->win_height += osd->line_skip;
+	display->win_height += display->line_skip;
     }
 
-  if (osd->win_width > osd->screen_width)
-    osd->win_width = osd->screen_width;
-  if (osd->win_height > osd->screen_height)
-    osd->win_height = osd->screen_height;
-  DBG("Window size set to %dx%d\n", osd->win_width, osd->win_height);
+  if (display->win_width > display->screen_width)
+    display->win_width = display->screen_width;
+  if (display->win_height > display->screen_height)
+    display->win_height = display->screen_height;
+  DBG("Window size set to %dx%d\n", display->win_width, display->win_height);
 
   int y = 0;
-  for (int i=0; i < osd->num_lines; i++)
+  for (int i=0; i < display->num_lines; i++)
     {
-      struct osd_line *line = &osd->lines[i];
+      struct display_line *line = &display->lines[i];
       if (i)
-	y += osd->line_skip;
+	y += display->line_skip;
       line->y_pos = y;
-      osd_justify_line(osd, i);
+      display_justify_line(display, i);
       y += line->height;
     }
 }
 
-static void osd_draw_box(struct osd_state *osd, struct osd_line *line, int x, int y, int w, int h)
+static void display_draw_box(struct display_state *display, struct display_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);
+  XftDrawRect(display->mask_draw, &display->mask_color,
+    x - line->line->outline_width, y - line->line->outline_width,
+    w + 2*line->line->outline_width, h + 2*line->line->outline_width);
+  XftDrawRect(display->image_draw, &display->fg_color, x, y, w, h);
 }
 
-static void osd_draw_line(struct osd_state *osd, int i)
+static void display_draw_line(struct display_state *display, int i)
 {
-  struct osd_line *line = &osd->lines[i];
+  struct display_line *line = &display->lines[i];
 
   // Allocate colors
   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, &osd->fg_color) ||
-      !XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->outline_color, &outline_color) ||
-      !XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &osd->mask_color))
+  if (!XftColorAllocName(display->dpy, display->visual, display->cmap, line->line->fg_color, &display->fg_color) ||
+      !XftColorAllocName(display->dpy, display->visual, display->cmap, line->line->outline_color, &outline_color) ||
+      !XftColorAllocValue(display->dpy, display->visual, display->cmap, &mask_rc, &display->mask_color))
     die("Cannot allocate colors");
 
   // Draw background in outline color
-  XftDrawRect(osd->image_draw, &outline_color, 0, line->y_pos, osd->win_width, line->height);
+  XftDrawRect(display->image_draw, &outline_color, 0, line->y_pos, display->win_width, line->height);
 
-  switch (line->type)
+  switch (line->line->type)
     {
     case OSD_TYPE_TEXT:
       {
-	int x = line->x_pos + line->outline_width;
-	int y = line->y_pos + line->outline_width + osd->line_height;
+	int x = line->x_pos + line->line->outline_width;
+	int y = line->y_pos + line->line->outline_width + display->line_height;
 
-	unsigned char *text = (unsigned char *) line->u.text;
-	int text_len = strlen(line->u.text);
-	XftDrawStringUtf8(osd->image_draw, &osd->fg_color, osd->font, x, y, text, text_len);
+	unsigned char *text = (unsigned char *) line->line->u.text;
+	int text_len = strlen(line->line->u.text);
+	XftDrawStringUtf8(display->image_draw, &display->fg_color, display->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;
+	int outline = line->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, &osd->mask_color, osd->font, x + dx, y + dy, text, text_len);
+	      XftDrawStringUtf8(display->mask_draw, &display->mask_color, display->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 x = line->x_pos + line->line->outline_width;
+	int y = line->y_pos + line->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 hu = display->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);
+	display_draw_box(display, line, x, y, su - su/3, 5*hu);
+	display_draw_box(display, line, x, y, su, hu);
+	display_draw_box(display, line, x, y + 4*hu, su, hu);
 	x += advance;
 #else
-	int hu = osd->line_height / 3;
+	int hu = display->line_height / 3;
 	int hd = hu;
 #endif
 	int min, max;
-	if (line->type == OSD_TYPE_PERCENTAGE)
+	if (line->line->type == OSD_TYPE_PERCENTAGE)
 	  {
 	    min = 0;
-	    max = (units+1) * line->u.percent / 100 - 1;
+	    max = (units+1) * line->line->u.percent / 100 - 1;
 	  }
 	else
-	  min = max = (units-1) * line->u.percent / 100;
+	  min = max = (units-1) * line->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);
+	      display_draw_box(display, line, x, y, su, display->line_height);
 	    else
-	      osd_draw_box(osd, line, x, y + hd, su, hu);
+	      display_draw_box(display, 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);
+	display_draw_box(display, line, x + su/3, y, su - su/3, 5*hu);
+	display_draw_box(display, line, x, y, su, hu);
+	display_draw_box(display, line, x, y + 4*hu, su, hu);
 #endif
 	break;
       }
     default:
-      die("osd_draw_line: unknown type %d", line->type);
+      die("display_draw_line: unknown type %d", line->line->type);
     }
 
-  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, &osd->mask_color);
+  XftColorFree(display->dpy, display->visual, display->cmap, &display->fg_color);
+  XftColorFree(display->dpy, display->visual, display->cmap, &outline_color);
+  XftColorFree(display->dpy, display->visual, display->cmap, &display->mask_color);
 }
 
 static void repace_bad_char(char * in)
@@ -420,11 +399,11 @@ static void repace_bad_char(char * in)
 	}
 }
 
-static void osd_log_to_file(struct osd_state *osd)
+static void display_log_to_file(struct display_state *display)
 {
 #define MAXIMUM_FILE_MANE_LEN 1024
 	int need_log=0;
-	for(int i=0;i<osd->num_lines;i++) need_log|=osd->lines[i].log;
+	for(int i=0;i<display->num_lines;i++) need_log|=display->lines[i].line->log;
 	if(need_log&1)
 	{
 		char name[MAXIMUM_FILE_MANE_LEN];
@@ -433,22 +412,22 @@ static void osd_log_to_file(struct osd_state *osd)
 		if(f)
 		{
 			fprintf(f,"%lld\n",(long long)time(0));
-			for(int i=0;i<osd->num_lines;i++)
+			for(int i=0;i<display->num_lines;i++)
 			{
-				struct osd_line * line = osd->lines+i;
+				struct osd_line * line = display->lines[i].line;
 				if(!(line->log & 1)) continue;
 				if(line->type!=OSD_TYPE_TEXT) continue;
 				// Allocate colors
 				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, &osd->fg_color) ||
-						!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->outline_color, &outline_color) ||
-						!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &osd->mask_color))
+				if (!XftColorAllocName(display->dpy, display->visual, display->cmap, line->fg_color, &display->fg_color) ||
+						!XftColorAllocName(display->dpy, display->visual, display->cmap, line->outline_color, &outline_color) ||
+						!XftColorAllocValue(display->dpy, display->visual, display->cmap, &mask_rc, &display->mask_color))
 					die("Cannot allocate colors");
-				typeof(osd->fg_color.color) c = osd->fg_color.color;
-				//fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,osd->lines[i].u.text);
+				typeof(display->fg_color.color) c = display->fg_color.color;
+				//fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,display->lines[i].u.text);
 				char text[1024];
-				snprintf(text,1000,osd->lines[i].u.text);
+				snprintf(text,1000,display->lines[i].line->u.text);
 				repace_bad_char(text);
 				fprintf(f,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,text);
 			}
@@ -465,20 +444,20 @@ static void osd_log_to_file(struct osd_state *osd)
 			time_t t = time(NULL);
 			struct tm tm = *localtime(&t);
 			fprintf(f,"%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
-			for(int i=0;i<osd->num_lines;i++)
+			for(int i=0;i<display->num_lines;i++)
 			{
-				struct osd_line * line = osd->lines+i;
+				struct osd_line * line = display->lines[i].line;
 				if(!(line->log & 2)) continue;
 				// Allocate colors
 				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, &osd->fg_color) ||
-						!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->outline_color, &outline_color) ||
-						!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &osd->mask_color))
+				if (!XftColorAllocName(display->dpy, display->visual, display->cmap, line->fg_color, &display->fg_color) ||
+						!XftColorAllocName(display->dpy, display->visual, display->cmap, line->outline_color, &outline_color) ||
+						!XftColorAllocValue(display->dpy, display->visual, display->cmap, &mask_rc, &display->mask_color))
 					die("Cannot allocate colors");
-				typeof(osd->fg_color.color) c = osd->fg_color.color;
-				//fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,osd->lines[i].u.text);
-				fprintf(f," \x1b[38;2;%d;%d;%dm%s\e[0m",c.red/256,c.green/256,c.blue/256,osd->lines[i].u.text);
+				typeof(display->fg_color.color) c = display->fg_color.color;
+				//fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,display->lines[i].u.text);
+				fprintf(f," \x1b[38;2;%d;%d;%dm%s\e[0m",c.red/256,c.green/256,c.blue/256,display->lines[i].line->u.text);
 			}
 			fprintf(f,"\n");
 			fclose(f);
@@ -486,100 +465,103 @@ static void osd_log_to_file(struct osd_state *osd)
 	}
 }
 
-void osd_show(struct osd_state *osd)
+void display_show(struct display_state *display, struct osd_line * lines, int num_lines)
 {
-  osd_hide(osd);
-  osd_prepare(osd);
-  osd_log_to_file(osd);
+  display_hide(display);
+
+  for(int i=0; i<num_lines; i++) display_add_line(display,lines+i);
+
+  display_prepare(display);
+  display_log_to_file(display);
 
   // Create our window
   XSetWindowAttributes win_attr = {
     .override_redirect = 1,
   };
-  osd->win = XCreateWindow(osd->dpy,
-	osd->root,
-	(osd->screen_width - osd->win_width) / 2 + osd->screen_x, (osd->screen_height - osd->win_height) / 2 + osd->screen_y,
-	osd->win_width, osd->win_height,
+  display->win = XCreateWindow(display->dpy,
+	display->root,
+	(display->screen_width - display->win_width) / 2 + display->screen_x, (display->screen_height - display->win_height) / 2 + display->screen_y,
+	display->win_width, display->win_height,
 	0,
-	osd->depth,
+	display->depth,
 	CopyFromParent,
-	osd->visual,
+	display->visual,
 	CWOverrideRedirect,
 	&win_attr);
-  XStoreName(osd->dpy, osd->win, "OSD");
-  stay_on_top(osd);
+  XStoreName(display->dpy, display->win, "OSD");
+  stay_on_top(display);
 
   // Create image pixmap and its graphic context
-  // osd->gc can be used for both osd->win and osd->image_bitmap as they have the same root and depth
-  osd->image_pixmap = XCreatePixmap(osd->dpy, osd->win, osd->win_width, osd->win_height, osd->depth);
+  // display->gc can be used for both display->win and display->image_bitmap as they have the same root and depth
+  display->image_pixmap = XCreatePixmap(display->dpy, display->win, display->win_width, display->win_height, display->depth);
   XGCValues gcv = {
     .graphics_exposures = 0,
   };
-  osd->gc = XCreateGC(osd->dpy, osd->win, GCGraphicsExposures, &gcv);
+  display->gc = XCreateGC(display->dpy, display->win, GCGraphicsExposures, &gcv);
 
   // Create mask bitmap and its GC
-  osd->mask_bitmap = XCreatePixmap(osd->dpy, osd->win, osd->win_width, osd->win_height, 1);
-  osd->mask_gc = XCreateGC(osd->dpy, osd->mask_bitmap, GCGraphicsExposures, &gcv);
+  display->mask_bitmap = XCreatePixmap(display->dpy, display->win, display->win_width, display->win_height, 1);
+  display->mask_gc = XCreateGC(display->dpy, display->mask_bitmap, GCGraphicsExposures, &gcv);
 
   // Clear the mask bitmap
-  XSetBackground(osd->dpy, osd->mask_gc, WhitePixel(osd->dpy, osd->screen));
-  XSetForeground(osd->dpy, osd->mask_gc, BlackPixel(osd->dpy, osd->screen));
-  XFillRectangle(osd->dpy, osd->mask_bitmap, osd->mask_gc, 0, 0, osd->win_width, osd->win_height);
+  XSetBackground(display->dpy, display->mask_gc, WhitePixel(display->dpy, display->screen));
+  XSetForeground(display->dpy, display->mask_gc, BlackPixel(display->dpy, display->screen));
+  XFillRectangle(display->dpy, display->mask_bitmap, display->mask_gc, 0, 0, display->win_width, display->win_height);
 
   // Create XftDraw for mask and image
-  osd->mask_draw = XftDrawCreateBitmap(osd->dpy, osd->mask_bitmap);
-  osd->image_draw = XftDrawCreate(osd->dpy, osd->image_pixmap, osd->visual, osd->cmap);
-  if (!osd->mask_draw || !osd->image_draw)
+  display->mask_draw = XftDrawCreateBitmap(display->dpy, display->mask_bitmap);
+  display->image_draw = XftDrawCreate(display->dpy, display->image_pixmap, display->visual, display->cmap);
+  if (!display->mask_draw || !display->image_draw)
     die("Cannot create XftDraw");
 
   // Draw individial lines
-  for (int i=0; i < osd->num_lines; i++)
-    osd_draw_line(osd, i);
+  for (int i=0; i < display->num_lines; i++)
+    display_draw_line(display, i);
 
-  XShapeCombineMask(osd->dpy, osd->win, ShapeBounding, 0, 0, osd->mask_bitmap, ShapeSet);
+  XShapeCombineMask(display->dpy, display->win, ShapeBounding, 0, 0, display->mask_bitmap, ShapeSet);
 
-  XSelectInput(osd->dpy, osd->win, ExposureMask);
-  XMapRaised(osd->dpy, osd->win);
-  XFlush(osd->dpy);
+  XSelectInput(display->dpy, display->win, ExposureMask);
+  XMapRaised(display->dpy, display->win);
+  XFlush(display->dpy);
 
-  osd->visible = 1;
+  display->visible = 1;
 }
 
-void osd_hide(struct osd_state *osd)
+void display_hide(struct display_state *display)
 {
-  if (!osd->visible)
+  if (!display->visible)
     return;
 
-  XftDrawDestroy(osd->image_draw);
-  XftDrawDestroy(osd->mask_draw);
-  XFreeGC(osd->dpy, osd->gc);
-  XFreeGC(osd->dpy, osd->mask_gc);
-  XFreePixmap(osd->dpy, osd->image_pixmap);
-  XFreePixmap(osd->dpy, osd->mask_bitmap);
-  XDestroyWindow(osd->dpy, osd->win);
-  XFlush(osd->dpy);
+  XftDrawDestroy(display->image_draw);
+  XftDrawDestroy(display->mask_draw);
+  XFreeGC(display->dpy, display->gc);
+  XFreeGC(display->dpy, display->mask_gc);
+  XFreePixmap(display->dpy, display->image_pixmap);
+  XFreePixmap(display->dpy, display->mask_bitmap);
+  XDestroyWindow(display->dpy, display->win);
+  XFlush(display->dpy);
 
-  osd->visible = 0;
+  display->visible = 0;
 }
 
-void osd_clear(struct osd_state *osd)
+void display_clear(struct display_state *display)
 {
-  osd_hide(osd);
-  osd->num_lines = 0;
+  display_hide(display);
+  display->num_lines = 0;
 }
 
-bool osd_handle_event(struct osd_state *osd, XEvent *ev)
+bool display_handle_event(struct display_state *display, XEvent *ev)
 {
-  if (!osd->visible)
+  if (!display->visible)
     return 0;
 
   if (ev->type == Expose)
     {
       XExposeEvent *ex = &ev->xexpose;
-      if (ex->window == osd->win)
+      if (ex->window == display->win)
 	{
 	  DBG("Expose cnt=%d (%d,%d)+(%d,%d)\n", ex->count, ex->x, ex->y, ex->width, ex->height);
-	  XCopyArea(osd->dpy, osd->image_pixmap, osd->win, osd->gc, ex->x, ex->y, ex->width, ex->height, ex->x, ex->y);
+	  XCopyArea(display->dpy, display->image_pixmap, display->win, display->gc, ex->x, ex->y, ex->width, ex->height, ex->x, ex->y);
 	  return 1;
 	}
     }
diff --git a/display.h b/display.h
index 131f7c3ee402344837acb433acfa0a5f94e16be8..550f1c49b797c02a7d5f151774ed04f54f096f0e 100644
--- a/display.h
+++ b/display.h
@@ -8,26 +8,14 @@
 #include <stdbool.h>
 #include <X11/Xlib.h>
 
-struct osd_state;
+#include "osdd-set.h"
 
-#define OSD_MAX_LINE_LEN 256
-
-enum osd_line_type {
-  OSD_TYPE_TEXT,
-  OSD_TYPE_PERCENTAGE,
-  OSD_TYPE_SLIDER,
-};
+struct display_state;
 
-struct osd_line {
-  enum osd_line_type type;
-  char *fg_color;
-  char *outline_color;
-  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;
+#define OSD_MAX_LINE_LEN 256
 
+struct display_line {
+  struct osd_line * line;
   // Used internally
   int width;
   int height;
@@ -36,22 +24,13 @@ struct osd_line {
   int slider_unit;
   int slider_space;
   int slider_units;
-  int log;
-};
-
-#define ALL_OSD_SET(set) for(int ALL_OSD_SET_i=0;ALL_OSD_SET_i<set.len;ALL_OSD_SET_i++) set->state[ALL_OSD_SET_i]
-#define OSD_MAX_SET_LEN 10
-struct osd_set {
-  struct osd_state* state[OSD_MAX_SET_LEN];
-  int len;
 };
 
-struct osd_state *osd_state_new(Display *dpy,int width,int height,int x,int y);
-struct osd_set osd_set_new(Display *dpy);
-void osd_free(struct osd_state *osd);
-void osd_set_font(struct osd_state *osd, char *font_name, double line_spacing);
-struct osd_line *osd_add_line(struct osd_state *osd, enum osd_line_type type);
-void osd_show(struct osd_state *osd);
-void osd_hide(struct osd_state *osd);
-void osd_clear(struct osd_state *osd);
-bool osd_handle_event(struct osd_state *osd, XEvent *ev);
+struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,int y);
+void display_free(struct display_state *display);
+void display_set_font(struct display_state *display, char *font_name, double line_spacing);
+struct display_line *display_add_line(struct display_state *display, struct osd_line * line);
+void display_show(struct display_state *display, struct osd_line * lines, int num_lines);
+void display_hide(struct display_state *display);
+void display_clear(struct display_state *display);
+bool display_handle_event(struct display_state *display, XEvent *ev);
diff --git a/osdd-set.c b/osdd-set.c
new file mode 100644
index 0000000000000000000000000000000000000000..629228eb4711fdfc2d2793f7d65063a7ff30d5af
--- /dev/null
+++ b/osdd-set.c
@@ -0,0 +1,81 @@
+/*
+ *	On-screen Display
+*
+ *	(c) 2013--2014 Martin Mares <mj@ucw.cz>
+ *	(c) 2020--2021 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
+ */
+
+#include <stdio.h>
+
+#include "osdd-set.h"
+#include "util.h"
+
+
+struct osd_line *osd_set_add_line(struct osd_set *set, enum osd_line_type type)
+{
+  if (set->num_lines >= set->max_lines)
+    {
+      set->max_lines = 2 * set->max_lines + 1;
+      set->lines = xrealloc(set->lines, sizeof(struct osd_line) * set->max_lines);
+    }
+
+  struct osd_line *l = &set->lines[set->num_lines++];
+  l->type = type;
+  l->fg_color = "green";
+  l->outline_color = "black";
+  l->outline_width = 0;
+
+  switch (l->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);
+    }
+
+  return l;
+}
+
+void osd_set_show(struct osd_set *set)
+{
+	for(int i=0;i<set->len;i++)
+	{
+		set->elements[i].show(set->elements[i].context,set->lines,set->num_lines);
+	}
+}
+
+void osd_set_clear(struct osd_set *set)
+{
+	for(int i=0;i<set->len;i++)
+	{
+		set->elements[i].clear(set->elements[i].context);
+	}
+	set->num_lines = 0;
+}
+
+bool osd_set_handle_event(struct osd_set *set, XEvent *ev)
+{
+	bool r=0;
+	for(int i=0;i<set->len;i++)
+	{
+		if(set->elements[i].handle_event) r |= set->elements[i].handle_event(set->elements[i].context,ev);
+	}
+	return r;
+}
+
+struct osd_set osd_set_new(void)
+{
+  struct osd_set set;
+  set.len=0;
+
+  set.num_lines=0;
+  set.max_lines=0;
+  set.lines=0;
+  return set;
+}
+
diff --git a/osdd-set.h b/osdd-set.h
new file mode 100644
index 0000000000000000000000000000000000000000..348ff1a0b42f67c85fb592f00b63148d7056aded
--- /dev/null
+++ b/osdd-set.h
@@ -0,0 +1,62 @@
+/*
+ *	On-screen Display
+ *
+ *	(c) 2013--2014 Martin Mares <mj@ucw.cz>
+ *	(c) 2020--2021 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
+ */
+
+#ifndef OSDD_SET_H
+#define OSDD_SET_H
+
+#include <stdbool.h>
+#include <X11/Xlib.h>
+
+struct display_state;
+
+#define OSD_MAX_LINE_LEN 256
+#define OSD_MAX_SET_LEN 64
+
+#define OSD_ABSTRACT_NAME_LEN 64
+
+enum osd_line_type {
+  OSD_TYPE_TEXT,
+  OSD_TYPE_PERCENTAGE,
+  OSD_TYPE_SLIDER,
+};
+
+struct osd_line {
+  enum osd_line_type type;
+  char *fg_color;
+  char *outline_color;
+  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;
+  int log;
+};
+
+struct osd_abstract {
+	void * context;
+
+	void (*show)(void * context, struct osd_line * lines, int num_lines);
+	void (*clear)(void * context);
+	bool (*handle_event)(void * context, XEvent *ev);
+};
+
+struct osd_set {
+  struct osd_abstract elements[OSD_MAX_SET_LEN];
+  int len;
+
+  struct osd_line *lines;
+  int num_lines;
+  int max_lines;
+};
+
+struct osd_set osd_set_new(void);
+struct osd_line *osd_set_add_line(struct osd_set *set, enum osd_line_type type);
+void osd_set_show(struct osd_set *set);
+void osd_set_clear(struct osd_set *set);
+bool osd_set_handle_event(struct osd_set *set, XEvent *ev);
+
+#endif
diff --git a/osdd.c b/osdd.c
index a92fbe06d0138ef2fc181fd85dd488bde5d6690b..e9dc4afee1dd991f387a09ec65af0757ebfcf358 100644
--- a/osdd.c
+++ b/osdd.c
@@ -15,10 +15,12 @@
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 
-#undef DEBUG
+#define DEBUG
 #include "util.h"
+#include "osdd-set.h"
 #include "display.h"
 
+
 static struct osd_set osd;
 #define FOREACHOSD for(int i=0;i<osd.len;i++)
 
@@ -26,7 +28,6 @@ static timestamp_t now;
 
 /*** Options ***/
 
-static char *font_name = "times-64:bold";
 static char *default_color = "green";
 static char *default_outline_color = "black";
 static int default_outline_width = 2;
@@ -35,7 +36,6 @@ static int default_min_duration = 250;
 static int default_log = 255;
 static int debug_mode;
 static int test_mode;
-static double line_spacing = 0.2;
 
 static const char short_opts[] = "c:d:Df:m:o:O:s:";
 
@@ -92,10 +92,10 @@ parse_opts(int argc, char **argv)
 	debug_mode = 1;
 	break;
       case 'f':
-	font_name = optarg;
+	//font_name = optarg;
 	break;
       case 'l':
-	line_spacing = atof(optarg);
+	//line_spacing = atof(optarg);
 	break;
       case 'm':
 	default_min_duration = atoi(optarg);
@@ -144,7 +144,7 @@ display_msg(struct msg *msg)
   int num_l=0;
   while (*line)
     {
-      // The parser it destructive, but it does not do any harm, since we display each message only once.
+      // The parser is destructive, but it does not do any harm, since we display each message only once.
       char *nl = strchr(line, '\n');
       *nl++ = 0;
 
@@ -162,22 +162,21 @@ display_msg(struct msg *msg)
 	}
       DBG("\t%s:%s\n", key, val);
 
-      struct osd_line *l[OSD_MAX_SET_LEN];
-      FOREACHOSD l[i]=0;
+      struct osd_line *l=0;
       if (!key[0])
 	{
-	  FOREACHOSD l[i] = osd_add_line(osd.state[i], OSD_TYPE_TEXT);
-	  FOREACHOSD sprintf(l[i]->u.text, "%.*s", OSD_MAX_LINE_LEN, val);
+	  l = osd_set_add_line(&osd, OSD_TYPE_TEXT);
+	  sprintf(l->u.text, "%.*s", OSD_MAX_LINE_LEN, val);
 	}
       else if (!strcmp(key, "percentage") || !strcmp(key, "percent"))
 	{
-	  FOREACHOSD l[i] = osd_add_line(osd.state[i], OSD_TYPE_PERCENTAGE);
-	  FOREACHOSD l[i]->u.percent = atoi(val);
+	  l = osd_set_add_line(&osd, OSD_TYPE_PERCENTAGE);
+	  l->u.percent = atoi(val);
 	}
       else if (!strcmp(key, "slider"))
 	{
-	  FOREACHOSD l[i] = osd_add_line(osd.state[i], OSD_TYPE_SLIDER);
-	  FOREACHOSD l[i]->u.percent = atoi(val);
+	  l = osd_set_add_line(&osd, OSD_TYPE_SLIDER);
+	  l->u.percent = atoi(val);
 	}
       else if (!strcmp(key, "duration"))
 	msg->max_light = now + atoi(val);
@@ -191,21 +190,21 @@ display_msg(struct msg *msg)
 	outline_color = val;
       else if (!strcmp(key, "outline-width"))
 	outline_width = atoi(val);
-      FOREACHOSD if (l[i])
+      if (l)
 	{
 	  num_l++;
-	  l[i]->fg_color = fg_color;
-	  l[i]->outline_color = outline_color;
-	  l[i]->outline_width = outline_width;
-	  l[i]->log = i?0:log;
+	  l->fg_color = fg_color;
+	  l->outline_color = outline_color;
+	  l->outline_width = outline_width;
+	  l->log = log;
 	}
 
       line = nl;
     }
 
-  if(!num_l) FOREACHOSD
+  if(!num_l)
   {
-	  struct osd_line *l = osd_add_line(osd.state[i],OSD_TYPE_TEXT);
+	  struct osd_line *l = osd_set_add_line(&osd,OSD_TYPE_TEXT);
 	  l->u.text[0]=0;
 	  l->fg_color = fg_color;
 	  l->outline_color = outline_color;
@@ -216,7 +215,7 @@ display_msg(struct msg *msg)
   if (msg->min_light > msg->max_light)
     msg->min_light = msg->max_light;
 
-  FOREACHOSD osd_show(osd.state[i]);
+  osd_set_show(&osd);
 }
 
 static void
@@ -228,7 +227,7 @@ msg_to_stdout(struct msg *msg)
   int out_parametr_index=0;
   while (*line)
     {
-      // The parser it destructive, but it does not do any harm, since we display each message only once.
+      // The parser is destructive, but it does not do any harm, since we display each message only once.
       char *nl = strchr(line, '\n');
       *nl++ = 0;
 
@@ -261,7 +260,7 @@ static void
 hide_msg(struct msg *msg)
 {
   DBG("## Hiding message\n");
-  FOREACHOSD osd_clear(osd.state[i]);
+  osd_set_clear(&osd);
   free(msg);
 }
 
@@ -400,8 +399,24 @@ main(int argc, char **argv)
       XFlush(dpy);
     }
 
-  osd = osd_set_new(dpy);
-  FOREACHOSD osd_set_font(osd.state[i], font_name, line_spacing);
+  osd = osd_set_new();
+  {
+  FILE * f = popen("xrandr | grep \\ connected","r");
+  char line[1001];
+  while(fscanf(f," %1000[^\n]",line)==1)
+  {
+	    int width,height,x,y;
+            char *l = line;
+            while(*l && !(*l==' ')) l++;
+            while(*l && !('0'<=*l&&*l<='9')) l++;
+            if(sscanf(l,"%dx%d+%d+%d",&width,&height,&x,&y)==4)
+		    if(osd.len < OSD_MAX_SET_LEN)
+		    {
+			    DBG("ADD screen %dx%d on %d,%d\n",width,height,x,y);
+			    osd.elements[osd.len++] = display_state_new(dpy,width,height,x,y);
+		    }
+  }
+  }
 
   struct pollfd pfd = {
     .fd = ConnectionNumber(dpy),
@@ -443,7 +458,7 @@ main(int argc, char **argv)
 	    {
 	      XEvent ev;
 	      XNextEvent(dpy, &ev);
-	      FOREACHOSD if (osd_handle_event(osd.state[i], &ev))
+	      if (osd_set_handle_event(&osd, &ev))
 		continue;
 	      if (ev.type != PropertyNotify)
 		continue;