diff --git a/src/nvidia.cc b/src/nvidia.cc index 5417e730..73b904a3 100644 --- a/src/nvidia.cc +++ b/src/nvidia.cc @@ -101,6 +101,8 @@ #include "temphelper.h" #include "x11.h" +#include + // Separators for nvidia string parsing // (sample: "perf=0, nvclock=324, nvclockmin=324, nvclockmax=324 ; perf=1, // nvclock=549, nvclockmin=549, nvclockmax=549") @@ -366,6 +368,14 @@ struct nvidia_c_string { const int MAXNUMGPU = 64; namespace { + +// Deleter for nv display to use with std::unique_ptr +void close_nvdisplay(Display * dp) { + XCloseDisplay(dp); +} + +using unique_display_t = std::unique_ptr; + class nvidia_display_setting : public conky::simple_config_setting { typedef conky::simple_config_setting Base; @@ -378,7 +388,7 @@ class nvidia_display_setting public: nvidia_display_setting() : Base("nvidia_display", std::string(), false) {} - virtual Display *get_nvdisplay(); + virtual unique_display_t get_nvdisplay(); }; void nvidia_display_setting::lua_setter(lua::state &l, bool init) { @@ -391,28 +401,21 @@ void nvidia_display_setting::lua_setter(lua::state &l, bool init) { ++s; } // namespace -Display *nvidia_display_setting::get_nvdisplay() { +unique_display_t nvidia_display_setting::get_nvdisplay() { if (!nvdisplay.empty()) { - Display *nvd = XOpenDisplay(nvdisplay.c_str()); - if (nvd == nullptr) { + unique_display_t nvd(XOpenDisplay(nvdisplay.c_str()), &close_nvdisplay); + if (!nvd) { NORM_ERR(nullptr, NULL, "can't open nvidia display: %s", XDisplayName(nvdisplay.c_str())); } return nvd; } - return nullptr; + return unique_display_t(nullptr, &close_nvdisplay); } // namespace void nvidia_display_setting::cleanup(lua::state &l) { lua::stack_sentry s(l, -1); - Display *nvdisplay = get_nvdisplay(); - - if (nvdisplay && nvdisplay != display) { - XCloseDisplay(nvdisplay); - nvdisplay = nullptr; - } - l.pop(); } @@ -754,8 +757,8 @@ static int cache_nvidia_value(TARGET_ID tid, ATTR_ID aid, Display *dpy, // Retrieve attribute value via nvidia interface static int get_nvidia_value(TARGET_ID tid, ATTR_ID aid, int gid, const char *arg) { - Display *dpy = nvidia_display.get_nvdisplay(); - if (!dpy) dpy = display; + auto nvdpy = nvidia_display.get_nvdisplay(); + Display * dpy = nvdpy ? nvdpy.get() : display; int value; // Check if the aid is cacheable @@ -785,8 +788,8 @@ static int get_nvidia_value(TARGET_ID tid, ATTR_ID aid, int gid, // Retrieve attribute string via nvidia interface static char *get_nvidia_string(TARGET_ID tid, ATTR_ID aid, int gid, const char *arg) { - Display *dpy = nvidia_display.get_nvdisplay(); - if (!dpy) dpy = display; + auto nvdpy = nvidia_display.get_nvdisplay(); + Display * dpy = nvdpy ? nvdpy.get() : display; char *str; // Query nvidia interface @@ -958,8 +961,8 @@ void print_nvidia_value(struct text_object *obj, char *p, int event_base; int error_base; - Display *dpy = nvidia_display.get_nvdisplay(); - if (!dpy) dpy = display; + auto nvdpy = nvidia_display.get_nvdisplay(); + Display * dpy = nvdpy ? nvdpy.get() : display; if (!dpy) { NORM_ERR("%s: no display set (try setting nvidia_display)", __func__); @@ -1062,8 +1065,8 @@ double get_nvidia_barval(struct text_object *obj) { int event_base; int error_base; - Display *dpy = nvidia_display.get_nvdisplay(); - if (!dpy) dpy = display; + auto nvdpy = nvidia_display.get_nvdisplay(); + Display * dpy = nvdpy ? nvdpy.get() : display; if (!dpy) { NORM_ERR("%s: no display set (try setting nvidia_display)", __func__);