X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fconky.c;h=59ba006d3c83213ccaeab042accea4403d5c62aa;hb=f3fed13727631e4b4a4a6facf3cf51d108091c46;hp=676ff7424e6a42e20cd1fe1a853ead09ce4b3579;hpb=f9fa7f1d1cd5e7f50987defe16f269f403640b0a;p=monky diff --git a/src/conky.c b/src/conky.c index 676ff74..59ba006 100644 --- a/src/conky.c +++ b/src/conky.c @@ -41,6 +41,8 @@ #include #endif +#include "build.h" + #define CONFIG_FILE "$HOME/.conkyrc" #define MAIL_FILE "$MAIL" #define MAX_IF_BLOCK_DEPTH 5 @@ -48,6 +50,65 @@ /* #define SIGNAL_BLOCKING */ #undef SIGNAL_BLOCKING +static void print_version() +{ + printf("Conky %s compiled %s for %s\n", + VERSION, BUILD_DATE, BUILD_ARCH); + + printf( + "\nCompiled in features:\n\n" +#ifdef X11 + " X11:\n" +# ifdef XFT + " * xft\n" +# endif /* XFT */ +# ifdef HAVE_XDAMAGE + " * Xdamage extension\n" +# endif /* HAVE_XDAMAGE */ +# ifdef HAVE_XDBE + " * Xdbe extension (double buffer)\n" +# endif /* HAVE_XDBE */ +#endif /* X11 */ + "\n Music detection:\n" +#ifdef XMMS + " * xmms\n" +#endif /* XMMS */ +#ifdef BMP + " * bmp\n" +#endif /* BMP */ +#ifdef AUDACIOUS + " * audacious\n" +#endif /* AUDACIOUS */ +#ifdef INFOPIPE + " * infopipe\n" +#endif /* INFOPIPE */ +#ifdef BMPX + " * bmpx\n" +#endif /* BMPX */ +#ifdef XMMS2 + " * xmms2\n" +#endif /* XMMS2 */ +#ifdef MPD + " * mpd\n" +#endif /* MPD */ + "\n General features:\n" +#ifdef TCP_PORT_MONITOR + " * portmon\n" +#endif /* TCP_PORT_MONITOR */ +#ifdef MLDONKEY + " * mldonkey\n" +#endif /* MLDONKEY */ +#ifdef HDDTEMP + " * hddtemp\n" +#endif /* HDDTEMP */ +#ifdef SETI + " * seti\n" +#endif /* SETI*/ + "\n"); + + exit(0); +} + #ifdef X11 /* @@ -86,10 +147,10 @@ struct font_list *fonts = NULL; #ifdef XFT -#define font_height() use_xft ? (fonts[selected_font].xftfont->ascent + fonts[selected_font].xftfont->descent) : \ -(fonts[selected_font].font->max_bounds.ascent + fonts[selected_font].font->max_bounds.descent) -#define font_ascent() use_xft ? fonts[selected_font].xftfont->ascent : fonts[selected_font].font->max_bounds.ascent -#define font_descent() use_xft ? fonts[selected_font].xftfont->descent : fonts[selected_font].font->max_bounds.descent +#define font_height() (use_xft ? (fonts[selected_font].xftfont->ascent + fonts[selected_font].xftfont->descent) : \ +(fonts[selected_font].font->max_bounds.ascent + fonts[selected_font].font->max_bounds.descent)) +#define font_ascent() (use_xft ? fonts[selected_font].xftfont->ascent : fonts[selected_font].font->max_bounds.ascent) +#define font_descent() (use_xft ? fonts[selected_font].xftfont->descent : fonts[selected_font].font->max_bounds.descent) #else @@ -267,7 +328,7 @@ static int fixed_size = 0, fixed_pos = 0; static int minimum_width, minimum_height; static int maximum_width; - +#endif /* X11 */ #ifdef HAVE_ICONV #define CODEPAGE_LENGTH 20 @@ -315,8 +376,6 @@ void free_iconv(void) /* UTF-8 */ int utf8_mode = 0; -#endif /* X11 */ - /* no buffers in used memory? */ int no_buffers; @@ -415,9 +474,9 @@ static inline int calc_text_width(const char *s, int l) if (use_xft) { XGlyphInfo gi; if (utf8_mode) { - XftTextExtentsUtf8(display, fonts[selected_font].xftfont, s, l, &gi); + XftTextExtentsUtf8(display, fonts[selected_font].xftfont, (FcChar8 *)s, l, &gi); } else { - XftTextExtents8(display, fonts[selected_font].xftfont, s, l, &gi); + XftTextExtents8(display, fonts[selected_font].xftfont, (FcChar8 *)s, l, &gi); } return gi.xOff; } else @@ -450,6 +509,8 @@ enum { OFFSET, VOFFSET, FONT, + GOTO, + TAB, }; static struct special_t { @@ -752,6 +813,17 @@ static inline void new_alignc(char *buf, long c) new_special(buf, ALIGNC)->arg = c; } +static inline void new_goto(char *buf, long c) +{ + new_special(buf, GOTO)->arg = c; +} + +static inline void new_tab(char *buf, int a, int b) { + struct special_t *s = new_special(buf, TAB); + s->width = a; + s->arg = b; +} + /* quite boring functions */ static inline void for_each_line(char *b, void (*f) (char *)) @@ -856,6 +928,8 @@ enum text_object_type { OBJ_fs_size, OBJ_fs_used, OBJ_fs_used_perc, + OBJ_goto, + OBJ_tab, OBJ_hr, OBJ_offset, OBJ_voffset, @@ -934,6 +1008,7 @@ enum text_object_type { OBJ_text, OBJ_time, OBJ_utime, + OBJ_tztime, OBJ_totaldown, OBJ_totalup, OBJ_updates, @@ -1031,6 +1106,9 @@ enum text_object_type { OBJ_iconv_start, OBJ_iconv_stop, #endif +#ifdef HDDTEMP + OBJ_hddtemp, +#endif }; struct text_object { @@ -1050,6 +1128,12 @@ struct text_object { unsigned char loadavg[3]; unsigned int cpu_index; struct mail_s *mail; + + struct { + char *tz; /* timezone variable */ + char *fmt; /* time display formatting */ + } tztime; + struct { struct fs_stat *fs; int w, h; @@ -1105,6 +1189,11 @@ struct text_object { int connection_index; /* 0 to n-1 connections. */ } tcp_port_monitor; #endif + struct { + char *addr; + int port; + char *dev; + } hddtemp; /* 2 */ } data; }; @@ -1707,6 +1796,12 @@ static void free_text_objects(unsigned int count, struct text_object *objs) free(objs[i].data.s); break; case OBJ_utime: + free(objs[i].data.s); + break; + case OBJ_tztime: + free(objs[i].data.tztime.tz); + free(objs[i].data.tztime.fmt); + break; case OBJ_imap: free(info.mail); break; @@ -1948,6 +2043,12 @@ static void free_text_objects(unsigned int count, struct text_object *objs) info.first_process = NULL; } break; +#ifdef HDDTEMP + case OBJ_hddtemp: + free(objs[i].data.hddtemp.dev); + free(objs[i].data.hddtemp.addr); + break; +#endif } } free(objs); @@ -2300,6 +2401,28 @@ static struct text_object *construct_text_object(const char *s, const char *arg, END OBJ(hr, 0) obj->data.i = arg ? atoi(arg) : 1; END OBJ(offset, 0) obj->data.i = arg ? atoi(arg) : 1; END OBJ(voffset, 0) obj->data.i = arg ? atoi(arg) : 1; + END OBJ(goto, 0) + + if (!arg) { + ERR("goto needs arguments"); + obj->type = OBJ_text; + obj->data.s = strdup("${goto}"); + return NULL; + } + + obj->data.i = atoi(arg); + + END OBJ(tab, 0) + int a = 10, b = 0; + if (arg) { + if (sscanf(arg, "%d %d", &a, &b) != 2) + sscanf(arg, "%d", &b); + } + if (a <= 0) + a = 1; + obj->data.pair.a = a; + obj->data.pair.b = b; + END OBJ(i2c, INFO_I2C) char buf1[64], buf2[64]; int n; @@ -2651,6 +2774,21 @@ static struct text_object *construct_text_object(const char *s, const char *arg, obj->data.i2c.devtype); END OBJ(time, 0) obj->data.s = strdup(arg ? arg : "%F %T"); END OBJ(utime, 0) obj->data.s = strdup(arg ? arg : "%F %T"); + END OBJ(tztime, 0) + char buf1[256], buf2[256], *fmt, *tz; + fmt = tz = NULL; + if (arg) { + int nArgs = sscanf(arg, "%255s %255[^\n]", buf1, buf2); + switch (nArgs) { + case 2: + tz = buf1; + case 1: + fmt = buf2; + } + } + + obj->data.tztime.fmt = strdup(fmt ? fmt : "%F %T"); + obj->data.tztime.tz = tz ? strdup(tz) : NULL; #ifdef HAVE_ICONV END OBJ(iconv_start, 0) if (iconv_converting) { @@ -2848,6 +2986,17 @@ static struct text_object *construct_text_object(const char *s, const char *arg, memset(&(info.bmpx), 0, sizeof(struct bmpx_s)); END #endif +#ifdef HDDTEMP + OBJ(hddtemp, 0) + if (!arg || scan_hddtemp(arg, &obj->data.hddtemp.dev, + &obj->data.hddtemp.addr, &obj->data.hddtemp.port)) { + ERR("hddtemp needs arguments"); + obj->type = OBJ_text; + obj->data.s = strdup("${hddtemp}"); + return NULL; + } + END +#endif #ifdef TCP_PORT_MONITOR OBJ(tcp_portmon, INFO_TCP_PORT_MONITOR) int argc, port_begin, port_end, item, connection_index; @@ -2902,8 +3051,8 @@ static struct text_object *construct_text_object(const char *s, const char *arg, CRIT_ERR("tcp_portmon: connection index must be non-negative"); } /* ok, args looks good. save the text object data */ - obj->data.tcp_port_monitor.port_range_begin = (in_addr_t)port_begin; - obj->data.tcp_port_monitor.port_range_end = (in_addr_t)port_end; + obj->data.tcp_port_monitor.port_range_begin = (in_port_t)port_begin; + obj->data.tcp_port_monitor.port_range_end = (in_port_t)port_end; obj->data.tcp_port_monitor.item = item; obj->data.tcp_port_monitor.connection_index = connection_index; @@ -3179,16 +3328,18 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * obj->a = get_freq(p, p_max_size, "%'.2f", 1000, obj->data.cpu_index); /* pk */ } } +#if defined(__linux__) OBJ(voltage_mv) { if (obj->a) { - obj->a = get_voltage(p, p_max_size, "%.0f", 1, obj->data.cpu_index); /* ptarjan */ + obj->a = get_voltage(p, p_max_size, "%.0f", 1, obj->data.cpu_index); } } OBJ(voltage_v) { if (obj->a) { - obj->a = get_voltage(p, p_max_size, "%'.3f", 1000, obj->data.cpu_index); /* ptarjan */ + obj->a = get_voltage(p, p_max_size, "%'.3f", 1000, obj->data.cpu_index); } } +#endif /* __linux__ */ OBJ(freq_dyn) { if (use_spacer) { @@ -3841,9 +3992,29 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * v[obj->data.loadavg[0] - 1]); } + OBJ(goto) { + new_goto(p, obj->data.i); + } + OBJ(tab) { + new_tab(p, obj->data.pair.a, obj->data.pair.b); + } OBJ(hr) { new_hr(p, obj->data.i); } + OBJ(hddtemp) { + char *temp; + char unit; + + temp = get_hddtemp_info(obj->data.hddtemp.dev, + obj->data.hddtemp.addr, obj->data.hddtemp.port, &unit); + if (!temp) { + snprintf(p, p_max_size, "N/A"); + } else if (unit == '*') { + snprintf(p, p_max_size, "%s", temp); + } else { + snprintf(p, p_max_size, "%s°%c", temp, unit); + } + } OBJ(offset) { new_offset(p, obj->data.i); } @@ -4102,6 +4273,25 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * struct tm *tm = gmtime(&t); strftime(p, p_max_size, obj->data.s, tm); } + OBJ(tztime) { + char* oldTZ = NULL; + if (obj->data.tztime.tz) { + oldTZ = getenv("TZ"); + setenv("TZ", obj->data.tztime.tz, 1); + tzset(); + } + time_t t = time(NULL); + struct tm *tm = localtime(&t); + setlocale(LC_TIME, ""); + strftime(p, p_max_size, obj->data.tztime.fmt, tm); + if (oldTZ) { + setenv("TZ", oldTZ, 1); + tzset(); + } else { + unsetenv("TZ"); + } + // Needless to free oldTZ since getenv gives ptr to static data + } OBJ(totaldown) { human_readable(obj->data.net->recv, p, 255); @@ -4784,64 +4974,10 @@ static inline int get_string_width_special(char *s) #endif /* X11 */ } -int fontchange = 0; - #ifdef X11 -static void text_size_updater(char *s) -{ - int w = 0; - char *p; - int h = font_height(); - /* get string widths and skip specials */ - p = s; - while (*p) { - if (*p == SPECIAL_CHAR) { - *p = '\0'; - w += get_string_width(s); - *p = SPECIAL_CHAR; +static void text_size_updater(char *s); - if (specials[special_index].type == BAR - || specials[special_index].type == GRAPH) { - w += specials[special_index].width; - if (specials[special_index].height > h) { - h = specials[special_index].height; - h += font_ascent(); - } - } - - else if (specials[special_index].type == OFFSET) { - w += specials[special_index].arg + get_string_width("a"); /* filthy, but works */ - } - else if (specials[special_index].type == VOFFSET) { - h += specials[special_index].arg; - } - else if (specials[special_index].type == FONT) { - fontchange = 1; - selected_font = specials[special_index].font_added; - h = font_height(); - } - - - special_index++; - s = p + 1; - } - p++; - } - w += get_string_width(s); - if (w > text_width) - text_width = w; - if (text_width > maximum_width && maximum_width) - text_width = maximum_width; - - text_height += h; -/* if (fontchange) { - selected_font = 0; - }*/ -} -#endif /* X11 */ - - -#ifdef X11 +int last_font_height; static void update_text_area() { int x, y; @@ -4854,7 +4990,9 @@ static void update_text_area() text_width = minimum_width; text_height = 0; special_index = 0; + int first_font_height = last_font_height = font_height(); for_each_line(text_buffer, text_size_updater); + text_height -= first_font_height; text_width += 1; if (text_height < minimum_height) text_height = minimum_height; @@ -4929,6 +5067,64 @@ static int cur_x, cur_y; /* current x and y for drawing */ static int draw_mode; /* FG, BG or OUTLINE */ static long current_color; +#ifdef X11 +static void text_size_updater(char *s) +{ + int w = 0; + char *p; + /* get string widths and skip specials */ + p = s; + while (*p) { + if (*p == SPECIAL_CHAR) { + *p = '\0'; + w += get_string_width(s); + *p = SPECIAL_CHAR; + + if (specials[special_index].type == BAR + || specials[special_index].type == GRAPH) { + w += specials[special_index].width; + if (specials[special_index].height > last_font_height) { + last_font_height = specials[special_index].height; + last_font_height += font_ascent(); + } + } else if (specials[special_index].type == OFFSET) { + w += specials[special_index].arg + get_string_width("a"); /* filthy, but works */ + } else if (specials[special_index].type == VOFFSET) { + last_font_height += specials[special_index].arg; + } else if (specials[special_index].type == GOTO) { + if (specials[special_index].arg >= 0) + w += (int)specials[special_index].arg - cur_x; + } else if (specials[special_index].type == TAB) { + int start = specials[special_index].arg; + int step = specials[special_index].width; + if (!step || step < 0) + step = 10; + w += step - (cur_x - text_start_x - start) % step; + } else if (specials[special_index].type == FONT) { + selected_font = specials[special_index].font_added; + if (font_height() > last_font_height) { + last_font_height = font_height(); + } + } + + special_index++; + s = p + 1; + } + p++; + } + w += get_string_width(s); + if (w > text_width) { + text_width = w; + } + if (text_width > maximum_width && maximum_width) { + text_width = maximum_width; + } + + text_height += last_font_height; + last_font_height = font_height(); +} +#endif /* X11 */ + static inline void set_foreground_color(long c) { current_color = c; @@ -5222,17 +5418,8 @@ static void draw_line(char *s) specials[special_index].height; int bar_usage = specials[special_index].arg; - int by; - -#ifdef XFT - if (use_xft) { - by = cur_y - (font_ascent() + h) / 2 - 1; - } else -#endif - { - by = cur_y - (font_ascent()/2) - 1; - } - if (h < (font_height())) { + int by = cur_y - (font_ascent() / 2) - 1; + if (h < font_height()) { by -= h / 2 - 1; } w = specials[special_index].width; @@ -5276,17 +5463,9 @@ static void draw_line(char *s) } int h = specials[special_index].height; - int by; unsigned long last_colour = current_color; -#ifdef XFT - if (use_xft) { - by = cur_y - (font_ascent() + h) / 2 - 1; - } else -#endif - { - by = cur_y - (font_ascent()/2) - 1; - } - if (h < (font_height())) { + int by = cur_y - (font_ascent()/2) - 1; + if (h < font_height()) { by -= h / 2 - 1; } w = specials[special_index].width; @@ -5309,13 +5488,13 @@ static void draw_line(char *s) float gradient_factor = 0; float gradient_update = 0; unsigned long tmpcolour = current_color; - if (specials[special_index].last_colour != 0 && specials[special_index].first_colour != 0) { + if (specials[special_index].last_colour != 0 || specials[special_index].first_colour != 0) { tmpcolour = specials[special_index].last_colour; gradient_size = gradient_max(specials[special_index].last_colour, specials[special_index].first_colour); gradient_factor = (float)gradient_size / (w - 2); } for (i = w - 2; i > -1; i--) { - if (specials[special_index].last_colour != 0 && specials[special_index].first_colour != 0) { + if (specials[special_index].last_colour != 0 || specials[special_index].first_colour != 0) { XSetForeground(display, window.gc, tmpcolour); gradient_update += gradient_factor; while (gradient_update > 0) { @@ -5349,12 +5528,12 @@ static void draw_line(char *s) break; case FONT: - if (fontchange) { + { int old = font_ascent(); cur_y -= font_ascent(); selected_font = specials[special_index].font_added; - if (cur_y + (font_ascent()) < old) { - cur_y = old; + if (cur_y + font_ascent() < cur_y + old) { + cur_y += old; } else { cur_y += font_ascent(); } @@ -5382,14 +5561,26 @@ static void draw_line(char *s) arg); break; - case OFFSET: - { - w += specials[special_index].arg; - } + case OFFSET: + w += specials[special_index].arg; + break; + + case VOFFSET: + cur_y += specials[special_index].arg; break; - case VOFFSET: + + case GOTO: + if (specials[special_index].arg >= 0) + cur_x = (int)specials[special_index].arg; + break; + + case TAB: { - cur_y += specials[special_index].arg; + int start = specials[special_index].arg; + int step = specials[special_index].width; + if (!step || step < 0) + step = 10; + w = step - (cur_x - text_start_x - start) % step; } break; @@ -5437,9 +5628,6 @@ static void draw_line(char *s) draw_string(s); cur_y += font_descent(); -/* if (fontchange) { - selected_font = 0; - }*/ #endif /* X11 */ } @@ -5482,6 +5670,7 @@ static void draw_text() static void draw_stuff() { #ifdef X11 + selected_font = 0; if (draw_shades && !draw_outline) { text_start_x++; text_start_y++; @@ -5493,6 +5682,7 @@ static void draw_stuff() } if (draw_outline) { + selected_font = 0; int i, j; for (i = -1; i < 2; i++) for (j = -1; j < 2; j++) { @@ -5569,16 +5759,18 @@ static void main_loop() #ifdef X11 Region region = XCreateRegion(); int event_base, error_base; +#ifdef HAVE_XDAMAGE if (!XDamageQueryExtension (display, &event_base, &error_base)) { ERR("Xdamage extension unavailable"); } Damage damage = XDamageCreate(display, window.window, XDamageReportNonEmpty); XserverRegion region2 = XFixesCreateRegionFromWindow(display, window.window, 0); XserverRegion part = XFixesCreateRegionFromWindow(display, window.window, 0); +#endif /* HAVE_XDAMAGE */ #endif /* X11 */ info.looped = 0; - while (total_run_times == 0 || info.looped < total_run_times - 1) { + while (total_run_times == 0 || info.looped < total_run_times) { info.looped++; #ifdef SIGNAL_BLOCKING @@ -5634,7 +5826,7 @@ static void main_loop() #endif need_to_update = 0; - + selected_font = 0; update_text_area(); #ifdef OWN_WINDOW if (own_window) { @@ -5788,6 +5980,7 @@ static void main_loop() #endif default: +#ifdef HAVE_XDAMAGE if (ev.type == event_base + XDamageNotify) { XDamageNotifyEvent *dev = (XDamageNotifyEvent *) &ev; XFixesSetRegion(display, part, &dev->area, 1); @@ -5795,6 +5988,7 @@ static void main_loop() XDamageSubtract(display, damage, region2, None); XFixesSetRegion(display, region2, 0, 0); } +#endif /* HAVE_XDAMAGE */ break; } } @@ -5870,13 +6064,13 @@ static void main_loop() g_signal_pending=0; } -#ifdef X11 +#if defined(X11) && defined(HAVE_XDAMAGE) XDamageDestroy(display, damage); XFixesDestroyRegion(display, region2); XFixesDestroyRegion(display, part); XDestroyRegion(region); region = NULL; -#endif /* X11 */ +#endif /* X11 && HAVE_XDAMAGE */ } static void load_config_file(const char *); @@ -6739,10 +6933,7 @@ int main(int argc, char **argv) switch (c) { case 'v': case 'V': - printf - ("Conky " VERSION " compiled " __DATE__ "\n"); - return 0; - + print_version(); case 'c': /* if current_config is set to a strdup of CONFIG_FILE, free it (even * though free() does the NULL check itself;), then load optarg value */ @@ -6937,6 +7128,7 @@ int main(int argc, char **argv) generate_text(); #ifdef X11 + selected_font = 0; update_text_area(); /* to get initial size of the window */ init_window @@ -6945,6 +7137,7 @@ int main(int argc, char **argv) text_height + border_margin * 2 + 1, set_transparent, background_colour, info.uname_s.nodename, argv, argc); + selected_font = 0; update_text_area(); /* to position text/window on screen */ #endif /* X11 */