Fix nvidia crash (resolves #520). (#698)

* Fix XShape handling.
 * Fix crash when XDamage is disabled.
 * Make sure the nvidia COOLER target is available before trying to pull
 attribute values.
 * Check the nvidia extension is actually available.
 * Check that the display is valid.
This commit is contained in:
Brenden Matthews
2018-12-09 20:14:08 -05:00
committed by GitHub
parent 155563a446
commit a0d4393826
5 changed files with 146 additions and 89 deletions

View File

@@ -95,6 +95,7 @@ RUN sh -c 'if [ "$X11" = "yes" ] ; then \
libcurl4-gnutls-dev \ libcurl4-gnutls-dev \
libsystemd-dev \ libsystemd-dev \
libxml2-dev \ libxml2-dev \
libxnvctrl-dev \
tolua++ \ tolua++ \
&& rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/apt/lists/* \
&& rm -rf /conky && rm -rf /conky

View File

@@ -61,9 +61,6 @@
#ifdef BUILD_IMLIB2 #ifdef BUILD_IMLIB2
#include "imlib2.h" #include "imlib2.h"
#endif /* BUILD_IMLIB2 */ #endif /* BUILD_IMLIB2 */
#ifdef BUILD_XSHAPE
#include <X11/extensions/shape.h>
#endif /* BUILD_XSHAPE */
#endif /* BUILD_X11 */ #endif /* BUILD_X11 */
#ifdef BUILD_NCURSES #ifdef BUILD_NCURSES
#include <ncurses.h> #include <ncurses.h>
@@ -2016,26 +2013,6 @@ static void main_loop() {
sigaddset(&newmask, SIGUSR1); sigaddset(&newmask, SIGUSR1);
#endif #endif
#ifdef BUILD_X11
#ifdef BUILD_XSHAPE
if (out_to_x.get(*state)) {
/* allow only decorated windows to be given mouse input */
int major_version, minor_version;
if (XShapeQueryVersion(display, &major_version, &minor_version) == 0) {
NORM_ERR("Input shapes are not supported");
} else {
if (own_window.get(*state) &&
(own_window_type.get(*state) != TYPE_NORMAL ||
((TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) !=
0))) {
XShapeCombineRectangles(display, window.window, ShapeInput, 0, 0,
nullptr, 0, ShapeSet, Unsorted);
}
}
}
#endif /* BUILD_XSHAPE */
#endif /* BUILD_X11 */
last_update_time = 0.0; last_update_time = 0.0;
next_update_time = get_time() - fmod(get_time(), active_update_interval()); next_update_time = get_time() - fmod(get_time(), active_update_interval());
info.looped = 0; info.looped = 0;
@@ -2055,8 +2032,6 @@ static void main_loop() {
#ifdef BUILD_X11 #ifdef BUILD_X11
if (out_to_x.get(*state)) { if (out_to_x.get(*state)) {
XFlush(display);
/* wait for X event or timeout */ /* wait for X event or timeout */
if (XPending(display) == 0) { if (XPending(display) == 0) {
@@ -2210,6 +2185,7 @@ static void main_loop() {
r.width = ev.xexpose.width; r.width = ev.xexpose.width;
r.height = ev.xexpose.height; r.height = ev.xexpose.height;
XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region); XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region);
XSync(display, False);
break; break;
} }
@@ -2339,8 +2315,10 @@ static void main_loop() {
} }
#ifdef BUILD_XDAMAGE #ifdef BUILD_XDAMAGE
if (x11_stuff.damage) {
XDamageSubtract(display, x11_stuff.damage, x11_stuff.region2, None); XDamageSubtract(display, x11_stuff.damage, x11_stuff.region2, None);
XFixesSetRegion(display, x11_stuff.region2, nullptr, 0); XFixesSetRegion(display, x11_stuff.region2, nullptr, 0);
}
#endif /* BUILD_XDAMAGE */ #endif /* BUILD_XDAMAGE */
/* XDBE doesn't seem to provide a way to clear the back buffer /* XDBE doesn't seem to provide a way to clear the back buffer
@@ -2433,9 +2411,11 @@ static void main_loop() {
XDestroyRegion(x11_stuff.region); XDestroyRegion(x11_stuff.region);
x11_stuff.region = nullptr; x11_stuff.region = nullptr;
#ifdef BUILD_XDAMAGE #ifdef BUILD_XDAMAGE
if (x11_stuff.damage) {
XDamageDestroy(display, x11_stuff.damage); XDamageDestroy(display, x11_stuff.damage);
XFixesDestroyRegion(display, x11_stuff.region2); XFixesDestroyRegion(display, x11_stuff.region2);
XFixesDestroyRegion(display, x11_stuff.part); XFixesDestroyRegion(display, x11_stuff.part);
}
#endif /* BUILD_XDAMAGE */ #endif /* BUILD_XDAMAGE */
} }
#endif /* BUILD_X11 */ #endif /* BUILD_X11 */
@@ -2654,11 +2634,14 @@ static void X11_create_window() {
if (XDamageQueryExtension(display, &x11_stuff.event_base, if (XDamageQueryExtension(display, &x11_stuff.event_base,
&x11_stuff.error_base) == 0) { &x11_stuff.error_base) == 0) {
NORM_ERR("Xdamage extension unavailable"); NORM_ERR("Xdamage extension unavailable");
} x11_stuff.damage = 0;
} else {
x11_stuff.damage = x11_stuff.damage =
XDamageCreate(display, window.window, XDamageReportNonEmpty); XDamageCreate(display, window.window, XDamageReportNonEmpty);
x11_stuff.region2 = XFixesCreateRegionFromWindow(display, window.window, 0); x11_stuff.region2 =
XFixesCreateRegionFromWindow(display, window.window, 0);
x11_stuff.part = XFixesCreateRegionFromWindow(display, window.window, 0); x11_stuff.part = XFixesCreateRegionFromWindow(display, window.window, 0);
}
#endif /* BUILD_XDAMAGE */ #endif /* BUILD_XDAMAGE */
selected_font = 0; selected_font = 0;

View File

@@ -91,7 +91,7 @@ void set_font() {
} }
void setup_fonts() { void setup_fonts() {
DBGP("setting up fonts"); DBGP2("setting up fonts");
if (!out_to_x.get(*state)) { return; } if (!out_to_x.get(*state)) { return; }
#ifdef BUILD_XFT #ifdef BUILD_XFT
if (use_xft.get(*state)) { if (use_xft.get(*state)) {
@@ -146,7 +146,7 @@ void free_fonts(bool utf8) {
} }
void load_fonts(bool utf8) { void load_fonts(bool utf8) {
DBGP("loading fonts"); DBGP2("loading fonts");
if (!out_to_x.get(*state)) { return; } if (!out_to_x.get(*state)) { return; }
for (auto &font : fonts) { for (auto &font : fonts) {
#ifdef BUILD_XFT #ifdef BUILD_XFT

View File

@@ -341,7 +341,7 @@ struct nvidia_c_string {
int perfmax = -1; int perfmax = -1;
}; };
static Display *nvdisplay; static Display *nvdisplay = nullptr;
// Maximum number of GPU connected: // Maximum number of GPU connected:
// For cache default value: choosed a model of direct access to array instead of // For cache default value: choosed a model of direct access to array instead of
@@ -381,7 +381,7 @@ void nvidia_display_setting::lua_setter(lua::state &l, bool init) {
void nvidia_display_setting::cleanup(lua::state &l) { void nvidia_display_setting::cleanup(lua::state &l) {
lua::stack_sentry s(l, -1); lua::stack_sentry s(l, -1);
if (nvdisplay) { if (nvdisplay && nvdisplay != display) {
XCloseDisplay(nvdisplay); XCloseDisplay(nvdisplay);
nvdisplay = nullptr; nvdisplay = nullptr;
} }
@@ -654,9 +654,9 @@ static inline int get_nvidia_target_count(Display *dpy, TARGET_ID tid) {
num_tgts = -1; num_tgts = -1;
} }
if (num_tgts < 1) { if (num_tgts < 1 && tid == TARGET_GPU) {
// Print error and exit if there's no NVIDIA's GPU // Print error and exit if there's no NVIDIA's GPU
CRIT_ERR(nullptr, NULL, NORM_ERR(nullptr, NULL,
"%s:" "%s:"
"\n Trying to query Nvidia target failed (using the " "\n Trying to query Nvidia target failed (using the "
"propietary drivers)." "propietary drivers)."
@@ -670,7 +670,7 @@ static inline int get_nvidia_target_count(Display *dpy, TARGET_ID tid) {
} }
static int cache_nvidia_value(TARGET_ID tid, ATTR_ID aid, Display *dpy, static int cache_nvidia_value(TARGET_ID tid, ATTR_ID aid, Display *dpy,
int *value, int gid) { int *value, int gid, const char *arg) {
static nvidia_c_value ac_value[MAXNUMGPU]; static nvidia_c_value ac_value[MAXNUMGPU];
if (aid == ATTR_MEM_TOTAL) { if (aid == ATTR_MEM_TOTAL) {
@@ -679,8 +679,9 @@ static int cache_nvidia_value(TARGET_ID tid, ATTR_ID aid, Display *dpy,
dpy, translate_nvidia_target[tid], gid, 0, dpy, translate_nvidia_target[tid], gid, 0,
translate_nvidia_attribute[aid], value)) { translate_nvidia_attribute[aid], value)) {
NORM_ERR( NORM_ERR(
"%s: Something went wrong running nvidia query (tid: %d, aid: %d)", "%s: Something went wrong running nvidia query (arg: %s tid: %d, "
__func__, tid, aid); "aid: %d)",
__func__, arg, tid, aid);
return -1; return -1;
} }
ac_value[gid].memtotal = *value; ac_value[gid].memtotal = *value;
@@ -693,8 +694,9 @@ static int cache_nvidia_value(TARGET_ID tid, ATTR_ID aid, Display *dpy,
dpy, translate_nvidia_target[tid], gid, 0, dpy, translate_nvidia_target[tid], gid, 0,
translate_nvidia_attribute[aid], value)) { translate_nvidia_attribute[aid], value)) {
NORM_ERR( NORM_ERR(
"%s: Something went wrong running nvidia query (tid: %d, aid: %d)", "%s: Something went wrong running nvidia query (arg: %s, tid: "
__func__, tid, aid); "%d, aid: %d)",
__func__, arg, tid, aid);
return -1; return -1;
} }
ac_value[gid].gputempthreshold = *value; ac_value[gid].gputempthreshold = *value;
@@ -707,23 +709,23 @@ static int cache_nvidia_value(TARGET_ID tid, ATTR_ID aid, Display *dpy,
} }
// Retrieve attribute value via nvidia interface // Retrieve attribute value via nvidia interface
static int get_nvidia_value(TARGET_ID tid, ATTR_ID aid, int gid) { static int get_nvidia_value(TARGET_ID tid, ATTR_ID aid, int gid,
const char *arg) {
Display *dpy = nvdisplay ? nvdisplay : display; Display *dpy = nvdisplay ? nvdisplay : display;
int value; int value;
// Check if the aid is cacheable // Check if the aid is cacheable
if (aid == ATTR_MEM_TOTAL || aid == ATTR_GPU_TEMP_THRESHOLD) { if (aid == ATTR_MEM_TOTAL || aid == ATTR_GPU_TEMP_THRESHOLD) {
if (cache_nvidia_value(tid, aid, dpy, &value, gid)) { if (cache_nvidia_value(tid, aid, dpy, &value, gid, arg)) { return -1; }
return -1;
}
// If not, then query it // If not, then query it
} else { } else {
if (!dpy || if (!dpy ||
!XNVCTRLQueryTargetAttribute(dpy, translate_nvidia_target[tid], gid, 0, !XNVCTRLQueryTargetAttribute(dpy, translate_nvidia_target[tid], gid, 0,
translate_nvidia_attribute[aid], &value)) { translate_nvidia_attribute[aid], &value)) {
NORM_ERR( NORM_ERR(
"%s: Something went wrong running nvidia query (tid: %d, aid: %d)", "%s: Something went wrong running nvidia query (arg: %s, tid: %d, "
__func__, tid, aid); "aid: %d)",
__func__, arg, tid, aid);
return -1; return -1;
} }
} }
@@ -737,7 +739,8 @@ static int get_nvidia_value(TARGET_ID tid, ATTR_ID aid, int gid) {
} }
// Retrieve attribute string via nvidia interface // Retrieve attribute string via nvidia interface
static char *get_nvidia_string(TARGET_ID tid, ATTR_ID aid, int gid) { static char *get_nvidia_string(TARGET_ID tid, ATTR_ID aid, int gid,
const char *arg) {
Display *dpy = nvdisplay ? nvdisplay : display; Display *dpy = nvdisplay ? nvdisplay : display;
char *str; char *str;
@@ -746,9 +749,10 @@ static char *get_nvidia_string(TARGET_ID tid, ATTR_ID aid, int gid) {
dpy, translate_nvidia_target[tid], gid, 0, dpy, translate_nvidia_target[tid], gid, 0,
translate_nvidia_attribute[aid], &str)) { translate_nvidia_attribute[aid], &str)) {
NORM_ERR( NORM_ERR(
"%s: Something went wrong running nvidia string query (tid: %d, aid: " "%s: Something went wrong running nvidia string query (arg, tid: %d, "
"aid: "
"%d, GPU %d)", "%d, GPU %d)",
__func__, tid, aid, gid); __func__, arg, tid, aid, gid);
return nullptr; return nullptr;
} }
// fprintf(stderr, "checking get_nvidia_string-> '%s'", str); // fprintf(stderr, "checking get_nvidia_string-> '%s'", str);
@@ -817,7 +821,7 @@ static int cache_nvidia_string_value(TARGET_ID tid, ATTR_ID aid, char *token,
// Retrieve token value from nvidia string // Retrieve token value from nvidia string
static int get_nvidia_string_value(TARGET_ID tid, ATTR_ID aid, char *token, static int get_nvidia_string_value(TARGET_ID tid, ATTR_ID aid, char *token,
SEARCH_ID search, int gid) { SEARCH_ID search, int gid, const char *arg) {
char *str; char *str;
char *kvp, *key, *val; char *kvp, *key, *val;
char *saveptr1, *saveptr2; char *saveptr1, *saveptr2;
@@ -827,12 +831,10 @@ static int get_nvidia_string_value(TARGET_ID tid, ATTR_ID aid, char *token,
// Checks if the value is cacheable and is already loaded // Checks if the value is cacheable and is already loaded
cache_nvidia_string_value(tid, aid, token, search, &value, 0, gid); cache_nvidia_string_value(tid, aid, token, search, &value, 0, gid);
if (value != -1) { if (value != -1) { return value; }
return value;
}
// Get string via nvidia interface // Get string via nvidia interface
str = get_nvidia_string(tid, aid, gid); str = get_nvidia_string(tid, aid, gid, arg);
// Split string into 'key=value' substrings, split substring // Split string into 'key=value' substrings, split substring
// into key and value, from value, check if token was found, // into key and value, from value, check if token was found,
@@ -878,15 +880,30 @@ static int get_nvidia_string_value(TARGET_ID tid, ATTR_ID aid, char *token,
} }
// Perform query and print result // Perform query and print result
void print_nvidia_value(struct text_object *obj, char *p, unsigned int p_max_size) { void print_nvidia_value(struct text_object *obj, char *p,
unsigned int p_max_size) {
struct nvidia_s *nvs = static_cast<nvidia_s *>(obj->data.opaque); struct nvidia_s *nvs = static_cast<nvidia_s *>(obj->data.opaque);
int value, temp1, temp2; int value, temp1, temp2;
char *str; char *str;
Bool ret;
int event_base;
int error_base;
Display *dpy = nvdisplay ? nvdisplay : display; Display *dpy = nvdisplay ? nvdisplay : display;
if (!dpy) {
NORM_ERR("%s: no display set (try setting nvidia_display)", __func__);
return;
}
if (!XNVCTRLQueryExtension(dpy, &event_base, &error_base)) {
NORM_ERR("%s: NV-CONTROL X extension not present", __func__);
return;
}
// num_GPU calculated only once based on the physical target // num_GPU calculated only once based on the physical target
static int num_GPU = get_nvidia_target_count(dpy, TARGET_GPU) - 1; static int num_GPU = get_nvidia_target_count(dpy, TARGET_GPU) - 1;
static int num_COOLER = get_nvidia_target_count(dpy, TARGET_COOLER);
// Assume failure // Assume failure
value = -1; value = -1;
@@ -900,19 +917,32 @@ void print_nvidia_value(struct text_object *obj, char *p, unsigned int p_max_siz
// Execute switch by query type // Execute switch by query type
switch (nvs->query) { switch (nvs->query) {
case QUERY_VALUE: case QUERY_VALUE:
value = get_nvidia_value(nvs->target, nvs->attribute, nvs->gpu_id); switch (nvs->attribute) {
case ATTR_FAN_LEVEL:
case ATTR_FAN_SPEED:
if (num_COOLER < 1) {
value = -1;
break;
}
default:
value = get_nvidia_value(nvs->target, nvs->attribute, nvs->gpu_id,
nvs->arg);
break;
}
break; break;
case QUERY_STRING: case QUERY_STRING:
str = get_nvidia_string(nvs->target, nvs->attribute, nvs->gpu_id); str = get_nvidia_string(nvs->target, nvs->attribute, nvs->gpu_id,
nvs->arg);
break; break;
case QUERY_STRING_VALUE: case QUERY_STRING_VALUE:
value = get_nvidia_string_value(nvs->target, nvs->attribute, nvs->token, value = get_nvidia_string_value(nvs->target, nvs->attribute, nvs->token,
nvs->search, nvs->gpu_id); nvs->search, nvs->gpu_id, nvs->arg);
break; break;
case QUERY_SPECIAL: case QUERY_SPECIAL:
switch (nvs->attribute) { switch (nvs->attribute) {
case ATTR_PERF_MODE: case ATTR_PERF_MODE:
temp1 = get_nvidia_value(nvs->target, nvs->attribute, nvs->gpu_id); temp1 = get_nvidia_value(nvs->target, nvs->attribute, nvs->gpu_id,
nvs->arg);
switch (temp1) { switch (temp1) {
case NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE: case NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE:
temp2 = asprintf(&str, "Adaptive"); temp2 = asprintf(&str, "Adaptive");
@@ -931,13 +961,17 @@ void print_nvidia_value(struct text_object *obj, char *p, unsigned int p_max_siz
} }
break; break;
case ATTR_MEM_FREE: case ATTR_MEM_FREE:
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id); temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id,
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id); nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id,
nvs->arg);
value = temp2 - temp1; value = temp2 - temp1;
break; break;
case ATTR_MEM_UTIL: case ATTR_MEM_UTIL:
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id); temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id,
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id); nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id,
nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
} }
@@ -970,18 +1004,23 @@ double get_nvidia_barval(struct text_object *obj) {
switch (nvs->attribute) { switch (nvs->attribute) {
case ATTR_UTILS_STRING: // one of the percentage utils (gpuutil, case ATTR_UTILS_STRING: // one of the percentage utils (gpuutil,
// membwutil, videoutil and pcieutil) // membwutil, videoutil and pcieutil)
value = get_nvidia_string_value(nvs->target, ATTR_UTILS_STRING, value =
nvs->token, nvs->search, nvs->gpu_id); get_nvidia_string_value(nvs->target, ATTR_UTILS_STRING, nvs->token,
nvs->search, nvs->gpu_id, nvs->arg);
break; break;
case ATTR_MEM_UTIL: // memutil case ATTR_MEM_UTIL: // memutil
case ATTR_MEM_USED: case ATTR_MEM_USED:
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id); temp1 =
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id); get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id, nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id,
nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_MEM_FREE: // memfree case ATTR_MEM_FREE: // memfree
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id); temp1 =
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id); get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id, nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id,
nvs->arg);
value = temp2 - temp1; value = temp2 - temp1;
break; break;
case ATTR_FAN_SPEED: // fanspeed: Warn user we are using fanlevel case ATTR_FAN_SPEED: // fanspeed: Warn user we are using fanlevel
@@ -990,33 +1029,38 @@ double get_nvidia_barval(struct text_object *obj) {
nvs->command, nvs->arg); nvs->command, nvs->arg);
// No break, continue into fanlevel // No break, continue into fanlevel
case ATTR_FAN_LEVEL: // fanlevel case ATTR_FAN_LEVEL: // fanlevel
value = get_nvidia_value(nvs->target, ATTR_FAN_LEVEL, nvs->gpu_id); value = get_nvidia_value(nvs->target, ATTR_FAN_LEVEL, nvs->gpu_id,
nvs->arg);
break; break;
case ATTR_GPU_TEMP: // gputemp (calculate out of gputempthreshold) case ATTR_GPU_TEMP: // gputemp (calculate out of gputempthreshold)
temp1 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP, nvs->gpu_id); temp1 =
temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP, nvs->gpu_id, nvs->arg);
get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD, nvs->gpu_id); temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD,
nvs->gpu_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_AMBIENT_TEMP: // ambienttemp (calculate out of gputempthreshold case ATTR_AMBIENT_TEMP: // ambienttemp (calculate out of gputempthreshold
// for consistency) // for consistency)
temp1 = get_nvidia_value(nvs->target, ATTR_AMBIENT_TEMP, nvs->gpu_id); temp1 = get_nvidia_value(nvs->target, ATTR_AMBIENT_TEMP, nvs->gpu_id,
temp2 = nvs->arg);
get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD, nvs->gpu_id); temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD,
nvs->gpu_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_GPU_FREQ: // gpufreq (calculate out of gpufreqmax) case ATTR_GPU_FREQ: // gpufreq (calculate out of gpufreqmax)
temp1 = get_nvidia_value(nvs->target, ATTR_GPU_FREQ, nvs->gpu_id); temp1 =
get_nvidia_value(nvs->target, ATTR_GPU_FREQ, nvs->gpu_id, nvs->arg);
temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING, temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING,
(char *)"nvclockmax", SEARCH_MAX, (char *)"nvclockmax", SEARCH_MAX,
nvs->gpu_id); nvs->gpu_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_MEM_FREQ: // memfreq (calculate out of memfreqmax) case ATTR_MEM_FREQ: // memfreq (calculate out of memfreqmax)
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_FREQ, nvs->gpu_id); temp1 =
get_nvidia_value(nvs->target, ATTR_MEM_FREQ, nvs->gpu_id, nvs->arg);
temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING, temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING,
(char *)"memclockmax", SEARCH_MAX, (char *)"memclockmax", SEARCH_MAX,
nvs->gpu_id); nvs->gpu_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_FREQS_STRING: // mtrfreq (calculate out of memfreqmax) case ATTR_FREQS_STRING: // mtrfreq (calculate out of memfreqmax)
@@ -1028,16 +1072,18 @@ double get_nvidia_barval(struct text_object *obj) {
nvs->command, nvs->arg); nvs->command, nvs->arg);
return 0; return 0;
} }
temp1 = get_nvidia_string_value(nvs->target, ATTR_FREQS_STRING, temp1 =
nvs->token, SEARCH_MAX, nvs->gpu_id); get_nvidia_string_value(nvs->target, ATTR_FREQS_STRING, nvs->token,
SEARCH_MAX, nvs->gpu_id, nvs->arg);
temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING, temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING,
(char *)"memTransferRatemax", (char *)"memTransferRatemax",
SEARCH_MAX, nvs->gpu_id); SEARCH_MAX, nvs->gpu_id, nvs->arg);
if (temp2 > temp1) temp1 = temp2; // extra safe here if (temp2 > temp1) temp1 = temp2; // extra safe here
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_IMAGE_QUALITY: // imagequality case ATTR_IMAGE_QUALITY: // imagequality
value = get_nvidia_value(nvs->target, ATTR_IMAGE_QUALITY, nvs->gpu_id); value = get_nvidia_value(nvs->target, ATTR_IMAGE_QUALITY, nvs->gpu_id,
nvs->arg);
break; break;
default: // Throw error if unsupported args are used default: // Throw error if unsupported args are used

