diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f74af6..a971992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ set(wmfs_src src/menu.c src/mouse.c src/screen.c + src/status.c src/tag.c src/util.c src/viwmfs.c diff --git a/src/event.c b/src/event.c index 2434ccd..4432261 100644 --- a/src/event.c +++ b/src/event.c @@ -198,7 +198,7 @@ clientmessageevent(XClientMessageEvent *ev) if(XGetWindowProperty(dpy, ROOT, net_atom[mess_t], 0, 4096, False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success) { - infobar_draw_statustext(mess_t - wmfs_statustext, (char*)ret); + statustext_handle(mess_t - wmfs_statustext, (char*)ret); XFree(ret); } } diff --git a/src/infobar.c b/src/infobar.c index bfe779b..f4bdef5 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -116,7 +116,7 @@ infobar_draw(int sc) infobar_draw_taglist(sc); infobar_draw_layout(sc); barwin_refresh_color(infobar[sc].bar); - infobar_draw_statustext(sc, infobar[sc].statustext); + statustext_handle(sc, infobar[sc].statustext); return; } @@ -166,95 +166,6 @@ infobar_draw_taglist(int sc) return; } -/** Draw text in the statustext and parse color format - *\param sc Screen - *\param str String -*/ -void -infobar_draw_statustext(int sc, char *str) -{ - /* str without \b[;;;;]\ blocks and str without colorsblocks * */ - char strwb[MAXSS] = { 0 }; - char strwc[MAXSS] = { 0 }; - - char buf[MAXSS] = { 0 }; - char as, col[8] = { 0 }; - int i, j, c, k = 0, b = 0; - uint bp[64][5] = { {0} }; - int len; - char *lastst; - - /* If the str == the current statustext, return (not needed) */ - if(!str) - return; - - barwin_refresh_color(infobar[sc].bar); - - /* save last status text address (for free at the end) */ - lastst = infobar[sc].statustext; - - infobar[sc].statustext = _strdup(str); - len = ((strlen(str) > sizeof(strwc)) ? sizeof(strwc) : strlen(str)); - - /* Search \b[;;;;#]\ blocks and store properties. */ - for(i = j = 0; i < len; ++i, ++j) - if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &bp[b][0], &bp[b][1], &bp[b][2], &bp[b][3], &bp[b][4], &as) == 6 - && as == '\\') - for(++b, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i); - else - strwb[j] = str[i]; - - /* Count how many color blocks there is and make a string without these (\#xxxxxx\) */ - for(i = j = c = 0; i < len; ++i, ++j) - if(strwb[i] == '\\' && strwb[i + 1] == '#' && strwb[i + 8] == '\\') - { - ++c; - i += 8; - --j; - } - else - strwc[j] = strwb[i]; - - /* Draw a first time the statustext for non colorized text */ - draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(strwc), - FHINFOBAR, infobar[sc].bar->fg, 0, strwc); - - /* Draw text with its color */ - if(c) - { - strcpy(buf, strwc); - - for(i = k = 0; i < len; ++i, ++k) - if(strwb[i] == '\\' && strwb[i + 1] == '#' && strwb[i + 8] == '\\') - { - /* Store current color in col[] */ - for(j = 0, ++i; strwb[i] != '\\'; col[j++] = strwb[i++]); - - /* Draw a rectangle with the bar color to draw the text properly */ - draw_rectangle(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]), - 0, INFOBARH - (sgeo[sc].width - SHADH) - textw(&buf[k]), - INFOBARH, conf.colors.bar); - - /* Draw text with its color */ - draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]), - FHINFOBAR, col, 0, &buf[k]); - - strcpy(buf, strwc); - ++i; - } - } - - /* Finally drawing rectangles with stored properties. */ - for(i = 0; i < b; ++i) - draw_rectangle(infobar[sc].bar->dr, bp[i][0], bp[i][1], bp[i][2], bp[i][3], bp[i][4]); - - barwin_refresh(infobar[sc].bar); - - free(lastst); - - return; -} - /** Destroy the InfoBar */ void diff --git a/src/status.c b/src/status.c new file mode 100644 index 0000000..47a5c2a --- /dev/null +++ b/src/status.c @@ -0,0 +1,181 @@ +/* +* status.c +* Copyright © 2008, 2009 Martin Duquesnoy +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* * Neither the name of the nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "wmfs.h" + +/** Check rectangles blocks in str and return properties + * --> \b[x;y;width;height;#color]\ + *\param r StatusRec pointer, rectangles properties + *\param str String + *\return n Length of r + */ +int +statustext_rectangle(StatusRec *r, char *str) +{ + char as; + int n, i, j, k; + + for(i = j = n = 0; i < strlen(str); ++i, ++j) + if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &r[n].x, &r[n].y, &r[n].w, &r[n].h, &r[n].color, &as) == 6 + && as == '\\') + for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i); + else if(j != i) + str[j] = str[i]; + + for(k = j; k < i; str[k++] = 0); + + return n; +} + +/** Check text blocks in str and return properties + * --> \s[x;y;#color;text]\ + *\param s StatusText pointer, text properties + *\param str String + *\return n Length of s + */ +int +statustext_text(StatusText *s, char *str) +{ + char as; + int n, i, j, k; + + for(i = j = n = 0; i < strlen(str); ++i, ++j) + if(sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^]]]%c", &s[n].x, &s[n].y, s[n].color, s[n].text, &as) == 5 + && as == '\\') + for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i); + else if(j != i) + str[j] = str[i]; + + for(k = j; k < i; str[k++] = 0); + + return n; +} + +/** Draw normal text and colored normal text + * --> \#color\ text in color + *\param sc Screen + *\param str String + */ +void +statustext_normal(int sc, char *str) +{ + char strwc[MAXSTATUS] = { 0 }; + char buf[MAXSTATUS] = { 0 }; + char col[8] = { 0 }; + int n, i, j, k; + + for(i = j = n = 0; i < strlen(str); ++i, ++j) + if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\') + { + ++n; + i += 8; + --j; + } + else + strwc[j] = str[i]; + + /* Draw normal text without any blocks */ + draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(strwc), + FHINFOBAR, infobar[sc].bar->fg, 0, strwc); + + if(n) + { + strcpy(buf, strwc); + + for(i = k = 0; i < strlen(str); ++i, ++k) + if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\') + { + /* Store current color in col[] */ + for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]); + + /* Draw a rectangle with the bar color to draw the text properly */ + draw_rectangle(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]), + 0, INFOBARH - (sgeo[sc].width - SHADH) - textw(&buf[k]), + INFOBARH, conf.colors.bar); + + /* Draw text with its color */ + draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]), + FHINFOBAR, col, 0, &buf[k]); + + strcpy(buf, strwc); + ++i; + } + } + + return; +} + +/** Handle statustext and draw all things in infobar of specified screen + *\param sc Screen number + *\param str String + */ +void +statustext_handle(int sc, char *str) +{ + char *lastst; + int i, nr, ns, len; + StatusRec r[128]; + StatusText s[128]; + + /* If the str == the current statustext, return (not needed) */ + if(!str) + return; + + barwin_refresh_color(infobar[sc].bar); + + /* save last status text address (for free at the end) */ + lastst = infobar[sc].statustext; + + infobar[sc].statustext = _strdup(str); + len = ((strlen(str) > MAXSTATUS) ? MAXSTATUS : strlen(str)); + + /* Store rectangles & located text properties. */ + nr = statustext_rectangle(r, str); + ns = statustext_text(s, str); + + /* Draw normal text (and possibly colored with \#color\ blocks) */ + statustext_normal(sc, str); + + /* Draw rectangles with stored properties. */ + for(i = 0; i < nr; ++i) + draw_rectangle(infobar[sc].bar->dr, r[i].x, r[i].y, r[i].w, r[i].h, r[i].color); + + /* Draw located text with stored properties. */ + for(i = 0; i < ns; ++i) + draw_text(infobar[sc].bar->dr, s[i].x, s[i].y, s[i].color, 0, s[i].text); + + barwin_refresh(infobar[sc].bar); + + free(lastst); + + return; +} diff --git a/src/structs.h b/src/structs.h index e5190f3..4c03cb2 100644 --- a/src/structs.h +++ b/src/structs.h @@ -399,6 +399,19 @@ typedef struct int nlauncher; } Conf; +typedef struct +{ + uint x, y, w, h; + uint color; +} StatusRec; + +typedef struct +{ + uint x, y; + char color[8]; + char text[512]; +} StatusText; + /* Config.c struct */ typedef struct { diff --git a/src/wmfs.h b/src/wmfs.h index 614cdd4..33922ab 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -87,7 +87,7 @@ #define DEF_CONF ".config/wmfs/wmfsrc" #define DEF_STATUS ".config/wmfs/status.sh" #define PAD conf.pad -#define MAXSS 4096 +#define MAXSTATUS 4096 #define CWIN(win, parent, x, y, w, h, b, mask, col, at) \ do { \ @@ -134,7 +134,6 @@ void infobar_init(void); void infobar_draw(int sc); void infobar_draw_layout(int sc); void infobar_draw_taglist(int sc); -void infobar_draw_statustext(int sc, char *str); void infobar_destroy(void); void infobar_set_position(int pos); void uicb_infobar_togglepos(uicb_t); @@ -281,6 +280,12 @@ void uicb_screen_select(uicb_t); void uicb_screen_next(uicb_t); void uicb_screen_prev(uicb_t); +/* status.c */ +int statustext_rectangle(StatusRec *r, char *str); +int statustext_text(StatusText *s, char *str); +void statustext_normal(int sc, char *str); +void statustext_handle(int sc, char *str); + /* layout.c */ void arrange(int screen, Bool update_layout); void freelayout(int screen);