From dec6ff0cd22cbe8242793e70d64b8d9f2b53dcf1 Mon Sep 17 00:00:00 2001
From: Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
Date: Fri, 5 Feb 2021 14:11:07 +0100
Subject: [PATCH] Parsing message just when arrive

---
 osdd-file.c      |  19 ++++--
 osdd-mqtt.c      |  13 +++-
 osdd-run         |   5 +-
 osdd-set.c       |  50 +++++++++++----
 osdd-set.h       |  28 +++++---
 osdd-to-string.c |  23 ++++++-
 osdd-to-string.h |  37 +++++++----
 osdd.c           | 162 ++++++++++++++---------------------------------
 8 files changed, 177 insertions(+), 160 deletions(-)

diff --git a/osdd-file.c b/osdd-file.c
index b3bcef1..ce1bdc8 100644
--- a/osdd-file.c
+++ b/osdd-file.c
@@ -39,16 +39,23 @@ void file_write_to_file(struct file_state *state, VECTOR(char) out)
 	VFREE(out);
 }
 
+static
+bool file_arrive(struct file_state *state, struct osd_line * lines, int num_lines)
+{
+	file_write_to_file(state,osd_to_string_arrivee_msq(&state->to_string, lines, num_lines));
+	return state->to_string.do_not_insert_msg_to_que;
+}
+
 static
 void file_show(struct file_state *state, struct osd_line * lines, int num_lines)
 {
-	file_write_to_file(state,osd_to_string(&state->to_string, lines, num_lines));
+	file_write_to_file(state,osd_to_string_show_msg(&state->to_string, lines, num_lines));
 }
 
 static
 void file_clear(struct file_state *state)
 {
-	file_write_to_file(state,osd_to_string_end_msg(&state->to_string));
+	file_write_to_file(state,osd_to_string_clear_msg(&state->to_string));
 }
 
 // *************************  NEW ******************
@@ -70,9 +77,9 @@ struct osd_abstract file_new(int argc, char ** argv, Display * nope)
 	(void)nope;
 	argc++;argv--;
 	struct osd_abstract r;
-	static const char short_opts[] = "+a" OSDD_TO_STRING_SHORTOP;
+	static const char short_opts[] = "+b" OSDD_TO_STRING_SHORTOP;
 	static const struct option long_opts[] = {
-		{ "append",		no_argument,	NULL,	'a' },
+		{ "append",		no_argument,	NULL,	'b' },
 		OSDD_TO_STRING_LONGOP
 		{ NULL,		0,			NULL,	0   },
 	};
@@ -90,7 +97,7 @@ struct osd_abstract file_new(int argc, char ** argv, Display * nope)
 		if(!osd_to_string_parse_arg(&state->to_string,opt))
 		switch (opt)
 		{
-			case 'a':
+			case 'b':
 				state->open_mode = "a";
 				break;
 			default:
@@ -116,6 +123,8 @@ struct osd_abstract file_new(int argc, char ** argv, Display * nope)
 	}
 
 	r.context = state;
+	bool (*arrive)(struct file_state*, struct osd_line*, int) = file_arrive;
+	r.arrive = (bool (*)(void*, struct osd_line*, int)) arrive;
 	void (*show)(struct file_state*, struct osd_line*, int) = file_show;
 	r.show = (void (*)(void*, struct osd_line*, int)) show;
 	void (*clear)(struct file_state*) = file_clear;
diff --git a/osdd-mqtt.c b/osdd-mqtt.c
index 86a4016..d03a608 100644
--- a/osdd-mqtt.c
+++ b/osdd-mqtt.c
@@ -142,16 +142,23 @@ void mqtt_write_to_mqtt(struct mqtt_state *state, VECTOR(char) out)
 	VFREE(out);
 }
 
+static
+bool mqtt_arrive(struct mqtt_state *state, struct osd_line * lines, int num_lines)
+{
+	mqtt_write_to_mqtt(state,osd_to_string_arrivee_msq(&state->to_string, lines, num_lines));
+	return state->to_string.do_not_insert_msg_to_que;
+}
+
 static
 void mqtt_show(struct mqtt_state *state, struct osd_line * lines, int num_lines)
 {
-	mqtt_write_to_mqtt(state,osd_to_string(&state->to_string, lines, num_lines));
+	mqtt_write_to_mqtt(state,osd_to_string_show_msg(&state->to_string, lines, num_lines));
 }
 
 static
 void mqtt_clear(struct mqtt_state *state)
 {
-	mqtt_write_to_mqtt(state,osd_to_string_end_msg(&state->to_string));
+	mqtt_write_to_mqtt(state,osd_to_string_clear_msg(&state->to_string));
 }
 
 // *************************  NEW ******************
