diff options
-rw-r--r-- | action.c | 472 | ||||
-rw-r--r-- | action.h | 45 | ||||
-rw-r--r-- | draw.c | 272 | ||||
-rw-r--r-- | dzen.h | 118 | ||||
-rw-r--r-- | main.c | 1010 | ||||
-rw-r--r-- | util.c | 62 |
6 files changed, 989 insertions, 990 deletions
@@ -1,7 +1,7 @@ /* - * (C)opyright MMVII Robert Manea <rob dot manea at gmail dot com> - * See LICENSE file for license details. - */ +* (C)opyright MMVII Robert Manea <rob dot manea at gmail dot com> +* See LICENSE file for license details. +*/ #include "dzen.h" #include "action.h" @@ -11,45 +11,45 @@ struct event_lookup ev_lookup_table[] = { - { "exposet", exposetitle}, - { "exposes", exposeslave}, - { "onstart", onstart}, - { "onexit", onexit}, - { "button1", button1}, - { "button2", button2}, - { "button3", button3}, - { "button4", button4}, - { "button5", button5}, - { "entertitle", entertitle}, - { "leavetitle", leavetitle}, - { "enterslave", enterslave}, - { "leaveslave", leaveslave}, - { "sigusr1", sigusr1}, - { "sigusr2", sigusr2}, - { 0, 0 } + { "exposet", exposetitle}, + { "exposes", exposeslave}, + { "onstart", onstart}, + { "onexit", onexit}, + { "button1", button1}, + { "button2", button2}, + { "button3", button3}, + { "button4", button4}, + { "button5", button5}, + { "entertitle", entertitle}, + { "leavetitle", leavetitle}, + { "enterslave", enterslave}, + { "leaveslave", leaveslave}, + { "sigusr1", sigusr1}, + { "sigusr2", sigusr2}, + { 0, 0 } }; struct action_lookup ac_lookup_table[] = { - { "exposetitle", a_exposetitle}, - { "exposeslave", a_exposeslave}, - { "print", a_print }, - { "exec", a_exec}, - { "exit", a_exit}, - { "collapse", a_collapse}, - { "uncollapse", a_uncollapse}, - { "stick", a_stick}, - { "unstick", a_unstick}, - { "togglestick", a_togglestick}, - { "hide", a_hide}, - { "unhide", a_unhide}, - { "scrollup", a_scrollup}, - { "scrolldown", a_scrolldown}, - { "menuprint", a_menuprint}, - { "menuexec", a_menuexec}, - { "raise", a_raise}, - { "lower", a_lower}, - { "scrollhome", a_scrollhome}, - { 0, 0 } + { "exposetitle", a_exposetitle}, + { "exposeslave", a_exposeslave}, + { "print", a_print }, + { "exec", a_exec}, + { "exit", a_exit}, + { "collapse", a_collapse}, + { "uncollapse", a_uncollapse}, + { "stick", a_stick}, + { "unstick", a_unstick}, + { "togglestick", a_togglestick}, + { "hide", a_hide}, + { "unhide", a_unhide}, + { "scrollup", a_scrollup}, + { "scrolldown", a_scrolldown}, + { "menuprint", a_menuprint}, + { "menuexec", a_menuexec}, + { "raise", a_raise}, + { "lower", a_lower}, + { "scrollhome", a_scrollhome}, + { 0, 0 } }; Ev ev_table[MAXEVENTS] = {{0}, {0}}; @@ -57,103 +57,103 @@ Ev ev_table[MAXEVENTS] = {{0}, {0}}; /* utilities */ void do_action(int event) { - int i; + int i; - if(ev_table[event].isset) - for(i=0; ev_table[event].action[i]->handler; i++) - ev_table[event].action[i]->handler(ev_table[event].action[i]->options); + if(ev_table[event].isset) + for(i=0; ev_table[event].action[i]->handler; i++) + ev_table[event].action[i]->handler(ev_table[event].action[i]->options); } int get_ev_id(char *evname) { - int i; + int i; - for(i=0; ev_lookup_table[i].name; i++) { - if(strcmp(ev_lookup_table[i].name, evname) == 0) - return ev_lookup_table[i].id; - } - return -1; + for(i=0; ev_lookup_table[i].name; i++) { + if(strcmp(ev_lookup_table[i].name, evname) == 0) + return ev_lookup_table[i].id; + } + return -1; } void * get_action_handler(char *acname) { - int i; + int i; - for(i=0; ac_lookup_table[i].name; i++) { - if(strcmp(ac_lookup_table[i].name, acname) == 0) - return ac_lookup_table[i].handler; - } - return (void *)NULL; + for(i=0; ac_lookup_table[i].name; i++) { + if(strcmp(ac_lookup_table[i].name, acname) == 0) + return ac_lookup_table[i].handler; + } + return (void *)NULL; } void free_ev_table(void) { - int i, j; + int i, j; - for(i=0; i<MAXEVENTS; i++) { - if(ev_table[i].isset) - for(j=0; ev_table[i].action[j]->handler; j++) - free(ev_table[i].action[j]); - } + for(i=0; i<MAXEVENTS; i++) { + if(ev_table[i].isset) + for(j=0; ev_table[i].action[j]->handler; j++) + free(ev_table[i].action[j]); + } } -void + void fill_ev_table(char *input) { - char *str1, *str2, *str3, *str4, - *token, *subtoken, *kommatoken, *dptoken; - char *saveptr1, *saveptr2, *saveptr3, *saveptr4; - int j, i=0, k=0; - int eid=0; - void *ah=0; - - - for (j = 1, str1 = input; ; j++, str1 = NULL) { - token = strtok_r(str1, ";", &saveptr1); - if (token == NULL) - break; - - for (str2 = token; ; str2 = NULL) { - subtoken = strtok_r(str2, "=", &saveptr2); - if (subtoken == NULL) - break; - if( (str2 == token) && ((eid = get_ev_id(subtoken)) != -1)) - ; - else if(eid == -1) - break; - - for (str3 = subtoken; ; str3 = NULL) { - kommatoken = strtok_r(str3, ",", &saveptr3); - if (kommatoken == NULL) - break; - - for (str4 = kommatoken; ; str4 = NULL) { - dptoken = strtok_r(str4, ":", &saveptr4); - if (dptoken == NULL) { - break; - } - if(str4 == kommatoken && str4 != token && eid != -1) { - ev_table[eid].isset = 1; - if((ah = (void *)get_action_handler(dptoken))) { - ev_table[eid].action[i] = emalloc(sizeof(As)); - ev_table[eid].action[i]->handler= get_action_handler(dptoken); - } - i++; - } - else if(str4 != token && eid != -1 && ah) { - ev_table[eid].action[i-1]->options[k] = strdup(dptoken); - k++; - } - else if(!ah) - break; - } - k=0; - } - ev_table[eid].action[i] = emalloc(sizeof(As)); - ev_table[eid].action[i]->handler = NULL; - i=0; - } - } + char *str1, *str2, *str3, *str4, + *token, *subtoken, *kommatoken, *dptoken; + char *saveptr1, *saveptr2, *saveptr3, *saveptr4; + int j, i=0, k=0; + int eid=0; + void *ah=0; + + + for (j = 1, str1 = input; ; j++, str1 = NULL) { + token = strtok_r(str1, ";", &saveptr1); + if (token == NULL) + break; + + for (str2 = token; ; str2 = NULL) { + subtoken = strtok_r(str2, "=", &saveptr2); + if (subtoken == NULL) + break; + if( (str2 == token) && ((eid = get_ev_id(subtoken)) != -1)) + ; + else if(eid == -1) + break; + + for (str3 = subtoken; ; str3 = NULL) { + kommatoken = strtok_r(str3, ",", &saveptr3); + if (kommatoken == NULL) + break; + + for (str4 = kommatoken; ; str4 = NULL) { + dptoken = strtok_r(str4, ":", &saveptr4); + if (dptoken == NULL) { + break; + } + if(str4 == kommatoken && str4 != token && eid != -1) { + ev_table[eid].isset = 1; + if((ah = (void *)get_action_handler(dptoken))) { + ev_table[eid].action[i] = emalloc(sizeof(As)); + ev_table[eid].action[i]->handler= get_action_handler(dptoken); + } + i++; + } + else if(str4 != token && eid != -1 && ah) { + ev_table[eid].action[i-1]->options[k] = strdup(dptoken); + k++; + } + else if(!ah) + break; + } + k=0; + } + ev_table[eid].action[i] = emalloc(sizeof(As)); + ev_table[eid].action[i]->handler = NULL; + i=0; + } + } } @@ -162,203 +162,203 @@ fill_ev_table(char *input) /* used internally */ int a_exposetitle(char * opt[]) { - XCopyArea(dzen.dpy, dzen.title_win.drawable, dzen.title_win.win, - dzen.gc, 0, 0, dzen.title_win.width, dzen.line_height, 0, 0); - return 0; + XCopyArea(dzen.dpy, dzen.title_win.drawable, dzen.title_win.win, + dzen.gc, 0, 0, dzen.title_win.width, dzen.line_height, 0, 0); + return 0; } /* used internally */ int a_exposeslave(char * opt[]) { - x_draw_body(); - return 0; + x_draw_body(); + return 0; } /* user selectable actions */ int -a_exit(char * opt[]) { - if(opt[0]) - dzen.ret_val = atoi(opt[0]); - dzen.running = False; - return 0; -} + a_exit(char * opt[]) { + if(opt[0]) + dzen.ret_val = atoi(opt[0]); + dzen.running = False; + return 0; + } int a_collapse(char * opt[]){ - int i; - if(dzen.slave_win.max_lines && !dzen.slave_win.issticky) { - for(i=0; i < dzen.slave_win.max_lines; i++) - XUnmapWindow(dzen.dpy, dzen.slave_win.line[i]); - XUnmapWindow(dzen.dpy, dzen.slave_win.win); - } - return 0; + int i; + if(dzen.slave_win.max_lines && !dzen.slave_win.issticky) { + for(i=0; i < dzen.slave_win.max_lines; i++) + XUnmapWindow(dzen.dpy, dzen.slave_win.line[i]); + XUnmapWindow(dzen.dpy, dzen.slave_win.win); + } + return 0; } int a_uncollapse(char * opt[]){ - int i; - if(dzen.slave_win.max_lines && !dzen.slave_win.issticky) { - XMapRaised(dzen.dpy, dzen.slave_win.win); - for(i=0; i < dzen.slave_win.max_lines; i++) - XMapRaised(dzen.dpy, dzen.slave_win.line[i]); - } - return 0; + int i; + if(dzen.slave_win.max_lines && !dzen.slave_win.issticky) { + XMapRaised(dzen.dpy, dzen.slave_win.win); + for(i=0; i < dzen.slave_win.max_lines; i++) + XMapRaised(dzen.dpy, dzen.slave_win.line[i]); + } + return 0; } int a_togglecollapse(char * opt[]){ - return 0; + return 0; } int -a_stick(char * opt[]) { - if(dzen.slave_win.max_lines) - dzen.slave_win.issticky = True; - return 0; -} + a_stick(char * opt[]) { + if(dzen.slave_win.max_lines) + dzen.slave_win.issticky = True; + return 0; + } int -a_unstick(char * opt[]) { - if(dzen.slave_win.max_lines) - dzen.slave_win.issticky = False; - return 0; -} + a_unstick(char * opt[]) { + if(dzen.slave_win.max_lines) + dzen.slave_win.issticky = False; + return 0; + } int -a_togglestick(char * opt[]) { - if(dzen.slave_win.max_lines) - dzen.slave_win.issticky = dzen.slave_win.issticky ? False : True; - return 0; -} + a_togglestick(char * opt[]) { + if(dzen.slave_win.max_lines) + dzen.slave_win.issticky = dzen.slave_win.issticky ? False : True; + return 0; + } static int -scroll(int n) { - if(dzen.slave_win.last_line_vis < dzen.slave_win.max_lines) - return; - if(dzen.slave_win.first_line_vis + n < 0) { - dzen.slave_win.first_line_vis = 0; - dzen.slave_win.last_line_vis = dzen.slave_win.max_lines; - } - else if(dzen.slave_win.last_line_vis + n > dzen.slave_win.tcnt) { - dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines; - dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; - } else { - dzen.slave_win.first_line_vis += n; - dzen.slave_win.last_line_vis += n; - } - - x_draw_body(); -} + scroll(int n) { + if(dzen.slave_win.last_line_vis < dzen.slave_win.max_lines) + return; + if(dzen.slave_win.first_line_vis + n < 0) { + dzen.slave_win.first_line_vis = 0; + dzen.slave_win.last_line_vis = dzen.slave_win.max_lines; + } + else if(dzen.slave_win.last_line_vis + n > dzen.slave_win.tcnt) { + dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines; + dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; + } else { + dzen.slave_win.first_line_vis += n; + dzen.slave_win.last_line_vis += n; + } + + x_draw_body(); + } int a_scrollup(char * opt[]) { - int n=1; + int n=1; - if(opt[0]) - n = atoi(opt[0]); - if(dzen.slave_win.max_lines) - scroll(-1*n); + if(opt[0]) + n = atoi(opt[0]); + if(dzen.slave_win.max_lines) + scroll(-1*n); - return 0; + return 0; } int a_scrolldown(char * opt[]) { - int n=1; - - if(opt[0]) - n = atoi(opt[0]); - if(dzen.slave_win.max_lines) - scroll(n); - - return 0; + int n=1; + + if(opt[0]) + n = atoi(opt[0]); + if(dzen.slave_win.max_lines) + scroll(n); + + return 0; } int a_hide(char * opt[]) { - if(!dzen.title_win.ishidden) { - XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, 1); - dzen.title_win.ishidden = True; - } - return 0; + if(!dzen.title_win.ishidden) { + XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, 1); + dzen.title_win.ishidden = True; + } + return 0; } int a_unhide(char * opt[]) { - if(dzen.title_win.ishidden) { - XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, dzen.line_height); - dzen.title_win.ishidden = False; - } - return 0; + if(dzen.title_win.ishidden) { + XResizeWindow(dzen.dpy, dzen.title_win.win, dzen.title_win.width, dzen.line_height); + dzen.title_win.ishidden = False; + } + return 0; } int a_exec(char * opt[]) { - int i; + int i; - if(opt) - for(i=0; opt[i]; i++) - if(opt[i]) - spawn(opt[i]); - return 0; + if(opt) + for(i=0; opt[i]; i++) + if(opt[i]) + spawn(opt[i]); + return 0; } int a_print(char * opt[]) { - int i; + int i; - if(opt) - for(i=0; opt[i]; i++) - puts(opt[i]); - return 0; + if(opt) + for(i=0; opt[i]; i++) + puts(opt[i]); + return 0; } int a_menuprint(char * opt[]) { - if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 - && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { - puts(dzen.slave_win.tbuf[dzen.slave_win.sel_line + dzen.slave_win.first_line_vis]); - dzen.slave_win.sel_line = -1; - fflush(stdout); - } - return 0; + if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 + && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { + puts(dzen.slave_win.tbuf[dzen.slave_win.sel_line + dzen.slave_win.first_line_vis]); + dzen.slave_win.sel_line = -1; + fflush(stdout); + } + return 0; } int a_menuexec(char * opt[]) { - if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 - && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { - spawn(dzen.slave_win.tbuf[dzen.slave_win.sel_line + dzen.slave_win.first_line_vis]); - dzen.slave_win.sel_line = -1; - } - return 0; + if(dzen.slave_win.ismenu && dzen.slave_win.sel_line != -1 + && (dzen.slave_win.sel_line + dzen.slave_win.first_line_vis) < dzen.slave_win.tcnt) { + spawn(dzen.slave_win.tbuf[dzen.slave_win.sel_line + dzen.slave_win.first_line_vis]); + dzen.slave_win.sel_line = -1; + } + return 0; } int a_raise(char * opt[]) { - XRaiseWindow(dzen.dpy, dzen.title_win.win); + XRaiseWindow(dzen.dpy, dzen.title_win.win); - if(dzen.slave_win.max_lines) - XRaiseWindow(dzen.dpy, dzen.slave_win.win); - return 0; + if(dzen.slave_win.max_lines) + XRaiseWindow(dzen.dpy, dzen.slave_win.win); + return 0; } int a_lower(char * opt[]) { - XLowerWindow(dzen.dpy, dzen.title_win.win); + XLowerWindow(dzen.dpy, dzen.title_win.win); - if(dzen.slave_win.max_lines) - XLowerWindow(dzen.dpy, dzen.slave_win.win); - return 0; + if(dzen.slave_win.max_lines) + XLowerWindow(dzen.dpy, dzen.slave_win.win); + return 0; } int a_scrollhome(char * opt[]) { - if(dzen.slave_win.max_lines) { - dzen.slave_win.first_line_vis = 0; - dzen.slave_win.last_line_vis = dzen.slave_win.max_lines; - x_draw_body(); - } - return 0; + if(dzen.slave_win.max_lines) { + dzen.slave_win.first_line_vis = 0; + dzen.slave_win.last_line_vis = dzen.slave_win.max_lines; + x_draw_body(); + } + return 0; } @@ -1,8 +1,8 @@ /* - * (C)opyright MMVII Robert Manea <rob dot manea at gmail dot com> - * See LICENSE file for license details. - * - */ +* (C)opyright MMVII Robert Manea <rob dot manea at gmail dot com> +* See LICENSE file for license details. +* +*/ #define MAXEVENTS 32 #define MAXACTIONS 256 @@ -13,36 +13,36 @@ typedef struct AS As; typedef struct EV Ev; enum ev_id { - /* internal events, should not be used by the user */ - exposetitle, exposeslave, - /* startup, exit */ - onstart, onexit, - /* mouse buttons */ - button1, button2, button3, button4, button5, - /* entering/leaving windows */ - entertitle, leavetitle, enterslave, leaveslave, - /* external signals */ - sigusr1, sigusr2 + /* internal events, should not be used by the user */ + exposetitle, exposeslave, + /* startup, exit */ + onstart, onexit, + /* mouse buttons */ + button1, button2, button3, button4, button5, + /* entering/leaving windows */ + entertitle, leavetitle, enterslave, leaveslave, + /* external signals */ + sigusr1, sigusr2 }; struct event_lookup { - char *name; - int id; + char *name; + int id; }; struct action_lookup { - char *name; - int (*handler)(char **); + char *name; + int (*handler)(char **); }; struct AS { - char *options[MAXOPTIONS]; - int (*handler)(char **); + char *options[MAXOPTIONS]; + int (*handler)(char **); }; struct EV { - int isset; - As *action[MAXACTIONS]; + int isset; + As *action[MAXACTIONS]; }; extern Ev ev_table[MAXEVENTS]; @@ -75,4 +75,3 @@ int a_raise(char **); int a_lower(char **); int a_scrollhome(char **); - @@ -9,165 +9,165 @@ /* static */ static unsigned int textnw(const char *text, unsigned int len) { - XRectangle r; + XRectangle r; - if(dzen.font.set) { - XmbTextExtents(dzen.font.set, text, len, NULL, &r); - return r.width; - } - return XTextWidth(dzen.font.xfont, text, len); + if(dzen.font.set) { + XmbTextExtents(dzen.font.set, text, len, NULL, &r); + return r.width; + } + return XTextWidth(dzen.font.xfont, text, len); } void drawtext(const char *text, int reverse, int line, int align) { - int x, y, w, h; - static char buf[1024]; - unsigned int len, olen; - XGCValues gcv; - GC mgc; - XRectangle r = { dzen.x, dzen.y, dzen.w, dzen.h}; - - - mgc = reverse ? dzen.gc : dzen.rgc; - if(line == -1) /* title window */ - XFillRectangles(dzen.dpy, dzen.title_win.drawable, mgc, &r, 1); - else /* slave window */ - XFillRectangles(dzen.dpy, dzen.slave_win.drawable, mgc, &r, 1); - - if(!text) - return; - - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; - h = dzen.font.ascent + dzen.font.descent; - /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dzen.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - - if(line != -1) { - if(align == ALIGNLEFT) - x = h/2; - else if(align == ALIGNCENTER) - x = (dzen.slave_win.width - textw(buf)+h)/2; - else - x = dzen.slave_win.width - textw(buf); - } else { - if(!align) - x = (dzen.w - textw(buf)+h)/2; - else if(align == ALIGNLEFT) - x = h/2; - else - x = dzen.title_win.width - textw(buf); - } - y = dzen.font.ascent + (dzen.line_height - h) / 2; - - mgc = reverse ? dzen.rgc : dzen.gc; - if(dzen.font.set) { - if(line == -1) - XmbDrawString(dzen.dpy, dzen.title_win.drawable, dzen.font.set, - mgc, x, y, buf, len); - else - XmbDrawString(dzen.dpy, dzen.slave_win.drawable, dzen.font.set, - mgc, x, y, buf, len); - } - else { - gcv.font = dzen.font.xfont->fid; - XChangeGC(dzen.dpy, mgc, GCForeground | GCFont, &gcv); - - if(line != -1) - XDrawString(dzen.dpy, dzen.slave_win.drawable, - mgc, x, y, buf, len); - else - XDrawString(dzen.dpy, dzen.title_win.drawable, - mgc, x, y, buf, len); - } + int x, y, w, h; + static char buf[1024]; + unsigned int len, olen; + XGCValues gcv; + GC mgc; + XRectangle r = { dzen.x, dzen.y, dzen.w, dzen.h}; + + + mgc = reverse ? dzen.gc : dzen.rgc; + if(line == -1) /* title window */ + XFillRectangles(dzen.dpy, dzen.title_win.drawable, mgc, &r, 1); + else /* slave window */ + XFillRectangles(dzen.dpy, dzen.slave_win.drawable, mgc, &r, 1); + + if(!text) + return; + + w = 0; + olen = len = strlen(text); + if(len >= sizeof buf) + len = sizeof buf - 1; + memcpy(buf, text, len); + buf[len] = 0; + h = dzen.font.ascent + dzen.font.descent; + /* shorten text if necessary */ + while(len && (w = textnw(buf, len)) > dzen.w - h) + buf[--len] = 0; + if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; + if(len > 3) + buf[len - 3] = '.'; + } + + if(line != -1) { + if(align == ALIGNLEFT) + x = h/2; + else if(align == ALIGNCENTER) + x = (dzen.slave_win.width - textw(buf)+h)/2; + else + x = dzen.slave_win.width - textw(buf); + } else { + if(!align) + x = (dzen.w - textw(buf)+h)/2; + else if(align == ALIGNLEFT) + x = h/2; + else + x = dzen.title_win.width - textw(buf); + } + y = dzen.font.ascent + (dzen.line_height - h) / 2; + + mgc = reverse ? dzen.rgc : dzen.gc; + if(dzen.font.set) { + if(line == -1) + XmbDrawString(dzen.dpy, dzen.title_win.drawable, dzen.font.set, + mgc, x, y, buf, len); + else + XmbDrawString(dzen.dpy, dzen.slave_win.drawable, dzen.font.set, + mgc, x, y, buf, len); + } + else { + gcv.font = dzen.font.xfont->fid; + XChangeGC(dzen.dpy, mgc, GCForeground | GCFont, &gcv); + + if(line != -1) + XDrawString(dzen.dpy, dzen.slave_win.drawable, + mgc, x, y, buf, len); + else + XDrawString(dzen.dpy, dzen.title_win.drawable, + mgc, x, y, buf, len); + } } unsigned long getcolor(const char *colstr) { - Colormap cmap = DefaultColormap(dzen.dpy, dzen.screen); - XColor color; + Colormap cmap = DefaultColormap(dzen.dpy, dzen.screen); + XColor color; - if(!XAllocNamedColor(dzen.dpy, cmap, colstr, &color, &color)) - eprint("dzen: error, cannot allocate color '%s'\n", colstr); - return color.pixel; + if(!XAllocNamedColor(dzen.dpy, cmap, colstr, &color, &color)) + eprint("dzen: error, cannot allocate color '%s'\n", colstr); + return color.pixel; } void setfont(const char *fontstr) { - char *def, **missing; - int i, n; - - missing = NULL; - if(dzen.font.set) - XFreeFontSet(dzen.dpy, dzen.font.set); - dzen.font.set = XCreateFontSet(dzen.dpy, fontstr, &missing, &n, &def); - if(missing) - XFreeStringList(missing); - if(dzen.font.set) { - XFontSetExtents *font_extents; - XFontStruct **xfonts; - char **font_names; - dzen.font.ascent = dzen.font.descent = 0; - font_extents = XExtentsOfFontSet(dzen.font.set); - n = XFontsOfFontSet(dzen.font.set, &xfonts, &font_names); - for(i = 0, dzen.font.ascent = 0, dzen.font.descent = 0; i < n; i++) { - if(dzen.font.ascent < (*xfonts)->ascent) - dzen.font.ascent = (*xfonts)->ascent; - if(dzen.font.descent < (*xfonts)->descent) - dzen.font.descent = (*xfonts)->descent; - xfonts++; - } - } - else { - if(dzen.font.xfont) - XFreeFont(dzen.dpy, dzen.font.xfont); - dzen.font.xfont = NULL; - if(!(dzen.font.xfont = XLoadQueryFont(dzen.dpy, fontstr))) - eprint("dzen: error, cannot load font: '%s'\n", fontstr); - dzen.font.ascent = dzen.font.xfont->ascent; - dzen.font.descent = dzen.font.xfont->descent; - } - dzen.font.height = dzen.font.ascent + dzen.font.descent; + char *def, **missing; + int i, n; + + missing = NULL; + if(dzen.font.set) + XFreeFontSet(dzen.dpy, dzen.font.set); + dzen.font.set = XCreateFontSet(dzen.dpy, fontstr, &missing, &n, &def); + if(missing) + XFreeStringList(missing); + if(dzen.font.set) { + XFontSetExtents *font_extents; + XFontStruct **xfonts; + char **font_names; + dzen.font.ascent = dzen.font.descent = 0; + font_extents = XExtentsOfFontSet(dzen.font.set); + n = XFontsOfFontSet(dzen.font.set, &xfonts, &font_names); + for(i = 0, dzen.font.ascent = 0, dzen.font.descent = 0; i < n; i++) { + if(dzen.font.ascent < (*xfonts)->ascent) + dzen.font.ascent = (*xfonts)->ascent; + if(dzen.font.descent < (*xfonts)->descent) + dzen.font.descent = (*xfonts)->descent; + xfonts++; + } + } + else { + if(dzen.font.xfont) + XFreeFont(dzen.dpy, dzen.font.xfont); + dzen.font.xfont = NULL; + if(!(dzen.font.xfont = XLoadQueryFont(dzen.dpy, fontstr))) + eprint("dzen: error, cannot load font: '%s'\n", fontstr); + dzen.font.ascent = dzen.font.xfont->ascent; + dzen.font.descent = dzen.font.xfont->descent; + } + dzen.font.height = dzen.font.ascent + dzen.font.descent; } unsigned int textw(const char *text) { - return textnw(text, strlen(text)) + dzen.font.height; + return textnw(text, strlen(text)) + dzen.font.height; } void drawheader(char * text) { - dzen.x = 0; - dzen.y = 0; - dzen.w = dzen.title_win.width; - dzen.h = dzen.line_height; - - if(text) - drawtext(text, 0, -1, dzen.title_win.alignment); - XCopyArea(dzen.dpy, dzen.title_win.drawable, dzen.title_win.win, - dzen.gc, 0, 0, dzen.title_win.width, dzen.line_height, 0, 0); + dzen.x = 0; + dzen.y = 0; + dzen.w = dzen.title_win.width; + dzen.h = dzen.line_height; + + if(text) + drawtext(text, 0, -1, dzen.title_win.alignment); + XCopyArea(dzen.dpy, dzen.title_win.drawable, dzen.title_win.win, + dzen.gc, 0, 0, dzen.title_win.width, dzen.line_height, 0, 0); } void -drawbody(char * text) { - if(dzen.slave_win.tcnt >= BUF_SIZE) - free_buffer(); - if(dzen.slave_win.tcnt < BUF_SIZE) { - dzen.slave_win.tbuf[dzen.slave_win.tcnt] = estrdup(text); - dzen.slave_win.tcnt++; - } -} + drawbody(char * text) { + if(dzen.slave_win.tcnt >= BUF_SIZE) + free_buffer(); + if(dzen.slave_win.tcnt < BUF_SIZE) { + dzen.slave_win.tbuf[dzen.slave_win.tcnt] = estrdup(text); + dzen.slave_win.tcnt++; + } + } @@ -28,74 +28,74 @@ typedef struct TW TWIN; typedef struct SW SWIN; struct Fnt { - XFontStruct *xfont; - XFontSet set; - int ascent; - int descent; - int height; + XFontStruct *xfont; + XFontSet set; + int ascent; + int descent; + int height; }; /* title window */ struct TW { - int x, y, width, height; + int x, y, width, height; - Window win; - Drawable drawable; - char alignment; - Bool ishidden; + Window win; + Drawable drawable; + char alignment; + Bool ishidden; }; /* slave window */ struct SW { - int x, y, width, height; - - Window win; - Window *line; - Drawable drawable; - - char *tbuf[BUF_SIZE]; - int tcnt; - int max_lines; - int first_line_vis; - int last_line_vis; - int sel_line; - - char alignment; - Bool ismenu; - Bool issticky; - Bool ismapped; + int x, y, width, height; + + Window win; + Window *line; + Drawable drawable; + + char *tbuf[BUF_SIZE]; + int tcnt; + int max_lines; + int first_line_vis; + int last_line_vis; + int sel_line; + + char alignment; + Bool ismenu; + Bool issticky; + Bool ismapped; }; struct DZEN { - int x, y, w, h; - Bool running; - unsigned long norm[ColLast]; - - TWIN title_win; - SWIN slave_win; - - char *fnt; - char *bg; - char *fg; - int line_height; - - Display *dpy; - int screen; - unsigned int depth; - - Visual *visual; - GC gc, rgc; - Fnt font; - - Bool ispersistent; - // The number of milliseconds to wait after an EOF from stdin before - // exiting. A value of 0 == forever - unsigned long timeout; - int cur_line; - int ret_val; - - /* should always be 0 if DZEN_XINERAMA not defined */ - int xinescreen; + int x, y, w, h; + Bool running; + unsigned long norm[ColLast]; + + TWIN title_win; + SWIN slave_win; + + char *fnt; + char *bg; + char *fg; + int line_height; + + Display *dpy; + int screen; + unsigned int depth; + + Visual *visual; + GC gc, rgc; + Fnt font; + + Bool ispersistent; + // The number of milliseconds to wait after an EOF from stdin before + // exiting. A value of 0 == forever + unsigned long timeout; + int cur_line; + int ret_val; + + /* should always be 0 if DZEN_XINERAMA not defined */ + int xinescreen; }; extern Dzen dzen; @@ -105,9 +105,9 @@ void x_draw_body(void); /* draw.c */ extern void drawtext(const char *text, - int reverse, - int line, - int aligne); + int reverse, + int line, + int aligne); extern unsigned long getcolor(const char *colstr); /* returns color of colstr */ extern void setfont(const char *fontstr); /* sets global font */ extern unsigned int textw(const char *text); /* returns width of text in px */ @@ -1,4 +1,4 @@ -/* +/* * (C)opyright MMVII Robert Manea <rob dot manea at gmail dot com> * See LICENSE file for license details. * @@ -26,610 +26,610 @@ typedef void sigfunc(int); static void catch_sigusr1() { - do_action(sigusr1); + do_action(sigusr1); } static void catch_sigusr2() { - do_action(sigusr2); + do_action(sigusr2); } static void catch_sigterm() { - do_action(onexit); + do_action(onexit); } static void catch_alrm() { - do_action(onexit); - /* TODO: that's quite rude, we need - a better way to do this */ - exit(0); + do_action(onexit); + /* TODO: that's quite rude, we need + a better way to do this */ + exit(0); } static sigfunc * setup_signal(int signr, sigfunc *shandler) { - struct sigaction nh, oh; + struct sigaction nh, oh; - nh.sa_handler = shandler; - sigemptyset(&nh.sa_mask); - nh.sa_flags = 0; + nh.sa_handler = shandler; + sigemptyset(&nh.sa_mask); + nh.sa_flags = 0; - if(sigaction(signr, &nh, &oh) < 0) - return SIG_ERR; + if(sigaction(signr, &nh, &oh) < 0) + return SIG_ERR; - return NULL; + return NULL; } char *rem=NULL; static int chomp(char *inbuf, char *outbuf, int start, int len) { - int i=0; - int off=start; - - if(rem) { - strncpy(outbuf, rem, strlen(rem)); - i += strlen(rem); - free(rem); - rem = NULL; - } - while(off < len) { - if(inbuf[off] != '\n') { - outbuf[i++] = inbuf[off++]; - } else if(inbuf[off] == '\n') { - outbuf[i] = '\0'; - return ++off; - } - } - - outbuf[i] = '\0'; - rem = estrdup(outbuf); - return 0; + int i=0; + int off=start; + + if(rem) { + strncpy(outbuf, rem, strlen(rem)); + i += strlen(rem); + free(rem); + rem = NULL; + } + while(off < len) { + if(inbuf[off] != '\n') { + outbuf[i++] = inbuf[off++]; + } else if(inbuf[off] == '\n') { + outbuf[i] = '\0'; + return ++off; + } + } + + outbuf[i] = '\0'; + rem = estrdup(outbuf); + return 0; } void free_buffer(void) { - int i; - for(i=0; i<BUF_SIZE; i++) - free(dzen.slave_win.tbuf[i]); - dzen.slave_win.tcnt = 0; - last_cnt = 0; + int i; + for(i=0; i<BUF_SIZE; i++) + free(dzen.slave_win.tbuf[i]); + dzen.slave_win.tcnt = 0; + last_cnt = 0; } static int read_stdin(void *ptr) { - char buf[1024], retbuf[2048]; - ssize_t n, n_off=0; - - if(!(n = read(STDIN_FILENO, buf, sizeof buf))) { - if(!dzen.ispersistent) { - dzen.running = False; - return -1; - } else - return -2; - } else { - while((n_off = chomp(buf, retbuf, n_off, n))) { - if(!dzen.cur_line || !dzen.slave_win.max_lines) { - drawheader(retbuf); - } - else - drawbody(retbuf); - dzen.cur_line++; - } - } - return 0; + char buf[1024], retbuf[2048]; + ssize_t n, n_off=0; + + if(!(n = read(STDIN_FILENO, buf, sizeof buf))) { + if(!dzen.ispersistent) { + dzen.running = False; + return -1; + } else + return -2; + } else { + while((n_off = chomp(buf, retbuf, n_off, n))) { + if(!dzen.cur_line || !dzen.slave_win.max_lines) { + drawheader(retbuf); + } + else + drawbody(retbuf); + dzen.cur_line++; + } + } + return 0; } static void x_highlight_line(int line) { - drawtext(dzen.slave_win.tbuf[line + dzen.slave_win.first_line_vis], 1, line+1, dzen.slave_win.alignment); - XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[line], dzen.rgc, - 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); + drawtext(dzen.slave_win.tbuf[line + dzen.slave_win.first_line_vis], 1, line+1, dzen.slave_win.alignment); + XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[line], dzen.rgc, + 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); } static void x_unhighlight_line(int line) { - drawtext(dzen.slave_win.tbuf[line + dzen.slave_win.first_line_vis], 0, line+1, dzen.slave_win.alignment); - XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[line], dzen.gc, - 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); + drawtext(dzen.slave_win.tbuf[line + dzen.slave_win.first_line_vis], 0, line+1, dzen.slave_win.alignment); + XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[line], dzen.gc, + 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); } void x_draw_body(void) { - dzen.x = 0; - dzen.y = 0; - dzen.w = dzen.slave_win.width; - dzen.h = dzen.line_height; - int i; - - if(!dzen.slave_win.last_line_vis) { - if(dzen.slave_win.tcnt < dzen.slave_win.max_lines) { - dzen.slave_win.first_line_vis = 0; - dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; - } - if(dzen.slave_win.tcnt >= dzen.slave_win.max_lines) { - dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines; - dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; - } - } - - for(i=0; i < dzen.slave_win.max_lines; i++) { - if(i < dzen.slave_win.last_line_vis) { - drawtext(dzen.slave_win.tbuf[i + dzen.slave_win.first_line_vis], 0, i, dzen.slave_win.alignment); - XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[i], dzen.gc, - 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); - } - else if(i < dzen.slave_win.max_lines) { - drawtext("", 0, i, dzen.slave_win.alignment); - XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[i], dzen.gc, - 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); - } - } + dzen.x = 0; + dzen.y = 0; + dzen.w = dzen.slave_win.width; + dzen.h = dzen.line_height; + int i; + + if(!dzen.slave_win.last_line_vis) { + if(dzen.slave_win.tcnt < dzen.slave_win.max_lines) { + dzen.slave_win.first_line_vis = 0; + dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; + } + if(dzen.slave_win.tcnt >= dzen.slave_win.max_lines) { + dzen.slave_win.first_line_vis = dzen.slave_win.tcnt - dzen.slave_win.max_lines; + dzen.slave_win.last_line_vis = dzen.slave_win.tcnt; + } + } + + for(i=0; i < dzen.slave_win.max_lines; i++) { + if(i < dzen.slave_win.last_line_vis) { + drawtext(dzen.slave_win.tbuf[i + dzen.slave_win.first_line_vis], 0, i, dzen.slave_win.alignment); + XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[i], dzen.gc, + 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); + } + else if(i < dzen.slave_win.max_lines) { + drawtext("", 0, i, dzen.slave_win.alignment); + XCopyArea(dzen.dpy, dzen.slave_win.drawable, dzen.slave_win.line[i], dzen.gc, + 0, 0, dzen.slave_win.width, dzen.line_height, 0, 0); + } + } } static void x_check_geometry(XRectangle si) { - dzen.title_win.x += si.x; - dzen.title_win.y += si.y; - - if(dzen.title_win.x > si.x + si.width) - dzen.title_win.x = si.x; - if (dzen.title_win.x < si.x) - dzen.title_win.x = si.x; - - if(!dzen.title_win.width) - dzen.title_win.width = si.width; - - if((dzen.title_win.x + dzen.title_win.width) > (si.x + si.width)) - dzen.title_win.width = si.width - (dzen.title_win.x - si.x); - if(!dzen.slave_win.width) { - dzen.slave_win.x = si.x; - dzen.slave_win.width = si.width; - } - if( dzen.title_win.width == dzen.slave_win.width) { - dzen.slave_win.x = dzen.title_win.x; - } - if(dzen.slave_win.width != si.width) { - dzen.slave_win.x = dzen.title_win.x + (dzen.title_win.width - dzen.slave_win.width)/2; - if(dzen.slave_win.x < si.x) - dzen.slave_win.x = si.x; - if(dzen.slave_win.x + dzen.slave_win.width > si.x + si.width) - dzen.slave_win.x = si.x + (si.width - dzen.slave_win.width); - } - dzen.line_height = dzen.font.height + 2; - - if (dzen.title_win.y + dzen.line_height > si.y + si.height) - dzen.title_win.y = 0; + dzen.title_win.x += si.x; + dzen.title_win.y += si.y; + + if(dzen.title_win.x > si.x + si.width) + dzen.title_win.x = si.x; + if (dzen.title_win.x < si.x) + dzen.title_win.x = si.x; + + if(!dzen.title_win.width) + dzen.title_win.width = si.width; + + if((dzen.title_win.x + dzen.title_win.width) > (si.x + si.width)) + dzen.title_win.width = si.width - (dzen.title_win.x - si.x); + if(!dzen.slave_win.width) { + dzen.slave_win.x = si.x; + dzen.slave_win.width = si.width; + } + if( dzen.title_win.width == dzen.slave_win.width) { + dzen.slave_win.x = dzen.title_win.x; + } + if(dzen.slave_win.width != si.width) { + dzen.slave_win.x = dzen.title_win.x + (dzen.title_win.width - dzen.slave_win.width)/2; + if(dzen.slave_win.x < si.x) + dzen.slave_win.x = si.x; + if(dzen.slave_win.x + dzen.slave_win.width > si.x + si.width) + dzen.slave_win.x = si.x + (si.width - dzen.slave_win.width); + } + dzen.line_height = dzen.font.height + 2; + + if (dzen.title_win.y + dzen.line_height > si.y + si.height) + dzen.title_win.y = 0; } static void qsi_no_xinerama(Display *dpy, XRectangle *rect) { - rect->x = 0; - rect->y = 0; - rect->width = DisplayWidth( dpy, DefaultScreen(dpy)); - rect->height = DisplayHeight(dpy, DefaultScreen(dpy)); + rect->x = 0; + rect->y = 0; + rect->width = DisplayWidth( dpy, DefaultScreen(dpy)); + rect->height = DisplayHeight(dpy, DefaultScreen(dpy)); } #ifdef DZEN_XINERAMA static void queryscreeninfo(Display *dpy, XRectangle *rect, int screen) { - XineramaScreenInfo *xsi = NULL; - int nscreens = 1; - - if(XineramaIsActive(dpy)) - xsi = XineramaQueryScreens(dpy, &nscreens); - - if(xsi == NULL || screen > nscreens || screen <= 0) { - qsi_no_xinerama(dpy, rect); - } else { - rect->x = xsi[screen-1].x_org; - rect->y = xsi[screen-1].y_org; - rect->width = xsi[screen-1].width; - rect->height = xsi[screen-1].height; - } + XineramaScreenInfo *xsi = NULL; + int nscreens = 1; + + if(XineramaIsActive(dpy)) + xsi = XineramaQueryScreens(dpy, &nscreens); + + if(xsi == NULL || screen > nscreens || screen <= 0) { + qsi_no_xinerama(dpy, rect); + } else { + rect->x = xsi[screen-1].x_org; + rect->y = xsi[screen-1].y_org; + rect->width = xsi[screen-1].width; + rect->height = xsi[screen-1].height; + } } #endif static void x_create_windows(void) { - XSetWindowAttributes wa; - Window root; - int i; - XRectangle si; + XSetWindowAttributes wa; + Window root; + int i; + XRectangle si; - dzen.dpy = XOpenDisplay(0); - if(!dzen.dpy) - eprint("dzen: cannot open display\n"); + dzen.dpy = XOpenDisplay(0); + if(!dzen.dpy) + eprint("dzen: cannot open display\n"); - dzen.screen = DefaultScreen(dzen.dpy); - root = RootWindow(dzen.dpy, dzen.screen); + dzen.screen = DefaultScreen(dzen.dpy); + root = RootWindow(dzen.dpy, dzen.screen); - /* style */ - dzen.norm[ColBG] = getcolor(dzen.bg); - dzen.norm[ColFG] = getcolor(dzen.fg); - setfont(dzen.fnt); + /* style */ + dzen.norm[ColBG] = getcolor(dzen.bg); + dzen.norm[ColFG] = getcolor(dzen.fg); + setfont(dzen.fnt); - /* window attributes */ - wa.override_redirect = 1; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask; + /* window attributes */ + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask; #ifdef DZEN_XINERAMA - queryscreeninfo(dzen.dpy, &si, dzen.xinescreen); + queryscreeninfo(dzen.dpy, &si, dzen.xinescreen); #else - qsi_no_xinerama(dzen.dpy, &si); + qsi_no_xinerama(dzen.dpy, &si); #endif - x_check_geometry(si); - - /* title window */ - dzen.title_win.win = XCreateWindow(dzen.dpy, root, - dzen.title_win.x, dzen.title_win.y, dzen.title_win.width, dzen.line_height, 0, - DefaultDepth(dzen.dpy, dzen.screen), CopyFromParent, - DefaultVisual(dzen.dpy, dzen.screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - dzen.title_win.drawable = XCreatePixmap(dzen.dpy, root, dzen.title_win.width, - dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen)); - - /* slave window */ - if(dzen.slave_win.max_lines) { - dzen.slave_win.first_line_vis = 0; - dzen.slave_win.last_line_vis = 0; - dzen.slave_win.issticky = False; - dzen.slave_win.y = dzen.title_win.y + dzen.line_height; - - if(dzen.title_win.y + dzen.line_height*dzen.slave_win.max_lines > si.y + si.height) - dzen.slave_win.y = (dzen.title_win.y - dzen.line_height) - dzen.line_height*(dzen.slave_win.max_lines) + dzen.line_height; - - dzen.slave_win.win = XCreateWindow(dzen.dpy, root, - dzen.slave_win.x, dzen.slave_win.y, dzen.slave_win.width, dzen.slave_win.max_lines * dzen.line_height, 0, - DefaultDepth(dzen.dpy, dzen.screen), CopyFromParent, - DefaultVisual(dzen.dpy, dzen.screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - - dzen.slave_win.drawable = XCreatePixmap(dzen.dpy, root, dzen.slave_win.width, - dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen)); - - /* windows holding the lines */ - dzen.slave_win.line = emalloc(sizeof(Window) * dzen.slave_win.max_lines); - for(i=0; i < dzen.slave_win.max_lines; i++) { - dzen.slave_win.line[i] = XCreateWindow(dzen.dpy, dzen.slave_win.win, - 0, i*dzen.line_height, dzen.slave_win.width, dzen.line_height, 0, - DefaultDepth(dzen.dpy, dzen.screen), CopyFromParent, - DefaultVisual(dzen.dpy, dzen.screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - } - - } - /* normal GC */ - dzen.gc = XCreateGC(dzen.dpy, root, 0, 0); - XSetForeground(dzen.dpy, dzen.gc, dzen.norm[ColFG]); - XSetBackground(dzen.dpy, dzen.gc, dzen.norm[ColBG]); - /* reverse GC */ - dzen.rgc = XCreateGC(dzen.dpy, root, 0, 0); - XSetForeground(dzen.dpy, dzen.rgc, dzen.norm[ColBG]); - XSetBackground(dzen.dpy, dzen.rgc, dzen.norm[ColFG]); + x_check_geometry(si); + + /* title window */ + dzen.title_win.win = XCreateWindow(dzen.dpy, root, + dzen.title_win.x, dzen.title_win.y, dzen.title_win.width, dzen.line_height, 0, + DefaultDepth(dzen.dpy, dzen.screen), CopyFromParent, + DefaultVisual(dzen.dpy, dzen.screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + dzen.title_win.drawable = XCreatePixmap(dzen.dpy, root, dzen.title_win.width, + dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen)); + + /* slave window */ + if(dzen.slave_win.max_lines) { + dzen.slave_win.first_line_vis = 0; + dzen.slave_win.last_line_vis = 0; + dzen.slave_win.issticky = False; + dzen.slave_win.y = dzen.title_win.y + dzen.line_height; + + if(dzen.title_win.y + dzen.line_height*dzen.slave_win.max_lines > si.y + si.height) + dzen.slave_win.y = (dzen.title_win.y - dzen.line_height) - dzen.line_height*(dzen.slave_win.max_lines) + dzen.line_height; + + dzen.slave_win.win = XCreateWindow(dzen.dpy, root, + dzen.slave_win.x, dzen.slave_win.y, dzen.slave_win.width, dzen.slave_win.max_lines * dzen.line_height, 0, + DefaultDepth(dzen.dpy, dzen.screen), CopyFromParent, + DefaultVisual(dzen.dpy, dzen.screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + + dzen.slave_win.drawable = XCreatePixmap(dzen.dpy, root, dzen.slave_win.width, + dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen)); + + /* windows holding the lines */ + dzen.slave_win.line = emalloc(sizeof(Window) * dzen.slave_win.max_lines); + for(i=0; i < dzen.slave_win.max_lines; i++) { + dzen.slave_win.line[i] = XCreateWindow(dzen.dpy, dzen.slave_win.win, + 0, i*dzen.line_height, dzen.slave_win.width, dzen.line_height, 0, + DefaultDepth(dzen.dpy, dzen.screen), CopyFromParent, + DefaultVisual(dzen.dpy, dzen.screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + } + + } + /* normal GC */ + dzen.gc = XCreateGC(dzen.dpy, root, 0, 0); + XSetForeground(dzen.dpy, dzen.gc, dzen.norm[ColFG]); + XSetBackground(dzen.dpy, dzen.gc, dzen.norm[ColBG]); + /* reverse GC */ + dzen.rgc = XCreateGC(dzen.dpy, root, 0, 0); + XSetForeground(dzen.dpy, dzen.rgc, dzen.norm[ColBG]); + XSetBackground(dzen.dpy, dzen.rgc, dzen.norm[ColFG]); } static void x_map_window(Window win) { - XMapRaised(dzen.dpy, win); - XSync(dzen.dpy, False); + XMapRaised(dzen.dpy, win); + XSync(dzen.dpy, False); } static void handle_xev(void) { - XEvent ev; - int i; - - XNextEvent(dzen.dpy, &ev); - switch(ev.type) { - case Expose: - if(ev.xexpose.count == 0) { - if(ev.xexpose.window == dzen.title_win.win) - drawheader(NULL); - if(ev.xexpose.window == dzen.slave_win.win) - do_action(exposeslave); - for(i=0; i < dzen.slave_win.max_lines; i++) - if(ev.xcrossing.window == dzen.slave_win.line[i]) - do_action(exposeslave); - } - XSync(dzen.dpy, False); - break; - case EnterNotify: - if(dzen.slave_win.ismenu) { - for(i=0; i < dzen.slave_win.max_lines; i++) - if(ev.xcrossing.window == dzen.slave_win.line[i]) - x_highlight_line(i); - } - if(ev.xcrossing.window == dzen.title_win.win) - do_action(entertitle); - if(ev.xcrossing.window == dzen.slave_win.win) - do_action(enterslave); - XSync(dzen.dpy, False); - break; - case LeaveNotify: - if(dzen.slave_win.ismenu) { - for(i=0; i < dzen.slave_win.max_lines; i++) - if(ev.xcrossing.window == dzen.slave_win.line[i]) - x_unhighlight_line(i); - } - if(ev.xcrossing.window == dzen.title_win.win) - do_action(leavetitle); - if(ev.xcrossing.window == dzen.slave_win.win) { - do_action(leaveslave); - } - XSync(dzen.dpy, False); - break; - case ButtonRelease: - if(dzen.slave_win.ismenu) { - for(i=0; i < dzen.slave_win.max_lines; i++) - if(ev.xbutton.window == dzen.slave_win.line[i]) - dzen.slave_win.sel_line = i; - } - switch(ev.xbutton.button) { - case Button1: - do_action(button1); - break; - case Button2: - do_action(button2); - break; - case Button3: - do_action(button3); - break; - case Button4: - do_action(button4); - break; - case Button5: - do_action(button5); - break; - } - XSync(dzen.dpy, False); - break; - } - XFlush(dzen.dpy); + XEvent ev; + int i; + + XNextEvent(dzen.dpy, &ev); + switch(ev.type) { + case Expose: + if(ev.xexpose.count == 0) { + if(ev.xexpose.window == dzen.title_win.win) + drawheader(NULL); + if(ev.xexpose.window == dzen.slave_win.win) + do_action(exposeslave); + for(i=0; i < dzen.slave_win.max_lines; i++) + if(ev.xcrossing.window == dzen.slave_win.line[i]) + do_action(exposeslave); + } + XSync(dzen.dpy, False); + break; + case EnterNotify: + if(dzen.slave_win.ismenu) { + for(i=0; i < dzen.slave_win.max_lines; i++) + if(ev.xcrossing.window == dzen.slave_win.line[i]) + x_highlight_line(i); + } + if(ev.xcrossing.window == dzen.title_win.win) + do_action(entertitle); + if(ev.xcrossing.window == dzen.slave_win.win) + do_action(enterslave); + XSync(dzen.dpy, False); + break; + case LeaveNotify: + if(dzen.slave_win.ismenu) { + for(i=0; i < dzen.slave_win.max_lines; i++) + if(ev.xcrossing.window == dzen.slave_win.line[i]) + x_unhighlight_line(i); + } + if(ev.xcrossing.window == dzen.title_win.win) + do_action(leavetitle); + if(ev.xcrossing.window == dzen.slave_win.win) { + do_action(leaveslave); + } + XSync(dzen.dpy, False); + break; + case ButtonRelease: + if(dzen.slave_win.ismenu) { + for(i=0; i < dzen.slave_win.max_lines; i++) + if(ev.xbutton.window == dzen.slave_win.line[i]) + dzen.slave_win.sel_line = i; + } + switch(ev.xbutton.button) { + case Button1: + do_action(button1); + break; + case Button2: + do_action(button2); + break; + case Button3: + do_action(button3); + break; + case Button4: + do_action(button4); + break; + case Button5: + do_action(button5); + break; + } + XSync(dzen.dpy, False); + break; + } + XFlush(dzen.dpy); } static void handle_newl(void) { - XWindowAttributes wa; - - if(dzen.slave_win.max_lines && (dzen.slave_win.tcnt > last_cnt)) { - if (XGetWindowAttributes(dzen.dpy, dzen.slave_win.win, &wa), - wa.map_state != IsUnmapped - /* scroll only if we're currently viewing the last line of input */ - && (dzen.slave_win.last_line_vis == last_cnt)) { - dzen.slave_win.first_line_vis = 0; - dzen.slave_win.last_line_vis = 0; - } else if(wa.map_state == IsUnmapped || !dzen.slave_win.last_line_vis) { - dzen.slave_win.first_line_vis = 0; - dzen.slave_win.last_line_vis = 0; - } - do_action(exposeslave); - last_cnt = dzen.slave_win.tcnt; - } + XWindowAttributes wa; + + if(dzen.slave_win.max_lines && (dzen.slave_win.tcnt > last_cnt)) { + if (XGetWindowAttributes(dzen.dpy, dzen.slave_win.win, &wa), + wa.map_state != IsUnmapped + /* scroll only if we're currently viewing the last line of input */ + && (dzen.slave_win.last_line_vis == last_cnt)) { + dzen.slave_win.first_line_vis = 0; + dzen.slave_win.last_line_vis = 0; + } else if(wa.map_state == IsUnmapped || !dzen.slave_win.last_line_vis) { + dzen.slave_win.first_line_vis = 0; + dzen.slave_win.last_line_vis = 0; + } + do_action(exposeslave); + last_cnt = dzen.slave_win.tcnt; + } } static int event_loop(void *ptr) { - int xfd, ret, dr=0; - fd_set rmask; - - /* fill background until data is available */ - drawheader(""); - - xfd = ConnectionNumber(dzen.dpy); - while(dzen.running) { - FD_ZERO(&rmask); - FD_SET(xfd, &rmask); - if(dr != -2) - FD_SET(STDIN_FILENO, &rmask); - - while(XPending(dzen.dpy)) - handle_xev(); - - ret = select(xfd+1, &rmask, NULL, NULL, NULL); - if(ret) { - if(dr != -2 && FD_ISSET(STDIN_FILENO, &rmask)) { - if((dr = read_stdin(NULL)) == -1) - return; - handle_newl(); - } - if(dr == -2 && dzen.timeout > 0) { - /* set an alarm to kill us after the timeout */ - struct itimerval t; - memset(&t, 0, sizeof t); - t.it_value.tv_sec = dzen.timeout; - t.it_value.tv_usec = 0; - setitimer(ITIMER_REAL, &t, NULL); - } - if(FD_ISSET(xfd, &rmask)) - handle_xev(); - } - } - return; + int xfd, ret, dr=0; + fd_set rmask; + + /* fill background until data is available */ + drawheader(""); + + xfd = ConnectionNumber(dzen.dpy); + while(dzen.running) { + FD_ZERO(&rmask); + FD_SET(xfd, &rmask); + if(dr != -2) + FD_SET(STDIN_FILENO, &rmask); + + while(XPending(dzen.dpy)) + handle_xev(); + + ret = select(xfd+1, &rmask, NULL, NULL, NULL); + if(ret) { + if(dr != -2 && FD_ISSET(STDIN_FILENO, &rmask)) { + if((dr = read_stdin(NULL)) == -1) + return; + handle_newl(); + } + if(dr == -2 && dzen.timeout > 0) { + /* set an alarm to kill us after the timeout */ + struct itimerval t; + memset(&t, 0, sizeof t); + t.it_value.tv_sec = dzen.timeout; + t.it_value.tv_usec = 0; + setitimer(ITIMER_REAL, &t, NULL); + } + if(FD_ISSET(xfd, &rmask)) + handle_xev(); + } + } + return; } static void clean_up(void) { - int i; - - free_ev_table(); - if(dzen.font.set) - XFreeFontSet(dzen.dpy, dzen.font.set); - else - XFreeFont(dzen.dpy, dzen.font.xfont); - - XFreePixmap(dzen.dpy, dzen.title_win.drawable); - if(dzen.slave_win.max_lines) { - XFreePixmap(dzen.dpy, dzen.slave_win.drawable); - for(i=0; i < dzen.slave_win.max_lines; i++) - XDestroyWindow(dzen.dpy, dzen.slave_win.line[i]); - free(dzen.slave_win.line); - XDestroyWindow(dzen.dpy, dzen.slave_win.win); - } - XFreeGC(dzen.dpy, dzen.gc); - XDestroyWindow(dzen.dpy, dzen.title_win.win); - XCloseDisplay(dzen.dpy); + int i; + + free_ev_table(); + if(dzen.font.set) + XFreeFontSet(dzen.dpy, dzen.font.set); + else + XFreeFont(dzen.dpy, dzen.font.xfont); + + XFreePixmap(dzen.dpy, dzen.title_win.drawable); + if(dzen.slave_win.max_lines) { + XFreePixmap(dzen.dpy, dzen.slave_win.drawable); + for(i=0; i < dzen.slave_win.max_lines; i++) + XDestroyWindow(dzen.dpy, dzen.slave_win.line[i]); + free(dzen.slave_win.line); + XDestroyWindow(dzen.dpy, dzen.slave_win.win); + } + XFreeGC(dzen.dpy, dzen.gc); + XDestroyWindow(dzen.dpy, dzen.title_win.win); + XCloseDisplay(dzen.dpy); } -static void + static void set_alignment(void) { - if(dzen.title_win.alignment) { - switch(dzen.title_win.alignment) { - case 'l': - dzen.title_win.alignment = ALIGNLEFT; - break; - case 'c': - dzen.title_win.alignment = ALIGNCENTER; - break; - case 'r': - dzen.title_win.alignment = ALIGNRIGHT; - break; - default: - dzen.title_win.alignment = ALIGNCENTER; - } - } - if(dzen.slave_win.alignment) { - switch(dzen.slave_win.alignment) { - case 'l': - dzen.slave_win.alignment = ALIGNLEFT; - break; - case 'c': - dzen.slave_win.alignment = ALIGNCENTER; - break; - case 'r': - dzen.slave_win.alignment = ALIGNRIGHT; - break; - default: - dzen.slave_win.alignment = ALIGNLEFT; - } - } + if(dzen.title_win.alignment) { + switch(dzen.title_win.alignment) { + case 'l': + dzen.title_win.alignment = ALIGNLEFT; + break; + case 'c': + dzen.title_win.alignment = ALIGNCENTER; + break; + case 'r': + dzen.title_win.alignment = ALIGNRIGHT; + break; + default: + dzen.title_win.alignment = ALIGNCENTER; + } + } + if(dzen.slave_win.alignment) { + switch(dzen.slave_win.alignment) { + case 'l': + dzen.slave_win.alignment = ALIGNLEFT; + break; + case 'c': + dzen.slave_win.alignment = ALIGNCENTER; + break; + case 'r': + dzen.slave_win.alignment = ALIGNRIGHT; + break; + default: + dzen.slave_win.alignment = ALIGNLEFT; + } + } } int main(int argc, char *argv[]) { - int i; - char *action_string = NULL; - char *endptr; - - /* default values */ - dzen.cur_line = 0; - dzen.ret_val = 0; - dzen.title_win.x = dzen.slave_win.x = 0; - dzen.title_win.y = 0; - dzen.title_win.width = dzen.slave_win.width = 0; - dzen.title_win.alignment = ALIGNCENTER; - dzen.slave_win.alignment = ALIGNLEFT; - dzen.fnt = FONT; - dzen.bg = BGCOLOR; - dzen.fg = FGCOLOR; - dzen.slave_win.max_lines = 0; - dzen.running = True; - dzen.xinescreen = 0; - - /* cmdline args */ - for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-l", 3)){ - if(++i < argc) dzen.slave_win.max_lines = atoi(argv[i]); - } - else if(!strncmp(argv[i], "-p", 3)) { - dzen.ispersistent = True; - if (i + 1 < argc) { - dzen.timeout = strtol(argv[i + 1], &endptr, 10); - *endptr ? dzen.timeout = 0 : i++; - } - } - else if(!strncmp(argv[i], "-ta", 4)) { - if(++i < argc) dzen.title_win.alignment = argv[i][0]; - } - else if(!strncmp(argv[i], "-sa", 4)) { - if(++i < argc) dzen.slave_win.alignment = argv[i][0]; - } - else if(!strncmp(argv[i], "-m", 3)) { - dzen.slave_win.ismenu = True; - } - else if(!strncmp(argv[i], "-fn", 4)) { - if(++i < argc) dzen.fnt = argv[i]; - } - else if(!strncmp(argv[i], "-e", 3)) { - if(++i < argc) action_string = argv[i]; - } - else if(!strncmp(argv[i], "-bg", 4)) { - if(++i < argc) dzen.bg = argv[i]; - } - else if(!strncmp(argv[i], "-fg", 4)) { - if(++i < argc) dzen.fg = argv[i]; - } - else if(!strncmp(argv[i], "-x", 3)) { - if(++i < argc) dzen.title_win.x = dzen.slave_win.x = atoi(argv[i]); - } - else if(!strncmp(argv[i], "-y", 3)) { - if(++i < argc) dzen.title_win.y = atoi(argv[i]); - } - else if(!strncmp(argv[i], "-w", 3)) { - if(++i < argc) dzen.slave_win.width = atoi(argv[i]); - } - else if(!strncmp(argv[i], "-tw", 3)) { - if(++i < argc) dzen.title_win.width = atoi(argv[i]); - } + int i; + char *action_string = NULL; + char *endptr; + + /* default values */ + dzen.cur_line = 0; + dzen.ret_val = 0; + dzen.title_win.x = dzen.slave_win.x = 0; + dzen.title_win.y = 0; + dzen.title_win.width = dzen.slave_win.width = 0; + dzen.title_win.alignment = ALIGNCENTER; + dzen.slave_win.alignment = ALIGNLEFT; + dzen.fnt = FONT; + dzen.bg = BGCOLOR; + dzen.fg = FGCOLOR; + dzen.slave_win.max_lines = 0; + dzen.running = True; + dzen.xinescreen = 0; + + /* cmdline args */ + for(i = 1; i < argc; i++) + if(!strncmp(argv[i], "-l", 3)){ + if(++i < argc) dzen.slave_win.max_lines = atoi(argv[i]); + } + else if(!strncmp(argv[i], "-p", 3)) { + dzen.ispersistent = True; + if (i + 1 < argc) { + dzen.timeout = strtol(argv[i + 1], &endptr, 10); + *endptr ? dzen.timeout = 0 : i++; + } + } + else if(!strncmp(argv[i], "-ta", 4)) { + if(++i < argc) dzen.title_win.alignment = argv[i][0]; + } + else if(!strncmp(argv[i], "-sa", 4)) { + if(++i < argc) dzen.slave_win.alignment = argv[i][0]; + } + else if(!strncmp(argv[i], "-m", 3)) { + dzen.slave_win.ismenu = True; + } + else if(!strncmp(argv[i], "-fn", 4)) { + if(++i < argc) dzen.fnt = argv[i]; + } + else if(!strncmp(argv[i], "-e", 3)) { + if(++i < argc) action_string = argv[i]; + } + else if(!strncmp(argv[i], "-bg", 4)) { + if(++i < argc) dzen.bg = argv[i]; + } + else if(!strncmp(argv[i], "-fg", 4)) { + if(++i < argc) dzen.fg = argv[i]; + } + else if(!strncmp(argv[i], "-x", 3)) { + if(++i < argc) dzen.title_win.x = dzen.slave_win.x = atoi(argv[i]); + } + else if(!strncmp(argv[i], "-y", 3)) { + if(++i < argc) dzen.title_win.y = atoi(argv[i]); + } + else if(!strncmp(argv[i], "-w", 3)) { + if(++i < argc) dzen.slave_win.width = atoi(argv[i]); + } + else if(!strncmp(argv[i], "-tw", 3)) { + if(++i < argc) dzen.title_win.width = atoi(argv[i]); + } #ifdef DZEN_XINERAMA - else if(!strncmp(argv[i], "-xs", 4)) { - if(++i < argc) dzen.xinescreen = atoi(argv[i]); - } + else if(!strncmp(argv[i], "-xs", 4)) { + if(++i < argc) dzen.xinescreen = atoi(argv[i]); + } #endif - else if(!strncmp(argv[i], "-v", 3)) - eprint("dzen-"VERSION", (C)opyright 2007 Robert Manea\n"); - else - eprint("usage: dzen2 [-v] [-p [timeout]] [-m] [-ta <l|c|r>] [-sa <l|c|r>] [-tw <pixel>]\n" - " [-e <string>] [-x <pixel>] [-y <pixel>] [-w <pixel>] \n" - " [-l <lines>] [-fn <font>] [-bg <color>] [-fg <color>] \n" + else if(!strncmp(argv[i], "-v", 3)) + eprint("dzen-"VERSION", (C)opyright 2007 Robert Manea\n"); + else + eprint("usage: dzen2 [-v] [-p [timeout]] [-m] [-ta <l|c|r>] [-sa <l|c|r>] [-tw <pixel>]\n" + " [-e <string>] [-x <pixel>] [-y <pixel>] [-w <pixel>] \n" + " [-l <lines>] [-fn <font>] [-bg <color>] [-fg <color>] \n" #ifdef DZEN_XINERAMA - " [-xs <screen>]\n" + " [-xs <screen>]\n" #endif - ); - - if(!dzen.title_win.width) - dzen.title_win.width = dzen.slave_win.width; - - if(!setlocale(LC_ALL, "") || !XSupportsLocale()) - puts("dzen: locale not available, expect problems with fonts.\n"); - - if(action_string) { - char edef[] = "exposet=exposetitle;exposes=exposeslave"; - fill_ev_table(edef); - fill_ev_table(action_string); - } else { - char edef[] = "exposet=exposetitle;exposes=exposeslave;" - "entertitle=uncollapse;leaveslave=collapse;" - "button1=menuexec;button2=togglestick;button3=exit:13;" - "button4=scrollup;button5=scrolldown"; - fill_ev_table(edef); - } - - if(ev_table[onexit].isset && (setup_signal(SIGTERM, catch_sigterm) == SIG_ERR)) - fprintf(stderr, "dzen: error hooking SIGTERM\n"); - if(ev_table[sigusr1].isset && (setup_signal(SIGUSR1, catch_sigusr1) == SIG_ERR)) - fprintf(stderr, "dzen: error hooking SIGUSR1\n"); - if(ev_table[sigusr2].isset && (setup_signal(SIGUSR2, catch_sigusr2) == SIG_ERR)) - fprintf(stderr, "dzen: error hooking SIGUSR2\n"); - if(setup_signal(SIGALRM, catch_alrm) == SIG_ERR) - fprintf(stderr, "dzen: error hooking SIGALARM\n"); - - set_alignment(); - x_create_windows(); - x_map_window(dzen.title_win.win); - - do_action(onstart); - - /* main loop */ - event_loop(NULL); - - do_action(onexit); - clean_up(); - - if(dzen.ret_val) - return dzen.ret_val; - - return EXIT_SUCCESS; + ); + + if(!dzen.title_win.width) + dzen.title_win.width = dzen.slave_win.width; + + if(!setlocale(LC_ALL, "") || !XSupportsLocale()) + puts("dzen: locale not available, expect problems with fonts.\n"); + + if(action_string) { + char edef[] = "exposet=exposetitle;exposes=exposeslave"; + fill_ev_table(edef); + fill_ev_table(action_string); + } else { + char edef[] = "exposet=exposetitle;exposes=exposeslave;" + "entertitle=uncollapse;leaveslave=collapse;" + "button1=menuexec;button2=togglestick;button3=exit:13;" + "button4=scrollup;button5=scrolldown"; + fill_ev_table(edef); + } + + if(ev_table[onexit].isset && (setup_signal(SIGTERM, catch_sigterm) == SIG_ERR)) + fprintf(stderr, "dzen: error hooking SIGTERM\n"); + if(ev_table[sigusr1].isset && (setup_signal(SIGUSR1, catch_sigusr1) == SIG_ERR)) + fprintf(stderr, "dzen: error hooking SIGUSR1\n"); + if(ev_table[sigusr2].isset && (setup_signal(SIGUSR2, catch_sigusr2) == SIG_ERR)) + fprintf(stderr, "dzen: error hooking SIGUSR2\n"); + if(setup_signal(SIGALRM, catch_alrm) == SIG_ERR) + fprintf(stderr, "dzen: error hooking SIGALARM\n"); + + set_alignment(); + x_create_windows(); + x_map_window(dzen.title_win.win); + + do_action(onstart); + + /* main loop */ + event_loop(NULL); + + do_action(onexit); + clean_up(); + + if(dzen.ret_val) + return dzen.ret_val; + + return EXIT_SUCCESS; } @@ -13,50 +13,50 @@ void * emalloc(unsigned int size) { - void *res = malloc(size); + void *res = malloc(size); - if(!res) - eprint("fatal: could not malloc() %u bytes\n", size); - return res; + if(!res) + eprint("fatal: could not malloc() %u bytes\n", size); + return res; } void eprint(const char *errstr, ...) { - va_list ap; + va_list ap; - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(EXIT_FAILURE); + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); } char * estrdup(const char *str) { - void *res = strdup(str); + void *res = strdup(str); - if(!res) - eprint("fatal: could not malloc() %u bytes\n", strlen(str)); - return res; + if(!res) + eprint("fatal: could not malloc() %u bytes\n", strlen(str)); + return res; } void spawn(const char *arg) { - static char *shell = NULL; - - if(!shell && !(shell = getenv("SHELL"))) - shell = "/bin/sh"; - if(!arg) - return; - /* The double-fork construct avoids zombie processes and keeps the code - * clean from stupid signal handlers. */ - if(fork() == 0) { - if(fork() == 0) { - setsid(); - execl(shell, shell, "-c", arg, (char *)NULL); - fprintf(stderr, "dzen: execl '%s -c %s'", shell, arg); - perror(" failed"); - } - exit(0); - } - wait(0); + static char *shell = NULL; + + if(!shell && !(shell = getenv("SHELL"))) + shell = "/bin/sh"; + if(!arg) + return; + /* The double-fork construct avoids zombie processes and keeps the code + * clean from stupid signal handlers. */ + if(fork() == 0) { + if(fork() == 0) { + setsid(); + execl(shell, shell, "-c", arg, (char *)NULL); + fprintf(stderr, "dzen: execl '%s -c %s'", shell, arg); + perror(" failed"); + } + exit(0); + } + wait(0); } |