Fixed small bug in config parsing (thanks robgrady, bug 1306032)
[monky] / src / conky.c
index d44ea07..3342d50 100644 (file)
@@ -17,6 +17,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <pthread.h>
 #include <string.h>
 #include <limits.h>
 #if HAVE_DIRENT_H
@@ -384,7 +385,7 @@ static int special_count;
 static int special_index;      /* used when drawing */
 #endif /* X11 */
 
-#define MAX_GRAPH_DEPTH 256    /* why 256? who knows. */
+#define MAX_GRAPH_DEPTH 256    /* why 256? cause an array of more then 256 doubles seems excessive, and who needs that kind of precision anyway? */
 
 static struct special_t *new_special(char *buf, int t)
 {
@@ -393,18 +394,6 @@ static struct special_t *new_special(char *buf, int t)
 
        buf[0] = SPECIAL_CHAR;
        buf[1] = '\0';
-       if (t == GRAPH && specials[special_count].graph == NULL) {
-               if (specials[special_count].width > 0
-                   && specials[special_count].width < MAX_GRAPH_DEPTH)
-                       specials[special_count].graph_width = specials[special_count].width - 3;        // subtract 3 for the box
-               else
-                       specials[special_count].graph_width =
-                           MAX_GRAPH_DEPTH;
-               specials[special_count].graph =
-                   calloc(specials[special_count].graph_width,
-                          sizeof(double));
-               specials[special_count].graph_scale = 100;
-       }
        specials[special_count].type = t;
        return &specials[special_count++];
 }
@@ -523,21 +512,56 @@ inline void graph_append(struct special_t *graph, double f)
        }
 }
 
