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