xdbe replaced with more generic pixmap based buffering but there are 2 bugs:
[monky] / src / conky.c
index a9973d8..7f5ec00 100644 (file)
@@ -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.
  *
@@ -70,6 +70,9 @@
 #ifdef XOAP
 #include <libxml/parser.h>
 #endif /* XOAP */
+#ifdef HAVE_CURL
+#include <curl/curl.h>
+#endif
 
 /* local headers */
 #include "core.h"
@@ -80,7 +83,9 @@
 #include "diskio.h"
 #include "entropy.h"
 #include "exec.h"
+#include "i8k.h"
 #include "proc.h"
+#include "user.h"
 #ifdef X11
 #include "fonts.h"
 #endif
@@ -145,6 +150,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;
 
@@ -161,10 +169,7 @@ int top_cpu, top_mem, top_time;
 #ifdef IOSTATS
 int top_io;
 #endif
-#ifdef __linux__
 int top_running;
-#endif
-static unsigned int top_name_width = 15;
 int output_methods;
 static int extra_newline;
 enum x_initialiser_state x_initialised = NO;
@@ -174,6 +179,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;
@@ -201,6 +207,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
@@ -261,9 +270,6 @@ static void print_version(void)
 #ifdef IMLIB2
                   "  * Imlib2\n"
 #endif /* IMLIB2 */
-#ifdef MIXER_IS_ALSA
-                  "  * ALSA mixer support\n"
-#endif /* MIXER_IS_ALSA */
 #ifdef APCUPSD
                   "  * apcupsd\n"
 #endif /* APCUPSD */
@@ -312,7 +318,8 @@ static int text_width, text_height;
 
 /* alignments */
 enum alignment {
-       TOP_LEFT = 1,
+       ALIGNMENT_ERROR,
+       TOP_LEFT,
        TOP_RIGHT,
        TOP_MIDDLE,
        BOTTOM_LEFT,
@@ -345,6 +352,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 */
@@ -450,14 +461,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);
 
@@ -499,6 +510,7 @@ static inline void for_each_line(char *b, int f(char *, int))
        char *ps, *pe;
        int special_index = 0; /* specials index */
 
+       if(! b) return;
        for (ps = b, pe = b; *pe; pe++) {
                if (*pe == '\n') {
                        *pe = '\0';
@@ -594,7 +606,7 @@ void human_readable(long long num, char *buf, int size)
                spaced_print(buf, size, "%d", 6, round_to_int(num));
                return;
        }
-       if (short_units) {
+       if (short_units || llabs(num) < 1000LL) {
                width = 5;
                format = "%.*f%.1s";
        } else {
@@ -621,11 +633,11 @@ void human_readable(long long num, char *buf, int size)
         * adjusting the decimal part of the number. Sample output:
         *  123MiB
         * 23.4GiB
-        * 5.12B   
+        * 5.12B
         * so the point of alignment resides between number and unit. The
         * upside of this is that there is minimal padding necessary, though
         * there should be a way to make alignment take place at the decimal
-        * dot (then with fixed width decimal part). 
+        * dot (then with fixed width decimal part).
         *
         * Note the repdigits below: when given a precision value, printf()
         * rounds the float to it, not just cuts off the remaining digits. So
@@ -713,33 +725,11 @@ static void extract_variable_text(const char *p)
        extract_variable_text_internal(&global_root_object, p);
 }
 
-void parse_conky_vars(struct text_object *root, const char *txt, char *p, struct information *cur)
+void parse_conky_vars(struct text_object *root, const char *txt,
+               char *p, int p_max_size, struct information *cur)
 {
        extract_variable_text_internal(root, txt);
-       generate_text_internal(p, max_user_text, *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);
-       }
+       generate_text_internal(p, p_max_size, *root, cur);
 }
 
 /* substitutes all occurrences of '\n' with SECRIT_MULTILINE_CHAR, which allows
@@ -774,6 +764,8 @@ void generate_text_internal(char *p, int p_max_size,
        buff_in[0] = 0;
 #endif /* HAVE_ICONV */
 
+       if(! p) return;
+
        p[0] = 0;
        obj = root.next;
        while (obj && p_max_size > 0) {
@@ -800,7 +792,8 @@ void generate_text_internal(char *p, int p_max_size,
  */
 #define DO_JUMP { \
        DBGP2("jumping"); \
-       obj = obj->special_data; \
+       if (obj->ifblock_next) \
+               obj = obj->ifblock_next; \
 }
 
 #define OBJ(a) break; case OBJ_##a:
@@ -838,18 +831,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
@@ -886,7 +871,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);
@@ -894,20 +879,27 @@ void generate_text_internal(char *p, int p_max_size,
                        OBJ(battery_time) {
                                get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_TIME);
                        }
+                       OBJ(battery_volts) {
+                               get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_VOLTS);
+                       }
+                       OBJ(battery_temp) {
+                               get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_TEMP);
+                       }
                        OBJ(battery_percent) {
                                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);
                        }