+short colour_depth = 0;
+void set_up_gradient();
+
+/* precalculated: 31/255, and 63/255 */
+#define CONST_8_TO_5_BITS 0.12156862745098
+#define CONST_8_TO_6_BITS 0.247058823529412
+
+/* adjust color values depending on color depth*/
+static unsigned int adjust_colors(unsigned int color)
+{
+       double r, g, b;
+       if (colour_depth == 0) {
+               set_up_gradient();
+       }
+       if (colour_depth == 16) {
+               r = (color & 0xff0000) >> 16;
+               g = (color & 0xff00) >> 8;
+               b =  color & 0xff;
+               color  = (int)(r * CONST_8_TO_5_BITS) << 11;
+               color |= (int)(g * CONST_8_TO_6_BITS) << 5;
+               color |= (int)(b * CONST_8_TO_5_BITS);
+       }
+       return color;
+}
+
 static void new_graph(char *buf, int w, int h, unsigned int first_colour, unsigned int second_colour, double i, int scale, int append)
 {
        struct special_t *s = new_special(buf, GRAPH);
        s->width = w;
+       if (s->graph == NULL) {
+               if (s->width > 0 && s->width < MAX_GRAPH_DEPTH) {
+                       s->graph_width = s->width - 3;  // subtract 3 for the box
+               } else {
+                       s->graph_width = MAX_GRAPH_DEPTH - 3;
+               }
+               s->graph = malloc(s->graph_width * sizeof(double));
+               memset(s->graph, 0, s->graph_width * sizeof(double));
+               s->graph_scale = 100;
+       }
        s->height = h;
-       s->first_colour = first_colour;
-       s->last_colour = second_colour;
+       s->first_colour = adjust_colors(first_colour);
+       s->last_colour = adjust_colors(second_colour);
        if (scale != 0) {
                s->scaled = 0;
        } else {
                s->scaled = 1;
        }
-       if (s->width) {
+       /*if (s->width) {
                s->graph_width = s->width - 3;  // subtract 3 for rectangle around
-       }
+       }*/
        if (s->scaled) {
                s->graph_scale = 1;
        } else {
@@ -725,6 +749,7 @@ enum text_object_type {
        OBJ_endif,
        OBJ_exec,
        OBJ_execi,
+       OBJ_texeci,
        OBJ_execbar,
        OBJ_execgraph,
        OBJ_execibar,
@@ -746,6 +771,7 @@ enum text_object_type {
        OBJ_alignr,
        OBJ_alignc,
        OBJ_i2c,
+#if defined(__linux__)
        OBJ_i8k_version,
        OBJ_i8k_bios,
        OBJ_i8k_serial,
@@ -757,6 +783,7 @@ enum text_object_type {
        OBJ_i8k_right_fan_rpm,
        OBJ_i8k_ac_status,      
        OBJ_i8k_buttons_status,
+#endif /* __linux__ */
        OBJ_if_existing,
        OBJ_if_mounted,
        OBJ_if_running,
@@ -817,6 +844,11 @@ enum text_object_type {
        OBJ_upspeedgraph,
        OBJ_uptime,
        OBJ_uptime_short,
+#ifdef __FreeBSD__
+       OBJ_apm_adapter,
+       OBJ_apm_battery_time,
+       OBJ_apm_battery_life,
+#endif /* __FreeBSD__ */
 #ifdef SETI
        OBJ_seti_prog,
        OBJ_seti_progbar,
@@ -851,7 +883,7 @@ struct text_object {
                struct fs_stat *fs;
                unsigned char loadavg[3];
                //unsigned int diskio;
-
+               unsigned int cpu_index;
                struct {
                        struct fs_stat *fs;
                        int w, h;
@@ -903,6 +935,27 @@ struct text_object {
 static unsigned int text_object_count;
 static struct text_object *text_objects;
 
+pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
+
+void *threaded_exec( struct text_object *obj ) {
+       char *p2 = obj->data.execi.buffer;
+       FILE *fp = popen(obj->data.execi.cmd,"r");
+       pthread_mutex_lock( &mutex1 );
+       int n2 = fread(p2, 1, TEXT_BUFFER_SIZE, fp);
+       (void) pclose(fp);      
+       p2[n2] = '\0';
+       if (n2 && p2[n2 - 1] == '\n')
+               p2[n2 - 1] = '\0';
+       
+       while (*p2) {
+               if (*p2 == '\001')
+                       *p2 = ' ';
+               p2++;
+       }
+       pthread_mutex_unlock( &mutex1 );
+       return NULL;
+}
+
 /* new_text_object() allocates a new zeroed text_object */
 static struct text_object *new_text_object()
 {
@@ -973,6 +1026,10 @@ static void free_text_objects()
                        free(text_objects[i].data.execi.cmd);
                        free(text_objects[i].data.execi.buffer);
                        break;
+               case OBJ_texeci:
+                       free(text_objects[i].data.execi.cmd);
+                       free(text_objects[i].data.execi.buffer);
+                       break;
                }
        }
 
@@ -1024,24 +1081,53 @@ if (s[0] == '#') {
        else
                strcpy(bat, "BAT0");
        obj->data.s = strdup(bat);
+#if defined(__linux__)
        END OBJ(i8k_version, INFO_I8K)
        END OBJ(i8k_bios, INFO_I8K)
        END OBJ(i8k_serial, INFO_I8K)
        END OBJ(i8k_cpu_temp, INFO_I8K)
        END OBJ(i8k_cpu_tempf, INFO_I8K)
        END OBJ(i8k_left_fan_status, INFO_I8K)  
-  END OBJ(i8k_right_fan_status, INFO_I8K)
+       END OBJ(i8k_right_fan_status, INFO_I8K)
        END OBJ(i8k_left_fan_rpm, INFO_I8K)
        END OBJ(i8k_right_fan_rpm, INFO_I8K)
        END OBJ(i8k_ac_status, INFO_I8K)
        END OBJ(i8k_buttons_status, INFO_I8K)
+#endif /* __linux__ */
        END OBJ(buffers, INFO_BUFFERS)
        END OBJ(cached, INFO_BUFFERS)
        END OBJ(cpu, INFO_CPU)
+               if (arg) {
+               if (strncmp(arg, "cpu", 3) == 0 && isdigit(arg[3])) {
+                       obj->data.cpu_index = atoi(&arg[3]);
+                       arg += 4;
+               } else {obj->data.cpu_index = 0; }
+               } else {
+                               obj->data.cpu_index = 0;
+                       }
        END OBJ(cpubar, INFO_CPU)
-        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+               if (arg) {
+               if (strncmp(arg, "cpu", 3) == 0 && isdigit(arg[3])) {
+                       obj->data.cpu_index = atoi(&arg[3]);
+                       arg += 4;
+               }
+               else {obj->data.cpu_index = 0;}
+               (void) scan_bar(arg, &obj->a, &obj->b);
+               } else {
+                               (void) scan_bar(arg, &obj->a, &obj->b);
+                               obj->data.cpu_index = 0;
+                       }
        END OBJ(cpugraph, INFO_CPU)
-                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
+                       if (arg) {
+               if (strncmp(arg, "cpu", 3) == 0 && isdigit(arg[3])) {
+                       obj->data.cpu_index = atoi(&arg[3]);
+                       arg += 4;
+               }
+                               (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
+                       } else {
+       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
+       obj->data.cpu_index = 0;
+                       }
        END OBJ(diskio, INFO_DISKIO)
        END OBJ(diskiograph, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
        END OBJ(color, 0) 
@@ -1052,8 +1138,20 @@ if (s[0] == '#') {
        OBJ(font, 0)
                        obj->data.s = scan_font(arg);
        END
-                       OBJ(downspeed, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(downspeedf, INFO_NET) obj->data.net = get_net_stat(arg);
+               OBJ(downspeed, INFO_NET) 
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("downspeed needs argument");
+               }
+       END OBJ(downspeedf, INFO_NET)
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("downspeedf needs argument");
+               }
        END OBJ(downspeedgraph, INFO_NET)
                        (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
        char buf[64];
@@ -1123,6 +1221,20 @@ if (s[0] == '#') {
                obj->data.execi.buffer =
                    (char *) calloc(1, TEXT_BUFFER_SIZE);
        }
+       END OBJ(texeci, 0) unsigned int n;
+
+       if (!arg
+                   || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
+               char buf[256];
+               ERR("${texeci <interval> command}");
+               obj->type = OBJ_text;
+               snprintf(buf, 256, "${%s}", s);
+               obj->data.s = strdup(buf);
+                   } else {
+                           obj->data.execi.cmd = strdup(arg + n);
+                           obj->data.execi.buffer =
+                                           (char *) calloc(1, TEXT_BUFFER_SIZE);
+                   }
        END OBJ(pre_exec, 0) obj->type = OBJ_text;
        if (arg) {
                FILE *fp = popen(arg, "r");
@@ -1184,7 +1296,7 @@ if (s[0] == '#') {
        if (!arg) {
                ERR("i2c needs arguments");
                obj->type = OBJ_text;
-               obj->data.s = strdup("${i2c}");
+               //obj->data.s = strdup("${i2c}");
                return;
        }
 
@@ -1195,12 +1307,12 @@ if (s[0] == '#') {
                obj->data.i2c.fd =
                    open_i2c_sensor(0, buf2, n, &obj->data.i2c.arg,
                                    obj->data.i2c.devtype);
-               strcpy(obj->data.i2c.type, buf2);
+               strncpy(obj->data.i2c.type, buf2, 63);
        } else {
                obj->data.i2c.fd =
                    open_i2c_sensor(buf1, buf2, n, &obj->data.i2c.arg,
                                    obj->data.i2c.devtype);
-               strcpy(obj->data.i2c.type, buf2);
+               strncpy(obj->data.i2c.type, buf2, 63);
        }
 
        END OBJ(top, INFO_TOP)
@@ -1209,7 +1321,7 @@ if (s[0] == '#') {
        if (!arg) {
                ERR("top needs arguments");
                obj->type = OBJ_text;
-               obj->data.s = strdup("${top}");
+               //obj->data.s = strdup("${top}");
                return;
        }
        if (sscanf(arg, "%63s %i", buf, &n) == 2) {
@@ -1269,8 +1381,20 @@ if (s[0] == '#') {
                ERR("invalid args given for top");
                return;
        }
-       END OBJ(addr, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(linkstatus, INFO_WIFI) obj->data.net = get_net_stat(arg);
+       END OBJ(addr, INFO_NET)
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("addr needs argument");
+               }
+       END OBJ(linkstatus, INFO_WIFI) 
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("linkstatus needs argument");
+               }
        END OBJ(tail, 0)
        char buf[64];
        int n1, n2;
@@ -1517,13 +1641,38 @@ int a = stippled_borders, b = 1;
                            obj->data.i2c.devtype);
        END OBJ(time, 0) obj->data.s = strdup(arg ? arg : "%F %T");
        END OBJ(utime, 0) obj->data.s = strdup(arg ? arg : "%F %T");
-       END OBJ(totaldown, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(totaldown, INFO_NET)
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("totaldown needs argument");
+               }
        END OBJ(totalup, INFO_NET) obj->data.net = get_net_stat(arg);
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("totalup needs argument");
+               }
        END OBJ(updates, 0)
        END OBJ(alignr, 0) obj->data.i = arg ? atoi(arg) : 0;
        END OBJ(alignc, 0) obj->data.i = arg ? atoi(arg) : 0;
-       END OBJ(upspeed, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(upspeedf, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(upspeed, INFO_NET)
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("upspeed needs argument");
+               }
+       END OBJ(upspeedf, INFO_NET) 
+               if(arg) {
+                       obj->data.net = get_net_stat(arg);
+               }
+               else {
+                       CRIT_ERR("upspeedf needs argument");
+               }
+
        END OBJ(upspeedgraph, INFO_NET)
                        (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
        char buf[64];
@@ -1537,6 +1686,11 @@ int a = stippled_borders, b = 1;
        }
        END OBJ(uptime_short, INFO_UPTIME) END OBJ(uptime, INFO_UPTIME) END
            OBJ(adt746xcpu, 0) END OBJ(adt746xfan, 0) END
+#ifdef __FreeBSD__
+       OBJ(apm_adapter, 0) END
+       OBJ(apm_battery_life, 0) END
+       OBJ(apm_battery_time, 0) END
+#endif /* __FreeBSD__ */
 #ifdef SETI
         OBJ(seti_prog, INFO_SETI) END OBJ(seti_progbar, INFO_SETI)
         (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
@@ -1770,30 +1924,35 @@ static void generate_text()
                                human_readable(cur->cached * 1024, p, 255);
                        }
                        OBJ(cpu) {
+                               if (obj->data.cpu_index > info.cpu_count) {
+                                       printf("obj->data.cpu_index %i info.cpu_count %i", obj->data.cpu_index, info.cpu_count);
+                                       CRIT_ERR("attempting to use more CPUs then you have!");
+                               }
                                if (!use_spacer)
                                        snprintf(p, n, "%*d", pad_percents,
-                                                (int) (cur->cpu_usage *
+                                               (int) round_to_int(cur->cpu_usage[obj->data.cpu_index] *
                                                        100.0));
                                else
                                        snprintf(p, 4, "%*d    ",
                                                 pad_percents,
-                                                (int) (cur->cpu_usage *
+                                                (int) round_to_int(cur->cpu_usage[obj->data.cpu_index] *
                                                        100.0));
                        }
                        OBJ(cpubar) {
-                               new_bar(p, obj->data.pair.a,
-                                       obj->data.pair.b,
-                                       (int) (cur->cpu_usage * 255.0));
+                               new_bar(p, obj->a,
+                                       obj->b,
+                                       (int) round_to_int(cur->cpu_usage[obj->data.cpu_index] * 255.0));
                        }
                        OBJ(cpugraph) {
                                new_graph(p, obj->a,
                                          obj->b, obj->c, obj->d,
-                                         (unsigned int) (cur->cpu_usage *
+                                         (unsigned int) round_to_int(cur->cpu_usage[obj->data.cpu_index] *
                                                          100), 100, 1);
                        }
                        OBJ(color) {
                                new_fg(p, obj->data.l);
                        }
+#if defined(__linux__)
                        OBJ(i8k_version) {
                                snprintf(p, n, "%s", i8k.version);
                        }
@@ -1855,7 +2014,7 @@ static void generate_text()
                                snprintf(p, n, "%s", i8k.buttons_status); 
 
                        }
-
+#endif /* __linux__ */
 
 #ifdef X11
                        OBJ(font) {
@@ -2120,6 +2279,25 @@ static void generate_text()
                                            current_update_time;
                                }
                        }
+                       OBJ(texeci) {
+                               static int running = 0;
+                               if (current_update_time - obj->data.execi.last_update < obj->data.execi.interval) {
+                                       snprintf(p, n, "%s", obj->data.execi.buffer);
+                               } else {
+                                       static pthread_t execthread;
+                                       if (!running) {
+                                               running = 1;
+                                               pthread_create( &execthread, NULL, (void*)threaded_exec, (void*) obj);
+                                               pthread_mutex_lock( &mutex1 );
+                                               obj->data.execi.last_update = current_update_time;
+                                               pthread_mutex_unlock( &mutex1 );
+                                       } else {
+                                               pthread_join( execthread, NULL);
+                                               running = 0;
+                                       }
+                                       snprintf(p, n, "%s", obj->data.execi.buffer);
+                               }
+                       }
 #endif
                        OBJ(fs_bar) {
                                if (obj->data.fs != NULL) {
@@ -2535,6 +2713,23 @@ static void generate_text()
                                format_seconds(p, n, (int) cur->uptime);
                        }
 
+#ifdef __FreeBSD__
+                       OBJ(apm_adapter) {
+                               snprintf(p, n, "%s", get_apm_adapter());
+                       }
+                       OBJ(apm_battery_life) {
+                               char    *msg;
+                               msg = get_apm_battery_life();
+                               snprintf(p, n, "%s", msg);
+                               free(msg);
+                       }
+                       OBJ(apm_battery_time) {
+                               char    *msg;
+                               msg = get_apm_battery_time();
+                               snprintf(p, n, "%s", msg);
+                               free(msg);
+                       }
+#endif /* __FreeBSD__ */
 #ifdef SETI
                        OBJ(seti_prog) {
                                snprintf(p, n, "%.2f",
@@ -2587,11 +2782,11 @@ static void generate_text()
                                }
                                seconds = tmp;
                                if (days > 0)
-                                       snprintf(p, n, "%i days %i:%i:%2i",
+                                       snprintf(p, n, "%i days %i:%02i:%02i",
                                                 days, hours, minutes,
                                                 seconds);
-                               else if (days > 0)
-                                       snprintf(p, n, "%i:%i:%02i", hours,
+                               else if (hours > 0)
+                                       snprintf(p, n, "%i:%02i:%02i", hours,
                                                 minutes, seconds);
                                else
                                        snprintf(p, n, "%i:%02i", minutes,
@@ -2616,11 +2811,11 @@ static void generate_text()
                                seconds = tmp;
                                if (days > 0)
                                        snprintf(p, n,
-                                                "%i days %i:%i:%02i",
+                                                "%i days %i:%02i:%02i",
                                                 days, hours, minutes,
                                                 seconds);
-                               else if (days > 0)
-                                       snprintf(p, n, "%i:%i:%02i", hours,
+                               else if (hours > 0)
+                                       snprintf(p, n, "%i:%02i:%02i", hours,
                                                 minutes, seconds);
                                else
                                        snprintf(p, n, "%i:%02i", minutes,
@@ -2722,7 +2917,7 @@ static void generate_text()
                                        else {
                                                obj->data.tail.readlines = 0;
 
-                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*4, fp) != NULL) {
+                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*20, fp) != NULL) {
                                                        if (added >= 30) {
                                                                freelasttail(head);
                                                        }
@@ -2747,7 +2942,7 @@ static void generate_text()
                                                        headtmp = headtmp->next;
                                                        for (i = 1;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
                                                                if (headtmp) {
-                                                                       strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 20 / obj->data.tail.wantedlines) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
+                                                                       strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 20) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
                                                                        headtmp = headtmp->next;
                                                                }
                                                        }
@@ -2782,7 +2977,7 @@ static void generate_text()
                                        }
                                        else {
                                                obj->data.tail.readlines = 0;
-                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*4, fp) != NULL && obj->data.tail.readlines <= obj->data.tail.wantedlines) {
+                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*20, fp) != NULL && obj->data.tail.readlines <= obj->data.tail.wantedlines) {
                                                        addtail(&head, obj->data.tail.buffer);
                                                        obj->data.tail.readlines++;
                                                }
@@ -2798,7 +2993,7 @@ static void generate_text()
                                                        strcpy(obj->data.tail.buffer, headtmp->data);
                                                        headtmp = headtmp->next;
                                                        while (headtmp) {
-                                                               strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 20 / obj->data.tail.wantedlines) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
+                                                               strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 20) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
                                                                headtmp = headtmp->next;
                                                        }
                                                        freetail(freetmp);
@@ -2846,8 +3041,9 @@ static void set_font()
 {
 #ifdef XFT
        if (use_xft) {
-                       if (window.xftdraw != NULL)
+                       if (window.xftdraw != NULL) {
                                XftDrawDestroy(window.xftdraw);
+                       }
                        window.xftdraw = XftDrawCreate(display, window.drawable,
                                        DefaultVisual(display,
                                                        screen),
@@ -3111,12 +3307,14 @@ static void draw_string(const char *s)
                        }
                }
        }
+#ifdef X11
        if (text_width == maximum_width) {
                /* this means the text is probably pushing the limit, so we'll chop it */
                while (cur_x + get_string_width(tmpstring2) - text_start_x > maximum_width && strlen(tmpstring2) > 0) {
                        tmpstring2[strlen(tmpstring2)-1] = '\0';
                }
        }
+#endif /* X11 */
        s = tmpstring2;
 #ifdef X11
 #ifdef XFT
@@ -3152,7 +3350,6 @@ static void draw_string(const char *s)
 }
 
 long redmask, greenmask, bluemask;
-short colour_depth = 0;
 
 void set_up_gradient()
 {
@@ -3334,7 +3531,7 @@ static void draw_line(char *s)
 
                        case BAR:
                                {
-                                       if (cur_x > maximum_width - text_start_x && maximum_width > 0) {
+                                       if (cur_x - text_start_x > maximum_width && maximum_width > 0) {
                                                break;
                                        }
                                        int h =
@@ -3390,7 +3587,7 @@ static void draw_line(char *s)
 
                        case GRAPH:
                        {
-                                       if (cur_x > maximum_width - text_start_x && maximum_width > 0) {
+                                       if (cur_x - text_start_x > maximum_width && maximum_width > 0) {
                                                break;
                                        }
                                        int h =
@@ -3476,7 +3673,7 @@ static void draw_line(char *s)
                                        selected_font = specials[special_index].font_added;
                                        cur_y += font_ascent();
 #ifdef XFT
-                                       if (!use_xft)
+                                       if (!use_xft || use_xdbe)
 #endif
                                        {
                                                set_font();
@@ -3649,9 +3846,11 @@ static void draw_stuff()
 static void clear_text(int exposures)
 {
 #ifdef XDBE
-       if (use_xdbe)
+       if (use_xdbe) {
                return;         /* The swap action is XdbeBackground, which clears */
+       } else
 #endif
+       {
        /* there is some extra space for borders and outlines */
        XClearArea(display, window.drawable,
                   text_start_x - border_margin - 1,
@@ -3659,6 +3858,7 @@ static void clear_text(int exposures)
                   text_width + border_margin * 2 + 2,
                   text_height + border_margin * 2 + 2,
                   exposures ? True : 0);
+       }
 }
 #endif /* X11 */
 
@@ -3724,7 +3924,7 @@ static void main_loop()
                        }
 #ifdef OWN_WINDOW
                        if (own_window) {
-       set_transparent_background(window.window);
+                               set_transparent_background(window.window);
                        }
 #endif
                }
@@ -3800,13 +4000,13 @@ static void main_loop()
                                break;
 
 #ifdef OWN_WINDOW
-                       /*case ReparentNotify:
-                                set background to ParentRelative for all parents 
+                       case ReparentNotify:
+                               /* set background to ParentRelative for all parents */
                                if (own_window) {
                                        set_transparent_background(window.
                                        window);
                                }
-                               break;*/
+                               break;
 
                        case ConfigureNotify:
                                if (own_window) {
@@ -3860,6 +4060,7 @@ static void main_loop()
                                                || ev.xconfigure.y != 0)) {
                                                fixed_pos = 1;
                                }*/
+                                       set_font();
                                }
                                break;
 #endif
@@ -3886,12 +4087,13 @@ static void main_loop()
                                r.width = text_width + border_margin * 2;
                                r.height = text_height + border_margin * 2;
                                XUnionRectWithRegion(&r, region, region);
-                       }
+               }
 #endif
                        XSetRegion(display, window.gc, region);
 #ifdef XFT
-                       if (use_xft)
+                       if (use_xft) {
                                XftDrawSetClip(window.xftdraw, region);
+                       }
 #endif
 #endif /* X11 */
                        draw_stuff();
@@ -3899,14 +4101,9 @@ static void main_loop()
                        XDestroyRegion(region);
                        region = XCreateRegion();
                }
-
-
 #endif /* X11 */
 
        }
-#ifdef X11
-       XDestroyRegion(region);
-#endif /* X11 */
 }
 
 static void load_config_file(const char *);
@@ -3934,8 +4131,9 @@ static void clean_up()
 {
 #ifdef X11
 #ifdef XDBE
-       if (use_xdbe)
+       if (use_xdbe) {
                XdbeDeallocateBackBufferName(display, window.back_buffer);
+       }
 #endif
 #ifdef OWN_WINDOW
        if (own_window)
@@ -4134,7 +4332,7 @@ static void load_config_file(const char *f)
 #define CONF2(a) if (strcasecmp(name, a) == 0)
 #define CONF(a) else CONF2(a)
 #define CONF3(a,b) \
-else if (strcasecmp(name, a) == 0 || strcasecmp(name, a) == 0)
+else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
 
 
 #ifdef X11