Use single function to parse sequences to keep the order

This commit is contained in:
Martin Duquesnoy 2012-01-10 20:17:26 +01:00
parent f6c0bc8a6c
commit 554952cc57
5 changed files with 95 additions and 111 deletions

View File

@ -63,11 +63,7 @@ config_theme(void)
t->client_titlebar_width = fetch_opt_first(ks[i], "12", "client_titlebar_width").num;
t->client_border_width = fetch_opt_first(ks[i], "1", "client_border_width").num;
/* insert_tail with SLIST */
if(SLIST_EMPTY(&W->h.theme))
SLIST_INSERT_HEAD(&W->h.theme, t, next);
else
SLIST_INSERT_AFTER(p, t, next);
SLIST_INSERT_TAIL(&W->h.theme, t, next, p);
p = t;
}

View File

@ -71,11 +71,7 @@ infobar_elem_tag_init(struct element *e)
barwin_mousebind_new(b, Button4, false, g, uicb_tag_next, NULL);
barwin_mousebind_new(b, Button5, false, g, uicb_tag_prev, NULL);
/* insert_tail with SLIST */
if(SLIST_EMPTY(&e->bars))
SLIST_INSERT_HEAD(&e->bars, b, enext);
else
SLIST_INSERT_AFTER(prev, b, enext);
SLIST_INSERT_TAIL(&e->bars, b, enext, prev);
prev = b;
j += s;

View File

@ -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;
/* Check if this is a sequence */
if(*dstr != '\\')
continue;
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);
p = ++dstr;
/* string sequence options */
sq->color = color_atoh(arg[1 + shift]);
sq->str = xstrdup(arg[2 + shift]);
if(!(strchr("sR", *p)) || !(end = strstr(p, "]\\")))
continue;
SLIST_INSERT_HEAD(&ib->statushead, sq, next);
dstr = end + 2;
}
free(sauv);
}
/** 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;
while((p = strstr(dstr, "\r[")))
{
char *arg[6] = { NULL };
int shift = 0;
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);
/* rectangle sequence options */
sq->geo.w = ATOI(arg[1 + shift]);
sq->geo.h = ATOI(arg[2 + shift]);
sq->color = color_atoh(arg[3 + shift]);
SLIST_INSERT_HEAD(&ib->statushead, sq, next);
/* 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);
sq->color = color_atoh(arg[1 + shift]);
sq->str = xstrdup(arg[2 + shift]);
break;
/*
* 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);
sq->geo.w = ATOI(arg[1 + shift]);
sq->geo.h = ATOI(arg[2 + shift]);
sq->color = color_atoh(arg[3 + shift]);
break;
}
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>" */

View File

@ -8,6 +8,7 @@
#include "wmfs.h"
void status_render(struct element *e);
void status_manage(struct element *e);
void uicb_status(Uicb cmd);

View File

@ -21,6 +21,13 @@
} \
} while(/* CONSTCOND */ 0);
/* Insert at the end with SLIST */
#define SLIST_INSERT_TAIL(head, elem, field, prev) \
if(SLIST_EMPTY(head)) \
SLIST_INSERT_HEAD(head, elem, field); \
else \
SLIST_INSERT_AFTER(prev, elem, field);
/* t is Map or Unmap */
#define WIN_STATE(w, t) do { \
X##t##Subwindows(W->dpy, w); \