+                       OBJ(cell_radio_dbm) {
+                               get_dbus_stuff(p, p_max_size, DBUS_CELL_DBM);
+                       }
+                       OBJ(cell_radio_percent) {
+                               get_dbus_stuff(p, p_max_size, DBUS_CELL_PERCENT);
+                       }
 #endif /* __OpenBSD__ */
 
                        OBJ(buffers) {
@@ -920,32 +912,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) {
@@ -983,98 +970,53 @@ 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",
                                                get_disk_protect_queue(obj->data.s));
                        }
                        OBJ(i8k_version) {
-                               snprintf(p, p_max_size, "%s", i8k.version);
+                               print_i8k_version(obj, p, p_max_size);
                        }
                        OBJ(i8k_bios) {
-                               snprintf(p, p_max_size, "%s", i8k.bios);
+                               print_i8k_bios(obj, p, p_max_size);
                        }
                        OBJ(i8k_serial) {
-                               snprintf(p, p_max_size, "%s", i8k.serial);
+                               print_i8k_serial(obj, p, p_max_size);
                        }
                        OBJ(i8k_cpu_temp) {
-                               int cpu_temp;
-
-                               sscanf(i8k.cpu_temp, "%d", &cpu_temp);
-                               temp_print(p, p_max_size, (double)cpu_temp, TEMP_CELSIUS);
+                               print_i8k_cpu_temp(obj, p, p_max_size);
                        }
                        OBJ(i8k_left_fan_status) {
-                               int left_fan_status;
-
-                               sscanf(i8k.left_fan_status, "%d", &left_fan_status);
-                               if (left_fan_status == 0) {
-                                       snprintf(p, p_max_size, "off");
-                               }
-                               if (left_fan_status == 1) {
-                                       snprintf(p, p_max_size, "low");
-                               }
-                               if (left_fan_status == 2) {
-                                       snprintf(p, p_max_size, "high");
-                               }
+                               print_i8k_left_fan_status(obj, p, p_max_size);
                        }
                        OBJ(i8k_right_fan_status) {
-                               int right_fan_status;
-
-                               sscanf(i8k.right_fan_status, "%d", &right_fan_status);
-                               if (right_fan_status == 0) {
-                                       snprintf(p, p_max_size, "off");
-                               }
-                               if (right_fan_status == 1) {
-                                       snprintf(p, p_max_size, "low");
-                               }
-                               if (right_fan_status == 2) {
-                                       snprintf(p, p_max_size, "high");
-                               }
+                               print_i8k_right_fan_status(obj, p, p_max_size);
                        }
                        OBJ(i8k_left_fan_rpm) {
-                               snprintf(p, p_max_size, "%s", i8k.left_fan_rpm);
+                               print_i8k_left_fan_rpm(obj, p, p_max_size);
                        }
                        OBJ(i8k_right_fan_rpm) {
-                               snprintf(p, p_max_size, "%s", i8k.right_fan_rpm);
+                               print_i8k_right_fan_rpm(obj, p, p_max_size);
                        }
                        OBJ(i8k_ac_status) {
-                               int ac_status;
-
-                               sscanf(i8k.ac_status, "%d", &ac_status);
-                               if (ac_status == -1) {
-                                       snprintf(p, p_max_size, "disabled (read i8k docs)");
-                               }
-                               if (ac_status == 0) {
-                                       snprintf(p, p_max_size, "off");
-                               }
-                               if (ac_status == 1) {
-                                       snprintf(p, p_max_size, "on");
-                               }
+                               print_i8k_ac_status(obj, p, p_max_size);
                        }
                        OBJ(i8k_buttons_status) {
-                               snprintf(p, p_max_size, "%s", i8k.buttons_status);
+                               print_i8k_buttons_status(obj, p, 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
@@ -1131,23 +1073,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) {
@@ -1158,7 +1100,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) {
@@ -1166,7 +1108,7 @@ void generate_text_internal(char *p, int p_max_size,
                                 * Do Ninja jump here: without leaving traces.
                                 * This is to prevent us from stale jumped flags.
                                 */
-                               obj = obj->sub;
+                               obj = obj->ifblock_next;
                                continue;
                        }
                        OBJ(endif) {
@@ -1188,7 +1130,7 @@ void generate_text_internal(char *p, int p_max_size,
                        }
 #endif /* IMLIB2 */
                        OBJ(eval) {
-                               evaluate(obj->data.s, p);
+                               evaluate(obj->data.s, p, p_max_size);
                        }
                        OBJ(exec) {
                                print_exec(obj, p, p_max_size);
@@ -1196,11 +1138,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);
                        }
@@ -1216,15 +1156,15 @@ 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);
                        }
                        OBJ(execpi) {
-                               print_execpi(obj, p);
+                               print_execpi(obj, p, p_max_size);
                        }
                        OBJ(texeci) {
                                print_texeci(obj, p, p_max_size);
@@ -1309,44 +1249,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);
-                                       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) {
@@ -1425,7 +1343,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 = ' ';
                                }
