版上似乎很少有人玩dzen2?

各种窗口管理器和美化相关
回复
头像
stesen
帖子: 397
注册时间: 2008-11-16 11:11

版上似乎很少有人玩dzen2?

#1

帖子 stesen » 2011-04-21 20:28

老外都很喜欢这玩意, 国内玩的似乎不多
配置也不烦, 还可以实现颜色、按键等等功能, 非常实惠
和conky相比,支持dwm之类的WM,支持按键

我用的是最新的版本,编译参考:
http://aur.archlinux.org/packages.php?ID=31899
http://crunchbanglinux.org/forums/topic ... -from-svn/

配置可以参考:
http://dzen.geekmode.org/dwiki/doku.php ... :mainindex

我的配置:
2011-04-21--1303389129_1280x800_scrot.png
2011-04-21--1303389129_1280x800_scrot.png (6.04 KiB) 查看 2433 次

代码: 全选

stesen@debian:~$ cat ~/tools/scripts/dzen2_info.sh 
#!/bin/sh
while true; do dzen2_info 2> /tmp/dzen.log ; done | dzen2 -p -x 500 -w 780 -h 15 -sa 1 -ta r -fn "DejaVu Sans YuanTi Condensed-7"
这里用while true死循环的原因是我写的dzen2_info程序偶尔在解析mpd信息时会segmentation fault,错误很难重现, 所以暂时先这样了
dzen2_info是一个c的程序, 最后输出部分的代码风格比较差,用perl或shell写会比较清晰

代码: 全选

stesen@debian:/work/builds/dzen2_info$ cat dzen_info.c 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>

#include <sys/types.h>
#include <sys/wait.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

#include "config.h"

#define DEBUG printf("%s():\t%d\n", __FUNCTION__, __LINE__)

#define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9))))
#define SCAN(match, name) \
    p = grab_number(linebuf, match, sizeof(match)-1); \
    if (p) { name = p; continue; }

#define LONG_BUFF_SIZE  32
#define SHORT_BUFF_SIZE 8
#define STATUS_DELAY 5
#define MPD_IP "127.0.0.1"
#define MPD_PORT 6600

int g_cpu_used;
int cpu_num;
struct sockaddr_in servaddr;

char mpd_buff[LONG_BUFF_SIZE << 1] = "";
char ldavg_buff[LONG_BUFF_SIZE] = "";
char net_buff1[LONG_BUFF_SIZE / 2] = "";
char net_buff2[LONG_BUFF_SIZE / 2] = "";
char clk_buff[LONG_BUFF_SIZE] = "";

struct cpu_info
{
    char name;
    unsigned int user;
    unsigned int nice;
    unsigned int system;
    unsigned int idle;
};


