X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fconky.c;h=215e79487833807309e2cdb5c3677853b20d5acc;hb=5b112f7a5d8ae68de4b52ac93374c4d68602f1b6;hp=456142a90ff1db39258bbbb0e63f8e3aec9267f2;hpb=c5925930c3a1e42b4b2aabfb4743e4b7f85d1800;p=monky diff --git a/src/conky.c b/src/conky.c index 456142a..215e794 100644 --- a/src/conky.c +++ b/src/conky.c @@ -70,6 +70,9 @@ #ifdef XOAP #include #endif /* XOAP */ +#ifdef HAVE_CURL +#include +#endif /* local headers */ #include "core.h" @@ -166,9 +169,7 @@ int top_cpu, top_mem, top_time; #ifdef IOSTATS int top_io; #endif -#ifdef __linux__ int top_running; -#endif int output_methods; static int extra_newline; enum x_initialiser_state x_initialised = NO; @@ -177,6 +178,10 @@ static volatile int g_signal_pending; double update_interval; double update_interval_old; double update_interval_bat; +int update_heartbeat_battery_skip = 1; +int update_skips_when_sleeping = 5; +int update_heartbeat_min = 0; +int update_heartbeat_max = 0; void *global_cpu = NULL; unsigned int max_text_width = 0; @@ -269,9 +274,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 */ @@ -320,7 +322,8 @@ static int text_width, text_height; /* alignments */ enum alignment { - TOP_LEFT = 1, + ALIGNMENT_ERROR, + TOP_LEFT, TOP_RIGHT, TOP_MIDDLE, BOTTOM_LEFT, @@ -462,7 +465,7 @@ 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; } @@ -511,6 +514,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'; @@ -606,7 +610,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 { @@ -633,11 +637,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 @@ -764,6 +768,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) { @@ -877,6 +883,15 @@ 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_rate) { + get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_RATE); + } OBJ(battery_percent) { percent_print(p, p_max_size, get_battery_perct(obj->data.s)); } @@ -886,6 +901,12 @@ void generate_text_internal(char *p, int p_max_size, 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) { @@ -898,12 +919,12 @@ 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!"); - } 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)); } @@ -1072,10 +1093,10 @@ void generate_text_internal(char *p, int p_max_size, print_diskiograph(obj, p, p_max_size); } OBJ(diskiograph_read) { - print_diskiograph(obj, p, p_max_size); + print_diskiograph_read(obj, p, p_max_size); } OBJ(diskiograph_write) { - print_diskiograph(obj, p, p_max_size); + print_diskiograph_write(obj, p, p_max_size); } #endif /* X11 */ OBJ(downspeed) { @@ -1329,7 +1350,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 = ' '; } @@ -1502,6 +1523,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); } @@ -2061,9 +2091,11 @@ void generate_text_internal(char *p, int p_max_size, OBJ(xmms2_percent) { snprintf(p, p_max_size, "%2.0f", cur->xmms2.progress * 100); } +#ifdef X11 OBJ(xmms2_bar) { new_bar(obj, p, p_max_size, (int) (cur->xmms2.progress * 255.0f)); } +#endif /* X11 */ OBJ(xmms2_playlist) { snprintf(p, p_max_size, "%s", cur->xmms2.playlist); } @@ -2139,6 +2171,7 @@ void generate_text_internal(char *p, int p_max_size, snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_MAIN_VOLUME]); } +#ifdef X11 OBJ(audacious_bar) { double progress; @@ -2147,6 +2180,7 @@ void generate_text_internal(char *p, int p_max_size, atof(cur->audacious.items[AUDACIOUS_LENGTH_SECONDS]); new_bar(obj, p, p_max_size, (int) (progress * 255.0f)); } +#endif /* X11 */ #endif /* AUDACIOUS */ #ifdef BMPX @@ -2172,7 +2206,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: @@ -2181,7 +2214,6 @@ void generate_text_internal(char *p, int p_max_size, case OBJ_top_io: #endif print_top(obj, p, p_max_size); -#endif /* __linux__ */ OBJ(tail) { print_tailhead("tail", obj, p, p_max_size); } @@ -2271,18 +2303,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); } @@ -2294,7 +2334,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 @@ -2374,9 +2414,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); @@ -3074,12 +3115,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 */ @@ -3118,36 +3161,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; } @@ -3445,8 +3501,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 @@ -3507,18 +3575,64 @@ static void main_loop(void) last_update_time = 0.0; next_update_time = get_time(); info.looped = 0; + + + // append arguments + if (update_heartbeat_min < update_heartbeat_max){ + msg = dbus_message_new_method_call("net.appcheck.Proximus", // target service + "/Proximus", // object path + "net.appcheck.Proximus", // interface to call on + "startTimer"); // method name + if (NULL == msg) { + fprintf(stderr, "Message Null\n"); + exit(1); + } + if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, &update_heartbeat_min, DBUS_TYPE_INT32, &update_heartbeat_max, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + DBusMessage *reply; + dbus_error_init (&err); + reply = dbus_connection_send_with_reply_and_block (conn, msg, 1500, &err); + + if (dbus_error_is_set(&err)) + { + fprintf (stderr, "dbus Error %s: %s\n",err.name,err.message); + } + + + if(reply) { + //fprintf (stderr, "got dbus reply to startTimer\n"); + dbus_message_unref (reply); + } + else{ + fprintf (stderr, "no reply to startTimer\n"); + update_heartbeat_min = update_heartbeat_max; + } + dbus_message_unref (msg); + } + + int WantSkips; + int DoneSkips; + bool sleeping = false; //i assume it's pretty hard to start this with the screen off... + while (terminate == 0 && (total_run_times == 0 || info.looped < total_run_times)) { + //fprintf(stderr, "started main_loop_while\n"); 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; + WantSkips = update_heartbeat_battery_skip; } else { update_interval = update_interval_old; + WantSkips = 0; } } + if (sleeping) WantSkips = update_skips_when_sleeping; info.looped++; + DoneSkips = 0; #ifdef SIGNAL_BLOCKING /* block signals. we will inspect for pending signals later */ @@ -3537,13 +3651,85 @@ static void main_loop(void) fd_set fdsr; struct timeval tv; int s; - t = next_update_time - get_time(); - - if (t < 0) { - t = 0; - } else if (t > update_interval) { - t = update_interval; - } + //should look for /org/freedesktop/Hal/devices/bme com.nokia.bme.signal + if (update_heartbeat_min != update_heartbeat_max) { //wait for signal + // add a rule for which messages we want to see + dbus_bus_add_match(conn, + "type='signal',interface='net.appcheck.Proximus'", + &err); // see signals from the given interface + dbus_bus_add_match(conn2, + "type='signal',interface='com.nokia.mce.signal'", + &err); // see signals from the given interface + dbus_connection_flush(conn); + dbus_connection_flush(conn2); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Match Error (%s)\n", err.message); + exit(1); + } + + int exitloop = 0; + while (exitloop == 0 && info.looped >= 10) { //first 10 frames drawn fast because if using lua + cairo it takes a while to get going + // non blocking read of the next available message + dbus_connection_read_write(conn, 0); + dbus_connection_read_write(conn2, 0); + msg = dbus_connection_pop_message(conn); + + // loop again if we haven't read a message + if (NULL == msg) { + msg = dbus_connection_pop_message(conn2); + if (NULL == msg){ + sleep(1); + continue; + } + } + // check if the message is a signal from the correct interface and with the correct name + if (dbus_message_is_signal(msg, "net.appcheck.Proximus", "heartbeat")) { + if(WantSkips == 0 || DoneSkips >= WantSkips){ + exitloop = 1; + fprintf(stderr, PACKAGE_NAME": woke by heartbeat\n"); + } + else { + fprintf(stderr, PACKAGE_NAME": ignoring this heartbeat\n"); + DoneSkips++; + } + } + else if (dbus_message_is_signal(msg, "com.nokia.mce.signal", "display_status_ind")){ + // read the parameters + if (!dbus_message_iter_init(msg, &args)) + fprintf(stderr, "Message has no arguments!\n"); + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + fprintf(stderr, "Argument is not string!\n"); + else { + char* sigvalue; + dbus_message_iter_get_basic(&args, &sigvalue); + if(!strcmp(sigvalue, MCE_DISPLAY_ON_STRING)){ + printf("wakeup because got display_status_ind signal with value %s\n", sigvalue); + exitloop = 1; + sleeping = false; + } + else if(!strcmp(sigvalue, MCE_DISPLAY_OFF_STRING)){ + printf("sleeping because got display_status_ind signal with value %s\n", sigvalue); + WantSkips = update_skips_when_sleeping; + sleeping = true; + } + } + } + else{ + //fprintf(stderr, PACKAGE_NAME": got dbus junk\n"); + } + dbus_message_unref(msg); + } + t = 0;//force legacy timer to skip -- update now or as soon as x is ready + } + else{ //signal not available, set up for legacy timer + t = next_update_time - get_time(); + if (t < 0) { + t = 0; + } + else if (t > update_interval) { + t = update_interval; + } + } tv.tv_sec = (long) t; tv.tv_usec = (long) (t * 1000000) % 1000000; @@ -3584,6 +3770,25 @@ static void main_loop(void) draw_stuff(); /* redraw everything in our newly sized window */ XResizeWindow(display, window.window, window.width, window.height); /* resize 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; + } +#ifdef IMLIB2 + { + cimlib_init(display, window.drawable, window.visual, window.colourmap); + } +#endif /* IMLIB2 */ + } +#endif set_transparent_background(window.window, own_window_argb_value); #ifdef HAVE_XDBE /* swap buffers */ @@ -3709,7 +3914,27 @@ 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; + } +#ifdef IMLIB2 + { + cimlib_init(display, window.drawable, window.visual, window.colourmap); + } +#endif /* IMLIB2 */ + } +#endif } text_width = window.width - window.border_inner_margin * 2 - window.border_outer_margin * 2 - window.border_width * 2; @@ -3743,6 +3968,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); @@ -3828,6 +4064,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(); @@ -3946,8 +4183,8 @@ static void main_loop(void) llua_update_info(&info, update_interval); #endif /* HAVE_LUA */ g_signal_pending = 0; - } - clean_up(NULL, NULL); + }//end of while{} (the real loop) + clean_up(current_mail_spool, NULL); #ifdef HAVE_SYS_INOTIFY_H if (inotify_fd != -1) { @@ -3956,7 +4193,7 @@ static void main_loop(void) inotify_fd = inotify_config_wd = 0; } #endif /* HAVE_SYS_INOTIFY_H */ -} +}//end of main_loop() #ifdef X11 static void load_config_file_x11(const char *); @@ -3973,11 +4210,40 @@ static void reload_config(void) initialisation(argc_copy, argv_copy); } -void clean_up(void *memtofree1, void* memtofree2) +#ifdef X11 +void clean_up_x11(void) { - int i; + 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 - free_update_callbacks(); +void clean_up_without_threads(void *memtofree1, void* memtofree2) { + int i; #ifdef NCURSES if(output_methods & TO_NCURSES) { @@ -4000,34 +4266,15 @@ void clean_up(void *memtofree1, void* memtofree2) } #ifdef X11 if (x_initialised == YES) { - if(window_created == 1) { - XClearArea(display, window.window, text_start_x - window.border_inner_margin - window.border_outer_margin - window.border_width, - text_start_y - window.border_inner_margin - window.border_outer_margin - window.border_width, - text_width + window.border_inner_margin * 2 + window.border_outer_margin * 2 + window.border_width * 2, - text_height + window.border_inner_margin * 2 + window.border_outer_margin * 2 + window.border_width * 2, 0); - } - destroy_window(); - free_fonts(); - if(x11_stuff.region) { - 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_templates(); @@ -4096,6 +4343,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) { @@ -4153,7 +4406,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 */ @@ -4199,9 +4452,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"); @@ -4251,6 +4502,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; @@ -4281,11 +4535,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(); @@ -4506,6 +4760,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; @@ -4528,15 +4805,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") { @@ -4548,23 +4822,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); @@ -4600,7 +4865,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; } @@ -5015,8 +5280,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; } @@ -5080,6 +5345,34 @@ char load_config_file(const char *f) } #endif /* IMLIB2 */ #endif /* X11 */ + CONF("update_heartbeat_min") { + if (value) { + update_heartbeat_min = strtod(value, 0); + } else { + CONF_ERR; + } + } + CONF("update_heartbeat_max") { + if (value) { + update_heartbeat_max = strtod(value, 0); + } else { + CONF_ERR; + } + } + CONF("update_heartbeat_battery_skip") { + if (value) { + update_heartbeat_battery_skip = strtod(value, 0); + } else { + CONF_ERR; + } + } + CONF("update_skips_when_sleeping") { + if (value) { + update_skips_when_sleeping = strtod(value, 0); + } else { + CONF_ERR; + } + } CONF("update_interval_on_battery") { if (value) { update_interval_bat = strtod(value, 0); @@ -5553,6 +5846,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 @@ -5572,15 +5866,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); @@ -5615,11 +5958,12 @@ 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) { int c = getopt_long(argc, argv, getopt_string, longopts, NULL); - static int startup_pause = 0; + int startup_pause; if (c == -1) { break; @@ -5637,7 +5981,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 @@ -5796,6 +6140,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) @@ -5836,7 +6185,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]); @@ -5862,48 +6213,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 */ @@ -5911,17 +6221,62 @@ 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 */ + + //dbus code from http://www.matthew.ath.cx/misc/dbus + dbus_error_init(&err); + // connect to the bus + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + conn2 = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn || NULL == conn2) { + exit(1); + } + // request a name on the bus (we don't use it for now) + ret = dbus_bus_request_name(conn, "net.appcheck.Conky", + DBUS_NAME_FLAG_REPLACE_EXISTING + , &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { + //dbus_connection_close(conn); + fprintf(stderr, "some other dbus Name Error\n"); + // exit(1); + } + main_loop(); + + dbus_connection_close(conn); + dbus_connection_close(conn2); + +#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; @@ -5938,7 +6293,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();