@@ -1474,45 +1392,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;
@@ -1557,6 +1466,13 @@ void generate_text_internal(char *p, int p_max_size,
                        }
 #endif /* X11 */
 
+                       OBJ(format_time) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_format_time(obj, p, p_max_size);
+                       }
                        /* mail stuff */
                        OBJ(mails) {
                                print_mails(obj, p, p_max_size);
@@ -1600,6 +1516,15 @@ void generate_text_internal(char *p, int p_max_size,
                        OBJ(nodename) {
                                snprintf(p, p_max_size, "%s", cur->uname_s.nodename);
                        }
+                       OBJ(nodename_short) {
+                               char *pos;
+                               pos = strstr(cur->uname_s.nodename, ".");
+                               if(pos != NULL) {
+                                       snprintf(p, MIN(pos-cur->uname_s.nodename+1, p_max_size), "%s", cur->uname_s.nodename);
+                               } else {
+                                       snprintf(p, p_max_size, "%s", cur->uname_s.nodename);
+                               }
+                       }
                        OBJ(outlinecolor) {
                                new_outline(p, obj->data.l);
                        }
@@ -1645,6 +1570,13 @@ void generate_text_internal(char *p, int p_max_size,
                                obj->data.s = buf;
                                print_pid_exe(obj, p, p_max_size);
                        }
+                       OBJ(pid_nice) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_nice(obj, p, p_max_size);
+                       }
                        OBJ(pid_openfiles) {
                                char buf[max_user_text];
 
@@ -1659,6 +1591,13 @@ void generate_text_internal(char *p, int p_max_size,
                                obj->data.s = buf;
                                print_pid_parent(obj, p, p_max_size);
                        }
+                       OBJ(pid_priority) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_priority(obj, p, p_max_size);
+                       }
                        OBJ(pid_state) {
                                char buf[max_user_text];
 
@@ -1694,6 +1633,41 @@ void generate_text_internal(char *p, int p_max_size,
                                obj->data.s = buf;
                                print_pid_stdout(obj, p, p_max_size);
                        }
+                       OBJ(pid_threads) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_threads(obj, p, p_max_size);
+                       }
+                       OBJ(pid_thread_list) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_thread_list(obj, p, p_max_size);
+                       }
+                       OBJ(pid_time_kernelmode) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_time_kernelmode(obj, p, p_max_size);
+                       }
+                       OBJ(pid_time_usermode) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_time_usermode(obj, p, p_max_size);
+                       }
+                       OBJ(pid_time) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_time(obj, p, p_max_size);
+                       }
                        OBJ(pid_uid) {
                                char buf[max_user_text];
 
@@ -1750,12 +1724,99 @@ void generate_text_internal(char *p, int p_max_size,
                                obj->data.s = buf;
                                print_pid_fsgid(obj, p, p_max_size);
                        }
+                       OBJ(pid_read) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_read(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmpeak) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmpeak(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmsize) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmsize(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmlck) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmlck(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmhwm) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmhwm(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmrss) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmrss(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmdata) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmdata(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmstk) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmstk(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmexe) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmexe(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmlib) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmlib(obj, p, p_max_size);
+                       }
+                       OBJ(pid_vmpte) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_vmpte(obj, p, p_max_size);
+                       }
+                       OBJ(pid_write) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_pid_write(obj, p, p_max_size);
+                       }
                        OBJ(processes) {
                                spaced_print(p, p_max_size, "%hu", 4, cur->procs);
                        }
                        OBJ(running_processes) {
                                spaced_print(p, p_max_size, "%hu", 4, cur->run_procs);
                        }