@@ -228,6 +235,8 @@ struct osd_abstract mqtt_new(int argc, char ** argv, Display * nope)
 	}
 
 	r.context = state;
+	bool (*arrive)(struct mqtt_state*, struct osd_line*, int) = mqtt_arrive;
+	r.arrive = (bool (*)(void*, struct osd_line*, int)) arrive;
 	void (*show)(struct mqtt_state*, struct osd_line*, int) = mqtt_show;
 	r.show = (void (*)(void*, struct osd_line*, int)) show;
 	void (*clear)(struct mqtt_state*) = mqtt_clear;
diff --git a/osdd-run b/osdd-run
index 37c054c..25f3751 100755
--- a/osdd-run
+++ b/osdd-run
@@ -9,13 +9,14 @@ echo "Xft.render: False" > $tmp
 XENVIRONMENT=$tmp \
 	./osdd -D \
 	DISPLAY_BY_OUTPUTS default nolog [ -n a%d ] \
-	FILE default log loglog [ -a -l' ' -m'\n' -T' ' -tiso -cterm ~/.osdd_log  ] \
+	FILE default log loglog [ -b -l' ' -m'\n' -T' ' -tiso -cterm ~/.osdd_log  ] \
 	FILE default log loglast [ -l'\n' -tunix -T'\n' -crgbHEX -r ~/.osdd_last ] \
+	FILE stdout [ -A -l' ' -m'\n' /dev/stdout ] \
 	MQTT default mqtt led [ -e'\0' -E -crgbDEC -tunix -R -q0 \
 		$(cat ~/.secret/mqtt/rpi0-all.addres) \
 		$(cat ~/.secret/mqtt/rpi0-led-include.user) \
 		$(cat ~/.secret/mqtt/rpi0-led-include.passwd) \
 		osd/arch ] \
-	| bash
+	| tee /dev/stderr | bash
 rm $tmp
 pkill -f not2osd
diff --git a/osdd-set.c b/osdd-set.c
index 3436952..0c82ef6 100644
--- a/osdd-set.c
+++ b/osdd-set.c
@@ -6,6 +6,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "osdd-set.h"
@@ -54,10 +55,10 @@ struct osd_set_trie * osd_set_trie_find(struct osd_set_trie * root, char * str,
 
 // ***************************************************************************************************************
 
-struct osd_line *osd_set_add_line(struct osd_set *set, enum osd_line_type type)
+struct osd_line *msg_add_line(struct msg *msg, enum osd_line_type type)
 {
-  VADDSIZE(set->lines, 1);
-  struct osd_line *l = &VLAST(set->lines);
+  VADDSIZE(msg->lines, 1);
+  struct osd_line *l = &VLAST(msg->lines);
   l->type = type;
   l->fg_color = "green";
   l->outline_color = "black";
@@ -79,30 +80,39 @@ struct osd_line *osd_set_add_line(struct osd_set *set, enum osd_line_type type)
   return l;
 }
 
-void osd_set_show(struct osd_set *set)
+bool osd_set_arrive(struct osd_set *set, struct msg *msg)
 {
+	bool do_not_insert_to_que=0;
 	for(int i=0;i<VSIZE(set->elements);i++)
 	{
-		if(set->is_active[i]) if(set->elements[i].show) set->elements[i].show(set->elements[i].context,set->lines,VSIZE(set->lines));
+		if(msg->output_active[i]) if(set->elements[i].arrive)
+			do_not_insert_to_que |= set->elements[i].arrive(set->elements[i].context,msg->lines,VSIZE(msg->lines));
 	}
+	return do_not_insert_to_que;
 }
 
-void osd_set_clear(struct osd_set *set)
+void osd_set_show(struct osd_set *set, struct msg *msg)
 {
 	for(int i=0;i<VSIZE(set->elements);i++)
 	{
-		if(set->elements[i].clear) set->elements[i].clear(set->elements[i].context);
+		if(msg->output_active[i]) if(set->elements[i].show) set->elements[i].show(set->elements[i].context,msg->lines,VSIZE(msg->lines));
 	}
-	VSETSIZE(set->lines, 0);
-	memset(set->is_active,0,sizeof(bool)*VSIZE(set->is_active));
 }
 
-void osd_set_active_outputs(struct osd_set *set, char * name, bool val)
+void osd_set_clear(struct osd_set *set, struct msg * msg)
+{
+	for(int i=0;i<VSIZE(set->elements);i++)
+	{
+		if(msg->output_active[i]) if(set->elements[i].clear) set->elements[i].clear(set->elements[i].context);
+	}
+}
+
+void osd_set_active_outputs(struct osd_set *set, struct msg *msg, char * name, bool val)
 {
 	struct osd_set_trie *trie = osd_set_trie_find(&set->trie,name,0);
 	if(trie)
 	{
-		for(int i=0;i<VSIZE(trie->vals);i++) set->is_active[trie->vals[i]]=val;
+		for(int i=0;i<VSIZE(trie->vals);i++) msg->output_active[trie->vals[i]]=val;
 	}
 }
 
@@ -121,7 +131,6 @@ struct osd_set osd_set_new(void)
   struct osd_set set;
   memset(&set, 0, sizeof(set));
   set.elements=0;
-  set.lines=0;
   return set;
 }
 