void mpd(void)
{

    char sock_buff[1024];
    char stat_buf[8];
    char *p, *ptr, *n;
    int i, nbytes;
    int sock_fd;

    char tmpbuf[128];
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(sock_fd < 0) {
        printf("socket err");
    }

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(MPD_PORT);
    servaddr.sin_addr.s_addr = inet_addr(MPD_IP);

    if(connect(sock_fd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        strcpy(mpd_buff, "connect err");
        return;
    }
    recv(sock_fd, tmpbuf, 128, 0);

    send(sock_fd, "status\n", 7, 0);
    nbytes = recv(sock_fd, sock_buff, sizeof(sock_buff), 0);
    if(nbytes <= 0) {
        strcpy(mpd_buff, "read 0 bytes");
        return;
    }

    p = strstr(sock_buff, "state");
    if(p == NULL) {
        strcpy(mpd_buff, "read status err");
        return;
    }
    p += sizeof("state: ") - 1;
    i = 0;
    while(*p && (*p != '\n')) {
        stat_buf[i] = *p;
        p++;
        i++;
    }
    stat_buf[i] = '\0';
    if(strcmp(stat_buf, "play") == 0) {
        send(sock_fd, "currentsong\n", 12, 0);
        recv(sock_fd, sock_buff, sizeof(sock_buff), 0);
        p = strstr(sock_buff, "file");
        if(p == NULL) {
            strcpy(mpd_buff, "read file err1");
            return;
        }
        ptr = strrchr(p, '/');
        if(ptr == NULL) {
            strcpy(mpd_buff, "read file err2");
            return;
        } else if ((ptr - p) > 127) {
            ptr = p + 127;
        }

        n = strchr(ptr, '\n');
        *n = '\0';
        p = strrchr(ptr, '.');
        if(p != NULL) {
            *p = '\0';
        }

        i = p - ptr;
        strncpy(mpd_buff, (ptr + 1), (i > (LONG_BUFF_SIZE << 1)) ? (LONG_BUFF_SIZE << 1) : i);
    } else if ((strcmp(stat_buf, "pause") == 0) || (strcmp(stat_buf, "stop") == 0)) {
        strcpy(mpd_buff, stat_buf);
    }
    close(sock_fd);
}

void cal_cpu_info(struct cpu_info *o, struct cpu_info *n)
{
    unsigned int od, nd;
    unsigned int id, sd;

    od = o->user + o->nice + o->system +o->idle;
    nd = n->user + n->nice + n->system +n->idle;
    id = n->user - o->user;
    sd = n->system - o->system;
    g_cpu_used = (((sd + id) * 100.0) / (nd - od));
}


void get_cpu_info(struct cpu_info *o)
{
    FILE *fd;
    int n;
    char buff[LONG_BUFF_SIZE * 4];

    fd = fopen("/proc/stat", "r");
    fgets (buff, sizeof(buff), fd);
    for(n=0;n<cpu_num;n++)
    {
        fgets (buff, sizeof(buff),fd);
        sscanf (buff, "%s %u %u %u %u", &o[n].name, &o[n].user, &o[n].nice,&o[n].system, &o[n].idle);
    }
    fclose(fd);
}

char inline *xstrdup(const char *s)
{
    char *t;

    if (s == NULL)
        return NULL;

    t = strdup(s);

    if (t == NULL)
        return NULL;

    return t;
}


char inline *skip_whitespace(const char *s)
{
    while (isspace(*s)) ++s;

    return (char *) s;
}


char inline *skip_non_whitespace(const char *s)
{
    while (*s && !isspace(*s)) ++s;

    return (char *) s;
}


static char inline *grab_number(char *str, const char *match, unsigned sz)
{
    if (strncmp(str, match, sz) == 0) {
        str = skip_whitespace(str + sz);
        (skip_non_whitespace(str))[1] = '\0';
        return xstrdup(str);
    }
    return NULL;
}

int cpu(void)
{
    struct cpu_info ocpu[2];
    struct cpu_info ncpu[2];
    int cpu_sum;
    int i;

    cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
    get_cpu_info(ocpu);
    sleep(1);
    get_cpu_info(ncpu);

    cpu_sum = 0;
    for (i=0; i<cpu_num; i++)
    {
        cal_cpu_info(&ocpu[i], &ncpu[i]);
        cpu_sum += g_cpu_used;
    }
    cpu_sum /= cpu_num;

    return cpu_sum;
}

int men(void)
{
    FILE *fp;
    int i, used_men;
    int arr[4];
    char linebuf[LONG_BUFF_SIZE * 4];
    union {
        struct {
            char *total;
            char *mfree;
            char *buf;
            char *cache;
        } u;
        char *str[4];
    } z;
    bzero(&z, sizeof(z));

    fp = fopen("/proc/meminfo", "r");
    while (fgets(linebuf, sizeof(linebuf), fp))
    {
        char *p;

        SCAN("MemTotal:", z.u.total);
        SCAN("MemFree:", z.u.mfree);
        SCAN("Buffers:", z.u.buf);
        SCAN("Cached:", z.u.cache);
    }
    fclose(fp);

    for (i = 0; i < 4; i++)
    {
        arr[i] = atoi(z.str[i]);
    }

    used_men = (arr[0] >> 10) - (arr[1] >> 10) - (arr[2] >> 10) - (arr[3] >> 10);

    for (i = 0; i < 4; i++)
        free(z.str[i]);

    return used_men;
}

void loadavg(void)
{
    FILE *fp;
    int i, n;

    n = 0;
    fp = fopen("/proc/loadavg", "r");
    fgets(ldavg_buff, sizeof(ldavg_buff), fp);
    for(i = 0; i < 64; i++) {
        if(isspace(ldavg_buff[i]))
            n++;
        if(n == 3) {
            ldavg_buff[i] = '\0';
            break;
        }
        if(ldavg_buff[i] == '\n')
            ldavg_buff[i] = '\0';
    }
    fclose(fp);
}

int temp(void)
{
    FILE *fp;
    int n;
    char tmp_buff[SHORT_BUFF_SIZE];

    fp = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
    fgets(tmp_buff, sizeof(tmp_buff), fp);
    n = atoi(tmp_buff);

    fclose(fp);
    return (n / 1000);
}

void net(void)
{
    FILE *fp;
    int i;
    char *p;
    char buf[256];
    unsigned int recved1[2], sent1[2];
    unsigned int recved2[2], sent2[2];

    fp = fopen("/proc/net/dev" ,"r");
    fgets(buf, sizeof(buf), fp);
    fgets(buf, sizeof(buf), fp);

    while(fgets(buf , sizeof(buf) , fp)) {
        p = buf;
        p = skip_whitespace(p);
        if((strncmp(p, "eth", 3)) == 0) {
            p = skip_non_whitespace(p);
            p = skip_whitespace(p);

            sscanf(p, "%u", &recved1[0]);

            for(i = 0; i < 8; i++) {
                p = skip_whitespace(p);
                p = skip_non_whitespace(p);
            }
            p = skip_whitespace(p);

            sscanf(p, "%u", &sent1[0]);
        } else if ((strncmp(p, "wlan", 4)) == 0) {
            p = skip_non_whitespace(p);
            p = skip_whitespace(p);

            sscanf(p, "%u", &recved1[1]);

            for(i = 0; i < 8; i++) {
                p = skip_whitespace(p);
                p = skip_non_whitespace(p);
            }
            p = skip_whitespace(p);

            sscanf(p, "%u", &sent1[1]);
        }
    }
    sleep(1);
    fseek(fp, 0, SEEK_SET);
    fgets(buf, sizeof(buf), fp);
    fgets(buf, sizeof(buf), fp);

    while(fgets(buf , sizeof(buf) , fp)) {
        p = buf;
        p = skip_whitespace(p);
        if((strncmp(p, "eth", 3)) == 0) {
            p = skip_non_whitespace(p);
            p = skip_whitespace(p);

            sscanf(p, "%u", &recved2[0]);

            for(i = 0; i < 8; i++) {
                p = skip_whitespace(p);
                p = skip_non_whitespace(p);
            }
            p = skip_whitespace(p);

            sscanf(p, "%u", &sent2[0]);
        } else if ((strncmp(p, "wlan", 4)) == 0) {
            p = skip_non_whitespace(p);
            p = skip_whitespace(p);

            sscanf(p, "%u", &recved2[1]);

            for(i = 0; i < 8; i++) {
                p = skip_whitespace(p);
                p = skip_non_whitespace(p);
            }
            p = skip_whitespace(p);
            sscanf(p, "%u", &sent2[1]);
        }
    }

    fclose(fp);
    sprintf(net_buff1, "%u/%uK",
            ((recved2[0] - recved1[0]) >> 10),
            ((sent2[0] - sent1[0]) >> 10));
    sprintf(net_buff2, "%u/%uK",
            ((recved2[1] - recved1[1]) >> 10),
            ((sent2[1] - sent1[1])) >> 10);
}

void clk(void)
{
    time_t curtime;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    curtime = tv.tv_sec;
    strftime(clk_buff, LONG_BUFF_SIZE, "%a %Y-%m-%d %I:%M %P", localtime(&curtime));
}

int batt(void)
{
    FILE *fpi, *fps;
    char tmp_buf1[LONG_BUFF_SIZE * 2];
    char tmp_buf2[LONG_BUFF_SIZE * 2];
    int rem, total;

    fps = fopen("/proc/acpi/battery/BAT0/state", "r");
    if(fps == NULL) {
        fclose(fps);
        return 0;
    }
    fgets(tmp_buf1, sizeof(tmp_buf1), fps);
    fgets(tmp_buf1, sizeof(tmp_buf1), fps);
    fgets(tmp_buf1, sizeof(tmp_buf1), fps);

    if(strcmp(tmp_buf1, "charging state:          charged\n") == 0){
        fclose(fps);
        return 0;
    }

    fpi = fopen("/proc/acpi/battery/BAT0/info", "r");
    if(fpi == NULL) {
        fclose(fps);
        fclose(fpi);
        return 0;
    }

    fgets(tmp_buf1, sizeof(tmp_buf1), fps);
    fgets(tmp_buf1, sizeof(tmp_buf1), fps);

    fgets(tmp_buf2, sizeof(tmp_buf2), fpi);
    fgets(tmp_buf2, sizeof(tmp_buf2), fpi);
    fgets(tmp_buf2, sizeof(tmp_buf2), fpi);


    sscanf(tmp_buf1, "remaining capacity:      %d mAh", &rem);
    sscanf(tmp_buf2, "last full capacity:      %d mAh", &total);

    fclose(fps);
    fclose(fpi);
    return ((rem * 100) / total);
}

/*
*  red "#ff0000"
*  yel "#C4A1E6"
*  blu "#477AB3"
*  grn "#00afff"
*  cyn "#6096BF"
*  mag "#7E62B3"
*  gry "#666666"
*  wht "#C0C0C0"
*/

int main(void)
{
    while(1) {
        mpd();
        loadavg();
        net();
        clk();
        int bat = batt();

        if (bat == 0) {
            printf("^fg(#00afff)^ca(1,gmpc)^i(/home/stesen/.dzen2/xpm/xbm8x8/mpd.xbm) ^ca()^fg(#5f87af)%s ^fg(#90960F)^ca(1,mpc play)^i(/home/stesen/.dzen2/xpm/xbm8x8/play.xbm) ^ca()^ca(1,mpc pause)^i(/home/stesen/.dzen2/xpm/xbm8x8/pause.xbm) ^ca()^ca(1,mpc prev)^i(/home/stesen/.dzen2/xpm/xbm8x8/prev.xbm) ^ca()^ca(1,mpc next)^i(/home/stesen/.dzen2/xpm/xbm8x8/next.xbm) ^ca()^fg()| ^fg(#00afff)^ca(1,xterm -e htop)^i(/home/stesen/.dzen2/xpm/xbm8x8/cpu.xbm) ^fg(#C0C0C0)%d%%  %s^fg() | ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/mem.xbm) ^fg(#C0C0C0)%dM ^fg()| ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/temp.xbm) ^fg(#C0C0C0)%d°C ^fg()^ca()| ^fg(#00afff)^ca(1,xterm -e ceni)^i(/home/stesen/.dzen2/xpm/xbm8x8/net_wired.xbm) ^fg(#C0C0C0)%s ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/wifi_01.xbm) ^fg(#C0C0C0)%s ^ca()^fg()| ^fg(#00afff)^ca(1,gvim)^i(/home/stesen/.dzen2/xpm/xbm8x8/clock.xbm)^fg(#C4F1A6) %s^ca()  \n", mpd_buff, cpu(), ldavg_buff, men(), temp(), net_buff1, net_buff2, clk_buff);
            fflush(stdout);
        } else {
            printf("^fg(#00afff)^ca(1,gmpc)^i(/home/stesen/.dzen2/xpm/xbm8x8/mpd.xbm) ^ca()^fg(#5f87af)%s ^fg(#90960F)^ca(1,mpc play)^i(/home/stesen/.dzen2/xpm/xbm8x8/play.xbm) ^ca()^ca(1,mpc pause)^i(/home/stesen/.dzen2/xpm/xbm8x8/pause.xbm) ^ca()^ca(1,mpc prev)^i(/home/stesen/.dzen2/xpm/xbm8x8/prev.xbm) ^ca()^ca(1,mpc next)^i(/home/stesen/.dzen2/xpm/xbm8x8/next.xbm) ^ca()^fg()| ^fg(#00afff)^ca(1,xterm -e htop)^i(/home/stesen/.dzen2/xpm/xbm8x8/cpu.xbm) ^fg(#C0C0C0)%d%% ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/load.xbm)^fg(#C0C0C0) %s^fg() | ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/mem.xbm) ^fg(#C0C0C0)%dM ^fg()| ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/temp.xbm) ^fg(#C0C0C0)%d°C ^fg()^ca() | ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/power-bat.xbm) ^fg(#ff0000)%d%% ^fg() | ^fg(#00afff)^ca(1,xterm -e ceni)^i(/home/stesen/.dzen2/xpm/xbm8x8/net_wired.xbm) ^fg(#C0C0C0)%s ^fg(#00afff)^i(/home/stesen/.dzen2/xpm/xbm8x8/wifi_01.xbm) ^fg(#C0C0C0)%s ^ca()^fg()| ^fg(#00afff)^ca(1,gvim)^i(/home/stesen/.dzen2/xpm/xbm8x8/clock.xbm)^fg(#C4F1A6) %s^ca()  \n", mpd_buff, cpu(), ldavg_buff, men(), temp(), bat, net_buff1, net_buff2, clk_buff);
            fflush(stdout);
        }
        sleep(STATUS_DELAY);
    }
    return 0;
}
等俺有钱了,俺把M$买来好好搓搓
aBiNg
帖子: 1331
注册时间: 2006-07-09 12:22
来自: 南京

Re: 版上似乎很少有人玩dzen2?

#2

帖子 aBiNg » 2011-04-23 16:14

是个 eye-candy 么?很酷的样子。好久没玩这些了,呵。那信息输出,居然用 c 写,真有闲心啊。:D
usbtopc
帖子: 96
注册时间: 2009-06-30 23:05

Re: 版上似乎很少有人玩dzen2?

#3

帖子 usbtopc » 2011-04-28 13:17

潮人都用dzen2,很时尚!

不过我目前还暂时找不到使用dzen2的理由,主要是懒得配置它。 :em04
裸跑X可能是最后的选择......
目前使用dwm-plus: http://code.google.com/p/dwm-plus/
头像
stesen
帖子: 397
注册时间: 2008-11-16 11:11

Re: 版上似乎很少有人玩dzen2?

#4

帖子 stesen » 2011-04-29 11:49

usbtopc 写了:潮人都用dzen2,很时尚!

不过我目前还暂时找不到使用dzen2的理由,主要是懒得配置它。 :em04
ls不是用dwm的么?
我也是从dwm开始喜欢上方的statusbar的
等俺有钱了,俺把M$买来好好搓搓
usbtopc
帖子: 96
注册时间: 2009-06-30 23:05

Re: 版上似乎很少有人玩dzen2?

#5

帖子 usbtopc » 2011-04-29 12:57

是的,但我更习惯于用conky来实现状态信息显示。
裸跑X可能是最后的选择......
目前使用dwm-plus: http://code.google.com/p/dwm-plus/
usbtopc
帖子: 96
注册时间: 2009-06-30 23:05

Re: 版上似乎很少有人玩dzen2?

#6

帖子 usbtopc » 2011-04-29 13:06

conky不用考虑具体的实现,用其接口就可以了,而且资源相对丰富。

dzen2说实话我一直没有勇气搞它,有些复杂,呵呵。 :em03
裸跑X可能是最后的选择......
目前使用dwm-plus: http://code.google.com/p/dwm-plus/
头像
stesen
帖子: 397
注册时间: 2008-11-16 11:11

Re: 版上似乎很少有人玩dzen2?

#7

帖子 stesen » 2011-04-29 19:35

usbtopc 写了:conky不用考虑具体的实现,用其接口就可以了,而且资源相对丰富。

dzen2说实话我一直没有勇气搞它,有些复杂,呵呵。 :em03
dzen2相对于conky的优势就是可以点击,代码也比较简洁,所有信息是stdin提供的,conky是内建的
conky是提供状态显示,dzen2只是提供一个界面,可以用来作mpd客户端,邮件客户端等等,简而言之就是一个类似zenity的东西

当然conky比较方便配置,dzen2的配置比较艰涩
等俺有钱了,俺把M$买来好好搓搓
回复