+                       OBJ(running_threads) {
+                               spaced_print(p, p_max_size, "%hu", 4, cur->run_threads);
+                       }
                        OBJ(threads) {
                                spaced_print(p, p_max_size, "%hu", 4, cur->threads);
                        }
@@ -1787,12 +1848,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);
@@ -1812,6 +1868,20 @@ void generate_text_internal(char *p, int p_max_size,
                        OBJ(totalup) {
                                print_totalup(obj, p, p_max_size);
                        }
+                       OBJ(gid_name) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_gid_name(obj, p, p_max_size);
+                       }
+                       OBJ(uid_name) {
+                               char buf[max_user_text];
+
+                               generate_text_internal(buf, max_user_text, *obj->sub, cur);
+                               obj->data.s = buf;
+                               print_uid_name(obj, p, p_max_size);
+                       }
                        OBJ(updates) {
                                snprintf(p, p_max_size, "%d", total_updates);
                        }
@@ -1828,7 +1898,7 @@ 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) {
@@ -1881,81 +1951,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) {
-                               format_media_player_time(p, p_max_size, mpd_get_info()->elapsed);
+                               print_mpd_elapsed(obj, p, p_max_size);
                        }
                        OBJ(mpd_length) {
-                               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
@@ -2049,7 +2086,7 @@ void generate_text_internal(char *p, int p_max_size,
                        }
 #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) {
@@ -2134,7 +2171,7 @@ void generate_text_internal(char *p, int p_max_size,
                                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 */
@@ -2162,7 +2199,6 @@ void generate_text_internal(char *p, int p_max_size,
                        /* we have four different types of top (top, top_mem,
                         * top_time and top_io). To avoid having almost-same code four
                         * times, we have this special handler. */
-#ifdef __linux__
                        break;
                        case OBJ_top:
                        case OBJ_top_mem:
@@ -2170,10 +2206,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);
-#endif /* __linux__ */
+                               print_top(obj, p, p_max_size);
                        OBJ(tail) {
                                print_tailhead("tail", obj, p, p_max_size);
                        }
@@ -2181,57 +2214,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) {
@@ -2262,12 +2249,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;
@@ -2279,43 +2261,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) {
@@ -2340,18 +2296,26 @@ void generate_text_internal(char *p, int p_max_size,
                                        }
                                }
                        }