@@ -129,11 +138,24 @@ void osd_set_add(struct osd_set *set, struct osd_abstract abs, int names_len, ch
 {
 	for(int i=0;i<names_len;i++)
 	{
-		fprintf(stderr,"NAME |%s|\n",names[i]);
+		//fprintf(stderr,"NAME |%s|\n",names[i]);
 		struct osd_set_trie *trie = osd_set_trie_find(&set->trie,names[i],1);
 		VPB(trie->vals, VSIZE(set->elements));
 	}
 	VPB(set->elements, abs);
-	VPB(set->is_active, 0);
 }
 
+struct msg* osd_set_new_msg(struct osd_set * set)
+{
+	int size = sizeof(struct msg) + sizeof(bool) * VSIZE(set->elements);
+	struct msg *msg = xmalloc(size);
+	memset(msg, 0, size);
+	VRESERVE(msg->lines, 4);
+	return msg;
+}
+void msg_free(struct msg * msg)
+{
+	VFREE(msg->lines);
+	if(msg->alocated_data) free(msg->alocated_data);
+	free(msg);
+}
diff --git a/osdd-set.h b/osdd-set.h
index 7caa0ae..37eb261 100644
--- a/osdd-set.h
+++ b/osdd-set.h
@@ -17,7 +17,7 @@ typedef struct _IO_FILE FILE;
 
 struct display_state;
 
-#define OSD_MAX_LINE_LEN 256
+#define OSD_MAX_LINE_LEN 1024
 
 #define OSD_TRIE_LEN (26+10+1)
 
@@ -53,16 +53,14 @@ struct osd_abstract {
 	void * context;
 
 	void (*show)(void * context, struct osd_line * lines, int num_lines);
+	bool (*arrive)(void * context, struct osd_line * lines, int num_lines);
 	void (*clear)(void * context);
 	bool (*handle_event)(void * context, XEvent *ev);
 };
 
 struct osd_set {
   VECTOR(struct osd_abstract) elements;
-  VECTOR(bool)  is_active;
   struct osd_set_trie trie;
-
-  VECTOR(struct osd_line) lines;
 };
 
 struct osd_creator_abstract {
@@ -79,13 +77,27 @@ struct osd_creator_abstract {
 	} new;
 };
 
+struct msg {
+  int min_duration, max_duration; // ms
+  timestamp_t start_light;
+  VECTOR(struct osd_line) lines;
+
+//internal usage only
+  struct msg *next;
+
+  void * alocated_data;
+  bool output_active[];
+};
 
 struct osd_set osd_set_new(void);
 void osd_set_add(struct osd_set *set, struct osd_abstract abs, int names_len, char ** names);
-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);
+struct osd_line *msg_add_line(struct msg *set, enum osd_line_type type);
+void osd_set_show(struct osd_set *set, struct msg *msg);
+bool osd_set_arrive(struct osd_set *set, struct msg *msg);
+void osd_set_clear(struct osd_set *set, struct msg * msg);
 bool osd_set_handle_event(struct osd_set *set, XEvent *ev);
