diff --git a/src/conky.cc b/src/conky.cc index 99bf6041..45851928 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -299,7 +299,6 @@ static const char *suffixes[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "" }; #ifdef BUILD_X11 static void X11_create_window(void); -static void X11_initialisation(void); struct _x11_stuff_s { Region region; @@ -2377,10 +2376,6 @@ void clean_up(void *memtofree1, void* memtofree2) XDestroyRegion(x11_stuff.region); x11_stuff.region = NULL; } - XCloseDisplay(display); - display = NULL; - free_and_zero(info.x11.desktop.all_names); - free_and_zero(info.x11.desktop.name); x_initialised = NO; }else{ free(fonts); //in set_default_configurations a font is set but not loaded @@ -2396,10 +2391,6 @@ void clean_up(void *memtofree1, void* memtofree2) info.first_process = NULL; } -#ifdef BUILD_X11 - free_desktop_info(); -#endif /* BUILD_X11 */ - free_text_objects(&global_root_object); free_and_zero(tmpstring1); free_and_zero(tmpstring2); @@ -2442,6 +2433,9 @@ void clean_up(void *memtofree1, void* memtofree2) clear_net_stats(); clear_diskio_stats(); free_and_zero(global_cpu); + + conky::cleanup_config_settings(*state); + state.reset(); } static bool string_to_bool(const char *s) @@ -2460,7 +2454,8 @@ static bool string_to_bool(const char *s) } #ifdef BUILD_X11 -static void set_default_configurations_for_x(void) +// XXX +static void __attribute__((unused)) set_default_configurations_for_x(void) { default_fg_color = WhitePixel(display, screen); default_bg_color = BlackPixel(display, screen); @@ -2558,13 +2553,6 @@ static void set_default_configurations(void) window.border_inner_margin = 3; window.border_outer_margin = 1; window.border_width = 1; - info.x11.monitor.number = 1; - info.x11.monitor.current = 0; - 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; #endif /* BUILD_X11 */ free_templates(); @@ -2613,52 +2601,6 @@ static bool append_works(const char *path) } #ifdef BUILD_X11 -#ifdef DEBUG -/* WARNING, this type not in Xlib spec */ -int x11_error_handler(Display *d, XErrorEvent *err) - __attribute__((noreturn)); -int x11_error_handler(Display *d, XErrorEvent *err) -{ - NORM_ERR("X Error: type %i Display %lx XID %li serial %lu error_code %i request_code %i minor_code %i other Display: %lx\n", - err->type, - (long unsigned)err->display, - (long)err->resourceid, - err->serial, - err->error_code, - err->request_code, - err->minor_code, - (long unsigned)d - ); - abort(); -} - -int x11_ioerror_handler(Display *d) - __attribute__((noreturn)); -int x11_ioerror_handler(Display *d) -{ - NORM_ERR("X Error: Display %lx\n", - (long unsigned)d - ); - exit(1); -} -#endif /* DEBUG */ - -static void X11_initialisation(void) -{ - if (x_initialised == YES) return; - state->pushboolean(true); - out_to_x.lua_set(*state); - init_X11(); - set_default_configurations_for_x(); - x_initialised = YES; -#ifdef DEBUG - _Xdebug = 1; - /* WARNING, this type not in Xlib spec */ - XSetErrorHandler(&x11_error_handler); - XSetIOErrorHandler(&x11_ioerror_handler); -#endif /* DEBUG */ -} - static char **xargv = 0; static int xargc = 0; @@ -3196,12 +3138,6 @@ char load_config_file(const char *f) } } CONF("text") { -#ifdef BUILD_X11 - if (out_to_x.get(*state)) { - X11_initialisation(); - } -#endif - free_and_zero(global_text); global_text = (char *) malloc(1); @@ -3392,7 +3328,7 @@ static void load_config_file_x11(const char *f) } CONF2("color0") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color0 = get_x11_color(value); @@ -3402,7 +3338,7 @@ static void load_config_file_x11(const char *f) } } CONF("color1") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color1 = get_x11_color(value); @@ -3412,7 +3348,7 @@ static void load_config_file_x11(const char *f) } } CONF("color2") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color2 = get_x11_color(value); @@ -3422,7 +3358,7 @@ static void load_config_file_x11(const char *f) } } CONF("color3") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color3 = get_x11_color(value); @@ -3432,7 +3368,7 @@ static void load_config_file_x11(const char *f) } } CONF("color4") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color4 = get_x11_color(value); @@ -3442,7 +3378,7 @@ static void load_config_file_x11(const char *f) } } CONF("color5") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color5 = get_x11_color(value); @@ -3452,7 +3388,7 @@ static void load_config_file_x11(const char *f) } } CONF("color6") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color6 = get_x11_color(value); @@ -3462,7 +3398,7 @@ static void load_config_file_x11(const char *f) } } CONF("color7") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color7 = get_x11_color(value); @@ -3472,7 +3408,7 @@ static void load_config_file_x11(const char *f) } } CONF("color8") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color8 = get_x11_color(value); @@ -3482,7 +3418,7 @@ static void load_config_file_x11(const char *f) } } CONF("color9") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { color9 = get_x11_color(value); @@ -3492,7 +3428,7 @@ static void load_config_file_x11(const char *f) } } CONF("default_color") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { default_fg_color = get_x11_color(value); @@ -3502,7 +3438,7 @@ static void load_config_file_x11(const char *f) } } CONF3("default_shade_color", "default_shadecolor") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { default_bg_color = get_x11_color(value); @@ -3512,7 +3448,7 @@ static void load_config_file_x11(const char *f) } } CONF3("default_outline_color", "default_outlinecolor") { - X11_initialisation(); + // XXX X11_initialisation(); if (x_initialised == YES) { if (value) { default_out_color = get_x11_color(value); @@ -3521,12 +3457,6 @@ static void load_config_file_x11(const char *f) } } } - CONF("text") { - /* initialize BUILD_X11 if nothing BUILD_X11-related is mentioned before TEXT (and if BUILD_X11 is the default outputmethod) */ - if (out_to_x.get(*state)) { - X11_initialisation(); - } - } #undef CONF #undef CONF2 #undef CONF3 @@ -3908,7 +3838,6 @@ int main(int argc, char **argv) argv_copy = argv; g_signal_pending = 0; max_user_text = MAX_USER_TEXT_DEFAULT; - memset(&info, 0, sizeof(info)); free_templates(); clear_net_stats(); @@ -3979,7 +3908,7 @@ int main(int argc, char **argv) "print(conky.asnumber(conky.variables.zxcv{}));\n" "print(conky.variables.asdf{}.text);\n" "print(conky.variables.asdf{}.xxx);\n" - "conky.config = { alignment='bar', asdf=47, [42]=47,\n" + "conky.config = { alignment='bar', asdf=47, [42]=47, out_to_x=true,\n" " own_window_hints='above, undecorated,,below'};\n" ); l.call(0, 0); @@ -3998,6 +3927,9 @@ int main(int argc, char **argv) "print('config.own_window_hints = ', conky.config.own_window_hints);\n" ); l.call(0, 0); + + conky::cleanup_config_settings(*state); + state.reset(); } catch(std::exception &e) { std::cerr << "caught exception: " << e.what() << std::endl; diff --git a/src/conky.h b/src/conky.h index 1f9bc8b9..b4194a71 100644 --- a/src/conky.h +++ b/src/conky.h @@ -147,9 +147,8 @@ struct monitor_info { struct desktop_info { int current; int number; - unsigned int nitems; - char *all_names; - char *name; + std::string all_names; + std::string name; }; struct x11_info { diff --git a/src/x11.cc b/src/x11.cc index dfbbd48c..d7084948 100644 --- a/src/x11.cc +++ b/src/x11.cc @@ -74,18 +74,51 @@ static void update_workarea(void); static Window find_desktop_window(Window *p_root, Window *p_desktop); static Window find_subwindow(Window win, int w, int h); +#ifdef DEBUG +/* WARNING, this type not in Xlib spec */ +static int __attribute__((noreturn)) x11_error_handler(Display *d, XErrorEvent *err) +{ + NORM_ERR("X Error: type %i Display %lx XID %li serial %lu error_code %i request_code %i minor_code %i other Display: %lx\n", + err->type, + (long unsigned)err->display, + (long)err->resourceid, + err->serial, + err->error_code, + err->request_code, + err->minor_code, + (long unsigned)d + ); + abort(); +} + +static int __attribute__((noreturn)) x11_ioerror_handler(Display *d) +{ + NORM_ERR("X Error: Display %lx\n", + (long unsigned)d + ); + exit(1); +} +#endif /* DEBUG */ + /* X11 initializer */ -void init_X11() +static void init_X11() { if (!display) { const std::string &dispstr = display_name.get(*state).c_str(); // passing NULL to XOpenDisplay should open the default display const char *disp = dispstr.size() ? dispstr.c_str() : NULL; if ((display = XOpenDisplay(disp)) == NULL) { - CRIT_ERR(NULL, NULL, "can't open display: %s", XDisplayName(disp)); + throw std::runtime_error(std::string("can't open display: ") + XDisplayName(disp)); } } + info.x11.monitor.number = 1; + info.x11.monitor.current = 0; + info.x11.desktop.current = 1; + info.x11.desktop.number = 1; + info.x11.desktop.all_names.clear(); + info.x11.desktop.name.clear(); + screen = DefaultScreen(display); display_width = DisplayWidth(display, screen); display_height = DisplayHeight(display, screen); @@ -93,6 +126,19 @@ void init_X11() get_x11_desktop_info(display, 0); update_workarea(); + +#ifdef DEBUG + _Xdebug = 1; + /* WARNING, this type not in Xlib spec */ + XSetErrorHandler(&x11_error_handler); + XSetIOErrorHandler(&x11_ioerror_handler); +#endif /* DEBUG */ +} + +static void deinit_X11() +{ + XCloseDisplay(display); + display = NULL; } static void update_workarea(void) @@ -713,10 +759,7 @@ static inline void get_x11_desktop_names(Display *current_display, Window root, (actual_type == ATOM(UTF8_STRING)) && (nitems > 0L) && (actual_format == 8) ) { - free_and_zero(current_info->x11.desktop.all_names); - current_info->x11.desktop.all_names = (char*)malloc(nitems*sizeof(char)); - memcpy(current_info->x11.desktop.all_names, prop, nitems); - current_info->x11.desktop.nitems = nitems; + current_info->x11.desktop.all_names.assign(reinterpret_cast(prop), nitems); } if(prop) { XFree(prop); @@ -724,19 +767,16 @@ static inline void get_x11_desktop_names(Display *current_display, Window root, } //Get current desktop name -static inline void get_x11_desktop_current_name(char *names) +static inline void get_x11_desktop_current_name(const std::string &names) { struct information *current_info = &info; unsigned int i = 0, j = 0; int k = 0; - while ( i < current_info->x11.desktop.nitems ) { + while ( i < names.size() ) { if ( names[i++] == '\0' ) { if ( ++k == current_info->x11.desktop.current ) { - free_and_zero(current_info->x11.desktop.name); - current_info->x11.desktop.name = (char*)malloc((i-j)*sizeof(char)); - //desktop names can be empty but should always be not null - strcpy( current_info->x11.desktop.name, (char *)&names[j] ); + current_info->x11.desktop.name.assign(names.c_str()+j); break; } j = i; @@ -834,19 +874,13 @@ void print_desktop_name(struct text_object *obj, char *p, int p_max_size) { (void)obj; - if(x_initialised != YES) { + if(not out_to_x.get(*state)) { strncpy(p, NOT_IN_X, p_max_size); - }else if(info.x11.desktop.name != NULL) { - strncpy(p, info.x11.desktop.name, p_max_size); + } else { + strncpy(p, info.x11.desktop.name.c_str(), p_max_size); } } -void free_desktop_info(void) -{ - free_and_zero(info.x11.desktop.name); - free_and_zero(info.x11.desktop.all_names); -} - #ifdef OWN_WINDOW /* reserve window manager space */ void set_struts(int sidenum) @@ -927,6 +961,30 @@ void xdbe_swap_buffers(void) } #endif /* BUILD_XDBE */ +namespace priv { + void out_to_x_setting::lua_setter(lua::state &l, bool init) + { + lua::stack_sentry s(l, -2); + + Base::lua_setter(l, init); + + if(init && do_convert(l, -1).first) + init_X11(); + + ++s; + } + + void out_to_x_setting::cleanup(lua::state &l) + { + lua::stack_sentry s(l, -1); + + if(do_convert(l, -1).first) + deinit_X11(); + + l.pop(); + } +} + template<> conky::lua_traits::Map conky::lua_traits::map = { { "top_left", TOP_LEFT }, @@ -942,10 +1000,10 @@ conky::lua_traits::Map conky::lua_traits::map = { }; conky::simple_config_setting text_alignment("alignment", NONE, false); -conky::simple_config_setting out_to_x("out_to_x", false, false); - conky::simple_config_setting display_name("display", std::string(), false); +priv::out_to_x_setting out_to_x; + #ifdef OWN_WINDOW conky::simple_config_setting own_window("own_window", false, false); conky::simple_config_setting set_transparent("own_window_transparent", false, false); diff --git a/src/x11.h b/src/x11.h index 1267193a..5a76b552 100644 --- a/src/x11.h +++ b/src/x11.h @@ -111,7 +111,6 @@ extern int workarea[4]; extern struct conky_window window; extern char window_created; -void init_X11(); void init_window(int width, int height, char **argv, int argc); void destroy_window(void); void create_gc(void); @@ -124,7 +123,6 @@ void print_monitor_number(struct text_object *, char *, int); void print_desktop(struct text_object *, char *, int); void print_desktop_number(struct text_object *, char *, int); void print_desktop_name(struct text_object *, char *, int); -void free_desktop_info(void); #ifdef BUILD_XDBE void xdbe_swap_buffers(void); @@ -145,7 +143,22 @@ enum alignment { }; extern conky::simple_config_setting text_alignment; -extern conky::simple_config_setting out_to_x; + +namespace priv { + class out_to_x_setting: public conky::simple_config_setting { + typedef conky::simple_config_setting Base; + + protected: + virtual void lua_setter(lua::state &l, bool init); + virtual void cleanup(lua::state &l); + + public: + out_to_x_setting() + : Base("out_to_x", false, false) + {} + }; +} +extern priv::out_to_x_setting out_to_x; extern conky::simple_config_setting display_name; #ifdef OWN_WINDOW