-                       OBJ(to_bytes) {
+                       OBJ(to_bytes) {//commented code is original - not working when input value contains a decimal point
                                char buf[max_user_text];
-                               long long bytes;
+                               //long long bytes;
+                               long double bytes;
                                char unit[16];  // 16 because we can also have long names (like mega-bytes)
 
                                generate_text_internal(buf, max_user_text, *obj->sub, cur);
-                               if(sscanf(buf, "%lli%s", &bytes, unit) == 2 && strlen(unit) < 16){
-                                       if(strncasecmp("b", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes);
-                                       else if(strncasecmp("k", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024);
-                                       else if(strncasecmp("m", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024 * 1024);
-                                       else if(strncasecmp("g", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024 * 1024 * 1024);
-                                       else if(strncasecmp("t", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024 * 1024 * 1024 * 1024);
+//                             if(sscanf(buf, "%lli%s", &bytes, unit) == 2 && strlen(unit) < 16){
+//                                     if(strncasecmp("b", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes);
+//                                     else if(strncasecmp("k", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024);
+//                                     else if(strncasecmp("m", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024 * 1024);
+//                                     else if(strncasecmp("g", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024 * 1024 * 1024);
+//                                     else if(strncasecmp("t", unit, 1) == 0) snprintf(buf, max_user_text, "%lli", bytes * 1024 * 1024 * 1024 * 1024);
+//                             }
+                               if(sscanf(buf, "%Lf%s", &bytes, unit) == 2 && strlen(unit) < 16){
+                                       if(strncasecmp("b", unit, 1) == 0) snprintf(buf, max_user_text, "%Lf", bytes);
+                                       else if(strncasecmp("k", unit, 1) == 0) snprintf(buf, max_user_text, "%Lf", bytes * 1024);
+                                       else if(strncasecmp("m", unit, 1) == 0) snprintf(buf, max_user_text, "%Lf", bytes * 1024 * 1024);
+                                       else if(strncasecmp("g", unit, 1) == 0) snprintf(buf, max_user_text, "%Lf", bytes * 1024 * 1024 * 1024);
+                                       else if(strncasecmp("t", unit, 1) == 0) snprintf(buf, max_user_text, "%Lf", bytes * 1024 * 1024 * 1024 * 1024);
                                }
                                snprintf(p, p_max_size, "%s", buf);
                        }
@@ -2363,7 +2327,7 @@ void generate_text_internal(char *p, int p_max_size,
                        }
 #ifdef NVIDIA
                        OBJ(nvidia) {
-                               print_nvidia_value(obj, display, p, p_max_size);
+                               print_nvidia_value(obj, p, p_max_size);
                        }
 #endif /* NVIDIA */
 #ifdef APCUPSD
@@ -2400,29 +2364,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]);
@@ -2451,9 +2407,10 @@ void generate_text_internal(char *p, int p_max_size,
 #ifdef HAVE_ICONV
                        iconv_convert(&a, buff_in, p, p_max_size);
 #endif /* HAVE_ICONV */
-                       if (obj->type != OBJ_text && obj->type != OBJ_execp && obj->type != OBJ_execpi
+                       if (obj->type == OBJ_execp || obj->type == OBJ_execpi || obj->type
+                                       == OBJ_exec
 #ifdef HAVE_LUA
-                                       && obj->type != OBJ_lua && obj->type != OBJ_lua_parse
+                                       || obj->type == OBJ_lua || obj->type == OBJ_lua_parse
 #endif /* HAVE_LUA */
                                        ) {
                                substitute_newlines(p, a - 2);
@@ -2472,15 +2429,15 @@ void generate_text_internal(char *p, int p_max_size,
 #endif /* X11 */
 }
 
-void evaluate(const char *text, char *buffer)
+void evaluate(const char *text, char *p, int p_max_size)
 {
        struct information *tmp_info;
        struct text_object subroot;
 
        tmp_info = malloc(sizeof(struct information));
        memcpy(tmp_info, &info, sizeof(struct information));
-       parse_conky_vars(&subroot, text, buffer, tmp_info);
-       DBGP("evaluated '%s' to '%s'", text, buffer);
+       parse_conky_vars(&subroot, text, p, p_max_size, tmp_info);
+       DBGP2("evaluated '%s' to '%s'", text, p);
 
        free_text_objects(&subroot, 1);
        free(tmp_info);
@@ -2492,6 +2449,7 @@ static void generate_text(void)
 {
        struct information *cur = &info;
        char *p;
+       unsigned int i, j, k;
 
        special_count = 0;
 
@@ -2508,6 +2466,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;
@@ -2535,7 +2509,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;
 }
@@ -2688,6 +2662,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)
@@ -2736,7 +2712,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;
@@ -2746,7 +2722,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;
        }
@@ -2764,8 +2746,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
@@ -2866,7 +2856,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;
@@ -3117,12 +3108,14 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
                                                                                  );
                                                                }
 #endif /* DEBUG_lol */
-                                                               XSetForeground(display, window.gc, tmpcolour[
-                                                                               (int)((float)(w - 2) - specials[special_index].graph[j] *
-                                                                                       (w - 2) / (float)specials[special_index].graph_scale)
-                                                                               ]);
+                                                                               set_foreground_color(tmpcolour[
+                                                                                               (int)((float)(w - 2) -
+                                                                                                       specials[special_index].graph[j]
+                                                                                                       * (w - 2) /
+                                                                                                       (float)specials[special_index].graph_scale)
+                                                                                               ]);
                                                        } else {
-                                                               XSetForeground(display, window.gc, tmpcolour[colour_idx++]);
+                                                               set_foreground_color(tmpcolour[colour_idx++]);
                                                        }
                                                }
                                                /* this is mugfugly, but it works */
@@ -3161,36 +3154,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;
                                        }
@@ -3488,8 +3494,20 @@ static void clear_text(int exposures)
 {
 #ifdef HAVE_XDBE
        if (use_xdbe) {
-               /* The swap action is XdbeBackground, which clears */
+/*
+                The swap action is XdbeBackground, which clears 
                return;
+*/
+       if (display && window.back_buffer) { // make sure these are !null
+               /* there is some extra space for borders and outlines */
+               XFillRectangle(display, window.back_buffer, window.gc_back,
+                        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);
+       }
+            
+            
        } else
 #endif
        if (display && window.window) { // make sure these are !null
@@ -3554,7 +3572,7 @@ static void main_loop(void)
                if(update_interval_bat != NOBATTERY && update_interval_bat != update_interval_old) {
                        char buf[max_user_text];
 
-                       get_battery_short_status(buf, max_user_text, "BAT0");
+                       get_battery_short_status(buf, max_user_text, "bq27200-0"); //why is this even hardcoded here? oh well.
                        if(buf[0] == 'D') {
                                update_interval = update_interval_bat;
                        } else {
@@ -3627,7 +3645,21 @@ 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);
+                                               fprintf(stderr, PACKAGE_NAME": resizing window to %d x %d\n",window.width,window.height);
+#ifdef HAVE_XDBE
+                                               if (use_xdbe) {
+                                                       XFreePixmap(display, window.back_buffer);
+                                                       window.back_buffer = XCreatePixmap(display, window.window,
+                                                                                                                          window.width, window.height, window.depth);
+                                                       if (window.back_buffer != None)
+                                                               window.drawable = window.back_buffer;
+                                                       else {
+                                                               window.drawable = window.window;
+                                                               use_xdbe = 0;
+                                                       }
+                                               }
+#endif
+                                               set_transparent_background(window.window, own_window_argb_value);
 #ifdef HAVE_XDBE
                                                /* swap buffers */
                                                xdbe_swap_buffers();
@@ -3727,9 +3759,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;
 
@@ -3752,7 +3784,21 @@ static void main_loop(void)
                                                                                        window.window, &attrs)) {
                                                                                window.width = attrs.width;
                                                                                window.height = attrs.height;
+                                                                               fprintf(stderr, PACKAGE_NAME": x11? resized our window to %d x %d\n",window.width,window.height);
                                                                        }
+#ifdef HAVE_XDBE
+                                                                       if (use_xdbe) {
+                                                                               XFreePixmap(display, window.back_buffer);
+                                                                               window.back_buffer = XCreatePixmap(display, window.window,
+                                                                                                                                                  window.width, window.height, window.depth);
+                                                                               if (window.back_buffer != None)
+                                                                                       window.drawable = window.back_buffer;
+                                                                               else {
+                                                                                       window.drawable = window.window;
+                                                                                       use_xdbe = 0;
+                                                                               }
+                                                                       }
+#endif
                                                                }
 
                                                                text_width = window.width - window.border_inner_margin * 2 - window.border_outer_margin * 2 - window.border_width * 2;
@@ -3786,6 +3832,17 @@ static void main_loop(void)
                                                                        window.type == TYPE_DESKTOP) {
                                                                /* allow conky to hold input focus. */
                                                                break;
+                                                       } else if(TEST_HINT(window.hints,HINT_FULLSCREEN)) {
+                                                               //detect top right click
+                                                               if (ev.xbutton.x > 750 && ev.xbutton.y < 50)
+                                                               {
+                                                                       terminate = 1;
+                                                               }
+                                                               if (ev.xbutton.x <= 50 && ev.xbutton.y <= 50)
+                                                               {       //minimize / goto task switcher
+                                                                       dbus_exit_app_view();
+                                                               }
+                                                               break;
                                                        } else {
                                                                /* forward the click to the desktop window */
                                                                XUngrabPointer(display, ev.xbutton.time);
@@ -3871,6 +3928,7 @@ static void main_loop(void)
                } else {
 #endif /* X11 */
                        t = (next_update_time - get_time()) * 1000000;
+                       fprintf(stderr, PACKAGE_NAME": trying to sleep %d microseconds\n",t);
                        if(t > 0) usleep((useconds_t)t);
                        update_text();
                        draw_stuff();
@@ -3936,12 +3994,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;
@@ -3968,6 +4026,7 @@ static void main_loop(void)
                                                                        current_config,
                                                                        IN_MODIFY);
                                                }