-void osd_set_active_outputs(struct osd_set *set, char * name, bool val);
+void osd_set_active_outputs(struct osd_set *set, struct msg *msg, char * name, bool val);
+struct msg* osd_set_new_msg(struct osd_set * set);
+void msg_free(struct msg * msg);
 
 #endif
diff --git a/osdd-to-string.c b/osdd-to-string.c
index c4f6876..f7f28d5 100644
--- a/osdd-to-string.c
+++ b/osdd-to-string.c
@@ -135,6 +135,13 @@ bool osd_to_string_parse_arg(struct osd_to_string_state *state, char arg)
 		case 'E':
 			state->end_of_mes_time = 1;
 			break;
+		case 'a':
+			state->on_arrive = 1;
+			break;
+		case 'A':
+			state->on_arrive = 1;
+			state->do_not_insert_msg_to_que = 1;
+			break;
 		default:
 			return 0;
 	}
@@ -219,8 +226,22 @@ VECTOR(char) osd_to_string(struct osd_to_string_state *state, struct osd_line *
 	return out;
 }
 
-VECTOR(char) osd_to_string_end_msg(struct osd_to_string_state *state)
+VECTOR(char) osd_to_string_arrivee_msq(struct osd_to_string_state *state, struct osd_line * lines, int num_lines)
+{
+	if(!state->on_arrive) return 0;
+	return osd_to_string(state, lines, num_lines);
+}
+
+VECTOR(char) osd_to_string_show_msg(struct osd_to_string_state *state, struct osd_line * lines, int num_lines)
+{
+	if(state->on_arrive) return 0;
+	return osd_to_string(state, lines, num_lines);
+
+}
+
+VECTOR(char) osd_to_string_clear_msg(struct osd_to_string_state *state)
 {
+	if(state->on_arrive) return 0;
 	if(!state->end_of_mes_by) return 0;
 	VECTOR(char) out=0;
 	if(state->end_of_mes_time) 
diff --git a/osdd-to-string.h b/osdd-to-string.h
index 459712d..c4adfeb 100644
--- a/osdd-to-string.h
+++ b/osdd-to-string.h
@@ -15,19 +15,26 @@
 		{ "time",		required_argument,	NULL,	't' },\
 		{ "time-separator",		required_argument,	NULL,	'T' },\
 		{ "end",		required_argument,	NULL,	'e' },\
+		{ "end-time",		no_argument,	NULL,	'E' },\
+		{ "on-arrive",		required_argument,	NULL,	'a' },\
+		{ "on-arrive-do-not-que",		required_argument,	NULL,	'A' },\
 
 #define OSDD_TO_STRING_SHORTOP \
-	"c:l:m:rt:T:e:E"
-
-#define OSDD_TO_STRING_HELP "\
--c, --color=<{}>\tSet how to print color of messages {no, rgbDEC, rgbHEX, rgbHEXHASHTAG, term, original}\n\
--l, --line-separator=<s>Separato of each line.\n\
--m, --msq-separator=<s>\tSeparato of each message.\n\
--r, --replace\t\tReplace not alphabet and number in output to '?'\n\
--t, --time=<{}>\t\tSet how to print actual time {no, unix, iso}\n\
--T, --time-separator=<s>Separator of time and message text\n\
--E, --end-time\t\tWrite actual time to end messages (format from -t -T)\n\
-"
+	"c:l:m:rt:T:e:EaA"
+
+#define OSDD_TO_STRING_HELP \
+"-c, --color=<{}>\tSet how to print color of messages {no, rgbDEC, rgbHEX, rgbHEXHASHTAG, term, original}\n" \
+"-l, --line-separator=<s>Separato of each line.\n"\
+"-m, --msq-separator=<s>\tSeparato of each message.\n"\
+"-r, --replace\t\tReplace not alphabet and number in output to '?'\n"\
+"-t, --time=<{}>\t\tSet how to print actual time {no, unix, iso}\n"\
+"-T, --time-separator=<s>Separator of time and message text\n"\
+"-e, --end-<s>\t\tPrint <s> on end of showing message\n"\
+"-E, --end-time\t\tWrite actual time to end messages (format from -t -T)\n"\
+"-a, --on-arrive\t\tPrint message just when arrive (not compatible with -e -E)\n"\
+"-A, --on-arrive\t\tPrint message just when arrive and do not insert it to message queue\n"\
+"\t\t\t\t(not compatible with -e -E)\n"
+
 
 struct osd_to_string_state
 {
@@ -50,9 +57,15 @@ struct osd_to_string_state
 	bool replace_no_text;
 	char * end_of_mes_by;
 	bool end_of_mes_time;
+	bool on_arrive;
+	bool do_not_insert_msg_to_que;
 };
 
 VECTOR(char) osd_to_string(struct osd_to_string_state *state, struct osd_line * lines, int num_lines);
-VECTOR(char) osd_to_string_end_msg(struct osd_to_string_state *state);
+
+VECTOR(char) osd_to_string_arrivee_msq(struct osd_to_string_state *state, struct osd_line * lines, int num_lines);
+VECTOR(char) osd_to_string_show_msg(struct osd_to_string_state *state, struct osd_line * lines, int num_lines);
+VECTOR(char) osd_to_string_clear_msg(struct osd_to_string_state *state);
+
 bool osd_to_string_parse_arg(struct osd_to_string_state *state, char arg);
 void osd_to_string_state_init(struct osd_to_string_state * state);
diff --git a/osdd.c b/osdd.c
index dd25e5d..b1637cb 100644
--- a/osdd.c
+++ b/osdd.c
@@ -15,7 +15,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 
-#define DEBUG
+//#undef DEBUG
 #include "util.h"
 #include "osdd-set.h"
 
@@ -179,24 +179,32 @@ parse_opt_next:;
 
 /*** Displaying of messages ***/
 
-struct msg {
-  struct msg *next;
-  timestamp_t min_light, max_light;
-  char text[1];
-};
 
 static void
 display_msg(struct msg *msg)
 {
   DBG("## Displaying message\n");
-  msg->min_light = now + default_min_duration;
-  msg->max_light = now + default_duration;
+  msg->start_light = now;
+
+  osd_set_show(&osd, msg);
+}
+
+static struct msg *
+parse_msg(unsigned char *buf, int len)
+{
   char *fg_color = default_color;
   char *outline_color = default_outline_color;
   int outline_width = default_outline_width;
 
-  char *line = msg->text;
-  int num_l=0;
+  char *line = xmalloc(sizeof(char) * (len+1));
+  memcpy(line, buf, len);
+  line[len] = 0;
+
+  struct msg *msg = osd_set_new_msg(&osd);
+  msg->min_duration = default_min_duration;
+  msg->max_duration = default_duration;
+  msg->alocated_data=line;
+
   bool is_output_set=0;
   while (*line)
     {
@@ -221,44 +229,43 @@ display_msg(struct msg *msg)
       struct osd_line *l=0;
       if (!key[0])
 	{
-	  l = osd_set_add_line(&osd, OSD_TYPE_TEXT);
+	  l = msg_add_line(msg, OSD_TYPE_TEXT);
 	  sprintf(l->u.text, "%.*s", OSD_MAX_LINE_LEN, val);
 	}
       else if (!strcmp(key, "percentage") || !strcmp(key, "percent"))
 	{
-	  l = osd_set_add_line(&osd, OSD_TYPE_PERCENTAGE);
+	  l = msg_add_line(msg, OSD_TYPE_PERCENTAGE);
 	  l->u.percent = atoi(val);
 	}
       else if (!strcmp(key, "slider"))
 	{
-	  l = osd_set_add_line(&osd, OSD_TYPE_SLIDER);
+	  l = msg_add_line(msg, OSD_TYPE_SLIDER);
 	  l->u.percent = atoi(val);
 	}
       else if (!strcmp(key, "duration"))
-	msg->max_light = now + atoi(val);
+	msg->max_duration = atoi(val);
       else if (!strcmp(key, "min-duration"))
-	msg->min_light = now + atoi(val);
+	msg->min_duration = atoi(val);
       else if (!strcmp(key, "color"))
 	fg_color = val;
       else if (!strcmp(key, "outline-color"))
 	outline_color = val;
       else if (!strcmp(key, "outline-width"))
 	outline_width = atoi(val);
-      else if (!strcmp(key, "output"))
+      else if (!strcmp(key, "output")||!strcmp(key, "to"))
 	  {
 		is_output_set=1;
-		osd_set_active_outputs(&osd,val,1);
+		osd_set_active_outputs(&osd,msg,val,1);
 	  }
       else if (!strcmp(key, "output-no"))
 	  {
 	    if(!is_output_set) 
-			osd_set_active_outputs(&osd,"default",1);
+			osd_set_active_outputs(&osd,msg,"default",1);
 		is_output_set=1;
-		osd_set_active_outputs(&osd,val,0);
+		osd_set_active_outputs(&osd,msg,val,0);
 	  }
       if (l)
 	{
-	  num_l++;
 	  l->fg_color = fg_color;
 	  l->outline_color = outline_color;
 	  l->outline_width = outline_width;
@@ -268,66 +275,27 @@ display_msg(struct msg *msg)
     }
 
   if(!is_output_set) 
-    osd_set_active_outputs(&osd,"default",1);
-  if(!num_l)
+    osd_set_active_outputs(&osd,msg,"default",1);
+  if(!VSIZE(msg->lines))
   {
-	  struct osd_line *l = osd_set_add_line(&osd,OSD_TYPE_TEXT);
+	  struct osd_line *l = msg_add_line(msg,OSD_TYPE_TEXT);
 	  l->u.text[0]=0;
 	  l->fg_color = fg_color;
 	  l->outline_color = outline_color;
 	  l->outline_width = outline_width;
   }
-
-  if (msg->min_light > msg->max_light)
-    msg->min_light = msg->max_light;
-
-  osd_set_show(&osd);
+  if (msg->min_duration > msg->max_duration)
+    msg->min_duration = msg->max_duration;
+  return msg;
 }
 
-static void
-msg_to_stdout(struct msg *msg)
-{
-  DBG("## Printing message to stdout\n");
-
-  char *line = msg->text;
-  int out_parametr_index=0;
-  while (*line)
-    {
-      // 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;
-
-      char *key;
-      char *val = strchr(line, ':');
-      if (val)
-	{
-	  key = line;
-	  *val++ = 0;
-	}
-      else
-	{
-	  key = "";
-	  val = line;
-	}
-      DBG("\t%s:%s\n", key, val);
-
-      if (!key[0])
-	{
-		printf(out_parametr_index++?" %s":"%s",val);
-	}
-
-      line = nl;
-    }
-	printf("\n");
-	fflush(stdout);
-}
 
 static void
 hide_msg(struct msg *msg)
 {
   DBG("## Hiding message\n");
-  osd_set_clear(&osd);
-  free(msg);
+  osd_set_clear(&osd, msg);
+  msg_free(msg);
 }
 
 /*** The message queue ***/
@@ -341,56 +309,18 @@ enqueue_msg(unsigned char *buf, int len)
   if (!len || buf[len-1] != '\n')
     return;
 
-  struct msg *msg = xmalloc(sizeof(*msg) + len);
-  memcpy(msg->text, buf, len);
-  msg->text[len] = 0;
-
-  char to[123];
-  *to=0;
-
-  char *line = msg->text;
-  while (*line)
-    {
-      char *nl = strchr(line, '\n');
-      *nl++=0;
-
-      char *key;
-      char *val = strchr(line, ':');
-      if (val)
-	{
-	  key = line;
-	  *val++ = 0;
-	}
-      else
-	{
-	  key = "";
-	  val = line;
-	}
-      DBG("\t%s:%s\n", key, val);
-
-      if (!strcmp(key, "to"))
-      {
-	      if(strlen(val)<120)
-		      strcpy(to,val);
-      }
-
-      val[-1]=':';
-      nl[-1]=10;
-      line = nl;
-    }
-  if(!strcmp(to,"stdout"))
+  struct msg *msg = parse_msg(buf,len);
+  if(osd_set_arrive(&osd, msg))
   {
-	  msg_to_stdout(msg);
+	  msg_free(msg);
+	  return;
   }
+  if (first_msg)
+    last_msg->next = msg;
   else
-  {
-	  if (first_msg)
-	    last_msg->next = msg;
-	  else
-	    first_msg = msg;
-	  last_msg = msg;
-	  msg->next = NULL;
-  }
+    first_msg = msg;
+  last_msg = msg;
+  msg->next = NULL;
 }
 
 static void
@@ -493,9 +423,9 @@ main(int argc, char **argv)
       if (current_msg)
 	{
 	  if (first_msg)
-	    wait_until = current_msg->min_light;
+	    wait_until = current_msg->min_duration + current_msg->start_light;
 	  else
-	    wait_until = current_msg->max_light;
+	    wait_until = current_msg->max_duration + current_msg->start_light;
 	  if (wait_until <= now)
 	    {
 	      hide_msg(current_msg);
-- 
GitLab