|
@@ -9,26 +9,20 @@
|
|
|
#include "util.h"
|
|
|
|
|
|
#include <string.h>
|
|
|
+#include <ctype.h>
|
|
|
|
|
|
/* Parse arg;between;semicolon */
|
|
|
-#define STATUS_GET_ARGS(i, inc, p, arg, n) \
|
|
|
- do { \
|
|
|
- for(i = 0, p += inc, arg[0] = p; *p && *p != ']' && i < n; ++p) \
|
|
|
- if(*p == ';') \
|
|
|
- { \
|
|
|
- *p = '\0'; \
|
|
|
- arg[++i] = ++p; \
|
|
|
- } \
|
|
|
- *p = '\0'; \
|
|
|
+#define STATUS_GET_ARGS(i, p, arg, n) \
|
|
|
+ do { \
|
|
|
+ for(i = 0, p += 2, arg[0] = p; *p && *p != ']' && i < n; ++p) \
|
|
|
+ if(*p == ';') \
|
|
|
+ { \
|
|
|
+ *p = '\0'; \
|
|
|
+ arg[++i] = ++p; \
|
|
|
+ } \
|
|
|
+ *p = '\0'; \
|
|
|
} while(/* CONSTCOND */ 0);
|
|
|
|
|
|
-#define STATUS_CHECK_END(str, end, p) \
|
|
|
- if(!(end = strstr(p, "]\\"))) \
|
|
|
- { \
|
|
|
- str = end + 2; \
|
|
|
- continue; \
|
|
|
- }
|
|
|
-
|
|
|
#define STATUS_CHECK_ARGS(i, n1, n2, str, end) \
|
|
|
if(i != n1 && i != n2) \
|
|
|
{ \
|
|
@@ -37,12 +31,12 @@
|
|
|
}
|
|
|
|
|
|
/* Alloc & fill status_sq struct with universal options: align/position and type */
|
|
|
-#define STATUS_FILL_SQ(sq, t, shift, arg) \
|
|
|
+#define STATUS_FILL_SQ(sq, t, ma, shift, arg) \
|
|
|
do { \
|
|
|
sq = xcalloc(1, sizeof(struct status_seq)); \
|
|
|
sq->type = t; \
|
|
|
\
|
|
|
- if(!strcmp(arg[0], "right") || !strcmp(arg[0], "left")) \
|
|
|
+ if(i == ma || !strcmp(arg[0], "right") || !strcmp(arg[0], "left")) \
|
|
|
sq->align = str_to_position(arg[0]); \
|
|
|
else \
|
|
|
{ \
|
|
@@ -53,73 +47,61 @@
|
|
|
} \
|
|
|
} while(/* CONSTCOND */ 0); \
|
|
|
|
|
|
-
|
|
|
-/** Check text blocks in str and list it
|
|
|
- * --> \s[left/right;#color;text]\ OR \s[x;y;#color;text]\
|
|
|
- *\param ib Infobar pointer
|
|
|
- *\param str String
|
|
|
- */
|
|
|
static void
|
|
|
-status_text(struct infobar *ib, char *str)
|
|
|
+status_parse(struct infobar *ib)
|
|
|
{
|
|
|
- struct status_seq *sq;
|
|
|
- int i;
|
|
|
- char *dstr = xstrdup(str), *sauv = dstr;
|
|
|
- char *p, *end;
|
|
|
+ struct status_seq *sq, *prev = NULL;
|
|
|
+ int i, shift = 0;
|
|
|
+ char *dstr = xstrdup(ib->status), *sauv = dstr;
|
|
|
+ char type, *p, *end, *arg[6] = { NULL };
|
|
|
|
|
|
- while((p = strstr(dstr, "\\s[")))
|
|
|
+ for(; *dstr; ++dstr)
|
|
|
{
|
|
|
- char *arg[5] = { NULL };
|
|
|
- int shift = 0;
|
|
|
-
|
|
|
- STATUS_CHECK_END(dstr, end, p);
|
|
|
- STATUS_GET_ARGS(i, 3, p, arg, 4);
|
|
|
- STATUS_CHECK_ARGS(i, 2, 3, dstr, end);
|
|
|
- STATUS_FILL_SQ(sq, 's', shift, arg);
|
|
|
+ /* Check if this is a sequence */
|
|
|
+ if(*dstr != '\\')
|
|
|
+ continue;
|
|
|
|
|
|
- /* string sequence options */
|
|
|
- sq->color = color_atoh(arg[1 + shift]);
|
|
|
- sq->str = xstrdup(arg[2 + shift]);
|
|
|
+ p = ++dstr;
|
|
|
|
|
|
- SLIST_INSERT_HEAD(&ib->statushead, sq, next);
|
|
|
+ if(!(strchr("sR", *p)) || !(end = strstr(p, "]\\")))
|
|
|
+ continue;
|
|
|
|
|
|
- dstr = end + 2;
|
|
|
- }
|
|
|
+ /* Then parse & list it */
|
|
|
+ switch((type = tolower(*p)))
|
|
|
+ {
|
|
|
+ /*
|
|
|
+ * Text sequence: \s[left/right;#color;text]\ OR \s[x;y;#color;text]\
|
|
|
+ */
|
|
|
+ case 's':
|
|
|
+ STATUS_GET_ARGS(i, p, arg, 4);
|
|
|
+ STATUS_CHECK_ARGS(i, 2, 3, dstr, end);
|
|
|
+ STATUS_FILL_SQ(sq, type, 2, shift, arg);
|
|
|
|
|
|
- free(sauv);
|
|
|
-}
|
|
|
+ sq->color = color_atoh(arg[1 + shift]);
|
|
|
+ sq->str = xstrdup(arg[2 + shift]);
|
|
|
|
|
|
-/** Check rectangle blocks in str and list it
|
|
|
- * --> \s[left/right;width;height;#color]\ OR \s[x;y;width;height;#color]\
|
|
|
- *\param ib Infobar pointer
|
|
|
- *\param str String
|
|
|
- */
|
|
|
-static void
|
|
|
-status_rect(struct infobar *ib, char *str)
|
|
|
-{
|
|
|
- struct status_seq *sq;
|
|
|
- int i;
|
|
|
- char *dstr = xstrdup(str), *sauv = dstr;
|
|
|
- char *p, *end;
|
|
|
+ break;
|
|
|
|
|
|
- while((p = strstr(dstr, "\r[")))
|
|
|
- {
|
|
|
- char *arg[6] = { NULL };
|
|
|
- int shift = 0;
|
|
|
+ /*
|
|
|
+ * Rectangle sequence: \s[left/right;w;h;#color]\ OR \s[x;y;w;h;#color]\
|
|
|
+ */
|
|
|
+ case 'r':
|
|
|
+ STATUS_GET_ARGS(i, p, arg, 5);
|
|
|
+ STATUS_CHECK_ARGS(i, 3, 4, dstr, end);
|
|
|
+ STATUS_FILL_SQ(sq, type, 3, shift, arg);
|
|
|
|
|
|
- STATUS_CHECK_END(dstr, end, p);
|
|
|
- STATUS_GET_ARGS(i, 2, p, arg, 5);
|
|
|
- STATUS_CHECK_ARGS(i, 3, 4, dstr, end);
|
|
|
- STATUS_FILL_SQ(sq, 'r', shift, arg);
|
|
|
+ sq->geo.w = ATOI(arg[1 + shift]);
|
|
|
+ sq->geo.h = ATOI(arg[2 + shift]);
|
|
|
+ sq->color = color_atoh(arg[3 + shift]);
|
|
|
|
|
|
- /* rectangle sequence options */
|
|
|
- sq->geo.w = ATOI(arg[1 + shift]);
|
|
|
- sq->geo.h = ATOI(arg[2 + shift]);
|
|
|
- sq->color = color_atoh(arg[3 + shift]);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- SLIST_INSERT_HEAD(&ib->statushead, sq, next);
|
|
|
+ SLIST_INSERT_TAIL(&ib->statushead, sq, next, prev);
|
|
|
|
|
|
+ prev = sq;
|
|
|
dstr = end + 2;
|
|
|
+ shift = 0;
|
|
|
}
|
|
|
|
|
|
free(sauv);
|
|
@@ -177,11 +159,35 @@ status_apply_list(struct element *e)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* Render current statustext of an element */
|
|
|
+void
|
|
|
+status_render(struct element *e)
|
|
|
+{
|
|
|
+ struct barwin *b = SLIST_FIRST(&e->bars);
|
|
|
+
|
|
|
+ if(!e->infobar->status)
|
|
|
+ return;
|
|
|
+
|
|
|
+ barwin_refresh_color(b);
|
|
|
+
|
|
|
+ /* Use simple text instead sequence if no sequence found */
|
|
|
+ if(SLIST_EMPTY(&e->infobar->statushead))
|
|
|
+ {
|
|
|
+ int l = draw_textw(e->infobar->theme, e->infobar->status);
|
|
|
+ draw_text(b->dr, e->infobar->theme, e->geo.w - l,
|
|
|
+ TEXTY(e->infobar->theme, e->geo.h), b->fg, e->infobar->status);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ status_apply_list(e);
|
|
|
+
|
|
|
+ barwin_refresh(b);
|
|
|
+}
|
|
|
+
|
|
|
+/* Parse and render statustext */
|
|
|
void
|
|
|
status_manage(struct element *e)
|
|
|
{
|
|
|
struct status_seq *sq;
|
|
|
- struct barwin *b = SLIST_FIRST(&e->bars);
|
|
|
|
|
|
SLIST_INIT(&e->infobar->statushead);
|
|
|
|
|
@@ -194,30 +200,8 @@ status_manage(struct element *e)
|
|
|
free(sq);
|
|
|
}
|
|
|
|
|
|
- if(!e->infobar->status)
|
|
|
- return;
|
|
|
-
|
|
|
- barwin_refresh_color(b);
|
|
|
-
|
|
|
- status_text(e->infobar, e->infobar->status);
|
|
|
- status_rect(e->infobar, e->infobar->status);
|
|
|
-
|
|
|
- /* DEBUG
|
|
|
- SLIST_FOREACH(sq, &e->infobar->statushead, next)
|
|
|
- printf("-> %c (%d;%d)x(%d;%d) (%d) (#%x) (%s)\n",
|
|
|
- sq->type, sq->geo.x, sq->geo.y, sq->geo.w, sq->geo.h, sq->align, sq->color, sq->str);
|
|
|
- */
|
|
|
-
|
|
|
- status_apply_list(e);
|
|
|
-
|
|
|
- /*
|
|
|
- l = draw_textw(e->infobar->theme, e->infobar->status);
|
|
|
- draw_text(b->dr, e->infobar->theme, e->geo.w - l,
|
|
|
- TEXTY(e->infobar->theme, e->geo.h), b->fg, e->infobar->status);
|
|
|
- */
|
|
|
-
|
|
|
- barwin_refresh(b);
|
|
|
-
|
|
|
+ status_parse(e->infobar);
|
|
|
+ status_render(e);
|
|
|
}
|
|
|
|
|
|
/* Syntax: "<infobar name> <status string>" */
|