+                                               break;
                                        }
 #ifdef HAVE_LUA
                                        else {
@@ -3977,6 +4036,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 */
 
@@ -3985,7 +4048,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) {
@@ -4006,12 +4069,44 @@ 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);
 }
 
-void clean_up(void *memtofree1, void* memtofree2)
+#ifdef X11
+void clean_up_x11(void)
 {
+       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();
+       fonts = NULL;
+       if(x11_stuff.region) {
+               XDestroyRegion(x11_stuff.region);
+               x11_stuff.region = NULL;
+       }
+       if(display) {
+               XCloseDisplay(display);
+               display = NULL;
+       }
+       if(info.x11.desktop.all_names) {
+               free(info.x11.desktop.all_names);
+               info.x11.desktop.all_names = NULL;
+       }
+       if (info.x11.desktop.name) {
+               free(info.x11.desktop.name);
+               info.x11.desktop.name = NULL;
+       }
+       x_initialised = NO;
+}
+#endif
+
+void clean_up_without_threads(void *memtofree1, void* memtofree2) {
        int i;
 
 #ifdef NCURSES
@@ -4035,36 +4130,17 @@ 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);
-               destroy_window();
-               free_fonts();
-               if(x11_stuff.region) {
-                       XDestroyRegion(x11_stuff.region);
-                       x11_stuff.region = NULL;
-               }
-               XCloseDisplay(display);
-               display = NULL;
-               if(info.x11.desktop.all_names) {
-                       free(info.x11.desktop.all_names);
-                       info.x11.desktop.all_names = NULL;
-               }
-               if (info.x11.desktop.name) {
-                       free(info.x11.desktop.name);
-                       info.x11.desktop.name = NULL;
-               }
-               x_initialised = NO;
+               clean_up_x11();
        }else{
                free(fonts);    //in set_default_configurations a font is set but not loaded
                font_count = -1;
        }
 
