From c782f9a22324c11593cb34c08da34f9ffc45af7e Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Mon, 29 Aug 2011 03:32:08 +0200 Subject: [PATCH] tag element + uicb tag --- wmfs2/src/config.h | 7 ++ wmfs2/src/draw.h | 1 + wmfs2/src/infobar.c | 164 ++++++++++++++++++++++++++++++++++++++++++-- wmfs2/src/infobar.h | 9 --- wmfs2/src/screen.c | 11 ++- wmfs2/src/tag.c | 54 ++++++++++++++- wmfs2/src/tag.h | 5 ++ wmfs2/src/util.h | 7 +- wmfs2/src/wmfs.h | 15 ++-- 9 files changed, 247 insertions(+), 26 deletions(-) diff --git a/wmfs2/src/config.h b/wmfs2/src/config.h index d76cc1d..42f6a40 100755 --- a/wmfs2/src/config.h +++ b/wmfs2/src/config.h @@ -12,11 +12,18 @@ #include "wmfs.h" #include "util.h" +#include "tag.h" static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] = { + /* Sys */ { "spawn", uicb_spawn }, { "quit", uicb_quit }, + + /* Tag */ + { "tag_set", uicb_tag_set }, + { "tag_next", uicb_tag_next }, + { "tag_prev", uicb_tag_prev }, { NULL, NULL } }; diff --git a/wmfs2/src/draw.h b/wmfs2/src/draw.h index 2258dd5..fbcbb27 100755 --- a/wmfs2/src/draw.h +++ b/wmfs2/src/draw.h @@ -13,6 +13,7 @@ #include "wmfs.h" #define TEXTY(w) ((W->font.height - W->font.de) + ((w - W->font.height) >> 1)) +#define PAD (4) static inline void draw_text(Drawable d, int x, int y, Color fg, const char *str) diff --git a/wmfs2/src/infobar.c b/wmfs2/src/infobar.c index 30616ca..d8d6a92 100755 --- a/wmfs2/src/infobar.c +++ b/wmfs2/src/infobar.c @@ -9,10 +9,155 @@ #include "barwin.h" #include "util.h" - #define ELEM_DEFAULT_ORDER "tlsS" #define INFOBAR_DEF_W (12) +#define ELEMX(e, head) TAILQ_PREV(e, head, next)->geo. + +static void infobar_elem_tag_init(Element *e); +static void infobar_elem_tag_update(Element *e); + +const struct elem_funcs +{ + char c; + void (*func_init)(Element *e); + void (*func_update)(Element *e); +} elem_funcs[] = +{ + { 't', infobar_elem_tag_init, infobar_elem_tag_update }, + + /* { 'l', infobar_elem_layout_init, infobar_elem_layout_update }, + { 's', infobar_elem_selbar_init, infobar_elem_selbar_update }, + { 'S', infobar_elem_status_init, infobar_elem_status_update },*/ + + { '\0', NULL, NULL } +}; + +static inline void +infobar_elem_placement(Element *e) +{ + Element *p = TAILQ_PREV(e, esub, next); + + e->geo.y = 0; + e->geo.w = 0; + e->geo.h = e->infobar->geo.h; + e->geo.x = (p ? p->geo.x + p->geo.w + PAD : 0); +} + +static void +infobar_elem_tag_init(Element *e) +{ + Tag *t; + Barwin *b, *prev; + int tmp, j; + + infobar_elem_placement(e); + + j = e->geo.x; + + TAILQ_FOREACH(t, &e->infobar->screen->tags, next) + { + tmp = draw_textw(t->name) + PAD; + + b = barwin_new(e->infobar->bar->win, j, 0, tmp, e->geo.h, 0x009900, 0x777777, false); + b->ptr = (void*)t; + barwin_map(b); + + if(SLIST_EMPTY(&e->bars)) + SLIST_INSERT_HEAD(&e->bars, b, next); + else + SLIST_INSERT_AFTER(prev, b, next); + + prev = b; + b = NULL; + j += tmp; + } +} + +static void +infobar_elem_tag_update(Element *e) +{ + Tag *t, *sel = e->infobar->screen->seltag; + Barwin *b; + + SLIST_FOREACH(b, &e->bars, next) + { + t = (Tag*)b->ptr; + + /* Selected */ + if(t == sel) + { + b->fg = 0x000000; + b->bg = 0x3D5700; + } + else + { + b->fg = 0x3D5700; + b->bg = 0x000000; + } + + barwin_refresh_color(b); + + draw_text(b->dr, (PAD >> 1), TEXTY(e->geo.h), b->fg, t->name); + + barwin_refresh(b); + } +} + +void +infobar_elem_init(Infobar *i) +{ + Element *e; + int n, j; + + for(n = 0; n < strlen(i->elemorder); ++n) + { + for(j = 0; j < LEN(elem_funcs); ++j) + if(elem_funcs[j].c == i->elemorder[n]) + { + e = xcalloc(1, sizeof(Element)); + + SLIST_INIT(&e->bars); + + e->infobar = i; + e->type = j; + e->func_init = elem_funcs[j].func_init; + e->func_update = elem_funcs[j].func_update; + + TAILQ_INSERT_TAIL(&i->elements, e, next); + + e->func_init(e); + + break; + } + } +} + +void +infobar_elem_update(Infobar *i) +{ + Element *e; + + TAILQ_FOREACH(e, &i->elements, next) + if(i->elemupdate & FLAGINT(e->type)) + e->func_update(e); +} + +void +infobar_elem_remove(Element *e) +{ + Barwin *b; + + TAILQ_REMOVE(&e->infobar->elements, e, next); + + while(!SLIST_EMPTY(&e->bars)) + { + b = SLIST_FIRST(&e->bars); + SLIST_REMOVE_HEAD(&e->bars, next); + barwin_remove(b); + } +} + void infobar_init(void) { @@ -25,7 +170,7 @@ infobar_init(void) i->screen = s; i->elemorder = xstrdup(ELEM_DEFAULT_ORDER); - STAILQ_INIT(&i->elements); + TAILQ_INIT(&i->elements); /* Positions TODO: geo = infobar_position(Position {Top,Bottom,Hidden}) */ i->geo = s->geo; @@ -39,18 +184,21 @@ infobar_init(void) barwin_map_subwin(i->bar); barwin_refresh_color(i->bar); - /* TODO: infobar_elem_init(i) */ + infobar_elem_init(i); infobar_refresh(i); SLIST_INSERT_HEAD(&s->infobars, i, next); - i = NULL; } } void infobar_refresh(Infobar *i) { - draw_text(i->bar->dr, 1, TEXTY(INFOBAR_DEF_W), 0x005500, "WMFS2"); + draw_text(i->bar->dr, 0, TEXTY(INFOBAR_DEF_W), 0x005500, "|"); + + i->elemupdate |= FLAGINT(ElemTag); + + infobar_elem_update(i); barwin_refresh(i->bar); } @@ -58,9 +206,13 @@ infobar_refresh(Infobar *i) void infobar_remove(Infobar *i) { + Element *e; + free(i->elemorder); - /* TODO: infobar_elem_free */ + TAILQ_FOREACH(e, &i->elements, next) + infobar_elem_remove(e); + barwin_remove(i->bar); SLIST_REMOVE(&i->screen->infobars, i, Infobar, next); diff --git a/wmfs2/src/infobar.h b/wmfs2/src/infobar.h index 52b8e2a..7222e26 100755 --- a/wmfs2/src/infobar.h +++ b/wmfs2/src/infobar.h @@ -9,15 +9,6 @@ #include "wmfs.h" enum { ElemTag = 0, ElemLayout, ElemSelbar, ElemStatus, ElemCustom }; -/* -const struct elem_funcs { char c; void (*func_init)(Infobar *i); void (*func_update)(Element *e); } elem_funcs[] = -{ - { 't', infobar_elem_tag_init, infobar_elem_tag_update }, - { 'l', infobar_elem_layout_init, infobar_elem_layout_update }, - { 's', infobar_elem_selbar_init, infobar_elem_selbar_update }, - { 'S', infobar_elem_status_init, infobar_elem_status_update }, - { '\0', NULL, NULL } -};*/ void infobar_init(void); Infobar *infobar_new(Scr33n *s); diff --git a/wmfs2/src/screen.c b/wmfs2/src/screen.c index 58e81e4..670248e 100755 --- a/wmfs2/src/screen.c +++ b/wmfs2/src/screen.c @@ -11,6 +11,7 @@ #include "screen.h" #include "util.h" +#include "tag.h" static Scr33n* screen_new(Geo *g, int id) @@ -21,7 +22,7 @@ screen_new(Geo *g, int id) s->seltag = NULL; s->id = id; - SLIST_INIT(&s->tags); + TAILQ_INIT(&s->tags); SLIST_INIT(&s->infobars); SLIST_INSERT_HEAD(&W->h.screen, s, next); @@ -57,6 +58,12 @@ screen_init(void) s = screen_new(&g, i); tag_screen(s, tag_new(s, "tag")); /* tmp */ + + { + tag_new(s, "tag2"); + tag_new(s, "tag3"); + } + s = NULL; } @@ -85,7 +92,7 @@ screen_free(void) s = SLIST_FIRST(&W->h.screen); SLIST_REMOVE_HEAD(&W->h.screen, next); infobar_free(s); - /*tag_free(s);*/ + tag_free(s); free(s); } } diff --git a/wmfs2/src/tag.c b/wmfs2/src/tag.c index 0a92e20..a4dcf23 100755 --- a/wmfs2/src/tag.c +++ b/wmfs2/src/tag.c @@ -5,6 +5,7 @@ #include "tag.h" #include "util.h" +#include "infobar.h" Tag* tag_new(Scr33n *s, char *name) @@ -18,7 +19,7 @@ tag_new(Scr33n *s, char *name) t->flags = 0; t->sel = NULL; - SLIST_INSERT_HEAD(&s->tags, t, next); + TAILQ_INSERT_TAIL(&s->tags, t, next); return t; } @@ -26,13 +27,62 @@ tag_new(Scr33n *s, char *name) void tag_screen(Scr33n *s, Tag *t) { + Infobar *i; + s->seltag = t; + SLIST_FOREACH(i, &s->infobars, next) + { + i->elemupdate |= FLAGINT(ElemTag); + infobar_elem_update(i); + } +} + +void +uicb_tag_set(Uicb cmd) +{ + int i = 0, n = ATOI(cmd); + Tag *t; + + TAILQ_FOREACH(t, &W->screen->tags, next) + if(++i == n) + { + tag_screen(W->screen, t); + return; + } +} + +void +uicb_tag_next(Uicb cmd) +{ + Tag *t; + + if((t = TAILQ_NEXT(W->screen->seltag, next))) + tag_screen(W->screen, t); + else if( /* CIRCULAR OPTION */ 1) + tag_screen(W->screen, TAILQ_FIRST(&W->screen->tags)); +} + +void +uicb_tag_prev(Uicb cmd) +{ + Tag *t; + + if((t = TAILQ_PREV(W->screen->seltag, tsub, next))) + tag_screen(W->screen, t); + else if( /* CIRCULAR OPTION */ 1) + tag_screen(W->screen, TAILQ_LAST(&W->screen->tags, tsub)); } void tag_free(Scr33n *s) { - FREE_LIST(Tag, s->tags); + Tag *t; + + TAILQ_FOREACH(t, &s->tags, next) + { + TAILQ_REMOVE(&s->tags, t, next); + free(t); + } } diff --git a/wmfs2/src/tag.h b/wmfs2/src/tag.h index 1128daa..4d8ef44 100755 --- a/wmfs2/src/tag.h +++ b/wmfs2/src/tag.h @@ -11,6 +11,11 @@ Tag *tag_new(Scr33n *s, char *name); void tag_screen(Scr33n *s, Tag *t); void tag_free(Scr33n *s); +void uicb_tag_set(Uicb cmd); +void uicb_tag_next(Uicb cmd); +void uicb_tag_prev(Uicb cmd); + + #endif /* TAG_H */ diff --git a/wmfs2/src/util.h b/wmfs2/src/util.h index 4ffc4c0..6e49145 100755 --- a/wmfs2/src/util.h +++ b/wmfs2/src/util.h @@ -6,6 +6,8 @@ #ifndef UTIL_H #define UTIL_H +#include + #include "wmfs.h" /* Todo FREE_LIST(type, head, function_remove) */ @@ -19,7 +21,10 @@ } \ } while(/* CONSTCOND */ 0); -#define ATOM(a) XInternAtom(W->dpy, (a), False) +#define ATOM(a) XInternAtom(W->dpy, (a), False) +#define LEN(x) (sizeof(x) / sizeof(*x)) +#define FLAGINT(i) (1 << i) +#define ATOI(s) strtol(s, NULL, 10) void *xmalloc(size_t nmemb, size_t size); void *xcalloc(size_t nmemb, size_t size); diff --git a/wmfs2/src/wmfs.h b/wmfs2/src/wmfs.h index 535fcb6..8791fee 100755 --- a/wmfs2/src/wmfs.h +++ b/wmfs2/src/wmfs.h @@ -57,6 +57,7 @@ struct Barwin Color fg, bg; Geo geo; Flags flags; + void *ptr; /* Special cases */ SLIST_HEAD(, MouseBind) mousebinds; SLIST_ENTRY(Barwin) next; }; @@ -64,12 +65,13 @@ struct Barwin /* Infobar's element */ struct Element { - SLIST_ENTRY(Barwin) bars; + SLIST_HEAD(, Barwin) bars; Geo geo; + Infobar *infobar; int type; - void (*func_init)(Infobar *i); + void (*func_init)(Element *e); void (*func_update)(Element *e); - STAILQ_ENTRY(Element) next; + TAILQ_ENTRY(Element) next; }; /* Infobar */ @@ -79,7 +81,8 @@ struct Infobar Geo geo; Scr33n *screen; char *elemorder; - STAILQ_HEAD(, Element) elements; + Flags elemupdate; + TAILQ_HEAD(esub, Element) elements; SLIST_ENTRY(Infobar) next; }; @@ -89,7 +92,7 @@ struct Scr33n Geo geo; Tag *seltag; int id; - SLIST_HEAD(, Tag) tags; + TAILQ_HEAD(tsub, Tag) tags; SLIST_HEAD(, Infobar) infobars; SLIST_ENTRY(Scr33n) next; }; @@ -101,7 +104,7 @@ struct Tag Scr33n *screen; Flags flags; Client *sel; - SLIST_ENTRY(Tag) next; + TAILQ_ENTRY(Tag) next; }; /* Client */