View File

@@ -54,6 +54,9 @@
#ifdef BUILD_XINERAMA #ifdef BUILD_XINERAMA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif #endif
#ifdef BUILD_XSHAPE
#include <X11/extensions/shape.h>
#endif /* BUILD_XSHAPE */
#ifdef BUILD_ARGB #ifdef BUILD_ARGB
bool have_argb_visual; bool have_argb_visual;
@@ -390,6 +393,7 @@ static int __attribute__((noreturn)) x11_ioerror_handler(Display *d) {
/* X11 initializer */ /* X11 initializer */
static void init_X11() { static void init_X11() {
DBGP("enter init_X11()");
if (display == nullptr) { if (display == nullptr) {
const std::string &dispstr = display_name.get(*state); const std::string &dispstr = display_name.get(*state);
// passing nullptr to XOpenDisplay should open the default display // passing nullptr to XOpenDisplay should open the default display
@@ -420,9 +424,12 @@ static void init_X11() {
/* WARNING, this type not in Xlib spec */ /* WARNING, this type not in Xlib spec */
XSetErrorHandler(&x11_error_handler); XSetErrorHandler(&x11_error_handler);
XSetIOErrorHandler(&x11_ioerror_handler); XSetIOErrorHandler(&x11_ioerror_handler);
DBGP("leave init_X11()");
} }
static void deinit_X11() { static void deinit_X11() {
DBGP("deinit_X11()");
XCloseDisplay(display); XCloseDisplay(display);
display = nullptr; display = nullptr;
} }
@@ -627,6 +634,7 @@ void destroy_window() {
} }
static void init_window(lua::state &l __attribute__((unused)), bool own) { static void init_window(lua::state &l __attribute__((unused)), bool own) {
DBGP("enter init_window()");
// own is unused if OWN_WINDOW is not defined // own is unused if OWN_WINDOW is not defined
(void)own; (void)own;
@@ -756,6 +764,24 @@ static void init_window(lua::state &l __attribute__((unused)), bool own) {
wmHint.flags = InputHint | StateHint; wmHint.flags = InputHint | StateHint;
/* allow decorated windows to be given input focus by WM */ /* allow decorated windows to be given input focus by WM */
wmHint.input = TEST_HINT(hints, HINT_UNDECORATED) ? False : True; wmHint.input = TEST_HINT(hints, HINT_UNDECORATED) ? False : True;
#ifdef BUILD_XSHAPE
if (!wmHint.input) {
/* allow only decorated windows to be given mouse input */
int major_version;
int minor_version;
if (XShapeQueryVersion(display, &major_version, &minor_version) == 0) {
NORM_ERR("Input shapes are not supported");
} else {
if (own_window.get(*state) &&
(own_window_type.get(*state) != TYPE_NORMAL ||
((TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) !=
0))) {
XShapeCombineRectangles(display, window.window, ShapeInput, 0, 0,
nullptr, 0, ShapeSet, Unsorted);
}
}
}
#endif /* BUILD_XSHAPE */
if (own_window_type.get(l) == TYPE_DOCK || if (own_window_type.get(l) == TYPE_DOCK ||
own_window_type.get(l) == TYPE_PANEL) { own_window_type.get(l) == TYPE_PANEL) {
wmHint.initial_state = WithdrawnState; wmHint.initial_state = WithdrawnState;
@@ -958,6 +984,7 @@ static void init_window(lua::state &l __attribute__((unused)), bool own) {
: 0) : 0)
#endif #endif
); );
DBGP("leave init_window()");
} }
static Window find_subwindow(Window win, int w, int h) { static Window find_subwindow(Window win, int w, int h) {