+#ifdef NVIDIA
+       set_nvidia_display(NULL);
+#endif
 #endif /* X11 */
 
-       free_update_callbacks();
-
        free_templates();
 
        free_text_objects(&global_root_object, 0);
@@ -4131,6 +4207,12 @@ void clean_up(void *memtofree1, void* memtofree2)
        }
 }
 
+void clean_up(void *memtofree1, void* memtofree2)
+{
+       free_update_callbacks();
+       clean_up_without_threads(memtofree1, memtofree2);
+}
+
 static int string_to_bool(const char *s)
 {
        if (!s) {
@@ -4188,7 +4270,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 */
 
@@ -4234,9 +4316,7 @@ static void set_default_configurations(void)
 #ifdef IOSTATS
        top_io = 0;
 #endif
-#ifdef __linux__
        top_running = 0;
-#endif
 #ifdef MPD
        mpd_env_host = getenv("MPD_HOST");
        mpd_env_port = getenv("MPD_PORT");
@@ -4286,6 +4366,9 @@ static void set_default_configurations(void)
        output_methods = TO_STDOUT;
 #endif
 #ifdef X11
+#ifdef BUILD_XFT
+       use_xft = 0;
+#endif
        show_graph_scale = 0;
        show_graph_range = 0;
        draw_shades = 1;
@@ -4304,6 +4387,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;
@@ -4312,11 +4399,11 @@ static void set_default_configurations(void)
        text_alignment = BOTTOM_LEFT;
        info.x11.monitor.number = 1;
        info.x11.monitor.current = 0;
-       info.x11.desktop.current = 1; 
+       info.x11.desktop.current = 1;
        info.x11.desktop.number = 1;
        info.x11.desktop.nitems = 0;
-       info.x11.desktop.all_names = NULL; 
-       info.x11.desktop.name = NULL; 
+       info.x11.desktop.all_names = NULL;
+       info.x11.desktop.name = NULL;
 #endif /* X11 */
 
        free_templates();
@@ -4338,6 +4425,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);
@@ -4393,7 +4482,7 @@ int x11_ioerror_handler(Display *d)
        NORM_ERR("X Error: Display %lx\n",
                        (long unsigned)d
                        );
-       abort();
+       exit(1);
 }
 #endif /* DEBUG */
 
@@ -4437,7 +4526,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
 
@@ -4535,6 +4624,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;
@@ -4557,15 +4669,12 @@ char load_config_file(const char *f)
 
 #ifdef X11
                CONF2("out_to_x") {
-                       /* don't listen if X is already initialised or
-                        * if we already know we don't want it */
-                       if(x_initialised != YES) {
-                               if (string_to_bool(value)) {
-                                       output_methods &= TO_X;
-                               } else {
-                                       output_methods &= ~TO_X;
-                                       x_initialised = NEVER;
-                               }
+                       if (string_to_bool(value)) {
+                               output_methods &= TO_X;
+                       } else {
+                               clean_up_x11();
+                               output_methods &= ~TO_X;
+                               x_initialised = NEVER;
                        }
                }
                CONF("display") {
@@ -4577,23 +4686,14 @@ char load_config_file(const char *f)
                                disp = strdup(value);
                        }
                }
