X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fconky.c;h=790e93c599414099ebca1f1ac6dafc1d54a8a2cb;hb=9c5e5d86bd74465ca1b6f037b084bdb0eda453f7;hp=de97dacd53ac1ac5b49db1e3f81e80e9b9ce4220;hpb=b6d1ff6c4213f47cc2edfdde16b3d9115ba9f47b;p=monky diff --git a/src/conky.c b/src/conky.c index de97dac..790e93c 100644 --- a/src/conky.c +++ b/src/conky.c @@ -10,7 +10,7 @@ * Please see COPYING for details * * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen - * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al. + * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al. * (see AUTHORS) * All rights reserved. * @@ -147,6 +147,9 @@ char *get_apm_battery_time(void); /* debugging level, used by logging.h */ int global_debug_level = 0; +/* disable inotify auto reload feature if desired */ +int disable_auto_reload = 0; + /* two strings for internal use */ static char *tmpstring1, *tmpstring2; @@ -166,9 +169,7 @@ int top_io; #ifdef __linux__ int top_running; #endif -static unsigned int top_name_width = 15; int output_methods; -char times_in_seconds = 0; static int extra_newline; enum x_initialiser_state x_initialised = NO; static volatile int g_signal_pending; @@ -177,6 +178,7 @@ double update_interval; double update_interval_old; double update_interval_bat; void *global_cpu = NULL; +unsigned int max_text_width = 0; int argc_copy; char** argv_copy; @@ -204,6 +206,9 @@ static void print_version(void) # ifdef XFT " * Xft\n" # endif /* XFT */ +# ifdef USE_ARGB + " * ARGB visual\n" +# endif /* USE_ARGB */ #endif /* X11 */ "\n Music detection:\n" #ifdef AUDACIOUS @@ -315,7 +320,8 @@ static int text_width, text_height; /* alignments */ enum alignment { - TOP_LEFT = 1, + ALIGNMENT_ERROR, + TOP_LEFT, TOP_RIGHT, TOP_MIDDLE, BOTTOM_LEFT, @@ -348,6 +354,10 @@ static unsigned long total_run_times; /* fork? */ static int fork_to_background; +/* set to 0 after the first time conky is run, so we don't fork again after the + * first forking */ +static int first_pass = 1; + static int cpu_avg_samples, net_avg_samples, diskio_avg_samples; /* filenames for output */ @@ -453,14 +463,14 @@ int check_contains(char *f, char *s) } fclose(where); } else { - NORM_ERR("Could not open the file"); + NORM_ERR("Could not open the file '%s'", f); } return ret; } #define SECRIT_MULTILINE_CHAR '\x02' -static inline int calc_text_width(const char *s) +int calc_text_width(const char *s) { size_t slen = strlen(s); @@ -723,29 +733,6 @@ void parse_conky_vars(struct text_object *root, const char *txt, generate_text_internal(p, p_max_size, *root, cur); } -static inline void format_media_player_time(char *buf, const int size, - int seconds) -{ - int days, hours, minutes; - - days = seconds / (24 * 60 * 60); - seconds %= (24 * 60 * 60); - hours = seconds / (60 * 60); - seconds %= (60 * 60); - minutes = seconds / 60; - seconds %= 60; - - if (days > 0) { - snprintf(buf, size, "%i days %i:%02i:%02i", days, - hours, minutes, seconds); - } else if (hours > 0) { - snprintf(buf, size, "%i:%02i:%02i", hours, minutes, - seconds); - } else { - snprintf(buf, size, "%i:%02i", minutes, seconds); - } -} - /* substitutes all occurrences of '\n' with SECRIT_MULTILINE_CHAR, which allows * multiline objects like $exec work with $align[rc] and friends */ @@ -843,18 +830,10 @@ void generate_text_internal(char *p, int p_max_size, } #if defined(__linux__) OBJ(voltage_mv) { - static int ok = 1; - if (ok) { - ok = get_voltage(p, p_max_size, "%.0f", 1, - obj->data.i); - } + print_voltage_mv(obj, p, p_max_size); } OBJ(voltage_v) { - static int ok = 1; - if (ok) { - ok = get_voltage(p, p_max_size, "%'.3f", 1000, - obj->data.i); - } + print_voltage_v(obj, p, p_max_size); } #ifdef HAVE_IWLIB @@ -891,7 +870,7 @@ void generate_text_internal(char *p, int p_max_size, get_acpi_fan(p, p_max_size); } OBJ(acpiacadapter) { - get_acpi_ac_adapter(p, p_max_size); + get_acpi_ac_adapter(p, p_max_size, (const char *)obj->data.opaque); } OBJ(battery) { get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_STATUS); @@ -903,12 +882,7 @@ void generate_text_internal(char *p, int p_max_size, percent_print(p, p_max_size, get_battery_perct(obj->data.s)); } OBJ(battery_bar) { -#ifdef X11 - if(output_methods & TO_X) { - new_bar(obj, p, get_battery_perct_bar(obj->data.s)); - }else -#endif /* X11 */ - new_bar_in_shell(obj, p, p_max_size, get_battery_perct_bar(obj->data.s) / 2.55); + new_bar(obj, p, p_max_size, get_battery_perct_bar(obj->data.s)); } OBJ(battery_short) { get_battery_short_status(p, p_max_size, obj->data.s); @@ -925,32 +899,27 @@ void generate_text_internal(char *p, int p_max_size, print_cmdline_to_pid(obj, p, p_max_size); } OBJ(cpu) { - if (obj->data.i > info.cpu_count) { - NORM_ERR("obj->data.i %i info.cpu_count %i", - obj->data.i, info.cpu_count); - CRIT_ERR(NULL, NULL, "attempting to use more CPUs than you have!"); - } - percent_print(p, p_max_size, + if (cur->cpu_usage) { + if (obj->data.i > info.cpu_count) { + NORM_ERR("obj->data.i %i info.cpu_count %i", + obj->data.i, info.cpu_count); + CRIT_ERR(NULL, NULL, "attempting to use more CPUs than you have!"); + } + percent_print(p, p_max_size, round_to_int(cur->cpu_usage[obj->data.i] * 100.0)); + } } -#ifdef X11 OBJ(cpugauge) - new_gauge(obj, p, round_to_int(cur->cpu_usage[obj->data.i] * 255.0)); -#endif /* X11 */ + new_gauge(obj, p, p_max_size, round_to_int(cur->cpu_usage[obj->data.i] * 255.0)); OBJ(cpubar) { -#ifdef X11 - if(output_methods & TO_X) { - new_bar(obj, p, round_to_int(cur->cpu_usage[obj->data.i] * 255.0)); - }else -#endif /* X11 */ - new_bar_in_shell(obj, p, p_max_size, round_to_int(cur->cpu_usage[obj->data.i] * 100)); + new_bar(obj, p, p_max_size, round_to_int(cur->cpu_usage[obj->data.i] * 255.0)); } #ifdef X11 OBJ(cpugraph) { - new_graph(obj, p, round_to_int(cur->cpu_usage[obj->data.i] * 100)); + new_graph(obj, p, p_max_size, round_to_int(cur->cpu_usage[obj->data.i] * 100)); } OBJ(loadgraph) { - print_loadgraph(obj, p); + print_loadgraph(obj, p, p_max_size); } #endif /* X11 */ OBJ(color) { @@ -988,15 +957,6 @@ void generate_text_internal(char *p, int p_max_size, new_fg(p, color9); } #endif /* X11 */ - OBJ(conky_version) { - snprintf(p, p_max_size, "%s", VERSION); - } - OBJ(conky_build_date) { - snprintf(p, p_max_size, "%s", BUILD_DATE); - } - OBJ(conky_build_arch) { - snprintf(p, p_max_size, "%s", BUILD_ARCH); - } #if defined(__linux__) OBJ(disk_protect) { snprintf(p, p_max_size, "%s", @@ -1034,16 +994,16 @@ void generate_text_internal(char *p, int p_max_size, } #if defined(IBM) OBJ(ibm_fan) { - get_ibm_acpi_fan(p, p_max_size); + get_ibm_acpi_fan(obj, p, p_max_size); } OBJ(ibm_temps) { print_ibm_temps(obj, p, p_max_size); } OBJ(ibm_volume) { - get_ibm_acpi_volume(p, p_max_size); + get_ibm_acpi_volume(obj, p, p_max_size); } OBJ(ibm_brightness) { - get_ibm_acpi_brightness(p, p_max_size); + get_ibm_acpi_brightness(obj, p, p_max_size); } #endif /* IBM */ /* information from sony_laptop kernel module @@ -1100,23 +1060,23 @@ void generate_text_internal(char *p, int p_max_size, } #endif /* X11 */ OBJ(diskio) { - print_diskio(obj, 0, p, p_max_size); + print_diskio(obj, p, p_max_size); } OBJ(diskio_write) { - print_diskio(obj, 1, p, p_max_size); + print_diskio_write(obj, p, p_max_size); } OBJ(diskio_read) { - print_diskio(obj, -1, p, p_max_size); + print_diskio_read(obj, p, p_max_size); } #ifdef X11 OBJ(diskiograph) { - print_diskiograph(obj, 0, p); + print_diskiograph(obj, p, p_max_size); } OBJ(diskiograph_read) { - print_diskiograph(obj, -1, p); + print_diskiograph_read(obj, p, p_max_size); } OBJ(diskiograph_write) { - print_diskiograph(obj, 1, p); + print_diskiograph_write(obj, p, p_max_size); } #endif /* X11 */ OBJ(downspeed) { @@ -1127,7 +1087,7 @@ void generate_text_internal(char *p, int p_max_size, } #ifdef X11 OBJ(downspeedgraph) { - print_downspeedgraph(obj, p); + print_downspeedgraph(obj, p, p_max_size); } #endif /* X11 */ OBJ(else) { @@ -1165,11 +1125,9 @@ void generate_text_internal(char *p, int p_max_size, OBJ(execp) { print_execp(obj, p, p_max_size); } -#ifdef X11 OBJ(execgauge) { print_execgauge(obj, p, p_max_size); } -#endif /* X11 */ OBJ(execbar) { print_execbar(obj, p, p_max_size); } @@ -1185,10 +1143,10 @@ void generate_text_internal(char *p, int p_max_size, OBJ(execigraph) { print_execigraph(obj, p, p_max_size); } +#endif /* X11 */ OBJ(execigauge) { print_execigauge(obj, p, p_max_size); } -#endif /* X11 */ OBJ(execi) { print_execi(obj, p, p_max_size); } @@ -1278,44 +1236,22 @@ void generate_text_internal(char *p, int p_max_size, #endif #ifdef HAVE_LUA OBJ(lua) { - char *str = llua_getstring(obj->data.s); - if (str) { - snprintf(p, p_max_size, "%s", str); - free(str); - } + print_lua(obj, p, p_max_size); } OBJ(lua_parse) { - char *str = llua_getstring(obj->data.s); - if (str) { - evaluate(str, p, p_max_size); - free(str); - } + print_lua_parse(obj, p, p_max_size); } OBJ(lua_bar) { - double per; - if (llua_getnumber(obj->data.s, &per)) { -#ifdef X11 - if(output_methods & TO_X) { - new_bar(obj, p, (per/100.0 * 255)); - } else -#endif /* X11 */ - new_bar_in_shell(obj, p, p_max_size, per); - } + print_lua_bar(obj, p, p_max_size); } #ifdef X11 OBJ(lua_graph) { - double per; - if (llua_getnumber(obj->data.s, &per)) { - new_graph(obj, p, per); - } + print_lua_graph(obj, p, p_max_size); } +#endif /* X11 */ OBJ(lua_gauge) { - double per; - if (llua_getnumber(obj->data.s, &per)) { - new_gauge(obj, p, (per/100.0 * 255)); - } + print_lua_gauge(obj, p, p_max_size); } -#endif /* X11 */ #endif /* HAVE_LUA */ #ifdef HDDTEMP OBJ(hddtemp) { @@ -1394,7 +1330,7 @@ void generate_text_internal(char *p, int p_max_size, DO_JUMP; } else if (spc) { *spc = '\0'; - if (check_contains(obj->data.s, spc + 1)) + if (!check_contains(obj->data.s, spc + 1)) DO_JUMP; *spc = ' '; } @@ -1443,45 +1379,36 @@ void generate_text_internal(char *p, int p_max_size, if (cur->memmax) percent_print(p, p_max_size, cur->mem * 100 / cur->memmax); } -#ifdef X11 OBJ(memgauge){ - new_gauge(obj, p, cur->memmax ? (cur->mem * 255) / (cur->memmax) : 0); + new_gauge(obj, p, p_max_size, cur->memmax ? (cur->mem * 255) / (cur->memmax) : 0); } -#endif /* X11 */ OBJ(membar) { -#ifdef X11 - if(output_methods & TO_X) { - new_bar(obj, p, cur->memmax ? (cur->mem * 255) / (cur->memmax) : 0); - }else -#endif /* X11 */ - new_bar_in_shell(obj, p, p_max_size, cur->memmax ? (cur->mem * 100) / (cur->memmax) : 0); + new_bar(obj, p, p_max_size, cur->memmax ? (cur->mem * 255) / (cur->memmax) : 0); } #ifdef X11 OBJ(memgraph) { - new_graph(obj, p, cur->memmax ? (cur->mem * 100.0) / (cur->memmax) : 0.0); + new_graph(obj, p, p_max_size, cur->memmax ? (cur->mem * 100.0) / (cur->memmax) : 0.0); } #endif /* X11 */ /* mixer stuff */ OBJ(mixer) { - print_mixer(obj, 0, p, p_max_size); + print_mixer(obj, p, p_max_size); } OBJ(mixerl) { - print_mixer(obj, -1, p, p_max_size); + print_mixerl(obj, p, p_max_size); } OBJ(mixerr) { - print_mixer(obj, 1, p, p_max_size); + print_mixerr(obj, p, p_max_size); } -#ifdef X11 OBJ(mixerbar) { - print_mixer_bar(obj, 0, p); + print_mixer_bar(obj, p, p_max_size); } OBJ(mixerlbar) { - print_mixer_bar(obj, -1, p); + print_mixerl_bar(obj, p, p_max_size); } OBJ(mixerrbar) { - print_mixer_bar(obj, 1, p); + print_mixerr_bar(obj, p, p_max_size); } -#endif /* X11 */ OBJ(if_mixer_mute) { if (!check_mixer_muted(obj)) { DO_JUMP; @@ -1531,11 +1458,7 @@ void generate_text_internal(char *p, int p_max_size, generate_text_internal(buf, max_user_text, *obj->sub, cur); obj->data.s = buf; - if(times_in_seconds) { - print_format_time(obj, p, p_max_size); - } else { - NORM_ERR("Enable \"times_in_seconds\" to use $format_time"); - } + print_format_time(obj, p, p_max_size); } /* mail stuff */ OBJ(mails) { @@ -1903,12 +1826,7 @@ void generate_text_internal(char *p, int p_max_size, } } OBJ(swapbar) { -#ifdef X11 - if(output_methods & TO_X) { - new_bar(obj, p, cur->swapmax ? (cur->swap * 255) / (cur->swapmax) : 0); - }else -#endif /* X11 */ - new_bar_in_shell(obj, p, p_max_size, cur->swapmax ? (cur->swap * 100) / (cur->swapmax) : 0); + new_bar(obj, p, p_max_size, cur->swapmax ? (cur->swap * 255) / (cur->swapmax) : 0); } OBJ(sysname) { snprintf(p, p_max_size, "%s", cur->uname_s.sysname); @@ -1958,22 +1876,14 @@ void generate_text_internal(char *p, int p_max_size, } #ifdef X11 OBJ(upspeedgraph) { - print_upspeedgraph(obj, p); + print_upspeedgraph(obj, p, p_max_size); } #endif /* X11 */ OBJ(uptime_short) { - if(times_in_seconds) { - snprintf(p, p_max_size, "%d", (int) cur->uptime); - } else { - format_seconds_short(p, p_max_size, (int) cur->uptime); - } + format_seconds_short(p, p_max_size, (int) cur->uptime); } OBJ(uptime) { - if(times_in_seconds) { - snprintf(p, p_max_size, "%d", (int) cur->uptime); - } else { - format_seconds(p, p_max_size, (int) cur->uptime); - } + format_seconds(p, p_max_size, (int) cur->uptime); } #ifdef __linux__ OBJ(user_names) { @@ -1986,7 +1896,7 @@ void generate_text_internal(char *p, int p_max_size, snprintf(p, p_max_size, "%s", cur->users.times); } OBJ(user_time) { - update_user_time(obj->data.s, times_in_seconds); + update_user_time(obj->data.s); snprintf(p, p_max_size, "%s", cur->users.ctime); } OBJ(user_number) { @@ -2019,89 +1929,48 @@ void generate_text_internal(char *p, int p_max_size, #endif /* __FreeBSD__ __OpenBSD__ */ #ifdef MPD -#define mpd_printf(fmt, val) \ - snprintf(p, p_max_size, fmt, mpd_get_info()->val) -#define mpd_sprintf(val) { \ - if (!obj->data.i || obj->data.i > p_max_size) \ - mpd_printf("%s", val); \ - else \ - snprintf(p, obj->data.i, "%s", mpd_get_info()->val); \ -} OBJ(mpd_title) - mpd_sprintf(title); + print_mpd_title(obj, p, p_max_size); OBJ(mpd_artist) - mpd_sprintf(artist); + print_mpd_artist(obj, p, p_max_size); OBJ(mpd_album) - mpd_sprintf(album); + print_mpd_album(obj, p, p_max_size); OBJ(mpd_random) - mpd_printf("%s", random); + print_mpd_random(obj, p, p_max_size); OBJ(mpd_repeat) - mpd_printf("%s", repeat); + print_mpd_repeat(obj, p, p_max_size); OBJ(mpd_track) - mpd_sprintf(track); + print_mpd_track(obj, p, p_max_size); OBJ(mpd_name) - mpd_sprintf(name); + print_mpd_name(obj, p, p_max_size); OBJ(mpd_file) - mpd_sprintf(file); + print_mpd_file(obj, p, p_max_size); OBJ(mpd_vol) - mpd_printf("%d", volume); + print_mpd_vol(obj, p, p_max_size); OBJ(mpd_bitrate) - mpd_printf("%d", bitrate); + print_mpd_bitrate(obj, p, p_max_size); OBJ(mpd_status) - mpd_printf("%s", status); + print_mpd_status(obj, p, p_max_size); OBJ(mpd_elapsed) { - if(times_in_seconds) { - snprintf(p, p_max_size, "%d", mpd_get_info()->elapsed); - } else { - format_media_player_time(p, p_max_size, mpd_get_info()->elapsed); - } + print_mpd_elapsed(obj, p, p_max_size); } OBJ(mpd_length) { - if(times_in_seconds) { - snprintf(p, p_max_size, "%d", mpd_get_info()->length); - } else { - format_media_player_time(p, p_max_size, mpd_get_info()->length); - } + print_mpd_length(obj, p, p_max_size); } OBJ(mpd_percent) { - percent_print(p, p_max_size, (int)(mpd_get_info()->progress * 100)); + print_mpd_percent(obj, p, p_max_size); } OBJ(mpd_bar) { -#ifdef X11 - if(output_methods & TO_X) { - new_bar(obj, p, (int) (mpd_get_info()->progress * 255.0f)); - } else -#endif /* X11 */ - new_bar_in_shell(obj, p, p_max_size, (int) (mpd_get_info()->progress * 100.0f)); + print_mpd_bar(obj, p, p_max_size); } OBJ(mpd_smart) { - struct mpd_s *mpd = mpd_get_info(); - int len = obj->data.i; - if (len == 0 || len > p_max_size) - len = p_max_size; - - memset(p, 0, p_max_size); - if (mpd->artist && *mpd->artist && - mpd->title && *mpd->title) { - snprintf(p, len, "%s - %s", mpd->artist, - mpd->title); - } else if (mpd->title && *mpd->title) { - snprintf(p, len, "%s", mpd->title); - } else if (mpd->artist && *mpd->artist) { - snprintf(p, len, "%s", mpd->artist); - } else if (mpd->file && *mpd->file) { - snprintf(p, len, "%s", mpd->file); - } else { - *p = 0; - } + print_mpd_smart(obj, p, p_max_size); } OBJ(if_mpd_playing) { if (!mpd_get_info()->is_playing) { DO_JUMP; } } -#undef mpd_sprintf -#undef mpd_printf #endif #ifdef MOC @@ -2193,11 +2062,9 @@ void generate_text_internal(char *p, int p_max_size, OBJ(xmms2_percent) { snprintf(p, p_max_size, "%2.0f", cur->xmms2.progress * 100); } -#ifdef X11 OBJ(xmms2_bar) { - new_bar(obj, p, (int) (cur->xmms2.progress * 255.0f)); + new_bar(obj, p, p_max_size, (int) (cur->xmms2.progress * 255.0f)); } -#endif /* X11 */ OBJ(xmms2_playlist) { snprintf(p, p_max_size, "%s", cur->xmms2.playlist); } @@ -2273,16 +2140,14 @@ void generate_text_internal(char *p, int p_max_size, snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_MAIN_VOLUME]); } -#ifdef X11 OBJ(audacious_bar) { double progress; progress = atof(cur->audacious.items[AUDACIOUS_POSITION_SECONDS]) / atof(cur->audacious.items[AUDACIOUS_LENGTH_SECONDS]); - new_bar(obj, p, (int) (progress * 255.0f)); + new_bar(obj, p, p_max_size, (int) (progress * 255.0f)); } -#endif /* X11 */ #endif /* AUDACIOUS */ #ifdef BMPX @@ -2316,9 +2181,7 @@ void generate_text_internal(char *p, int p_max_size, #ifdef IOSTATS case OBJ_top_io: #endif - /* yes, passing top_name_width instead - * of p_max_size is intended here */ - print_top(obj, p, top_name_width); + print_top(obj, p, p_max_size); #endif /* __linux__ */ OBJ(tail) { print_tailhead("tail", obj, p, p_max_size); @@ -2327,57 +2190,11 @@ void generate_text_internal(char *p, int p_max_size, print_tailhead("head", obj, p, p_max_size); } OBJ(lines) { - static int rep = 0; - FILE *fp = open_file(obj->data.s, &rep); - - if(fp != NULL) { -/* FIXME: use something more general (see also tail.c, head.c */ -#define BUFSZ 0x1000 - char buf[BUFSZ]; - int j, lines; - - lines = 0; - while(fgets(buf, BUFSZ, fp) != NULL){ - for(j = 0; buf[j] != 0; j++) { - if(buf[j] == '\n') { - lines++; - } - } - } - sprintf(p, "%d", lines); - fclose(fp); - } else { - sprintf(p, "File Unreadable"); - } + print_lines(obj, p, p_max_size); } OBJ(words) { - static int rep = 0; - FILE *fp = open_file(obj->data.s, &rep); - - if(fp != NULL) { - char buf[BUFSZ]; - int j, words; - char inword = FALSE; - - words = 0; - while(fgets(buf, BUFSZ, fp) != NULL){ - for(j = 0; buf[j] != 0; j++) { - if(!isspace(buf[j])) { - if(inword == FALSE) { - words++; - inword = TRUE; - } - } else { - inword = FALSE; - } - } - } - sprintf(p, "%d", words); - fclose(fp); - } else { - sprintf(p, "File Unreadable"); - } + print_words(obj, p, p_max_size); } #ifdef TCP_PORT_MONITOR OBJ(tcp_portmon) { @@ -2408,12 +2225,7 @@ void generate_text_internal(char *p, int p_max_size, } #ifdef IBM OBJ(smapi) { - char *s; - if(obj->data.s) { - s = smapi_get_val(obj->data.s); - snprintf(p, p_max_size, "%s", s); - free(s); - } + print_smapi(obj, p, p_max_size); } OBJ(if_smapi_bat_installed) { int idx; @@ -2425,43 +2237,17 @@ void generate_text_internal(char *p, int p_max_size, NORM_ERR("argument to if_smapi_bat_installed must be an integer"); } OBJ(smapi_bat_perc) { - int idx, val; - if(obj->data.s && sscanf(obj->data.s, "%i", &idx) == 1) { - val = smapi_bat_installed(idx) ? - smapi_get_bat_int(idx, "remaining_percent") : 0; - percent_print(p, p_max_size, val); - } else - NORM_ERR("argument to smapi_bat_perc must be an integer"); + print_smapi_bat_perc(obj, p, p_max_size); } OBJ(smapi_bat_temp) { - int idx, val; - if(obj->data.s && sscanf(obj->data.s, "%i", &idx) == 1) { - val = smapi_bat_installed(idx) ? - smapi_get_bat_int(idx, "temperature") : 0; - /* temperature is in milli degree celsius */ - temp_print(p, p_max_size, val / 1000, TEMP_CELSIUS); - } else - NORM_ERR("argument to smapi_bat_temp must be an integer"); + print_smapi_bat_temp(obj, p, p_max_size); } OBJ(smapi_bat_power) { - int idx, val; - if(obj->data.s && sscanf(obj->data.s, "%i", &idx) == 1) { - val = smapi_bat_installed(idx) ? - smapi_get_bat_int(idx, "power_now") : 0; - /* power_now is in mW, set to W with one digit precision */ - snprintf(p, p_max_size, "%.1f", ((double)val / 1000)); - } else - NORM_ERR("argument to smapi_bat_power must be an integer"); + print_smapi_bat_power(obj, p, p_max_size); } -#ifdef X11 OBJ(smapi_bat_bar) { - if(obj->data.i >= 0 && smapi_bat_installed(obj->data.i)) - new_bar(obj, p, (int) - (255 * smapi_get_bat_int(obj->data.i, "remaining_percent") / 100)); - else - new_bar(obj, p, 0); + print_smapi_bat_bar(obj, p, p_max_size); } -#endif /* X11 */ #endif /* IBM */ OBJ(include) { if(obj->sub) { @@ -2546,29 +2332,21 @@ void generate_text_internal(char *p, int p_max_size, } OBJ(apcupsd_loadbar) { double progress; -#ifdef X11 - if(output_methods & TO_X) { - progress = atof(cur->apcupsd.items[APCUPSD_LOAD]) / 100.0 * 255.0; - new_bar(obj, p, (int) progress); - } else -#endif /* X11 */ - { - progress = atof(cur->apcupsd.items[APCUPSD_LOAD]); - new_bar_in_shell(obj, p, p_max_size, (int) progress); - } + progress = atof(cur->apcupsd.items[APCUPSD_LOAD]) / 100.0 * 255.0; + new_bar(obj, p, p_max_size, (int) progress); } #ifdef X11 OBJ(apcupsd_loadgraph) { double progress; progress = atof(cur->apcupsd.items[APCUPSD_LOAD]); - new_graph(obj, p, (int)progress); + new_graph(obj, p, p_max_size, (int)progress); } +#endif /* X11 */ OBJ(apcupsd_loadgauge) { double progress; progress = atof(cur->apcupsd.items[APCUPSD_LOAD]) / 100.0 * 255.0; - new_gauge(obj, p, (int)progress); + new_gauge(obj, p, p_max_size, (int)progress); } -#endif /* X11 */ OBJ(apcupsd_charge) { snprintf(p, p_max_size, "%s", cur->apcupsd.items[APCUPSD_CHARGE]); @@ -2626,7 +2404,7 @@ void evaluate(const char *text, char *p, int p_max_size) tmp_info = malloc(sizeof(struct information)); memcpy(tmp_info, &info, sizeof(struct information)); parse_conky_vars(&subroot, text, p, p_max_size, tmp_info); - DBGP("evaluated '%s' to '%s'", text, p); + DBGP2("evaluated '%s' to '%s'", text, p); free_text_objects(&subroot, 1); free(tmp_info); @@ -2638,6 +2416,7 @@ static void generate_text(void) { struct information *cur = &info; char *p; + unsigned int i, j, k; special_count = 0; @@ -2654,6 +2433,22 @@ static void generate_text(void) p = text_buffer; generate_text_internal(p, max_user_text, global_root_object, cur); + if(max_text_width > 0) { + for(i = 0, j = 0; p[i] != 0; i++) { + if(p[i] == '\n') j = 0; + else if(j == max_text_width) { + k = i + strlen(p + i) + 1; + if(k < text_buffer_size) { + while(k != i) { + p[k] = p[k-1]; + k--; + } + p[k] = '\n'; + j = 0; + } else NORM_ERR("The end of the text_buffer is reached, increase \"text_buffer_size\""); + } else j++; + } + } if (stuff_in_uppercase) { char *tmp_p; @@ -2681,7 +2476,7 @@ void set_update_interval(double interval) update_interval_old = interval; } -static inline int get_string_width(const char *s) +int get_string_width(const char *s) { return *s ? calc_text_width(s) : 0; } @@ -2834,6 +2629,8 @@ static long current_color; static int text_size_updater(char *s, int special_index) { int w = 0; + int lw; + int contain_SECRIT_MULTILINE_CHAR = 0; char *p; if ((output_methods & TO_X) == 0) @@ -2882,7 +2679,7 @@ static int text_size_updater(char *s, int special_index) special_index++; s = p + 1; } else if (*p == SECRIT_MULTILINE_CHAR) { - int lw; + contain_SECRIT_MULTILINE_CHAR = 1; *p = '\0'; lw = get_string_width(s); *p = SECRIT_MULTILINE_CHAR; @@ -2892,7 +2689,13 @@ static int text_size_updater(char *s, int special_index) } p++; } - w += get_string_width(s); + /* Check also last substring if string contains SECRIT_MULTILINE_CHAR */ + if (contain_SECRIT_MULTILINE_CHAR) { + lw = get_string_width(s); + w = lw > w ? lw : w; + } else { + w += get_string_width(s); + } if (w > text_width) { text_width = w; } @@ -2910,8 +2713,16 @@ static inline void set_foreground_color(long c) { #ifdef X11 if (output_methods & TO_X) { - current_color = c; - XSetForeground(display, window.gc, c); +#ifdef USE_ARGB + if (have_argb_visual) { + current_color = c | (own_window_argb_value << 24); + } else { +#endif /* USE_ARGB */ + current_color = c; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ + XSetForeground(display, window.gc, current_color); } #endif /* X11 */ #ifdef NCURSES @@ -3012,7 +2823,8 @@ static void draw_string(const char *s) XftColor c2; c.pixel = current_color; - XQueryColor(display, DefaultColormap(display, screen), &c); + // query color on custom colormap + XQueryColor(display, window.colourmap, &c); c2.pixel = c.pixel; c2.color.red = c.red; @@ -3307,36 +3119,49 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) if (seconds != 0) { timeunits = seconds / 86400; seconds %= 86400; if (timeunits > 0) { - asprintf(&tmp_day_str, "%dd", timeunits); + if (asprintf(&tmp_day_str, "%dd", timeunits) < 0) { + tmp_day_str = 0; + } } else { tmp_day_str = strdup(""); } timeunits = seconds / 3600; seconds %= 3600; if (timeunits > 0) { - asprintf(&tmp_hour_str, "%dh", timeunits); + if (asprintf(&tmp_hour_str, "%dh", timeunits) < 0) { + tmp_day_str = 0; + } } else { tmp_hour_str = strdup(""); } timeunits = seconds / 60; seconds %= 60; if (timeunits > 0) { - asprintf(&tmp_min_str, "%dm", timeunits); + if (asprintf(&tmp_min_str, "%dm", timeunits) < 0) { + tmp_min_str = 0; + } } else { tmp_min_str = strdup(""); } if (seconds > 0) { - asprintf(&tmp_sec_str, "%ds", seconds); + if (asprintf(&tmp_sec_str, "%ds", seconds) < 0) { + tmp_sec_str = 0; + } } else { tmp_sec_str = strdup(""); } - asprintf(&tmp_str, "%s%s%s%s", tmp_day_str, tmp_hour_str, tmp_min_str, tmp_sec_str); - free(tmp_day_str); free(tmp_hour_str); free(tmp_min_str); free(tmp_sec_str); + if (asprintf(&tmp_str, "%s%s%s%s", tmp_day_str, + tmp_hour_str, tmp_min_str, tmp_sec_str) < 0) { + tmp_str = 0; + } +#define FREE(a) if ((a)) free((a)); + FREE(tmp_day_str); FREE(tmp_hour_str); FREE(tmp_min_str); FREE(tmp_sec_str); } else { - asprintf(&tmp_str, "Range not possible"); // should never happen, but better safe then sorry + tmp_str = strdup("Range not possible"); /* should never happen, but better safe then sorry */ } cur_x += (w / 2) - (font_ascent() * (strlen(tmp_str) / 2)); cur_y += font_h / 2; draw_string(tmp_str); - free(tmp_str); + FREE(tmp_str); +#undef FREE cur_x = tmp_x; cur_y = tmp_y; } @@ -3773,7 +3598,7 @@ static void main_loop(void) draw_stuff(); /* redraw everything in our newly sized window */ XResizeWindow(display, window.window, window.width, window.height); /* resize window */ - set_transparent_background(window.window); + set_transparent_background(window.window, own_window_argb_value); #ifdef HAVE_XDBE /* swap buffers */ xdbe_swap_buffers(); @@ -3873,9 +3698,9 @@ static void main_loop(void) #ifdef OWN_WINDOW case ReparentNotify: - /* set background to ParentRelative for all parents */ + /* make background transparent */ if (own_window) { - set_transparent_background(window.window); + set_transparent_background(window.window, own_window_argb_value); } break; @@ -4082,12 +3907,12 @@ static void main_loop(void) break; } #ifdef HAVE_SYS_INOTIFY_H - if (inotify_fd != -1 && inotify_config_wd == -1 && current_config != 0) { + if (!disable_auto_reload && inotify_fd != -1 && inotify_config_wd == -1 && current_config != 0) { inotify_config_wd = inotify_add_watch(inotify_fd, current_config, IN_MODIFY); } - if (inotify_fd != -1 && inotify_config_wd != -1 && current_config != 0) { + if (!disable_auto_reload && inotify_fd != -1 && inotify_config_wd != -1 && current_config != 0) { int len = 0, idx = 0; fd_set descriptors; struct timeval time_to_wait; @@ -4114,6 +3939,7 @@ static void main_loop(void) current_config, IN_MODIFY); } + break; } #ifdef HAVE_LUA else { @@ -4123,6 +3949,10 @@ static void main_loop(void) idx += INOTIFY_EVENT_SIZE + ev->len; } } + } else if (disable_auto_reload && inotify_fd != -1) { + inotify_rm_watch(inotify_fd, inotify_config_wd); + close(inotify_fd); + inotify_fd = inotify_config_wd = 0; } #endif /* HAVE_SYS_INOTIFY_H */ @@ -4131,7 +3961,7 @@ static void main_loop(void) #endif /* HAVE_LUA */ g_signal_pending = 0; } - clean_up(NULL, NULL); + clean_up(current_mail_spool, NULL); #ifdef HAVE_SYS_INOTIFY_H if (inotify_fd != -1) { @@ -4152,6 +3982,7 @@ static void reload_config(void) { char *current_config_copy = strdup(current_config); clean_up(NULL, NULL); + sleep(1); /* slight pause */ current_config = current_config_copy; initialisation(argc_copy, argv_copy); } @@ -4160,6 +3991,8 @@ void clean_up(void *memtofree1, void* memtofree2) { int i; + free_update_callbacks(); + #ifdef NCURSES if(output_methods & TO_NCURSES) { endwin(); @@ -4181,10 +4014,12 @@ void clean_up(void *memtofree1, void* memtofree2) } #ifdef X11 if (x_initialised == YES) { - XClearArea(display, window.window, text_start_x - window.border_inner_margin - window.border_outer_margin - window.border_width, - text_start_y - window.border_inner_margin - window.border_outer_margin - window.border_width, - text_width + window.border_inner_margin * 2 + window.border_outer_margin * 2 + window.border_width * 2, - text_height + window.border_inner_margin * 2 + window.border_outer_margin * 2 + window.border_width * 2, 0); + if(window_created == 1) { + XClearArea(display, window.window, text_start_x - window.border_inner_margin - window.border_outer_margin - window.border_width, + text_start_y - window.border_inner_margin - window.border_outer_margin - window.border_width, + text_width + window.border_inner_margin * 2 + window.border_outer_margin * 2 + window.border_width * 2, + text_height + window.border_inner_margin * 2 + window.border_outer_margin * 2 + window.border_width * 2, 0); + } destroy_window(); free_fonts(); if(x11_stuff.region) { @@ -4209,8 +4044,6 @@ void clean_up(void *memtofree1, void* memtofree2) #endif /* X11 */ - free_update_callbacks(); - free_templates(); free_text_objects(&global_root_object, 0); @@ -4334,7 +4167,7 @@ static enum alignment string_to_alignment(const char *s) } else if (strcasecmp(s, "none") == EQUAL) { return NONE; } - return TOP_LEFT; + return ALIGNMENT_ERROR; } #endif /* X11 */ @@ -4450,6 +4283,10 @@ static void set_default_configurations(void) window.hints = 0; strcpy(window.class_name, PACKAGE_NAME); sprintf(window.title, PACKAGE_NAME" (%s)", info.uname_s.nodename); +#ifdef USE_ARGB + use_argb_visual = 0; + own_window_argb_value = 255; +#endif #endif stippled_borders = 0; window.border_inner_margin = 3; @@ -4484,6 +4321,8 @@ static void set_default_configurations(void) stuff_in_uppercase = 0; info.users.number = 1; + set_times_in_seconds(0); + #ifdef TCP_PORT_MONITOR /* set default connection limit */ tcp_portmon_set_max_connections(0); @@ -4539,7 +4378,7 @@ int x11_ioerror_handler(Display *d) NORM_ERR("X Error: Display %lx\n", (long unsigned)d ); - abort(); + exit(1); } #endif /* DEBUG */ @@ -4583,7 +4422,7 @@ static void X11_create_window(void) XMoveWindow(display, window.window, window.x, window.y); } if (own_window) { - set_transparent_background(window.window); + set_transparent_background(window.window, own_window_argb_value); } #endif @@ -4681,6 +4520,29 @@ static int do_config_step(int *line, FILE *fp, char *buf, char **name, char **va return 0; } +#ifdef X11 +void setalignment(int* ltext_alignment, unsigned int windowtype, const char* value, const char *f, int line, char setbyconffile) { +#ifdef OWN_WINDOW + if (windowtype == TYPE_DOCK) { + NORM_ERR("alignment is disabled when own_window_type is dock"); + } else +#endif /*OWN_WINDOW */ + if (value) { + int a = string_to_alignment(value); + + if (a <= 0) { + if (setbyconffile) { + CONF_ERR; + } else NORM_ERR("'%s' is not a alignment setting", value); + } else { + *ltext_alignment = a; + } + } else if (setbyconffile) { + CONF_ERR; + } +} +#endif /* X11 */ + char load_config_file(const char *f) { int line = 0; @@ -4724,22 +4586,7 @@ char load_config_file(const char *f) } } CONF("alignment") { -#ifdef OWN_WINDOW - if (window.type == TYPE_DOCK) - ; - else -#endif /*OWN_WINDOW */ - if (value) { - int a = string_to_alignment(value); - - if (a <= 0) { - CONF_ERR; - } else { - text_alignment = a; - } - } else { - CONF_ERR; - } + setalignment(&text_alignment, window.type, value, f, line, 1); } CONF("background") { fork_to_background = string_to_bool(value); @@ -4948,7 +4795,10 @@ char load_config_file(const char *f) } #endif /* X11 */ CONF("times_in_seconds") { - times_in_seconds = string_to_bool(value); + set_times_in_seconds(string_to_bool(value)); + } + CONF("max_text_width") { + max_text_width = atoi(value); } CONF("out_to_console") { if(string_to_bool(value)) { @@ -4960,6 +4810,9 @@ char load_config_file(const char *f) CONF("extra_newline") { extra_newline = string_to_bool(value); } + CONF("disable_auto_reload") { + disable_auto_reload = string_to_bool(value); + } CONF("out_to_stderr") { if(string_to_bool(value)) output_methods |= TO_STDERR; @@ -5117,16 +4970,8 @@ char load_config_file(const char *f) no_buffers = string_to_bool(value); } CONF("top_name_width") { - if (value) { - if (sscanf(value, "%u", &top_name_width) != 1) { - CONF_ERR; - } - } else { + if (set_top_name_width(value)) CONF_ERR; - } - if (top_name_width >= max_user_text) { - top_name_width = max_user_text - 1; - } } CONF("top_cpu_separate") { cpu_separate = string_to_bool(value); @@ -5225,6 +5070,17 @@ char load_config_file(const char *f) CONF_ERR; } } +#ifdef USE_ARGB + CONF("own_window_argb_visual") { + use_argb_visual = string_to_bool(value); + } + CONF("own_window_argb_value") { + own_window_argb_value = strtol(value, 0, 0); + if (own_window_argb_value > 255 || own_window_argb_value < 0) { + CONF_ERR2("own_window_argb_value must be <= 255 and >= 0"); + } + } +#endif /* USE_ARGB */ #endif CONF("stippled_borders") { if (value) { @@ -5719,6 +5575,7 @@ static const char *getopt_string = "vVqdDt:u:i:hc:p:" static const struct option longopts[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, + { "quiet", 0, NULL, 'q' }, { "debug", 0, NULL, 'D' }, { "config", 1, NULL, 'c' }, #ifdef CONFIG_OUTPUT @@ -5738,15 +5595,64 @@ static const struct option longopts[] = { { "window-id", 1, NULL, 'w' }, #endif /* X11 */ { "text", 1, NULL, 't' }, - { "interval", 0, NULL, 'u' }, - { "pause", 0, NULL, 'p' }, + { "interval", 1, NULL, 'u' }, + { "pause", 1, NULL, 'p' }, { 0, 0, 0, 0 } }; +void set_current_config(void); +void set_current_config(void) +{ + /* check if specified config file is valid */ + if (current_config) { + struct stat sb; + if (stat(current_config, &sb) || + (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode))) { + NORM_ERR("invalid configuration file '%s'\n", current_config); + free(current_config); + current_config = 0; + } + } + + /* load current_config, CONFIG_FILE or SYSTEM_CONFIG_FILE */ + + if (!current_config) { + /* load default config file */ + char buf[DEFAULT_TEXT_BUFFER_SIZE]; + FILE *fp; + + /* Try to use personal config file first */ + to_real_path(buf, CONFIG_FILE); + if (buf[0] && (fp = fopen(buf, "r"))) { + current_config = strndup(buf, max_user_text); + fclose(fp); + } + + /* Try to use system config file if personal config not readable */ + if (!current_config && (fp = fopen(SYSTEM_CONFIG_FILE, "r"))) { + current_config = strndup(SYSTEM_CONFIG_FILE, max_user_text); + fclose(fp); + } + + /* No readable config found */ + if (!current_config) { +#define NOCFGFILEFOUND "no readable personal or system-wide config file found" +#ifdef BUILD_BUILTIN_CONFIG + current_config = strdup("==builtin=="); + NORM_ERR(NOCFGFILEFOUND + ", using builtin default"); +#else + CRIT_ERR(NULL, NULL, NOCFGFILEFOUND); +#endif /* ! CONF_OUTPUT */ + } + } +} + void initialisation(int argc, char **argv) { struct sigaction act, oact; set_default_configurations(); + set_current_config(); load_config_file(current_config); currentconffile = conftree_add(currentconffile, current_config); @@ -5803,7 +5709,7 @@ void initialisation(int argc, char **argv) { set_first_font(optarg); break; case 'a': - text_alignment = string_to_alignment(optarg); + setalignment(&text_alignment, window.type, optarg, NULL, 0, 0); break; #ifdef OWN_WINDOW @@ -5848,8 +5754,10 @@ void initialisation(int argc, char **argv) { break; #endif /* X11 */ case 'p': - startup_pause = atoi(optarg); - sleep(startup_pause); + if (first_pass) { + startup_pause = atoi(optarg); + sleep(startup_pause); + } break; case '?': @@ -5872,7 +5780,7 @@ void initialisation(int argc, char **argv) { } global_text = NULL; /* fork */ - if (fork_to_background) { + if (fork_to_background && first_pass) { int pid = fork(); switch (pid) { @@ -6000,7 +5908,9 @@ int main(int argc, char **argv) current_config = strndup(optarg, max_user_text); break; case 'q': - freopen("/dev/null", "w", stderr); + if (!freopen("/dev/null", "w", stderr)) { + NORM_ERR("unable to redirect stderr to /dev/null"); + } break; case 'h': print_help(argv[0]); @@ -6026,48 +5936,7 @@ int main(int argc, char **argv) } } - /* check if specified config file is valid */ - if (current_config) { - struct stat sb; - if (stat(current_config, &sb) || - (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode))) { - NORM_ERR("invalid configuration file '%s'\n", current_config); - free(current_config); - current_config = 0; - } - } - - /* load current_config, CONFIG_FILE or SYSTEM_CONFIG_FILE */ - - if (!current_config) { - /* load default config file */ - char buf[DEFAULT_TEXT_BUFFER_SIZE]; - FILE *fp; - - /* Try to use personal config file first */ - to_real_path(buf, CONFIG_FILE); - if (buf[0] && (fp = fopen(buf, "r"))) { - current_config = strndup(buf, max_user_text); - fclose(fp); - } - - /* Try to use system config file if personal config not readable */ - if (!current_config && (fp = fopen(SYSTEM_CONFIG_FILE, "r"))) { - current_config = strndup(SYSTEM_CONFIG_FILE, max_user_text); - fclose(fp); - } - - /* No readable config found */ - if (!current_config) { -#ifdef CONFIG_OUTPUT - current_config = strdup("==builtin=="); - NORM_ERR("no readable personal or system-wide config file found," - " using builtin default"); -#else - CRIT_ERR(NULL, NULL, "no readable personal or system-wide config file found"); -#endif /* ! CONF_OUTPUT */ - } - } + set_current_config(); #ifdef XOAP /* Load xoap keys, if existing */ @@ -6080,6 +5949,8 @@ int main(int argc, char **argv) initialisation(argc, argv); + first_pass = 0; /* don't ever call fork() again */ + main_loop(); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)