diff options
46 files changed, 3138 insertions, 767 deletions
diff --git a/doc/version.mk b/doc/version.mk index d622b1f..714e597 100644 --- a/doc/version.mk +++ b/doc/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 346.47 +NVIDIA_VERSION = 349.12 diff --git a/samples/nv-control-events.c b/samples/nv-control-events.c index 9265990..6b3dfc4 100644 --- a/samples/nv-control-events.c +++ b/samples/nv-control-events.c @@ -683,6 +683,7 @@ static AttrEntry attr_table[] = { MAKE_ENTRY(NV_CTRL_GVI_TEST_MODE), MAKE_ENTRY(NV_CTRL_COLOR_SPACE), MAKE_ENTRY(NV_CTRL_COLOR_RANGE), + MAKE_ENTRY(NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR), MAKE_ENTRY(NV_CTRL_GPU_SCALING_DEFAULT_TARGET), MAKE_ENTRY(NV_CTRL_GPU_SCALING_DEFAULT_METHOD), MAKE_ENTRY(NV_CTRL_DITHERING_MODE), @@ -733,6 +734,7 @@ static AttrEntry attr_table[] = { MAKE_ENTRY(NV_CTRL_MULTIGPU_MASTER_POSSIBLE), MAKE_ENTRY(NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE), MAKE_ENTRY(NV_CTRL_XV_SYNC_TO_DISPLAY_ID), + MAKE_ENTRY(NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID), MAKE_ENTRY(NV_CTRL_PALETTE_UPDATE_EVENT), MAKE_ENTRY(NV_CTRL_GSYNC_ALLOWED), { -1, NULL, NULL } diff --git a/samples/nv-control-info.c b/samples/nv-control-info.c index fbaab54..f8912f1 100644 --- a/samples/nv-control-info.c +++ b/samples/nv-control-info.c @@ -160,6 +160,8 @@ static AttrEntry attr_int_table[] = { MAKE_ENTRY(NV_CTRL_BUS_RATE), MAKE_ENTRY(NV_CTRL_SHOW_SLI_VISUAL_INDICATOR), MAKE_ENTRY(NV_CTRL_XV_SYNC_TO_DISPLAY), + MAKE_ENTRY(NV_CTRL_XV_SYNC_TO_DISPLAY_ID), + MAKE_ENTRY(NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID), MAKE_ENTRY(NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2), MAKE_ENTRY(NV_CTRL_GVO_OVERRIDE_HW_CSC), MAKE_ENTRY(NV_CTRL_GVO_CAPABILITIES), @@ -266,6 +268,7 @@ static AttrEntry attr_int_table[] = { MAKE_ENTRY(NV_CTRL_GVI_TEST_MODE), MAKE_ENTRY(NV_CTRL_COLOR_SPACE), MAKE_ENTRY(NV_CTRL_COLOR_RANGE), + MAKE_ENTRY(NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR), MAKE_ENTRY(NV_CTRL_GPU_SCALING_DEFAULT_TARGET), MAKE_ENTRY(NV_CTRL_GPU_SCALING_DEFAULT_METHOD), MAKE_ENTRY(NV_CTRL_DITHERING_MODE), @@ -294,7 +297,6 @@ static AttrEntry attr_int_table[] = { MAKE_ENTRY(NV_CTRL_3D_VISION_PRO_GLASSES_SYNC_CYCLE), MAKE_ENTRY(NV_CTRL_3D_VISION_PRO_GLASSES_MISSED_SYNC_CYCLES), MAKE_ENTRY(NV_CTRL_3D_VISION_PRO_GLASSES_BATTERY_LEVEL), - MAKE_ENTRY(NV_CTRL_3D_VISION_PRO_GLASSES_BATTERY_LEVEL), MAKE_ENTRY(NV_CTRL_GVO_ANC_PARITY_COMPUTATION), MAKE_ENTRY(NV_CTRL_3D_VISION_PRO_GLASSES_PAIR_EVENT), MAKE_ENTRY(NV_CTRL_3D_VISION_PRO_GLASSES_UNPAIR_EVENT), diff --git a/samples/version.mk b/samples/version.mk index d622b1f..714e597 100644 --- a/samples/version.mk +++ b/samples/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 346.47 +NVIDIA_VERSION = 349.12 diff --git a/src/common-utils/common-utils.c b/src/common-utils/common-utils.c index 81fd7ed..fe7889e 100644 --- a/src/common-utils/common-utils.c +++ b/src/common-utils/common-utils.c @@ -1,17 +1,23 @@ /* * Copyright (C) 2010-2012 NVIDIA Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ @@ -60,40 +66,45 @@ void *nvalloc(size_t size) /* * nvstrcat() - allocate a new string, copying all given strings - * into it. taken from glib + * into it. */ char *nvstrcat(const char *str, ...) { - unsigned int l; - va_list args; - char *s; - char *concat; - - l = 1 + strlen(str); - va_start(args, str); - s = va_arg(args, char *); - - while (s) { - l += strlen(s); - s = va_arg(args, char *); + const char *s; + char *result; + size_t len; + va_list ap; + + /* walk the varargs to compute the length of the result string */ + + va_start(ap, str); + + for (s = str, len = 1; s; s = va_arg(ap, char *)) { + len += strlen(s); + } + + va_end(ap); + + /* allocate the result string */ + + result = nvalloc(len); + if (!result) { + return result; } - va_end(args); + result[0] = '\0'; - concat = nvalloc(l); - concat[0] = 0; + /* concatenate the input strings, writing into the result string */ - strcat(concat, str); - va_start(args, str); - s = va_arg(args, char *); - while (s) { - strcat(concat, s); - s = va_arg(args, char *); + va_start(ap, str); + + for (s = str; s; s = va_arg(ap, char *)) { + strcat(result, s); } - va_end(args); - return concat; + va_end(ap); + return result; } /* nvstrcat() */ diff --git a/src/common-utils/common-utils.h b/src/common-utils/common-utils.h index 709ff02..7a1f71a 100644 --- a/src/common-utils/common-utils.h +++ b/src/common-utils/common-utils.h @@ -1,17 +1,23 @@ /* * Copyright (C) 2010-2012 NVIDIA Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef __COMMON_UTILS_H__ diff --git a/src/common-utils/gen-manpage-opts-helper.c b/src/common-utils/gen-manpage-opts-helper.c index 84bac62..b41e2aa 100644 --- a/src/common-utils/gen-manpage-opts-helper.c +++ b/src/common-utils/gen-manpage-opts-helper.c @@ -1,17 +1,23 @@ /* * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #include <stdio.h> diff --git a/src/common-utils/gen-manpage-opts-helper.h b/src/common-utils/gen-manpage-opts-helper.h index b09852e..97a2908 100644 --- a/src/common-utils/gen-manpage-opts-helper.h +++ b/src/common-utils/gen-manpage-opts-helper.h @@ -1,17 +1,23 @@ /* * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #if !defined(__GEN_MANPAGE_OPTS_HELPER_H__) diff --git a/src/common-utils/msg.c b/src/common-utils/msg.c index cdd3c4f..349c640 100644 --- a/src/common-utils/msg.c +++ b/src/common-utils/msg.c @@ -1,17 +1,23 @@ /* * Copyright (C) 2004 NVIDIA Corporation. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #include <stdio.h> diff --git a/src/common-utils/msg.h b/src/common-utils/msg.h index 5e32c19..3eae767 100644 --- a/src/common-utils/msg.h +++ b/src/common-utils/msg.h @@ -1,17 +1,23 @@ /* * Copyright (C) 2004 NVIDIA Corporation. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef __MSG_H__ diff --git a/src/common-utils/nvgetopt.c b/src/common-utils/nvgetopt.c index aaebd78..1716495 100644 --- a/src/common-utils/nvgetopt.c +++ b/src/common-utils/nvgetopt.c @@ -1,17 +1,23 @@ /* * Copyright (C) 2004-2010 NVIDIA Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses>. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * * nvgetopt.c - portable getopt_long() replacement; removes the need diff --git a/src/common-utils/nvgetopt.h b/src/common-utils/nvgetopt.h index fc735ee..0fec64d 100644 --- a/src/common-utils/nvgetopt.h +++ b/src/common-utils/nvgetopt.h @@ -1,20 +1,23 @@ /* * Copyright (C) 2004-2010 NVIDIA Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses>. - * - * - * nvgetopt.h + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef __NVGETOPT_H__ diff --git a/src/config-file.c b/src/config-file.c index 02061ae..033fba2 100644 --- a/src/config-file.c +++ b/src/config-file.c @@ -236,7 +236,6 @@ int nv_write_config_file(const char *filename, const CtrlSystem *system, time_t now; ReturnStatus status; CtrlAttributePerms perms; - NVCTRLAttributeValidValuesRec valid; CtrlTargetNode *node; CtrlTarget *t; char *prefix, scratch[4]; @@ -363,23 +362,18 @@ int nv_write_config_file(const char *filename, const CtrlSystem *system, continue; } - /* Ignore display attributes, they are written later on */ + /* + * Ignore display attributes (they are written later on) and only + * write attributes that can be written for an X screen target + */ status = NvCtrlGetAttributePerms(t, a->type, a->attr, &perms); - if (status != NvCtrlSuccess || + if (status != NvCtrlSuccess || !(perms.write) || + !(perms.valid_targets & CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET)) || (perms.valid_targets & CTRL_TARGET_PERM_BIT(DISPLAY_TARGET))) { continue; } - /* Only write attributes that can be written */ - - status = NvCtrlGetValidAttributeValues(t, a->attr, &valid); - if (status != NvCtrlSuccess || - !(valid.permissions & ATTRIBUTE_TYPE_WRITE) || - (valid.permissions & ATTRIBUTE_TYPE_DISPLAY)) {; - continue; - } - status = NvCtrlGetAttribute(t, a->attr, &val); if (status != NvCtrlSuccess) { continue; @@ -468,21 +462,14 @@ int nv_write_config_file(const char *filename, const CtrlSystem *system, continue; } - /* Make sure this is a display attribute */ + /* Make sure this is a display and writable attribute */ status = NvCtrlGetAttributePerms(t, a->type, a->attr, &perms); - if (status != NvCtrlSuccess || + if (status != NvCtrlSuccess || !(perms.write) || !(perms.valid_targets & CTRL_TARGET_PERM_BIT(DISPLAY_TARGET))) { continue; } - status = NvCtrlGetValidAttributeValues(t, a->attr, &valid); - if (status != NvCtrlSuccess || - !(valid.permissions & ATTRIBUTE_TYPE_WRITE) || - !(valid.permissions & ATTRIBUTE_TYPE_DISPLAY)) { - continue; - } - status = NvCtrlGetAttribute(t, a->attr, &val); if (status == NvCtrlSuccess) { fprintf(stream, "%s%c%s=%d\n", prefix, diff --git a/src/gtk+-2.x/ctkcolorcontrols.c b/src/gtk+-2.x/ctkcolorcontrols.c index c57bf56..db2d9e7 100644 --- a/src/gtk+-2.x/ctkcolorcontrols.c +++ b/src/gtk+-2.x/ctkcolorcontrols.c @@ -42,13 +42,15 @@ ctk_color_controls_class_init(CtkColorControlsClass *ctk_object_class); static void ctk_color_controls_finalize(GObject *object); static gboolean build_color_space_table(CtkColorControls *ctk_color_controls, - NVCTRLAttributeValidValuesRec valid); + CtrlAttributeValidValues valid); static gint map_nvctrl_value_to_table(CtkColorControls *ctk_color_controls, gint val); -static -gboolean update_color_space_menu_info(CtkColorControls *ctk_color_controls); +static gboolean update_color_space_menu_info(CtkColorControls *ctk_color_controls); +static gboolean update_color_range_menu_info(CtkColorControls *ctk_color_controls); +static gboolean update_current_color_space_menu_info(CtkColorControls *ctk_color_controls); +static gboolean update_current_color_range_menu_info(CtkColorControls *ctk_color_controls); static void setup_reset_button(CtkColorControls *ctk_color_controls); @@ -59,30 +61,36 @@ static void color_range_menu_changed(GtkWidget *widget, static void color_control_update_received(GObject *object, CtrlEvent *event, gpointer user_data); -static void setup_color_range_dropdown(CtkColorControls *ctk_color_controls); -static -void post_color_range_update(CtkColorControls *ctk_color_controls, - gint color_range); - -static -void post_color_space_update(CtkColorControls *ctk_color_controls, - gint color_space); +static void post_current_color_range_update(CtkColorControls *ctk_color_controls, + gint color_range); +static void post_current_color_space_update(CtkColorControls *ctk_color_controls, + gint color_space); +static void post_color_range_update(CtkColorControls *ctk_color_controls, + gint color_range); +static void post_color_space_update(CtkColorControls *ctk_color_controls, + gint color_space); /* macros */ #define FRAME_PADDING 5 /* help text */ static const char * __color_controls_help = -"The Color Controls allow changing the color space and color range " -"of the display device."; +"The Color Controls allow changing the preferred color space and color range " +"of the display device. These settings may be overridden depending on the " +"current mode and color space on the display device."; static const char * __color_space_help = "The possible values for Color Space vary depending on the capabilities of " "the display device and the GPU, but may contain \"RGB\", \"YCbCr422\", " -"and \"YCbCr444\"."; +"and \"YCbCr444\". If an HDMI 2.0 4K@60Hz mode is in use and the display " +"device or GPU is incapable of driving the mode in RGB, the preferred color " +"space is preserved, but the current color space is overridden to YCbCr420."; static const char * __color_range_help = -"The possible values for Color Range are \"Limited\" and \"Full\"."; +"The possible values for Color Range are \"Limited\" and \"Full\". " +"If the current color space only allows a limited color range, the " +"preferred color range is preserved, but the current color range " +"is overridden to limited range."; GType ctk_color_controls_get_type(void) { @@ -145,20 +153,20 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, { GObject *object; CtkColorControls *ctk_color_controls; - GtkWidget *frame, *hbox, *label; + GtkWidget *frame, *vbox, *hbox, *label; GtkWidget *table, *separator; CtkDropDownMenu *menu; ReturnStatus ret1, ret2; - NVCTRLAttributeValidValuesRec valid1, valid2; + CtrlAttributeValidValues valid_color_spaces, valid_throwaway; gint i; /* check if color configuration is supported */ ret1 = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_COLOR_SPACE, - &valid1); + &valid_color_spaces); ret2 = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_COLOR_RANGE, - &valid2); + &valid_throwaway); if ((ret1 != NvCtrlSuccess) || (ret2 != NvCtrlSuccess)) { return NULL; @@ -177,8 +185,27 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, ctk_color_controls->reset_button = reset_button; ctk_color_controls->name = strdup(name); + /* check if querying current color space and range are supported */ + ret1 = NvCtrlGetValidAttributeValues(ctrl_target, + NV_CTRL_CURRENT_COLOR_SPACE, + &valid_throwaway); + ret2 = NvCtrlGetValidAttributeValues(ctrl_target, + NV_CTRL_CURRENT_COLOR_RANGE, + &valid_throwaway); + + if ((ret1 != NvCtrlSuccess) || (ret2 != NvCtrlSuccess)) { + /* + * Fall back to querying the preferred color space and range, to + * support older drivers which don't support querying the current + * color range. + */ + ctk_color_controls->current_color_attributes_supported = FALSE; + } else { + ctk_color_controls->current_color_attributes_supported = TRUE; + } + /* build a table holding available color space */ - if (!build_color_space_table(ctk_color_controls, valid1)) { + if (!build_color_space_table(ctk_color_controls, valid_color_spaces)) { return NULL; } @@ -191,7 +218,7 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, frame = gtk_frame_new("Color Controls"); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); - table = gtk_table_new(1, 6, FALSE); + table = gtk_table_new(3, 4, FALSE); gtk_container_add(GTK_CONTAINER(frame), table); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 15); @@ -216,7 +243,7 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, } } ctk_color_controls->color_space_menu = GTK_WIDGET(menu); - ctk_config_set_tooltip(ctk_config, + ctk_config_set_tooltip(ctk_config, ctk_color_controls->color_space_menu, __color_space_help); @@ -247,20 +274,39 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, ctk_color_controls->color_space_menu, FALSE, FALSE, 0); - /* V-bar */ + /* Build current color space widget */ hbox = gtk_hbox_new(FALSE, 0); - separator = gtk_vseparator_new(); - gtk_box_pack_start(GTK_BOX(hbox), separator, FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 0, 1, GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + label = gtk_label_new("Current Color Space: "); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 0, 1, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + label = gtk_label_new(NULL); + ctk_color_controls->current_color_space_txt = label; + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + /* H-bar */ + vbox = gtk_vbox_new(FALSE, 0); + separator = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0); + gtk_table_attach(GTK_TABLE(table), vbox, 0, 4, 1, 2, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); /* Build color widgets & pack them in table */ /* dropdown list for color range */ - - ctk_color_controls->color_range_menu = + + menu = (CtkDropDownMenu *) ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY); - - ctk_config_set_tooltip(ctk_config, + ctk_drop_down_menu_append_item(menu, "Full", 0); + ctk_drop_down_menu_append_item(menu, "Limited", 1); + ctk_color_controls->color_range_menu = GTK_WIDGET(menu); + + ctk_config_set_tooltip(ctk_config, ctk_color_controls->color_range_menu, __color_range_help); @@ -270,7 +316,7 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, /* Packing label & dropdown */ hbox = gtk_hbox_new(FALSE, 0); - gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 0, 1, + gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); label = gtk_label_new("Color Range: "); @@ -278,12 +324,28 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); hbox = gtk_hbox_new(FALSE, 0); - gtk_table_attach(GTK_TABLE(table), hbox, 4, 5, 0, 1, + gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3, GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); gtk_box_pack_start(GTK_BOX(hbox), ctk_color_controls->color_range_menu, FALSE, FALSE, 0); + /* Build CurrentMode widget */ + hbox = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 2, 3, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + label = gtk_label_new("Current Color Range: "); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 2, 3, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + label = gtk_label_new(NULL); + ctk_color_controls->current_color_range_txt = label; + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show_all(GTK_WIDGET(object)); ctk_color_controls_setup(ctk_color_controls); @@ -297,6 +359,17 @@ GtkWidget* ctk_color_controls_new(CtrlTarget *ctrl_target, G_CALLBACK(color_control_update_received), (gpointer) ctk_color_controls); + if (ctk_color_controls->current_color_attributes_supported) { + g_signal_connect(G_OBJECT(ctk_event), + CTK_EVENT_NAME(NV_CTRL_CURRENT_COLOR_RANGE), + G_CALLBACK(color_control_update_received), + (gpointer) ctk_color_controls); + g_signal_connect(G_OBJECT(ctk_event), + CTK_EVENT_NAME(NV_CTRL_CURRENT_COLOR_SPACE), + G_CALLBACK(color_control_update_received), + (gpointer) ctk_color_controls); + } + return GTK_WIDGET(object); } /* ctk_color_controls_new() */ @@ -318,7 +391,6 @@ static void setup_reset_button(CtkColorControls *ctk_color_controls) return; } - /* The color space menu is always available */ color_space_menu = CTK_DROP_DOWN_MENU(ctk_color_controls->color_space_menu); history = ctk_drop_down_menu_get_current_value(color_space_menu); @@ -327,15 +399,10 @@ static void setup_reset_button(CtkColorControls *ctk_color_controls) goto enable; } - /* Color range is dependent on the color space */ - if (ctk_widget_get_sensitive(ctk_color_controls->color_range_menu)) { - color_range_menu = - CTK_DROP_DOWN_MENU(ctk_color_controls->color_range_menu); - history = ctk_drop_down_menu_get_current_value(color_range_menu); - val = ctk_color_controls->color_range_table[history]; - if (val != NV_CTRL_COLOR_RANGE_FULL) { - goto enable; - } + color_range_menu = CTK_DROP_DOWN_MENU(ctk_color_controls->color_range_menu); + history = ctk_drop_down_menu_get_current_value(color_range_menu); + if (val != NV_CTRL_COLOR_RANGE_FULL) { + goto enable; } /* Don't disable reset button here, since other settings that are not @@ -366,26 +433,162 @@ void ctk_color_controls_setup(CtkColorControls *ctk_color_controls) gtk_widget_hide(ctk_color_controls->color_controls_box); } + if (!update_color_range_menu_info(ctk_color_controls)) { + gtk_widget_set_sensitive(ctk_color_controls->color_controls_box, FALSE); + gtk_widget_hide(ctk_color_controls->color_controls_box); + } + + if (ctk_color_controls->current_color_attributes_supported && + !update_current_color_space_menu_info(ctk_color_controls)) { + gtk_widget_set_sensitive(ctk_color_controls->color_controls_box, FALSE); + gtk_widget_hide(ctk_color_controls->color_controls_box); + } + + if (ctk_color_controls->current_color_attributes_supported && + !update_current_color_range_menu_info(ctk_color_controls)) { + gtk_widget_set_sensitive(ctk_color_controls->color_controls_box, FALSE); + gtk_widget_hide(ctk_color_controls->color_controls_box); + } + setup_reset_button(ctk_color_controls); } /* ctk_color_controls_setup() */ +static void update_current_color_range_text(CtkColorControls *ctk_color_controls, + gint color_range) +{ + switch(color_range) { + case NV_CTRL_CURRENT_COLOR_RANGE_FULL: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_range_txt), + "Full"); + break; + case NV_CTRL_CURRENT_COLOR_RANGE_LIMITED: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_range_txt), + "Limited"); + break; + default: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_range_txt), + "Unknown"); + break; + } +} /* update_current_color_range_text() */ + +static gboolean update_current_color_range_menu_info(CtkColorControls *ctk_color_controls) +{ + CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; + gint current_color_range = NV_CTRL_CURRENT_COLOR_RANGE_FULL; + + if (NvCtrlSuccess != + NvCtrlGetAttribute(ctrl_target, + NV_CTRL_CURRENT_COLOR_RANGE, + ¤t_color_range)) { + return FALSE; + } + + update_current_color_range_text(ctk_color_controls, current_color_range); + + return TRUE; + +} /* update_current_color_range_menu_info() */ + +static gboolean update_color_range_menu_info(CtkColorControls *ctk_color_controls) +{ + CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; + gint color_range = NV_CTRL_COLOR_RANGE_FULL; + + /* color space */ + if (NvCtrlSuccess != + NvCtrlGetAttribute(ctrl_target, + NV_CTRL_COLOR_RANGE, + &color_range)) { + return FALSE; + } + + g_signal_handlers_block_by_func + (G_OBJECT(ctk_color_controls->color_range_menu), + G_CALLBACK(color_range_menu_changed), + (gpointer) ctk_color_controls); + + ctk_drop_down_menu_set_current_value + (CTK_DROP_DOWN_MENU(ctk_color_controls->color_range_menu), color_range); + + g_signal_handlers_unblock_by_func + (G_OBJECT(ctk_color_controls->color_range_menu), + G_CALLBACK(color_range_menu_changed), + (gpointer) ctk_color_controls); + + if (!ctk_color_controls->current_color_attributes_supported) { + /* + * If querying the current color space isn't supported, fall back to + * displaying the preferred color space as the current color space. + */ + update_current_color_range_text(ctk_color_controls, color_range); + } + + return TRUE; + +} /* update_color_range_menu_info() */ + +static void update_current_color_space_text(CtkColorControls *ctk_color_controls, + gint color_space) +{ + switch(color_space) { + case NV_CTRL_CURRENT_COLOR_SPACE_YCbCr420: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_space_txt), + "YCbCr420"); + break; + case NV_CTRL_CURRENT_COLOR_SPACE_YCbCr422: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_space_txt), + "YCbCr422"); + break; + case NV_CTRL_CURRENT_COLOR_SPACE_YCbCr444: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_space_txt), + "YCbCr444"); + break; + case NV_CTRL_CURRENT_COLOR_SPACE_RGB: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_space_txt), + "RGB"); + break; + default: + gtk_label_set_text(GTK_LABEL(ctk_color_controls->current_color_space_txt), + "Unknown"); + break; + } +} /* update_current_color_space_text() */ + +static gboolean update_current_color_space_menu_info(CtkColorControls *ctk_color_controls) +{ + CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; + gint current_color_space = NV_CTRL_CURRENT_COLOR_SPACE_RGB; + + if (NvCtrlSuccess != + NvCtrlGetAttribute(ctrl_target, + NV_CTRL_CURRENT_COLOR_SPACE, + ¤t_color_space)) { + return FALSE; + } + + update_current_color_space_text(ctk_color_controls, current_color_space); + + return TRUE; + +} /* update_current_color_space_menu_info() */ static gboolean update_color_space_menu_info(CtkColorControls *ctk_color_controls) { CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; - gint color_space = NV_CTRL_COLOR_SPACE_RGB; + gint color_space_nvctrl, color_space; /* color space */ if (NvCtrlSuccess != NvCtrlGetAttribute(ctrl_target, NV_CTRL_COLOR_SPACE, - &color_space)) { + &color_space_nvctrl)) { return FALSE; } color_space = map_nvctrl_value_to_table(ctk_color_controls, - color_space); + color_space_nvctrl); g_signal_handlers_block_by_func (G_OBJECT(ctk_color_controls->color_space_menu), @@ -400,14 +603,34 @@ static gboolean update_color_space_menu_info(CtkColorControls *ctk_color_control G_CALLBACK(color_space_menu_changed), (gpointer) ctk_color_controls); - /* dynamically regenerate color range dropdown */ - setup_color_range_dropdown(ctk_color_controls); + if (!ctk_color_controls->current_color_attributes_supported) { + /* + * If querying the current color space isn't supported, fall back to + * displaying the preferred color space as the current color space. + */ + update_current_color_space_text(ctk_color_controls, color_space_nvctrl); + } return TRUE; } /* update_color_space_menu_info() */ static +void post_current_color_range_update(CtkColorControls *ctk_color_controls, + gint color_range) +{ + static const char *color_range_table[] = { + "Full", /* NV_CTRL_CURRENT_COLOR_RANGE_FULL */ + "Limited", /* NV_CTRL_CURRENT_COLOR_RANGE_LIMITED */ + }; + + ctk_config_statusbar_message(ctk_color_controls->ctk_config, + "Current Color Range set to %s for %s.", + color_range_table[color_range], + ctk_color_controls->name); +} + +static void post_color_range_update(CtkColorControls *ctk_color_controls, gint color_range) { @@ -424,11 +647,28 @@ void post_color_range_update(CtkColorControls *ctk_color_controls, } static +void post_current_color_space_update(CtkColorControls *ctk_color_controls, + gint color_space) +{ + static const char *color_space_table[] = { + "RGB", /* NV_CTRL_CURRENT_COLOR_SPACE_RGB */ + "YCbCr422", /* NV_CTRL_CURRENT_COLOR_SPACE_YCbCr422 */ + "YCbCr444", /* NV_CTRL_CURRENT_COLOR_SPACE_YCbCr444 */ + "YCbCr420" /* NV_CTRL_CURRENT_COLOR_SPACE_YCbCr420 */ + }; + + ctk_config_statusbar_message(ctk_color_controls->ctk_config, + "Current Color Space set to %s for %s.", + color_space_table[color_space], + ctk_color_controls->name); +} + +static void post_color_space_update(CtkColorControls *ctk_color_controls, gint color_space) { static const char *color_space_table[] = { - "RGB", /* NV_CTRL_COLOR_SPACE_RGB */ + "RGB", /* NV_CTRL_COLOR_SPACE_RGB */ "YCbCr422", /* NV_CTRL_COLOR_SPACE_YCbCr422 */ "YCbCr444" /* NV_CTRL_COLOR_SPACE_YCbCr444 */ }; @@ -447,10 +687,7 @@ static void color_range_menu_changed(GtkWidget *widget, CTK_COLOR_CONTROLS(user_data); CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(widget); - gint history, color_range = NV_CTRL_COLOR_RANGE_FULL; - - history = ctk_drop_down_menu_get_current_value(menu); - color_range = ctk_color_controls->color_range_table[history]; + gint color_range = ctk_drop_down_menu_get_current_value(menu); NvCtrlSetAttribute(ctrl_target, NV_CTRL_COLOR_RANGE, @@ -459,6 +696,13 @@ static void color_range_menu_changed(GtkWidget *widget, /* reflecting the change to statusbar message and the reset button */ post_color_range_update(ctk_color_controls, color_range); + if (!ctk_color_controls->current_color_attributes_supported) { + /* + * If querying the current color space isn't supported, fall back to + * displaying the preferred color space as the current color space. + */ + update_current_color_range_text(ctk_color_controls, color_range); + } } /* color_range_menu_changed() */ @@ -469,29 +713,33 @@ static void color_space_menu_changed(GtkWidget *widget, CTK_COLOR_CONTROLS(user_data); CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(widget); - gint history, color_space = NV_CTRL_COLOR_SPACE_RGB; - + gint history, color_space_nvctrl, color_space; + history = ctk_drop_down_menu_get_current_value(menu); - color_space = ctk_color_controls->color_space_table[history]; + color_space_nvctrl = ctk_color_controls->color_space_table[history]; NvCtrlSetAttribute(ctrl_target, NV_CTRL_COLOR_SPACE, - color_space); + color_space_nvctrl); color_space = map_nvctrl_value_to_table(ctk_color_controls, - color_space); - - /* Regenerate the color range dropdown to reflect the new color space */ - setup_color_range_dropdown(ctk_color_controls); + color_space_nvctrl); post_color_space_update(ctk_color_controls, color_space); + if (!ctk_color_controls->current_color_attributes_supported) { + /* + * If querying the current color space isn't supported, fall back to + * displaying the preferred color space as the current color space. + */ + update_current_color_space_text(ctk_color_controls, color_space_nvctrl); + } } /* color_space_menu_changed() */ /* - * ctk_color_controls_reset() - Resets the color range and + * ctk_color_controls_reset() - Resets the color range and * & color space when Reset HW Defaults is clicked */ void ctk_color_controls_reset(CtkColorControls *ctk_color_controls) @@ -557,6 +805,12 @@ static void color_control_update_received(GObject *object, /* update status bar message */ switch (event->int_attr.attribute) { + case NV_CTRL_CURRENT_COLOR_RANGE: + post_current_color_range_update(ctk_object, event->int_attr.value); + break; + case NV_CTRL_CURRENT_COLOR_SPACE: + post_current_color_space_update(ctk_object, event->int_attr.value); + break; case NV_CTRL_COLOR_RANGE: post_color_range_update(ctk_object, event->int_attr.value); break; @@ -572,12 +826,12 @@ static void color_control_update_received(GObject *object, * modes supported by the DFP. */ static gboolean build_color_space_table(CtkColorControls *ctk_color_controls, - NVCTRLAttributeValidValuesRec valid) + CtrlAttributeValidValues valid) { gint i, n = 0, color_space_count = 0; - gint mask = valid.u.bits.ints; + gint mask = valid.allowed_ints; - if (valid.type != ATTRIBUTE_TYPE_INT_BITS) { + if (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS) { return False; } @@ -595,7 +849,7 @@ static gboolean build_color_space_table(CtkColorControls *ctk_color_controls, } for (i = 0, n = 0; n < ctk_color_controls->color_space_table_size; i++) { - if (valid.u.bits.ints & (1 << i)) { + if (valid.allowed_ints & (1 << i)) { ctk_color_controls->color_space_table[n] = i; n++; } @@ -605,105 +859,6 @@ static gboolean build_color_space_table(CtkColorControls *ctk_color_controls, } /* build_color_space_table() */ - - -/* - * setup_color_range_dropdown() - dynamically generate dropdown list for - * color range depending on selected color space. - */ -static void setup_color_range_dropdown(CtkColorControls *ctk_color_controls) -{ - CtrlTarget *ctrl_target = ctk_color_controls->ctrl_target; - gint i, n = 0, color_range_count = 0; - gint mask, val; - gboolean enable = FALSE; - ReturnStatus ret; - NVCTRLAttributeValidValuesRec valid; - CtkDropDownMenu *d; - - ret = NvCtrlGetValidAttributeValues(ctrl_target, - NV_CTRL_COLOR_RANGE, - &valid); - if (ret != NvCtrlSuccess) { - goto done; - } - - if (valid.type != ATTRIBUTE_TYPE_INT_BITS) { - goto done; - } - mask = valid.u.bits.ints; - /* count no. of supported color space */ - while(mask) { - mask = mask & (mask - 1); - color_range_count++; - } - - if (ctk_color_controls->color_range_table) { - free(ctk_color_controls->color_range_table); - ctk_color_controls->color_range_table_size = 0; - } - ctk_color_controls->color_range_table_size = color_range_count; - ctk_color_controls->color_range_table = - calloc(color_range_count, sizeof(ctk_color_controls->color_range_table[0])); - if (!ctk_color_controls->color_range_table) { - goto done; - } - - for (i = 0, n = 0; n < ctk_color_controls->color_range_table_size; i++) { - if (valid.u.bits.ints & (1 << i)) { - ctk_color_controls->color_range_table[n] = i; - n++; - } - } - - /* dropdown list for color range */ - d = (CtkDropDownMenu *) ctk_color_controls->color_range_menu; - - g_signal_handlers_block_by_func - (G_OBJECT(ctk_color_controls->color_range_menu), - G_CALLBACK(color_range_menu_changed), - (gpointer) ctk_color_controls); - - ctk_drop_down_menu_reset(d); - - for (i = 0; i < ctk_color_controls->color_range_table_size; i++) { - switch (ctk_color_controls->color_range_table[i]) { - case NV_CTRL_COLOR_RANGE_FULL: - ctk_drop_down_menu_append_item(d, "Full", i); - break; - default: - case NV_CTRL_COLOR_RANGE_LIMITED: - ctk_drop_down_menu_append_item(d, "Limited", i); - break; - } - } - - /* color range */ - if (NvCtrlSuccess != - NvCtrlGetAttribute(ctrl_target, - NV_CTRL_COLOR_RANGE, - &val)) { - val = NV_CTRL_COLOR_RANGE_FULL; - } - - ctk_drop_down_menu_set_current_value(d, val); - - g_signal_handlers_unblock_by_func - (G_OBJECT(ctk_color_controls->color_range_menu), - G_CALLBACK(color_range_menu_changed), - (gpointer) ctk_color_controls); - - /* If dropdown only has one item, disable it */ - if (ctk_color_controls->color_range_table_size <= 1) { - goto done; - } - enable = TRUE; - -done: - gtk_widget_set_sensitive(ctk_color_controls->color_range_menu, enable); -} /* setup_color_range_dropdown() */ - - static gint map_nvctrl_value_to_table(CtkColorControls *ctk_color_controls, gint val) { diff --git a/src/gtk+-2.x/ctkcolorcontrols.h b/src/gtk+-2.x/ctkcolorcontrols.h index abeb9f5..3eb8517 100644 --- a/src/gtk+-2.x/ctkcolorcontrols.h +++ b/src/gtk+-2.x/ctkcolorcontrols.h @@ -59,14 +59,15 @@ struct _CtkColorControls GtkWidget *color_controls_box; GtkWidget *color_range_menu; + GtkWidget *current_color_range_txt; GtkWidget *color_space_menu; + GtkWidget *current_color_space_txt; gint *color_space_table; gint color_space_table_size; - gint *color_range_table; - gint color_range_table_size; gint default_color_config; gint default_color_space; + gboolean current_color_attributes_supported; char *name; }; diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.c b/src/gtk+-2.x/ctkdisplayconfig-utils.c index 7d7db48..c959dce 100644 --- a/src/gtk+-2.x/ctkdisplayconfig-utils.c +++ b/src/gtk+-2.x/ctkdisplayconfig-utils.c @@ -2762,36 +2762,36 @@ static nvDisplayPtr gpu_add_display_from_server(nvGpuPtr gpu, unsigned int valid1 = 0; unsigned int valid2 = 0; unsigned int valid3 = 0; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; ret = NvCtrlGetValidAttributeValues(gpu->ctrl_target, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, &valid); if ((ret != NvCtrlSuccess) || - (valid.type != ATTRIBUTE_TYPE_INT_BITS)) { + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { valid1 = 0; } else { - valid1 = valid.u.bits.ints; + valid1 = valid.allowed_ints; } ret = NvCtrlGetValidAttributeValues(gpu->ctrl_target, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2, &valid); if ((ret != NvCtrlSuccess) || - (valid.type != ATTRIBUTE_TYPE_INT_BITS)) { + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { valid2 = 0; } else { - valid2 = valid.u.bits.ints; + valid2 = valid.allowed_ints; } ret = NvCtrlGetValidAttributeValues(gpu->ctrl_target, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3, &valid); if ((ret != NvCtrlSuccess) || - (valid.type != ATTRIBUTE_TYPE_INT_BITS)) { + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { valid3 = 0; } else { - valid3 = valid.u.bits.ints; + valid3 = valid.allowed_ints; } /* Count the number of valid modes there are */ @@ -3232,17 +3232,17 @@ static Bool layout_add_gpu_from_server(nvLayoutPtr layout, } } else { - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; ret = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_BASE_MOSAIC, &valid); if ((ret == NvCtrlSuccess) && - (valid.type == ATTRIBUTE_TYPE_INT_BITS)) { + (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { - if (valid.u.bits.ints & NV_CTRL_BASE_MOSAIC_FULL) { + if (valid.allowed_ints & NV_CTRL_BASE_MOSAIC_FULL) { gpu->mosaic_type = MOSAIC_TYPE_BASE_MOSAIC; - } else if (valid.u.bits.ints & NV_CTRL_BASE_MOSAIC_LIMITED) { + } else if (valid.allowed_ints & NV_CTRL_BASE_MOSAIC_LIMITED) { gpu->mosaic_type = MOSAIC_TYPE_BASE_MOSAIC_LIMITED; } diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c index b6c5450..8a1bb7c 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.c +++ b/src/gtk+-2.x/ctkdisplayconfig.c @@ -1197,7 +1197,7 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target, ReturnStatus ret; const char *stereo_mode_str; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; int stereo_mode, stereo_mode_max = NV_CTRL_STEREO_MAX; /* @@ -1565,7 +1565,7 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target, * before the change was made. The newest at that time was HDMI_3D. */ - if (valid.type == ATTRIBUTE_TYPE_INTEGER) { + if (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INTEGER) { stereo_mode_max = NV_CTRL_STEREO_HDMI_3D; } @@ -1578,9 +1578,11 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target, break; } - if (stereo_mode_str && (valid.type == ATTRIBUTE_TYPE_INTEGER || - (valid.type == ATTRIBUTE_TYPE_INT_BITS && - valid.u.bits.ints & (1 << stereo_mode)))) { + if (stereo_mode_str && + ((valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INTEGER) || + (((valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS) && + (valid.allowed_ints & (1 << stereo_mode)))))) { + ctk_object->stereo_table[ctk_object->stereo_table_size++] = stereo_mode; ctk_combo_box_text_append_text( diff --git a/src/gtk+-2.x/ctkditheringcontrols.c b/src/gtk+-2.x/ctkditheringcontrols.c index 3ddd6fb..2467bb9 100644 --- a/src/gtk+-2.x/ctkditheringcontrols.c +++ b/src/gtk+-2.x/ctkditheringcontrols.c @@ -934,7 +934,7 @@ static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_c { CtrlTarget *ctrl_target = ctk_dithering_controls->ctrl_target; ReturnStatus ret; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; gint i, n = 0, num_of_modes = 0, mask; if (ctk_dithering_controls->dithering_mode_table_size > 0 && @@ -948,7 +948,8 @@ static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_c NV_CTRL_DITHERING_MODE, &valid); - if (ret != NvCtrlSuccess || valid.type != ATTRIBUTE_TYPE_INT_BITS) { + if ((ret != NvCtrlSuccess) || + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { /* * We do not have valid information to build a mode table * so we need to create default data for the placeholder menu. @@ -966,7 +967,7 @@ static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_c } /* count no. of supported modes */ - mask = valid.u.bits.ints; + mask = valid.allowed_ints; while(mask) { mask = mask & (mask - 1); num_of_modes++; @@ -981,7 +982,7 @@ static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_c } for (i = 0; i < num_of_modes; i++) { - if (valid.u.bits.ints & (1 << i)) { + if (valid.allowed_ints & (1 << i)) { ctk_dithering_controls->dithering_mode_table[n] = i; n++; } diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c index 76b0e97..3bf820c 100644 --- a/src/gtk+-2.x/ctkevent.c +++ b/src/gtk+-2.x/ctkevent.c @@ -281,6 +281,8 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) MAKE_SIGNAL(NV_CTRL_GVI_TEST_MODE); MAKE_SIGNAL(NV_CTRL_COLOR_SPACE); MAKE_SIGNAL(NV_CTRL_COLOR_RANGE); + MAKE_SIGNAL(NV_CTRL_CURRENT_COLOR_SPACE); + MAKE_SIGNAL(NV_CTRL_CURRENT_COLOR_RANGE); MAKE_SIGNAL(NV_CTRL_DITHERING); MAKE_SIGNAL(NV_CTRL_DITHERING_MODE); MAKE_SIGNAL(NV_CTRL_DITHERING_DEPTH); @@ -321,6 +323,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) MAKE_SIGNAL(NV_CTRL_MULTIGPU_MASTER_POSSIBLE); MAKE_SIGNAL(NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE); MAKE_SIGNAL(NV_CTRL_XV_SYNC_TO_DISPLAY_ID); + MAKE_SIGNAL(NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID); MAKE_SIGNAL(NV_CTRL_BACKLIGHT_BRIGHTNESS); MAKE_SIGNAL(NV_CTRL_GPU_LOGO_BRIGHTNESS); MAKE_SIGNAL(NV_CTRL_GPU_SLI_LOGO_BRIGHTNESS); @@ -333,6 +336,8 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) MAKE_SIGNAL(NV_CTRL_VIDEO_DECODER_UTILIZATION); MAKE_SIGNAL(NV_CTRL_GPU_OVER_VOLTAGE_OFFSET); MAKE_SIGNAL(NV_CTRL_GPU_CURRENT_CORE_VOLTAGE); + MAKE_SIGNAL(NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR); + MAKE_SIGNAL(NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL); #undef MAKE_SIGNAL /* @@ -342,7 +347,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) * knows about. */ -#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GPU_CURRENT_CORE_VOLTAGE +#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID #warning "There are attributes that do not emit signals!" #endif diff --git a/src/gtk+-2.x/ctkframelock.c b/src/gtk+-2.x/ctkframelock.c index 63acf72..57d8f1f 100644 --- a/src/gtk+-2.x/ctkframelock.c +++ b/src/gtk+-2.x/ctkframelock.c @@ -1214,7 +1214,7 @@ static void list_entry_update_gpu_controls(CtkFramelock *ctk_framelock, static gboolean framelock_refresh_rates_compatible(int server, int client) { - int range; + double range; /* client can be 0, e.g. if querying NV_CTRL_REFRESH_RATE{,_3} fails, * or if the display device is disabled. */ @@ -1222,11 +1222,11 @@ static gboolean framelock_refresh_rates_compatible(int server, int client) return FALSE; } - range = ABS(((int64_t)(server - client) * 1000000) / client); + range = ABS(((double)(server - client) * 1000000.0) / client); /* Framelock can be achieved if the range between refresh rates is less * than 50 ppm */ - return range <= 50; + return range <= 50.0; } /** list_entry_update_display_controls() ***************************** @@ -4106,7 +4106,7 @@ static void update_display_config(nvListEntryPtr display_entry, int config) { nvDisplayDataPtr display_data = (nvDisplayDataPtr)display_entry->data; ReturnStatus ret; - NVCTRLAttributeValidValuesRec valid_config; + CtrlAttributeValidValues valid_config; gboolean serverable = FALSE; gboolean clientable = FALSE; @@ -4119,12 +4119,12 @@ static void update_display_config(nvListEntryPtr display_entry, int config) &valid_config); if (ret == NvCtrlSuccess && - (valid_config.type == ATTRIBUTE_TYPE_INT_BITS)) { - if (valid_config.u.bits.ints & + (valid_config.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { + if (valid_config.allowed_ints & (1<<NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_CLIENT)) { clientable = TRUE; } - if (valid_config.u.bits.ints & + if (valid_config.allowed_ints & (1<<NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_SERVER)) { serverable = TRUE; } @@ -4601,7 +4601,7 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target, GtkWidget *combo_box; GtkWidget *button; GtkWidget *image; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; /* make sure we have a valid target */ @@ -4742,7 +4742,7 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target, ret = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_FRAMELOCK_VIDEO_MODE, &valid); - if ((ret == NvCtrlSuccess) && (valid.permissions & ATTRIBUTE_TYPE_WRITE)) { + if ((ret == NvCtrlSuccess) && valid.permissions.write) { ctk_framelock->video_mode_read_only = FALSE; } @@ -4915,10 +4915,11 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target, * range from NV-CONTROL */ - if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_RANGE)) { - valid.type = ATTRIBUTE_TYPE_RANGE; - valid.u.range.min = 0; - valid.u.range.max = 4; + if ((ret != NvCtrlSuccess) || + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_RANGE)) { + valid.valid_type = CTRL_ATTRIBUTE_VALID_TYPE_RANGE; + valid.range.min = 0; + valid.range.max = 4; } if (NvCtrlSuccess != @@ -4931,8 +4932,8 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target, hbox = gtk_hbox_new(FALSE, 5); label = gtk_label_new("Sync Interval:"); - adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(val, valid.u.range.min, - valid.u.range.max, + adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(val, valid.range.min, + valid.range.max, 1, 1, 0)); scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment)); gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), val); diff --git a/src/gtk+-2.x/ctkgvo-sync.c b/src/gtk+-2.x/ctkgvo-sync.c index 125ad39..72e5bfe 100644 --- a/src/gtk+-2.x/ctkgvo-sync.c +++ b/src/gtk+-2.x/ctkgvo-sync.c @@ -331,7 +331,7 @@ GtkWidget* ctk_gvo_sync_new(CtrlTarget *ctrl_target, GtkWidget *table, *menu; gint val, i; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; ReturnStatus ret; gint row; @@ -553,7 +553,9 @@ GtkWidget* ctk_gvo_sync_new(CtrlTarget *ctrl_target, NV_CTRL_GVO_SYNC_DELAY_PIXELS, &valid); - if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE)) { + if ((ret == NvCtrlSuccess) && + (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_RANGE)) { + ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_GVO_SYNC_DELAY_PIXELS, &val); if (ret != NvCtrlSuccess) val = 0; @@ -571,8 +573,8 @@ GtkWidget* ctk_gvo_sync_new(CtrlTarget *ctrl_target, GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING); ctk_gvo_sync->hsync_delay_spin_button = - gtk_spin_button_new_with_range(valid.u.range.min, - valid.u.range.max, 1); + gtk_spin_button_new_with_range(valid.range.min, + valid.range.max, 1); ctk_config_set_tooltip(ctk_config, ctk_gvo_sync->hsync_delay_spin_button, @@ -608,7 +610,9 @@ GtkWidget* ctk_gvo_sync_new(CtrlTarget *ctrl_target, NV_CTRL_GVO_SYNC_DELAY_LINES, &valid); - if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE)) { + if ((ret == NvCtrlSuccess) && + (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_RANGE)) { + ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_GVO_SYNC_DELAY_LINES, &val); if (ret != NvCtrlSuccess) val = 0; @@ -626,8 +630,8 @@ GtkWidget* ctk_gvo_sync_new(CtrlTarget *ctrl_target, GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING); ctk_gvo_sync->vsync_delay_spin_button = - gtk_spin_button_new_with_range(valid.u.range.min, - valid.u.range.max, 1); + gtk_spin_button_new_with_range(valid.range.min, + valid.range.max, 1); ctk_config_set_tooltip(ctk_config, ctk_gvo_sync->vsync_delay_spin_button, diff --git a/src/gtk+-2.x/ctkgvo.c b/src/gtk+-2.x/ctkgvo.c index 02f0e7c..14d960b 100644 --- a/src/gtk+-2.x/ctkgvo.c +++ b/src/gtk+-2.x/ctkgvo.c @@ -524,7 +524,7 @@ static void query_video_format_details(CtkGvo *ctk_gvo) { CtrlTarget *ctrl_target = ctk_gvo->ctrl_target; ReturnStatus ret; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; gint i, val; /* Valid output video formats */ @@ -532,30 +532,33 @@ static void query_video_format_details(CtkGvo *ctk_gvo) ret = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, &valid); - if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) { + if ((ret != NvCtrlSuccess) || + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { ctk_gvo->valid_output_video_format_mask[0] = 0; } else { - ctk_gvo->valid_output_video_format_mask[0] = valid.u.bits.ints; + ctk_gvo->valid_output_video_format_mask[0] = valid.allowed_ints; } ret = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2, &valid); - if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) { + if ((ret != NvCtrlSuccess) || + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { ctk_gvo->valid_output_video_format_mask[1] = 0; } else { - ctk_gvo->valid_output_video_format_mask[1] = valid.u.bits.ints; + ctk_gvo->valid_output_video_format_mask[1] = valid.allowed_ints; } ret = NvCtrlGetValidAttributeValues(ctrl_target, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3, &valid); - if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) { + if ((ret != NvCtrlSuccess) || + (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { ctk_gvo->valid_output_video_format_mask[2] = 0; } else { - ctk_gvo->valid_output_video_format_mask[2] = valid.u.bits.ints; + ctk_gvo->valid_output_video_format_mask[2] = valid.allowed_ints; } for (i = 0; videoFormatDetails[i].format != -1; i++) { diff --git a/src/gtk+-2.x/ctkimagesliders.c b/src/gtk+-2.x/ctkimagesliders.c index 50e64c2..e348462 100644 --- a/src/gtk+-2.x/ctkimagesliders.c +++ b/src/gtk+-2.x/ctkimagesliders.c @@ -438,7 +438,7 @@ static void setup_scale(CtkImageSliders *ctk_image_sliders, { CtrlTarget *ctrl_target = ctk_image_sliders->ctrl_target; ReturnStatus ret0, ret1; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; int val; GtkAdjustment *adj = CTK_SCALE(scale)->gtk_adjustment; @@ -449,13 +449,13 @@ static void setup_scale(CtkImageSliders *ctk_image_sliders, ret1 = NvCtrlGetAttribute(ctrl_target, attribute, &val); if ((ret0 == NvCtrlSuccess) && (ret1 == NvCtrlSuccess) && - (valid.type == ATTRIBUTE_TYPE_RANGE)) { + (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_RANGE)) { g_signal_handlers_block_by_func(adj, scale_value_changed, ctk_image_sliders); - ctk_adjustment_set_lower(adj, valid.u.range.min); - ctk_adjustment_set_upper(adj, valid.u.range.max); + ctk_adjustment_set_lower(adj, valid.range.min); + ctk_adjustment_set_upper(adj, valid.range.max); gtk_adjustment_changed(GTK_ADJUSTMENT(adj)); gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), val); diff --git a/src/gtk+-2.x/ctkmultisample.c b/src/gtk+-2.x/ctkmultisample.c index fff5642..2e9eb69 100644 --- a/src/gtk+-2.x/ctkmultisample.c +++ b/src/gtk+-2.x/ctkmultisample.c @@ -32,7 +32,7 @@ /* local prototypes */ static void build_fsaa_translation_table(CtkMultisample *ctk_multisample, - NVCTRLAttributeValidValuesRec valid); + CtrlAttributeValidValues valid); static int map_nv_ctrl_fsaa_value_to_slider(CtkMultisample *ctk_multisample, int value); @@ -229,7 +229,7 @@ GtkWidget *ctk_multisample_new(CtrlTarget *ctrl_target, gint val, app_control, override, enhance, mode, i; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; ReturnStatus ret, ret0; @@ -437,7 +437,7 @@ GtkWidget *ctk_multisample_new(CtrlTarget *ctrl_target, override = !app_control; if ((ret == NvCtrlSuccess) && (ret0 == NvCtrlSuccess) && - (valid.type == ATTRIBUTE_TYPE_RANGE)) { + (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_RANGE)) { /* create "Anisotropic Filtering" frame */ @@ -477,8 +477,8 @@ GtkWidget *ctk_multisample_new(CtrlTarget *ctrl_target, /* Aniso scale */ - min = valid.u.range.min; - max = valid.u.range.max; + min = valid.range.min; + max = valid.range.max; /* create the slider */ adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(val, min, max, @@ -584,21 +584,23 @@ GtkWidget *ctk_multisample_new(CtrlTarget *ctrl_target, */ static void build_fsaa_translation_table(CtkMultisample *ctk_multisample, - NVCTRLAttributeValidValuesRec valid) + CtrlAttributeValidValues valid) { gint i, n = 0; gint index_8xs = -1; gint index_16x = -1; gint index_32x = -1; gint index_32xs = -1; - gint mask = valid.u.bits.ints; + gint mask = valid.allowed_ints; ctk_multisample->fsaa_translation_table_size = 0; memset(ctk_multisample->fsaa_translation_table, 0, sizeof(gint) * (NV_CTRL_FSAA_MODE_MAX + 1)); - if (valid.type != ATTRIBUTE_TYPE_INT_BITS) return; + if (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS) { + return; + } for (i = 0; i <= NV_CTRL_FSAA_MODE_MAX; i++) { if (mask & (1 << i)) { diff --git a/src/gtk+-2.x/ctkopengl.c b/src/gtk+-2.x/ctkopengl.c index ee8781e..494ac37 100644 --- a/src/gtk+-2.x/ctkopengl.c +++ b/src/gtk+-2.x/ctkopengl.c @@ -36,6 +36,8 @@ static void post_allow_flipping_button_toggled(CtkOpenGL *, gboolean); static void post_allow_gsync_button_toggled(CtkOpenGL *, gboolean); +static void post_show_gsync_visual_indicator_button_toggled(CtkOpenGL *, gboolean); + static void post_force_stereo_button_toggled(CtkOpenGL *, gboolean); static void post_show_sli_visual_indicator_button_toggled(CtkOpenGL *, @@ -56,6 +58,8 @@ static void allow_flipping_button_toggled(GtkWidget *, gpointer); static void allow_gsync_button_toggled(GtkWidget *, gpointer); +static void show_gsync_visual_indicator_button_toggled(GtkWidget *, gpointer); + static void force_stereo_button_toggled (GtkWidget *, gpointer); static void xinerama_stereo_button_toggled (GtkWidget *, gpointer); @@ -156,6 +160,12 @@ static const char *__use_conformant_clamping_help = "seams at the edges of textures in some older games such as " "Quake 3."; +static const char *__show_gsync_visual_indicator_help = +"Enabling this option causes OpenGL to draw an indicator showing whether " +"G-SYNC is in use, when an application is swapping using flipping. This " +"option is applied to OpenGL applications that are started after this option " +"is set."; + #define __SYNC_TO_VBLANK (1 << 1) #define __ALLOW_FLIPPING (1 << 2) #define __AA_LINE_GAMMA_VALUE (1 << 3) @@ -169,6 +179,7 @@ static const char *__use_conformant_clamping_help = #define __SHOW_MULTIGPU_VISUAL_INDICATOR (1 << 11) #define __CONFORMANT_CLAMPING (1 << 12) #define __ALLOW_GSYNC (1 << 13) +#define __SHOW_GSYNC_VISUAL_INDICATOR (1 << 14) @@ -219,10 +230,11 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, gint sync_to_vblank; gint flipping_allowed; gint gsync_allowed; + gint show_gsync_visual_indicator; gint force_stereo; gint xinerama_stereo; gint stereo_eyes_exchange; - NVCTRLAttributeValidValuesRec image_settings_valid; + CtrlAttributeValidValues image_settings_valid; gint image_settings_value; gint aa_line_gamma; gint use_conformant_clamping; @@ -232,6 +244,7 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, ReturnStatus ret_sync_to_vblank; ReturnStatus ret_flipping_allowed; ReturnStatus ret_gsync_allowed; + ReturnStatus ret_show_gsync_visual_indicator; ReturnStatus ret_force_stereo; ReturnStatus ret_xinerama_stereo; ReturnStatus ret_stereo_eyes_exchange; @@ -258,6 +271,11 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, NV_CTRL_GSYNC_ALLOWED, &gsync_allowed); + ret_show_gsync_visual_indicator = + NvCtrlGetAttribute(ctrl_target, + NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR, + &show_gsync_visual_indicator); + ret_force_stereo = NvCtrlGetAttribute(ctrl_target, NV_CTRL_FORCE_STEREO, @@ -277,7 +295,7 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, NV_CTRL_IMAGE_SETTINGS, &image_settings_valid); if ((ret_image_settings == NvCtrlSuccess) && - (image_settings_valid.type == ATTRIBUTE_TYPE_RANGE)) { + (image_settings_valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_RANGE)) { ret_image_settings = NvCtrlGetAttribute(ctrl_target, NV_CTRL_IMAGE_SETTINGS, @@ -310,6 +328,7 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, if ((ret_sync_to_vblank != NvCtrlSuccess) && (ret_flipping_allowed != NvCtrlSuccess) && (ret_gsync_allowed != NvCtrlSuccess) && + (ret_show_gsync_visual_indicator != NvCtrlSuccess) && (ret_force_stereo != NvCtrlSuccess) && (ret_xinerama_stereo != NvCtrlSuccess) && (ret_stereo_eyes_exchange != NvCtrlSuccess) && @@ -458,6 +477,39 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, ctk_opengl->allow_gsync_button = check_button; + /* + * show G-SYNC visual indicator + * + * Always create the checkbox, but only show it if the attribute starts out + * available. + */ + + label = gtk_label_new("Enable G-SYNC Visual Indicator"); + + check_button = gtk_check_button_new(); + gtk_container_add(GTK_CONTAINER(check_button), label); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), + show_gsync_visual_indicator); + + gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(check_button), "toggled", + G_CALLBACK(show_gsync_visual_indicator_button_toggled), + (gpointer) ctk_opengl); + + g_signal_connect(G_OBJECT(ctk_event), + CTK_EVENT_NAME(NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR), + G_CALLBACK(value_changed), (gpointer) ctk_opengl); + + ctk_config_set_tooltip(ctk_config, check_button, + __show_gsync_visual_indicator_help); + + ctk_opengl->active_attributes |= __SHOW_GSYNC_VISUAL_INDICATOR; + + ctk_opengl->show_gsync_visual_indicator_button = check_button; + + if (ret_force_stereo == NvCtrlSuccess) { label = gtk_label_new("Force Stereo Flipping"); @@ -556,8 +608,8 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, /* create the slider */ adjustment = GTK_ADJUSTMENT( gtk_adjustment_new(image_settings_value, - image_settings_valid.u.range.min, - image_settings_valid.u.range.max, + image_settings_valid.range.min, + image_settings_valid.range.max, 1, 1, 0.0)); scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment)); gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), image_settings_value); @@ -746,6 +798,9 @@ GtkWidget* ctk_opengl_new(CtrlTarget *ctrl_target, if (ret_gsync_allowed != NvCtrlSuccess) { gtk_widget_hide(GTK_WIDGET(ctk_opengl->allow_gsync_button)); } + if (ret_show_gsync_visual_indicator != NvCtrlSuccess) { + gtk_widget_hide(GTK_WIDGET(ctk_opengl->show_gsync_visual_indicator_button)); + } return GTK_WIDGET(object); } @@ -777,6 +832,14 @@ static void post_allow_gsync_button_toggled(CtkOpenGL *ctk_opengl, enabled ? "allowed" : "not allowed"); } +static void post_show_gsync_visual_indicator_button_toggled(CtkOpenGL *ctk_opengl, + gboolean enabled) +{ + ctk_config_statusbar_message(ctk_opengl->ctk_config, + "G-SYNC visual indicator %s.", + enabled ? "enabled" : "disabled"); +} + static void post_force_stereo_button_toggled(CtkOpenGL *ctk_opengl, gboolean enabled) { @@ -878,6 +941,19 @@ static void allow_gsync_button_toggled(GtkWidget *widget, post_allow_gsync_button_toggled(ctk_opengl, enabled); } +static void show_gsync_visual_indicator_button_toggled(GtkWidget *widget, + gpointer user_data) +{ + CtkOpenGL *ctk_opengl = CTK_OPENGL(user_data); + CtrlTarget *ctrl_target = ctk_opengl->ctrl_target; + gboolean enabled; + + enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + NvCtrlSetAttribute(ctrl_target, NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR, enabled); + post_show_gsync_visual_indicator_button_toggled(ctk_opengl, enabled); +} + static void force_stereo_button_toggled(GtkWidget *widget, gpointer user_data) { @@ -1021,6 +1097,12 @@ static void value_changed(GObject *object, CtrlEvent *event, gpointer user_data) post_allow_gsync_button_toggled(ctk_opengl, value); check_available = TRUE; break; + case NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR: + button = GTK_TOGGLE_BUTTON(ctk_opengl->show_gsync_visual_indicator_button); + func = G_CALLBACK(show_gsync_visual_indicator_button_toggled); + post_show_gsync_visual_indicator_button_toggled(ctk_opengl, value); + check_available = TRUE; + break; case NV_CTRL_FORCE_STEREO: button = GTK_TOGGLE_BUTTON(ctk_opengl->force_stereo_button); func = G_CALLBACK(force_stereo_button_toggled); @@ -1256,7 +1338,7 @@ static GtkWidget *create_slider(CtkOpenGL *ctk_opengl, GtkAdjustment *adjustment; GtkWidget *scale, *widget; gint min, max, val, step_incr, page_incr; - NVCTRLAttributeValidValuesRec range; + CtrlAttributeValidValues range; ReturnStatus ret; /* get the attribute value */ @@ -1266,9 +1348,11 @@ static GtkWidget *create_slider(CtkOpenGL *ctk_opengl, NvCtrlGetValidAttributeValues(ctrl_target, attribute, &range); - if (range.type != ATTRIBUTE_TYPE_RANGE) return NULL; - min = range.u.range.min; - max = range.u.range.max; + if (range.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_RANGE) { + return NULL; + } + min = range.range.min; + max = range.range.max; step_incr = ((max) - (min))/10; if (step_incr <= 0) step_incr = 1; @@ -1353,6 +1437,11 @@ GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table, "application profile key."); } + if (ctk_opengl->active_attributes & __SHOW_GSYNC_VISUAL_INDICATOR) { + ctk_help_heading(b, &i, "G-SYNC Visual Indicator"); + ctk_help_para(b, &i, "%s", __show_gsync_visual_indicator_help); + } + if (ctk_opengl->active_attributes & __FORCE_STEREO) { ctk_help_heading(b, &i, "Force Stereo Flipping"); ctk_help_para(b, &i, "%s", __force_stereo_help); diff --git a/src/gtk+-2.x/ctkopengl.h b/src/gtk+-2.x/ctkopengl.h index 845f8e3..12f413e 100644 --- a/src/gtk+-2.x/ctkopengl.h +++ b/src/gtk+-2.x/ctkopengl.h @@ -56,6 +56,7 @@ struct _CtkOpenGL GtkWidget *sync_to_vblank_button; GtkWidget *allow_flipping_button; GtkWidget *allow_gsync_button; + GtkWidget *show_gsync_visual_indicator_button; GtkWidget *use_conformant_clamping_button; GtkWidget *force_stereo_button; GtkWidget *xinerama_stereo_button; diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c index e52fef6..5c9e890 100644 --- a/src/gtk+-2.x/ctkpowermizer.c +++ b/src/gtk+-2.x/ctkpowermizer.c @@ -95,7 +95,8 @@ static const char *__performance_levels_table_help = "performance level is indicated by a Performance Level number, along with " "the Graphics, Memory and Processor clocks for that level. The currently active " "performance level is shown in regular text. All other performance " -"levels are shown in gray."; +"levels are shown in gray. Note that multiple performance levels may share " +"the same range of available clocks."; static const char *__editable_performance_levels_table_help = "Each Performance Level that allows clock modifications will allow custom " @@ -436,8 +437,8 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) row_idx = 2; //reset value used to calculate vseparator. for (i = 0; i < ctk_powermizer->num_perf_levels; i++) { - NVCTRLAttributeValidValuesRec gpu_clock_valid_val; - NVCTRLAttributeValidValuesRec mem_transfer_rate_valid_val; + CtrlAttributeValidValues gpu_clock_valid_val; + CtrlAttributeValidValues mem_transfer_rate_valid_val; GtkWidget *txt_nvclock_offset = NULL; GtkWidget *txt_mem_transfer_rate_offset = NULL; gint gpu_clock_val = 0, mem_transfer_rate_val = 0; @@ -451,7 +452,8 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) NV_CTRL_GPU_NVCLOCK_OFFSET, &gpu_clock_valid_val); if ((ret == NvCtrlSuccess) && - (gpu_clock_valid_val.permissions & ATTRIBUTE_TYPE_WRITE)) { + gpu_clock_valid_val.permissions.write) { + ret = NvCtrlGetDisplayAttribute(ctrl_target, i, NV_CTRL_GPU_NVCLOCK_OFFSET, @@ -479,7 +481,8 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET, &mem_transfer_rate_valid_val); if ((ret == NvCtrlSuccess) && - (mem_transfer_rate_valid_val.permissions & ATTRIBUTE_TYPE_WRITE)) { + mem_transfer_rate_valid_val.permissions.write) { + ret = NvCtrlGetDisplayAttribute(ctrl_target, i, @@ -533,7 +536,7 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) col_idx+1, col_idx+2, row_idx, row_idx+1, GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); /* Min */ - g_snprintf(tmp_str, 24, "%jd MHz", gpu_clock_valid_val.u.range.min); + g_snprintf(tmp_str, 24, "%jd MHz", gpu_clock_valid_val.range.min); label = gtk_label_new(tmp_str); gtk_widget_set_sensitive(label, active); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); @@ -541,7 +544,7 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) col_idx+2, col_idx+3, row_idx, row_idx+1, GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); /* Max */ - g_snprintf(tmp_str, 24, "%jd MHz", gpu_clock_valid_val.u.range.max); + g_snprintf(tmp_str, 24, "%jd MHz", gpu_clock_valid_val.range.max); label = gtk_label_new(tmp_str); gtk_widget_set_sensitive(label, active); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); @@ -567,7 +570,7 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) /* Min */ g_snprintf(tmp_str, 24, "%jd MHz", - mem_transfer_rate_valid_val.u.range.min); + mem_transfer_rate_valid_val.range.min); label = gtk_label_new(tmp_str); gtk_widget_set_sensitive(label, active); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); @@ -576,7 +579,7 @@ static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer) GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); /* Max */ g_snprintf(tmp_str, 24, "%jd MHz", - mem_transfer_rate_valid_val.u.range.max); + mem_transfer_rate_valid_val.range.max); label = gtk_label_new(tmp_str); gtk_widget_set_sensitive(label, active); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); @@ -1176,7 +1179,7 @@ GtkWidget* ctk_powermizer_new(CtrlTarget *ctrl_target, gboolean adaptive_clock_state_available = FALSE; gboolean cuda_dp_ui = FALSE; gboolean pcie_gen_queriable = FALSE; - NVCTRLAttributeValidValuesRec valid_modes; + CtrlAttributeValidValues valid_modes; char *clock_string = NULL; perfModeEntry pEntry; @@ -1465,8 +1468,8 @@ GtkWidget* ctk_powermizer_new(CtrlTarget *ctrl_target, &valid_modes); if ((ret == NvCtrlSuccess) && - (valid_modes.type == ATTRIBUTE_TYPE_INT_BITS)) { - const unsigned int bit_mask = valid_modes.u.bits.ints; + (valid_modes.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS)) { + const unsigned int bit_mask = valid_modes.allowed_ints; hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); diff --git a/src/gtk+-2.x/ctkthermal.c b/src/gtk+-2.x/ctkthermal.c index 890f07e..ec36c78 100644 --- a/src/gtk+-2.x/ctkthermal.c +++ b/src/gtk+-2.x/ctkthermal.c @@ -566,10 +566,10 @@ static void apply_button_clicked(GtkWidget *widget, gpointer user_data) if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( ctk_thermal->cooler_control[i].widget))) { cooler_level = - ctk_thermal->cooler_control[i].range.u.range.max; + ctk_thermal->cooler_control[i].range.range.max; } else { cooler_level = - ctk_thermal->cooler_control[i].range.u.range.min; + ctk_thermal->cooler_control[i].range.range.min; } } @@ -583,9 +583,9 @@ static void apply_button_clicked(GtkWidget *widget, gpointer user_data) "Failed to set new Fan Speed!"); return; } + ctk_thermal->cooler_control[i].changed = FALSE; } } - ctk_thermal->cooler_control[i].changed = FALSE; ctk_thermal->settings_changed = FALSE; ctk_thermal->enable_reset_button = TRUE; @@ -701,7 +701,7 @@ static void sync_gui_to_modify_cooler_level(CtkThermal *ctk_thermal) { GtkRange *gtk_range; GtkAdjustment *gtk_adjustment_fan; - NVCTRLAttributeValidValuesRec cooler_range; + CtrlAttributeValidValues cooler_range; gboolean can_access_cooler_level = TRUE; ReturnStatus ret; gint val, i, enabled; @@ -741,8 +741,8 @@ static void sync_gui_to_modify_cooler_level(CtkThermal *ctk_thermal) G_CALLBACK(adjustment_value_changed), (gpointer) ctk_thermal); gtk_range_set_range(gtk_range, - ctk_thermal->cooler_control[i].range.u.range.min, - ctk_thermal->cooler_control[i].range.u.range.max); + ctk_thermal->cooler_control[i].range.range.min, + ctk_thermal->cooler_control[i].range.range.max); val = gtk_adjustment_get_value(gtk_adjustment_fan); if (val != ctk_thermal->cooler_control[i].level) { @@ -1059,8 +1059,8 @@ GtkWidget* ctk_thermal_new(CtrlTarget *ctrl_target, ReturnStatus ret1; CtrlTarget *cooler_target; CtrlTarget *sensor_target; - NVCTRLAttributeValidValuesRec cooler_range; - NVCTRLAttributeValidValuesRec sensor_range; + CtrlAttributeValidValues cooler_range; + CtrlAttributeValidValues sensor_range; gint trigger, core, ambient; gint upper; gchar *s; @@ -1239,7 +1239,7 @@ GtkWidget* ctk_thermal_new(CtrlTarget *ctrl_target, &sensor_range); if (ret != NvCtrlSuccess) { /* sensor information unavailable */ - sensor_range.u.range.min = sensor_range.u.range.max = 0; + sensor_range.range.min = sensor_range.range.max = 0; } ret = NvCtrlGetAttribute(sensor_target, @@ -1259,8 +1259,8 @@ GtkWidget* ctk_thermal_new(CtrlTarget *ctrl_target, /* print sensor related information */ draw_sensor_gui(vbox, ctk_thermal, thermal_sensor_target_type_supported, cur_sensor_idx, - reading, sensor_range.u.range.min, - sensor_range.u.range.max, target, provider); + reading, sensor_range.range.min, + sensor_range.range.max, target, provider); cur_sensor_idx++; } } else { @@ -1435,8 +1435,8 @@ sensor_end: adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(cooler_level, - cooler_range.u.range.min, - cooler_range.u.range.max, + cooler_range.range.min, + cooler_range.range.max, 1, 5, 0.0)); name = g_strdup_printf("Fan %d Speed", cur_cooler_idx); scale = ctk_scale_new(GTK_ADJUSTMENT(adjustment), name, diff --git a/src/gtk+-2.x/ctkthermal.h b/src/gtk+-2.x/ctkthermal.h index edb9bba..c3406e8 100644 --- a/src/gtk+-2.x/ctkthermal.h +++ b/src/gtk+-2.x/ctkthermal.h @@ -47,7 +47,7 @@ typedef struct _CtkThermal CtkThermal; typedef struct _CtkThermalClass CtkThermalClass; typedef struct _CoolerControl { - NVCTRLAttributeValidValuesRec range; + CtrlAttributeValidValues range; CtrlTarget *ctrl_target; int level; diff --git a/src/gtk+-2.x/ctkxvideo.c b/src/gtk+-2.x/ctkxvideo.c index 6e53447..d48b6be 100644 --- a/src/gtk+-2.x/ctkxvideo.c +++ b/src/gtk+-2.x/ctkxvideo.c @@ -149,20 +149,17 @@ static void xv_sync_to_display_set_enabled(CtkXVideo *ctk_xvideo, /* - * xv_sync_to_display_radio_button_add() - create a radio button and plug it - * into the xv_sync_display_buttons radio group. + * xv_sync_to_display_radio_button_label() - create the label for the radio + * button widget specified. */ -static GtkWidget *xv_sync_to_display_radio_button_add(CtkXVideo *ctk_xvideo, - GtkWidget *last_button, - gint display_id) +static gchar *xv_sync_to_display_radio_button_label(CtkXVideo *ctk_xvideo, + gint display_id) { CtrlTarget *ctrl_target; ReturnStatus ret; char *name = NULL; char *randr = NULL; gchar *label; - GtkWidget *button; - GSList *slist; ctrl_target = NvCtrlGetTarget(ctk_xvideo->ctrl_target->system, DISPLAY_TARGET, display_id); @@ -191,6 +188,27 @@ static GtkWidget *xv_sync_to_display_radio_button_add(CtkXVideo *ctk_xvideo, free(name); free(randr); + return label; +} + +/* + * xv_sync_to_display_radio_button_add() - create a radio button and plug it + * into the xv_sync_display_buttons radio group. + */ +static GtkWidget *xv_sync_to_display_radio_button_add(CtkXVideo *ctk_xvideo, + GtkWidget *last_button, + gint display_id) +{ + gchar *label; + GtkWidget *button; + GSList *slist; + + if (display_id == NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO) { + label = g_strdup("Auto"); + } else { + label = xv_sync_to_display_radio_button_label(ctk_xvideo, display_id); + } + if (last_button) { slist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(last_button)); } else { @@ -232,6 +250,7 @@ static void xv_sync_to_display_rebuild_buttons(CtkXVideo *ctk_xvideo, int i; GtkWidget *last_button; + GtkWidget *button; CtrlTarget *ctrl_target = ctk_xvideo->ctrl_target; @@ -262,11 +281,21 @@ static void xv_sync_to_display_rebuild_buttons(CtkXVideo *ctk_xvideo, } - /* Add a button for each display device */ - + /* Add a button for No Display Specified */ last_button = NULL; + button = xv_sync_to_display_radio_button_add(ctk_xvideo, NULL, + NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO); + + if (button) { + /* Track the first button */ + if (!last_button) { + ctk_xvideo->xv_sync_to_display_buttons = button; + } + + last_button = button; + } + /* Add a button for each display device */ for (i = 0; i < pData[0]; i++) { - GtkWidget *button; int display_id = pData[1+i]; button = xv_sync_to_display_radio_button_add(ctk_xvideo, @@ -308,6 +337,35 @@ static void enabled_displays_handler(GObject *object, gpointer arg1, } +/* + * Finds the radio button matching value and selects it and returns 1. If + * the value is not found, return 0. + */ +static int xv_sync_to_display_enable_index(CtkXVideo *ctk_xvideo, int value) +{ + gpointer user_data; + GSList *slist = gtk_radio_button_get_group( + GTK_RADIO_BUTTON(ctk_xvideo->xv_sync_to_display_buttons)); + + while (slist) { + GtkWidget *button = GTK_WIDGET(slist->data); + + user_data = g_object_get_data(G_OBJECT(button), "display_id"); + if (GPOINTER_TO_INT(user_data) == value && + value != NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO) { + xv_sync_to_display_set_enabled(ctk_xvideo, button, TRUE); + return 1; + } else { + xv_sync_to_display_set_enabled(ctk_xvideo, button, FALSE); + } + + slist = g_slist_next(slist); + } + + return 0; + +} + /* * Handler for NV_CTRL_XV_SYNC_TO_DISPLAY_ID events. @@ -317,28 +375,47 @@ static void xv_sync_to_display_id_handler(GObject *object, gpointer user_data) { CtkXVideo *ctk_xvideo = CTK_XVIDEO(user_data); - GSList *slist; if (event->type != CTRL_EVENT_TYPE_INTEGER_ATTRIBUTE) { return; } - /* Find the right button and enable it */ - - slist = - gtk_radio_button_get_group(GTK_RADIO_BUTTON(ctk_xvideo->xv_sync_to_display_buttons)); + /* + * Find and enable the button for the correct display id, otherwise enable + * the unspecified option. + */ + if (!xv_sync_to_display_enable_index(ctk_xvideo, event->int_attr.value)) + { + xv_sync_to_display_enable_index(ctk_xvideo, + NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO); + } +} - while (slist) { - GtkWidget *button = GTK_WIDGET(slist->data); - user_data = g_object_get_data(G_OBJECT(button), "display_id"); - if (GPOINTER_TO_INT(user_data) == event->int_attr.value) { - xv_sync_to_display_set_enabled(ctk_xvideo, button, TRUE); - break; - } +/* + * Handler for NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID events. + */ +static void current_xv_sync_to_display_id_handler(GObject *object, + CtrlEvent *event, + gpointer user_data) +{ + CtkXVideo *ctk_xvideo = CTK_XVIDEO(user_data); + gchar *current_sync_name; - slist = g_slist_next(slist); + if (event->type != CTRL_EVENT_TYPE_INTEGER_ATTRIBUTE) { + return; } + + /* + * Find and enable the button for the correct display id, otherwise enable + * the unspecified option. + */ + current_sync_name = + xv_sync_to_display_radio_button_label(ctk_xvideo, event->int_attr.value); + + gtk_label_set_text(GTK_LABEL(ctk_xvideo->current_xv_sync_to_display_label), + current_sync_name); + g_free(current_sync_name); } @@ -356,9 +433,14 @@ GtkWidget* ctk_xvideo_new(CtrlTarget *ctrl_target, GtkWidget *frame; GtkWidget *alignment; GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *hseparator; int xv_overlay_present, xv_texture_present, xv_blitter_present; + int display_id; gboolean show_page; ReturnStatus ret; + gchar *current_sync_name; /* * before we do anything else, determine if any of the Xv adapters @@ -391,7 +473,6 @@ GtkWidget* ctk_xvideo_new(CtrlTarget *ctrl_target, show_page = FALSE; if (xv_texture_present || xv_blitter_present) { - int display_id; ret = NvCtrlGetAttribute(ctrl_target, NV_CTRL_XV_SYNC_TO_DISPLAY_ID, &display_id); @@ -422,6 +503,40 @@ GtkWidget* ctk_xvideo_new(CtrlTarget *ctrl_target, banner = ctk_banner_image_new(BANNER_ARTWORK_XVIDEO); gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0); + /* Top Label */ + + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0); + + label = gtk_label_new("Xvideo Settings"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + hseparator = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(hbox), hseparator, TRUE, TRUE, 0); + + /* Current Sync Value */ + + ret = NvCtrlGetAttribute(ctrl_target, + NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID, + &display_id); + if (ret == NvCtrlSuccess) { + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 5); + + label = gtk_label_new("Currently synced to display:"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); + label = gtk_label_new(""); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); + + current_sync_name = xv_sync_to_display_radio_button_label(ctk_xvideo, + display_id); + gtk_label_set_text(GTK_LABEL(label), current_sync_name); + g_free(current_sync_name); + + ctk_xvideo->current_xv_sync_to_display_label = label; + } else { + ctk_xvideo->current_xv_sync_to_display_label = NULL; + } /* Sync to display selection */ @@ -440,6 +555,13 @@ GtkWidget* ctk_xvideo_new(CtrlTarget *ctrl_target, G_CALLBACK(xv_sync_to_display_id_handler), (gpointer) ctk_xvideo); + if (ctk_xvideo->current_xv_sync_to_display_label) { + g_signal_connect(G_OBJECT(ctk_event), + CTK_EVENT_NAME(NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID), + G_CALLBACK(current_xv_sync_to_display_id_handler), + (gpointer) ctk_xvideo); + } + g_signal_connect(G_OBJECT(ctk_event), CTK_EVENT_NAME(NV_CTRL_ENABLED_DISPLAYS), G_CALLBACK(enabled_displays_handler), diff --git a/src/gtk+-2.x/ctkxvideo.h b/src/gtk+-2.x/ctkxvideo.h index ca2201f..e06e232 100644 --- a/src/gtk+-2.x/ctkxvideo.h +++ b/src/gtk+-2.x/ctkxvideo.h @@ -54,6 +54,7 @@ struct _CtkXVideo CtrlTarget *ctrl_target; CtkConfig *ctk_config; + GtkWidget *current_xv_sync_to_display_label; GtkWidget *xv_sync_to_display_buttons; /* first button in group */ GtkWidget *xv_sync_to_display_button_box; diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h index 94876e2..b62c22f 100644 --- a/src/libXNVCtrl/NVCtrl.h +++ b/src/libXNVCtrl/NVCtrl.h @@ -2121,18 +2121,16 @@ /* - * NV_CTRL_SWITCH_TO_DISPLAYS - deprecated + * NV_CTRL_SWITCH_TO_DISPLAYS - not supported */ -#define NV_CTRL_SWITCH_TO_DISPLAYS 276 /* deprecated */ +#define NV_CTRL_SWITCH_TO_DISPLAYS 276 /* not supported */ /* - * NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT - deprecated + * NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT - not supported */ -#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT 277 /* RW- */ -#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_CLOSE 0 -#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_OPEN 1 +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT 277 /* not supported */ /* * NV_CTRL_NOTEBOOK_INTERNAL_LCD - deprecated @@ -2477,9 +2475,13 @@ #define NV_CTRL_GPU_COOLER_MANUAL_CONTROL_FALSE 0 #define NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE 1 -/* - * NV_CTRL_THERMAL_COOLER_LEVEL - Returns cooler's current operating - * level. +/* + * NV_CTRL_THERMAL_COOLER_LEVEL - The cooler's target level. + * Normally, the driver dynamically adjusts the cooler based on + * the needs of the GPU. But when NV_CTRL_GPU_COOLER_MANUAL_CONTROL=TRUE, + * the driver will attempt to make the cooler achieve the setting in + * NV_CTRL_THERMAL_COOLER_LEVEL. The actual current level of the cooler + * is reported in NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL. */ #define NV_CTRL_THERMAL_COOLER_LEVEL 320 /* RW-C */ @@ -2722,8 +2724,11 @@ #define NV_CTRL_GVI_TEST_MODE_ENABLE 1 /* - * NV_CTRL_COLOR_SPACE - This option sets color space of the video - * signal. + * NV_CTRL_COLOR_SPACE - This option controls the preferred color space of the + * video signal. This may not match the current color space depending on the + * current mode on this display. + * + * NV_CTRL_CURRENT_COLOR_SPACE will reflect the actual color space in use. */ #define NV_CTRL_COLOR_SPACE 348 /* RWDG */ #define NV_CTRL_COLOR_SPACE_RGB 0 @@ -2731,8 +2736,13 @@ #define NV_CTRL_COLOR_SPACE_YCbCr444 2 /* - * NV_CTRL_COLOR_RANGE - This option sets color range of the video - * signal. + * NV_CTRL_COLOR_RANGE - This option controls the preferred color range of the + * video signal. + * + * If the current color space requires it, the actual color range will be + * limited. + * + * NV_CTRL_CURRENT_COLOR_RANGE will reflect the actual color range in use. */ #define NV_CTRL_COLOR_RANGE 349 /* RWDG */ #define NV_CTRL_COLOR_RANGE_FULL 0 @@ -3227,9 +3237,12 @@ /* * NV_CTRL_XV_SYNC_TO_DISPLAY_ID - When XVideo Sync To VBlank is enabled, this - * controls which display device will be synched to. + * controls which display device will be synched to if the display is enabled. + * Returns NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO if no display has been + * selected. */ #define NV_CTRL_XV_SYNC_TO_DISPLAY_ID 401 /* RW- */ +#define NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO 0xFFFFFFFF /* * NV_CTRL_BACKLIGHT_BRIGHTNESS - The backlight brightness of an internal panel. @@ -3342,10 +3355,62 @@ * This attribute is available on GPUs that support * NV_CTRL_GPU_OVER_VOLTAGE_OFFSET. */ -#define NV_CTRL_GPU_CURRENT_CORE_VOLTAGE 413 /* R--G */ +#define NV_CTRL_GPU_CURRENT_CORE_VOLTAGE 413 /* R--G */ + +/* + * NV_CTRL_CURRENT_COLOR_SPACE - Returns the current color space of the video + * signal. + * + * This will match NV_CTRL_COLOR_SPACE unless the current mode on this display + * device is an HDMI 2.0 4K@60Hz mode and the display device or GPU does not + * support driving this mode in RGB, in which case YCbCr420 will be returned. + */ +#define NV_CTRL_CURRENT_COLOR_SPACE 414 /* R-DG */ +#define NV_CTRL_CURRENT_COLOR_SPACE_RGB 0 +#define NV_CTRL_CURRENT_COLOR_SPACE_YCbCr422 1 +#define NV_CTRL_CURRENT_COLOR_SPACE_YCbCr444 2 +#define NV_CTRL_CURRENT_COLOR_SPACE_YCbCr420 3 + +/* + * NV_CTRL_CURRENT_COLOR_RANGE - Returns the current color range of the video + * signal. + */ +#define NV_CTRL_CURRENT_COLOR_RANGE 415 /* R-DG */ +#define NV_CTRL_CURRENT_COLOR_RANGE_FULL 0 +#define NV_CTRL_CURRENT_COLOR_RANGE_LIMITED 1 + +/* + * NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR - when TRUE, OpenGL will indicate when + * G-SYNC is in use for full-screen applications. + */ + +#define NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR 416 /* RW-X */ +#define NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR_FALSE 0 +#define NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR_TRUE 1 + +/* + * NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL - Returns cooler's current + * operating level. This may fluctuate dynamically. When + * NV_CTRL_GPU_COOLER_MANUAL_CONTROL=TRUE, the driver attempts + * to make this match NV_CTRL_THERMAL_COOLER_LEVEL. When + * NV_CTRL_GPU_COOLER_MANUAL_CONTROL=FALSE, the driver adjusts the + * current level based on the needs of the GPU. + */ + +#define NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL 417 /* R--C */ + + + +/* + * NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID - When XVideo Sync To VBlank is + * enabled, this returns the display id of the device currently synched to. + * Returns NV_CTRL_XV_SYNC_TO_DISPLAY_ID_AUTO if no display is currently + * set. + */ -#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_GPU_CURRENT_CORE_VOLTAGE +#define NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID 419 /* R-- */ +#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID /**************************************************************************/ diff --git a/src/libXNVCtrl/utils.mk b/src/libXNVCtrl/utils.mk index 88598d2..9c50176 100644 --- a/src/libXNVCtrl/utils.mk +++ b/src/libXNVCtrl/utils.mk @@ -1,17 +1,23 @@ # # Copyright (C) 2008 NVIDIA Corporation # -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: # -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. # -# You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses>. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. # # # utils.mk: common Makefile fragment used by nvidia-xconfig, diff --git a/src/libXNVCtrl/version.mk b/src/libXNVCtrl/version.mk index d622b1f..714e597 100644 --- a/src/libXNVCtrl/version.mk +++ b/src/libXNVCtrl/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 346.47 +NVIDIA_VERSION = 349.12 diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c index 4ce6145..609b391 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c +++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c @@ -46,76 +46,76 @@ const CtrlTargetTypeInfo targetTypeInfoTable[] = { [X_SCREEN_TARGET] = - { "X Screen", /* name */ - "screen", /* parsed_name */ - NV_CTRL_TARGET_TYPE_X_SCREEN, /* nvctrl */ - ATTRIBUTE_TYPE_X_SCREEN, /* permission_bit */ - NV_TRUE, /* uses_display_devices */ - 1, 6 }, /* required major,minor protocol rev */ + { "X Screen", /* name */ + "screen", /* parsed_name */ + NV_CTRL_TARGET_TYPE_X_SCREEN, /* nvctrl */ + CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET), /* permission_bit */ + NV_TRUE, /* uses_display_devices */ + 1, 6 }, /* required major,minor protocol rev */ [GPU_TARGET] = - { "GPU", /* name */ - "gpu", /* parsed_name */ - NV_CTRL_TARGET_TYPE_GPU, /* nvctrl */ - ATTRIBUTE_TYPE_GPU, /* permission_bit */ - NV_TRUE, /* uses_display_devices */ - 1, 10 }, /* required major,minor protocol rev */ + { "GPU", /* name */ + "gpu", /* parsed_name */ + NV_CTRL_TARGET_TYPE_GPU, /* nvctrl */ + CTRL_TARGET_PERM_BIT(GPU_TARGET), /* permission_bit */ + NV_TRUE, /* uses_display_devices */ + 1, 10 }, /* required major,minor protocol rev */ [FRAMELOCK_TARGET] = - { "Frame Lock Device", /* name */ - "framelock", /* parsed_name */ - NV_CTRL_TARGET_TYPE_FRAMELOCK, /* nvctrl */ - ATTRIBUTE_TYPE_FRAMELOCK, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 10 }, /* required major,minor protocol rev */ + { "Frame Lock Device", /* name */ + "framelock", /* parsed_name */ + NV_CTRL_TARGET_TYPE_FRAMELOCK, /* nvctrl */ + CTRL_TARGET_PERM_BIT(FRAMELOCK_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 10 }, /* required major,minor protocol rev */ [VCS_TARGET] = - { "VCS", /* name */ - "vcs", /* parsed_name */ - NV_CTRL_TARGET_TYPE_VCSC, /* nvctrl */ - ATTRIBUTE_TYPE_VCSC, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 12 }, /* required major,minor protocol rev */ + { "VCS", /* name */ + "vcs", /* parsed_name */ + NV_CTRL_TARGET_TYPE_VCSC, /* nvctrl */ + CTRL_TARGET_PERM_BIT(VCS_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 12 }, /* required major,minor protocol rev */ [GVI_TARGET] = - { "SDI Input Device", /* name */ - "gvi", /* parsed_name */ - NV_CTRL_TARGET_TYPE_GVI, /* nvctrl */ - ATTRIBUTE_TYPE_GVI, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 18 }, /* required major,minor protocol rev */ + { "SDI Input Device", /* name */ + "gvi", /* parsed_name */ + NV_CTRL_TARGET_TYPE_GVI, /* nvctrl */ + CTRL_TARGET_PERM_BIT(GVI_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 18 }, /* required major,minor protocol rev */ [COOLER_TARGET] = - { "Fan", /* name */ - "fan", /* parsed_name */ - NV_CTRL_TARGET_TYPE_COOLER, /* nvctrl */ - ATTRIBUTE_TYPE_COOLER, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 20 }, /* required major,minor protocol rev */ + { "Fan", /* name */ + "fan", /* parsed_name */ + NV_CTRL_TARGET_TYPE_COOLER, /* nvctrl */ + CTRL_TARGET_PERM_BIT(COOLER_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 20 }, /* required major,minor protocol rev */ [THERMAL_SENSOR_TARGET] = - { "Thermal Sensor", /* name */ - "thermalsensor", /* parsed_name */ - NV_CTRL_TARGET_TYPE_THERMAL_SENSOR, /* nvctrl */ - ATTRIBUTE_TYPE_THERMAL_SENSOR, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 23 }, /* required major,minor protocol rev */ + { "Thermal Sensor", /* name */ + "thermalsensor", /* parsed_name */ + NV_CTRL_TARGET_TYPE_THERMAL_SENSOR, /* nvctrl */ + CTRL_TARGET_PERM_BIT(THERMAL_SENSOR_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 23 }, /* required major,minor protocol rev */ [NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET] = - { "3D Vision Pro Transceiver", /* name */ - "svp", /* parsed_name */ - NV_CTRL_TARGET_TYPE_3D_VISION_PRO_TRANSCEIVER, /* nvctrl */ - ATTRIBUTE_TYPE_3D_VISION_PRO_TRANSCEIVER, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 25 }, /* required major,minor protocol rev */ + { "3D Vision Pro Transceiver", /* name */ + "svp", /* parsed_name */ + NV_CTRL_TARGET_TYPE_3D_VISION_PRO_TRANSCEIVER, /* nvctrl */ + CTRL_TARGET_PERM_BIT(NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 25 }, /* required major,minor protocol rev */ [DISPLAY_TARGET] = - { "Display Device", /* name */ - "dpy", /* parsed_name */ - NV_CTRL_TARGET_TYPE_DISPLAY, /* nvctrl */ - ATTRIBUTE_TYPE_DISPLAY, /* permission_bit */ - NV_FALSE, /* uses_display_devices */ - 1, 27 }, /* required major,minor protocol rev */ + { "Display Device", /* name */ + "dpy", /* parsed_name */ + NV_CTRL_TARGET_TYPE_DISPLAY, /* nvctrl */ + CTRL_TARGET_PERM_BIT(DISPLAY_TARGET), /* permission_bit */ + NV_FALSE, /* uses_display_devices */ + 1, 27 }, /* required major,minor protocol rev */ }; const int targetTypeInfoTableLen = ARRAY_LEN(targetTypeInfoTable); @@ -247,6 +247,16 @@ NvCtrlAttributeHandle *NvCtrlAttributeInit(CtrlSystem *system, h->xrandr = NvCtrlInitXrandrAttributes(h); } + /* + * initialize NVML-specific attributes for NVML-related target types. + */ + + if ((subsystems & NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM) && + TARGET_TYPE_IS_NVML_COMPATIBLE(target_type)) { + + h->nvml = NvCtrlInitNvmlAttributes(h); + } + return (NvCtrlAttributeHandle *) h; failed: @@ -591,8 +601,30 @@ ReturnStatus NvCtrlQueryTargetCount(const CtrlTarget *ctrl_target, return NvCtrlBadHandle; } - return NvCtrlNvControlQueryTargetCount(h, target_type, val); - + switch (target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret = NvCtrlNvmlQueryTargetCount(ctrl_target, + target_type, + val); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + return NvCtrlNvControlQueryTargetCount(h, target_type, val); + default: + return NvCtrlBadHandle; + } } /* NvCtrlQueryTargetCount() */ ReturnStatus NvCtrlGetAttribute(const CtrlTarget *ctrl_target, @@ -629,118 +661,49 @@ ReturnStatus NvCtrlGetVoidAttribute(const CtrlTarget *ctrl_target, ReturnStatus NvCtrlGetValidAttributeValues(const CtrlTarget *ctrl_target, int attr, - NVCTRLAttributeValidValuesRec *val) + CtrlAttributeValidValues *val) { return NvCtrlGetValidDisplayAttributeValues(ctrl_target, 0, attr, val); } /* NvCtrlGetValidAttributeValues() */ - -/* - * Helper function for converting NV-CONTROL specific permission data into - * CtrlAttributePerms (API agnostic) permission data that the front-end can use. - */ - -static void convert_from_nvctrl_perms(CtrlAttributePerms *dst, - const NVCTRLAttributePermissionsRec *src) -{ - memset(dst, 0, sizeof(*dst)); - - dst->read = (src->permissions & ATTRIBUTE_TYPE_READ) ? NV_TRUE : NV_FALSE; - dst->write = (src->permissions & ATTRIBUTE_TYPE_WRITE) ? NV_TRUE : NV_FALSE; - - if (src->permissions & ATTRIBUTE_TYPE_X_SCREEN) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_DISPLAY) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(DISPLAY_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_GPU) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(GPU_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_FRAMELOCK) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(FRAMELOCK_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_VCSC) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(VCS_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_GVI) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(GVI_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_COOLER) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(COOLER_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_THERMAL_SENSOR) { - dst->valid_targets |= CTRL_TARGET_PERM_BIT(THERMAL_SENSOR_TARGET); - } - if (src->permissions & ATTRIBUTE_TYPE_3D_VISION_PRO_TRANSCEIVER) { - dst->valid_targets |= - CTRL_TARGET_PERM_BIT(NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET); - } -} - - - ReturnStatus NvCtrlGetAttributePerms(const CtrlTarget *ctrl_target, - int attr_type, + CtrlAttributeType attr_type, int attr, CtrlAttributePerms *perms) { - NVCTRLAttributePermissionsRec nvctrlPerms; const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); if (h == NULL) { return NvCtrlBadHandle; } - memset(&nvctrlPerms, 0, sizeof(nvctrlPerms)); - memset(perms, 0, sizeof(*perms)); + if (perms == NULL) { + return NvCtrlBadArgument; + } switch (attr_type) { - case CTRL_ATTRIBUTE_TYPE_INTEGER: - XNVCTRLQueryAttributePermissions(h->dpy, attr, &nvctrlPerms); - - convert_from_nvctrl_perms(perms, &nvctrlPerms); - break; - - case CTRL_ATTRIBUTE_TYPE_STRING: - XNVCTRLQueryStringAttributePermissions(h->dpy, attr, &nvctrlPerms); - convert_from_nvctrl_perms(perms, &nvctrlPerms); - break; - - case CTRL_ATTRIBUTE_TYPE_BINARY_DATA: - XNVCTRLQueryBinaryDataAttributePermissions(h->dpy, attr, &nvctrlPerms); - convert_from_nvctrl_perms(perms, &nvctrlPerms); - break; - - case CTRL_ATTRIBUTE_TYPE_STRING_OPERATION: - XNVCTRLQueryStringOperationAttributePermissions(h->dpy, attr, - &nvctrlPerms); - convert_from_nvctrl_perms(perms, &nvctrlPerms); - break; - - case CTRL_ATTRIBUTE_TYPE_COLOR: - /* Allow non NV-CONTROL attributes to be read/written on X screen - * targets - */ - perms->read = NV_TRUE; - perms->write = NV_TRUE; - perms->valid_targets |= CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); - break; - - case CTRL_ATTRIBUTE_TYPE_SDI_CSC: - /* Allow SDI CSC matrix to be read/written on X screen targets */ - perms->read = NV_TRUE; - perms->write = NV_TRUE; - perms->valid_targets |= CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); - break; + case CTRL_ATTRIBUTE_TYPE_INTEGER: + case CTRL_ATTRIBUTE_TYPE_STRING: + case CTRL_ATTRIBUTE_TYPE_BINARY_DATA: + case CTRL_ATTRIBUTE_TYPE_STRING_OPERATION: + return NvCtrlNvControlGetAttributePerms(h, attr_type, attr, perms); + + case CTRL_ATTRIBUTE_TYPE_COLOR: + case CTRL_ATTRIBUTE_TYPE_SDI_CSC: + /* + * Allow non NV-CONTROL attributes to be read/written on X screen + * targets + */ + perms->read = NV_TRUE; + perms->write = NV_TRUE; + perms->valid_targets = CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); + return NvCtrlSuccess; - default: - return NvCtrlBadArgument; + default: + return NvCtrlBadArgument; } - - return NvCtrlSuccess; } @@ -798,8 +761,32 @@ ReturnStatus NvCtrlGetDisplayAttribute64(const CtrlTarget *ctrl_target, if (((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) || ((attr >= NV_CTRL_ATTR_NV_BASE) && (attr <= NV_CTRL_ATTR_NV_LAST_ATTRIBUTE))) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlGetAttribute(h, display_mask, attr, val); + + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret = NvCtrlNvmlGetAttribute(ctrl_target, + attr, + val); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + if (!h->nv) return NvCtrlMissingExtension; + return NvCtrlNvControlGetAttribute(h, display_mask, attr, val); + default: + return NvCtrlBadHandle; + } } return NvCtrlNoAttribute; @@ -815,7 +802,9 @@ ReturnStatus NvCtrlGetDisplayAttribute(const CtrlTarget *ctrl_target, status = NvCtrlGetDisplayAttribute64(ctrl_target, display_mask, attr, &value_64); - *val = value_64; + if (status == NvCtrlSuccess) { + *val = value_64; + } return status; @@ -833,8 +822,35 @@ ReturnStatus NvCtrlSetDisplayAttribute(CtrlTarget *ctrl_target, } if ((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlSetAttribute(h, display_mask, attr, val); + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret; + ret = NvCtrlNvmlSetAttribute(ctrl_target, + attr, + display_mask, + val); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + if (!h->nv) { + return NvCtrlMissingExtension; + } + return NvCtrlNvControlSetAttribute(h, display_mask, attr, val); + default: + return NvCtrlBadHandle; + } } return NvCtrlNoAttribute; @@ -865,7 +881,7 @@ ReturnStatus NvCtrlGetVoidDisplayAttribute(const CtrlTarget *ctrl_target, ReturnStatus NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target, unsigned int display_mask, int attr, - NVCTRLAttributeValidValuesRec *val) + CtrlAttributeValidValues *val) { const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); @@ -874,9 +890,35 @@ NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target, } if ((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlGetValidAttributeValues(h, display_mask, - attr, val); + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret; + ret = NvCtrlNvmlGetValidAttributeValues(ctrl_target, + attr, + val); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + if (!h->nv) { + return NvCtrlMissingExtension; + } + return NvCtrlNvControlGetValidAttributeValues(h, display_mask, + attr, val); + default: + return NvCtrlBadHandle; + } } return NvCtrlNoAttribute; @@ -886,18 +928,18 @@ NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target, /* * GetValidStringDisplayAttributeValuesExtraAttr() -fill the - * NVCTRLAttributeValidValuesRec strucure for extra string atrributes i.e. + * CtrlAttributeValidValues strucure for extra string atrributes i.e. * NvCtrlNvControl*, NvCtrlGlx*, NvCtrlXrandr*, NvCtrlVidMode*, or NvCtrlXv*. */ static ReturnStatus -GetValidStringDisplayAttributeValuesExtraAttr(NVCTRLAttributeValidValuesRec - *val) +GetValidStringDisplayAttributeValuesExtraAttr(CtrlAttributeValidValues *val) { if (val) { - memset(val, 0, sizeof(NVCTRLAttributeValidValuesRec)); - val->type = ATTRIBUTE_TYPE_STRING; - val->permissions = ATTRIBUTE_TYPE_READ | ATTRIBUTE_TYPE_X_SCREEN; + memset(val, 0, sizeof(*val)); + val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_STRING; + val->permissions.read = NV_TRUE; + val->permissions.valid_targets = CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); return NvCtrlSuccess; } else { return NvCtrlBadArgument; @@ -907,13 +949,13 @@ GetValidStringDisplayAttributeValuesExtraAttr(NVCTRLAttributeValidValuesRec /* * NvCtrlGetValidStringDisplayAttributeValues() -fill the - * NVCTRLAttributeValidValuesRec structure for String attributes + * CtrlAttributeValidValues structure for String attributes */ ReturnStatus NvCtrlGetValidStringDisplayAttributeValues(const CtrlTarget *ctrl_target, unsigned int display_mask, int attr, - NVCTRLAttributeValidValuesRec *val) + CtrlAttributeValidValues *val) { const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); @@ -922,10 +964,35 @@ NvCtrlGetValidStringDisplayAttributeValues(const CtrlTarget *ctrl_target, } if ((attr >= 0) && (attr <= NV_CTRL_STRING_LAST_ATTRIBUTE)) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlGetValidStringDisplayAttributeValues(h, - display_mask, - attr, val); + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret; + ret = NvCtrlNvmlGetValidStringAttributeValues(ctrl_target, + attr, + val); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + if (!h->nv) { + return NvCtrlMissingExtension; + } + return NvCtrlNvControlGetValidStringDisplayAttributeValues( + h, display_mask, attr, val); + default: + return NvCtrlBadHandle; + } } /* @@ -982,42 +1049,66 @@ ReturnStatus NvCtrlGetStringDisplayAttribute(const CtrlTarget *ctrl_target, return NvCtrlBadHandle; } - if ((attr >= 0) && (attr <= NV_CTRL_STRING_LAST_ATTRIBUTE)) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlGetStringAttribute(h, display_mask, attr, ptr); - } + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret = NvCtrlNvmlGetStringAttribute(ctrl_target, + attr, + ptr); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + if ((attr >= 0) && (attr <= NV_CTRL_STRING_LAST_ATTRIBUTE)) { + if (!h->nv) return NvCtrlMissingExtension; + return NvCtrlNvControlGetStringAttribute(h, display_mask, attr, ptr); + } - if ((attr >= NV_CTRL_STRING_NV_CONTROL_BASE) && - (attr <= NV_CTRL_STRING_NV_CONTROL_LAST_ATTRIBUTE)) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlGetStringAttribute(h, display_mask, attr, ptr); - } + if ((attr >= NV_CTRL_STRING_NV_CONTROL_BASE) && + (attr <= NV_CTRL_STRING_NV_CONTROL_LAST_ATTRIBUTE)) { + if (!h->nv) return NvCtrlMissingExtension; + return NvCtrlNvControlGetStringAttribute(h, display_mask, attr, ptr); + } - if ((attr >= NV_CTRL_STRING_GLX_BASE) && - (attr <= NV_CTRL_STRING_GLX_LAST_ATTRIBUTE)) { - if (!h->glx) return NvCtrlMissingExtension; - return NvCtrlGlxGetStringAttribute(h, display_mask, attr, ptr); - } + if ((attr >= NV_CTRL_STRING_GLX_BASE) && + (attr <= NV_CTRL_STRING_GLX_LAST_ATTRIBUTE)) { + if (!h->glx) return NvCtrlMissingExtension; + return NvCtrlGlxGetStringAttribute(h, display_mask, attr, ptr); + } - if ((attr >= NV_CTRL_STRING_XRANDR_BASE) && - (attr <= NV_CTRL_STRING_XRANDR_LAST_ATTRIBUTE)) { - if (!h->xrandr) return NvCtrlMissingExtension; - return NvCtrlXrandrGetStringAttribute(h, display_mask, attr, ptr); - } + if ((attr >= NV_CTRL_STRING_XRANDR_BASE) && + (attr <= NV_CTRL_STRING_XRANDR_LAST_ATTRIBUTE)) { + if (!h->xrandr) return NvCtrlMissingExtension; + return NvCtrlXrandrGetStringAttribute(h, display_mask, attr, ptr); + } - if ((attr >= NV_CTRL_STRING_XF86VIDMODE_BASE) && - (attr <= NV_CTRL_STRING_XF86VIDMODE_LAST_ATTRIBUTE)) { - if (!h->vm) return NvCtrlMissingExtension; - return NvCtrlVidModeGetStringAttribute(h, display_mask, attr, ptr); - } + if ((attr >= NV_CTRL_STRING_XF86VIDMODE_BASE) && + (attr <= NV_CTRL_STRING_XF86VIDMODE_LAST_ATTRIBUTE)) { + if (!h->vm) return NvCtrlMissingExtension; + return NvCtrlVidModeGetStringAttribute(h, display_mask, attr, ptr); + } - if ((attr >= NV_CTRL_STRING_XV_BASE) && - (attr <= NV_CTRL_STRING_XV_LAST_ATTRIBUTE)) { - if (!h->xv) return NvCtrlMissingExtension; - return NvCtrlXvGetStringAttribute(h, display_mask, attr, ptr); - } + if ((attr >= NV_CTRL_STRING_XV_BASE) && + (attr <= NV_CTRL_STRING_XV_LAST_ATTRIBUTE)) { + if (!h->xv) return NvCtrlMissingExtension; + return NvCtrlXvGetStringAttribute(h, display_mask, attr, ptr); + } - return NvCtrlNoAttribute; + return NvCtrlNoAttribute; + + default: + return NvCtrlBadHandle; + } } /* NvCtrlGetStringDisplayAttribute() */ @@ -1033,8 +1124,32 @@ ReturnStatus NvCtrlSetStringDisplayAttribute(CtrlTarget *ctrl_target, } if ((attr >= 0) && (attr <= NV_CTRL_STRING_LAST_ATTRIBUTE)) { - if (!h->nv) return NvCtrlMissingExtension; - return NvCtrlNvControlSetStringAttribute(h, display_mask, attr, ptr); + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret = NvCtrlNvmlSetStringAttribute(ctrl_target, + attr, + ptr); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + if (!h->nv) return NvCtrlMissingExtension; + return NvCtrlNvControlSetStringAttribute(h, display_mask, attr, + ptr); + default: + return NvCtrlBadHandle; + } } return NvCtrlNoAttribute; @@ -1051,7 +1166,31 @@ ReturnStatus NvCtrlGetBinaryAttribute(const CtrlTarget *ctrl_target, return NvCtrlBadHandle; } - return NvCtrlNvControlGetBinaryAttribute(h, display_mask, attr, data, len); + switch (h->target_type) { + case GPU_TARGET: + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + { + ReturnStatus ret = NvCtrlNvmlGetBinaryAttribute(ctrl_target, + attr, + data, + len); + if ((ret != NvCtrlMissingExtension) && + (ret != NvCtrlNotSupported)) { + return ret; + } + /* Fall through */ + } + case DISPLAY_TARGET: + case X_SCREEN_TARGET: + case FRAMELOCK_TARGET: + case VCS_TARGET: + case GVI_TARGET: + case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: + return NvCtrlNvControlGetBinaryAttribute(h, display_mask, attr, data, len); + default: + return NvCtrlBadHandle; + } } /* NvCtrlGetBinaryAttribute() */ @@ -1095,6 +1234,8 @@ char *NvCtrlAttributesStrError(ReturnStatus status) return "Write only attribute"; break; case NvCtrlAttributeNotAvailable: return "Attribute not available"; break; + case NvCtrlNotSupported: + return "Operation not supported"; break; case NvCtrlError: /* fall through to default */ default: return "Unknown Error"; break; @@ -1124,6 +1265,9 @@ void NvCtrlAttributeClose(NvCtrlAttributeHandle *handle) if ( h->xv ) { NvCtrlXvAttributesClose(h); } + if ( h->nvml ) { + NvCtrlNvmlAttributesClose(h); + } free(h); } /* NvCtrlAttributeClose() */ diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h index 8e458c6..52c46a4 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h +++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h @@ -61,7 +61,7 @@ typedef struct { char *parsed_name; /* name used by parser */ int nvctrl; /* NV-CONTROL target type value (NV_CTRL_TARGET_TYPE) */ - /* flag set in NVCTRLAttributeValidValuesRec.permissions */ + /* flag set in CtrlAttributePerms.valid_targets */ unsigned int permission_bit; /* whether this target type is aware of display devices */ @@ -268,6 +268,7 @@ typedef enum { NvCtrlReadOnlyAttribute, NvCtrlWriteOnlyAttribute, NvCtrlAttributeNotAvailable, + NvCtrlNotSupported, NvCtrlError } ReturnStatus; @@ -338,6 +339,38 @@ typedef struct { /* + * Used to return valid values of an attribute + */ +typedef enum { + CTRL_ATTRIBUTE_VALID_TYPE_UNKNOWN = 0, + CTRL_ATTRIBUTE_VALID_TYPE_INTEGER, + CTRL_ATTRIBUTE_VALID_TYPE_BITMASK, + CTRL_ATTRIBUTE_VALID_TYPE_BOOL, + CTRL_ATTRIBUTE_VALID_TYPE_RANGE, + CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS, + CTRL_ATTRIBUTE_VALID_TYPE_64BIT_INTEGER, + CTRL_ATTRIBUTE_VALID_TYPE_STRING, + CTRL_ATTRIBUTE_VALID_TYPE_BINARY_DATA, + CTRL_ATTRIBUTE_VALID_TYPE_STRING_OPERATION, +} CtrlAttributeValidType; + +typedef struct { + CtrlAttributeValidType valid_type; + union { + /* Only used by RANGE attributes */ + struct { + int64_t min; + int64_t max; + } range; + + /* Only used by INT_BITS attributes */ + unsigned int allowed_ints; + }; + CtrlAttributePerms permissions; +} CtrlAttributeValidValues; + + +/* * Event handle and event structure used to provide an event mechanism to * communicate different backends with the frontend */ @@ -466,12 +499,14 @@ typedef struct { #define NV_CTRL_ATTRIBUTES_XVIDEO_SUBSYSTEM 0x4 #define NV_CTRL_ATTRIBUTES_GLX_SUBSYSTEM 0x8 #define NV_CTRL_ATTRIBUTES_XRANDR_SUBSYSTEM 0x10 +#define NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM 0x20 #define NV_CTRL_ATTRIBUTES_ALL_SUBSYSTEMS \ (NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM | \ NV_CTRL_ATTRIBUTES_XF86VIDMODE_SUBSYSTEM | \ NV_CTRL_ATTRIBUTES_XVIDEO_SUBSYSTEM | \ NV_CTRL_ATTRIBUTES_GLX_SUBSYSTEM | \ - NV_CTRL_ATTRIBUTES_XRANDR_SUBSYSTEM) + NV_CTRL_ATTRIBUTES_XRANDR_SUBSYSTEM | \ + NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM) @@ -598,13 +633,12 @@ ReturnStatus NvCtrlGetVoidAttribute(const CtrlTarget *ctrl_target, /* * NvCtrlGetValidAttributeValues() - get the valid settable values for - * the specified attribute. See the description of - * NVCTRLAttributeValidValuesRec in NVCtrl.h. + * the specified attribute. */ ReturnStatus NvCtrlGetValidAttributeValues(const CtrlTarget *ctrl_target, int attr, - NVCTRLAttributeValidValuesRec *val); + CtrlAttributeValidValues *val); /* @@ -612,7 +646,7 @@ ReturnStatus NvCtrlGetValidAttributeValues(const CtrlTarget *ctrl_target, */ ReturnStatus NvCtrlGetAttributePerms(const CtrlTarget *ctrl_target, - int attr_type, + CtrlAttributeType attr_type, int attr, CtrlAttributePerms *perms); @@ -658,11 +692,11 @@ ReturnStatus NvCtrlGetVoidDisplayAttribute(const CtrlTarget *ctrl_target, ReturnStatus NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target, unsigned int display_mask, int attr, - NVCTRLAttributeValidValuesRec *val); + CtrlAttributeValidValues *val); ReturnStatus NvCtrlGetValidStringDisplayAttributeValues(const CtrlTarget *ctrl_target, unsigned int display_mask, int attr, - NVCTRLAttributeValidValuesRec *val); + CtrlAttributeValidValues *val); ReturnStatus NvCtrlGetStringDisplayAttribute(const CtrlTarget *ctrl_target, unsigned int display_mask, diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c index 6a22ff0..e17fbdd 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c +++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c @@ -252,14 +252,152 @@ ReturnStatus NvCtrlNvControlSetAttribute (NvCtrlAttributePrivateHandle *h, } +/* + * Helper function for converting NV-CONTROL specific permission data into + * CtrlAttributePerms (API agnostic) permission data that the front-end can use. + */ + +static void convertFromNvCtrlPermissions(CtrlAttributePerms *dst, + unsigned int permissions) +{ + memset(dst, 0, sizeof(*dst)); + + dst->read = (permissions & ATTRIBUTE_TYPE_READ) ? NV_TRUE : NV_FALSE; + dst->write = (permissions & ATTRIBUTE_TYPE_WRITE) ? NV_TRUE : NV_FALSE; + + if (permissions & ATTRIBUTE_TYPE_X_SCREEN) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_DISPLAY) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(DISPLAY_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_GPU) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(GPU_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_FRAMELOCK) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(FRAMELOCK_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_VCSC) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(VCS_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_GVI) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(GVI_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_COOLER) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(COOLER_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_THERMAL_SENSOR) { + dst->valid_targets |= CTRL_TARGET_PERM_BIT(THERMAL_SENSOR_TARGET); + } + if (permissions & ATTRIBUTE_TYPE_3D_VISION_PRO_TRANSCEIVER) { + dst->valid_targets |= + CTRL_TARGET_PERM_BIT(NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET); + } +} + + +ReturnStatus +NvCtrlNvControlGetAttributePerms(const NvCtrlAttributePrivateHandle *h, + CtrlAttributeType attr_type, int attr, + CtrlAttributePerms *perms) +{ + NVCTRLAttributePermissionsRec nvctrlPerms; + + switch (attr_type) { + case CTRL_ATTRIBUTE_TYPE_INTEGER: + XNVCTRLQueryAttributePermissions(h->dpy, attr, &nvctrlPerms); + convertFromNvCtrlPermissions(perms, nvctrlPerms.permissions); + break; + + case CTRL_ATTRIBUTE_TYPE_STRING: + XNVCTRLQueryStringAttributePermissions(h->dpy, attr, &nvctrlPerms); + convertFromNvCtrlPermissions(perms, nvctrlPerms.permissions); + break; + + case CTRL_ATTRIBUTE_TYPE_BINARY_DATA: + XNVCTRLQueryBinaryDataAttributePermissions(h->dpy, attr, &nvctrlPerms); + convertFromNvCtrlPermissions(perms, nvctrlPerms.permissions); + break; + + case CTRL_ATTRIBUTE_TYPE_STRING_OPERATION: + XNVCTRLQueryStringOperationAttributePermissions(h->dpy, attr, + &nvctrlPerms); + convertFromNvCtrlPermissions(perms, nvctrlPerms.permissions); + break; + + default: + return NvCtrlBadArgument; + } + + return NvCtrlSuccess; + +} + + +/* + * Helper function for converting NV-CONTROL specific valid values data into + * CtrlAttributeValidValues (API agnostic) data that the front-end can use. + */ + +static void +convertFromNvCtrlValidValues(CtrlAttributeValidValues *dst, + const NVCTRLAttributeValidValuesRec *src) +{ + memset(dst, 0, sizeof(*dst)); + + switch (src->type) { + case ATTRIBUTE_TYPE_INTEGER: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_INTEGER; + break; + case ATTRIBUTE_TYPE_BITMASK: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_BITMASK; + break; + case ATTRIBUTE_TYPE_BOOL: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_BOOL; + break; + case ATTRIBUTE_TYPE_RANGE: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_RANGE; + break; + case ATTRIBUTE_TYPE_INT_BITS: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS; + break; + case ATTRIBUTE_TYPE_64BIT_INTEGER: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_64BIT_INTEGER; + break; + case ATTRIBUTE_TYPE_STRING: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_STRING; + break; + case ATTRIBUTE_TYPE_BINARY_DATA: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_BINARY_DATA; + break; + case ATTRIBUTE_TYPE_STRING_OPERATION: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_STRING_OPERATION; + break; + default: + dst->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_UNKNOWN; + } + + if (src->type == ATTRIBUTE_TYPE_RANGE) { + dst->range.min = src->u.range.min; + dst->range.max = src->u.range.max; + } + else if (src->type == ATTRIBUTE_TYPE_INT_BITS) { + dst->allowed_ints = src->u.bits.ints; + } + + convertFromNvCtrlPermissions(&(dst->permissions), src->permissions); +} + ReturnStatus NvCtrlNvControlGetValidAttributeValues(const NvCtrlAttributePrivateHandle *h, unsigned int display_mask, int attr, - NVCTRLAttributeValidValuesRec *val) + CtrlAttributeValidValues *val) { if (attr <= NV_CTRL_LAST_ATTRIBUTE) { const CtrlTargetTypeInfo *targetTypeInfo; + NVCTRLAttributeValidValuesRec valid; + targetTypeInfo = NvCtrlGetTargetTypeInfo(h->target_type); if (targetTypeInfo == NULL) { return NvCtrlBadHandle; @@ -268,7 +406,10 @@ NvCtrlNvControlGetValidAttributeValues(const NvCtrlAttributePrivateHandle *h, if (XNVCTRLQueryValidTargetAttributeValues(h->dpy, targetTypeInfo->nvctrl, h->target_id, display_mask, - attr, val)) { + attr, &valid)) { + if (val != NULL) { + convertFromNvCtrlValidValues(val, &valid); + } return NvCtrlSuccess; } else { return NvCtrlAttributeNotAvailable; @@ -285,13 +426,15 @@ NvCtrlNvControlGetValidStringDisplayAttributeValues (const NvCtrlAttributePrivateHandle *h, unsigned int display_mask, int attr, - NVCTRLAttributeValidValuesRec *val) + CtrlAttributeValidValues *val) { if (attr <= NV_CTRL_STRING_LAST_ATTRIBUTE) { if (NV_VERSION2(h->nv->major_version, h->nv->minor_version) >= NV_VERSION2(1, 22)) { const CtrlTargetTypeInfo *targetTypeInfo; + NVCTRLAttributeValidValuesRec valid; + targetTypeInfo = NvCtrlGetTargetTypeInfo(h->target_type); if (targetTypeInfo == NULL) { return NvCtrlBadHandle; @@ -301,16 +444,20 @@ NvCtrlNvControlGetValidStringDisplayAttributeValues targetTypeInfo->nvctrl, h->target_id, display_mask, - attr, val)) { + attr, &valid)) { + if (val != NULL) { + convertFromNvCtrlValidValues(val, &valid); + } return NvCtrlSuccess; } else { return NvCtrlAttributeNotAvailable; } } else { if (val) { - memset(val, 0, sizeof(NVCTRLAttributeValidValuesRec)); - val->type = ATTRIBUTE_TYPE_STRING; - val->permissions = ATTRIBUTE_TYPE_READ | ATTRIBUTE_TYPE_X_SCREEN; + memset(val, 0, sizeof(*val)); + val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_STRING; + val->permissions.read = NV_TRUE; + val->permissions.valid_targets = CTRL_TARGET_PERM_BIT(X_SCREEN_TARGET); return NvCtrlSuccess; } else { return NvCtrlBadArgument; diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c index 77aaf79..27ce8ff 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c +++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c @@ -23,6 +23,7 @@ #include <stdlib.h> /* 64 bit malloc */ #include <string.h> +#include <assert.h> #include "NvCtrlAttributes.h" #include "NvCtrlAttributesPrivate.h" @@ -30,6 +31,8 @@ #include "msg.h" #include "parse.h" +#include "NVCtrlLib.h" + #ifdef NVML_AVAILABLE #include <nvml.h> @@ -189,3 +192,1436 @@ ReturnStatus NvCtrlDestroyNvml(void) #endif } + +/* + * Creates and fills an IDs dictionary so we can translate from NV-CONTROL IDs + * to NVML indexes + * + * XXX Needed while using NV-CONTROL as fallback during the migration process + */ + +#ifdef NVML_AVAILABLE + +static void matchNvCtrlWithNvmlIds(const NvCtrlAttributePrivateHandle *h, + int deviceCount, + unsigned int **idsDictionary) +{ + char nvmlUUID[MAX_NVML_STR_LEN]; + char *nvctrlUUID = NULL; + nvmlDevice_t device; + int i, j; + + *idsDictionary = nvalloc(deviceCount * sizeof(unsigned int)); + + /* Fallback case is to use same id either for NV-CONTROL and NVML */ + for (i = 0; i < deviceCount; i++) { + (*idsDictionary)[i] = i; + } + + if (h->nv != NULL) { + for (i = 0; i < deviceCount; i++) { + /* Get GPU UUID through NV-CONTROL */ + if (!XNVCTRLQueryTargetStringAttribute(h->dpy, + NV_CTRL_TARGET_TYPE_GPU, + i, 0, + NV_CTRL_STRING_GPU_UUID, + &nvctrlUUID)) { + continue; + } + + if (nvctrlUUID == NULL) { + continue; + } + + /* Look for the same UUID through NVML */ + for (j = 0; j < deviceCount; j++) { + if (NVML_SUCCESS != nvmlDeviceGetHandleByIndex(j, &device)) { + continue; + } + + if (NVML_SUCCESS != nvmlDeviceGetUUID(device, nvmlUUID, + MAX_NVML_STR_LEN)) { + continue; + } + + if (strcmp(nvctrlUUID, nvmlUUID) == 0) { + /* We got a match */ + (*idsDictionary)[i] = j; + break; + } + } + + XFree(nvctrlUUID); + } + } +} + +#endif // NVML_AVAILABLE + + + +/* + * Initializes an NVML private handle to hold some information to be used later + * on + */ + +NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h) +{ +#ifdef NVML_AVAILABLE + + NvCtrlNvmlAttributes *nvml = NULL; + unsigned int count; + unsigned int *nvctrlToNvmlId; + int i; + + /* Check parameters */ + if (!__isNvmlLoaded || h == NULL || + !TARGET_TYPE_IS_NVML_COMPATIBLE(h->target_type)) { + goto fail; + } + + /* Create storage for NVML attributes */ + nvml = nvalloc(sizeof(NvCtrlNvmlAttributes)); + + /* Initialize NVML attributes */ + if (nvmlDeviceGetCount(&count) != NVML_SUCCESS) { + goto fail; + } + nvml->deviceCount = count; + + nvml->sensorCountPerGPU = calloc(count, sizeof(unsigned int)); + nvml->sensorCount = 0; + nvml->coolerCountPerGPU = calloc(count, sizeof(unsigned int)); + nvml->coolerCount = 0; + if ((nvml->sensorCountPerGPU == NULL) || + (nvml->coolerCountPerGPU == NULL)) { + + goto fail; + } + + /* Fill the NV-CONTROL to NVML IDs dictionary */ + matchNvCtrlWithNvmlIds(h, count, &nvctrlToNvmlId); + + /* + * Fill 'sensorCountPerGPU', 'coolerCountPerGPU' and properly set + * 'deviceIdx' + */ + nvml->deviceIdx = h->target_id; /* Fallback */ + + if (h->target_type == GPU_TARGET) { + nvml->deviceIdx = nvctrlToNvmlId[h->target_id]; + } + + for (i = 0; i < count; i++) { + int devIdx = nvctrlToNvmlId[i]; + nvmlDevice_t device; + nvmlReturn_t ret = nvmlDeviceGetHandleByIndex(devIdx, &device); + if (ret == NVML_SUCCESS) { + unsigned int temp; + unsigned int speed; + + /* + * XXX Currently, NVML only allows to get the GPU temperature so + * check for nvmlDeviceGetTemperature() success to figure + * out if that sensor is available. + */ + ret = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, + &temp); + if (ret == NVML_SUCCESS) { + if ((h->target_type == THERMAL_SENSOR_TARGET) && + (h->target_id == nvml->sensorCount)) { + + nvml->deviceIdx = devIdx; + } + + nvml->sensorCountPerGPU[i] = 1; + nvml->sensorCount++; + } + + /* + * XXX NVML assumes at most 1 fan per GPU so check for + * nvmlDeviceGetFanSpeed succes to figure out if that fan is + * available. + */ + ret = nvmlDeviceGetFanSpeed(device, &speed); + if (ret == NVML_SUCCESS) { + if ((h->target_type == COOLER_TARGET) && + (h->target_id == nvml->coolerCount)) { + + nvml->deviceIdx = devIdx; + } + + nvml->coolerCountPerGPU[i] = 1; + nvml->coolerCount++; + } + } + } + + free(nvctrlToNvmlId); + + return nvml; + + fail: + free(nvml->sensorCountPerGPU); + free(nvml->coolerCountPerGPU); + free(nvml); + return NULL; + +#else + return NULL; +#endif +} + + + +/* + * Frees any resource hold by the NVML private handle + */ + +void NvCtrlNvmlAttributesClose(NvCtrlAttributePrivateHandle *h) +{ +#ifdef NVML_AVAILABLE + + /* Check parameters */ + if (h == NULL || h->nvml == NULL) { + return; + } + + free(h->nvml->sensorCountPerGPU); + free(h->nvml->coolerCountPerGPU); + free(h->nvml); + h->nvml = NULL; + +#endif +} + + + +/* + * Get the number of 'target_type' targets according to NVML + */ + +ReturnStatus NvCtrlNvmlQueryTargetCount(const CtrlTarget *ctrl_target, + int target_type, int *val) +{ +#ifdef NVML_AVAILABLE + + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(target_type)); + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + switch (target_type) { + case GPU_TARGET: + *val = (int)(h->nvml->deviceCount); + break; + case THERMAL_SENSOR_TARGET: + *val = (int)(h->nvml->sensorCount); + break; + case COOLER_TARGET: + *val = (int)(h->nvml->coolerCount); + break; + default: + return NvCtrlBadArgument; + } + + return NvCtrlSuccess; + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Get NVML String Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus NvCtrlNvmlGetGPUStringAttribute(const CtrlTarget *ctrl_target, + int attr, char **ptr) +{ + char res[MAX_NVML_STR_LEN]; + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + nvmlDevice_t device; + nvmlReturn_t ret; + *ptr = NULL; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_STRING_PRODUCT_NAME: + ret = nvmlDeviceGetName(device, res, MAX_NVML_STR_LEN); + break; + + case NV_CTRL_STRING_VBIOS_VERSION: + ret = nvmlDeviceGetVbiosVersion(device, res, MAX_NVML_STR_LEN); + break; + + case NV_CTRL_STRING_GPU_UUID: + ret = nvmlDeviceGetUUID(device, res, MAX_NVML_STR_LEN); + break; + + case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION: + case NV_CTRL_STRING_SLI_MODE: + case NV_CTRL_STRING_PERFORMANCE_MODES: + case NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS: + case NV_CTRL_STRING_GPU_UTILIZATION: + case NV_CTRL_STRING_MULTIGPU_MODE: + case NV_CTRL_STRING_GVIO_FIRMWARE_VERSION: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a GPU string attribute? */ + nv_warning_msg("Unhandled string attribute %s (%d) of GPU (%d)", + STR_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + *ptr = strdup(res); + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +#endif // NVML_AVAILABLE + +ReturnStatus NvCtrlNvmlGetStringAttribute(const CtrlTarget *ctrl_target, + int attr, char **ptr) +{ +#ifdef NVML_AVAILABLE + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + return NvCtrlNvmlGetGPUStringAttribute(ctrl_target, attr, ptr); + + case THERMAL_SENSOR_TARGET: + /* Did we forget to handle a sensor string attribute? */ + nv_warning_msg("Unhandled string attribute %s (%d) of Thermal " + "sensor (%d)", STR_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + + case COOLER_TARGET: + /* Did we forget to handle a cooler string attribute? */ + nv_warning_msg("Unhandled string attribute %s (%d) of Fan (%d)", + STR_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + + default: + return NvCtrlBadHandle; + } + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Set NVML String Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus NvCtrlNvmlSetGPUStringAttribute(CtrlTarget *ctrl_target, + int attr, const char *ptr) +{ + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a GPU string attribute? */ + nv_warning_msg("Unhandled string attribute %s (%d) of GPU (%d) " + "(set to '%s')", STR_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target), (ptr ? ptr : "")); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +#endif // NVML_AVAILABLE + +ReturnStatus NvCtrlNvmlSetStringAttribute(CtrlTarget *ctrl_target, + int attr, const char *ptr) +{ +#ifdef NVML_AVAILABLE + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + return NvCtrlNvmlSetGPUStringAttribute(ctrl_target, attr, ptr); + + case THERMAL_SENSOR_TARGET: + /* Did we forget to handle a sensor string attribute? */ + nv_warning_msg("Unhandled string attribute %s (%d) of Thermal " + "sensor (%d) (set to '%s')", + STR_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target), (ptr ? ptr : "")); + return NvCtrlNotSupported; + + case COOLER_TARGET: + /* Did we forget to handle a cooler string attribute? */ + nv_warning_msg("Unhandled string attribute %s (%d) of Fan (%d) " + "(set to '%s')", STR_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target), (ptr ? ptr : "")); + return NvCtrlNotSupported; + + default: + return NvCtrlBadHandle; + } + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Get NVML Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target, + int attr, int64_t *val) +{ + unsigned int res; + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY: + case NV_CTRL_USED_DEDICATED_GPU_MEMORY: + { + nvmlMemory_t memory; + ret = nvmlDeviceGetMemoryInfo(device, &memory); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY: + res = memory.total >> 20; // bytes --> MB + break; + case NV_CTRL_USED_DEDICATED_GPU_MEMORY: + res = memory.used >> 20; // bytes --> MB + break; + } + } + } + break; + + case NV_CTRL_PCI_DOMAIN: + case NV_CTRL_PCI_BUS: + case NV_CTRL_PCI_DEVICE: + case NV_CTRL_PCI_FUNCTION: + case NV_CTRL_PCI_ID: + { + nvmlPciInfo_t pci; + ret = nvmlDeviceGetPciInfo(device, &pci); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_PCI_DOMAIN: + res = pci.domain; + break; + case NV_CTRL_PCI_BUS: + res = pci.bus; + break; + case NV_CTRL_PCI_DEVICE: + res = pci.device; + break; + case NV_CTRL_PCI_FUNCTION: + { + char *f = strrchr(pci.busId, '.'); + if (f != NULL) { + res = atoi(f + 1); + } + else { + res = 0; + } + } + break; + case NV_CTRL_PCI_ID: + res = ((pci.pciDeviceId << 16) & 0xffff0000) | + ((pci.pciDeviceId >> 16) & 0x0000ffff); + break; + } + } + } + break; + + case NV_CTRL_GPU_PCIE_GENERATION: + ret = nvmlDeviceGetMaxPcieLinkGeneration(device, &res); + break; + + case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH: + ret = nvmlDeviceGetMaxPcieLinkWidth(device, &res); + break; + + case NV_CTRL_VIDEO_RAM: + case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH: + case NV_CTRL_GPU_PCIE_MAX_LINK_SPEED: + case NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED: + case NV_CTRL_BUS_TYPE: + case NV_CTRL_GPU_MEMORY_BUS_WIDTH: + case NV_CTRL_GPU_CORES: + case NV_CTRL_IRQ: + case NV_CTRL_GPU_COOLER_MANUAL_CONTROL: + case NV_CTRL_GPU_POWER_SOURCE: + case NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL: + case NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE: + case NV_CTRL_GPU_POWER_MIZER_MODE: + case NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE: + case NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_IMMEDIATE: + case NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_REBOOT: + case NV_CTRL_GPU_ECC_SUPPORTED: + case NV_CTRL_GPU_ECC_STATUS: + case NV_CTRL_GPU_ECC_CONFIGURATION: + case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION: + case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS: + case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS: + case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED: + case NV_CTRL_ENABLED_DISPLAYS: + case NV_CTRL_CONNECTED_DISPLAYS: + case NV_CTRL_MAX_SCREEN_WIDTH: + case NV_CTRL_MAX_SCREEN_HEIGHT: + case NV_CTRL_MAX_DISPLAYS: + case NV_CTRL_DEPTH_30_ALLOWED: + case NV_CTRL_MULTIGPU_MASTER_POSSIBLE: + case NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE: + case NV_CTRL_BASE_MOSAIC: + case NV_CTRL_XINERAMA: + case NV_CTRL_ATTR_NV_MAJOR_VERSION: + case NV_CTRL_ATTR_NV_MINOR_VERSION: + case NV_CTRL_OPERATING_SYSTEM: + case NV_CTRL_NO_SCANOUT: + case NV_CTRL_GPU_CORE_TEMPERATURE: + case NV_CTRL_AMBIENT_TEMPERATURE: + case NV_CTRL_GPU_CURRENT_CLOCK_FREQS: + case NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS: + case NV_CTRL_VIDEO_ENCODER_UTILIZATION: + case NV_CTRL_VIDEO_DECODER_UTILIZATION: + case NV_CTRL_FRAMELOCK: + case NV_CTRL_IS_GVO_DISPLAY: + case NV_CTRL_DITHERING: + case NV_CTRL_CURRENT_DITHERING: + case NV_CTRL_DITHERING_MODE: + case NV_CTRL_CURRENT_DITHERING_MODE: + case NV_CTRL_DITHERING_DEPTH: + case NV_CTRL_CURRENT_DITHERING_DEPTH: + case NV_CTRL_DIGITAL_VIBRANCE: + case NV_CTRL_IMAGE_SHARPENING_DEFAULT: + case NV_CTRL_REFRESH_RATE: + case NV_CTRL_REFRESH_RATE_3: + case NV_CTRL_COLOR_SPACE: + case NV_CTRL_COLOR_RANGE: + case NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES: + case NV_CTRL_DPY_HDMI_3D: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a GPU integer attribute? */ + nv_warning_msg("Unhandled integer attribute %s (%d) of GPU " + "(%d)", INT_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + *val = res; + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +static int getThermalCoolerId(const NvCtrlAttributePrivateHandle *h, + unsigned int thermalCoolerCount, + const unsigned int *thermalCoolerCountPerGPU) +{ + int i, count; + + if ((h->target_id < 0) || (h->target_id >= thermalCoolerCount)) { + return -1; + } + + count = 0; + for (i = 0; i < h->nvml->deviceCount; i++) { + int tmp = count + thermalCoolerCountPerGPU[i]; + if (h->target_id < tmp) { + return (h->target_id - count); + } + count = tmp; + } + + return -1; +} + +static ReturnStatus NvCtrlNvmlGetThermalAttribute(const CtrlTarget *ctrl_target, + int attr, int64_t *val) +{ + unsigned int res; + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + int sensorId; + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + /* Get the proper device according to the sensor ID */ + sensorId = getThermalCoolerId(h, h->nvml->sensorCount, + h->nvml->sensorCountPerGPU); + if (sensorId == -1) { + return NvCtrlBadHandle; + } + + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_THERMAL_SENSOR_READING: + ret = nvmlDeviceGetTemperature(device, + NVML_TEMPERATURE_GPU, + &res); + break; + + case NV_CTRL_THERMAL_SENSOR_PROVIDER: + case NV_CTRL_THERMAL_SENSOR_TARGET: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a sensor integer attribute? */ + nv_warning_msg("Unhandled integer attribute %s (%d) of " + "Thermal sensor (%d)", INT_ATTRIBUTE_NAME(attr), + attr, NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + *val = res; + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +static ReturnStatus NvCtrlNvmlGetCoolerAttribute(const CtrlTarget *ctrl_target, + int attr, int64_t *val) +{ + unsigned int res; + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + int coolerId; + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + /* Get the proper device according to the cooler ID */ + coolerId = getThermalCoolerId(h, h->nvml->coolerCount, + h->nvml->coolerCountPerGPU); + if (coolerId == -1) { + return NvCtrlBadHandle; + } + + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_THERMAL_COOLER_LEVEL: + ret = nvmlDeviceGetFanSpeed(device, &res); + break; + + case NV_CTRL_THERMAL_COOLER_SPEED: + case NV_CTRL_THERMAL_COOLER_CONTROL_TYPE: + case NV_CTRL_THERMAL_COOLER_TARGET: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a cooler integer attribute? */ + nv_warning_msg("Unhandled integer attribute %s (%d) of Fan " + "(%d)", INT_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + *val = res; + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +#endif // NVML_AVAILABLE + +ReturnStatus NvCtrlNvmlGetAttribute(const CtrlTarget *ctrl_target, + int attr, int64_t *val) +{ +#ifdef NVML_AVAILABLE + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + return NvCtrlNvmlGetGPUAttribute(ctrl_target, attr, val); + case THERMAL_SENSOR_TARGET: + return NvCtrlNvmlGetThermalAttribute(ctrl_target, attr, val); + case COOLER_TARGET: + return NvCtrlNvmlGetCoolerAttribute(ctrl_target, attr, val); + default: + return NvCtrlBadHandle; + } + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Set NVML Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target, + int attr, int index, int val) +{ + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_GPU_CURRENT_CLOCK_FREQS: + case NV_CTRL_GPU_POWER_MIZER_MODE: + case NV_CTRL_GPU_ECC_CONFIGURATION: + case NV_CTRL_GPU_COOLER_MANUAL_CONTROL: + case NV_CTRL_DITHERING: + case NV_CTRL_DITHERING_MODE: + case NV_CTRL_DITHERING_DEPTH: + case NV_CTRL_DIGITAL_VIBRANCE: + case NV_CTRL_COLOR_SPACE: + case NV_CTRL_COLOR_RANGE: + case NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a GPU integer attribute? */ + nv_warning_msg("Unhandled integer attribute %s (%d) of GPU " + "(%d) (set to %d)", INT_ATTRIBUTE_NAME(attr), + attr, NvCtrlGetTargetId(ctrl_target), val); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +static ReturnStatus NvCtrlNvmlSetCoolerAttribute(CtrlTarget *ctrl_target, + int attr, int val) +{ + NvCtrlAttributePrivateHandle *h = getPrivateHandle(ctrl_target); + int coolerId; + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + /* Get the proper device according to the cooler ID */ + coolerId = getThermalCoolerId(h, h->nvml->coolerCount, + h->nvml->coolerCountPerGPU); + if (coolerId == -1) { + return NvCtrlBadHandle; + } + + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_THERMAL_COOLER_LEVEL: + case NV_CTRL_THERMAL_COOLER_LEVEL_SET_DEFAULT: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a cooler integer attribute? */ + nv_warning_msg("Unhandled integer attribute %s (%d) of Fan " + "(%d) (set to %d)", INT_ATTRIBUTE_NAME(attr), + attr, NvCtrlGetTargetId(ctrl_target), val); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +#endif // NVML_AVAILABLE + +ReturnStatus NvCtrlNvmlSetAttribute(CtrlTarget *ctrl_target, int attr, + int index, int val) +{ +#ifdef NVML_AVAILABLE + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + return NvCtrlNvmlSetGPUAttribute(ctrl_target, attr, index, val); + + case THERMAL_SENSOR_TARGET: + /* Did we forget to handle a sensor integer attribute? */ + nv_warning_msg("Unhandled integer attribute %s (%d) of Thermal " + "sensor (%d) (set to %d)", INT_ATTRIBUTE_NAME(attr), + attr, NvCtrlGetTargetId(ctrl_target), val); + return NvCtrlNotSupported; + + case COOLER_TARGET: + return NvCtrlNvmlSetCoolerAttribute(ctrl_target, attr, val); + default: + return NvCtrlBadHandle; + } + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Get NVML Binary Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus +NvCtrlNvmlGetGPUBinaryAttribute(const CtrlTarget *ctrl_target, + int attr, unsigned char **data, int *len) +{ + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU: + case NV_CTRL_BINARY_DATA_VCSCS_USED_BY_GPU: + case NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU: + case NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU: + case NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU: + case NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU: + case NV_CTRL_BINARY_DATA_GPU_FLAGS: + case NV_CTRL_BINARY_DATA_XSCREENS_USING_GPU: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* Did we forget to handle a GPU binary attribute? */ + nv_warning_msg("Unhandled binary attribute %s (%d) of GPU (%d)", + BIN_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +#endif // NVML_AVAILABLE + +ReturnStatus +NvCtrlNvmlGetBinaryAttribute(const CtrlTarget *ctrl_target, + int attr, unsigned char **data, int *len) +{ +#ifdef NVML_AVAILABLE + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + return NvCtrlNvmlGetGPUBinaryAttribute(ctrl_target, + attr, + data, + len); + + case THERMAL_SENSOR_TARGET: + /* Did we forget to handle a sensor binary attribute? */ + nv_warning_msg("Unhandled binary attribute %s (%d) of Thermal " + "sensor (%d)", BIN_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + + case COOLER_TARGET: + /* Did we forget to handle a cooler binary attribute? */ + nv_warning_msg("Unhandled binary attribute %s (%d) of Fan (%d)", + BIN_ATTRIBUTE_NAME(attr), attr, + NvCtrlGetTargetId(ctrl_target)); + return NvCtrlNotSupported; + + default: + return NvCtrlBadHandle; + } + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Get NVML Valid String Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus +NvCtrlNvmlGetGPUValidStringAttributeValues(int attr, + CtrlAttributeValidValues *val) +{ + switch (attr) { + case NV_CTRL_STRING_PRODUCT_NAME: + case NV_CTRL_STRING_VBIOS_VERSION: + case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION: + case NV_CTRL_STRING_SLI_MODE: + case NV_CTRL_STRING_PERFORMANCE_MODES: + case NV_CTRL_STRING_MULTIGPU_MODE: + case NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS: + case NV_CTRL_STRING_GVIO_FIRMWARE_VERSION: + case NV_CTRL_STRING_GPU_UUID: + case NV_CTRL_STRING_GPU_UTILIZATION: + /* + * XXX We'll eventually need to add support for this attributes. For + * string attributes, NV-CONTROL only sets the attribute type + * and permissions so no actual NVML call will be needed. + */ + return NvCtrlNotSupported; + + default: + /* The attribute queried is not GPU-targeted */ + return NvCtrlAttributeNotAvailable; + } + + return NvCtrlSuccess; +} + +#endif // NVML_AVAILABLE + +ReturnStatus +NvCtrlNvmlGetValidStringAttributeValues(const CtrlTarget *ctrl_target, + int attr, + CtrlAttributeValidValues *val) +{ +#ifdef NVML_AVAILABLE + ReturnStatus ret; + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + ret = NvCtrlNvmlGetGPUValidStringAttributeValues(attr, val); + break; + + case THERMAL_SENSOR_TARGET: + case COOLER_TARGET: + /* The attribute queried is not sensor nor fan-targeted */ + ret = NvCtrlAttributeNotAvailable; + break; + + default: + ret = NvCtrlBadHandle; + break; + } + + + /* + * XXX Did we forgot to handle this attribute? - REMOVE THIS after + * nvidia-settings NVML migration work is done + */ + if (ret == NvCtrlAttributeNotAvailable) { + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + ReturnStatus ret2; + + if (!h->nv) { + return NvCtrlMissingExtension; + } + + ret2 = NvCtrlNvControlGetValidStringDisplayAttributeValues(h, 0, attr, val); + + assert(ret2 == NvCtrlAttributeNotAvailable); + + return ret2; + } + + return ret; + +#else + return NvCtrlMissingExtension; +#endif +} + + + +/* + * Get NVML Valid Attribute Values + */ + +#ifdef NVML_AVAILABLE + +static ReturnStatus +NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr, + CtrlAttributeValidValues *val) +{ + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_VIDEO_RAM: + case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY: + case NV_CTRL_USED_DEDICATED_GPU_MEMORY: + case NV_CTRL_PCI_DOMAIN: + case NV_CTRL_PCI_BUS: + case NV_CTRL_PCI_DEVICE: + case NV_CTRL_PCI_FUNCTION: + case NV_CTRL_PCI_ID: + case NV_CTRL_GPU_PCIE_GENERATION: + case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH: + case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH: + case NV_CTRL_GPU_PCIE_MAX_LINK_SPEED: + case NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED: + case NV_CTRL_BUS_TYPE: + case NV_CTRL_GPU_MEMORY_BUS_WIDTH: + case NV_CTRL_GPU_CORES: + case NV_CTRL_IRQ: + case NV_CTRL_GPU_COOLER_MANUAL_CONTROL: + case NV_CTRL_GPU_POWER_SOURCE: + case NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL: + case NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE: + case NV_CTRL_GPU_POWER_MIZER_MODE: + case NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE: + case NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_IMMEDIATE: + case NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_REBOOT: + case NV_CTRL_GPU_ECC_SUPPORTED: + case NV_CTRL_GPU_ECC_STATUS: + case NV_CTRL_GPU_ECC_CONFIGURATION: + case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION: + case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS: + case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS: + case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED: + case NV_CTRL_ENABLED_DISPLAYS: + case NV_CTRL_CONNECTED_DISPLAYS: + case NV_CTRL_MAX_SCREEN_WIDTH: + case NV_CTRL_MAX_SCREEN_HEIGHT: + case NV_CTRL_MAX_DISPLAYS: + case NV_CTRL_DEPTH_30_ALLOWED: + case NV_CTRL_MULTIGPU_MASTER_POSSIBLE: + case NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE: + case NV_CTRL_BASE_MOSAIC: + case NV_CTRL_XINERAMA: + case NV_CTRL_ATTR_NV_MAJOR_VERSION: + case NV_CTRL_ATTR_NV_MINOR_VERSION: + case NV_CTRL_OPERATING_SYSTEM: + case NV_CTRL_NO_SCANOUT: + case NV_CTRL_GPU_CORE_TEMPERATURE: + case NV_CTRL_AMBIENT_TEMPERATURE: + case NV_CTRL_GPU_CURRENT_CLOCK_FREQS: + case NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS: + case NV_CTRL_VIDEO_ENCODER_UTILIZATION: + case NV_CTRL_VIDEO_DECODER_UTILIZATION: + case NV_CTRL_FRAMELOCK: + case NV_CTRL_IS_GVO_DISPLAY: + case NV_CTRL_DITHERING: + case NV_CTRL_CURRENT_DITHERING: + case NV_CTRL_DITHERING_MODE: + case NV_CTRL_CURRENT_DITHERING_MODE: + case NV_CTRL_DITHERING_DEPTH: + case NV_CTRL_CURRENT_DITHERING_DEPTH: + case NV_CTRL_DIGITAL_VIBRANCE: + case NV_CTRL_IMAGE_SHARPENING_DEFAULT: + case NV_CTRL_REFRESH_RATE: + case NV_CTRL_REFRESH_RATE_3: + case NV_CTRL_COLOR_SPACE: + case NV_CTRL_COLOR_RANGE: + case NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES: + case NV_CTRL_DPY_HDMI_3D: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* The attribute queried is not GPU-targeted */ + return NvCtrlAttributeNotAvailable; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +static ReturnStatus +NvCtrlNvmlGetThermalValidAttributeValues(const CtrlTarget *ctrl_target, + int attr, + CtrlAttributeValidValues *val) +{ + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + int sensorId; + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + /* Get the proper device and sensor ID according to the target ID */ + sensorId = getThermalCoolerId(h, h->nvml->sensorCount, + h->nvml->sensorCountPerGPU); + if (sensorId == -1) { + return NvCtrlBadHandle; + } + + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_THERMAL_SENSOR_READING: + case NV_CTRL_THERMAL_SENSOR_PROVIDER: + case NV_CTRL_THERMAL_SENSOR_TARGET: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* The attribute queried is not sensor-targeted */ + return NvCtrlAttributeNotAvailable; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +static ReturnStatus +NvCtrlNvmlGetCoolerValidAttributeValues(const CtrlTarget *ctrl_target, + int attr, + CtrlAttributeValidValues *val) +{ + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + int coolerId; + nvmlDevice_t device; + nvmlReturn_t ret; + + if ((h == NULL) || (h->nvml == NULL)) { + return NvCtrlBadHandle; + } + + /* Get the proper device and cooler ID according to the target ID */ + coolerId = getThermalCoolerId(h, h->nvml->coolerCount, + h->nvml->coolerCountPerGPU); + if (coolerId == -1) { + return NvCtrlBadHandle; + } + + + ret = nvmlDeviceGetHandleByIndex(h->nvml->deviceIdx, &device); + if (ret == NVML_SUCCESS) { + switch (attr) { + case NV_CTRL_THERMAL_COOLER_LEVEL: + case NV_CTRL_THERMAL_COOLER_SPEED: + case NV_CTRL_THERMAL_COOLER_CONTROL_TYPE: + case NV_CTRL_THERMAL_COOLER_TARGET: + /* + * XXX We'll eventually need to add support for this attributes + * through NVML + */ + return NvCtrlNotSupported; + + default: + /* The attribute queried is not fan-targeted */ + return NvCtrlAttributeNotAvailable; + } + + if (ret == NVML_SUCCESS) { + return NvCtrlSuccess; + } + } + + /* An NVML error occurred */ + printNvmlError(ret); + return NvCtrlNotSupported; +} + +#endif // NVML_AVAILABLE + +ReturnStatus +NvCtrlNvmlGetValidAttributeValues(const CtrlTarget *ctrl_target, + int attr, + CtrlAttributeValidValues *val) +{ +#ifdef NVML_AVAILABLE + ReturnStatus ret; + + if (!__isNvmlLoaded) { + return NvCtrlMissingExtension; + } + + /* + * This should't be reached for target types that are not handled through + * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up + * to date). + */ + assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target))); + + switch (NvCtrlGetTargetType(ctrl_target)) { + case GPU_TARGET: + ret = NvCtrlNvmlGetGPUValidAttributeValues(ctrl_target, + attr, + val); + break; + + case THERMAL_SENSOR_TARGET: + ret = NvCtrlNvmlGetThermalValidAttributeValues(ctrl_target, + attr, + val); + break; + + case COOLER_TARGET: + ret = NvCtrlNvmlGetCoolerValidAttributeValues(ctrl_target, + attr, + val); + break; + + default: + ret = NvCtrlBadHandle; + } + + + /* + * XXX Did we forgot to handle this attribute? - REMOVE THIS after + * nvidia-settings NVML migration work is done + */ + if (ret == NvCtrlAttributeNotAvailable) { + const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target); + ReturnStatus ret2; + + if (!h->nv) { + return NvCtrlMissingExtension; + } + + ret2 = NvCtrlNvControlGetValidAttributeValues(h, 0, attr, val); + + assert(ret2 == NvCtrlAttributeNotAvailable); + + return ret2; + } + + return ret; + +#else + return NvCtrlMissingExtension; +#endif +} + diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h index 08bdcae..a96840e 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h +++ b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h @@ -77,8 +77,35 @@ #define NV_DLSYM(handle, symbol) ({ dlerror(); dlsym(handle, symbol); }) -/* XXX Modify to be TRUE only for target types which actually need NV-CONTROL */ -#define TARGET_TYPE_NEEDS_NVCONTROL(_TARGET_TYPE_) (TRUE) +/* Useful macros to deal with target types */ + +#ifndef NVML_AVAILABLE +#define TARGET_TYPE_IS_NVML_COMPATIBLE(_TARGET_TYPE) (FALSE) +#else +/* XXX Modify to be TRUE only for target types which are NVML-related */ +#define TARGET_TYPE_IS_NVML_COMPATIBLE(_TARGET_TYPE_) \ + (((_TARGET_TYPE_) == GPU_TARGET) || \ + ((_TARGET_TYPE_) == THERMAL_SENSOR_TARGET) || \ + ((_TARGET_TYPE_) == COOLER_TARGET)) +#endif + +#define TARGET_TYPE_NEEDS_NVCONTROL(_TARGET_TYPE_) \ + (!(TARGET_TYPE_IS_NVML_COMPATIBLE(_TARGET_TYPE_))) + + +/* Useful macros to deal with attribute names */ + +#define ATTRIBUTE_NAME(_ATTR_, _ATTR_TYPE_) \ + ((nv_get_attribute_entry(_ATTR_, _ATTR_TYPE_) != NULL) ? \ + (nv_get_attribute_entry(_ATTR_, _ATTR_TYPE_)->name) : \ + ("Unknown")) + +#define INT_ATTRIBUTE_NAME(_ATTR_) ATTRIBUTE_NAME(_ATTR_, CTRL_ATTRIBUTE_TYPE_INTEGER) +#define STR_ATTRIBUTE_NAME(_ATTR_) ATTRIBUTE_NAME(_ATTR_, CTRL_ATTRIBUTE_TYPE_STRING) +#define SOP_ATTRIBUTE_NAME(_ATTR_) ATTRIBUTE_NAME(_ATTR_, CTRL_ATTRIBUTE_TYPE_STRING_OPERATION) +#define BIN_ATTRIBUTE_NAME(_ATTR_) ATTRIBUTE_NAME(_ATTR_, CTRL_ATTRIBUTE_TYPE_BINARY_DATA) +#define COL_ATTRIBUTE_NAME(_ATTR_) ATTRIBUTE_NAME(_ATTR_, CTRL_ATTRIBUTE_TYPE_COLOR) +#define CSC_ATTRIBUTE_NAME(_ATTR_) ATTRIBUTE_NAME(_ATTR_, CTRL_ATTRIBUTE_TYPE_SDI_CSC) typedef struct __NvCtrlAttributes NvCtrlAttributes; @@ -91,6 +118,7 @@ typedef struct __NvCtrlXvTextureAttributes NvCtrlXvTextureAttributes; typedef struct __NvCtrlXvBlitterAttributes NvCtrlXvBlitterAttributes; typedef struct __NvCtrlXvAttribute NvCtrlXvAttribute; typedef struct __NvCtrlXrandrAttributes NvCtrlXrandrAttributes; +typedef struct __NvCtrlNvmlAttributes NvCtrlNvmlAttributes; typedef struct __NvCtrlEventPrivateHandle NvCtrlEventPrivateHandle; typedef struct __NvCtrlEventPrivateHandleNode NvCtrlEventPrivateHandleNode; @@ -134,6 +162,15 @@ struct __NvCtrlXrandrAttributes { XRRCrtcGamma *pGammaRamp; }; +struct __NvCtrlNvmlAttributes { + unsigned int deviceIdx; /* XXX Needed while using NV-CONTROL as fallback */ + unsigned int deviceCount; + unsigned int sensorCount; + unsigned int *sensorCountPerGPU; + unsigned int coolerCount; + unsigned int *coolerCountPerGPU; +}; + struct __NvCtrlAttributePrivateHandle { Display *dpy; /* display connection */ CtrlTargetType target_type; /* Type of target this handle controls */ @@ -147,6 +184,9 @@ struct __NvCtrlAttributePrivateHandle { NvCtrlXvAttributes *xv; /* XVideo info */ Bool glx; /* GLX extension available */ NvCtrlXrandrAttributes *xrandr; /* XRandR extension info */ + + /* NVML-specific attributes */ + NvCtrlNvmlAttributes *nvml; }; struct __NvCtrlEventPrivateHandle { @@ -308,15 +348,20 @@ NvCtrlNvControlSetAttributeWithReply (NvCtrlAttributePrivateHandle *, unsigned int, int, int); ReturnStatus +NvCtrlNvControlGetAttributePerms(const NvCtrlAttributePrivateHandle *, + CtrlAttributeType, int, + CtrlAttributePerms *); + +ReturnStatus NvCtrlNvControlGetValidAttributeValues(const NvCtrlAttributePrivateHandle *, unsigned int, int, - NVCTRLAttributeValidValuesRec *); + CtrlAttributeValidValues *); ReturnStatus NvCtrlNvControlGetValidStringDisplayAttributeValues (const NvCtrlAttributePrivateHandle *, unsigned int, int, - NVCTRLAttributeValidValuesRec *); + CtrlAttributeValidValues *); ReturnStatus NvCtrlNvControlGetStringAttribute(const NvCtrlAttributePrivateHandle *, @@ -352,7 +397,33 @@ void NvCtrlAssignGammaInput(NvCtrlGammaInput *pGammaInput, const unsigned int bitmask); /* NVML backend functions */ + ReturnStatus NvCtrlInitNvml(void); ReturnStatus NvCtrlDestroyNvml(void); +NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *); +void NvCtrlNvmlAttributesClose(NvCtrlAttributePrivateHandle *); + +ReturnStatus NvCtrlNvmlQueryTargetCount(const CtrlTarget *ctrl_target, + int target_type, int *val); +ReturnStatus NvCtrlNvmlGetStringAttribute(const CtrlTarget *ctrl_target, + int attr, char **ptr); +ReturnStatus NvCtrlNvmlSetStringAttribute(CtrlTarget *ctrl_target, + int attr, const char *ptr); +ReturnStatus NvCtrlNvmlGetAttribute(const CtrlTarget *ctrl_target, + int attr, int64_t *val); +ReturnStatus NvCtrlNvmlSetAttribute(CtrlTarget *ctrl_target, int attr, + int index, int val); +ReturnStatus +NvCtrlNvmlGetBinaryAttribute(const CtrlTarget *ctrl_target, + int attr, unsigned char **data, int *len); +ReturnStatus +NvCtrlNvmlGetValidStringAttributeValues(const CtrlTarget *ctrl_target, + int attr, + CtrlAttributeValidValues *val); +ReturnStatus +NvCtrlNvmlGetValidAttributeValues(const CtrlTarget *ctrl_target, + int attr, + CtrlAttributeValidValues *val); + #endif /* __NVCTRL_ATTRIBUTES_PRIVATE__ */ diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c b/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c index f08fe08..61cdcbf 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c +++ b/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c @@ -818,10 +818,10 @@ static Bool load_system_info(CtrlSystem *system, const char *display) { ReturnStatus status; CtrlTarget *xscreenQueryTarget = NULL; + CtrlTarget *nvmlQueryTarget = NULL; int i, target_type, val, len, target_count; int *pData = NULL; const CtrlTargetTypeInfo *targetTypeInfo; - Bool nvml_found; if (!system) { return FALSE; @@ -837,9 +837,13 @@ static Bool load_system_info(CtrlSystem *system, const char *display) system->dpy = XOpenDisplay(system->display); /* Try to initialize the NVML library */ - nvml_found = (NvCtrlInitNvml() == NvCtrlSuccess); + if (NvCtrlInitNvml() == NvCtrlSuccess) { + nvmlQueryTarget = nv_alloc_ctrl_target(system, GPU_TARGET, 0, + NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM| + NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM); + } - if (system->dpy == NULL && !nvml_found) { + if ((system->dpy == NULL) && (nvmlQueryTarget == NULL)) { nv_error_msg("Unable to load info from any available system"); return FALSE; } @@ -868,6 +872,18 @@ static Bool load_system_info(CtrlSystem *system, const char *display) target_count = ScreenCount(system->dpy); } } + else if ((nvmlQueryTarget != NULL) && + TARGET_TYPE_IS_NVML_COMPATIBLE(target_type)) { + + status = NvCtrlNvmlQueryTargetCount(nvmlQueryTarget, + target_type, &val); + if (status != NvCtrlSuccess) { + nv_warning_msg("Unable to determine number of NVIDIA %ss", + targetTypeInfo->name); + val = 0; + } + target_count = val; + } else { /* @@ -1009,6 +1025,11 @@ static Bool load_system_info(CtrlSystem *system, const char *display) NvCtrlTargetListAdd(&(system->physical_screens), target, FALSE); } + /* Clean up */ + if (nvmlQueryTarget != NULL) { + nv_free_ctrl_target(nvmlQueryTarget); + } + return TRUE; } diff --git a/src/parse.c b/src/parse.c index a4b16b1..4fadb3c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -129,6 +129,7 @@ const AttributeTableEntry attributeTable[] = { { "SLIMode", NV_CTRL_STRING_SLI_MODE, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns a string describing the current SLI mode, if any." }, { "MultiGpuMode", NV_CTRL_STRING_MULTIGPU_MODE, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns a string describing the current MultiGPU mode, if any." }, { "AllowGSYNC", NV_CTRL_GSYNC_ALLOWED, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables or disables the use of G-SYNC when available." }, + { "ShowGSYNCVisualIndicator", NV_CTRL_SHOW_GSYNC_VISUAL_INDICATOR, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "If this is enabled (1), the driver will draw an indicator showing whether G-SYNC is in use, when an application is swapping using flipping." }, /* GPU */ { "BusType", NV_CTRL_BUS_TYPE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the type of bus connecting the specified device to the computer. If the target is an X screen, then it uses the GPU driving the X screen as the device." }, @@ -179,7 +180,8 @@ const AttributeTableEntry attributeTable[] = { { "ECCDoubleBitErrors", NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of double-bit ECC errors detected by the targeted GPU since the last POST." }, { "ECCAggregateDoubleBitErrors", NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of double-bit ECC errors detected by the targeted GPU since the last counter reset." }, { "GPUFanControlState", NV_CTRL_GPU_COOLER_MANUAL_CONTROL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The current fan control state; the value of this attribute controls the availability of additional fan control attributes. Note that this attribute is unavailable unless fan control support has been enabled by setting the \"Coolbits\" X config option." }, - { "GPUCurrentFanSpeed", NV_CTRL_THERMAL_COOLER_LEVEL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the GPU fan's current speed." }, + { "GPUTargetFanSpeed", NV_CTRL_THERMAL_COOLER_LEVEL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the GPU fan's target speed." }, + { "GPUCurrentFanSpeed", NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the GPU fan's current speed." }, { "GPUResetFanSpeed", NV_CTRL_THERMAL_COOLER_LEVEL_SET_DEFAULT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Resets the GPU fan's speed to its default." }, { "GPUCurrentFanSpeedRPM", NV_CTRL_THERMAL_COOLER_SPEED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the GPU fan's tachometer-measured speed in rotations per minute (RPM)." }, { "GPUFanControlType", NV_CTRL_THERMAL_COOLER_CONTROL_TYPE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns how the GPU fan is controlled. '1' means the fan can only be toggled on and off; '2' means the fan has variable speed. '0' means the fan is restricted and cannot be adjusted under end user control." }, @@ -313,8 +315,10 @@ const AttributeTableEntry attributeTable[] = { { "RefreshRate", NV_CTRL_REFRESH_RATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {1,0,0,0,0,0,0} }, "Returns the refresh rate of the specified display device in cHz (Centihertz) (to get the refresh rate in Hz, divide the returned value by 100)." }, { "RefreshRate3", NV_CTRL_REFRESH_RATE_3, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,1,0,0,0,0,0} }, "Returns the refresh rate of the specified display device in mHz (Millihertz) (to get the refresh rate in Hz, divide the returned value by 1000)." }, { "OverscanCompensation", NV_CTRL_OVERSCAN_COMPENSATION, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjust the amount of overscan compensation scaling, in pixels, to apply to the specified display device." }, - { "ColorSpace", NV_CTRL_COLOR_SPACE, INT_ATTR, {1,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the color space of the signal sent to the display device." }, - { "ColorRange", NV_CTRL_COLOR_RANGE, INT_ATTR, {1,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the color range of the signal sent to the display device." }, + { "ColorSpace", NV_CTRL_COLOR_SPACE, INT_ATTR, {1,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the preferred color space of the signal sent to the display device." }, + { "ColorRange", NV_CTRL_COLOR_RANGE, INT_ATTR, {1,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the preferred color range of the signal sent to the display device." }, + { "CurrentColorSpace", NV_CTRL_CURRENT_COLOR_SPACE, INT_ATTR, {1,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current color space of the signal sent to the display device." }, + { "CurrentColorRange", NV_CTRL_CURRENT_COLOR_RANGE, INT_ATTR, {1,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current color range of the signal sent to the display device." }, { "SynchronousPaletteUpdates", NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls whether colormap updates are synchronized with X rendering." }, { "CurrentMetaModeID", NV_CTRL_CURRENT_METAMODE_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The ID of the current MetaMode." }, { "RandROutputID", NV_CTRL_DISPLAY_RANDR_OUTPUT_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The RandR Output ID that corresponds to the display device." }, @@ -334,7 +338,8 @@ const AttributeTableEntry attributeTable[] = { /* X Video */ { "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,1,0} }, "DEPRECATED: Use \"XVideoSyncToDisplayID\" instead." }, - { "XVideoSyncToDisplayID", NV_CTRL_XV_SYNC_TO_DISPLAY_ID, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,1,0,0} }, "Controls which display device is synced to by the texture and blitter adaptors when they are set to synchronize to the vertical blanking." }, + { "XVideoSyncToDisplayID", NV_CTRL_XV_SYNC_TO_DISPLAY_ID, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,1,0,0} }, "Controls which display device is synced to by the XVideo texture and blitter adaptors when they are set to synchronize to the vertical blanking." }, + { "CurrentXVideoSyncToDisplayID", NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,1,0,0} }, "Returns the display device synced to by the XVideo texture and blitter adaptors when they are set to synchronize to the vertical blanking." }, /* 3D Vision Pro */ { "3DVisionProResetTransceiverToFactorySettings", NV_CTRL_3D_VISION_PRO_RESET_TRANSCEIVER_TO_FACTORY_SETTINGS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Resets the 3D Vision Pro transceiver to its factory settings."}, @@ -375,7 +380,7 @@ const int attributeTableLen = ARRAY_LEN(attributeTable); * the last attribute that the table knows about. */ -#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GPU_CURRENT_CORE_VOLTAGE +#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_CURRENT_XV_SYNC_TO_DISPLAY_ID #warning "Have you forgotten to add a new integer attribute to attributeTable?" #endif diff --git a/src/query-assign.c b/src/query-assign.c index b4e84f0..5bc489c 100644 --- a/src/query-assign.c +++ b/src/query-assign.c @@ -55,11 +55,11 @@ static int query_all_targets(const char *display_name, const int target_type, CtrlSystemList *); static void print_valid_values(const Options *op, const AttributeTableEntry *a, - NVCTRLAttributeValidValuesRec valid); + CtrlAttributeValidValues valid); static void print_additional_info(const char *name, int attr, - NVCTRLAttributeValidValuesRec valid, + CtrlAttributeValidValues valid, const char *indent); static ReturnStatus get_framelock_sync_state(CtrlTarget *target, @@ -910,7 +910,7 @@ static int validate_value(const Options *op, CtrlTarget *t, char *whence) { int bad_val = NV_FALSE; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; ReturnStatus status; char d_str[256]; char *tmp_d_str; @@ -928,8 +928,10 @@ static int validate_value(const Options *op, CtrlTarget *t, return NV_FALSE; } - if (target_type != DISPLAY_TARGET && - valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { + if ((target_type != DISPLAY_TARGET) && + (valid.permissions.valid_targets & + CTRL_TARGET_PERM_BIT(DISPLAY_TARGET))) { + tmp_d_str = display_device_mask_to_display_device_name(d); sprintf(d_str, ", display device: %s", tmp_d_str); free(tmp_d_str); @@ -937,43 +939,43 @@ static int validate_value(const Options *op, CtrlTarget *t, d_str[0] = '\0'; } - switch (valid.type) { - case ATTRIBUTE_TYPE_INTEGER: - case ATTRIBUTE_TYPE_BITMASK: + switch (valid.valid_type) { + case CTRL_ATTRIBUTE_VALID_TYPE_INTEGER: + case CTRL_ATTRIBUTE_VALID_TYPE_BITMASK: /* don't do any checks on integer or bitmask values */ break; - case ATTRIBUTE_TYPE_BOOL: + case CTRL_ATTRIBUTE_VALID_TYPE_BOOL: if ((p->val.i < 0) || (p->val.i > 1)) { bad_val = NV_TRUE; } break; - case ATTRIBUTE_TYPE_RANGE: + case CTRL_ATTRIBUTE_VALID_TYPE_RANGE: if (a->f.int_flags.is_packed) { - if (((p->val.i >> 16) < (valid.u.range.min >> 16)) || - ((p->val.i >> 16) > (valid.u.range.max >> 16)) || - ((p->val.i & 0xffff) < (valid.u.range.min & 0xffff)) || - ((p->val.i & 0xffff) > (valid.u.range.max & 0xffff))) + if (((p->val.i >> 16) < (valid.range.min >> 16)) || + ((p->val.i >> 16) > (valid.range.max >> 16)) || + ((p->val.i & 0xffff) < (valid.range.min & 0xffff)) || + ((p->val.i & 0xffff) > (valid.range.max & 0xffff))) bad_val = NV_TRUE; } else { - if ((p->val.i < valid.u.range.min) || - (p->val.i > valid.u.range.max)) + if ((p->val.i < valid.range.min) || + (p->val.i > valid.range.max)) bad_val = NV_TRUE; } break; - case ATTRIBUTE_TYPE_INT_BITS: + case CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS: if (a->f.int_flags.is_packed) { unsigned int u, l; u = (((unsigned int) p->val.i) >> 16); l = (p->val.i & 0xffff); - if ((u > 15) || ((valid.u.bits.ints & (1 << u << 16)) == 0) || - (l > 15) || ((valid.u.bits.ints & (1 << l)) == 0)) { + if ((u > 15) || ((valid.allowed_ints & (1 << u << 16)) == 0) || + (l > 15) || ((valid.allowed_ints & (1 << l)) == 0)) { bad_val = NV_TRUE; } } else { if ((p->val.i > 31) || (p->val.i < 0) || - ((valid.u.bits.ints & (1<<p->val.i)) == 0)) { + ((valid.allowed_ints & (1<<p->val.i)) == 0)) { bad_val = NV_TRUE; } } @@ -987,7 +989,7 @@ static int validate_value(const Options *op, CtrlTarget *t, targetTypeInfo = NvCtrlGetTargetTypeInfo(target_type); if (!targetTypeInfo || - !(targetTypeInfo->permission_bit & valid.permissions)) { + !(targetTypeInfo->permission_bit & valid.permissions.valid_targets)) { bad_val = NV_TRUE; } @@ -1021,7 +1023,7 @@ static int validate_value(const Options *op, CtrlTarget *t, */ static void print_valid_values(const Options *op, const AttributeTableEntry *a, - NVCTRLAttributeValidValuesRec valid) + CtrlAttributeValidValues valid) { int bit, print_bit, last, last2, n, i; char str[256]; @@ -1039,16 +1041,16 @@ static void print_valid_values(const Options *op, const AttributeTableEntry *a, #define INDENT " " - switch (valid.type) { - case ATTRIBUTE_TYPE_STRING: + switch (valid.valid_type) { + case CTRL_ATTRIBUTE_VALID_TYPE_STRING: nv_msg(INDENT, "'%s' is a string attribute.", name); break; - case ATTRIBUTE_TYPE_64BIT_INTEGER: + case CTRL_ATTRIBUTE_VALID_TYPE_64BIT_INTEGER: nv_msg(INDENT, "'%s' is a 64 bit integer attribute.", name); break; - case ATTRIBUTE_TYPE_INTEGER: + case CTRL_ATTRIBUTE_VALID_TYPE_INTEGER: if ((a->type == CTRL_ATTRIBUTE_TYPE_INTEGER) && a->f.int_flags.is_packed) { nv_msg(INDENT, "'%s' is a packed integer attribute.", name); @@ -1057,37 +1059,37 @@ static void print_valid_values(const Options *op, const AttributeTableEntry *a, } break; - case ATTRIBUTE_TYPE_BITMASK: + case CTRL_ATTRIBUTE_VALID_TYPE_BITMASK: nv_msg(INDENT, "'%s' is a bitmask attribute.", name); break; - case ATTRIBUTE_TYPE_BOOL: + case CTRL_ATTRIBUTE_VALID_TYPE_BOOL: nv_msg(INDENT, "'%s' is a boolean attribute; valid values are: " "1 (on/true) and 0 (off/false).", name); break; - case ATTRIBUTE_TYPE_RANGE: + case CTRL_ATTRIBUTE_VALID_TYPE_RANGE: if ((a->type == CTRL_ATTRIBUTE_TYPE_INTEGER) && a->f.int_flags.is_packed) { nv_msg(INDENT, "The valid values for '%s' are in the ranges " "%" PRId64 " - %" PRId64 ", %" PRId64 " - %" PRId64 " (inclusive).", - name, valid.u.range.min >> 16, valid.u.range.max >> 16, - valid.u.range.min & 0xffff, valid.u.range.max & 0xffff); + name, valid.range.min >> 16, valid.range.max >> 16, + valid.range.min & 0xffff, valid.range.max & 0xffff); } else { nv_msg(INDENT, "The valid values for '%s' are in the range " "%" PRId64 " - %" PRId64 " (inclusive).", name, - valid.u.range.min, valid.u.range.max); + valid.range.min, valid.range.max); } break; - case ATTRIBUTE_TYPE_INT_BITS: + case CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS: last = last2 = -1; /* scan through the bitmask once to get the last valid bits */ for (bit = 0; bit < 32; bit++) { - if (valid.u.bits.ints & (1 << bit)) { + if (valid.allowed_ints & (1 << bit)) { if ((bit > 15) && (a->type == CTRL_ATTRIBUTE_TYPE_INTEGER) && a->f.int_flags.is_packed) { @@ -1116,7 +1118,7 @@ static void print_valid_values(const Options *op, const AttributeTableEntry *a, at = &c; } - if (valid.u.bits.ints & (1 << bit)) { + if (valid.allowed_ints & (1 << bit)) { if (*at == str || *at == str2) { *at += sprintf(*at, "%d", print_bit); } else if (bit == last || bit == last2) { @@ -1135,13 +1137,17 @@ static void print_valid_values(const Options *op, const AttributeTableEntry *a, nv_msg(INDENT, "Valid values for '%s' are: %s.", name, str); } break; + + default: + /* This should not be reached */ + break; } - if (!(valid.permissions & ATTRIBUTE_TYPE_WRITE)) { + if (!valid.permissions.write) { nv_msg(INDENT, "'%s' is a read-only attribute.", name); } - if (valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { + if (valid.permissions.valid_targets & CTRL_TARGET_PERM_BIT(DISPLAY_TARGET)) { nv_msg(INDENT, "'%s' is display device specific.", name); } @@ -1154,7 +1160,7 @@ static void print_valid_values(const Options *op, const AttributeTableEntry *a, const CtrlTargetTypeInfo *targetTypeInfo = NvCtrlGetTargetTypeInfo(i); - if (valid.permissions & targetTypeInfo->permission_bit) { + if (valid.permissions.valid_targets & targetTypeInfo->permission_bit) { if (n > 0) c += sprintf(c, ", "); c += sprintf(c, "%s", targetTypeInfo->name); n++; @@ -1191,7 +1197,7 @@ typedef enum { static void print_queried_value(const Options *op, CtrlTarget *target, - NVCTRLAttributeValidValuesRec *v, + CtrlAttributeValidValues *v, int val, const AttributeTableEntry *a, uint32 mask, @@ -1221,7 +1227,7 @@ static void print_queried_value(const Options *op, snprintf(val_str, 64, "%.2f Hz", ((float) val) / 100.0); } else if (a->f.int_flags.is_1000Hz) { snprintf(val_str, 64, "%.3f Hz", ((float) val) / 1000.0); - } else if (v->type == ATTRIBUTE_TYPE_BITMASK) { + } else if (v->valid_type == CTRL_ATTRIBUTE_VALID_TYPE_BITMASK) { snprintf(val_str, 64, "0x%08x", val); } else if (a->f.int_flags.is_packed) { snprintf(val_str, 64, "%d,%d", val >> 16, val & 0xffff); @@ -1232,7 +1238,8 @@ static void print_queried_value(const Options *op, /* append the display device name, if necessary */ if ((NvCtrlGetTargetType(target) != DISPLAY_TARGET) && - v->permissions & ATTRIBUTE_TYPE_DISPLAY) { + (v->permissions.valid_targets & CTRL_TARGET_PERM_BIT(DISPLAY_TARGET))) { + tmp_d_str = display_device_mask_to_display_device_name(mask); snprintf(d_str, 64, "; display device: %s", tmp_d_str); free(tmp_d_str); @@ -1330,18 +1337,18 @@ static void print_additional_fsaa_info(const char *name, static void print_additional_info(const char *name, int attr, - NVCTRLAttributeValidValuesRec valid, + CtrlAttributeValidValues valid, const char *indent) { switch (attr) { case NV_CTRL_FSAA_MODE: - print_additional_fsaa_info(name, valid.u.bits.ints, indent); + print_additional_fsaa_info(name, valid.allowed_ints, indent); break; case NV_CTRL_STEREO: - if (valid.type == ATTRIBUTE_TYPE_INT_BITS) { - print_additional_stereo_info(name, valid.u.bits.ints, indent); + if (valid.valid_type == CTRL_ATTRIBUTE_VALID_TYPE_INT_BITS) { + print_additional_stereo_info(name, valid.allowed_ints, indent); } break; @@ -1369,7 +1376,7 @@ static int query_all(const Options *op, const char *display_name, int bit, entry, val, i; uint32 mask; ReturnStatus status; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; CtrlSystem *system; system = NvCtrlConnectToSystem(display_name, systems); @@ -1516,7 +1523,8 @@ static int query_all(const Options *op, const char *display_name, nv_msg(NULL,""); } - if (valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { + if (valid.permissions.valid_targets & + CTRL_TARGET_PERM_BIT(DISPLAY_TARGET)) { continue; } @@ -1608,54 +1616,57 @@ static char *get_display_state_str(CtrlTarget *t) static int print_target_connections(CtrlTarget *t, const char *relation_str, const char *null_relation_str, - unsigned int attrib, - unsigned int target_type) + CtrlTargetType other_target_type) { - int *pData; - int len, i; - ReturnStatus status; const CtrlTargetTypeInfo *targetTypeInfo; + CtrlTargetNode *node; + int count; - targetTypeInfo = NvCtrlGetTargetTypeInfo(target_type); + targetTypeInfo = NvCtrlGetTargetTypeInfo(other_target_type); - /* Query the connected targets */ + /* Count how many 'other_target_type' targets are related to 't' */ + + count = 0; + for (node = t->relations; node; node = node->next) { + if (NvCtrlGetTargetType(node->t) == other_target_type) { + count++; + } + } - status = - NvCtrlGetBinaryAttribute(t, 0, attrib, - (unsigned char **) &pData, - &len); - if (status != NvCtrlSuccess) return NV_FALSE; - if (pData[0] == 0) { + if (count == 0) { nv_msg(" ", "%s any %s.", null_relation_str, targetTypeInfo->name); nv_msg(NULL, ""); - free(pData); return NV_TRUE; } nv_msg(" ", "%s the following %s%s:", relation_str, targetTypeInfo->name, - ((pData[0] > 1) ? "s" : "")); + ((count > 1) ? "s" : "")); /* List the connected targets */ - for (i = 1; i <= pData[0]; i++) { - CtrlTarget *other = NvCtrlGetTarget(t->system, target_type, pData[i]); + for (node = t->relations; node; node = node->next) { + CtrlTarget *other = node->t; char *target_name = NULL; char *product_name = NULL; Bool is_x_name = NV_FALSE; char *extra_str = NULL; + if (NvCtrlGetTargetType(other) != other_target_type) { + continue; + } + if (other) { target_name = other->name; - switch (target_type) { + switch (other_target_type) { case GPU_TARGET: product_name = get_product_name(other, NV_CTRL_STRING_PRODUCT_NAME); @@ -1698,7 +1709,7 @@ static int print_target_connections(CtrlTarget *t, nv_msg(" ", "%s (%s %d)", target_name, targetTypeInfo->name, - pData[i]); + NvCtrlGetTargetId(other)); } if (product_name) { @@ -1714,7 +1725,6 @@ static int print_target_connections(CtrlTarget *t, } nv_msg(NULL, ""); - free(pData); return NV_TRUE; } /* print_target_connections() */ @@ -1858,37 +1868,31 @@ static int query_all_targets(const char *display_name, const int target_type, (t, "Is driving", "Is not driving", - NV_CTRL_BINARY_DATA_XSCREENS_USING_GPU, X_SCREEN_TARGET); print_target_connections (t, "Supports", "Does not support", - NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU, DISPLAY_TARGET); print_target_connections (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU, FRAMELOCK_TARGET); print_target_connections (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_VCSCS_USED_BY_GPU, VCS_TARGET); print_target_connections (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU, COOLER_TARGET); print_target_connections (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU, THERMAL_SENSOR_TARGET); break; @@ -1897,13 +1901,11 @@ static int query_all_targets(const char *display_name, const int target_type, (t, "Is driven by", "Is not driven by", - NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN, GPU_TARGET); print_target_connections (t, "Is assigned", "Is not assigned", - NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN, DISPLAY_TARGET); break; @@ -1912,7 +1914,6 @@ static int query_all_targets(const char *display_name, const int target_type, (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK, GPU_TARGET); break; @@ -1921,7 +1922,6 @@ static int query_all_targets(const char *display_name, const int target_type, (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_GPUS_USING_VCSC, GPU_TARGET); break; @@ -1930,8 +1930,7 @@ static int query_all_targets(const char *display_name, const int target_type, (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU, - COOLER_TARGET); + GPU_TARGET); break; case THERMAL_SENSOR_TARGET: @@ -1939,8 +1938,7 @@ static int query_all_targets(const char *display_name, const int target_type, (t, "Is connected to", "Is not connected to", - NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU, - THERMAL_SENSOR_TARGET); + GPU_TARGET); break; default: @@ -1969,7 +1967,7 @@ static int process_parsed_attribute_internal(const Options *op, ParsedAttribute *p, uint32 d, int target_type, int assign, int verbose, char *whence, - NVCTRLAttributeValidValuesRec + CtrlAttributeValidValues valid) { ReturnStatus status; @@ -1977,8 +1975,10 @@ static int process_parsed_attribute_internal(const Options *op, int ret; const AttributeTableEntry *a = p->attr_entry; - if (target_type != DISPLAY_TARGET && - valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { + if ((target_type != DISPLAY_TARGET) && + (valid.permissions.valid_targets & + CTRL_TARGET_PERM_BIT(DISPLAY_TARGET))) { + tmp_d_str = display_device_mask_to_display_device_name(d); sprintf(str, ", display device: %s", tmp_d_str); free(tmp_d_str); @@ -2127,8 +2127,9 @@ int nv_process_parsed_attribute(const Options *op, char *whence, *tmp_d_str0, *tmp_d_str1; ReturnStatus status; CtrlTargetNode *n; - NVCTRLAttributeValidValuesRec valid; + CtrlAttributeValidValues valid; const AttributeTableEntry *a = p->attr_entry; + int display_id_found = NV_FALSE; val = NV_FALSE; @@ -2323,12 +2324,14 @@ int nv_process_parsed_attribute(const Options *op, * If we are assigning, and the value for this attribute is a display * device id/name string, then we need to validate and convert the * given string against list of available display devices. The resulting - * id, if any, is then fed back into the ParsedAttrinute's value as an - * int which is ultimately written out to NV-CONTROL. + * id, if any, is then fed back into the ParsedAttribute's value as an + * int which is ultimately written out to NV-CONTROL. Once the string is + * converted, we can reuse it for all targets. */ if (assign && (a->type == CTRL_ATTRIBUTE_TYPE_INTEGER) && - a->f.int_flags.is_display_id) { + a->f.int_flags.is_display_id && + !display_id_found) { CtrlTargetNode *dpy_node; int found = NV_FALSE; int multi_match = NV_FALSE; @@ -2389,8 +2392,10 @@ int nv_process_parsed_attribute(const Options *op, continue; } - /* Put converted id back into a->val */ + /* Put converted id back into p->val */ + nvfree(p->val.str); p->val.i = id; + display_id_found = NV_TRUE; } @@ -2676,7 +2681,7 @@ int nv_process_parsed_attribute(const Options *op, * that the attribute is writable; if it's not, give up */ - if (assign && !(valid.permissions & ATTRIBUTE_TYPE_WRITE)) { + if (assign && !valid.permissions.write) { nv_error_msg("The attribute '%s' specified %s cannot be " "assigned (it is a read-only attribute).", a->name, whence); diff --git a/src/version.h b/src/version.h index 0fbccd5..b01b79d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define NVIDIA_VERSION "346.47" +#define NVIDIA_VERSION "349.12" diff --git a/src/version.mk b/src/version.mk index d622b1f..714e597 100644 --- a/src/version.mk +++ b/src/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 346.47 +NVIDIA_VERSION = 349.12 @@ -1,17 +1,23 @@ # # Copyright (C) 2008 NVIDIA Corporation # -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: # -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. # -# You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses>. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. # # # utils.mk: common Makefile fragment used by nvidia-xconfig, @@ -1 +1 @@ -NVIDIA_VERSION = 346.47 +NVIDIA_VERSION = 349.12 |