+#ifdef NVIDIA
+               CONF("nvidia_display") {
+                       if(value)
+                               set_nvidia_display(value);
+               }
+#endif
                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);
@@ -4629,7 +4729,7 @@ char load_config_file(const char *f)
                CONF("border_width") {
                        if (value) {
                                window.border_width = strtol(value, 0, 0);
-                               if (window.border_width < 0) window.border_width = 0;
+                               if (window.border_width < 1) window.border_width = 1;
                        } else {
                                CONF_ERR;
                        }
@@ -4801,6 +4901,12 @@ char load_config_file(const char *f)
                        draw_outline = string_to_bool(value);
                }
 #endif /* X11 */
+               CONF("times_in_seconds") {
+                       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)) {
                                output_methods |= TO_STDOUT;
@@ -4811,6 +4917,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;
@@ -4968,16 +5077,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);
@@ -5043,8 +5144,8 @@ char load_config_file(const char *f)
                                                        SET_HINT(window.hints, HINT_STICKY);
                                                } else if (strncmp(p_hint, "skip_taskbar", 12) == EQUAL) {
                                                        SET_HINT(window.hints, HINT_SKIP_TASKBAR);
-                                               } else if (strncmp(p_hint, "skip_pager", 10) == EQUAL) {
-                                                       SET_HINT(window.hints, HINT_SKIP_PAGER);
+                                               } else if (strncmp(p_hint, "fullscreen", 10) == EQUAL) {
+                                                       SET_HINT(window.hints, HINT_FULLSCREEN);
                                                } else {
                                                        CONF_ERR;
                                                }
@@ -5076,6 +5177,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) {
@@ -5570,6 +5682,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
@@ -5589,15 +5702,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);
 
@@ -5632,6 +5794,7 @@ void initialisation(int argc, char **argv) {
                        "kvm_open")) == NULL) {
                CRIT_ERR(NULL, NULL, "cannot read kvm");
        }
+       pthread_mutex_init(&kvm_proc_mutex, NULL);
 #endif
 
        while (1) {
@@ -5654,7 +5817,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
@@ -5699,8 +5862,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 '?':
@@ -5723,7 +5888,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) {
@@ -5811,6 +5976,11 @@ int main(int argc, char **argv)
        tcp_portmon_set_max_connections(0);
 #endif
 
+#ifdef HAVE_CURL
+       if(curl_global_init(CURL_GLOBAL_ALL))
+               NORM_ERR("curl_global_init() failed, you may not be able to use curl variables");
+#endif
+
        /* handle command line parameters that don't change configs */
 #ifdef X11
        if (((s = getenv("LC_ALL")) && *s) || ((s = getenv("LC_CTYPE")) && *s)
@@ -5851,7 +6021,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]);
@@ -5877,48 +6049,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 */
@@ -5926,15 +6057,28 @@ int main(int argc, char **argv)
 #endif /* XOAP */
 
 #ifdef HAVE_SYS_INOTIFY_H
-       inotify_fd = inotify_init1(IN_NONBLOCK);
+       inotify_fd = inotify_init();
+       if(inotify_fd != -1) {
+               int fl;
+
+               fl = fcntl(inotify_fd, F_GETFL);
+               fcntl(inotify_fd, F_SETFL, fl | O_NONBLOCK);
+       }
 #endif /* HAVE_SYS_INOTIFY_H */
 
        initialisation(argc, argv);
 
+       first_pass = 0; /* don't ever call fork() again */
+
        main_loop();
 
+#ifdef HAVE_CURL
+       curl_global_cleanup();
+#endif
+
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        kvm_close(kd);
+       pthread_mutex_destroy(&kvm_proc_mutex);
 #endif
 
        return 0;
@@ -5951,7 +6095,7 @@ static void signal_handler(int sig)
 {
        /* signal handler is light as a feather, as it should be.
         * we will poll g_signal_pending with each loop of conky
-        * and do any signal processing there, NOT here (except 
+        * and do any signal processing there, NOT here (except
         * SIGALRM because this is caused when conky is hanging) */
        if(sig == SIGALRM) {
                alarm_handler();