我正在尝试为DWM 6.1编写一个补丁来为状态栏着色,到目前为止我已设法这样做了,但我使用的是十六进制字符,如\x01
来表示颜色。这样做我发现了一个问题。当dwm获得状态栏的宽度时,也会使用转义字符进行计数,从而导致错误的状态栏。
我写了一个虚拟程序试图解决这个问题。我的想法是,给出以下状态文本:
char buf[] = "Hello World\x01, Bye!\x02";
必须用颜色1写Hello World
,用颜色2写, Bye!
。我想解析文本并得到:
char cleanBuf[] = "Hello World, Bye!";
我已经做到了。但是现在我需要以某种方式记住转义序列所在的位置,以便用相应的颜色绘制文本。我认为按照它们出现的顺序存储颜色stack
,在这种情况下,堆栈将具有{color1, color2}
。对于文本的开头和结尾指针必须采用颜色的结构,Hello World
我需要一个指向H
的指针和另一个指向d
的指针。这样我就可以创建一个新的字符串来解析XDrawString
并用相应的颜色打印出来。
这是最好的方法吗?我想我的事情有点复杂化了。如果您想尝试,完整的程序是here。我在这里粘贴主循环:
while (1) {
XNextEvent(dpy, &e);
if (e.type == Expose && e.xexpose.count < 1) {
char buf[] = "Hello World\x01, Bye!\x02";
char cleanBuf[strlen(buf)];
memset(cleanBuf, 0, strlen(cleanBuf));
char *copy = strdup(buf);
char *delim = "\x01\x02";
char *res = strtok(buf, delim);
strcat(cleanBuf, res);
unsigned long color1 = 0xff0000;
unsigned long color2 = 0x00ff00;
unsigned long color;
int x = 10;
while (res) {
/* Figure out what delimiter was used */
// Thanks to http://stackoverflow.com/a/12460511/1612432
char deli = copy[res - buf + strlen(res)];
if (deli == '\x01')
color = color1;
else if (deli == '\x02')
color = color2;
else
color = 0xffffff;
XSetForeground(dpy, gc, color);
XDrawString(dpy, win, gc, x, 10, res, strlen(res));
x += 50;
res = strtok(0, delim);
if (res)
strcat(cleanBuf, res);
}
free(copy);
} else if (e.type == ButtonPress)
break;
}
答案 0 :(得分:1)
我终于可以使用以下方法解析字符串:
void
parsestatus(char *text, unsigned long *color_queue, char tokens[][256]) {
// TODO move variables that can to main in order to not recreated them
char *copy = strdup(text);
char cleanBuf[strlen(text)];
memset(cleanBuf, 0, strlen(cleanBuf));
char delim[NUMCOLORS+1];
/* Thanks to http://stackoverflow.com/a/24931903/1612432 */
for (int i = 0; i < NUMCOLORS; ++i)
delim[i] = i + 1;
/* Terminates as string */
delim[NUMCOLORS] = '\0';
char *res = strtok(copy, delim);
strcat(tokens[0], res);
strcat(cleanBuf, res);
int i = 1;
while (res) {
/* Figure out what delimiter was used */
// Thanks to http://stackoverflow.com/a/12460511/1612432
int deli = text[res - copy + strlen(res)] - 1;
color_queue[i-1] = colors[deli];
res = strtok(0, delim);
if (res){
strcat(tokens[i++], res);
strcat(cleanBuf, res);
}
}
free(copy);
strncpy(text, cleanBuf, strlen(cleanBuf));
text[strlen(cleanBuf)] = '\0';
}
然后,在每次调用XmbDrawString
之后,我会减去终止字符的长度,如下所示:
tx += TEXTW(text[k]) - TEXTW("\x0");