diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2014-02-09 11:36:20 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2014-02-09 11:36:20 -0800 |
commit | d968a4fe6080617367369cdabebeb9b8b5b9f408 (patch) | |
tree | 9ffa943a8c1d949d178ed923dc1a177fcea68056 | |
parent | dfbf9ba4cc36aafd98510c79979571aad3ef905e (diff) |
334.16334.16
55 files changed, 3213 insertions, 2346 deletions
diff --git a/doc/Makefile b/doc/Makefile index 5f60bf2..a511322 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -53,7 +53,7 @@ ifeq ($(MANPAGE_GZIP),1) else MANPAGE = $(MANPAGE_not_gzipped) endif -GEN_MANPAGE_OPTS = $(OUTPUTDIR)/gen-manpage-opts +GEN_MANPAGE_OPTS = $(OUTPUTDIR_ABSOLUTE)/gen-manpage-opts OPTIONS_1_INC = $(OUTPUTDIR)/options.1.inc common_cflags += -I $(COMMON_UTILS_DIR) @@ -102,7 +102,7 @@ $(GEN_MANPAGE_OPTS): $(GEN_MANPAGE_OPTS_OBJS) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_BIN_LDFLAGS) $^ -o $@ $(OPTIONS_1_INC): $(GEN_MANPAGE_OPTS) - @./$< > $@ + @$< > $@ $(MANPAGE_not_gzipped): nvidia-settings.1.m4 $(OPTIONS_1_INC) $(VERSION_MK) $(call quiet_cmd,M4) \ diff --git a/doc/version.mk b/doc/version.mk index 2bca142..591ef07 100644 --- a/doc/version.mk +++ b/doc/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 331.38 +NVIDIA_VERSION = 334.16 diff --git a/samples/nv-control-framelock.c b/samples/nv-control-framelock.c index 322ccb2..dd3ffe3 100644 --- a/samples/nv-control-framelock.c +++ b/samples/nv-control-framelock.c @@ -68,16 +68,20 @@ static void do_query(Display *dpy) Bool ret; int num_framelocks; int framelock; - int gpu; - int mask; - char *name; - - int *data; - int len; - int i; + int gpu, display; + int *gpu_data, *display_data; + char *gpu_name, *display_name; + + int len; + int i, j; int enabled; + int current_config; + int display_enabled; + + const char *current_str; + /* Query the number of frame lock devices on the server */ @@ -95,7 +99,7 @@ static void do_query(Display *dpy) /* Display information for all frame lock devices found */ for (framelock = 0; framelock < num_framelocks; framelock++) { - + printf("\n"); printf("- Frame Lock Board %d :\n", framelock); @@ -107,7 +111,7 @@ static void do_query(Display *dpy) framelock, // target_id 0, // display_mask NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK, - (unsigned char **) &data, + (unsigned char **) &gpu_data, &len); if (!ret) { printf(" - Failed to query list of GPUs!\n"); @@ -116,32 +120,33 @@ static void do_query(Display *dpy) /* Display information for all GPUs connected to frame lock device */ - if ( !data[0] ) { + if ( !gpu_data[0] ) { printf(" - No GPUs found!\n"); } else { - printf(" - Found %d GPU(s).\n", data[0]); + printf(" - Found %d GPU(s).\n", gpu_data[0]); } - for (i = 1; i <= data[0]; i++) { - gpu = data[i]; - + for (i = 1; i <= gpu_data[0]; i++) { + gpu = gpu_data[i]; + /* Query GPU product name */ - + ret = XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_STRING_PRODUCT_NAME, - &name); + &gpu_name); if (!ret) { printf(" - Failed to query GPU %d product name.\n", gpu); continue; - } - printf(" - GPU %d (%s) :\n", gpu, name); + } + printf(" - GPU %d (%s) :\n", gpu, gpu_name); + XFree(gpu_name); /* Query GPU sync state */ - printf(" - Sync : "); + printf(" - Sync : "); ret = XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id @@ -156,52 +161,97 @@ static void do_query(Display *dpy) /* Query GPU displays */ - printf(" - Displays Mask : "); - ret = XNVCTRLQueryTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_ENABLED_DISPLAYS, - &mask); + ret = XNVCTRLQueryTargetBinaryData + (dpy, + NV_CTRL_TARGET_TYPE_GPU, + gpu, + 0, + NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU, + (unsigned char **) &display_data, + &len); + if (!ret) { - printf("Failed to query enabled displays.\n"); - } else { - printf("0x%08x\n", mask); + printf(" - Failed to query connected displays.\n"); + continue; } - /* Query GPU server (master) */ - - printf(" - Server Mask : "); - ret = XNVCTRLQueryTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_FRAMELOCK_MASTER, - &mask); - if (!ret) { - printf("Failed to query server mask.\n"); - } else { - printf("0x%08x\n", mask); + if (!display_data[0]) { + printf(" - No Connected Displays found.\n"); } - /* Query GPU clients (slaves) */ + for (j = 1; j <= display_data[0]; j++) { + + display = display_data[j]; + + /* Query if this display is enabled. Silently skip if not */ + + ret = XNVCTRLQueryTargetAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_DISPLAY_ENABLED, + &display_enabled); + + if (!ret) { + printf(" - Failed to query enabled displays.\n"); + continue; + } + + if (!display_enabled) { + continue; + } + + /* Query current framelock config for this display */ + + ret = XNVCTRLQueryTargetAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, + ¤t_config); + + if (!ret) { + current_config = -1; + } + + if (current_config == NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_SERVER) { + current_str = " - Server"; + } else if (current_config == + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_CLIENT) { + current_str = " - Client"; + } else if (current_config == + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_DISABLED) { + current_str = " - Disabled"; + } else { + current_str = " - Unknown"; + } + + /* Query Display name */ + + ret = XNVCTRLQueryTargetStringAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_STRING_DISPLAY_NAME_RANDR, + &display_name); + + if (ret && display_name) { + printf(" - Display : %s%s\n", display_name, current_str); + XFree(display_name); + } else { + printf(" - Display : 0x%08x%s\n", display, current_str); + } - printf(" - Clients Mask : "); - ret = XNVCTRLQueryTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_FRAMELOCK_SLAVES, - &mask); - if (!ret) { - printf("Failed to query clients mask.\n"); - } else { - printf("0x%08x\n", mask); } + XFree(display_data); + } /* Done disabling GPUs */ - XFree(data); + XFree(gpu_data); } /* Done disabling Frame Lock Devices */ @@ -213,8 +263,8 @@ static void do_query(Display *dpy) * do_enable() * * Enables frame lock on the X Server by setting the first capable/available - * display device as the frame lock server (master) and setting all other - * display devices as clients (slaves). + * display device as the frame lock server and setting all other display + * devices as clients. * * NOTE: It is up to the user to ensure that each display device is set with * the same refresh rate (mode timings). @@ -225,18 +275,20 @@ static void do_enable(Display *dpy) Bool ret; int num_framelocks; int framelock; - int gpu; - unsigned int mask; - int *data; + int gpu, display; + int *gpu_data, *display_data; + char *display_name; + int len; - int i; + int i, j; int enabled; - int masterable; + int serverable; int pick_server = 1; int server_set = 0; + NVCTRLAttributeValidValuesRec values; /* Query the number of frame lock devices to enable */ @@ -252,41 +304,41 @@ static void do_enable(Display *dpy) } /* Enable frame lock on all GPUs connected to each frame lock device */ - + for (framelock = 0; framelock < num_framelocks; framelock++) { - + printf("\n"); printf("- Frame Lock Board %d :\n", framelock); /* Query the GPUs connected to this frame lock device */ - + ret = XNVCTRLQueryTargetBinaryData (dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK, framelock, // target_id 0, // display_mask NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK, - (unsigned char **) &data, + (unsigned char **) &gpu_data, &len); if (!ret) { printf(" - Failed to query list of GPUs!\n"); continue; } - + /* Enable frame lock on all GPUs connected to the frame lock device */ - - if ( !data[0] ) { + + if ( !gpu_data[0] ) { printf(" - No GPUs found!\n"); } else { - printf(" - Found %d GPU(s).\n", data[0]); + printf(" - Found %d GPU(s).\n", gpu_data[0]); } - for (i = 1; i <= data[0]; i++) { - gpu = data[i]; - - printf(" - Enabling Quadro Sync Device %d - GPU %d... ", + for (i = 1; i <= gpu_data[0]; i++) { + gpu = gpu_data[i]; + + printf(" - Enabling Quadro Sync Device %d - GPU %d...\n", framelock, gpu); - + /* Make sure frame lock is disabled */ XNVCTRLQueryTargetAttribute(dpy, @@ -296,110 +348,130 @@ static void do_enable(Display *dpy) NV_CTRL_FRAMELOCK_SYNC, &enabled); if (enabled != NV_CTRL_FRAMELOCK_SYNC_DISABLE) { - printf("Frame lock already enabled!\n"); + printf(" - Frame lock already enabled!\n"); continue; } /* Get the list of displays to enable */ - ret = XNVCTRLQueryTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_ENABLED_DISPLAYS, - (int *)&mask); - if (!ret) { - printf("Failed to query enabled displays!\n"); - continue; - } + ret = XNVCTRLQueryTargetBinaryData + (dpy, + NV_CTRL_TARGET_TYPE_GPU, + gpu, + 0, + NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU, + (unsigned char **) &display_data, + &len); - /* Query if any of the enabled displays can be set as a - * master on this GPU. - */ - - ret = XNVCTRLQueryTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - mask, // display_mask - NV_CTRL_FRAMELOCK_MASTERABLE, - &masterable); if (!ret) { - printf("Failed to query masterable!\n"); + printf(" - Failed to query enabled displays.\n"); continue; } - - /* Clear the master setting if any */ - - if (masterable) { - XNVCTRLSetTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_FRAMELOCK_MASTER, - 0); + + if (!display_data[0]) { + printf(" - No Connected Displays found!\n"); } - - /* Clear the slaves setting if any */ - XNVCTRLSetTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_FRAMELOCK_SLAVES, - 0); - - printf("\n"); - - /* Pick the first available/capable display device as master */ - - if (pick_server && masterable) { - - /* Just pick the first enabled display */ - - unsigned int master = (1<<31); - while (master && !(master & masterable)) { - master >>= 1; + for (j = 1; j <= display_data[0]; j++) { + + display = display_data[j]; + + /* Query if display is enabled. Silently continue if not */ + + ret = XNVCTRLQueryTargetAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_DISPLAY_ENABLED, + &enabled); + + if (!ret) { + printf(" - Failed to query enabled displays.\n"); + continue; + } + + if (!enabled) { + continue; + } + + /* Query possible framelock configs for this display */ + + ret = XNVCTRLQueryValidTargetAttributeValues + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, + &values); + + if (!ret) { + continue; + } + + serverable = (values.u.bits.ints & + (1 << NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_SERVER)); + + /* Query Display name */ + + ret = XNVCTRLQueryTargetStringAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_STRING_DISPLAY_NAME_RANDR, + &display_name); + + if (ret && display_name) { + printf(" - Display %s", display_name); + XFree(display_name); + } else { + printf(" - Display 0x%08x", display); } - - if (master) { - mask &= ~master; + + /* Pick the first capable display device as the server */ + + if (pick_server && serverable) { /* Make sure we're not using the House Sync signal. */ - + XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK, framelock, // target_id 0, // display_mask NV_CTRL_USE_HOUSE_SYNC, NV_CTRL_USE_HOUSE_SYNC_FALSE); - - /* Set the master */ - - XNVCTRLSetTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_FRAMELOCK_MASTER, - master); - printf(" - Set Server Display : 0x%08x\n", master); - pick_server = 0; + XNVCTRLSetTargetAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_SERVER); + server_set = 1; - } - } + pick_server = 0; - /* Set rest of enabled display devices as clients (slaves) */ + printf(" - Set as Server\n"); - if (mask) { - XNVCTRLSetTargetAttribute(dpy, - NV_CTRL_TARGET_TYPE_GPU, - gpu, // target_id - 0, // display_mask - NV_CTRL_FRAMELOCK_SLAVES, - mask); - printf(" - Set Client Display(s) : 0x%08x\n", mask); + } else { + + XNVCTRLSetTargetAttribute + (dpy, + NV_CTRL_TARGET_TYPE_DISPLAY, + display, + 0, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_CLIENT); + + printf(" - Set as Client\n"); + + } } + XFree(display_data); + /* Enable frame lock */ XNVCTRLSetTargetAttribute(dpy, @@ -410,7 +482,7 @@ static void do_enable(Display *dpy) NV_CTRL_FRAMELOCK_SYNC_ENABLE); XFlush(dpy); printf(" - Frame Lock Sync Enabled.\n"); - + /* If we just enabled the server, also toggle the test signal * to guarantee accuracy of the universal frame count (as * returned by the glXQueryFrameCountNV() function in the @@ -423,7 +495,7 @@ static void do_enable(Display *dpy) 0, // display_mask NV_CTRL_FRAMELOCK_TEST_SIGNAL, NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE); - + XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id @@ -437,7 +509,7 @@ static void do_enable(Display *dpy) } /* Done enabling GPUs */ - XFree(data); + XFree(gpu_data); } /* Done enabling framelocks */ } @@ -471,7 +543,7 @@ static void do_disable(Display *dpy) /* Disable frame lock on all GPUs connected to each frame lock device */ for (framelock = 0; framelock < num_framelocks; framelock++) { - + printf("\n"); printf("- Frame Lock Board %d :\n", framelock); @@ -491,7 +563,7 @@ static void do_disable(Display *dpy) } /* Disable frame lock on all GPUs connected to the frame lock device */ - + if ( !data[0] ) { printf(" - No GPUs found!\n"); } else { @@ -500,7 +572,7 @@ static void do_disable(Display *dpy) for (i = 1; i <= data[0]; i++) { gpu = data[i]; - + printf(" - Disabling Quadro Sync Device %d - GPU %d... ", framelock, gpu); @@ -533,13 +605,13 @@ int main(int argc, char *argv[]) * Open a display connection, and make sure the NV-CONTROL X * extension is present on the screen we want to use. */ - + dpy = XOpenDisplay(NULL); if (!dpy) { printf("Cannot open display '%s'.\n", XDisplayName(NULL)); return 1; } - + /* Query the NV-CONTROL version */ ret = XNVCTRLQueryVersion(dpy, &major, &minor); @@ -548,7 +620,7 @@ int main(int argc, char *argv[]) XDisplayName(NULL)); return 1; } - + /* Print some information */ printf("Using NV-CONTROL extension %d.%d on %s\n\n", @@ -559,7 +631,7 @@ int main(int argc, char *argv[]) " is required for configuring Frame Lock via target types.\n"); return 1; } - + /* Do what the user wants */ if (argc <= 1 || (strcmp(argv[1], "-q") == 0)) { diff --git a/samples/version.mk b/samples/version.mk index 2bca142..591ef07 100644 --- a/samples/version.mk +++ b/samples/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 331.38 +NVIDIA_VERSION = 334.16 diff --git a/src/XF86Config-parser/Flags.c b/src/XF86Config-parser/Flags.c index 55720e0..3413edc 100644 --- a/src/XF86Config-parser/Flags.c +++ b/src/XF86Config-parser/Flags.c @@ -512,30 +512,29 @@ xconfigPrintOptionList(FILE *fp, XConfigOptionPtr list, int tabs) * - If the extension can be enabled, this function returns NULL. * * - If the extension should be disabled, this function returns a - * string that lists the conflicting options that are enabled. + * string that lists the conflicting options that are enabled. The string + * returned has to be freed by the caller. */ -const char *xconfigValidateComposite(XConfigPtr config, - GenerateOptions *gop, - int composite_specified, - int xinerama_enabled, - int depth, - int overlay_enabled, - int cioverlay_enabled, - int ubb_enabled, - int stereo_enabled) +char *xconfigValidateComposite(XConfigPtr config, + GenerateOptions *gop, + int composite_specified, + int xinerama_enabled, + int depth, + int overlay_enabled, + int cioverlay_enabled, + int ubb_enabled, + int stereo_enabled) { - int i, n, disable_composite; - static char err_str[256]; - int size = 256; - char *s; + int i, n; + char *err_str; const struct { const char *name; int value; } composite_incompatible_options[] = { - { "Xinerama", xinerama_enabled }, + { "Xinerama", xinerama_enabled && !gop->xinerama_plus_composite_works }, { "Overlay", overlay_enabled }, { "CIOverlay", cioverlay_enabled }, { "UBB", ubb_enabled }, @@ -558,34 +557,26 @@ const char *xconfigValidateComposite(XConfigPtr config, return NULL; } - disable_composite = FALSE; - s = err_str; n = 0; - err_str[0] = '\0'; + err_str = NULL; for (i = 0; i < ARRAY_LEN(composite_incompatible_options); i++) { int value = composite_incompatible_options[i].value; const char *name = composite_incompatible_options[i].name; - int wrote; if (value) { - disable_composite = TRUE; + err_str = nv_prepend_to_string_list(err_str, name, + (n > 1) ? ", " : " or "); n++; - - wrote = snprintf(s, size, "%s%s", (n > 1) ? " or " : "", name); - if (wrote <= 0) { - break; - } - size -= wrote; - s += wrote; } } /* Special case checking for depth 8 */ if (depth <= 8) { - snprintf(s, size, "%sdepth=8", (n > 1) ? " or " : ""); + err_str = nv_prepend_to_string_list(err_str, "depth=8", + (n > 1) ? ", " : " or "); } - return disable_composite ? err_str : NULL; + return err_str; } diff --git a/src/XF86Config-parser/Generate.c b/src/XF86Config-parser/Generate.c index 0705b39..cdd7054 100644 --- a/src/XF86Config-parser/Generate.c +++ b/src/XF86Config-parser/Generate.c @@ -1321,7 +1321,8 @@ static int get_xserver_information(const char *versionString, int *isXorg, int *isModular, int *autoloadsGLX, - int *supportsExtensionSection) + int *supportsExtensionSection, + int *xineramaPlusCompositeWorks) { #define XSERVER_VERSION_FORMAT_1 "X Window System Version" #define XSERVER_VERSION_FORMAT_2 "X.Org X Server" @@ -1336,6 +1337,7 @@ static int get_xserver_information(const char *versionString, *isModular = FALSE; *autoloadsGLX = FALSE; *supportsExtensionSection = FALSE; + *xineramaPlusCompositeWorks = FALSE; return TRUE; } @@ -1400,6 +1402,17 @@ static int get_xserver_information(const char *versionString, *autoloadsGLX = TRUE; } + /* + * support for Xinerama and Composite at the same time works on X.Org + * xserver 1.15. + */ + + if ((major == 6) || (major == 7) || ((major == 1) && (minor < 15))) { + *xineramaPlusCompositeWorks = FALSE; + } else { + *xineramaPlusCompositeWorks = TRUE; + } + return TRUE; } /* get_xserver_information() */ @@ -1435,6 +1448,7 @@ void xconfigGetXServerInUse(GenerateOptions *gop) gop->supports_extension_section = FALSE; gop->autoloads_glx = FALSE; + gop->xinerama_plus_composite_works = FALSE; /* run `X -version` with a PATH that hopefully includes the X binary */ @@ -1464,7 +1478,8 @@ void xconfigGetXServerInUse(GenerateOptions *gop) &isXorg, &dummy, /* isModular */ &gop->autoloads_glx, - &gop->supports_extension_section); + &gop->supports_extension_section, + &gop->xinerama_plus_composite_works); if (found) { if (isXorg) { diff --git a/src/XF86Config-parser/xf86Parser.h b/src/XF86Config-parser/xf86Parser.h index 1135ffd..89c1569 100644 --- a/src/XF86Config-parser/xf86Parser.h +++ b/src/XF86Config-parser/xf86Parser.h @@ -624,6 +624,7 @@ typedef struct { int supports_extension_section; int autoloads_glx; + int xinerama_plus_composite_works; } GenerateOptions; @@ -762,15 +763,15 @@ void xconfigGenerateLoadDefaultOptions(GenerateOptions *gop); void xconfigGetXServerInUse(GenerateOptions *gop); -const char *xconfigValidateComposite(XConfigPtr config, - GenerateOptions *gop, - int composite_enabled, - int xinerama_enabled, - int depth, - int overlay_enabled, - int cioverlay_enabled, - int ubb_enabled, - int stereo); +char *xconfigValidateComposite(XConfigPtr config, + GenerateOptions *gop, + int composite_enabled, + int xinerama_enabled, + int depth, + int overlay_enabled, + int cioverlay_enabled, + int ubb_enabled, + int stereo); /* * check (and update, if necessary) the inputs in the specified layout diff --git a/src/app-profiles.c b/src/app-profiles.c index a56bcbc..88dfebf 100644 --- a/src/app-profiles.c +++ b/src/app-profiles.c @@ -74,7 +74,7 @@ static void splice_string(char **s, size_t b, size_t e, const char *replace) #define HEX_DIGITS "0123456789abcdefABCDEF" -char *nv_app_profile_cfg_file_syntax_to_json(const char *orig_s) +char *nv_app_profile_file_syntax_to_json(const char *orig_s) { char *s = strdup(orig_s); @@ -428,6 +428,119 @@ static json_t *json_settings_parse(json_t *old_settings, const char *filename) } /* + * Load app profile key documentation from file. + */ +json_t *nv_app_profile_key_documentation_load(const char *key_docs_file) +{ + json_t *key_docs = NULL; + int ret, i; + struct stat stat_buf; + FILE *fp = NULL; + + char *orig_text = NULL; + char *json_text = NULL; + json_t *orig_file = NULL; + json_t *orig_json_keys = NULL; + json_error_t error; + + if (!key_docs_file) { + goto done; + } + + ret = open_and_stat(key_docs_file, "r", &fp, &stat_buf); + if (ret < 0) { + goto done; + } + + orig_text = slurp(fp); + + if (!orig_text) { + nv_error_msg("Could not read from file %s", key_docs_file); + goto done; + } + + // Convert the file contents to JSON + json_text = nv_app_profile_file_syntax_to_json(orig_text); + + if (!json_text) { + nv_error_msg("App profile parse error in %s: " + "text is not valid app profile key " + "documentation syntax", key_docs_file); + goto done; + } + + // Parse the resulting JSON + orig_file = json_loads(json_text, 0, &error); + + if (!orig_file) { + nv_error_msg("App profile parse error in %s: %s on %s, line %d\n", + key_docs_file, error.text, error.source, error.line); + goto done; + } + + // Process the array of key objects within the top level object + orig_json_keys = json_object_get(orig_file, "registry_keys"); + + if (orig_json_keys) { + int size = json_array_size(orig_json_keys); + + key_docs = json_array(); + + for (i = 0; i < size; i++) { + json_t *json_name, *json_description, *json_type; + json_t *json_key_object = json_array_get(orig_json_keys, i); + + if (!json_is_object(json_key_object)) { + nv_error_msg("App profile parse error in %s: " + "Object expected in 'registry_keys' array " + "at position %d", + key_docs_file, i); + continue; + } + + json_name = json_object_get(json_key_object, "key"); + json_description = json_object_get(json_key_object, "description"); + json_type = json_object_get(json_key_object, "type"); + + /* + * Any invalid and non-string type for any fields per key will + * cause the key's data to not be added. + */ + if (json_is_string(json_name) && + json_is_string(json_description) && + json_is_string(json_type)) { + + json_t *new_json_key_object = json_object(); + + json_object_set(new_json_key_object, "key", json_name); + json_object_set(new_json_key_object, "description", + json_description); + json_object_set(new_json_key_object, "type", json_type); + + json_array_append_new(key_docs, new_json_key_object); + } + } + } + + +done: + if (json_array_size(key_docs) == 0) { + json_decref(key_docs); + key_docs = NULL; + } + + free(orig_text); + free(json_text); + json_decref(orig_file); + + if (fp) { + fclose(fp); + } + + return key_docs; +} + +/* * Load app profile settings from an already-open file. This operation is * atomic: either all of the settings from the file are added to the * configuration, or none are. @@ -462,7 +575,7 @@ static void app_profile_config_load_file(AppProfileConfig *config, } // Convert the file contents to JSON - json_text = nv_app_profile_cfg_file_syntax_to_json(orig_text); + json_text = nv_app_profile_file_syntax_to_json(orig_text); if (!json_text) { nv_error_msg("App profile parse error in %s: text is not valid app profile configuration syntax", filename); diff --git a/src/app-profiles.h b/src/app-profiles.h index 6aa9de3..b5feb14 100644 --- a/src/app-profiles.h +++ b/src/app-profiles.h @@ -137,6 +137,11 @@ AppProfileConfig *nv_app_profile_config_load(const char *global_config_file, size_t search_path_count); /* + * Load the registry keys documentation from the installed file. + */ +json_t *nv_app_profile_key_documentation_load(const char *key_docs_file); + +/* * Duplicate the configuration; the copy can then be edited and compared against * the original. */ @@ -279,7 +284,7 @@ int nv_app_profile_config_check_backing_files(AppProfileConfig *config); * Utility function to strip comments and translate hex/octal values to decimal * so the JSON parser can understand. */ -char *nv_app_profile_cfg_file_syntax_to_json(const char *orig_s); +char *nv_app_profile_file_syntax_to_json(const char *orig_s); int nv_app_profile_config_check_valid_source_file(AppProfileConfig *config, const char *filename, diff --git a/src/command-line.c b/src/command-line.c index 06db883..ef47ad3 100644 --- a/src/command-line.c +++ b/src/command-line.c @@ -34,6 +34,7 @@ #include "NvCtrlAttributes.h" #include "common-utils.h" +#include "config-file.h" /* local prototypes */ @@ -41,17 +42,6 @@ static void print_attribute_help(char *attr); static void print_help(void); /* - * verbosity, controls output of errors, warnings and other - * information (used by msg.c). - */ - -int __verbosity = VERBOSITY_DEPRECATED; -int __terse = NV_FALSE; -int __display_device_string = NV_FALSE; -int __verbosity_level_changed = NV_FALSE; -int __list_targets = NV_FALSE; - -/* * print_version() - print version information */ @@ -79,7 +69,7 @@ static void print_version(void) static void print_attribute_help(char *attr) { - const AttributeTableEntry *entry; + int i; int found = 0; int list_all = 0; int show_desc = 1; @@ -95,52 +85,86 @@ static void print_attribute_help(char *attr) nv_msg(NULL, ""); - for (entry = attributeTable; entry->name; entry++) { + for (i = 0; i < attributeTableLen; i++) { + const AttributeTableEntry *entry = attributeTable + i; if (list_all || !strcasecmp(attr, entry->name)) { if (show_desc) { nv_msg(NULL, "Attribute '%s':", entry->name); - if (entry->flags & NV_PARSER_TYPE_FRAMELOCK) { - nv_msg(NULL, " - Is Frame Lock attribute."); - } - if (entry->flags & NV_PARSER_TYPE_NO_CONFIG_WRITE) { - nv_msg(NULL, " - Attribute is not written to the rc file."); + /* Attribute type (value) information */ + + switch (entry->type) { + case NV_PARSER_ATTRIBUTE_TYPE_INTEGER: + nv_msg(NULL, " - Attribute value is an integer."); + break; + case NV_PARSER_ATTRIBUTE_TYPE_STRING: + case NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION: + nv_msg(NULL, " - Attribute value is a string."); + break; + case NV_PARSER_ATTRIBUTE_TYPE_COLOR: + nv_msg(NULL, " - Attribute value is a color."); + break; + case NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC: + nv_msg(NULL, " - Attribute value is a SDI CSC matrix."); + break; } - if (entry->flags & NV_PARSER_TYPE_GUI_ATTRIBUTE) { + + /* Attribute flags (common) */ + + if (entry->flags.is_gui_attribute) { nv_msg(NULL, " - Is GUI attribute."); } - if (entry->flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { - nv_msg(NULL, " - Attribute value is packed integer."); - } - if (entry->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY) { - nv_msg(NULL, " - Attribute value is a display mask."); - } - if (entry->flags & NV_PARSER_TYPE_NO_QUERY_ALL) { - nv_msg(NULL, " - Attribute not queried in 'query all'."); - } - if (entry->flags & NV_PARSER_TYPE_NO_ZERO_VALUE) { - nv_msg(NULL, " - Attribute cannot be zero."); - } - if (entry->flags & NV_PARSER_TYPE_100Hz) { - nv_msg(NULL, " - Attribute value is in units of Centihertz (1/100Hz)."); - } - if (entry->flags & NV_PARSER_TYPE_1000Hz) { - nv_msg(NULL, " - Attribute value is in units of Milihertz (1/1000 Hz)."); - } - if (entry->flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) { - nv_msg(NULL, " - Attribute value is string."); + if (entry->flags.is_framelock_attribute) { + nv_msg(NULL, " - Is Frame Lock attribute."); } - if (entry->flags & NV_PARSER_TYPE_SDI) { + if (entry->flags.is_sdi_attribute) { nv_msg(NULL, " - Is SDI attribute."); } - if (entry->flags & NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY) { - nv_msg(NULL, " - Attribute value is switch display."); + if (entry->flags.no_config_write) { + nv_msg(NULL, " - Attribute is not written to the rc file."); + } + if (entry->flags.no_query_all) { + nv_msg(NULL, " - Attribute not queried in 'query all'."); } - if (entry->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID) { - nv_msg(NULL, " - Attribute value is a display id."); + + /* Attribute type-specific flags */ + + switch (entry->type) { + case NV_PARSER_ATTRIBUTE_TYPE_INTEGER: + if (entry->f.int_flags.is_100Hz) { + nv_msg(NULL, " - Attribute value is in units of Centihertz " + "(1/100Hz)."); + } + if (entry->f.int_flags.is_1000Hz) { + nv_msg(NULL, " - Attribute value is in units of Milihertz " + "(1/1000 Hz)."); + } + if (entry->f.int_flags.is_packed) { + nv_msg(NULL, " - Attribute value is packed integer."); + } + if (entry->f.int_flags.is_display_mask) { + nv_msg(NULL, " - Attribute value is a display mask."); + } + if (entry->f.int_flags.is_display_id) { + nv_msg(NULL, " - Attribute value is a display ID."); + } + if (entry->f.int_flags.no_zero) { + nv_msg(NULL, " - Attribute cannot be zero."); + } + if (entry->f.int_flags.is_switch_display) { + nv_msg(NULL, " - Attribute value is switch display."); + } + break; + case NV_PARSER_ATTRIBUTE_TYPE_STRING: + case NV_PARSER_ATTRIBUTE_TYPE_COLOR: + case NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC: + case NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION: + /* Nothing specific to report for these */ + break; } + nv_msg(TAB, "%s", entry->desc); nv_msg(NULL, ""); } else { @@ -200,10 +224,12 @@ Options *parse_command_line(int argc, char *argv[], char *dpy, Options *op; int n, c; char *strval; + int boolval; op = nvalloc(sizeof(Options)); op->config = DEFAULT_RC_FILE; - + op->write_config = NV_TRUE; + /* * initialize the controlled display to the gui display name * passed in. @@ -213,7 +239,7 @@ Options *parse_command_line(int argc, char *argv[], char *dpy, while (1) { c = nvgetopt(argc, argv, __options, &strval, - NULL, /* boolval */ + &boolval, /* boolval */ NULL, /* intval */ NULL, /* doubleval */ NULL); /* disable_val */ @@ -230,27 +256,27 @@ Options *parse_command_line(int argc, char *argv[], char *dpy, case 'c': op->ctrl_display = strval; break; case 'p': op->page = strval; break; case 'V': - __verbosity = VERBOSITY_DEFAULT; + nv_set_verbosity(NV_VERBOSITY_DEFAULT); if (!strval) { /* user didn't give argument, assume "all" */ - __verbosity = VERBOSITY_ALL; + nv_set_verbosity(NV_VERBOSITY_ALL); } else if (nv_strcasecmp(strval, "none") == NV_TRUE) { - __verbosity = VERBOSITY_NONE; + nv_set_verbosity(NV_VERBOSITY_NONE); } else if (nv_strcasecmp(strval, "errors") == NV_TRUE) { - __verbosity = VERBOSITY_ERROR; + nv_set_verbosity(NV_VERBOSITY_ERROR); } else if (nv_strcasecmp(strval, "deprecations") == NV_TRUE) { - __verbosity = VERBOSITY_DEPRECATED; + nv_set_verbosity(NV_VERBOSITY_DEPRECATED); } else if (nv_strcasecmp(strval, "warnings") == NV_TRUE) { - __verbosity = VERBOSITY_WARNING; + nv_set_verbosity(NV_VERBOSITY_WARNING); } else if (nv_strcasecmp(strval, "all") == NV_TRUE) { - __verbosity = VERBOSITY_ALL; + nv_set_verbosity(NV_VERBOSITY_ALL); } else { nv_error_msg("Invalid verbosity level '%s'. Please run " "`%s --help` for usage information.\n", strval, argv[0]); exit(0); } - __verbosity_level_changed = NV_TRUE; + set_dynamic_verbosity(NV_FALSE); break; case 'a': n = op->num_assignments; @@ -267,10 +293,11 @@ Options *parse_command_line(int argc, char *argv[], char *dpy, break; case CONFIG_FILE_OPTION: op->config = strval; break; case 'g': print_glxinfo(NULL, handles_array); exit(0); break; - case 't': __terse = NV_TRUE; break; - case 'd': __display_device_string = NV_TRUE; break; + case 't': op->terse = NV_TRUE; break; + case 'd': op->dpy_string = NV_TRUE; break; case 'e': print_attribute_help(strval); exit(0); break; - case 'L': __list_targets = NV_TRUE; break; + case 'L': op->list_targets = NV_TRUE; break; + case 'w': op->write_config = boolval; break; default: nv_error_msg("Invalid commandline, please run `%s --help` " "for usage information.\n", argv[0]); diff --git a/src/command-line.h b/src/command-line.h index 2cfa076..21e17c8 100644 --- a/src/command-line.h +++ b/src/command-line.h @@ -91,6 +91,25 @@ typedef struct { * when started. */ + int list_targets; /* + * If true, list resolved targets of operations + * (from query/assign or rc file) and exit. + */ + + int terse; /* + * If true, output minimal information to query + * operations. + */ + + int dpy_string; /* + * If true, output the display device mask as a list + * of display device names instead of a number. + */ + + int write_config; /* + * If true, write out the configuration file on exit. + */ + } Options; diff --git a/src/common-utils/common-utils.c b/src/common-utils/common-utils.c index 9bd349e..f581f0d 100644 --- a/src/common-utils/common-utils.c +++ b/src/common-utils/common-utils.c @@ -29,8 +29,6 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> -#include <sys/ioctl.h> -#include <sys/termios.h> #include "common-utils.h" @@ -354,311 +352,6 @@ char *nv_prepend_to_string_list(char *list, const char *item, const char *delim) } -/****************************************************************************/ -/* TextRows helper functions */ -/****************************************************************************/ - -/* - * nv_format_text_rows() - this function breaks the given string str - * into some number of rows, where each row is not longer than the - * specified width. - * - * If prefix is non-NULL, the first line is prepended with the prefix, - * and subsequent lines are indented to line up with the prefix. - * - * If word_boundary is TRUE, then attempt to only break lines on - * boundaries between words. - */ - -TextRows *nv_format_text_rows(const char *prefix, - const char *str, - int width, int word_boundary) -{ - int len, prefix_len, z, w, i; - char *line, *buf, *local_prefix, *a, *b, *c; - TextRows *t; - - /* initialize the TextRows structure */ - - t = (TextRows *) malloc(sizeof(TextRows)); - - if (!t) return NULL; - - t->t = NULL; - t->n = 0; - t->m = 0; - - if (!str) return t; - - buf = strdup(str); - - if (!buf) return t; - - z = strlen(buf); /* length of entire string */ - a = buf; /* pointer to the start of the string */ - - /* initialize the prefix fields */ - - if (prefix) { - prefix_len = strlen(prefix); - local_prefix = strdup(prefix); - } else { - prefix_len = 0; - local_prefix = NULL; - } - - /* adjust the max width for any prefix */ - - w = width - prefix_len; - - do { - /* - * if the string will fit on one line, point b to the end of the - * string - */ - - if (z < w) b = a + z; - - /* - * if the string won't fit on one line, move b to where the - * end of the line should be, and then move b back until we - * find a space; if we don't find a space before we back b all - * the way up to a, just assign b to where the line should end. - */ - - else { - b = a + w; - - if (word_boundary) { - while ((b >= a) && (!isspace(*b))) b--; - if (b <= a) b = a + w; - } - } - - /* look for any newline between a and b, and move b to it */ - - for (c = a; c < b; c++) if (*c == '\n') { b = c; break; } - - /* - * copy the string that starts at a and ends at b, prepending - * with a prefix, if present - */ - - len = b-a; - len += prefix_len; - line = (char *) malloc(len+1); - if (local_prefix) strncpy(line, local_prefix, prefix_len); - strncpy(line + prefix_len, a, len - prefix_len); - line[len] = '\0'; - - /* append the new line to the array of text rows */ - - t->t = (char **) realloc(t->t, sizeof(char *) * (t->n + 1)); - t->t[t->n] = line; - t->n++; - - if (t->m < len) t->m = len; - - /* - * adjust the length of the string and move the pointer to the - * beginning of the new line - */ - - z -= (b - a + 1); - a = b + 1; - - /* move to the first non whitespace character (excluding newlines) */ - - if (word_boundary && isspace(*b)) { - while ((z) && (isspace(*a)) && (*a != '\n')) a++, z--; - } else { - if (!isspace(*b)) z++, a--; - } - - if (local_prefix) { - for (i = 0; i < prefix_len; i++) local_prefix[i] = ' '; - } - - } while (z > 0); - - if (local_prefix) free(local_prefix); - free(buf); - - return t; -} - - -/* - * nv_text_rows_append() - append the given msg to the existing TextRows - */ - -void nv_text_rows_append(TextRows *t, const char *msg) -{ - int len; - - t->t = realloc(t->t, sizeof(char *) * (t->n + 1)); - - if (msg) { - t->t[t->n] = strdup(msg); - len = strlen(msg); - if (t->m < len) t->m = len; - } else { - t->t[t->n] = NULL; - } - - t->n++; -} - -/* - * nv_concat_text_rows() - concatenate two text rows, storing the - * result in t0 - */ - -void nv_concat_text_rows(TextRows *t0, TextRows *t1) -{ - int n, i; - - n = t0->n + t1->n; - - t0->t = realloc(t0->t, sizeof(char *) * n); - - for (i = 0; i < t1->n; i++) { - t0->t[i + t0->n] = strdup(t1->t[i]); - } - - t0->m = NV_MAX(t0->m, t1->m); - t0->n = n; - -} /* nv_concat_text_rows() */ - - -/* - * nv_free_text_rows() - free the TextRows data structure allocated by - * nv_format_text_rows() - */ - -void nv_free_text_rows(TextRows *t) -{ - int i; - - if (!t) return; - for (i = 0; i < t->n; i++) free(t->t[i]); - if (t->t) free(t->t); - free(t); - -} /* nv_free_text_rows() */ - - -/****************************************************************************/ -/* printing helper functions */ -/****************************************************************************/ - -#define DEFAULT_WIDTH 75 - -static unsigned short __terminal_width = 0; - -/* - * reset_current_terminal_width() - if new_val is zero, then use the - * TIOCGWINSZ ioctl to get the current width of the terminal, and - * assign it the value to __terminal_width. If the ioctl fails, use a - * hardcoded constant. If new_val is non-zero, then use new_val. - */ - -void reset_current_terminal_width(unsigned short new_val) -{ - struct winsize ws; - - if (new_val) { - __terminal_width = new_val; - return; - } - - if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { - __terminal_width = DEFAULT_WIDTH; - } else { - __terminal_width = ws.ws_col - 1; - } -} - -/* - * Call silence_fmt(1) to turn fmtout(), fmtoutp() and format() into noops. - */ -static int __silent = 0; - -void silence_fmt(int val) -{ - __silent = val; -} - - -static void vformat(FILE *stream, const int wb, - const char *prefix, const char *buf) -{ - int i; - TextRows *t; - - if (!__terminal_width) reset_current_terminal_width(0); - - t = nv_format_text_rows(prefix, buf, __terminal_width, wb); - - for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]); - - nv_free_text_rows(t); -} - - -#define NV_VFORMAT(stream, wb, prefix, fmt) \ -do { \ - char *buf; \ - NV_VSNPRINTF(buf, fmt); \ - vformat(stream, wb, prefix, buf); \ - free (buf); \ -} while(0) - - -void fmtout(const char *fmt, ...) -{ - if (__silent > 0) { - return; - } - NV_VFORMAT(stdout, TRUE, NULL, fmt); -} - - -void fmtoutp(const char *prefix, const char *fmt, ...) -{ - if (__silent > 0) { - return; - } - NV_VFORMAT(stdout, TRUE, prefix, fmt); -} - - -void fmterr(const char *fmt, ...) -{ - vformat(stderr, 0, NULL, ""); - NV_VFORMAT(stderr, TRUE, "ERROR: ", fmt); - vformat(stderr, 0, NULL, ""); -} - - -void fmtwarn(const char *fmt, ...) -{ - vformat(stderr, 0, NULL, ""); - NV_VFORMAT(stderr, TRUE, "WARNING: ", fmt); - vformat(stderr, 0, NULL, ""); -} - - -void fmt(FILE *stream, const char *prefix, const char *fmt, ...) -{ - if (__silent > 0) { - return; - } - NV_VFORMAT(stream, TRUE, prefix, fmt); -} - - /* * Read from the given FILE stream until a newline, EOF, or nul * terminator is encountered, writing data into a growable buffer. diff --git a/src/common-utils/common-utils.h b/src/common-utils/common-utils.h index e9d505e..3db71b6 100644 --- a/src/common-utils/common-utils.h +++ b/src/common-utils/common-utils.h @@ -22,6 +22,8 @@ #include <sys/types.h> #include <stdint.h> +#include "msg.h" + #if !defined(TRUE) #define TRUE 1 #endif @@ -38,32 +40,6 @@ #define TAB " " #define BIGTAB " " -#define VERBOSITY_NONE 0 /* nothing */ -#define VERBOSITY_ERROR 1 /* errors only */ -#define VERBOSITY_DEPRECATED 2 /* errors, deprecation messages and warnings */ -#define VERBOSITY_WARNING 3 /* errors and warnings */ -#define VERBOSITY_ALL 4 /* errors, warnings and other info */ - -#define VERBOSITY_DEFAULT VERBOSITY_ERROR - -/* - * Define a printf format attribute macro. This definition is based on the one - * from Xfuncproto.h, available in the 'xproto' package at - * http://xorg.freedesktop.org/releases/individual/proto/ - */ - -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) -# define NV_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) -#else /* not gcc >= 2.3 */ -# define NV_ATTRIBUTE_PRINTF(x,y) -#endif - -typedef struct { - char **t; /* the text rows */ - int n; /* number of rows */ - int m; /* maximum row length */ -} TextRows; - void *nvalloc(size_t size); char *nvstrcat(const char *str, ...); void *nvrealloc(void *ptr, size_t size); @@ -79,22 +55,6 @@ void nvfree(void *s); char *tilde_expansion(const char *str); char *nv_prepend_to_string_list(char *list, const char *item, const char *delim); -TextRows *nv_format_text_rows(const char *prefix, - const char *str, - int width, int word_boundary); -void nv_text_rows_append(TextRows *t, const char *msg); -void nv_concat_text_rows(TextRows *t0, TextRows *t1); -void nv_free_text_rows(TextRows *t); - -void reset_current_terminal_width(unsigned short new_val); - -void silence_fmt(int val); -void fmtout(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); -void fmtoutp(const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); -void fmterr(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); -void fmtwarn(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); -void fmt(FILE *stream, const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(3, 4); - char *fget_next_line(FILE *fp, int *eof); int nv_open(const char *pathname, int flags, mode_t mode); @@ -107,51 +67,6 @@ char *nv_trim_space(char *string); char *nv_trim_char(char *string, char trim); char *nv_trim_char_strict(char *string, char trim); -/* - * NV_VSNPRINTF(): macro that assigns buf using vsnprintf(). This is - * correct for differing semantics of the vsnprintf() return value: - * - * -1 when the buffer is not long enough (glibc < 2.1) - * - * or - * - * the length the string would have been if the buffer had been large - * enough (glibc >= 2.1) - * - * This macro allocates memory for buf; the caller should free it when - * done. - */ - -#define NV_FMT_BUF_LEN 256 - -#define NV_VSNPRINTF(buf, fmt) \ -do { \ - if (!fmt) { \ - (buf) = NULL; \ - } else { \ - va_list ap; \ - int len, current_len = NV_FMT_BUF_LEN; \ - \ - while (1) { \ - (buf) = nvalloc(current_len); \ - \ - va_start(ap, fmt); \ - len = vsnprintf((buf), current_len, (fmt), ap); \ - va_end(ap); \ - \ - if ((len > -1) && (len < current_len)) { \ - break; \ - } else if (len > -1) { \ - current_len = len + 1; \ - } else { \ - current_len += NV_FMT_BUF_LEN; \ - } \ - \ - nvfree(buf); \ - } \ - } \ -} while (0) - #if defined(__GNUC__) # define NV_INLINE __inline__ #else diff --git a/src/common-utils/gen-manpage-opts-helper.c b/src/common-utils/gen-manpage-opts-helper.c index 532015d..c05ef38 100644 --- a/src/common-utils/gen-manpage-opts-helper.c +++ b/src/common-utils/gen-manpage-opts-helper.c @@ -17,16 +17,18 @@ #include <stdio.h> #include <ctype.h> #include <string.h> +#include <stdlib.h> #include "nvgetopt.h" #include "gen-manpage-opts-helper.h" +#include "common-utils.h" static void print_option(const NVGetoptOption *o) { char scratch[64], *s; int j, len; - int italics, bold, omitWhiteSpace; + int italics, bold, omitWhiteSpace, firstchar; /* if we are going to need the argument, process it now */ if (o->flags & NVGETOPT_HAS_ARGUMENT) { @@ -88,13 +90,15 @@ static void print_option(const NVGetoptOption *o) * '&' : toggles italics on and off * '^' : toggles bold on and off * '-' : is backslashified: "\-" + * '.' : must not be the first character of a line * - * Whitespace is omitted when italics or bold is on + * Trailing whitespace is omitted when italics or bold is on */ - italics = 0; - bold = 0; - omitWhiteSpace = 0; + italics = FALSE; + bold = FALSE; + omitWhiteSpace = FALSE; + firstchar = TRUE; for (s = o->description; s && *s; s++) { @@ -107,6 +111,7 @@ static void print_option(const NVGetoptOption *o) } omitWhiteSpace = italics; italics = !italics; + firstchar = TRUE; break; case '^': if (bold) { @@ -116,19 +121,33 @@ static void print_option(const NVGetoptOption *o) } omitWhiteSpace = bold; bold = !bold; + firstchar = TRUE; break; case '-': printf("\\-"); - omitWhiteSpace = 0; + omitWhiteSpace = FALSE; + firstchar = FALSE; break; case ' ': if (!omitWhiteSpace) { printf(" "); + firstchar = FALSE; } break; + case '.': + if (firstchar) { + fprintf(stderr, "Error: *roff can't start a line with '.' " + "If you used '&' or '^' to format text in the " + "description of the '%s' option, please add some " + "text before the end of the sentence, so that a " + "valid manpage can be generated.\n", o->name); + exit(1); + } + /* fall through */ default: printf("%c", *s); - omitWhiteSpace = 0; + omitWhiteSpace = FALSE; + firstchar = FALSE; break; } } diff --git a/src/common-utils/msg.c b/src/common-utils/msg.c new file mode 100644 index 0000000..cdd3c4f --- /dev/null +++ b/src/common-utils/msg.c @@ -0,0 +1,416 @@ +/* + * 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. + * + * 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>. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#if defined(__sun) +#include <sys/termios.h> +#endif + +#include "msg.h" +#include "common-utils.h" + + +/* + * verbosity, controls output of errors, warnings and other + * information. + */ + +static NvVerbosity __verbosity = NV_VERBOSITY_DEFAULT; + +NvVerbosity nv_get_verbosity() +{ + return __verbosity; +} + +void nv_set_verbosity(NvVerbosity level) +{ + __verbosity = level; +} + + +/****************************************************************************/ +/* Formatted I/O functions */ +/****************************************************************************/ + +#define DEFAULT_WIDTH 75 + +static unsigned short __terminal_width = 0; + +/* + * reset_current_terminal_width() - if new_val is zero, then use the + * TIOCGWINSZ ioctl to get the current width of the terminal, and + * assign it the value to __terminal_width. If the ioctl fails, use a + * hardcoded constant. If new_val is non-zero, then use new_val. + */ + +void reset_current_terminal_width(unsigned short new_val) +{ + struct winsize ws; + + if (new_val) { + __terminal_width = new_val; + return; + } + + if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { + __terminal_width = DEFAULT_WIDTH; + } else { + __terminal_width = ws.ws_col - 1; + } +} + + +static void format(FILE *stream, const char *prefix, const char *buf, + const int whitespace) +{ + int i; + TextRows *t; + + if (!__terminal_width) reset_current_terminal_width(0); + + t = nv_format_text_rows(prefix, buf, __terminal_width, whitespace); + + for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]); + + nv_free_text_rows(t); +} + + +#define NV_FORMAT(stream, prefix, fmt, whitespace) \ +do { \ + char *buf; \ + NV_VSNPRINTF(buf, fmt); \ + format(stream, prefix, buf, whitespace); \ + free (buf); \ +} while(0) + + +/* + * nv_error_msg() - print an error message, nicely formatted using the + * format() function. + * + * This function should be used for all errors. + */ + +void nv_error_msg(const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_ERROR) return; + + format(stderr, NULL, "", TRUE); + NV_FORMAT(stderr, "ERROR: ", fmt, TRUE); + format(stderr, NULL, "", TRUE); +} /* nv_error_msg() */ + + +/* + * nv_deprecated_msg() - print a deprecation message, nicely formatted using + * the format() function. + * + * This function should be used for all deprecation messages. + */ + +void nv_deprecated_msg(const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_DEPRECATED) return; + + format(stderr, NULL, "", TRUE); + NV_FORMAT(stderr, "DEPRECATED: ", fmt, TRUE); + format(stderr, NULL, "", TRUE); +} + + +/* + * nv_warning_msg() - print a warning message, nicely formatted using + * the format() function. + * + * This function should be used for all warnings. + */ + +void nv_warning_msg(const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_WARNING) return; + + format(stderr, NULL, "", TRUE); + NV_FORMAT(stderr, "WARNING: ", fmt, TRUE); + format(stderr, NULL, "", TRUE); +} /* nv_warning_msg() */ + + +/* + * nv_info_msg() - print an info message, nicely formatted using + * the format() function. + * + * This function should be used to display verbose information. + */ + +void nv_info_msg(const char *prefix, const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_ALL) return; + + NV_FORMAT(stdout, prefix, fmt, TRUE); +} /* nv_info_msg() */ + + +/* + * nv_info_msg_to_file() - Prints the message, just like nv_info_msg() + * using format() the difference is, it prints to any stream defined by + * the corresponding argument. + */ + +void nv_info_msg_to_file(FILE *stream, const char *prefix, const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_ALL) return; + + NV_FORMAT(stream, prefix, fmt, TRUE); +} /* nv_info_msg_to_file() */ + + +/* + * nv_msg() - print a message, nicely formatted using the format() + * function. + * + * This function should be used to display messages independent + * of the verbosity level. + */ + +void nv_msg(const char *prefix, const char *fmt, ...) +{ + NV_FORMAT(stdout, prefix, fmt, TRUE); +} /* nv_msg() */ + + +/* + * nv_msg_preserve_whitespace() - Prints the message, just like nv_msg() + * using format(), the difference is, whitespace characters are not + * skipped during the text processing. + */ + +void nv_msg_preserve_whitespace(const char *prefix, const char *fmt, ...) +{ + NV_FORMAT(stdout, prefix, fmt, FALSE); +} /* nv_msg_preserve_whitespace() */ + + +/* + * XXX gcc's '-ansi' option causes vsnprintf to not be defined, so + * declare the prototype here. + */ + +#if defined(__STRICT_ANSI__) +int vsnprintf(char *str, size_t size, const char *format, + va_list ap); +#endif + + +/****************************************************************************/ +/* TextRows helper functions */ +/****************************************************************************/ + +/* + * nv_format_text_rows() - this function breaks the given string str + * into some number of rows, where each row is not longer than the + * specified width. + * + * If prefix is non-NULL, the first line is prepended with the prefix, + * and subsequent lines are indented to line up with the prefix. + * + * If word_boundary is TRUE, then attempt to only break lines on + * boundaries between words. + */ + +TextRows *nv_format_text_rows(const char *prefix, const char *str, int width, + int word_boundary) +{ + int len, prefix_len, z, w, i; + char *line, *buf, *local_prefix, *a, *b, *c; + TextRows *t; + + /* initialize the TextRows structure */ + + t = (TextRows *) malloc(sizeof(TextRows)); + + if (!t) return NULL; + + t->t = NULL; + t->n = 0; + t->m = 0; + + if (!str) return t; + + buf = strdup(str); + + if (!buf) return t; + + z = strlen(buf); /* length of entire string */ + a = buf; /* pointer to the start of the string */ + + /* initialize the prefix fields */ + + if (prefix) { + prefix_len = strlen(prefix); + local_prefix = strdup(prefix); + } else { + prefix_len = 0; + local_prefix = NULL; + } + + /* adjust the max width for any prefix */ + + w = width - prefix_len; + + do { + /* + * if the string will fit on one line, point b to the end of the + * string + */ + + if (z < w) b = a + z; + + /* + * if the string won't fit on one line, move b to where the + * end of the line should be, and then move b back until we + * find a space; if we don't find a space before we back b all + * the way up to a, just assign b to where the line should end. + */ + + else { + b = a + w; + + if (word_boundary) { + while ((b >= a) && (!isspace(*b))) b--; + if (b <= a) b = a + w; + } + } + + /* look for any newline between a and b, and move b to it */ + + for (c = a; c < b; c++) if (*c == '\n') { b = c; break; } + + /* + * copy the string that starts at a and ends at b, prepending + * with a prefix, if present + */ + + len = b-a; + len += prefix_len; + line = (char *) malloc(len+1); + if (local_prefix) strncpy(line, local_prefix, prefix_len); + strncpy(line + prefix_len, a, len - prefix_len); + line[len] = '\0'; + + /* append the new line to the array of text rows */ + + t->t = (char **) realloc(t->t, sizeof(char *) * (t->n + 1)); + t->t[t->n] = line; + t->n++; + + if (t->m < len) t->m = len; + + /* + * adjust the length of the string and move the pointer to the + * beginning of the new line + */ + + z -= (b - a + 1); + a = b + 1; + + /* move to the first non whitespace character (excluding newlines) */ + + if (word_boundary && isspace(*b)) { + while ((z) && (isspace(*a)) && (*a != '\n')) a++, z--; + } else { + if (!isspace(*b)) z++, a--; + } + + if (local_prefix) { + for (i = 0; i < prefix_len; i++) local_prefix[i] = ' '; + } + + } while (z > 0); + + if (local_prefix) free(local_prefix); + free(buf); + + return t; +} + + +/* + * nv_text_rows_append() - append the given msg to the existing TextRows + */ + +void nv_text_rows_append(TextRows *t, const char *msg) +{ + int len; + + t->t = realloc(t->t, sizeof(char *) * (t->n + 1)); + + if (msg) { + t->t[t->n] = strdup(msg); + len = strlen(msg); + if (t->m < len) t->m = len; + } else { + t->t[t->n] = NULL; + } + + t->n++; +} + +/* + * nv_concat_text_rows() - concatenate two text rows, storing the + * result in t0 + */ + +void nv_concat_text_rows(TextRows *t0, TextRows *t1) +{ + int n, i; + + n = t0->n + t1->n; + + t0->t = realloc(t0->t, sizeof(char *) * n); + + for (i = 0; i < t1->n; i++) { + t0->t[i + t0->n] = strdup(t1->t[i]); + } + + t0->m = NV_MAX(t0->m, t1->m); + t0->n = n; + +} /* nv_concat_text_rows() */ + + +/* + * nv_free_text_rows() - free the TextRows data structure allocated by + * nv_format_text_rows() + */ + +void nv_free_text_rows(TextRows *t) +{ + int i; + + if (!t) return; + for (i = 0; i < t->n; i++) free(t->t[i]); + if (t->t) free(t->t); + free(t); + +} /* nv_free_text_rows() */ + diff --git a/src/common-utils/msg.h b/src/common-utils/msg.h new file mode 100644 index 0000000..5e32c19 --- /dev/null +++ b/src/common-utils/msg.h @@ -0,0 +1,137 @@ +/* + * 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. + * + * 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>. + */ + +#ifndef __MSG_H__ +#define __MSG_H__ + +#include <stdarg.h> +#include <stdio.h> + + +/* + * Define a printf format attribute macro. This definition is based on the one + * from Xfuncproto.h, available in the 'xproto' package at + * http://xorg.freedesktop.org/releases/individual/proto/ + */ + +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) +# define NV_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) +#else /* not gcc >= 2.3 */ +# define NV_ATTRIBUTE_PRINTF(x,y) +#endif + + +/* + * NV_VSNPRINTF(): macro that assigns buf using vsnprintf(). This is + * correct for differing semantics of the vsnprintf() return value: + * + * -1 when the buffer is not long enough (glibc < 2.1) + * + * or + * + * the length the string would have been if the buffer had been large + * enough (glibc >= 2.1) + * + * This macro allocates memory for buf; the caller should free it when + * done. + */ + +#define NV_FMT_BUF_LEN 256 + +#define NV_VSNPRINTF(buf, fmt) \ +do { \ + if (!fmt) { \ + (buf) = NULL; \ + } else { \ + va_list ap; \ + int len, current_len = NV_FMT_BUF_LEN; \ + \ + while (1) { \ + (buf) = nvalloc(current_len); \ + \ + va_start(ap, fmt); \ + len = vsnprintf((buf), current_len, (fmt), ap); \ + va_end(ap); \ + \ + if ((len > -1) && (len < current_len)) { \ + break; \ + } else if (len > -1) { \ + current_len = len + 1; \ + } else { \ + current_len += NV_FMT_BUF_LEN; \ + } \ + \ + nvfree(buf); \ + } \ + } \ +} while (0) + + +/* + * verbosity, controls output of errors, warnings and other + * information. + */ + +typedef enum { + NV_VERBOSITY_NONE = 0, /* no errors, warnings or info */ + NV_VERBOSITY_ERROR, /* errors only */ + NV_VERBOSITY_DEPRECATED, /* errors and deprecation messages */ + NV_VERBOSITY_WARNING, /* errors and all warnings */ + NV_VERBOSITY_ALL, /* errors, all warnings and other info */ + NV_VERBOSITY_DEFAULT = NV_VERBOSITY_ALL +} NvVerbosity; + +NvVerbosity nv_get_verbosity(void); +void nv_set_verbosity(NvVerbosity level); + + +/* + * Formatted I/O functions + */ + +void reset_current_terminal_width(unsigned short new_val); + +void nv_error_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_deprecated_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_warning_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_info_msg(const char *prefix, + const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); +void nv_info_msg_to_file(FILE *stream, + const char *prefix, + const char *fmt, ...) NV_ATTRIBUTE_PRINTF(3, 4); +void nv_msg(const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); +void nv_msg_preserve_whitespace(const char *prefix, + const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); + + +/* + * TextRows structure and helper functions + */ + +typedef struct { + char **t; /* the text rows */ + int n; /* number of rows */ + int m; /* maximum row length */ +} TextRows; + +TextRows *nv_format_text_rows(const char *prefix, const char *str, int width, + int word_boundary); +void nv_text_rows_append(TextRows *t, const char *msg); +void nv_concat_text_rows(TextRows *t0, TextRows *t1); +void nv_free_text_rows(TextRows *t); + + +#endif /* __MSG_H__ */ diff --git a/src/common-utils/src.mk b/src/common-utils/src.mk index 12ba143..6dbed7a 100644 --- a/src/common-utils/src.mk +++ b/src/common-utils/src.mk @@ -2,9 +2,11 @@ COMMON_UTILS_SRC += nvgetopt.c COMMON_UTILS_SRC += common-utils.c +COMMON_UTILS_SRC += msg.c COMMON_UTILS_EXTRA_DIST += nvgetopt.h COMMON_UTILS_EXTRA_DIST += common-utils.h +COMMON_UTILS_EXTRA_DIST += msg.h COMMON_UTILS_EXTRA_DIST += src.mk # gen-manpage-opts-helper.c is listed in EXTRA_DIST, rather than SRC, diff --git a/src/config-file.c b/src/config-file.c index 9478467..2364291 100644 --- a/src/config-file.c +++ b/src/config-file.c @@ -63,7 +63,8 @@ static ParsedAttributeWrapper *parse_config_file(char *buf, const int length, ConfigProperties *); -static int process_config_file_attributes(const char *file, +static int process_config_file_attributes(const Options *op, + const char *file, ParsedAttributeWrapper *w, const char *display_name, CtrlHandlesArray *handles_array); @@ -83,8 +84,18 @@ static void write_config_properties(FILE *stream, ConfigProperties *conf, static char *create_display_device_target_string(CtrlHandleTarget *t, ConfigProperties *conf); -extern int __verbosity; -extern int __verbosity_level_changed; +/* + * set_dynamic_verbosity() - Sets the __dynamic_verbosity variable which + * allows temporary toggling of the verbosity level to hide some output + * messages when verbosity has not been explicitly set by the user. + */ + +static int __dynamic_verbosity = NV_TRUE; + +void set_dynamic_verbosity(int dynamic) +{ + __dynamic_verbosity = dynamic; +} /* * nv_read_config_file() - read the specified config file, building a @@ -104,7 +115,8 @@ extern int __verbosity_level_changed; * problems in the future? */ -int nv_read_config_file(const char *file, const char *display_name, +int nv_read_config_file(const Options *op, const char *file, + const char *display_name, ParsedAttribute *p, ConfigProperties *conf, CtrlHandlesArray *handles_array) { @@ -185,7 +197,7 @@ int nv_read_config_file(const char *file, const char *display_name, /* process the parsed attributes */ - ret = process_config_file_attributes(file, w, display_name, + ret = process_config_file_attributes(op, file, w, display_name, handles_array); /* @@ -225,7 +237,6 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, NVCTRLAttributeValidValuesRec valid; CtrlHandleTarget *t; char *prefix, scratch[4]; - const char *tmp; char *locale = "C"; if (!filename) { @@ -305,28 +316,30 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, /* loop over all the entries in the table */ - for (entry = 0; attributeTable[entry].name; entry++) { + for (entry = 0; entry < attributeTableLen; entry++) { const AttributeTableEntry *a = &attributeTable[entry]; - /* + /* * skip all attributes that are not supposed to be written * to the config file */ - if (a->flags & NV_PARSER_TYPE_NO_CONFIG_WRITE) continue; + if (a->flags.no_config_write) { + continue; + } /* * special case the color attributes because we want to * print floats */ - - if (a->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) { + + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_COLOR) { float c[3], b[3], g[3]; /* * if we are using RandR gamma, skip saving the color info */ - + status = NvCtrlGetAttribute(t->h, NV_CTRL_ATTR_RANDR_GAMMA_AVAILABLE, &val); if (status == NvCtrlSuccess && val) continue; @@ -338,9 +351,16 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, continue; } + /* Only write out integer attributes, string and SDI CSC attributes + * aren't written here. + */ + if (a->type != NV_PARSER_ATTRIBUTE_TYPE_INTEGER) { + continue; + } + /* Ignore display attributes, they are written later on */ - ret = nv_get_attribute_perms(h, a->attr, a->flags, &perms); + ret = nv_get_attribute_perms(h, a, &perms); if (!ret || (perms.permissions & ATTRIBUTE_TYPE_DISPLAY)) { continue; } @@ -359,7 +379,7 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, continue; } - if (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID) { + if (a->f.int_flags.is_display_id) { const char *name = nv_get_display_target_config_name(h, val); if (name) { @@ -406,21 +426,23 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, /* loop over all the entries in the table */ - for (entry = 0; attributeTable[entry].name; entry++) { + for (entry = 0; entry < attributeTableLen; entry++) { const AttributeTableEntry *a = &attributeTable[entry]; - /* + /* * skip all attributes that are not supposed to be written * to the config file */ - if (a->flags & NV_PARSER_TYPE_NO_CONFIG_WRITE) continue; + if (a->flags.no_config_write) { + continue; + } - /* + /* * for the display target we only write color attributes for now */ - if (a->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_COLOR) { float c[3], b[3], g[3]; if (!randr_gamma_available) continue; @@ -434,9 +456,16 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, continue; } + /* Only write out integer attributes, string and SDI CSC attributes + * aren't written here. + */ + if (a->type != NV_PARSER_ATTRIBUTE_TYPE_INTEGER) { + continue; + } + /* Make sure this is a display attribute */ - ret = nv_get_attribute_perms(h, a->attr, a->flags, &perms); + ret = nv_get_attribute_perms(h, a, &perms); if (!ret || !(perms.permissions & ATTRIBUTE_TYPE_DISPLAY)) { continue; } @@ -469,20 +498,13 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, while (p) { char target_str[64]; + const AttributeTableEntry *a = p->attr_entry; if (!p->next) { p = p->next; continue; } - tmp = nv_get_attribute_name(p->attr, NV_PARSER_TYPE_STRING_ATTRIBUTE, - p->flags); - if (!tmp) { - nv_error_msg("Failure to save unknown attribute %d.", p->attr); - p = p->next; - continue; - } - /* * if the parsed attribute has a target specification, and a * target type other than an X screen, include a target @@ -491,7 +513,7 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, target_str[0] = '\0'; - if ((p->flags & NV_PARSER_HAS_TARGET) && + if (p->parser_flags.has_target && (p->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN)) { const TargetTypeEntry *targetTypeEntry; @@ -504,13 +526,14 @@ int nv_write_config_file(const char *filename, CtrlHandles *h, } } - if (p->flags & NV_PARSER_TYPE_HIJACK_DISPLAY_DEVICE) { + if (a->flags.hijack_display_device) { fprintf(stream, "%s%s%c%s[0x%08x]=%d\n", p->display, target_str, - DISPLAY_NAME_SEPARATOR, tmp, p->display_device_mask, + DISPLAY_NAME_SEPARATOR, a->name, + p->display_device_mask, p->val.i); } else { fprintf(stream, "%s%s%c%s=%d\n", p->display, target_str, - DISPLAY_NAME_SEPARATOR, tmp, p->val.i); + DISPLAY_NAME_SEPARATOR, a->name, p->val.i); } @@ -641,20 +664,21 @@ static ParsedAttributeWrapper *parse_config_file(char *buf, const char *file, * file. */ -static int process_config_file_attributes(const char *file, +static int process_config_file_attributes(const Options *op, + const char *file, ParsedAttributeWrapper *w, const char *display_name, CtrlHandlesArray *handles_array) { int i; - int old_verbosity = __verbosity; + NvVerbosity old_verbosity = nv_get_verbosity(); /* Override the verbosity in the default behavior so * nvidia-settings isn't so alarmist when loading the RC file. */ - if (!__verbosity_level_changed) { - __verbosity = VERBOSITY_NONE; + if (__dynamic_verbosity) { + nv_set_verbosity(NV_VERBOSITY_NONE); } /* @@ -677,7 +701,7 @@ static int process_config_file_attributes(const char *file, for (i = 0; w[i].line != -1; i++) { - nv_process_parsed_attribute(&w[i].a, w[i].h, NV_TRUE, NV_FALSE, + nv_process_parsed_attribute(op, &w[i].a, w[i].h, NV_TRUE, NV_FALSE, "on line %d of configuration file " "'%s'", w[i].line, file); /* @@ -691,8 +715,8 @@ static int process_config_file_attributes(const char *file, /* Reset the default verbosity */ - if (!__verbosity_level_changed) { - __verbosity = old_verbosity; + if (__dynamic_verbosity) { + nv_set_verbosity(old_verbosity); } return NV_TRUE; @@ -708,16 +732,17 @@ static int process_config_file_attributes(const char *file, */ static void save_gui_parsed_attributes(ParsedAttributeWrapper *w, - ParsedAttribute *p) + ParsedAttribute *p_list) { int i; for (i = 0; w[i].line != -1; i++) { - if (w[i].a.flags & NV_PARSER_TYPE_GUI_ATTRIBUTE) { - nv_parsed_attribute_add(p, &w[i].a); + ParsedAttribute *p = &(w[i].a); + if (p->attr_entry->flags.is_gui_attribute) { + nv_parsed_attribute_add(p_list, p); } } -} /* save_gui_parsed_attributes() */ +} diff --git a/src/config-file.h b/src/config-file.h index d6006c1..6f856b6 100644 --- a/src/config-file.h +++ b/src/config-file.h @@ -51,9 +51,11 @@ typedef struct { } ConfigProperties; +void set_dynamic_verbosity(int dynamic); + void init_config_properties(ConfigProperties *conf); -int nv_read_config_file(const char *, const char *, +int nv_read_config_file(const Options *, const char *, const char *, ParsedAttribute *, ConfigProperties *, CtrlHandlesArray *); diff --git a/src/gtk+-2.x/ctk3dvisionpro.c b/src/gtk+-2.x/ctk3dvisionpro.c index ef64553..ccf53d5 100644 --- a/src/gtk+-2.x/ctk3dvisionpro.c +++ b/src/gtk+-2.x/ctk3dvisionpro.c @@ -169,9 +169,29 @@ static const char** get_signal_strength_icon(int signal_strength) return NULL; } + + +static void ctk_3d_vision_pro_finalize(GObject *object) +{ + Ctk3DVisionPro *ctk_object = CTK_3D_VISION_PRO(object); + + g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event), + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + (gpointer) ctk_object); +} + + + static void ctk_3d_vision_pro_class_init(Ctk3DVisionProClass *ctk_3d_vision_pro_class) { + GObjectClass *gobject_class = (GObjectClass *)ctk_3d_vision_pro_class; + gobject_class->finalize = ctk_3d_vision_pro_finalize; + __signals[CHANGED] = g_signal_new("changed", G_OBJECT_CLASS_TYPE(ctk_3d_vision_pro_class), G_SIGNAL_RUN_LAST, @@ -180,6 +200,8 @@ static void ctk_3d_vision_pro_class_init(Ctk3DVisionProClass G_TYPE_NONE, 0); } + + GType ctk_3d_vision_pro_get_type(void) { static GType ctk_3d_vision_pro_type = 0; @@ -674,7 +696,7 @@ static void enable_widgets(Ctk3DVisionPro *ctk_3d_vision_pro, Bool enable) gtk_widget_set_sensitive(ctk_3d_vision_pro->table.hscrollbar, enable); } -static void svp_config_changed(GtkWidget *widget, gpointer arg1, +static void svp_config_changed(GtkObject *object, gpointer arg1, gpointer user_data) { CtkEventStruct *event_struct; @@ -696,7 +718,7 @@ static void svp_config_changed(GtkWidget *widget, gpointer arg1, case NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE: { SVP_RANGE range; - CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(widget); + CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(ctk_3d_vision_pro->menu); range = ctk_drop_down_menu_get_current_value(menu); if (range != CHANNEL_RANGE_TO_OPTION_MENU_IDX(event_struct->value)) { @@ -1458,6 +1480,7 @@ GtkWidget* ctk_3d_vision_pro_new(NvCtrlAttributeHandle *handle, ctk_3d_vision_pro->handle = handle; ctk_3d_vision_pro->ctk_config = ctk_config; + ctk_3d_vision_pro->ctk_event = ctk_event; ctk_3d_vision_pro->add_glasses_dlg = NULL; // populate ctk_3d_vision_pro... diff --git a/src/gtk+-2.x/ctk3dvisionpro.h b/src/gtk+-2.x/ctk3dvisionpro.h index 4786f13..f87adf0 100644 --- a/src/gtk+-2.x/ctk3dvisionpro.h +++ b/src/gtk+-2.x/ctk3dvisionpro.h @@ -108,6 +108,7 @@ struct _Ctk3DVisionPro NvCtrlAttributeHandle *handle; GtkWindow *parent_wnd; CtkConfig *ctk_config; + CtkEvent *ctk_event; GtkWidget *menu; guint num_htu; HtuInfo** htu_info; diff --git a/src/gtk+-2.x/ctkappprofile.c b/src/gtk+-2.x/ctkappprofile.c index 939634b..69d9f57 100644 --- a/src/gtk+-2.x/ctkappprofile.c +++ b/src/gtk+-2.x/ctkappprofile.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include <assert.h> +#include <unistd.h> #include <string.h> #include <gtk/gtk.h> #include <gdk/gdk.h> @@ -38,103 +39,6 @@ #define STATUSBAR_UPDATE_WARNING "This will take effect after changes are saved." enum { - PROFILE_SETTING_GL_FSAA_MODE, - PROFILE_SETTING_GL_LOG_MAX_ANISO, - PROFILE_SETTING_GL_NO_DSO_FINALIZER, - PROFILE_SETTING_GL_SINGLE_THREADED, - PROFILE_SETTING_GL_SYNC_DISPLAY_DEVICE, - PROFILE_SETTING_GL_SYNC_TO_VBLANK, - PROFILE_SETTING_GL_SORT_FBCONFIGS, - PROFILE_SETTING_GL_ALLOW_UNOFFICIAL_PROTOCOL, - PROFILE_SETTING_GL_SELINUX_BOOLEANS, - PROFILE_SETTING_GL_SHADER_DISK_CACHE, - PROFILE_SETTING_GL_SHADER_DISK_CACHE_PATH, - PROFILE_SETTING_GL_YIELD, - PROFILE_SETTING_GL_THREADED_OPTIMIZATIONS, - PROFILE_SETTING_GL_DOOM3, - PROFILE_SETTING_GL_EXTENSION_STRING_VERSION, - NUM_PROFILE_SETTINGS -}; - -static const char *profile_setting_keys[] = { - "GLFSAAMode", // PROFILE_SETTING_GL_FSAA_MODE - "GLLogMaxAniso", // PROFILE_SETTING_GL_LOG_MAX_ANISO - "GLNoDsoFinalizer", // PROFILE_SETTING_GL_NO_DSO_FINALIZER - "GLSingleThreaded", // PROFILE_SETTING_GL_SINGLE_THREADED - "GLSyncDisplayDevice", // PROFILE_SETTING_GL_SYNC_DISPLAY_DEVICE - "GLSyncToVblank", // PROFILE_SETTING_GL_SYNC_TO_VBLANK - "GLSortFbconfigs", // PROFILE_SETTING_GL_SORT_FBCONFIGS - "GLAllowUnofficialProtocol", // PROFILE_SETTING_GL_ALLOW_UNOFFICIAL_PROTOCOL - "GLSELinuxBooleans", // PROFILE_SETTING_GL_SELINUX_BOOLEANS - "GLShaderDiskCache", // PROFILE_SETTING_GL_SHADER_DISK_CACHE - "GLShaderDiskCachePath", // PROFILE_SETTING_GL_SHADER_DISK_CACHE_PATH - "GLYield", // PROFILE_SETTING_GL_YIELD - "GLThreadedOptimizations", // PROFILE_SETTING_GL_THREADED_OPTIMIZATIONS - "GLDoom3", // PROFILE_SETTING_GL_DOOM3 - "GLExtensionStringVersion" // PROFILE_SETTING_GL_EXTENSION_STRING_VERSION -}; - -/* - * XXX: it might be a good idea to generate some of these descriptions - * dynamically based on other tables used by nvidia-settings - */ -static const char *profile_setting_descriptions[] = { - // PROFILE_SETTING_GL_FSAA_MODE - "This setting enables full-scene antialiasing in a process using OpenGL. This expects " - "the same integer value that can be used to configure FSAA through nvidia-settings " - "and the NV-CONTROL X extension. To see available FSAA values, run:\n\n" - "\tnvidia-settings --query=fsaa --verbose", - // PROFILE_SETTING_GL_LOG_MAX_ANISO - "This enables anisotropic texture filtering. The possible values are:\n\n" - "\t0\tNo anisotropic filtering\n" - "\t1\t2x anisotropic filtering\n" - "\t2\t4x anisotropic filtering\n" - "\t3\t8x anisotropic filtering\n" - "\t4\t16x anisotropic filtering", - // PROFILE_SETTING_GL_NO_DSO_FINALIZER - "This works around problems with certain multithreaded applications in which " - "one thread exits while others are executing OpenGL code. This may be set to true or false.", - // PROFILE_SETTING_GL_SINGLE_THREADED - "This works around some legacy dynamic loaders which can cause applications linked against pthreads " - "which dlopen() libGL multiple times to crash. This may be set to true or false. ", - // PROFILE_SETTING_GL_SYNC_DISPLAY_DEVICE - "This allows an application to specify target a display device to sync with if sync to vblank is enabled. " - "This should be set to a string containing a valid display device name (for example, \"CRT-1\").", - // PROFILE_SETTING_GL_SYNC_TO_VBLANK - "This enables sync to vblank for an application. This may be set to true or false. ", - // PROFILE_SETTING_GL_SORT_FBCONFIGS - "By default the NVIDIA GLX implementation will sort FBConfigs as described by the specification. This " - "may be set to false to disable this behavior.", - // PROFILE_SETTING_GL_ALLOW_UNOFFICIAL_PROTOCOL - "Setting this to true will allow the client-side NVIDIA GLX implementation to send \"incomplete\" GLX protocol.", - // PROFILE_SETTING_GL_SELINUX_BOOLEANS - "This allows the user to override driver detection of specific SELinux policy booleans, which may " - "work around problems when running the driver under SELinux in permissive mode. This should be set to a " - "string value; see __GL_SELINUX_BOOLEANS in the README for a description of legal string formats.", - // PROFILE_SETTING_GL_SHADER_DISK_CACHE - "This enables the shader disk cache for direct rendering. This value may be set to true or false.", - // PROFILE_SETTING_GL_SHADER_DISK_CACHE_PATH - "This setting affects where shader caches are stored on disk for a given application. " - "This value should be set to a string containing a valid pathname.", - // PROFILE_SETTING_GL_YIELD - "This controls how the NVIDIA graphics driver will perform a yield. This may be set to one of the following strings:\n\n" - "\t\"USLEEP\"\tOpenGL will call usleep(0) to yield\n" - "\t\"NOTHING\"\tOpenGL will never yield\n" - "\t<any other value>\tOpenGL will call sched_yield() to yield (default)", - // PROFILE_SETTING_GL_THREADED_OPTIMIZATIONS - "This setting enables multi-threaded optimizations in the OpenGL driver which may improve application performance. " - "This may be set to true or false.", - // PROFILE_SETTING_GL_DOOM3 - "This enables optimal SLI and Multi-GPU settings for games such as Doom 3 and Quake 4. " - "This may be set to true or false.", - // PROFILE_SETTING_GL_EXTENSION_STRING_VERSION - "This forces the extension string returned by glXQueryExtensionsString() to one that appeared in an earlier " - "version of the NVIDIA graphics driver. This may work around bugs in certain applications which expect an extension " - "string to be smaller than a certain size. This value should be set to a string value or integer containing the " - "desired version number (e.g. \"17700\" to force the extension string in the 177.* driver series).", -}; - -enum { RULE_FEATURE_PROCNAME, RULE_FEATURE_DSO, RULE_FEATURE_TRUE, @@ -189,6 +93,8 @@ typedef struct _ToolbarItemTemplate { const gchar *icon_id; GCallback callback; gpointer user_data; + GtkWidget *(* init_callback)(gpointer); + gpointer init_data; guint flags; const gchar *help_text; @@ -196,6 +102,7 @@ typedef struct _ToolbarItemTemplate { } ToolbarItemTemplate; #define TOOLBAR_ITEM_GHOST_IF_NOTHING_SELECTED (1 << 0) +#define TOOLBAR_ITEM_USE_WIDGET (1 << 1) /* * Template used to construct tree view columns and generate help text with @@ -415,6 +322,42 @@ static void tree_view_cursor_changed_toolbar_item_ghost(GtkTreeView *tree_view, } +static GtkWidget *populate_registry_key_combo_callback(gpointer init_data) +{ + CtkAppProfile *ctk_app_profile; + CtkDropDownMenu *menu = NULL; + json_t *key_docs; + int i; + EditProfileDialog *dialog = (EditProfileDialog *) init_data; + + if (!dialog || dialog->registry_key_combo) { + return NULL; + } + + ctk_app_profile = CTK_APP_PROFILE(dialog->parent); + key_docs = ctk_app_profile->key_docs; + + if (json_array_size(key_docs) <= 0) { + dialog->registry_key_combo = NULL; + return NULL; + } + + menu = (CtkDropDownMenu *) + ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO); + dialog->registry_key_combo = GTK_WIDGET(menu); + + ctk_drop_down_menu_append_item(menu, "Custom", -1); + for (i = 0; i < json_array_size(key_docs); i++) { + json_t *json_key_object = json_array_get(key_docs, i); + json_t *json_name = json_object_get(json_key_object, "key"); + ctk_drop_down_menu_append_item(menu, + json_string_value(json_name), + i); + } + + return dialog->registry_key_combo; +} + /* Simple helper function to fill a toolbar with buttons from a table */ static void populate_toolbar(GtkToolbar *toolbar, const ToolbarItemTemplate *item, @@ -440,13 +383,26 @@ static void populate_toolbar(GtkToolbar *toolbar, } else { icon = NULL; } - widget = gtk_toolbar_append_item(toolbar, - item->text, - item->help_text, - NULL, - icon, - item->callback, - item->user_data); + + if (item->flags & TOOLBAR_ITEM_USE_WIDGET) { + widget = (*item->init_callback)(item->init_data); + if (widget) { + gtk_toolbar_append_widget(toolbar, widget, + item->help_text, NULL); + } else { + item++; + continue; + } + } else { + widget = gtk_toolbar_append_item(toolbar, + item->text, + item->help_text, + NULL, + icon, + item->callback, + item->user_data); + } + if (help_data) { ctk_help_data_list_prepend(help_data, item->text, @@ -1644,6 +1600,63 @@ static GtkWidget *create_rule_profile_name_entry(EditRuleDialog *dialog) return hbox; } + +/* + * The following two functions use the JSON data types to convert data or + * provide data per type. For types that don't match known types we use '-1' + * since we support unspecified types for unknown keys. Also since JSON doesn't + * have a proper boolean type, we use JSON_FALSE + */ + +static int get_type_from_string(const char *s) +{ + if (!strcmp(s, "boolean")) { + return JSON_FALSE; + } else if (!strcmp(s, "integer")) { + return JSON_INTEGER; + } else if (!strcmp(s, "string")) { + return JSON_STRING; + } else if (!strcmp(s, "float")) { + return JSON_REAL; + } else { + return -1; + } +} + +static json_t *get_default_json_from_type(int type) +{ + switch (type) { + case -1: + case JSON_TRUE: + case JSON_FALSE: + default: + return json_false(); + case JSON_INTEGER: + return json_integer(0); + case JSON_REAL: + return json_real(0.0); + case JSON_STRING: + return json_string(""); + } +} + +static const char *get_expected_type_string_from_key(json_t *key_docs, + const char *key) +{ + int i; + for (i = 0; i < json_array_size(key_docs); i++) { + json_t *json_obj = json_array_get(key_docs, i); + json_t *json_key = json_object_get(json_obj, "key"); + const char * name = json_string_value(json_key); + if (!strcmp(name, key)) { + json_key = json_object_get(json_obj, "type"); + return json_string_value(json_key); + } + } + return "unspecified"; +} + + static void setting_key_renderer_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model, @@ -1657,6 +1670,23 @@ static void setting_key_renderer_func(GtkTreeViewColumn *tree_column, g_object_set(cell, "text", key, NULL); } +static void setting_expected_type_renderer_func(GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + json_t *key_docs = (json_t *) data; + const char *expected_type = NULL; + json_t *setting; + gtk_tree_model_get(model, iter, + SETTING_LIST_STORE_COL_SETTING, &setting, -1); + expected_type = get_expected_type_string_from_key(key_docs, + json_string_value(json_object_get(setting, "key"))); + g_object_set(cell, "text", expected_type, NULL); +} + + static void setting_type_renderer_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model, @@ -1673,14 +1703,14 @@ static void setting_type_renderer_func(GtkTreeViewColumn *tree_column, type = "string"; break; case JSON_INTEGER: - type = "int"; + type = "integer"; break; case JSON_REAL: type = "float"; break; case JSON_TRUE: case JSON_FALSE: - type = "bool"; + type = "boolean"; break; default: assert(0); @@ -1926,11 +1956,20 @@ static EditRuleDialog* edit_rule_dialog_new(CtkAppProfile *ctk_app_profile) .help_text = "Each entry in the \"Key\" column describes a key for a setting." }, { - .title = "Type", + .title = "Expected Type", + .renderer_func = setting_expected_type_renderer_func, + .min_width = 80, + .func_data = ctk_app_profile->key_docs, + .help_text = "Each entry in the \"Expected Type\" column describes the type " + "expected for a known setting key. Unrecognized keys may have an " + "unspecified type." + }, + { + .title = "Current Type", .renderer_func = setting_type_renderer_func, - .min_width = 100, + .min_width = 80, .func_data = NULL, - .help_text = "Each entry in the \"Type\" column describes the underlying JSON type for " + .help_text = "Each entry in the \"Current Type\" column describes the current type for " "a setting value." }, { @@ -2101,32 +2140,86 @@ static void edit_rule_dialog_destroy(EditRuleDialog *dialog) free(dialog); } +static int lookup_column_number_by_name(GtkTreeView *tree_view, + const char *name) +{ + int i; + GtkTreeViewColumn *column; + GtkLabel *label; + + for (i = 0, column = gtk_tree_view_get_column(tree_view, i); + column; + column = gtk_tree_view_get_column(tree_view, ++i)) { + label = GTK_LABEL(gtk_tree_view_column_get_widget(column)); + if (label) { + const char *s = gtk_label_get_text(label); + if (!strcmp(s, name)) { + return i; + } + } + } + + return 0; // Default to the first column if not found. +} + static void edit_profile_dialog_settings_new_row(GtkTreeView *tree_view, GtkTreeModel *tree_model, GtkTreePath **path, - GtkTreeViewColumn **column) + GtkTreeViewColumn **column, + json_t *key_docs, + int key_index) { GtkTreeIter iter; json_t *setting = json_object(); - json_object_set(setting, "key", json_string("")); - json_object_set(setting, "value", json_false()); + const char *s; + int expected_type; + int column_to_edit; + + if (json_array_size(key_docs) > 0 && key_index >= 0) { + json_t *key_obj = json_array_get(key_docs, key_index); + s = json_string_value(json_object_get(key_obj, "key")); + + expected_type = get_type_from_string(get_expected_type_string_from_key(key_docs, s)); + column_to_edit = lookup_column_number_by_name(tree_view, "Value"); + } else { + s = ""; + expected_type = -1; + column_to_edit = lookup_column_number_by_name(tree_view, "Key"); + } + + json_object_set_new(setting, "key", json_string(s)); + json_object_set_new(setting, "value", + get_default_json_from_type(expected_type)); + gtk_list_store_append(GTK_LIST_STORE(tree_model), &iter); - gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, SETTING_LIST_STORE_COL_SETTING, setting, -1); + gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, + SETTING_LIST_STORE_COL_SETTING, setting, -1); *path = gtk_tree_model_get_path(tree_model, &iter); - *column = gtk_tree_view_get_column(tree_view, 0); + *column = gtk_tree_view_get_column(tree_view, column_to_edit); } static void edit_profile_dialog_add_setting(GtkWidget *widget, gpointer user_data) { EditProfileDialog *dialog = (EditProfileDialog *)user_data; + CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(dialog->parent); GtkTreePath *path; GtkTreeViewColumn *column; + CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(dialog->registry_key_combo); + int key_index; + + if (menu) { + key_index = ctk_drop_down_menu_get_current_value(menu); + } else { + key_index = -1; + } edit_profile_dialog_settings_new_row(dialog->settings_view, - GTK_TREE_MODEL(dialog->settings_store), - &path, - &column); + GTK_TREE_MODEL(dialog->settings_store), + &path, + &column, + ctk_app_profile->key_docs, + key_index); gtk_widget_grab_focus(GTK_WIDGET(dialog->settings_view)); gtk_tree_view_set_cursor(dialog->settings_view, path, column, TRUE); @@ -2230,26 +2323,31 @@ static gboolean widget_get_visible(GtkWidget *widget) return visible; } -static const gchar *get_canonical_setting_key(const gchar *key) +static const gchar *get_canonical_setting_key(const gchar *key, + json_t *key_docs) { size_t i; - for (i = 0; i < NUM_PROFILE_SETTINGS; i++) { - if (!strcasecmp(key, profile_setting_keys[i])) { - return profile_setting_keys[i]; + for (i = 0; i < json_array_size(key_docs); i++) { + json_t *key_obj = json_array_get(key_docs, i); + json_t *key_name = json_object_get(key_obj, "key"); + if (json_is_string(key_name) && + !strcasecmp(key, json_string_value(key_name))) { + return json_string_value(key_name); } } return NULL; } -static gboolean check_unrecognized_setting_keys(const json_t *settings) +static gboolean check_unrecognized_setting_keys(const json_t *settings, + json_t *key_docs) { const json_t *setting; - const char *setting_key; + const char *key; size_t i, size; for (i = 0, size = json_array_size(settings); i < size; i++) { setting = json_array_get(settings, i); - setting_key = json_string_value(json_object_get(setting, "key")); - if (!get_canonical_setting_key(setting_key)) { + key = json_string_value(json_object_get(setting, "key")); + if (!get_canonical_setting_key(key, key_docs)) { return TRUE; } } @@ -2297,7 +2395,7 @@ static gboolean edit_profile_dialog_validate(EditProfileDialog *dialog) free(reason); } - if (check_unrecognized_setting_keys(dialog->settings)) { + if (check_unrecognized_setting_keys(dialog->settings, ctk_app_profile->key_docs)) { g_string_append_printf(nonfatal_errors, "%s\tThis profile has settings with keys that may not be recognized " "by the NVIDIA graphics driver. Consult the on-line help for a list " "of valid keys.\n", get_bullet()); @@ -2411,6 +2509,13 @@ static void get_profile_dialog_toolbar_items(EditProfileDialog *dialog, { const ToolbarItemTemplate settings_items[] = { { + .text = "Choose Key Drop Down", + .help_text = "The Key Drop Down allows you to select the registry setting key to add.", + .init_callback = populate_registry_key_combo_callback, + .init_data = dialog, + .flags = TOOLBAR_ITEM_USE_WIDGET + }, + { .text = "Add Setting", .help_text = "The Add Setting button allows you to create a new setting in the profile.", .icon_id = GTK_STOCK_ADD, @@ -2495,6 +2600,7 @@ static void setting_key_edited(GtkCellRendererText *renderer, gpointer user_data) { EditProfileDialog *dialog = (EditProfileDialog *)user_data; + CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(dialog->parent); GtkTreePath *path; GtkTreeIter iter; json_t *setting; @@ -2517,7 +2623,8 @@ static void setting_key_edited(GtkCellRendererText *renderer, gtk_tree_model_get(GTK_TREE_MODEL(dialog->settings_store), &iter, SETTING_LIST_STORE_COL_SETTING, &setting, -1); - canonical_key = get_canonical_setting_key(new_text); + canonical_key = get_canonical_setting_key(new_text, + ctk_app_profile->key_docs); if (!canonical_key) { edit_profile_dialog_statusbar_message(dialog, "The key [%s] is not recognized by nvidia-settings. " @@ -2534,6 +2641,27 @@ static void setting_key_edited(GtkCellRendererText *renderer, gtk_tree_path_free(path); } +static gboolean is_expected_setting_value(json_t *value, int expected_type) +{ + switch (json_typeof(value)) { + + // Allowed Types + case JSON_STRING: + return (expected_type == -1 || expected_type == JSON_STRING); + case JSON_TRUE: + case JSON_FALSE: + return (expected_type == -1 || + expected_type == JSON_FALSE || + expected_type == JSON_TRUE); + case JSON_REAL: + return (expected_type == -1 || expected_type == JSON_REAL); + case JSON_INTEGER: + return (expected_type == -1 || expected_type == JSON_INTEGER); + default: + return FALSE; + } +} + static gboolean is_valid_setting_value(json_t *value, char **invalid_type_str) { switch (json_typeof(value)) { @@ -2567,12 +2695,15 @@ static void setting_value_edited(GtkCellRendererText *renderer, gchar *invalid_type_str = NULL; gchar *new_text_in_json; EditProfileDialog *dialog = (EditProfileDialog *)user_data; + CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(dialog->parent); GtkTreePath *path; GtkTreeIter iter; json_t *setting; json_t *value; json_error_t error; gboolean update_value = TRUE; + const char *type_str = NULL; + int expected_type; if (dialog->setting_update_canceled) { // Don't update anything @@ -2581,7 +2712,7 @@ static void setting_value_edited(GtkCellRendererText *renderer, path = gtk_tree_path_new_from_string(path_s); if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->settings_store), - &iter, path)) { + &iter, path)) { return; } @@ -2590,7 +2721,10 @@ static void setting_value_edited(GtkCellRendererText *renderer, gtk_tree_model_get(GTK_TREE_MODEL(dialog->settings_store), &iter, SETTING_LIST_STORE_COL_SETTING, &setting, -1); - new_text_in_json = nv_app_profile_cfg_file_syntax_to_json(new_text); + type_str = json_string_value(json_object_get(setting, "key")); + expected_type = get_type_from_string(get_expected_type_string_from_key(ctk_app_profile->key_docs, type_str)); + + new_text_in_json = nv_app_profile_file_syntax_to_json(new_text); value = json_loads(new_text_in_json, JSON_DECODE_ANY, &error); if (!value) { @@ -2603,6 +2737,10 @@ static void setting_value_edited(GtkCellRendererText *renderer, "A value of type \"%s\" is not allowed in the configuration.", invalid_type_str); update_value = FALSE; + } else if (!is_expected_setting_value(value, expected_type)) { + edit_profile_dialog_statusbar_message(dialog, + "The parsed type of the value entered does not match the type " + "expected."); } if (update_value) { @@ -2619,6 +2757,7 @@ static TreeViewColumnTemplate *get_profile_settings_tree_view_columns(EditProfil size_t *num_columns) { TreeViewColumnTemplate *settings_tree_view_columns_copy; + CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(dialog->parent); const TreeViewColumnTemplate settings_tree_view_columns[] = { { .title = "Key", @@ -2635,11 +2774,20 @@ static TreeViewColumnTemplate *get_profile_settings_tree_view_columns(EditProfil "on the cell containing the key." }, { - .title = "Type", + .title = "Expected Type", + .renderer_func = setting_expected_type_renderer_func, + .min_width = 80, + .func_data = ctk_app_profile->key_docs, + .help_text = "Each entry in the \"Expected Type\" column describes the type " + "expected for a known setting key. Unrecognized keys may have an " + "unspecified type. This column is read-only" + }, + { + .title = "Current Type", .renderer_func = setting_type_renderer_func, - .min_width = 100, + .min_width = 80, .func_data = NULL, - .help_text = "Each entry in the \"Type\" column describes the underlying JSON type for " + .help_text = "Each entry in the \"Current Type\" column describes the underlying JSON type for " "a setting value. Supported JSON types are: string, true, false, and number. " "This column is read-only." }, @@ -2741,6 +2889,8 @@ static EditProfileDialog *edit_profile_dialog_new(CtkAppProfile *ctk_app_profile return NULL; } + dialog->parent = GTK_WIDGET(ctk_app_profile); + settings_tree_view_columns = get_profile_settings_tree_view_columns(dialog, &num_settings_tree_view_columns); get_profile_dialog_toolbar_items(dialog, @@ -2749,7 +2899,6 @@ static EditProfileDialog *edit_profile_dialog_new(CtkAppProfile *ctk_app_profile &edit_profile_dialog_toolbar_items, &num_edit_profile_dialog_toolbar_items); - dialog->parent = GTK_WIDGET(ctk_app_profile); dialog->top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); dialog->top_help_data = NULL; @@ -2824,6 +2973,8 @@ static EditProfileDialog *edit_profile_dialog_new(CtkAppProfile *ctk_app_profile toolbar = gtk_toolbar_new(); tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->settings_store)); + dialog->registry_key_combo = NULL; + populate_toolbar(GTK_TOOLBAR(toolbar), edit_profile_settings_toolbar_items, num_edit_profile_settings_toolbar_items, @@ -3427,6 +3578,37 @@ static char *get_default_global_config_file(void) } } +static char *get_default_keys_file(const char *driver_version) +{ + char *file = NULL; + const char *file_noversion = "/usr/share/nvidia/nvidia-application-" + "profiles-key-documentation"; + + if (driver_version) { + file = nvstrcat("/usr/share/nvidia/nvidia-application-profiles-", + driver_version, "-key-documentation", NULL); + } + + if (file && access(file, F_OK) != -1) { + return file; + } else if (access(file_noversion, F_OK) != -1) { + /* On some systems, this file is installed without a version number */ + + free(file); + return nvstrdup(file_noversion); + } else { + nv_error_msg("nvidia-settings could not find the registry key file. " + "This file should have been installed along with this " + "driver at either %s or %s. The application profiles " + "will continue to work, but values cannot be " + "preopulated or validated, and will not be listed in " + "the help text. Please see the README for possible " + "values and descriptions.", file, file_noversion); + free(file); + return NULL; + } +} + #define SEARCH_PATH_NUM_FILES 4 static char **get_default_search_path(size_t *num_files) @@ -4000,6 +4182,7 @@ GtkTextBuffer *ctk_app_profile_create_help(CtkAppProfile *ctk_app_profile, GtkTe size_t j; GtkTextIter i; GtkTextBuffer *b; + json_t * key_docs = ctk_app_profile->key_docs; b = gtk_text_buffer_new(table); gtk_text_buffer_get_iter_at_offset(b, &i, 0); @@ -4091,12 +4274,21 @@ GtkTextBuffer *ctk_app_profile_create_help(CtkAppProfile *ctk_app_profile, GtkTe ctk_help_heading(b, &i, "Supported Setting Keys"); - ctk_help_para(b, &i, "This NVIDIA® Linux Graphics Driver supports the following application profile setting " - "keys. For more information on a given key, please consult the README."); + if (json_array_size(key_docs) > 0) { + ctk_help_para(b, &i, "This NVIDIA® Linux Graphics Driver supports the following application profile setting " + "keys. For more information on a given key, please consult the README."); - for (j = 0; j < NUM_PROFILE_SETTINGS; j++) { - ctk_help_term(b, &i, "%s", profile_setting_keys[j]); - ctk_help_para(b, &i, "%s", profile_setting_descriptions[j]); + for (j = 0; j < json_array_size(key_docs); j++) { + json_t *key_obj = json_array_get(key_docs, j); + json_t *key_name = json_object_get(key_obj, "key"); + json_t *key_desc = json_object_get(key_obj, "description"); + ctk_help_term(b, &i, "%s", json_string_value(key_name)); + ctk_help_para(b, &i, "%s", json_string_value(key_desc)); + } + } else { + ctk_help_para(b, &i, "There was an error reading the application profile setting " + "keys resource file. For information on available keys, please " + "consult the README."); } ctk_help_finish(b); @@ -4119,7 +4311,8 @@ static void enabled_check_button_toggled(GtkToggleButton *toggle_button, STATUSBAR_UPDATE_WARNING); } -GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config) +GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config, + const gchar *driver_version) { GObject *object; CtkAppProfile *ctk_app_profile; @@ -4133,6 +4326,7 @@ GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config) GtkWidget *toolbar; char *global_config_file; + char *keys_file; char **search_path; size_t search_path_size; ToolbarItemTemplate *save_reload_toolbar_items; @@ -4147,6 +4341,11 @@ GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config) gtk_box_set_spacing(GTK_BOX(ctk_app_profile), 10); + /* Load registry keys resource file */ + keys_file = get_default_keys_file(driver_version); + ctk_app_profile->key_docs = nv_app_profile_key_documentation_load(keys_file); + free(keys_file); + /* Load app profile settings */ // TODO only load this if the page is exposed search_path = get_default_search_path(&search_path_size); diff --git a/src/gtk+-2.x/ctkappprofile.h b/src/gtk+-2.x/ctkappprofile.h index 5a34f1d..6c1e8e6 100644 --- a/src/gtk+-2.x/ctkappprofile.h +++ b/src/gtk+-2.x/ctkappprofile.h @@ -109,6 +109,8 @@ typedef struct _EditProfileDialog { GtkWidget *add_edit_profile_button; + GtkWidget *registry_key_combo; + // Used in the special case where a currently edited row // will be deleted, in which case we don't want to update // the model. @@ -157,6 +159,7 @@ struct _CtkAppProfile CtkConfig *ctk_config; AppProfileConfig *gold_config, *cur_config; + json_t *key_docs; // Interfaces layered on top of the config object for use with GtkTreeView CtkApcProfileModel *apc_profile_model; @@ -193,7 +196,7 @@ struct _CtkAppProfileClass }; GType ctk_app_profile_get_type (void) G_GNUC_CONST; -GtkWidget* ctk_app_profile_new (CtkConfig *); +GtkWidget* ctk_app_profile_new (CtkConfig *, const gchar *); GtkTextBuffer* ctk_app_profile_create_help (CtkAppProfile *, GtkTextTagTable *); char *serialize_settings(const json_t *settings, gboolean add_markup); diff --git a/src/gtk+-2.x/ctkcolorcontrols.c b/src/gtk+-2.x/ctkcolorcontrols.c index ba2f3d5..575e21a 100644 --- a/src/gtk+-2.x/ctkcolorcontrols.c +++ b/src/gtk+-2.x/ctkcolorcontrols.c @@ -58,7 +58,7 @@ static void color_range_menu_changed(GtkWidget *widget, static void color_control_update_received(GtkObject *object, gpointer arg1, gpointer user_data); -static gboolean setup_color_range_dropdown(CtkColorControls *ctk_color_controls); +static void setup_color_range_dropdown(CtkColorControls *ctk_color_controls); static void post_color_range_update(CtkColorControls *ctk_color_controls, gint color_range); @@ -399,11 +399,7 @@ static gboolean update_color_space_menu_info(CtkColorControls *ctk_color_control (gpointer) ctk_color_controls); /* dynamically regenerate color range dropdown */ - if (!setup_color_range_dropdown(ctk_color_controls)) { - gtk_widget_set_sensitive(ctk_color_controls->color_range_menu, FALSE); - } else { - gtk_widget_set_sensitive(ctk_color_controls->color_range_menu, TRUE); - } + setup_color_range_dropdown(ctk_color_controls); return TRUE; @@ -482,8 +478,9 @@ static void color_space_menu_changed(GtkWidget *widget, color_space = map_nvctrl_value_to_table(ctk_color_controls, color_space); - /* reflecting the change in color space to other widgets & reset button */ - ctk_color_controls_setup(ctk_color_controls); + /* Regenerate the color range dropdown to reflect the new color space */ + setup_color_range_dropdown(ctk_color_controls); + post_color_space_update(ctk_color_controls, color_space); } /* color_space_menu_changed() */ @@ -600,10 +597,11 @@ static gboolean build_color_space_table(CtkColorControls *ctk_color_controls, * setup_color_range_dropdown() - dynamically generate dropdown list for * color range depending on selected color space. */ -static gboolean setup_color_range_dropdown(CtkColorControls *ctk_color_controls) +static void setup_color_range_dropdown(CtkColorControls *ctk_color_controls) { gint i, n = 0, color_range_count = 0; gint mask, val; + gboolean enable = FALSE; ReturnStatus ret; NVCTRLAttributeValidValuesRec valid; CtkDropDownMenu *d; @@ -612,11 +610,11 @@ static gboolean setup_color_range_dropdown(CtkColorControls *ctk_color_controls) NV_CTRL_COLOR_RANGE, &valid); if (ret != NvCtrlSuccess) { - return FALSE; + goto done; } if (valid.type != ATTRIBUTE_TYPE_INT_BITS) { - return FALSE; + goto done; } mask = valid.u.bits.ints; /* count no. of supported color space */ @@ -633,7 +631,7 @@ static gboolean setup_color_range_dropdown(CtkColorControls *ctk_color_controls) 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) { - return FALSE; + goto done; } for (i = 0, n = 0; n < ctk_color_controls->color_range_table_size; i++) { @@ -682,11 +680,12 @@ static gboolean setup_color_range_dropdown(CtkColorControls *ctk_color_controls) /* If dropdown only has one item, disable it */ if (ctk_color_controls->color_range_table_size <= 1) { - return FALSE; + goto done; } + enable = TRUE; - return TRUE; - +done: + gtk_widget_set_sensitive(ctk_color_controls->color_range_menu, enable); } /* setup_color_range_dropdown() */ diff --git a/src/gtk+-2.x/ctkcolorcorrection.c b/src/gtk+-2.x/ctkcolorcorrection.c index 6afb93f..6fe089e 100644 --- a/src/gtk+-2.x/ctkcolorcorrection.c +++ b/src/gtk+-2.x/ctkcolorcorrection.c @@ -83,6 +83,8 @@ flush_attribute_channel_values (CtkColorCorrection *, gint, gint); static void ctk_color_correction_class_init(CtkColorCorrectionClass *); +static void ctk_color_correction_finalize(GObject *); + static void apply_parsed_attribute_list(CtkColorCorrection *, ParsedAttribute *); @@ -154,10 +156,13 @@ GType ctk_color_correction_get_type( } + static void ctk_color_correction_class_init(CtkColorCorrectionClass *ctk_color_correction_class) { + GObjectClass *gobject_class = (GObjectClass *)ctk_color_correction_class; + signals[CHANGED] = g_signal_new("changed", G_OBJECT_CLASS_TYPE(ctk_color_correction_class), @@ -166,9 +171,28 @@ ctk_color_correction_class_init(CtkColorCorrectionClass NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + gobject_class->finalize = ctk_color_correction_finalize; +} + + + +static void ctk_color_correction_finalize(GObject *object) +{ + CtkColorCorrection *ctk_object = CTK_COLOR_CORRECTION(object); + + g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event), + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + (gpointer) ctk_object); + + } + GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle, CtkConfig *ctk_config, ParsedAttribute *p, CtkEvent *ctk_event) @@ -199,6 +223,7 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle, ctk_color_correction = CTK_COLOR_CORRECTION(object); ctk_color_correction->handle = handle; ctk_color_correction->ctk_config = ctk_config; + ctk_color_correction->ctk_event = ctk_event; ctk_color_correction->confirm_timer = 0; ctk_color_correction->confirm_countdown = DEFAULT_CONFIRM_COLORCORRECTION_TIMEOUT; @@ -858,11 +883,14 @@ static void apply_parsed_attribute_list( while (p) { CtrlHandleTargetNode *node; + const AttributeTableEntry *a = p->attr_entry; if (!p->next) goto next_attribute; - - if (!(p->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE)) goto next_attribute; - + + if (a->type != NV_PARSER_ATTRIBUTE_TYPE_COLOR) { + goto next_attribute; + } + /* * Apply the parsed attribute's settings only if the color * correction's target matches one of the (parse attribute's) @@ -878,8 +906,8 @@ static void apply_parsed_attribute_list( (attr_target_id != target_id)) { continue; } - - switch (p->attr & (ALL_VALUES | ALL_CHANNELS)) { + + switch (a->attr & (ALL_VALUES | ALL_CHANNELS)) { case (CONTRAST_VALUE | RED_CHANNEL): set_color_state(ctk_color_correction, CONTRAST, RED_CHANNEL, p->val.f, TRUE); break; @@ -922,13 +950,13 @@ static void apply_parsed_attribute_list( default: continue; } - - attr |= (p->attr & (ALL_VALUES | ALL_CHANNELS)); + + attr |= (a->attr & (ALL_VALUES | ALL_CHANNELS)); } - + next_attribute: - + p = p->next; } diff --git a/src/gtk+-2.x/ctkcolorcorrection.h b/src/gtk+-2.x/ctkcolorcorrection.h index cbeaa09..d160542 100644 --- a/src/gtk+-2.x/ctkcolorcorrection.h +++ b/src/gtk+-2.x/ctkcolorcorrection.h @@ -55,6 +55,7 @@ struct _CtkColorCorrection GtkVBox parent; NvCtrlAttributeHandle *handle; CtkConfig *ctk_config; + CtkEvent *ctk_event; GtkWidget *option_menu; GtkObject *brightness_adjustment; GtkObject *contrast_adjustment; diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.c b/src/gtk+-2.x/ctkdisplayconfig-utils.c index d3a7107..27e5e03 100644 --- a/src/gtk+-2.x/ctkdisplayconfig-utils.c +++ b/src/gtk+-2.x/ctkdisplayconfig-utils.c @@ -82,8 +82,6 @@ void apply_modeline_token(char *token, char *value, void *data) modeline->source |= MODELINE_SOURCE_EDID; } else if (!strcasecmp("nv-control", value)) { modeline->source |= MODELINE_SOURCE_NVCONTROL; - } else { - nv_warning_msg("Unknown modeline source '%s'", value); } /* X config name */ @@ -141,8 +139,6 @@ void apply_metamode_token(char *token, char *value, void *data) metamode->source = METAMODE_SOURCE_NVCONTROL; } else if (!strcasecmp("randr", value)) { metamode->source = METAMODE_SOURCE_RANDR; - } else { - nv_warning_msg("Unknown MetaMode source '%s'", value); } /* Switchable */ @@ -156,14 +152,8 @@ void apply_metamode_token(char *token, char *value, void *data) metamode->switchable = FALSE; } } - - /* Unknown token */ - } else { - nv_warning_msg("Unknown MetaMode token value pair: %s=%s", - token, value); } - -} /* apply_metamode_token() */ +} @@ -184,14 +174,8 @@ void apply_monitor_token(char *token, char *value, void *data) if (!strcasecmp("source", token)) { if (*source) free(*source); *source = strdup(value); - - /* Unknown token */ - } else { - nv_warning_msg("Unknown monitor range token value pair: %s=%s", - token, value); } - -} /* apply_monitor_token() */ +} @@ -221,11 +205,6 @@ void apply_screen_info_token(char *token, char *value, void *data) } else if (!strcasecmp("height", token)) { screen_info->height = atoi(value); - - /* Unknown token */ - } else { - nv_warning_msg("Unknown screen info token value pair: %s=%s", - token, value); } } @@ -645,10 +624,9 @@ static void apply_mode_attribute_token(char *token, char *value, void *data) str = parse_read_integer_pair(str, 0, &(mode->viewPortOut.x), &(mode->viewPortOut.y)); - } /* Rotation */ - if (!strcasecmp("rotation", token)) { + } else if (!strcasecmp("rotation", token)) { if (!strcasecmp("left", value) || !strcasecmp("CCW", value) || !strcasecmp("90", value)) { @@ -662,10 +640,9 @@ static void apply_mode_attribute_token(char *token, char *value, void *data) !strcasecmp("270", value)) { mode->rotation = ROTATION_270; } - } /* Reflection */ - if (!strcasecmp("reflection", token)) { + } else if (!strcasecmp("reflection", token)) { if (!strcasecmp("x", value)) { mode->reflection = REFLECTION_X; } else if (!strcasecmp("y", value)) { @@ -674,8 +651,7 @@ static void apply_mode_attribute_token(char *token, char *value, void *data) mode->reflection = REFLECTION_XY; } } - -} /* apply_mode_attribute_token() */ +} diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c index ee2e25e..119d7cc 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.c +++ b/src/gtk+-2.x/ctkdisplayconfig.c @@ -1183,6 +1183,10 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, gchar *sli_mode = NULL; ReturnStatus ret; + const char *stereo_mode_str; + NVCTRLAttributeValidValuesRec valid; + int stereo_mode, stereo_mode_max = NV_CTRL_STEREO_MAX; + /* * Get SLI Mode. If SLI Mode is "Mosaic", do not * load this page @@ -1546,41 +1550,57 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, (gpointer) ctk_object); /* Screen Stereo Mode */ - ctk_object->mnu_screen_stereo = gtk_option_menu_new(); - menu = gtk_menu_new(); - menu_item = gtk_menu_item_new_with_label("Disabled"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("DCC Glasses"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("BlueLine Glasses"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Onboard (DIN)"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Passive Eye Per Display"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Vertical Interlaced"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Color Interleaved"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Horizontal Interlaced"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Checkerboard 3D DLP"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("Inverse Checkerboard 3D DLP"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("NVIDIA 3D Vision"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("NVIDIA 3D Vision Pro"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - menu_item = gtk_menu_item_new_with_label("HDMI 3D"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - gtk_option_menu_set_menu - (GTK_OPTION_MENU(ctk_object->mnu_screen_stereo), menu); - ctk_config_set_tooltip(ctk_config, ctk_object->mnu_screen_stereo, - __screen_stereo_help); - g_signal_connect(G_OBJECT(ctk_object->mnu_screen_stereo), - "changed", G_CALLBACK(screen_stereo_changed), - (gpointer) ctk_object); + ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_STEREO, &valid); + + if (ret == NvCtrlSuccess) { + + ctk_object->mnu_screen_stereo = gtk_option_menu_new(); + menu = gtk_menu_new(); + + ctk_object->stereo_table_size = 0; + memset(ctk_object->stereo_table, 0, + sizeof(int) * ARRAY_LEN(ctk_object->stereo_table)); + + /* + * The current driver will return type _INT_BITS that we can use to + * list the available stereo modes. Older drivers will return the type + * _INTEGER that we can use as a flag to list all possible stereo modes + * before the change was made. The newest at that time was HDMI_3D. + */ + + if (valid.type == ATTRIBUTE_TYPE_INTEGER) { + stereo_mode_max = NV_CTRL_STEREO_HDMI_3D; + } + + for (stereo_mode = NV_CTRL_STEREO_OFF; + stereo_mode <= stereo_mode_max; + stereo_mode++) { + stereo_mode_str = NvCtrlGetStereoModeNameIfExists(stereo_mode); + + if (stereo_mode_str == (const char *) -1) { + break; + } + + if (stereo_mode_str && (valid.type == ATTRIBUTE_TYPE_INTEGER || + (valid.type == ATTRIBUTE_TYPE_INT_BITS && + valid.u.bits.ints & (1 << stereo_mode)))) { + ctk_object->stereo_table[ctk_object->stereo_table_size++] = + stereo_mode; + menu_item = gtk_menu_item_new_with_label(stereo_mode_str); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); + } + } + + gtk_option_menu_set_menu + (GTK_OPTION_MENU(ctk_object->mnu_screen_stereo), menu); + ctk_config_set_tooltip(ctk_config, ctk_object->mnu_screen_stereo, + __screen_stereo_help); + g_signal_connect(G_OBJECT(ctk_object->mnu_screen_stereo), + "changed", G_CALLBACK(screen_stereo_changed), + (gpointer) ctk_object); + } else { + ctk_object->mnu_screen_stereo = NULL; + } /* Screen Position Type (Absolute/Relative Menu) */ ctk_object->mnu_screen_position_type = gtk_option_menu_new(); @@ -2009,15 +2029,19 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, ctk_object->box_screen_depth = hbox; /* X screen stereo dropdown */ - label = gtk_label_new("Stereo Mode:"); - labels = g_slist_append(labels, label); + if (ctk_object->mnu_screen_stereo) { + label = gtk_label_new("Stereo Mode:"); + labels = g_slist_append(labels, label); - hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5); - gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_screen_stereo, - TRUE, TRUE, 0); - ctk_object->box_screen_stereo = hbox; + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5); + gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_screen_stereo, + TRUE, TRUE, 0); + ctk_object->box_screen_stereo = hbox; + } else { + ctk_object->box_screen_stereo = NULL; + } /* X screen positioning */ label = gtk_label_new("Position:"); @@ -4428,6 +4452,7 @@ static void setup_screen_stereo_dropdown(CtkDisplayConfig *ctk_object) { nvScreenPtr screen = ctk_display_layout_get_selected_screen (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); + int i, index = screen->stereo; if (!ctk_object->box_screen_stereo) return; @@ -4437,6 +4462,14 @@ static void setup_screen_stereo_dropdown(CtkDisplayConfig *ctk_object) return; } + /* translation from stereo mode to dropdown index */ + for (i = 0; i < ctk_object->stereo_table_size; i++) { + if (ctk_object->stereo_table[i] == screen->stereo) { + index = i; + break; + } + } + /* Set the selected positioning type */ g_signal_handlers_block_by_func (G_OBJECT(ctk_object->mnu_screen_stereo), @@ -4444,7 +4477,7 @@ static void setup_screen_stereo_dropdown(CtkDisplayConfig *ctk_object) gtk_option_menu_set_history (GTK_OPTION_MENU(ctk_object->mnu_screen_stereo), - screen->stereo); + index); g_signal_handlers_unblock_by_func (G_OBJECT(ctk_object->mnu_screen_stereo), @@ -6635,6 +6668,12 @@ static void screen_stereo_changed(GtkWidget *widget, gpointer user_data) screen->stereo = idx; + if (idx >= 0 && idx < ctk_object->stereo_table_size) { + + /* translation from dropdown index to stereo mode */ + screen->stereo = ctk_object->stereo_table[idx]; + } + /* Can't apply screen stereo changes */ ctk_object->apply_possible = FALSE; @@ -7925,10 +7964,6 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data) if (!screen->handle) continue; if (screen->no_scanout) continue; - if (!update_screen_metamodes(ctk_object, screen)) { - clear_apply = FALSE; - } - if (screen->primaryDisplay && ctk_object->primary_display_changed) { ret = NvCtrlSetStringAttribute(screen->handle, NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER, @@ -7944,6 +7979,11 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data) ctk_object->primary_display_changed = FALSE; } } + + if (!update_screen_metamodes(ctk_object, screen)) { + clear_apply = FALSE; + } + } /* Clear the apply button if all went well, and we were able to apply @@ -8750,7 +8790,7 @@ static int generateXConfig(CtkDisplayConfig *ctk_object, XConfigPtr *pConfig) /* Check if composite should be disabled */ { - const char *composite_disabled_str = NULL; + char *composite_disabled_str = NULL; nvScreenPtr screen; /* See if any X screens have overlay, cioverlay, ubb or stereo enabled, @@ -8781,6 +8821,7 @@ static int generateXConfig(CtkDisplayConfig *ctk_object, XConfigPtr *pConfig) xconfigRemoveNamedOption(&(config->extensions->options), "Composite", NULL); xconfigAddNewOption(&config->extensions->options, "Composite", "Disable"); + nvfree(composite_disabled_str); } } diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h index ba9acff..b0d47a8 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.h +++ b/src/gtk+-2.x/ctkdisplayconfig.h @@ -126,6 +126,8 @@ typedef struct _CtkDisplayConfig GtkWidget *box_display_stereo; GtkWidget *mnu_display_stereo; + int stereo_table[NV_CTRL_STEREO_MAX + 1]; + int stereo_table_size; GtkWidget *box_display_orientation; GtkWidget *mnu_display_rotation; diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c index a8b2db1..dc9e5bf 100644 --- a/src/gtk+-2.x/ctkevent.c +++ b/src/gtk+-2.x/ctkevent.c @@ -430,9 +430,10 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN); MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN); MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_GPU_FLAGS); + MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU); #undef MAKE_BINARY_SIGNAL -#if NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE != NV_CTRL_BINARY_DATA_GPU_FLAGS +#if NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE != NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU #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 fe43a31..debc66a 100644 --- a/src/gtk+-2.x/ctkframelock.c +++ b/src/gtk+-2.x/ctkframelock.c @@ -5782,20 +5782,26 @@ static void add_devices(CtkFramelock *ctk_framelock, * to the parsed attribute list. * */ -#define __ADD_ATTR(ATTR,VAL) \ - a.display = display_name; \ - a.target_type = target_type; \ - a.target_id = target_id; \ - a.attr = (ATTR); \ - a.val.i = (VAL); \ - a.display_device_mask = 0; \ - a.flags |= NV_PARSER_HAS_TARGET; \ - nv_parsed_attribute_add(head, &a); +#define __ADD_ATTR(ATTR, VAL) \ + { \ + ParsedAttribute a; \ + \ + memset(&a, 0, sizeof(a)); \ + \ + a.display = display_name; \ + a.target_type = target_type; \ + a.target_id = target_id; \ + a.attr_entry = \ + nv_get_attribute_entry((ATTR), NV_PARSER_ATTRIBUTE_TYPE_INTEGER); \ + a.val.i = (VAL); \ + a.parser_flags.has_target = NV_TRUE; \ + \ + nv_parsed_attribute_add(head, &a); \ + } static void add_entry_to_parsed_attributes(nvListEntryPtr entry, ParsedAttribute *head) { - ParsedAttribute a; char *display_name = NULL; int target_type = 0; int target_id = 0; @@ -5804,14 +5810,13 @@ static void add_entry_to_parsed_attributes(nvListEntryPtr entry, return; } - memset(&a, 0, sizeof(a)); - switch (entry->data_type) { case ENTRY_DATA_FRAMELOCK: { int use_house_sync; nvFrameLockDataPtr data = (nvFrameLockDataPtr)(entry->data); + display_name = NvCtrlGetDisplayName(data->handle); target_type = NV_CTRL_TARGET_TYPE_FRAMELOCK; target_id = NvCtrlGetTargetId(data->handle); @@ -5854,22 +5859,26 @@ static void add_entry_to_parsed_attributes(nvListEntryPtr entry, case ENTRY_DATA_DISPLAY: { - nvDisplayDataPtr data = (nvDisplayDataPtr)(entry->data); - int config; - ReturnStatus ret; + nvDisplayDataPtr data = (nvDisplayDataPtr)(entry->data); + int config; + ReturnStatus ret; - display_name = NvCtrlGetDisplayName(data->handle); + display_name = NvCtrlGetDisplayName(data->handle); + target_type = NV_CTRL_TARGET_TYPE_DISPLAY; + target_id = NvCtrlGetTargetId(data->handle); - ret = NvCtrlGetAttribute(data->handle, - NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, - &config); - if (ret != NvCtrlSuccess) { - config = NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_DISABLED; - } - target_type = NV_CTRL_TARGET_TYPE_DISPLAY; - target_id = NvCtrlGetTargetId(data->handle); + ret = NvCtrlGetAttribute(data->handle, + NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, + &config); + if (ret != NvCtrlSuccess) { + config = NV_CTRL_FRAMELOCK_DISPLAY_CONFIG_DISABLED; + } - __ADD_ATTR(NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, config); + __ADD_ATTR(NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, config); + + if (display_name) { + free(display_name); + } } break; @@ -5947,18 +5956,25 @@ static void apply_parsed_attribute_list(CtkFramelock *ctk_framelock, /* Add frame lock devices for all servers */ for (p = list; p && p->next; p = p->next) { + + /* Only process Frame Lock attributes */ + if (!(p->attr_entry->flags.is_framelock_attribute)) { + continue; + } + + /* Check to see if the server is already added */ if (server_name) { free(server_name); } server_name = nv_standardize_screen_name(p->display, -2); - if (!server_name) continue; - - /* Not a frame lock attribute */ - if (!(p->flags & NV_PARSER_TYPE_FRAMELOCK)) continue; + if (!server_name) { + continue; + } - /* Server already added */ - if (find_server_by_name - ((nvListTreePtr)(ctk_framelock->tree), server_name)) continue; + if (find_server_by_name((nvListTreePtr)(ctk_framelock->tree), + server_name)) { + continue; + } /* Add all the devices from this attribute's server */ add_devices(ctk_framelock, server_name, FALSE); diff --git a/src/gtk+-2.x/ctkgpu.c b/src/gtk+-2.x/ctkgpu.c index e681c86..c2d1b65 100644 --- a/src/gtk+-2.x/ctkgpu.c +++ b/src/gtk+-2.x/ctkgpu.c @@ -44,8 +44,13 @@ static gboolean update_gpu_usage(gpointer); typedef struct { gint graphics; + gboolean graphics_specified; + gint video; + gboolean video_specified; + gint pcie; + gboolean pcie_specified; } utilizationEntry, * utilizationEntryPtr; GType ctk_gpu_get_type( @@ -181,6 +186,23 @@ gchar *get_bus_id_str(NvCtrlAttributeHandle *handle) } +static void apply_gpu_utilization_token(char *token, char *value, void *data) +{ + utilizationEntryPtr pEntry = (utilizationEntryPtr) data; + + if (!strcasecmp("graphics", token)) { + pEntry->graphics = atoi(value); + pEntry->graphics_specified = TRUE; + } else if (!strcasecmp("video", token)) { + pEntry->video = atoi(value); + pEntry->video_specified = TRUE; + } else if (!strcasecmp("pcie", token)) { + pEntry->pcie = atoi(value); + pEntry->pcie_specified = TRUE; + } +} + + GtkWidget* ctk_gpu_new( NvCtrlAttributeHandle *handle, @@ -225,6 +247,7 @@ GtkWidget* ctk_gpu_new( int row = 0; int total_rows = 21; int gpu_memory; + utilizationEntry entry; /* @@ -322,6 +345,19 @@ GtkWidget* ctk_gpu_new( } else { irq = g_strdup_printf("%d", tmp); } + + /* NV_CTRL_STRING_GPU_UTILIZATION */ + + memset(&entry, 0, sizeof(entry)); + + ret = NvCtrlGetStringAttribute(handle, + NV_CTRL_STRING_GPU_UTILIZATION, + &tmp_str); + if (ret == NvCtrlSuccess) { + parse_token_value_pairs(tmp_str, apply_gpu_utilization_token, &entry); + XFree(tmp_str); + } + /* List of X Screens using the GPU */ @@ -475,14 +511,22 @@ GtkWidget* ctk_gpu_new( 0, 0.5, "Memory Interface:", 0, 0.5, memory_interface); } - ctk_gpu->gpu_utilization_label = - add_table_row(table, row++, - 0, 0.5, "GPU Utilization:", - 0, 0.5, NULL); - ctk_gpu->video_utilization_label = - add_table_row(table, row++, - 0, 0.5, "Video Engine Utilization:", - 0, 0.5, NULL); + + /* GPU utilization */ + + if (entry.graphics_specified) { + ctk_gpu->gpu_utilization_label = + add_table_row(table, row++, + 0, 0.5, "GPU Utilization:", + 0, 0.5, NULL); + } + if (entry.video_specified) { + ctk_gpu->video_utilization_label = + add_table_row(table, row++, + 0, 0.5, "Video Engine Utilization:", + 0, 0.5, NULL); + } + /* spacing */ row += 3; add_table_row(table, row++, @@ -725,24 +769,6 @@ static void probe_displays_received(GtkObject *object, gpointer arg1, -static void apply_gpu_utilization_token(char *token, char *value, void *data) -{ - utilizationEntryPtr pEntry = (utilizationEntryPtr) data; - - if (!strcasecmp("graphics", token)) { - pEntry->graphics = atoi(value); - } else if (!strcasecmp("video", token)) { - pEntry->video = atoi(value); - } else if (!strcasecmp("pcie", token)) { - pEntry->pcie = atoi(value); - } else { - nv_warning_msg("Unknown GPU utilization token value pair: %s=%s", - token, value); - } -} - - - static gboolean update_gpu_usage(gpointer user_data) { CtkGpu *ctk_gpu; @@ -780,42 +806,54 @@ static gboolean update_gpu_usage(gpointer user_data) NV_CTRL_STRING_GPU_UTILIZATION, &utilizationStr); if (ret != NvCtrlSuccess) { - gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_utilization_label), "Unknown"); - gtk_label_set_text(GTK_LABEL(ctk_gpu->video_utilization_label), - "Unknown"); + if (ctk_gpu->gpu_utilization_label) { + gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_utilization_label), + "Unknown"); + } + if (ctk_gpu->video_utilization_label) { + gtk_label_set_text(GTK_LABEL(ctk_gpu->video_utilization_label), + "Unknown"); + } if (ctk_gpu->pcie_utilization_label) { gtk_label_set_text(GTK_LABEL(ctk_gpu->pcie_utilization_label), "Unknown"); } return FALSE; - } else { - memset(&entry, -1, sizeof(&entry)); - parse_token_value_pairs(utilizationStr, apply_gpu_utilization_token, - &entry); - if (entry.graphics != -1) { - utilization_text = g_strdup_printf("%d %%", - entry.graphics); + } - gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_utilization_label), - utilization_text); - } - if (entry.video != -1) { - utilization_text = g_strdup_printf("%d %%", - entry.video); + memset(&entry, 0, sizeof(entry)); + parse_token_value_pairs(utilizationStr, apply_gpu_utilization_token, + &entry); + if ((entry.graphics_specified) && + (ctk_gpu->gpu_utilization_label)) { + utilization_text = g_strdup_printf("%d %%", + entry.graphics); - gtk_label_set_text(GTK_LABEL(ctk_gpu->video_utilization_label), - utilization_text); - } - if ((entry.pcie != -1) && - (ctk_gpu->pcie_utilization_label)) { - utilization_text = g_strdup_printf("%d %%", - entry.pcie); + gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_utilization_label), + utilization_text); + g_free(utilization_text); + } + if ((entry.video_specified) && + (ctk_gpu->video_utilization_label)) { + utilization_text = g_strdup_printf("%d %%", + entry.video); - gtk_label_set_text(GTK_LABEL(ctk_gpu->pcie_utilization_label), - utilization_text); - } + gtk_label_set_text(GTK_LABEL(ctk_gpu->video_utilization_label), + utilization_text); g_free(utilization_text); } + if ((entry.pcie_specified) && + (ctk_gpu->pcie_utilization_label)) { + utilization_text = g_strdup_printf("%d %%", + entry.pcie); + + gtk_label_set_text(GTK_LABEL(ctk_gpu->pcie_utilization_label), + utilization_text); + g_free(utilization_text); + } + + XFree(utilizationStr); + return TRUE; } diff --git a/src/gtk+-2.x/ctkgvo-banner.c b/src/gtk+-2.x/ctkgvo-banner.c index 99057fd..8ffd798 100644 --- a/src/gtk+-2.x/ctkgvo-banner.c +++ b/src/gtk+-2.x/ctkgvo-banner.c @@ -88,6 +88,9 @@ static void gvo_event_received(GtkObject *object, gpointer arg1, gpointer user_data); +static void ctk_gvo_banner_class_init(CtkGvoBannerClass *ctk_object_class); +static void ctk_gvo_banner_finalize(GObject *object); + /* @@ -103,7 +106,7 @@ GType ctk_gvo_banner_get_type(void) sizeof (CtkGvoBannerClass), NULL, /* base_init */ NULL, /* base_finalize */ - NULL, /* constructor */ + (GClassInitFunc) ctk_gvo_banner_class_init, /* class_init, */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (CtkGvoBanner), @@ -123,6 +126,29 @@ GType ctk_gvo_banner_get_type(void) +static void ctk_gvo_banner_class_init(CtkGvoBannerClass *ctk_object_class) +{ + GObjectClass *gobject_class = (GObjectClass *)ctk_object_class; + gobject_class->finalize = ctk_gvo_banner_finalize; +} + + + +static void ctk_gvo_banner_finalize(GObject *object) +{ + CtkGvoBanner *ctk_object = CTK_GVO_BANNER(object); + + g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event), + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + (gpointer) ctk_object); +} + + + /* * ctk_gvo_banner_new() - constructor for the CtkGvoBanner widget */ diff --git a/src/gtk+-2.x/ctkgvo.c b/src/gtk+-2.x/ctkgvo.c index f833bcd..3bf36c5 100644 --- a/src/gtk+-2.x/ctkgvo.c +++ b/src/gtk+-2.x/ctkgvo.c @@ -772,12 +772,12 @@ GtkTextBuffer* ctk_gvo_create_help(GtkTextTagTable *table) GtkTextBuffer *b; b = gtk_text_buffer_new(table); - + gtk_text_buffer_get_iter_at_offset(b, &i, 0); ctk_help_title(b, &i, "GVO (Graphics to Video Out) Help"); - ctk_help_para(b, &i, "This page gives access to general information about " - "the SDI device as well as configuration of Clone Mode."); + ctk_help_para(b, &i, "This page reports general information about the SDI " + "device."); ctk_help_heading(b, &i, "General Information"); ctk_help_para(b, &i, "This section shows information about the SDI device " diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c index 3bdf176..84b5341 100644 --- a/src/gtk+-2.x/ctkpowermizer.c +++ b/src/gtk+-2.x/ctkpowermizer.c @@ -181,9 +181,6 @@ static void apply_perf_mode_token(char *token, char *value, void *data) pEntry->processorclockmin = atoi(value); } else if (!strcasecmp("processorclockmax", token)) { pEntry->processorclockmax = atoi(value); - } else { - nv_warning_msg("Unknown Perf Mode token value pair: %s=%s", - token, value); } } diff --git a/src/gtk+-2.x/ctkscreen.c b/src/gtk+-2.x/ctkscreen.c index 421fe21..2a654bb 100644 --- a/src/gtk+-2.x/ctkscreen.c +++ b/src/gtk+-2.x/ctkscreen.c @@ -34,22 +34,6 @@ #include "ctkutils.h" #include "ctkbanner.h" -static const _CtkStereoMode stereoMode[] = { - { NV_CTRL_STEREO_OFF, "Stereo Disabled" }, - { NV_CTRL_STEREO_DDC, "DDC Stereo" }, - { NV_CTRL_STEREO_BLUELINE, "Blueline Stereo" }, - { NV_CTRL_STEREO_DIN, "Onboard DIN Stereo" }, - { NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY, "Passive One-Eye-per-Display Stereo" }, - { NV_CTRL_STEREO_VERTICAL_INTERLACED, "Vertical Interlaced Stereo" }, - { NV_CTRL_STEREO_COLOR_INTERLACED, "Color Interleaved Stereo" }, - { NV_CTRL_STEREO_HORIZONTAL_INTERLACED, "Horizontal Interlaced Stereo" }, - { NV_CTRL_STEREO_CHECKERBOARD_PATTERN, "Checkerboard Pattern Stereo" }, - { NV_CTRL_STEREO_INVERSE_CHECKERBOARD_PATTERN, "Inverse Checkerboard Stereo" }, - { NV_CTRL_STEREO_3D_VISION, "NVIDIA 3D Vision Stereo" }, - { NV_CTRL_STEREO_3D_VISION_PRO, "NVIDIA 3D Vision Pro Stereo" }, - { NV_CTRL_STEREO_HDMI_3D, "HDMI 3D Stereo" }, -}; - void ctk_screen_event_handler(GtkWidget *widget, XRRScreenChangeNotifyEvent *ev, gpointer data); @@ -60,17 +44,6 @@ static void associated_displays_received(GtkObject *object, gpointer arg1, static void info_update_gpu_error(GtkObject *object, gpointer arg1, gpointer user_data); -static const char *get_stereo_mode_string(int stereo_mode) -{ - int i; - for (i = 0; i < ARRAY_LEN(stereoMode); i++) { - if (stereoMode[i].stereo_mode == stereo_mode) { - return stereoMode[i].name; - } - } - return "Unknown"; -} - GType ctk_screen_get_type( void ) @@ -339,7 +312,7 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, add_table_row(table, 19, 0, 0, "Recovered GPU Errors:", 0, 0, tmp); if (ctk_screen->stereo_available) { add_table_row(table, 20, 0, 0, "Stereo Mode:", 0, 0, - get_stereo_mode_string(stereo_mode)); + NvCtrlGetStereoModeName(stereo_mode)); } g_free(screen_number); diff --git a/src/gtk+-2.x/ctkscreen.h b/src/gtk+-2.x/ctkscreen.h index 13bc003..c950a75 100644 --- a/src/gtk+-2.x/ctkscreen.h +++ b/src/gtk+-2.x/ctkscreen.h @@ -66,11 +66,6 @@ struct _CtkScreenClass GtkVBoxClass parent_class; }; -typedef struct { - int stereo_mode; - const char *name; -} _CtkStereoMode; - GType ctk_screen_get_type (void) G_GNUC_CONST; GtkWidget* ctk_screen_new (NvCtrlAttributeHandle *handle, CtkEvent *ctk_event); diff --git a/src/gtk+-2.x/ctkvcs.c b/src/gtk+-2.x/ctkvcs.c index 4d9a08c..77bc7e4 100644 --- a/src/gtk+-2.x/ctkvcs.c +++ b/src/gtk+-2.x/ctkvcs.c @@ -50,9 +50,6 @@ static void apply_fan_entry_token(char *token, char *value, void *data) pFanEntry->fan_speed = atoi(value); } else if (!strcasecmp("fail", token)) { pFanEntry->fan_failed = atoi(value); - } else { - nv_warning_msg("Unknown Fan Entry token value pair: %s=%s", - token, value); } } @@ -66,9 +63,6 @@ static void apply_thermal_entry_token(char *token, char *value, void *data) pThermalEntry->exhaust_temp = atoi(value); } else if (!strcasecmp("board", token)) { pThermalEntry->board_temp = atoi(value); - } else { - nv_warning_msg("Unknown Thermal Entry token value pair: %s=%s", - token, value); } } @@ -96,9 +90,6 @@ static void apply_psu_entry_token(char *token, char *value, void *data) } else { pPSUEntry->psu_state = VCS_PSU_STATE_ABNORMAL; } - } else { - nv_warning_msg("Unknown PSU Entry token value pair: %s=%s", - token, value); } } diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c index 7ade747..2848734 100644 --- a/src/gtk+-2.x/ctkwindow.c +++ b/src/gtk+-2.x/ctkwindow.c @@ -405,11 +405,14 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf, GtkTextBuffer *help; + NvCtrlAttributeHandle *server_handle = NULL; + CtkEvent *ctk_event; CtkConfig *ctk_config; gint column_offset, i; gboolean slimm_page_added; /* XXX Kludge to only show one SLIMM page */ + gchar *driver_version; /* create the new object */ @@ -564,27 +567,26 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf, if (h->targets[X_SCREEN_TARGET].n) { - NvCtrlAttributeHandle *screen_handle = NULL; GtkWidget *child; int i; /* * XXX For now, just use the first handle in the list * to communicate with the X server for these two - * pages. + * pages and the app profile page below. */ for (i = 0 ; i < h->targets[X_SCREEN_TARGET].n; i++) { if (h->targets[X_SCREEN_TARGET].t[i].h) { - screen_handle = h->targets[X_SCREEN_TARGET].t[i].h; + server_handle = h->targets[X_SCREEN_TARGET].t[i].h; break; } } - if (screen_handle) { + if (server_handle) { /* X Server information */ - child = ctk_server_new(screen_handle, ctk_config); + child = ctk_server_new(server_handle, ctk_config); add_page(child, ctk_server_create_help(tag_table, CTK_SERVER(child)), @@ -593,7 +595,7 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf, /* X Server Display Configuration */ - child = ctk_display_config_new(screen_handle, ctk_config); + child = ctk_display_config_new(server_handle, ctk_config); if (child) { add_page(child, ctk_display_config_create_help(tag_table, @@ -1022,7 +1024,18 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf, } /* app profile configuration */ - widget = ctk_app_profile_new(ctk_config); + if (server_handle) + { + ReturnStatus ret = NvCtrlGetStringAttribute(server_handle, + NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, + &driver_version); + if (ret != NvCtrlSuccess) { + driver_version = NULL; + } + } + + widget = ctk_app_profile_new(ctk_config, driver_version); + XFree(driver_version); add_page(widget, ctk_app_profile_create_help(CTK_APP_PROFILE(widget), tag_table), ctk_window, NULL, NULL, "Application Profiles", diff --git a/src/image_data/nvidia_icon_pixdata.h b/src/image_data/nvidia_icon_pixdata.h index 4555b18..4555b18 100755..100644 --- a/src/image_data/nvidia_icon_pixdata.h +++ b/src/image_data/nvidia_icon_pixdata.h diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h index 9fa995c..20af156 100644 --- a/src/libXNVCtrl/NVCtrl.h +++ b/src/libXNVCtrl/NVCtrl.h @@ -341,6 +341,7 @@ #define NV_CTRL_STEREO_3D_VISION 10 #define NV_CTRL_STEREO_3D_VISION_PRO 11 #define NV_CTRL_STEREO_HDMI_3D 12 +#define NV_CTRL_STEREO_MAX NV_CTRL_STEREO_HDMI_3D /* * NV_CTRL_EMULATE - controls OpenGL software emulation of future @@ -4468,8 +4469,23 @@ /* Depth 8 and display composition transformations are mutually exclusive. */ #define NV_CTRL_BINARY_DATA_GPU_FLAGS_DEPTH_8_DISPLAY_TRANSFORM_EXCLUSIVE 2 +/* + * NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU - Returns the list of valid + * display devices that can be connected to the GPU target. + * + * The format of the returned data is: + * + * 4 CARD32 number of display devices + * 4 * n CARD32 display device indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. + */ + +#define NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU 20 /* R--G */ -#define NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE NV_CTRL_BINARY_DATA_GPU_FLAGS +#define NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE \ + NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU /**************************************************************************/ diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c index 543ef7f..ce4b8d1 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c +++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c @@ -932,6 +932,54 @@ const char *NvCtrlGetMultisampleModeName(int multisample_mode) } /* NvCtrlGetMultisampleModeName */ +/* + * NvCtrlGetStereoModeNameIfExists() - lookup string describing the STEREO + * Mode. If is doesn't exist, return NULL. + */ + +const char *NvCtrlGetStereoModeNameIfExists(int stereo_mode) +{ + static const char *stereo_modes[] = { + [NV_CTRL_STEREO_OFF] = "Disabled", + [NV_CTRL_STEREO_DDC] = "DDC", + [NV_CTRL_STEREO_BLUELINE] = "Blueline", + [NV_CTRL_STEREO_DIN] = "Onboard DIN", + [NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY] = "Passive One-Eye-per-Display", + [NV_CTRL_STEREO_VERTICAL_INTERLACED] = "Vertical Interlaced", + [NV_CTRL_STEREO_COLOR_INTERLACED] = "Color Interleaved", + [NV_CTRL_STEREO_HORIZONTAL_INTERLACED] = "Horizontal Interlaced", + [NV_CTRL_STEREO_CHECKERBOARD_PATTERN] = "Checkerboard Pattern", + [NV_CTRL_STEREO_INVERSE_CHECKERBOARD_PATTERN] = "Inverse Checkerboard", + [NV_CTRL_STEREO_3D_VISION] = "NVIDIA 3D Vision", + [NV_CTRL_STEREO_3D_VISION_PRO] = "NVIDIA 3D Vision Pro", + [NV_CTRL_STEREO_HDMI_3D] = "HDMI 3D", + }; + + + if ((stereo_mode < 0) || (stereo_mode >= ARRAY_LEN(stereo_modes))) { + return (const char *) -1; + } + + return stereo_modes[stereo_mode]; +} + +/* + * NvCtrlGetStereoModeName() - lookup string describing the STEREO + * Mode. If is doesn't exist, return descriptive text that the mode + * was not found. + */ + +const char *NvCtrlGetStereoModeName(int stereo_mode) +{ + const char *c = NvCtrlGetStereoModeNameIfExists(stereo_mode); + + if (!c || (c == (const char *) -1)) { + c = "Unknown Mode"; + } + + return c; +} + ReturnStatus NvCtrlGetColorAttributes(NvCtrlAttributeHandle *handle, float contrast[3], @@ -1040,7 +1088,17 @@ static unsigned short ComputeGammaRampVal(int gammaRampSize, j += half; } - if (j < 0.0) j = 0.0; + /* brightness */ + + brightness *= scale; + + j += brightness; + if (j > (double)num) { + j = (double)num; + } + if (j < 0.0) { + j = 0.0; + } /* gamma */ @@ -1052,14 +1110,6 @@ static unsigned short ComputeGammaRampVal(int gammaRampSize, val = (int) (pow (j / (double)num, gamma) * (double)num + 0.5); } - /* brightness */ - - brightness *= scale; - - val += (int)brightness; - if (val > num) val = num; - if (val < 0) val = 0; - val <<= shift; return (unsigned short) val; } diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h index f00c84d..dac483d 100644 --- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h +++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h @@ -474,6 +474,9 @@ NvCtrlGetGvoColorConversion(NvCtrlAttributeHandle *handle, float colorOffset[3], float colorScale[3]); +const char *NvCtrlGetStereoModeNameIfExists(int stereo_mode); +const char *NvCtrlGetStereoModeName(int stereo_mode); + const char *NvCtrlGetMultisampleModeName(int multisample_mode); char *NvCtrlAttributesStrError (ReturnStatus status); diff --git a/src/msg.c b/src/msg.c deleted file mode 100644 index 7887daa..0000000 --- a/src/msg.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix - * and Linux systems. - * - * 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. - * - * 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>. - */ - -#include "msg.h" -#include "command-line.h" -#include "common-utils.h" - -#include <NvCtrlAttributes.h> - -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include <unistd.h> -#include <sys/ioctl.h> -#if defined(__sun) -#include <sys/termios.h> -#endif - -extern int __verbosity; - -static void format(FILE*, const char*, char *, int); -static int get_terminal_width(void); - -#define NV_FORMAT(stream, prefix, fmt, whitespace) \ -do { \ - char *buf; \ - NV_VSNPRINTF(buf, fmt); \ - format(stream, prefix, buf, whitespace); \ - free (buf); \ -} while(0) - -/* - * nv_error_msg() - print an error message, nicely formatted using the - * format() function. - * - * This function should be used for all errors. - */ - -void nv_error_msg(const char *fmt, ...) -{ - if (__verbosity < VERBOSITY_ERROR) return; - - fprintf(stderr, "\n"); - - NV_FORMAT(stderr, "ERROR: ", fmt, False); - - fprintf(stderr, "\n"); - -} /* nv_error_msg() */ - - - -/* - * nv_deprecated_msg() - print a deprecation message, nicely formatted using - * the format() function. - * - * This function should be used for all deprecation messages. - */ - -void nv_deprecated_msg(const char *fmt, ...) -{ - if (__verbosity < VERBOSITY_DEPRECATED) return; - - fprintf(stderr, "\n"); - - NV_FORMAT(stderr, "DEPRECATED: ", fmt, False); - - fprintf(stderr, "\n"); -} - - - -/* - * nv_warning_msg() - print a warning message, nicely formatted using - * the format() function. - * - * This function should be used for all warnings. - */ - -void nv_warning_msg(const char *fmt, ...) -{ - if (__verbosity < VERBOSITY_WARNING) return; - - fprintf(stdout, "\n"); - - NV_FORMAT(stdout, "WARNING: ", fmt, False); - - fprintf(stdout, "\n"); - -} /* nv_warning_msg() */ - - - -/* - * nv_info_msg() - print an info message, nicely formatted using - * the format() function. - * - * This function should be used to display verbose information. - */ - -void nv_info_msg(const char *prefix, const char *fmt, ...) -{ - if (__verbosity < VERBOSITY_ALL) return; - - NV_FORMAT(stdout, prefix, fmt, False); - -} /* nv_info_msg() */ - - - -/* - * nv_msg() - print a message, nicely formatted using the format() - * function. - * - * This function should be used to display messages independent - * of the verbosity level. - */ - -void nv_msg(const char *prefix, const char *fmt, ...) -{ - NV_FORMAT(stdout, prefix, fmt, False); - -} /* nv_msg() */ - - -/* - * nv_msg_preserve_whitespace() - Prints the message, just like nv_msg() - * using format(), the difference is, whitespace characters are not - * skipped during the text processing. - */ - -void nv_msg_preserve_whitespace(const char *prefix, const char *fmt, ...) -{ - NV_FORMAT(stdout, prefix, fmt, True); - -} /* nv_msg_preserve_whitespace() */ - - -/* - * XXX gcc's '-ansi' option causes vsnprintf to not be defined, so - * declare the prototype here. - */ - -#if defined(__STRICT_ANSI__) -int vsnprintf(char *str, size_t size, const char *format, - va_list ap); -#endif - - - -/* - * format() - formats and prints the string buf so that no more than - * 80 characters are printed across. - */ - -static void format(FILE *stream, const char *prefix, - char *buf, int preserveWhitespace) -{ - int len, prefix_len, z, w, i, max_width; - char *line, *local_prefix, *a, *b, *c; - - max_width = get_terminal_width(); - - /* loop until we've printed the entire string */ - - z = strlen(buf); - a = buf; - - if (prefix) { - prefix_len = strlen(prefix); - local_prefix = nvalloc(prefix_len+1); - strcpy(local_prefix, prefix); - } else { - prefix_len = 0; - local_prefix = NULL; - } - - do { - w = max_width; - - /* adjust the max width for any prefix */ - - w -= prefix_len; - - /* - * if the string will fit on one line, point b to the end of the - * string - */ - - if (z < w) b = a + z; - - /* - * if the string won't fit on one line, move b to where the end of - * the line should be, and then move b back until we find a space; - * if we don't find a space before we back b all the way up to a, start - * b at a, and move forward until we do find a space - */ - - else { - b = a + w; - while ((b >= a) && (!isspace(*b))) b--; - - if (b <= a) { - b = a; - while (*b && !isspace(*b)) b++; - } - } - - /* look for any newline in the line, and move b to it */ - - for (c = a; c < b; c++) if (*c=='\n') { b = c; break; } - - /* print the string that starts at a and ends at b */ - - /* - * XXX this could be done just by temporarily overwriting b - * with '\0' - */ - - len = b-a; - line = nvalloc(len+1); - strncpy(line, a, len); - line[len] = '\0'; - if (local_prefix) { - fprintf(stream, "%s%s\n", local_prefix, line); - } else { - fprintf(stream, "%s\n", line); - } - free(line); - - /* - * adjust the length of the string and move the pointer to the - * beginning of the new line - */ - - z -= (b - a + 1); - a = b + 1; - - if (!preserveWhitespace) { - /* move to the first non whitespace character */ - while ((z > 0) && (isspace(*a))) a++, z--; - } - - if (local_prefix) { - for (i = 0; i < prefix_len; i++) local_prefix[i] = ' '; - } - - } while (z > 0); - - if (local_prefix) free (local_prefix); - -} /* format() */ - - -#define DEFAULT_MAX_WIDTH 75 - -static int get_terminal_width(void) -{ - struct winsize ws; - - if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { - return DEFAULT_MAX_WIDTH; - } else { - return (ws.ws_col - 1); - } -} - diff --git a/src/msg.h b/src/msg.h deleted file mode 100644 index 9be5ab2..0000000 --- a/src/msg.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix - * and Linux systems. - * - * 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. - * - * 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>. - */ - -#ifndef __MSG_H__ -#define __MSG_H__ - -#include <stdarg.h> -#include <stdio.h> - -#include "common-utils.h" - -void nv_error_msg(const char*, ...) NV_ATTRIBUTE_PRINTF(1, 2); -void nv_deprecated_msg(const char*, ...) NV_ATTRIBUTE_PRINTF(1, 2); -void nv_warning_msg(const char*, ...) NV_ATTRIBUTE_PRINTF(1, 2); -void nv_info_msg(const char*, const char*, ...) NV_ATTRIBUTE_PRINTF(2, 3); -void nv_msg(const char*, const char*, ...) NV_ATTRIBUTE_PRINTF(2, 3); -void nv_msg_preserve_whitespace(const char*, const char*, ...) NV_ATTRIBUTE_PRINTF(2, 3); - -#endif /* __MSG_H__ */ diff --git a/src/nvidia-settings.c b/src/nvidia-settings.c index bda2b20..5f2438b 100644 --- a/src/nvidia-settings.c +++ b/src/nvidia-settings.c @@ -29,9 +29,6 @@ #include <stdlib.h> -extern int __list_targets; - - int main(int argc, char **argv) { ConfigProperties conf; @@ -46,6 +43,8 @@ int main(int argc, char **argv) handles_array.n = 0; handles_array.array = NULL; + nv_set_verbosity(NV_VERBOSITY_DEPRECATED); + /* * initialize the ui * @@ -115,7 +114,7 @@ int main(int argc, char **argv) /* upload the data from the config file */ if (!op->no_load) { - ret = nv_read_config_file(op->config, op->ctrl_display, + ret = nv_read_config_file(op, op->config, op->ctrl_display, p, &conf, &handles_array); } else { ret = 1; @@ -126,7 +125,7 @@ int main(int argc, char **argv) * we only list the resolved targets, then exit now. */ - if (op->only_load || __list_targets) { + if (op->only_load || op->list_targets) { return ret ? 0 : 1; } @@ -155,7 +154,9 @@ int main(int argc, char **argv) /* write the configuration file */ - nv_write_config_file(op->config, h, p, &conf); + if (op->write_config) { + nv_write_config_file(op->config, h, p, &conf); + } /* cleanup */ diff --git a/src/option-table.h b/src/option-table.h index a5feea6..df5994b 100644 --- a/src/option-table.h +++ b/src/option-table.h @@ -184,6 +184,9 @@ static const NVGetoptOption __options[] = { " which the query/assign operation would have been performed, without " "actually performing the operation(s), and exit." }, + { "write-config", 'w', NVGETOPT_IS_BOOLEAN | NVGETOPT_HELP_ALWAYS, NULL, + "Save the configuration file on exit (enabled by default)." }, + { NULL, 0, 0, NULL, NULL}, }; diff --git a/src/parse.c b/src/parse.c index 0433ffe..d647594 100644 --- a/src/parse.c +++ b/src/parse.c @@ -34,8 +34,6 @@ /* local helper functions */ -static char **nv_strtok(char *s, char c, int *n); -static void nv_free_strtoks(char **s, int n); static int ctoi(const char c); static int count_number_of_chars(char *o, char d); @@ -49,344 +47,381 @@ static uint32 display_device_name_to_display_device_mask(const char *str); * attribute. */ -#define F NV_PARSER_TYPE_FRAMELOCK -#define C NV_PARSER_TYPE_COLOR_ATTRIBUTE -#define N NV_PARSER_TYPE_NO_CONFIG_WRITE -#define G NV_PARSER_TYPE_GUI_ATTRIBUTE -#define P NV_PARSER_TYPE_PACKED_ATTRIBUTE -#define D NV_PARSER_TYPE_VALUE_IS_DISPLAY -#define A NV_PARSER_TYPE_NO_QUERY_ALL -#define Z NV_PARSER_TYPE_NO_ZERO_VALUE -#define H NV_PARSER_TYPE_100Hz -#define K NV_PARSER_TYPE_1000Hz -#define S NV_PARSER_TYPE_STRING_ATTRIBUTE -#define I NV_PARSER_TYPE_SDI -#define W NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY -#define M NV_PARSER_TYPE_SDI_CSC -#define T NV_PARSER_TYPE_HIJACK_DISPLAY_DEVICE -#define V NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID +#define INT_ATTR NV_PARSER_ATTRIBUTE_TYPE_INTEGER +#define STR_ATTR NV_PARSER_ATTRIBUTE_TYPE_STRING +#define COL_ATTR NV_PARSER_ATTRIBUTE_TYPE_COLOR +#define CSC_ATTR NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC +#define SOP_ATTR NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION const AttributeTableEntry attributeTable[] = { - /* name constant flags description */ + /* name attribute type common flags special flags description + * + * .-------------- is_100Hz + * no_query_all -----------. | .------------ is_1000Hz + * no_config_write ---------. | | | .---------- is_packed + * hijack_display_device -------. | | | | | .-------- is_display_mask + * is_sdi_attribute -----. | | | | | | | .------ is_display_id + * is_framelock_attribute ---. | | | | | | | | | .---- no_zero + * is_gui_attribute -. | | | | | | | | | | | .-- is_switch_display + * | | | | | | | | | | | | | + */ /* Version information */ - { "OperatingSystem", NV_CTRL_OPERATING_SYSTEM, N, "The operating system on which the X server is running. 0-Linux, 1-FreeBSD, 2-SunOS." }, - { "NvidiaDriverVersion", NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, S|N, "The NVIDIA X driver version." }, - { "NvControlVersion", NV_CTRL_STRING_NV_CONTROL_VERSION, S|N, "The NV-CONTROL X driver extension version." }, - { "GLXServerVersion", NV_CTRL_STRING_GLX_SERVER_VERSION, S|N, "The GLX X server extension version." }, - { "GLXClientVersion", NV_CTRL_STRING_GLX_CLIENT_VERSION, S|N, "The GLX client version." }, - { "OpenGLVersion", NV_CTRL_STRING_GLX_OPENGL_VERSION, S|N, "The OpenGL version." }, - { "XRandRVersion", NV_CTRL_STRING_XRANDR_VERSION, S|N, "The X RandR version." }, - { "XF86VidModeVersion", NV_CTRL_STRING_XF86VIDMODE_VERSION, S|N, "The XF86 Video Mode X extension version." }, - { "XvVersion", NV_CTRL_STRING_XV_VERSION, S|N, "The Xv X extension version." }, - { "ScreenPosition", NV_CTRL_STRING_SCREEN_RECTANGLE, S|N, "Returns the physical X Screen's initial position and size (in absolute coordinates) within the desktop as the \"token=value \" string: \"x=#, y=#, width=#, height=#\"." }, - + { "OperatingSystem", NV_CTRL_OPERATING_SYSTEM, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The operating system on which the X server is running. 0-Linux, 1-FreeBSD, 2-SunOS." }, + { "NvidiaDriverVersion", NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The NVIDIA X driver version." }, + { "NvControlVersion", NV_CTRL_STRING_NV_CONTROL_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The NV-CONTROL X driver extension version." }, + { "GLXServerVersion", NV_CTRL_STRING_GLX_SERVER_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The GLX X server extension version." }, + { "GLXClientVersion", NV_CTRL_STRING_GLX_CLIENT_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The GLX client version." }, + { "OpenGLVersion", NV_CTRL_STRING_GLX_OPENGL_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The OpenGL version." }, + { "XRandRVersion", NV_CTRL_STRING_XRANDR_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The X RandR version." }, + { "XF86VidModeVersion", NV_CTRL_STRING_XF86VIDMODE_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The XF86 Video Mode X extension version." }, + { "XvVersion", NV_CTRL_STRING_XV_VERSION, STR_ATTR, {0,0,0,0,1,0}, {}, "The Xv X extension version." }, + /* X screen */ - { "Ubb", NV_CTRL_UBB, 0, "Is UBB enabled for the specified X screen." }, - { "Overlay", NV_CTRL_OVERLAY, 0, "Is the RGB overlay enabled for the specified X screen." }, - { "Stereo", NV_CTRL_STEREO, 0, "The stereo mode for the specified X screen." }, - { "TwinView", NV_CTRL_TWINVIEW, 0, "Is TwinView enabled for the specified X screen." }, - { "ConnectedDisplays", NV_CTRL_CONNECTED_DISPLAYS, D, "DEPRECATED: use \"-q dpys\" instead." }, - { "EnabledDisplays", NV_CTRL_ENABLED_DISPLAYS, D, "DEPRECATED: use \"-q dpys\" instead." }, - { "AssociatedDisplays", NV_CTRL_ASSOCIATED_DISPLAY_DEVICES, N|D, "DEPRECATED: use \"-q xscreens -V all\" instead." }, - { "ProbeDisplays", NV_CTRL_PROBE_DISPLAYS, A|D, "When this attribute is queried, the X driver re-probes the hardware to detect which display devices are connected to the GPU or DPU driving the specified X screen." }, - { "InitialPixmapPlacement", NV_CTRL_INITIAL_PIXMAP_PLACEMENT, N, "Controls where X pixmaps are initially created." }, - { "MultiGpuDisplayOwner", NV_CTRL_MULTIGPU_DISPLAY_OWNER, N, "GPU ID of the GPU that has the display device(s) used for showing the X screen." }, - { "HWOverlay", NV_CTRL_HWOVERLAY, 0, "When a workstation overlay is in use, this value is 1 if the hardware overlay is used, or 0 if the overlay is emulated." }, - { "OnDemandVBlankInterrupts", NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS, 0, "Enable/Disable/Query of on-demand vertical blanking interrupt control on the GPU. The 'OnDemandVBlankInterrupts' X server configuration option must be enabled for this option to be available." }, - { "GlyphCache", NV_CTRL_GLYPH_CACHE, N, "Enable or disable caching of glyphs (text) in video memory." }, - { "SwitchToDisplays", NV_CTRL_SWITCH_TO_DISPLAYS, D|N|W, "Used to set which displays should be active." }, - { "NotebookDisplayChangeLidEvent", NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT, N, "Reports notebook lid open/close events." }, - { "NotebookInternalLCD", NV_CTRL_NOTEBOOK_INTERNAL_LCD, N|D, "DEPRECATED." }, - { "Depth30Allowed", NV_CTRL_DEPTH_30_ALLOWED, N, "Returns whether the NVIDIA X driver supports depth 30 on the specified X screen or GPU." }, - { "NoScanout", NV_CTRL_NO_SCANOUT, N, "Returns whether the special \"NoScanout\" mode is enabled on the specified X screen or GPU." }, - { "XServerUniqueId", NV_CTRL_X_SERVER_UNIQUE_ID, N, "Returns a pseudo-unique identification number for the X server." }, - { "PixmapCache", NV_CTRL_PIXMAP_CACHE, N, "Controls whether pixmaps are allocated in a cache." }, - { "PixmapCacheRoundSizeKB", NV_CTRL_PIXMAP_CACHE_ROUNDING_SIZE_KB, N, "Controls the number of kilobytes to add to the pixmap cache when there is not enough room." }, - { "AccelerateTrapezoids", NV_CTRL_ACCELERATE_TRAPEZOIDS, N, "Enable or disable GPU acceleration of RENDER Trapezoids." }, + { "Ubb", NV_CTRL_UBB, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Is UBB enabled for the specified X screen." }, + { "Overlay", NV_CTRL_OVERLAY, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Is the RGB overlay enabled for the specified X screen." }, + { "Stereo", NV_CTRL_STEREO, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The stereo mode for the specified X screen." }, + { "TwinView", NV_CTRL_TWINVIEW, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Is TwinView enabled for the specified X screen." }, + { "ConnectedDisplays", NV_CTRL_CONNECTED_DISPLAYS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"-q dpys\" instead." }, + { "EnabledDisplays", NV_CTRL_ENABLED_DISPLAYS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"-q dpys\" instead." }, + { "AssociatedDisplays", NV_CTRL_ASSOCIATED_DISPLAY_DEVICES, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"-q xscreens -V all\" instead." }, + { "ProbeDisplays", NV_CTRL_PROBE_DISPLAYS, INT_ATTR, {0,0,0,0,0,1}, { .int_flags = {0,0,0,1,0,0,0} }, "When this attribute is queried, the X driver re-probes the hardware to detect which display devices are connected to the GPU or DPU driving the specified X screen." }, + { "InitialPixmapPlacement", NV_CTRL_INITIAL_PIXMAP_PLACEMENT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls where X pixmaps are initially created." }, + { "MultiGpuDisplayOwner", NV_CTRL_MULTIGPU_DISPLAY_OWNER, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "GPU ID of the GPU that has the display device(s) used for showing the X screen." }, + { "HWOverlay", NV_CTRL_HWOVERLAY, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When a workstation overlay is in use, this value is 1 if the hardware overlay is used, or 0 if the overlay is emulated." }, + { "OnDemandVBlankInterrupts", NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable/Disable/Query of on-demand vertical blanking interrupt control on the GPU. The 'OnDemandVBlankInterrupts' X server configuration option must be enabled for this option to be available." }, + { "GlyphCache", NV_CTRL_GLYPH_CACHE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable or disable caching of glyphs (text) in video memory." }, + { "SwitchToDisplays", NV_CTRL_SWITCH_TO_DISPLAYS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,1} }, "Used to set which displays should be active." }, + { "NotebookDisplayChangeLidEvent", NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports notebook lid open/close events." }, + { "NotebookInternalLCD", NV_CTRL_NOTEBOOK_INTERNAL_LCD, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED." }, + { "Depth30Allowed", NV_CTRL_DEPTH_30_ALLOWED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether the NVIDIA X driver supports depth 30 on the specified X screen or GPU." }, + { "NoScanout", NV_CTRL_NO_SCANOUT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether the special \"NoScanout\" mode is enabled on the specified X screen or GPU." }, + { "XServerUniqueId", NV_CTRL_X_SERVER_UNIQUE_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns a pseudo-unique identification number for the X server." }, + { "PixmapCache", NV_CTRL_PIXMAP_CACHE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls whether pixmaps are allocated in a cache." }, + { "PixmapCacheRoundSizeKB", NV_CTRL_PIXMAP_CACHE_ROUNDING_SIZE_KB, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the number of kilobytes to add to the pixmap cache when there is not enough room." }, + { "AccelerateTrapezoids", NV_CTRL_ACCELERATE_TRAPEZOIDS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable or disable GPU acceleration of RENDER Trapezoids." }, + { "ScreenPosition", NV_CTRL_STRING_SCREEN_RECTANGLE, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the physical X Screen's initial position and size (in absolute coordinates) within the desktop as the \"token=value \" string: \"x=#, y=#, width=#, height=#\"." }, + { "AddMetaMode", NV_CTRL_STRING_OPERATION_ADD_METAMODE, SOP_ATTR, {0,0,0,0,1,1}, {}, "Adds the given MetaMode to the X screen." }, + { "ParseMetaMode", NV_CTRL_STRING_OPERATION_ADD_METAMODE, SOP_ATTR, {0,0,0,0,1,1}, {}, "Parses and validates a given MetaMode." }, /* OpenGL */ - { "SyncToVBlank", NV_CTRL_SYNC_TO_VBLANK, 0, "Enables sync to vertical blanking for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." }, - { "LogAniso", NV_CTRL_LOG_ANISO, 0, "Enables anisotropic filtering for OpenGL clients; on some NVIDIA hardware, this can only be enabled or disabled; on other hardware different levels of anisotropic filtering can be specified. This setting only takes effect on OpenGL clients started after it is set." }, - { "FSAA", NV_CTRL_FSAA_MODE, 0, "The full screen antialiasing setting for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set. Enabling antialiasing will disable FXAA." }, - { "TextureSharpen", NV_CTRL_TEXTURE_SHARPEN, 0, "Enables texture sharpening for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." }, - { "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, N, "Inhibit the use of CPU-specific features such as MMX, SSE, or 3DNOW! for OpenGL clients; this option may result in performance loss, but may be useful in conjunction with software such as the Valgrind memory debugger. This setting only takes effect on OpenGL clients started after it is set." }, - { "GammaCorrectedAALines", NV_CTRL_OPENGL_AA_LINE_GAMMA, 0, "For OpenGL clients, allow gamma-corrected antialiased lines to consider variances in the color display capabilities of output devices when rendering smooth lines. Only available on recent Quadro GPUs. This setting only takes effect on OpenGL clients started after it is set." }, - { "TextureClamping", NV_CTRL_TEXTURE_CLAMPING, 0, "Define the behavior of OpenGL texture clamping for unbordered textures. If enabled (1), the conformant behavior is used. If disabled (0), GL_CLAMP is remapped to GL_CLAMP_TO_EDGE to avoid seams in applications that rely on this behavior, which was the only option in some very old hardware." }, - { "FXAA", NV_CTRL_FXAA, 0, "Enables or disables the use of FXAA, Fast Approximate Anti-Aliasing. Enabling FXAA will disable regular antialiasing modes." }, - - { "AllowFlipping", NV_CTRL_FLIPPING_ALLOWED, 0, "Defines the swap behavior of OpenGL. When 1, OpenGL will swap by flipping when possible; When 0, OpenGL will always swap by blitting." }, - { "FSAAAppControlled", NV_CTRL_FSAA_APPLICATION_CONTROLLED, 0, "When Application Control for FSAA is enabled, then what the application requests is used, and the FSAA attribute is ignored. If this is disabled, then any application setting is overridden with the FSAA attribute." }, - { "LogAnisoAppControlled", NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED, 0, "When Application Control for LogAniso is enabled, then what the application requests is used, and the LogAniso attribute is ignored. If this is disabled, then any application setting is overridden with the LogAniso attribute." }, - { "ForceStereoFlipping", NV_CTRL_FORCE_STEREO, 0, "When 1, OpenGL will force stereo flipping even when no stereo drawables are visible (if the device is configured to support it, see the \"Stereo\" X config option). When 0, fall back to the default behavior of only flipping when a stereo drawable is visible." }, - { "OpenGLImageSettings", NV_CTRL_IMAGE_SETTINGS, 0, "The image quality setting for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." }, - { "XineramaStereoFlipping", NV_CTRL_XINERAMA_STEREO, 0, "When 1, OpenGL will allow stereo flipping on multiple X screens configured with Xinerama. When 0, flipping is allowed only on one X screen at a time." }, - { "ShowSLIHUD", NV_CTRL_SHOW_SLI_HUD, 0, "If this is enabled (1), the driver will draw information about the current SLI mode into a \"heads-up display\" inside OpenGL windows accelerated with SLI. This setting only takes effect on OpenGL clients started after it is set." }, - { "ShowSLIVisualIndicator", NV_CTRL_SHOW_SLI_VISUAL_INDICATOR, 0, "If this is enabled (1), the driver will draw information about the current SLI mode into a \"visual indicator\" inside OpenGL windows accelerated with SLI. This setting only takes effect on OpenGL clients started after it is set." }, - { "ShowMultiGpuVisualIndicator", NV_CTRL_SHOW_MULTIGPU_VISUAL_INDICATOR, 0, "If this is enabled (1), the driver will draw information about the current MultiGPU mode into a \"visual indicator\" inside OpenGL windows accelerated with SLI. This setting only takes effect on OpenGL clients started after it is set." }, - { "FSAAAppEnhanced", NV_CTRL_FSAA_APPLICATION_ENHANCED, 0, "Controls how the FSAA attribute is applied when FSAAAppControlled is disabled. When FSAAAppEnhanced is disabled, OpenGL applications will be forced to use the FSAA mode specified by the FSAA attribute. When the FSAAAppEnhanced attribute is enabled, only those applications that have selected a multisample FBConfig will be made to use the FSAA mode specified." }, - { "GammaCorrectedAALinesValue", NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE, 0, "Returns the gamma value used by OpenGL when gamma-corrected antialiased lines are enabled." }, - { "StereoEyesExchange", NV_CTRL_STEREO_EYES_EXCHANGE, 0, "Swaps the left and right eyes of stereo images." }, - { "SLIMode", NV_CTRL_STRING_SLI_MODE, S|N, "Returns a string describing the current SLI mode, if any." }, - { "SliMosaicModeAvailable", NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE, N, "Returns whether or not SLI Mosaic Mode is supported." }, - { "MultiGpuMode", NV_CTRL_STRING_MULTIGPU_MODE, S|N, "Returns a string describing the current MultiGPU mode, if any." }, + { "SyncToVBlank", NV_CTRL_SYNC_TO_VBLANK, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables sync to vertical blanking for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." }, + { "LogAniso", NV_CTRL_LOG_ANISO, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables anisotropic filtering for OpenGL clients; on some NVIDIA hardware, this can only be enabled or disabled; on other hardware different levels of anisotropic filtering can be specified. This setting only takes effect on OpenGL clients started after it is set." }, + { "FSAA", NV_CTRL_FSAA_MODE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The full screen antialiasing setting for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set. Enabling antialiasing will disable FXAA." }, + { "TextureSharpen", NV_CTRL_TEXTURE_SHARPEN, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables texture sharpening for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." }, + { "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Inhibit the use of CPU-specific features such as MMX, SSE, or 3DNOW! for OpenGL clients; this option may result in performance loss, but may be useful in conjunction with software such as the Valgrind memory debugger. This setting only takes effect on OpenGL clients started after it is set." }, + { "GammaCorrectedAALines", NV_CTRL_OPENGL_AA_LINE_GAMMA, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "For OpenGL clients, allow gamma-corrected antialiased lines to consider variances in the color display capabilities of output devices when rendering smooth lines. Only available on recent Quadro GPUs. This setting only takes effect on OpenGL clients started after it is set." }, + { "TextureClamping", NV_CTRL_TEXTURE_CLAMPING, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Define the behavior of OpenGL texture clamping for unbordered textures. If enabled (1), the conformant behavior is used. If disabled (0), GL_CLAMP is remapped to GL_CLAMP_TO_EDGE to avoid seams in applications that rely on this behavior, which was the only option in some very old hardware." }, + { "FXAA", NV_CTRL_FXAA, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables or disables the use of FXAA, Fast Approximate Anti-Aliasing. Enabling FXAA will disable regular antialiasing modes." }, + { "AllowFlipping", NV_CTRL_FLIPPING_ALLOWED, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Defines the swap behavior of OpenGL. When 1, OpenGL will swap by flipping when possible; When 0, OpenGL will always swap by blitting." }, + { "FSAAAppControlled", NV_CTRL_FSAA_APPLICATION_CONTROLLED, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When Application Control for FSAA is enabled, then what the application requests is used, and the FSAA attribute is ignored. If this is disabled, then any application setting is overridden with the FSAA attribute." }, + { "LogAnisoAppControlled", NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When Application Control for LogAniso is enabled, then what the application requests is used, and the LogAniso attribute is ignored. If this is disabled, then any application setting is overridden with the LogAniso attribute." }, + { "ForceStereoFlipping", NV_CTRL_FORCE_STEREO, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When 1, OpenGL will force stereo flipping even when no stereo drawables are visible (if the device is configured to support it, see the \"Stereo\" X config option). When 0, fall back to the default behavior of only flipping when a stereo drawable is visible." }, + { "OpenGLImageSettings", NV_CTRL_IMAGE_SETTINGS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The image quality setting for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." }, + { "XineramaStereoFlipping", NV_CTRL_XINERAMA_STEREO, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When 1, OpenGL will allow stereo flipping on multiple X screens configured with Xinerama. When 0, flipping is allowed only on one X screen at a time." }, + { "ShowSLIHUD", NV_CTRL_SHOW_SLI_HUD, 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 information about the current SLI mode into a \"heads-up display\" inside OpenGL windows accelerated with SLI. This setting only takes effect on OpenGL clients started after it is set." }, + { "ShowSLIVisualIndicator", NV_CTRL_SHOW_SLI_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 information about the current SLI mode into a \"visual indicator\" inside OpenGL windows accelerated with SLI. This setting only takes effect on OpenGL clients started after it is set." }, + { "ShowMultiGpuVisualIndicator", NV_CTRL_SHOW_MULTIGPU_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 information about the current MultiGPU mode into a \"visual indicator\" inside OpenGL windows accelerated with SLI. This setting only takes effect on OpenGL clients started after it is set." }, + { "FSAAAppEnhanced", NV_CTRL_FSAA_APPLICATION_ENHANCED, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls how the FSAA attribute is applied when FSAAAppControlled is disabled. When FSAAAppEnhanced is disabled, OpenGL applications will be forced to use the FSAA mode specified by the FSAA attribute. When the FSAAAppEnhanced attribute is enabled, only those applications that have selected a multisample FBConfig will be made to use the FSAA mode specified." }, + { "GammaCorrectedAALinesValue", NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the gamma value used by OpenGL when gamma-corrected antialiased lines are enabled." }, + { "StereoEyesExchange", NV_CTRL_STEREO_EYES_EXCHANGE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Swaps the left and right eyes of stereo images." }, + { "SliMosaicModeAvailable", NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether or not SLI Mosaic Mode is supported." }, + { "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." }, /* GPU */ - { "BusType", NV_CTRL_BUS_TYPE, N, "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." }, - { "PCIEMaxLinkSpeed", NV_CTRL_GPU_PCIE_MAX_LINK_SPEED, N, "Returns the maximum speed that the PCIe link between the GPU and the system may be trained to. This is expressed in gigatransfers per second (GT/s). The link may be dynamically trained to a slower speed, based on the GPU's utilization and performance settings." }, - { "PCIEMaxLinkWidth", NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH, N, "Returns the maximum width that the PCIe link between the GPU and the system may be trained to. This is expressed in number of lanes. The trained link width may vary dynamically and possibly be narrower based on the GPU's utilization and performance settings." }, - { "PCIECurrentLinkSpeed", NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED, N, "Returns the current PCIe link speed, in gigatransfers per second (GT/s)." }, - { "PCIECurrentLinkWidth", NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH, N, "Returns the current PCIe link width of the GPU, in number of lanes." }, - { "VideoRam", NV_CTRL_VIDEO_RAM, N, "Returns the total amount of memory available to the specified GPU (or the GPU driving the specified X screen). Note: if the GPU supports TurboCache(TM), the value reported may exceed the amount of video memory installed on the GPU. The value reported for integrated GPUs may likewise exceed the amount of dedicated system memory set aside by the system BIOS for use by the integrated GPU." }, - { "TotalDedicatedGPUMemory",NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY, N, "Returns the amount of total dedicated memory on the specified GPU in MB." }, - { "UsedDedicatedGPUMemory", NV_CTRL_USED_DEDICATED_GPU_MEMORY, N, "Returns the amount of dedicated memory used on the specified GPU in MB." }, - { "Irq", NV_CTRL_IRQ, N, "Returns the interrupt request line used by the specified device. If the target is an X screen, then it uses the GPU driving the X screen as the device." }, - { "CUDACores", NV_CTRL_GPU_CORES, N, "Returns number of CUDA cores supported by the graphics pipeline." }, - { "GPUMemoryInterface", NV_CTRL_GPU_MEMORY_BUS_WIDTH, N, "Returns bus bandwidth of the GPU's memory interface." }, - { "GPUCoreTemp", NV_CTRL_GPU_CORE_TEMPERATURE, N, "Reports the current core temperature in Celsius of the GPU driving the X screen." }, - { "GPUAmbientTemp", NV_CTRL_AMBIENT_TEMPERATURE, N, "Reports the current temperature in Celsius of the immediate neighborhood of the GPU driving the X screen." }, - { "GPUOverclockingState", NV_CTRL_GPU_OVERCLOCKING_STATE, N, "The current overclocking state; the value of this attribute controls the availability of additional overclocking attributes. Note that this attribute is unavailable unless overclocking support has been enabled by the system administrator." }, - { "GPU2DClockFreqs", NV_CTRL_GPU_2D_CLOCK_FREQS, N|P, "The GPU and memory clock frequencies when operating in 2D mode. New clock frequencies are tested before being applied, and may be rejected. Note that if the target clocks are too aggressive, their testing may render the system unresponsive. Also note that while this attribute may always be queried, it cannot be set unless GPUOverclockingState is set to MANUAL. Since the target clocks may be rejected, the requester should read this attribute after the set to determine success or failure." }, - { "GPU3DClockFreqs", NV_CTRL_GPU_3D_CLOCK_FREQS, N|P, "The GPU and memory clock frequencies when operating in 3D mode. New clock frequencies are tested before being applied, and may be rejected. Note that if the target clocks are too aggressive, their testing may render the system unresponsive. Also note that while this attribute may always be queried, it cannot be set unless GPUOverclockingState is set to MANUAL. Since the target clocks may be rejected, the requester should read this attribute after the set to determine success or failure." }, - { "GPUDefault2DClockFreqs", NV_CTRL_GPU_DEFAULT_2D_CLOCK_FREQS, N|P, "Returns the default memory and GPU core clocks when operating in 2D mode." }, - { "GPUDefault3DClockFreqs", NV_CTRL_GPU_DEFAULT_3D_CLOCK_FREQS, N|P, "Returns the default memory and GPU core clocks when operating in 3D mode." }, - { "GPUCurrentClockFreqs", NV_CTRL_GPU_CURRENT_CLOCK_FREQS, N|P, "Returns the current GPU and memory clocks of the graphics device driving the X screen." }, - { "GPUCurrentProcessorClockFreqs", NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS, N, "Returns the current processor clock of the graphics device driving the X screen." }, - { "GPUCurrentClockFreqsString", NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS, S|N, "Returns the current GPU, memory and Processor clocks of the graphics device driving the X screen." }, - { "BusRate", NV_CTRL_BUS_RATE, N, "If the device is on an AGP bus, then BusRate returns the configured AGP rate. If the device is on a PCI Express bus, then this attribute returns the width of the physical link." }, - { "PCIDomain", NV_CTRL_PCI_DOMAIN, N, "Returns the PCI domain number for the specified device." }, - { "PCIBus", NV_CTRL_PCI_BUS, N, "Returns the PCI bus number for the specified device." }, - { "PCIDevice", NV_CTRL_PCI_DEVICE, N, "Returns the PCI device number for the specified device." }, - { "PCIFunc", NV_CTRL_PCI_FUNCTION, N, "Returns the PCI function number for the specified device." }, - { "PCIID", NV_CTRL_PCI_ID, N|P, "Returns the PCI vendor and device ID of the specified device." }, - { "PCIEGen", NV_CTRL_GPU_PCIE_GENERATION, N, "Returns the PCIe generation that this GPU, in this system, is compliant with." }, - { "GPUErrors", NV_CTRL_NUM_GPU_ERRORS_RECOVERED, N, "Returns the number of GPU errors occurred." }, - { "GPUPowerSource", NV_CTRL_GPU_POWER_SOURCE, N, "Reports the type of power source of the GPU." }, - { "GPUCurrentPerfMode", NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, N, "Reports the current performance mode of the GPU driving the X screen. Running a 3D app, for example, will change this performance mode if Adaptive Clocking is enabled." }, - { "GPUCurrentPerfLevel", NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, N, "Reports the current Performance level of the GPU driving the X screen. Each Performance level has associated NVClock and Mem Clock values." }, - { "GPUAdaptiveClockState", NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, N, "Reports if Adaptive Clocking is Enabled on the GPU driving the X screen." }, - { "GPUPerfModes", NV_CTRL_STRING_PERFORMANCE_MODES, S|N, "Returns a string with all the performance modes defined for this GPU along with their associated NV Clock and Memory Clock values." }, - { "GPUPowerMizerMode", NV_CTRL_GPU_POWER_MIZER_MODE, 0, "Allows setting different GPU powermizer modes." }, - { "GPUPowerMizerDefaultMode", NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE, N, "Reports the default powermizer mode of the GPU, if any." }, - { "ECCSupported", NV_CTRL_GPU_ECC_SUPPORTED, N, "Reports whether the underlying GPU supports ECC. All of the other ECC attributes are only applicable if this attribute indicates that ECC is supported." }, - { "ECCStatus", NV_CTRL_GPU_ECC_STATUS, N, "Reports whether ECC is enabled." }, - { "GPULogoBrightness", NV_CTRL_GPU_LOGO_BRIGHTNESS, 0, "Controls brightness of the logo on the GPU, if any. The value is variable from 0% - 100%." }, - { "GPUSLIBridgeLogoBrightness", NV_CTRL_GPU_SLI_LOGO_BRIGHTNESS, 0, "Controls brightness of the logo on the SLI bridge, if any. The value is variable from 0% - 100%." }, - { "ECCConfigurationSupported", NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED, N, "Reports whether ECC whether the ECC configuration setting can be changed." }, - { "ECCConfiguration", NV_CTRL_GPU_ECC_CONFIGURATION, N, "Returns the current ECC configuration setting." }, - { "ECCDefaultConfiguration", NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION, N, "Returns the default ECC configuration setting." }, - { "ECCDoubleBitErrors", NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS, N, "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, N, "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, N, "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, N, "Returns the GPU fan's currently programmed speed, as a percentage of the maximum speed." }, - { "GPUResetFanSpeed", NV_CTRL_THERMAL_COOLER_LEVEL_SET_DEFAULT, N, "Resets the GPU fan's speed to its default." }, - { "GPUCurrentFanSpeedRPM", NV_CTRL_THERMAL_COOLER_SPEED, N, "Returns the GPU fan's tachometer-measured speed in rotations per minute (RPM)." }, - { "GPUFanControlType", NV_CTRL_THERMAL_COOLER_CONTROL_TYPE, N, "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." }, - { "GPUFanTarget", NV_CTRL_THERMAL_COOLER_TARGET, N, "Returns the objects the fan cools. '1' means the GPU, '2' means video memory, '4' means the power supply, and '7' means all of the above." }, - { "ThermalSensorReading", NV_CTRL_THERMAL_SENSOR_READING, N, "Returns the thermal sensor's current reading." }, - { "ThermalSensorProvider", NV_CTRL_THERMAL_SENSOR_PROVIDER, N, "Returns the hardware device that provides the thermal sensor." }, - { "ThermalSensorTarget", NV_CTRL_THERMAL_SENSOR_TARGET, N, "Returns what hardware component the thermal sensor is measuring." }, - { "GPUDoublePrecisionBoostImmediate", NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_IMMEDIATE, N, "Toggles GPU double precision; the change is applied immediately. Only available when the change can be made immediately." }, - { "GPUDoublePrecisionBoostReboot", NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_REBOOT, N, "Toggles GPU double precision; the change is applied on the next reboot. Only available when the change requires a reboot." }, - { "BaseMosaic", NV_CTRL_BASE_MOSAIC, N, "Returns the current Base Mosaic configuration." }, - { "GpuUUID", NV_CTRL_STRING_GPU_UUID, S|N, "Returns the global unique identifier of the GPU." }, - { "MultiGpuMasterPossible", NV_CTRL_MULTIGPU_MASTER_POSSIBLE, N, "Returns whether or not the GPU can be configured as the master GPU for a Multi GPU configuration (SLI, SLI Mosaic, Base Mosaic, ...)." }, + { "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." }, + { "PCIEMaxLinkSpeed", NV_CTRL_GPU_PCIE_MAX_LINK_SPEED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the maximum speed that the PCIe link between the GPU and the system may be trained to. This is expressed in gigatransfers per second (GT/s). The link may be dynamically trained to a slower speed, based on the GPU's utilization and performance settings." }, + { "PCIEMaxLinkWidth", NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the maximum width that the PCIe link between the GPU and the system may be trained to. This is expressed in number of lanes. The trained link width may vary dynamically and possibly be narrower based on the GPU's utilization and performance settings." }, + { "PCIECurrentLinkSpeed", NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current PCIe link speed, in gigatransfers per second (GT/s)." }, + { "PCIECurrentLinkWidth", NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current PCIe link width of the GPU, in number of lanes." }, + { "VideoRam", NV_CTRL_VIDEO_RAM, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the total amount of memory available to the specified GPU (or the GPU driving the specified X screen). Note: if the GPU supports TurboCache(TM), the value reported may exceed the amount of video memory installed on the GPU. The value reported for integrated GPUs may likewise exceed the amount of dedicated system memory set aside by the system BIOS for use by the integrated GPU." }, + { "TotalDedicatedGPUMemory", NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the amount of total dedicated memory on the specified GPU in MB." }, + { "UsedDedicatedGPUMemory", NV_CTRL_USED_DEDICATED_GPU_MEMORY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the amount of dedicated memory used on the specified GPU in MB." }, + { "Irq", NV_CTRL_IRQ, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the interrupt request line used by the specified device. If the target is an X screen, then it uses the GPU driving the X screen as the device." }, + { "CUDACores", NV_CTRL_GPU_CORES, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns number of CUDA cores supported by the graphics pipeline." }, + { "GPUMemoryInterface", NV_CTRL_GPU_MEMORY_BUS_WIDTH, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns bus bandwidth of the GPU's memory interface." }, + { "GPUCoreTemp", NV_CTRL_GPU_CORE_TEMPERATURE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the current core temperature in Celsius of the GPU driving the X screen." }, + { "GPUAmbientTemp", NV_CTRL_AMBIENT_TEMPERATURE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the current temperature in Celsius of the immediate neighborhood of the GPU driving the X screen." }, + { "GPUOverclockingState", NV_CTRL_GPU_OVERCLOCKING_STATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The current overclocking state; the value of this attribute controls the availability of additional overclocking attributes. Note that this attribute is unavailable unless overclocking support has been enabled by the system administrator." }, + { "GPU2DClockFreqs", NV_CTRL_GPU_2D_CLOCK_FREQS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "The GPU and memory clock frequencies when operating in 2D mode. New clock frequencies are tested before being applied, and may be rejected. Note that if the target clocks are too aggressive, their testing may render the system unresponsive. Also note that while this attribute may always be queried, it cannot be set unless GPUOverclockingState is set to MANUAL. Since the target clocks may be rejected, the requester should read this attribute after the set to determine success or failure." }, + { "GPU3DClockFreqs", NV_CTRL_GPU_3D_CLOCK_FREQS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "The GPU and memory clock frequencies when operating in 3D mode. New clock frequencies are tested before being applied, and may be rejected. Note that if the target clocks are too aggressive, their testing may render the system unresponsive. Also note that while this attribute may always be queried, it cannot be set unless GPUOverclockingState is set to MANUAL. Since the target clocks may be rejected, the requester should read this attribute after the set to determine success or failure." }, + { "GPUDefault2DClockFreqs", NV_CTRL_GPU_DEFAULT_2D_CLOCK_FREQS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the default memory and GPU core clocks when operating in 2D mode." }, + { "GPUDefault3DClockFreqs", NV_CTRL_GPU_DEFAULT_3D_CLOCK_FREQS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the default memory and GPU core clocks when operating in 3D mode." }, + { "GPUCurrentClockFreqs", NV_CTRL_GPU_CURRENT_CLOCK_FREQS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the current GPU and memory clocks of the graphics device driving the X screen." }, + { "GPUCurrentProcessorClockFreqs", NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current processor clock of the graphics device driving the X screen." }, + { "BusRate", NV_CTRL_BUS_RATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "If the device is on an AGP bus, then BusRate returns the configured AGP rate. If the device is on a PCI Express bus, then this attribute returns the width of the physical link." }, + { "PCIDomain", NV_CTRL_PCI_DOMAIN, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the PCI domain number for the specified device." }, + { "PCIBus", NV_CTRL_PCI_BUS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the PCI bus number for the specified device." }, + { "PCIDevice", NV_CTRL_PCI_DEVICE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the PCI device number for the specified device." }, + { "PCIFunc", NV_CTRL_PCI_FUNCTION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the PCI function number for the specified device." }, + { "PCIID", NV_CTRL_PCI_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the PCI vendor and device ID of the specified device." }, + { "PCIEGen", NV_CTRL_GPU_PCIE_GENERATION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the PCIe generation that this GPU, in this system, is compliant with." }, + { "GPUErrors", NV_CTRL_NUM_GPU_ERRORS_RECOVERED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of GPU errors occurred." }, + { "GPUPowerSource", NV_CTRL_GPU_POWER_SOURCE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the type of power source of the GPU." }, + { "GPUCurrentPerfMode", NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the current performance mode of the GPU driving the X screen. Running a 3D app, for example, will change this performance mode if Adaptive Clocking is enabled." }, + { "GPUCurrentPerfLevel", NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the current Performance level of the GPU driving the X screen. Each Performance level has associated NVClock and Mem Clock values." }, + { "GPUAdaptiveClockState", NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports if Adaptive Clocking is Enabled on the GPU driving the X screen." }, + { "GPUPowerMizerMode", NV_CTRL_GPU_POWER_MIZER_MODE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Allows setting different GPU powermizer modes." }, + { "GPUPowerMizerDefaultMode", NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the default powermizer mode of the GPU, if any." }, + { "ECCSupported", NV_CTRL_GPU_ECC_SUPPORTED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports whether the underlying GPU supports ECC. All of the other ECC attributes are only applicable if this attribute indicates that ECC is supported." }, + { "ECCStatus", NV_CTRL_GPU_ECC_STATUS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports whether ECC is enabled." }, + { "GPULogoBrightness", NV_CTRL_GPU_LOGO_BRIGHTNESS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls brightness of the logo on the GPU, if any. The value is variable from 0% - 100%." }, + { "GPUSLIBridgeLogoBrightness", NV_CTRL_GPU_SLI_LOGO_BRIGHTNESS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls brightness of the logo on the SLI bridge, if any. The value is variable from 0% - 100%." }, + { "ECCConfigurationSupported", NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports whether ECC whether the ECC configuration setting can be changed." }, + { "ECCConfiguration", NV_CTRL_GPU_ECC_CONFIGURATION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current ECC configuration setting." }, + { "ECCDefaultConfiguration", NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the default ECC configuration setting." }, + { "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." }, + { "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." }, + { "GPUFanTarget", NV_CTRL_THERMAL_COOLER_TARGET, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the objects the fan cools. '1' means the GPU, '2' means video memory, '4' means the power supply, and '7' means all of the above." }, + { "ThermalSensorReading", NV_CTRL_THERMAL_SENSOR_READING, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the thermal sensor's current reading." }, + { "ThermalSensorProvider", NV_CTRL_THERMAL_SENSOR_PROVIDER, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the hardware device that provides the thermal sensor." }, + { "ThermalSensorTarget", NV_CTRL_THERMAL_SENSOR_TARGET, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns what hardware component the thermal sensor is measuring." }, + { "GPUDoublePrecisionBoostImmediate", NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_IMMEDIATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Toggles GPU double precision; the change is applied immediately. Only available when the change can be made immediately." }, + { "GPUDoublePrecisionBoostReboot", NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_REBOOT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Toggles GPU double precision; the change is applied on the next reboot. Only available when the change requires a reboot." }, + { "BaseMosaic", NV_CTRL_BASE_MOSAIC, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current Base Mosaic configuration." }, + { "MultiGpuMasterPossible", NV_CTRL_MULTIGPU_MASTER_POSSIBLE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether or not the GPU can be configured as the master GPU for a Multi GPU configuration (SLI, SLI Mosaic, Base Mosaic, ...)." }, + { "GPUCurrentClockFreqsString", NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the current GPU, memory and Processor clocks of the graphics device driving the X screen." }, + { "GPUPerfModes", NV_CTRL_STRING_PERFORMANCE_MODES, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns a string with all the performance modes defined for this GPU along with their associated NV Clock and Memory Clock values." }, + { "GpuUUID", NV_CTRL_STRING_GPU_UUID, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the global unique identifier of the GPU." }, + { "GPUUtilization", NV_CTRL_STRING_GPU_UTILIZATION, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the current percentage utilization of the GPU components." }, /* Framelock */ - { "FrameLockAvailable", NV_CTRL_FRAMELOCK, N|F|G, "Returns whether the underlying GPU supports Frame Lock. All of the other frame lock attributes are only applicable if this attribute is enabled (Supported)." }, - { "FrameLockMaster", NV_CTRL_FRAMELOCK_MASTER, N|F|G|D, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, - { "FrameLockPolarity", NV_CTRL_FRAMELOCK_POLARITY, N|F|G, "Sync to the rising edge of the Frame Lock pulse, the falling edge of the Frame Lock pulse, or both." }, - { "FrameLockSyncDelay", NV_CTRL_FRAMELOCK_SYNC_DELAY, N|F|G, "Returns the delay between the frame lock pulse and the GPU sync. This is an 11 bit value which is multiplied by 7.81 to determine the sync delay in microseconds." }, - { "FrameLockSyncInterval", NV_CTRL_FRAMELOCK_SYNC_INTERVAL, N|F|G, "This defines the number of house sync pulses for each Frame Lock sync period. This only applies to the server, and only when recieving house sync. A value of zero means every house sync pulse is one frame period." }, - { "FrameLockPort0Status", NV_CTRL_FRAMELOCK_PORT0_STATUS, N|F|G, "Input/Output status of the RJ45 port0." }, - { "FrameLockPort1Status", NV_CTRL_FRAMELOCK_PORT1_STATUS, N|F|G, "Input/Output status of the RJ45 port1." }, - { "FrameLockHouseStatus", NV_CTRL_FRAMELOCK_HOUSE_STATUS, N|F|G, "Returns whether or not the house sync signal was detected on the BNC connector of the frame lock board." }, - { "FrameLockEnable", NV_CTRL_FRAMELOCK_SYNC, N|F|G, "Enable/disable the syncing of display devices to the frame lock pulse as specified by previous calls to FrameLockMaster and FrameLockSlaves." }, - { "FrameLockSyncReady", NV_CTRL_FRAMELOCK_SYNC_READY, N|F|G, "Reports whether a slave frame lock board is receiving sync, whether or not any display devices are using the signal." }, - { "FrameLockStereoSync", NV_CTRL_FRAMELOCK_STEREO_SYNC, N|F|G, "This indicates that the GPU stereo signal is in sync with the frame lock stereo signal." }, - { "FrameLockTestSignal", NV_CTRL_FRAMELOCK_TEST_SIGNAL, N|F|G, "To test the connections in the sync group, tell the master to enable a test signal, then query port[01] status and sync_ready on all slaves. When done, tell the master to disable the test signal. Test signal should only be manipulated while FrameLockEnable is enabled. The FrameLockTestSignal is also used to reset the Universal Frame Count (as returned by the glXQueryFrameCountNV() function in the GLX_NV_swap_group extension). Note: for best accuracy of the Universal Frame Count, it is recommended to toggle the FrameLockTestSignal on and off after enabling frame lock." }, - { "FrameLockEthDetected", NV_CTRL_FRAMELOCK_ETHERNET_DETECTED, N|F|G, "The frame lock boards are cabled together using regular cat5 cable, connecting to RJ45 ports on the backplane of the card. There is some concern that users may think these are Ethernet ports and connect them to a router/hub/etc. The hardware can detect this and will shut off to prevent damage (either to itself or to the router). FrameLockEthDetected may be called to find out if Ethernet is connected to one of the RJ45 ports. An appropriate error message should then be displayed." }, - { "FrameLockVideoMode", NV_CTRL_FRAMELOCK_VIDEO_MODE, N|F|G, "Get/set what video mode is used to interpret the house sync signal. This should only be set on the master." }, - { "FrameLockSyncRate", NV_CTRL_FRAMELOCK_SYNC_RATE, N|F|G, "Returns the refresh rate that the frame lock board is sending to the GPU, in mHz (Millihertz) (i.e., to get the refresh rate in Hz, divide the returned value by 1000)." }, - { "FrameLockTiming", NV_CTRL_FRAMELOCK_TIMING, N|F|G, "This is 1 when the GPU is both receiving and locked to an input timing signal. Timing information may come from the following places: another frame lock device that is set to master, the house sync signal, or the GPU's internal timing from a display device." }, - { "FramelockUseHouseSync", NV_CTRL_USE_HOUSE_SYNC, N|F|G, "When 1, the server (master) frame lock device will propagate the incoming house sync signal as the outgoing frame lock sync signal. If the frame lock device cannot detect a frame lock sync signal, it will default to using the internal timings from the GPU connected to the primary connector." }, - { "FrameLockSlaves", NV_CTRL_FRAMELOCK_SLAVES, N|F|G|D, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, - { "FrameLockMasterable", NV_CTRL_FRAMELOCK_MASTERABLE, N|F|G|D, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, - { "FrameLockSlaveable", NV_CTRL_FRAMELOCK_SLAVEABLE, N|F|G|D, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, - { "FrameLockFPGARevision", NV_CTRL_FRAMELOCK_FPGA_REVISION, N|F|G, "Returns the FPGA revision of the Frame Lock device." }, - { "FrameLockSyncRate4", NV_CTRL_FRAMELOCK_SYNC_RATE_4, N|F|G, "Returns the refresh rate that the frame lock board is sending to the GPU in 1/10000 Hz (i.e., to get the refresh rate in Hz, divide the returned value by 10000)." }, - { "FrameLockSyncDelayResolution", NV_CTRL_FRAMELOCK_SYNC_DELAY_RESOLUTION, N|F|G, "Returns the number of nanoseconds that one unit of FrameLockSyncDelay corresponds to." }, - { "FrameLockIncomingHouseSyncRate", NV_CTRL_FRAMELOCK_INCOMING_HOUSE_SYNC_RATE, N|F|G, "Returns the rate of the incoming house sync signal to the frame lock board, in mHz (Millihertz) (i.e., to get the house sync rate in Hz, divide the returned value by 1000)." }, - - /* GVO */ - { "GvoSupported", NV_CTRL_GVO_SUPPORTED, I|N, "Returns whether this X screen supports GVO; if this screen does not support GVO output, then all other GVO attributes are unavailable." }, - { "GvoSyncMode", NV_CTRL_GVO_SYNC_MODE, I, "Selects the GVO sync mode; possible values are: FREE_RUNNING - GVO does not sync to any external signal. GENLOCK - the GVO output is genlocked to an incoming sync signal; genlocking locks at hsync. This requires that the output video format exactly match the incoming sync video format. FRAMELOCK - the GVO output is frame locked to an incoming sync signal; frame locking locks at vsync. This requires that the output video format have the same refresh rate as the incoming sync video format." }, - { "GvoSyncSource", NV_CTRL_GVO_SYNC_SOURCE, I, "If the GVO sync mode is set to either GENLOCK or FRAMELOCK, this controls which sync source is used as the incoming sync signal (either Composite or SDI). If the GVO sync mode is FREE_RUNNING, this attribute has no effect." }, - { "GvioRequestedVideoFormat", NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, I, "Specifies the requested output video format for a GVO device, or the requested capture format for a GVI device." }, - { "GvoOutputVideoFormat", NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, I|A, "DEPRECATED: use \"GvioRequestedVideoFormat\" instead." }, - { "GviSyncOutputFormat", NV_CTRL_GVI_SYNC_OUTPUT_FORMAT, I|N, "Returns the output sync signal from the GVI device." }, - { "GvioDetectedVideoFormat", NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, I|N, "Returns the input video format detected by the GVO or GVI device. For GVI devices, the jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, - { "GvoInputVideoFormat", NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, I|N|A, "DEPRECATED: use \"GvioDetectedVideoFormat\" instead." }, - { "GvoDataFormat", NV_CTRL_GVO_DATA_FORMAT, I, "Configures how the data in the source (either the X screen or the GLX pbuffer) is interpreted and displayed by the GVO device." }, - { "GvoCompositeSyncInputDetected", NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED, I|N, "Indicates whether Composite Sync input is detected." }, - { "GvoCompositeSyncInputDetectMode", NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE, I|N, "Get/set the Composite Sync input detect mode." }, - { "GvoSdiSyncInputDetected", NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED, I|N, "Indicates whether SDI Sync input is detected, and what type." }, - { "GvoVideoOutputs", NV_CTRL_GVO_VIDEO_OUTPUTS, I|N, "Indicates which GVO video output connectors are currently transmitting data." }, - { "GvoSyncDelayPixels", NV_CTRL_GVO_SYNC_DELAY_PIXELS, I, "Controls the skew between the input sync and the output sync in numbers of pixels from hsync; this is a 12-bit value. If the GVO Capabilities has the Advanced Sync Skew bit set, then setting this value will set a sync advance instead of a delay." }, - { "GvoSyncDelayLines", NV_CTRL_GVO_SYNC_DELAY_LINES, I, "Controls the skew between the input sync and the output sync in numbers of lines from vsync; this is a 12-bit value. If the GVO Capabilities has the Advanced Sync Skew bit set, then setting this value will set a sync advance instead of a delay." }, - { "GvoInputVideoFormatReacquire", NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE, I|N, "Forces input detection to reacquire the input format." }, - { "GvoGlxLocked", NV_CTRL_GVO_GLX_LOCKED, I|N, "Indicates that GVO configuration is locked by GLX; this occurs when the GLX_NV_video_out function calls glXGetVideoDeviceNV(). All GVO output resources are locked until either glXReleaseVideoDeviceNV() is called or the X Display used when calling glXGetVideoDeviceNV() is closed." }, - { "GvoOverrideHwCsc", NV_CTRL_GVO_OVERRIDE_HW_CSC, I, "Override the SDI hardware's Color Space Conversion with the values controlled through XNVCTRLSetGvoColorConversion() and XNVCTRLGetGvoColorConversion()." }, - { "GvoCapabilities", NV_CTRL_GVO_CAPABILITIES, I|N, "Returns a description of the GVO capabilities that differ between NVIDIA SDI products. This value is a bitmask where each bit indicates whether that capability is available." }, - { "GvoCompositeTermination", NV_CTRL_GVO_COMPOSITE_TERMINATION, I, "Enable or disable 75 ohm termination of the SDI composite input signal." }, - { "GvoFlipQueueSize", NV_CTRL_GVO_FLIP_QUEUE_SIZE, I, "Sets/Returns the GVO flip queue size. This value is used by the GLX_NV_video_out extension to determine the size of the internal flip queue when pbuffers are sent to the video device (via glXSendPbufferToVideoNV()). This attribute is applied to GLX when glXGetVideoDeviceNV() is called by the application." }, - { "GvoLockOwner", NV_CTRL_GVO_LOCK_OWNER, I|N, "Indicates that the GVO device is available or in use (by GLX, Clone Mode, or TwinView)." }, - { "GvoOutputVideoLocked", NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED, I|N, "Returns whether or not the GVO output video is locked to the GPU output signal." }, - { "GvoSyncLockStatus", NV_CTRL_GVO_SYNC_LOCK_STATUS, I|N, "Returns whether or not the GVO device is locked to the input reference signal." }, - { "GvoANCTimeCodeGeneration", NV_CTRL_GVO_ANC_TIME_CODE_GENERATION, I, "Controls whether the GVO device generates time codes in the ANC region of the SDI video output stream." }, - { "GvoComposite", NV_CTRL_GVO_COMPOSITE, I, "Enables/Disables SDI compositing. This attribute is only available when an SDI input source is detected and is in genlock mode." }, - { "GvoCompositeAlphaKey", NV_CTRL_GVO_COMPOSITE_ALPHA_KEY, I, "When SDI compositing is enabled, this enables/disables alpha blending." }, - { "GvoCompositeNumKeyRanges", NV_CTRL_GVO_COMPOSITE_NUM_KEY_RANGES, I|N, "Returns the number of ranges available for each channel (Y/Luma, Cr, and Cb) that are used SDI compositing through color keying." }, - { "GvioFirmwareVersion", NV_CTRL_STRING_GVIO_FIRMWARE_VERSION, I|S|N, "Indicates the version of the firmware on the GVO or GVI device." }, - { "GvoFirmwareVersion", NV_CTRL_STRING_GVIO_FIRMWARE_VERSION, I|S|N|A,"DEPRECATED: use \"GvioFirmwareVersion\" instead." }, - { "GvoSyncToDisplay", NV_CTRL_GVO_SYNC_TO_DISPLAY, I|N, "Controls synchronization of the non-SDI display to the SDI display when both are active." }, - { "GvoFullRangeColor", NV_CTRL_GVO_FULL_RANGE_COLOR, I, "Allow full range color data [4-1019]. If disabled, color data is clamped to [64-940]." }, - { "IsGvoDisplay", NV_CTRL_IS_GVO_DISPLAY, N|D, "Returns whether or not the given display device is driven by the GVO device." }, - { "GvoEnableRGBData", NV_CTRL_GVO_ENABLE_RGB_DATA, I, "Indicates that RGB data is being sent via a PASSTHU mode." }, - { "GvoAudioBlanking", NV_CTRL_GVO_AUDIO_BLANKING, I, "Indicates that the GVO device should drop audio ancillary data packets when frames are repeated." }, - { "GviNumJacks", NV_CTRL_GVI_NUM_JACKS, I|N, "Returns the number of input (BNC) jacks on a GVI device that can read video streams." }, - { "GviMaxLinksPerStream", NV_CTRL_GVI_MAX_LINKS_PER_STREAM, I|N, "Returns the maximum number of links that can make up a stream." }, - { "GviDetectedChannelBitsPerComponent", NV_CTRL_GVI_DETECTED_CHANNEL_BITS_PER_COMPONENT, I|N, "Returns the detected bits per component on the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, - { "GviRequestedStreamBitsPerComponent", NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT, I, "Indicates the number of bits per component for a capture stream." }, - { "GviDetectedChannelComponentSampling", NV_CTRL_GVI_DETECTED_CHANNEL_COMPONENT_SAMPLING, I|N, "Returns the detected sampling format on the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, - { "GviRequestedStreamComponentSampling", NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING, I, "Indicates the sampling format for a capture stream." }, - { "GviRequestedStreamChromaExpand", NV_CTRL_GVI_REQUESTED_STREAM_CHROMA_EXPAND, I, "Indicates whether 4:2:2 -> 4:4:4 chroma expansion is enabled for the capture stream." }, - { "GviDetectedChannelColorSpace", NV_CTRL_GVI_DETECTED_CHANNEL_COLOR_SPACE, I|N, "Returns the detected color space (RGB, YCRCB, etc) for the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, - { "GviDetectedChannelLinkID", NV_CTRL_GVI_DETECTED_CHANNEL_LINK_ID, I|N, "Returns the detected link identifier for the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, - { "GviDetectedChannelSMPTE352Identifier", NV_CTRL_GVI_DETECTED_CHANNEL_SMPTE352_IDENTIFIER, I|N, "Returns the detected 4-byte SMPTE 352 identifier from the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, - { "GviGlobalIdentifier", NV_CTRL_GVI_GLOBAL_IDENTIFIER, I|N, "Returns the global identifier for the given NV-CONTROL GVI device." }, - { "GviMaxChannelsPerJack", NV_CTRL_GVI_MAX_CHANNELS_PER_JACK, I|N, "Returns the maximum supported number of channels per single jack on a GVI device." }, - { "GviMaxStreams", NV_CTRL_GVI_MAX_STREAMS, I|N, "Returns the maximum supported number of streams that can be configured on a GVI device." }, - { "GviNumCaptureSurfaces", NV_CTRL_GVI_NUM_CAPTURE_SURFACES, I|N, "Controls the number of capture buffers for storing incoming video from the GVI device." }, - { "GviBoundGpu", NV_CTRL_GVI_BOUND_GPU, I|N, "Returns the target index of the GPU currently attached to the GVI device." }, - { "GviTestMode", NV_CTRL_GVI_TEST_MODE, I|N, "Enable or disable GVI test mode." }, - { "GvoCSCMatrix", 0, I|M|N, "Sets the GVO Color Space Conversion (CSC) matrix. Accepted values are \"ITU_601\", \"ITU_709\", \"ITU_177\", and \"Identity\"." }, + { "FrameLockAvailable", NV_CTRL_FRAMELOCK, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether the underlying GPU supports Frame Lock. All of the other frame lock attributes are only applicable if this attribute is enabled (Supported)." }, + { "FrameLockMaster", NV_CTRL_FRAMELOCK_MASTER, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, + { "FrameLockPolarity", NV_CTRL_FRAMELOCK_POLARITY, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sync to the rising edge of the Frame Lock pulse, the falling edge of the Frame Lock pulse, or both." }, + { "FrameLockSyncDelay", NV_CTRL_FRAMELOCK_SYNC_DELAY, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the delay between the frame lock pulse and the GPU sync. This is an 11 bit value which is multiplied by 7.81 to determine the sync delay in microseconds." }, + { "FrameLockSyncInterval", NV_CTRL_FRAMELOCK_SYNC_INTERVAL, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "This defines the number of house sync pulses for each Frame Lock sync period. This only applies to the server, and only when recieving house sync. A value of zero means every house sync pulse is one frame period." }, + { "FrameLockPort0Status", NV_CTRL_FRAMELOCK_PORT0_STATUS, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Input/Output status of the RJ45 port0." }, + { "FrameLockPort1Status", NV_CTRL_FRAMELOCK_PORT1_STATUS, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Input/Output status of the RJ45 port1." }, + { "FrameLockHouseStatus", NV_CTRL_FRAMELOCK_HOUSE_STATUS, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether or not the house sync signal was detected on the BNC connector of the frame lock board." }, + { "FrameLockEnable", NV_CTRL_FRAMELOCK_SYNC, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable/disable the syncing of display devices to the frame lock pulse as specified by previous calls to FrameLockMaster and FrameLockSlaves." }, + { "FrameLockSyncReady", NV_CTRL_FRAMELOCK_SYNC_READY, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports whether a slave frame lock board is receiving sync, whether or not any display devices are using the signal." }, + { "FrameLockStereoSync", NV_CTRL_FRAMELOCK_STEREO_SYNC, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "This indicates that the GPU stereo signal is in sync with the frame lock stereo signal." }, + { "FrameLockTestSignal", NV_CTRL_FRAMELOCK_TEST_SIGNAL, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "To test the connections in the sync group, tell the master to enable a test signal, then query port[01] status and sync_ready on all slaves. When done, tell the master to disable the test signal. Test signal should only be manipulated while FrameLockEnable is enabled. The FrameLockTestSignal is also used to reset the Universal Frame Count (as returned by the glXQueryFrameCountNV() function in the GLX_NV_swap_group extension). Note: for best accuracy of the Universal Frame Count, it is recommended to toggle the FrameLockTestSignal on and off after enabling frame lock." }, + { "FrameLockEthDetected", NV_CTRL_FRAMELOCK_ETHERNET_DETECTED, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The frame lock boards are cabled together using regular cat5 cable, connecting to RJ45 ports on the backplane of the card. There is some concern that users may think these are Ethernet ports and connect them to a router/hub/etc. The hardware can detect this and will shut off to prevent damage (either to itself or to the router). FrameLockEthDetected may be called to find out if Ethernet is connected to one of the RJ45 ports. An appropriate error message should then be displayed." }, + { "FrameLockVideoMode", NV_CTRL_FRAMELOCK_VIDEO_MODE, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Get/set what video mode is used to interpret the house sync signal. This should only be set on the master." }, + { "FrameLockSyncRate", NV_CTRL_FRAMELOCK_SYNC_RATE, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the refresh rate that the frame lock board is sending to the GPU, in mHz (Millihertz) (i.e., to get the refresh rate in Hz, divide the returned value by 1000)." }, + { "FrameLockTiming", NV_CTRL_FRAMELOCK_TIMING, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "This is 1 when the GPU is both receiving and locked to an input timing signal. Timing information may come from the following places: another frame lock device that is set to master, the house sync signal, or the GPU's internal timing from a display device." }, + { "FramelockUseHouseSync", NV_CTRL_USE_HOUSE_SYNC, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When 1, the server (master) frame lock device will propagate the incoming house sync signal as the outgoing frame lock sync signal. If the frame lock device cannot detect a frame lock sync signal, it will default to using the internal timings from the GPU connected to the primary connector." }, + { "FrameLockSlaves", NV_CTRL_FRAMELOCK_SLAVES, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, + { "FrameLockMasterable", NV_CTRL_FRAMELOCK_MASTERABLE, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, + { "FrameLockSlaveable", NV_CTRL_FRAMELOCK_SLAVEABLE, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED: use \"FrameLockDisplayConfig\" instead." }, + { "FrameLockFPGARevision", NV_CTRL_FRAMELOCK_FPGA_REVISION, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the FPGA revision of the Frame Lock device." }, + { "FrameLockSyncRate4", NV_CTRL_FRAMELOCK_SYNC_RATE_4, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the refresh rate that the frame lock board is sending to the GPU in 1/10000 Hz (i.e., to get the refresh rate in Hz, divide the returned value by 10000)." }, + { "FrameLockSyncDelayResolution", NV_CTRL_FRAMELOCK_SYNC_DELAY_RESOLUTION, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of nanoseconds that one unit of FrameLockSyncDelay corresponds to." }, + { "FrameLockIncomingHouseSyncRate", NV_CTRL_FRAMELOCK_INCOMING_HOUSE_SYNC_RATE, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the rate of the incoming house sync signal to the frame lock board, in mHz (Millihertz) (i.e., to get the house sync rate in Hz, divide the returned value by 1000)." }, + { "FrameLockDisplayConfig", NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, INT_ATTR, {1,1,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the FrameLock mode of operation for the display device." }, + + /* GVIO */ + { "GvoSupported", NV_CTRL_GVO_SUPPORTED, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether this X screen supports GVO; if this screen does not support GVO output, then all other GVO attributes are unavailable." }, + { "GvoSyncMode", NV_CTRL_GVO_SYNC_MODE, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Selects the GVO sync mode; possible values are: FREE_RUNNING - GVO does not sync to any external signal. GENLOCK - the GVO output is genlocked to an incoming sync signal; genlocking locks at hsync. This requires that the output video format exactly match the incoming sync video format. FRAMELOCK - the GVO output is frame locked to an incoming sync signal; frame locking locks at vsync. This requires that the output video format have the same refresh rate as the incoming sync video format." }, + { "GvoSyncSource", NV_CTRL_GVO_SYNC_SOURCE, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "If the GVO sync mode is set to either GENLOCK or FRAMELOCK, this controls which sync source is used as the incoming sync signal (either Composite or SDI). If the GVO sync mode is FREE_RUNNING, this attribute has no effect." }, + { "GvioRequestedVideoFormat", NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Specifies the requested output video format for a GVO device, or the requested capture format for a GVI device." }, + { "GvoOutputVideoFormat", NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, INT_ATTR, {0,0,1,0,0,1}, { .int_flags = {0,0,0,0,0,0,0} }, "DEPRECATED: use \"GvioRequestedVideoFormat\" instead." }, + { "GviSyncOutputFormat", NV_CTRL_GVI_SYNC_OUTPUT_FORMAT, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the output sync signal from the GVI device." }, + { "GvioDetectedVideoFormat", NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the input video format detected by the GVO or GVI device. For GVI devices, the jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, + { "GvoInputVideoFormat", NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, INT_ATTR, {0,0,1,0,1,1}, { .int_flags = {0,0,0,0,0,0,0} }, "DEPRECATED: use \"GvioDetectedVideoFormat\" instead." }, + { "GvoDataFormat", NV_CTRL_GVO_DATA_FORMAT, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Configures how the data in the source (either the X screen or the GLX pbuffer) is interpreted and displayed by the GVO device." }, + { "GvoCompositeSyncInputDetected", NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates whether Composite Sync input is detected." }, + { "GvoCompositeSyncInputDetectMode", NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Get/set the Composite Sync input detect mode." }, + { "GvoSdiSyncInputDetected", NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates whether SDI Sync input is detected, and what type." }, + { "GvoVideoOutputs", NV_CTRL_GVO_VIDEO_OUTPUTS, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates which GVO video output connectors are currently transmitting data." }, + { "GvoSyncDelayPixels", NV_CTRL_GVO_SYNC_DELAY_PIXELS, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the skew between the input sync and the output sync in numbers of pixels from hsync; this is a 12-bit value. If the GVO Capabilities has the Advanced Sync Skew bit set, then setting this value will set a sync advance instead of a delay." }, + { "GvoSyncDelayLines", NV_CTRL_GVO_SYNC_DELAY_LINES, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the skew between the input sync and the output sync in numbers of lines from vsync; this is a 12-bit value. If the GVO Capabilities has the Advanced Sync Skew bit set, then setting this value will set a sync advance instead of a delay." }, + { "GvoInputVideoFormatReacquire", NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Forces input detection to reacquire the input format." }, + { "GvoGlxLocked", NV_CTRL_GVO_GLX_LOCKED, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "DEPRECATED: use \"GvoLockOwner\" instead." }, + { "GvoOverrideHwCsc", NV_CTRL_GVO_OVERRIDE_HW_CSC, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Override the SDI hardware's Color Space Conversion with the values controlled through XNVCTRLSetGvoColorConversion() and XNVCTRLGetGvoColorConversion()." }, + { "GvoCapabilities", NV_CTRL_GVO_CAPABILITIES, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns a description of the GVO capabilities that differ between NVIDIA SDI products. This value is a bitmask where each bit indicates whether that capability is available." }, + { "GvoCompositeTermination", NV_CTRL_GVO_COMPOSITE_TERMINATION, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable or disable 75 ohm termination of the SDI composite input signal." }, + { "GvoFlipQueueSize", NV_CTRL_GVO_FLIP_QUEUE_SIZE, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets/Returns the GVO flip queue size. This value is used by the GLX_NV_video_out extension to determine the size of the internal flip queue when pbuffers are sent to the video device (via glXSendPbufferToVideoNV()). This attribute is applied to GLX when glXGetVideoDeviceNV() is called by the application." }, + { "GvoLockOwner", NV_CTRL_GVO_LOCK_OWNER, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates that the GVO device is available or in use (by GLX, Clone Mode, or TwinView)." }, + { "GvoOutputVideoLocked", NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether or not the GVO output video is locked to the GPU output signal." }, + { "GvoSyncLockStatus", NV_CTRL_GVO_SYNC_LOCK_STATUS, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether or not the GVO device is locked to the input reference signal." }, + { "GvoANCTimeCodeGeneration", NV_CTRL_GVO_ANC_TIME_CODE_GENERATION, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls whether the GVO device generates time codes in the ANC region of the SDI video output stream." }, + { "GvoComposite", NV_CTRL_GVO_COMPOSITE, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables/Disables SDI compositing. This attribute is only available when an SDI input source is detected and is in genlock mode." }, + { "GvoCompositeAlphaKey", NV_CTRL_GVO_COMPOSITE_ALPHA_KEY, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When SDI compositing is enabled, this enables/disables alpha blending." }, + { "GvoCompositeNumKeyRanges", NV_CTRL_GVO_COMPOSITE_NUM_KEY_RANGES, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of ranges available for each channel (Y/Luma, Cr, and Cb) that are used SDI compositing through color keying." }, + { "GvoSyncToDisplay", NV_CTRL_GVO_SYNC_TO_DISPLAY, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls synchronization of the non-SDI display to the SDI display when both are active." }, + { "GvoFullRangeColor", NV_CTRL_GVO_FULL_RANGE_COLOR, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Allow full range color data [4-1019]. If disabled, color data is clamped to [64-940]." }, + { "IsGvoDisplay", NV_CTRL_IS_GVO_DISPLAY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "Returns whether or not the given display device is driven by the GVO device." }, + { "GvoEnableRGBData", NV_CTRL_GVO_ENABLE_RGB_DATA, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates that RGB data is being sent via a PASSTHU mode." }, + { "GvoAudioBlanking", NV_CTRL_GVO_AUDIO_BLANKING, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates that the GVO device should drop audio ancillary data packets when frames are repeated." }, + { "GviNumJacks", NV_CTRL_GVI_NUM_JACKS, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of input (BNC) jacks on a GVI device that can read video streams." }, + { "GviMaxLinksPerStream", NV_CTRL_GVI_MAX_LINKS_PER_STREAM, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the maximum number of links that can make up a stream." }, + { "GviDetectedChannelBitsPerComponent", NV_CTRL_GVI_DETECTED_CHANNEL_BITS_PER_COMPONENT, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the detected bits per component on the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, + { "GviRequestedStreamBitsPerComponent", NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates the number of bits per component for a capture stream." }, + { "GviDetectedChannelComponentSampling", NV_CTRL_GVI_DETECTED_CHANNEL_COMPONENT_SAMPLING, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the detected sampling format on the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, + { "GviRequestedStreamComponentSampling", NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates the sampling format for a capture stream." }, + { "GviRequestedStreamChromaExpand", NV_CTRL_GVI_REQUESTED_STREAM_CHROMA_EXPAND, INT_ATTR, {0,0,1,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Indicates whether 4:2:2 -> 4:4:4 chroma expansion is enabled for the capture stream." }, + { "GviDetectedChannelColorSpace", NV_CTRL_GVI_DETECTED_CHANNEL_COLOR_SPACE, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the detected color space (RGB, YCRCB, etc) for the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, + { "GviDetectedChannelLinkID", NV_CTRL_GVI_DETECTED_CHANNEL_LINK_ID, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the detected link identifier for the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, + { "GviDetectedChannelSMPTE352Identifier", NV_CTRL_GVI_DETECTED_CHANNEL_SMPTE352_IDENTIFIER, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the detected 4-byte SMPTE 352 identifier from the given jack+channel of the GVI device. The jack+channel must be passed through via the display mask param where the jack number is in the lower 16 bits and the channel number is in the upper 16 bits." }, + { "GviGlobalIdentifier", NV_CTRL_GVI_GLOBAL_IDENTIFIER, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the global identifier for the given NV-CONTROL GVI device." }, + { "GviMaxChannelsPerJack", NV_CTRL_GVI_MAX_CHANNELS_PER_JACK, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the maximum supported number of channels per single jack on a GVI device." }, + { "GviMaxStreams", NV_CTRL_GVI_MAX_STREAMS, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the maximum supported number of streams that can be configured on a GVI device." }, + { "GviNumCaptureSurfaces", NV_CTRL_GVI_NUM_CAPTURE_SURFACES, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the number of capture buffers for storing incoming video from the GVI device." }, + { "GviBoundGpu", NV_CTRL_GVI_BOUND_GPU, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the target index of the GPU currently attached to the GVI device." }, + { "GviTestMode", NV_CTRL_GVI_TEST_MODE, INT_ATTR, {0,0,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable or disable GVI test mode." }, + { "GvioFirmwareVersion", NV_CTRL_STRING_GVIO_FIRMWARE_VERSION, STR_ATTR, {0,0,1,0,1,0}, {}, "Indicates the version of the firmware on the GVO or GVI device." }, + { "GvoFirmwareVersion", NV_CTRL_STRING_GVIO_FIRMWARE_VERSION, STR_ATTR, {0,0,1,0,1,1}, {}, "DEPRECATED: use \"GvioFirmwareVersion\" instead." }, + { "GvoCSCMatrix", 0, CSC_ATTR, {0,0,1,0,1,0}, {}, "Sets the GVO Color Space Conversion (CSC) matrix. Accepted values are \"ITU_601\", \"ITU_709\", \"ITU_177\", and \"Identity\"." }, /* Display */ - { "Brightness", BRIGHTNESS_VALUE|ALL_CHANNELS, N|C|G, "Controls the overall brightness of the display." }, - { "RedBrightness", BRIGHTNESS_VALUE|RED_CHANNEL, C|G, "Controls the brightness of the color red in the display." }, - { "GreenBrightness", BRIGHTNESS_VALUE|GREEN_CHANNEL, C|G, "Controls the brightness of the color green in the display." }, - { "BlueBrightness", BRIGHTNESS_VALUE|BLUE_CHANNEL, C|G, "Controls the brightness of the color blue in the display." }, - { "Contrast", CONTRAST_VALUE|ALL_CHANNELS, N|C|G, "Controls the overall contrast of the display." }, - { "RedContrast", CONTRAST_VALUE|RED_CHANNEL, C|G, "Controls the contrast of the color red in the display." }, - { "GreenContrast", CONTRAST_VALUE|GREEN_CHANNEL, C|G, "Controls the contrast of the color green in the display." }, - { "BlueContrast", CONTRAST_VALUE|BLUE_CHANNEL, C|G, "Controls the contrast of the color blue in the display." }, - { "Gamma", GAMMA_VALUE|ALL_CHANNELS, N|C|G, "Controls the overall gamma of the display." }, - { "RedGamma", GAMMA_VALUE|RED_CHANNEL, C|G, "Controls the gamma of the color red in the display." }, - { "GreenGamma", GAMMA_VALUE|GREEN_CHANNEL, C|G, "Controls the gamma of the color green in the display." }, - { "BlueGamma", GAMMA_VALUE|BLUE_CHANNEL, C|G, "Controls the gamma of the color blue in the display." }, - { "Dithering", NV_CTRL_DITHERING, 0, "Controls the dithering: auto (0), enabled (1), disabled (2)." }, - { "CurrentDithering", NV_CTRL_CURRENT_DITHERING, 0, "Returns the current dithering state: enabled (1), disabled (0)." }, - { "DitheringMode", NV_CTRL_DITHERING_MODE, 0, "Controls the dithering mode when CurrentDithering=1; auto (0), temporally repeating dithering pattern (1), static dithering pattern (2), temporally stochastic dithering (3)." }, - { "CurrentDitheringMode", NV_CTRL_CURRENT_DITHERING_MODE, 0, "Returns the current dithering mode: none (0), temporally repeating dithering pattern (1), static dithering pattern (2), temporally stochastic dithering (3)." }, - { "DitheringDepth", NV_CTRL_DITHERING_DEPTH, 0, "Controls the dithering depth when CurrentDithering=1; auto (0), 6 bits per channel (1), 8 bits per channel (2)." }, - { "CurrentDitheringDepth", NV_CTRL_CURRENT_DITHERING_DEPTH, 0, "Returns the current dithering depth: none (0), 6 bits per channel (1), 8 bits per channel (2)." }, - { "DigitalVibrance", NV_CTRL_DIGITAL_VIBRANCE, 0, "Sets the digital vibrance level of the display device." }, - { "ImageSharpening", NV_CTRL_IMAGE_SHARPENING, 0, "Adjusts the sharpness of the display's image quality by amplifying high frequency content." }, - { "ImageSharpeningDefault", NV_CTRL_IMAGE_SHARPENING_DEFAULT, 0, "Returns default value of image sharpening." }, - { "FrontendResolution", NV_CTRL_FRONTEND_RESOLUTION, N|P, "Returns the dimensions of the frontend (current) resolution as determined by the NVIDIA X Driver. This attribute is a packed integer; the width is packed in the upper 16 bits and the height is packed in the lower 16-bits." }, - { "BackendResolution", NV_CTRL_BACKEND_RESOLUTION, N|P, "Returns the dimensions of the backend resolution as determined by the NVIDIA X Driver. The backend resolution is the resolution (supported by the display device) the GPU is set to scale to. If this resolution matches the frontend resolution, GPU scaling will not be needed/used. This attribute is a packed integer; the width is packed in the upper 16-bits and the height is packed in the lower 16-bits." }, - { "FlatpanelNativeResolution", NV_CTRL_FLATPANEL_NATIVE_RESOLUTION, N|P, "Returns the dimensions of the native resolution of the flat panel as determined by the NVIDIA X Driver. The native resolution is the resolution at which a flat panel must display any image. All other resolutions must be scaled to this resolution through GPU scaling or the DFP's native scaling capabilities in order to be displayed. This attribute is only valid for flat panel (DFP) display devices. This attribute is a packed integer; the width is packed in the upper 16-bits and the height is packed in the lower 16-bits." }, - { "FlatpanelBestFitResolution", NV_CTRL_FLATPANEL_BEST_FIT_RESOLUTION, N|P, "Returns the dimensions of the resolution, selected by the X driver, from the DFP's EDID that most closely matches the frontend resolution of the current mode. The best fit resolution is selected on a per-mode basis. This attribute is only valid for flat panel (DFP) display devices. This attribute is a packed integer; the width is packed in the upper 16-bits and the height is packed in the lower 16-bits." }, - { "DFPScalingActive", NV_CTRL_DFP_SCALING_ACTIVE, N, "Returns the current state of DFP scaling. DFP scaling is mode-specific (meaning it may vary depending on which mode is currently set). DFP scaling is active if the GPU is set to scale to the best fit resolution (GPUScaling is set to use FlatpanelBestFitResolution) and the best fit and native resolutions are different." }, - { "GPUScaling", NV_CTRL_GPU_SCALING, P, "Controls what the GPU scales to and how. This attribute is a packed integer; the scaling target (native/best fit) is packed in the upper 16-bits and the scaling method is packed in the lower 16-bits." }, - { "GPUScalingDefaultTarget", NV_CTRL_GPU_SCALING_DEFAULT_TARGET, 0, "Returns the default gpu scaling target for the Flatpanel." }, - { "GPUScalingDefaultMethod", NV_CTRL_GPU_SCALING_DEFAULT_METHOD, 0, "Returns the default gpu scaling method for the Flatpanel." }, - { "GPUScalingActive", NV_CTRL_GPU_SCALING_ACTIVE, N, "Returns the current state of GPU scaling. GPU scaling is mode-specific (meaning it may vary depending on which mode is currently set). GPU scaling is active if the frontend timing (current resolution) is different than the target resolution. The target resolution is either the native resolution of the flat panel or the best fit resolution supported by the flat panel. What (and how) the GPU should scale to is controlled through the GPUScaling attribute." }, - { "RefreshRate", NV_CTRL_REFRESH_RATE, N|H, "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, N|K, "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, 0, "Adjust the amount of overscan compensation scaling, in pixels, to apply to the specified display device." }, - { "ColorSpace", NV_CTRL_COLOR_SPACE, 0, "Sets the color space of the signal sent to the display device." }, - { "ColorRange", NV_CTRL_COLOR_RANGE, 0, "Sets the color range of the signal sent to the display device." }, - { "SynchronousPaletteUpdates", NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES, 0, "Controls whether colormap updates are synchronized with X rendering." }, - { "CurrentMetaModeID", NV_CTRL_CURRENT_METAMODE_ID, N, "The ID of the current MetaMode." }, - { "CurrentMetaMode", NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2, S|N, "Controls the current MetaMode." }, - { "XineramaInfoOrder", NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER, S|N, "Controls the nvidiaXineramaInfoOrder." }, - { "RandROutputID", NV_CTRL_DISPLAY_RANDR_OUTPUT_ID, N, "The RandR Output ID that corresponds to the display device." }, - { "FrameLockDisplayConfig", NV_CTRL_FRAMELOCK_DISPLAY_CONFIG, N, "Controls the FrameLock mode of operation for the display device." }, - { "Hdmi3D", NV_CTRL_DPY_HDMI_3D, N, "Returns whether the specified display device is currently using HDMI 3D Frame Packed Stereo mode. If so, the result of refresh rate queries will be doubled." }, - { "BacklightBrightness", NV_CTRL_BACKLIGHT_BRIGHTNESS, N, "Controls the backlight brightness of an internal panel." }, + { "Brightness", BRIGHTNESS_VALUE|ALL_CHANNELS, COL_ATTR, {1,0,0,0,1,0}, {}, "Controls the overall brightness of the display." }, + { "RedBrightness", BRIGHTNESS_VALUE|RED_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the brightness of the color red in the display." }, + { "GreenBrightness", BRIGHTNESS_VALUE|GREEN_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the brightness of the color green in the display." }, + { "BlueBrightness", BRIGHTNESS_VALUE|BLUE_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the brightness of the color blue in the display." }, + { "Contrast", CONTRAST_VALUE|ALL_CHANNELS, COL_ATTR, {1,0,0,0,1,0}, {}, "Controls the overall contrast of the display." }, + { "RedContrast", CONTRAST_VALUE|RED_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the contrast of the color red in the display." }, + { "GreenContrast", CONTRAST_VALUE|GREEN_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the contrast of the color green in the display." }, + { "BlueContrast", CONTRAST_VALUE|BLUE_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the contrast of the color blue in the display." }, + { "Gamma", GAMMA_VALUE|ALL_CHANNELS, COL_ATTR, {1,0,0,0,1,0}, {}, "Controls the overall gamma of the display." }, + { "RedGamma", GAMMA_VALUE|RED_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the gamma of the color red in the display." }, + { "GreenGamma", GAMMA_VALUE|GREEN_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {}, "Controls the gamma of the color green in the display." }, + { "BlueGamma", GAMMA_VALUE|BLUE_CHANNEL, COL_ATTR, {1,0,0,0,0,0}, {},"Controls the gamma of the color blue in the display." }, + { "Dithering", NV_CTRL_DITHERING, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the dithering: auto (0), enabled (1), disabled (2)." }, + { "CurrentDithering", NV_CTRL_CURRENT_DITHERING, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current dithering state: enabled (1), disabled (0)." }, + { "DitheringMode", NV_CTRL_DITHERING_MODE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the dithering mode when CurrentDithering=1; auto (0), temporally repeating dithering pattern (1), static dithering pattern (2), temporally stochastic dithering (3)." }, + { "CurrentDitheringMode", NV_CTRL_CURRENT_DITHERING_MODE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current dithering mode: none (0), temporally repeating dithering pattern (1), static dithering pattern (2), temporally stochastic dithering (3)." }, + { "DitheringDepth", NV_CTRL_DITHERING_DEPTH, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the dithering depth when CurrentDithering=1; auto (0), 6 bits per channel (1), 8 bits per channel (2)." }, + { "CurrentDitheringDepth", NV_CTRL_CURRENT_DITHERING_DEPTH, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current dithering depth: none (0), 6 bits per channel (1), 8 bits per channel (2)." }, + { "DigitalVibrance", NV_CTRL_DIGITAL_VIBRANCE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the digital vibrance level of the display device." }, + { "ImageSharpening", NV_CTRL_IMAGE_SHARPENING, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the sharpness of the display's image quality by amplifying high frequency content." }, + { "ImageSharpeningDefault", NV_CTRL_IMAGE_SHARPENING_DEFAULT, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns default value of image sharpening." }, + { "FrontendResolution", NV_CTRL_FRONTEND_RESOLUTION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the dimensions of the frontend (current) resolution as determined by the NVIDIA X Driver. This attribute is a packed integer; the width is packed in the upper 16 bits and the height is packed in the lower 16-bits." }, + { "BackendResolution", NV_CTRL_BACKEND_RESOLUTION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the dimensions of the backend resolution as determined by the NVIDIA X Driver. The backend resolution is the resolution (supported by the display device) the GPU is set to scale to. If this resolution matches the frontend resolution, GPU scaling will not be needed/used. This attribute is a packed integer; the width is packed in the upper 16-bits and the height is packed in the lower 16-bits." }, + { "FlatpanelNativeResolution", NV_CTRL_FLATPANEL_NATIVE_RESOLUTION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the dimensions of the native resolution of the flat panel as determined by the NVIDIA X Driver. The native resolution is the resolution at which a flat panel must display any image. All other resolutions must be scaled to this resolution through GPU scaling or the DFP's native scaling capabilities in order to be displayed. This attribute is only valid for flat panel (DFP) display devices. This attribute is a packed integer; the width is packed in the upper 16-bits and the height is packed in the lower 16-bits." }, + { "FlatpanelBestFitResolution", NV_CTRL_FLATPANEL_BEST_FIT_RESOLUTION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Returns the dimensions of the resolution, selected by the X driver, from the DFP's EDID that most closely matches the frontend resolution of the current mode. The best fit resolution is selected on a per-mode basis. This attribute is only valid for flat panel (DFP) display devices. This attribute is a packed integer; the width is packed in the upper 16-bits and the height is packed in the lower 16-bits." }, + { "DFPScalingActive", NV_CTRL_DFP_SCALING_ACTIVE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current state of DFP scaling. DFP scaling is mode-specific (meaning it may vary depending on which mode is currently set). DFP scaling is active if the GPU is set to scale to the best fit resolution (GPUScaling is set to use FlatpanelBestFitResolution) and the best fit and native resolutions are different." }, + { "GPUScaling", NV_CTRL_GPU_SCALING, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,1,0,0,0,0} }, "Controls what the GPU scales to and how. This attribute is a packed integer; the scaling target (native/best fit) is packed in the upper 16-bits and the scaling method is packed in the lower 16-bits." }, + { "GPUScalingDefaultTarget", NV_CTRL_GPU_SCALING_DEFAULT_TARGET, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the default gpu scaling target for the Flatpanel." }, + { "GPUScalingDefaultMethod", NV_CTRL_GPU_SCALING_DEFAULT_METHOD, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the default gpu scaling method for the Flatpanel." }, + { "GPUScalingActive", NV_CTRL_GPU_SCALING_ACTIVE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current state of GPU scaling. GPU scaling is mode-specific (meaning it may vary depending on which mode is currently set). GPU scaling is active if the frontend timing (current resolution) is different than the target resolution. The target resolution is either the native resolution of the flat panel or the best fit resolution supported by the flat panel. What (and how) the GPU should scale to is controlled through the GPUScaling attribute." }, + { "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, {0,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, {0,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." }, + { "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." }, + { "Hdmi3D", NV_CTRL_DPY_HDMI_3D, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether the specified display device is currently using HDMI 3D Frame Packed Stereo mode. If so, the result of refresh rate queries will be doubled." }, + { "BacklightBrightness", NV_CTRL_BACKLIGHT_BRIGHTNESS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the backlight brightness of an internal panel." }, + { "CurrentMetaMode", NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2, STR_ATTR, {0,0,0,0,1,0}, {}, "Controls the current MetaMode." }, + { "XineramaInfoOrder", NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER, STR_ATTR, {0,0,0,0,1,0}, {}, "Controls the nvidiaXineramaInfoOrder." }, + { "BuildModepool", NV_CTRL_STRING_OPERATION_BUILD_MODEPOOL, SOP_ATTR, {0,0,0,0,1,1}, {}, "Build the modepool of the display device if it does not already have one." }, /* TV */ - { "TVOverScan", NV_CTRL_TV_OVERSCAN, 0, "Adjusts the amount of overscan on the specified display device." }, - { "TVFlickerFilter", NV_CTRL_TV_FLICKER_FILTER, 0, "Adjusts the amount of flicker filter on the specified display device." }, - { "TVBrightness", NV_CTRL_TV_BRIGHTNESS, 0, "Adjusts the amount of brightness on the specified display device." }, - { "TVHue", NV_CTRL_TV_HUE, 0, "Adjusts the amount of hue on the specified display device." }, - { "TVContrast", NV_CTRL_TV_CONTRAST, 0, "Adjusts the amount of contrast on the specified display device." }, - { "TVSaturation", NV_CTRL_TV_SATURATION, 0, "Adjusts the amount of saturation on the specified display device." }, + { "TVOverScan", NV_CTRL_TV_OVERSCAN, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of overscan on the specified display device." }, + { "TVFlickerFilter", NV_CTRL_TV_FLICKER_FILTER, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of flicker filter on the specified display device." }, + { "TVBrightness", NV_CTRL_TV_BRIGHTNESS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of brightness on the specified display device." }, + { "TVHue", NV_CTRL_TV_HUE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of hue on the specified display device." }, + { "TVContrast", NV_CTRL_TV_CONTRAST, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of contrast on the specified display device." }, + { "TVSaturation", NV_CTRL_TV_SATURATION, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of saturation on the specified display device." }, /* X Video */ - { "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, D|Z|N, "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, V, "Controls which display device is synced to by the texture and blitter adaptors when they are set to synchronize to the vertical blanking." }, + { "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,1,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 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, N, "Resets the 3D Vision Pro transceiver to its factory settings."}, - {"3DVisionProTransceiverChannel", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL, N, "Controls the channel that is currently used by the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverMode", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE, N, "Controls the mode in which the 3D Vision Pro transceiver operates."}, - {"3DVisionProTransceiverChannelFrequency", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_FREQUENCY, N|T, "Returns the frequency of the channel(in kHz) of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverChannelQuality", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_QUALITY, N|T, "Returns the quality of the channel(in percentage) of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverChannelCount", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_COUNT, N, "Returns the number of channels on the 3D Vision Pro transceiver."}, - {"3DVisionProPairGlasses", NV_CTRL_3D_VISION_PRO_PAIR_GLASSES, N, "Puts the 3D Vision Pro transceiver into pairing mode to gather additional glasses."}, - {"3DVisionProUnpairGlasses", NV_CTRL_3D_VISION_PRO_UNPAIR_GLASSES, N, "Tells a specific pair of glasses to unpair."}, - {"3DVisionProDiscoverGlasses", NV_CTRL_3D_VISION_PRO_DISCOVER_GLASSES, N, "Tells the 3D Vision Pro transceiver about the glasses that have been paired using NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_BEACON."}, - {"3DVisionProIdentifyGlasses", NV_CTRL_3D_VISION_PRO_IDENTIFY_GLASSES, N, "Causes glasses LEDs to flash for a short period of time."}, - {"3DVisionProGlassesSyncCycle", NV_CTRL_3D_VISION_PRO_GLASSES_SYNC_CYCLE, N|T, "Controls the sync cycle duration(in milliseconds) of the glasses."}, - {"3DVisionProGlassesMissedSyncCycles", NV_CTRL_3D_VISION_PRO_GLASSES_MISSED_SYNC_CYCLES, N|T, "Returns the number of state sync cycles recently missed by the glasses."}, - {"3DVisionProGlassesBatteryLevel", NV_CTRL_3D_VISION_PRO_GLASSES_BATTERY_LEVEL, N|T, "Returns the battery level(in percentage) of the glasses."}, - {"3DVisionProTransceiverHardwareRevision", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_HARDWARE_REVISION, S|N, "Returns the hardware revision of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverFirmwareVersionA", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_A, S|N, "Returns the firmware version of chip A of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverFirmwareDateA", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_A, S|N, "Returns the date of the firmware of chip A of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverFirmwareVersionB", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_B, S|N, "Returns the firmware version of chip B of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverFirmwareDateB", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_B, S|N, "Returns the date of the firmware of chip B of the 3D Vision Pro transceiver."}, - {"3DVisionProTransceiverAddress", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_ADDRESS, S|N, "Returns the RF address of the 3D Vision Pro transceiver."}, - {"3DVisionProGlassesFirmwareVersionA", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_VERSION_A, S|N|T, "Returns the firmware version of chip A of the glasses."}, - {"3DVisionProGlassesFirmwareDateA", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_DATE_A, S|N|T, "Returns the date of the firmware of chip A of the glasses."}, - {"3DVisionProGlassesAddress", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_ADDRESS, S|N|T, "Returns the RF address of the glasses."}, - {"3DVisionProGlassesName", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_NAME, S|N|T, "Controls the name the glasses should use."}, - {"GPUUtilization", NV_CTRL_STRING_GPU_UTILIZATION, S|N, "Returns the current percentage utilization of the GPU components." }, - - { NULL, 0, 0, NULL } + { "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."}, + { "3DVisionProTransceiverChannel", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the channel that is currently used by the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverMode", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the mode in which the 3D Vision Pro transceiver operates."}, + { "3DVisionProTransceiverChannelFrequency", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_FREQUENCY, INT_ATTR, {0,0,0,1,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the frequency of the channel(in kHz) of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverChannelQuality", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_QUALITY, INT_ATTR, {0,0,0,1,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the quality of the channel(in percentage) of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverChannelCount", NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_COUNT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of channels on the 3D Vision Pro transceiver."}, + { "3DVisionProPairGlasses", NV_CTRL_3D_VISION_PRO_PAIR_GLASSES, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Puts the 3D Vision Pro transceiver into pairing mode to gather additional glasses."}, + { "3DVisionProUnpairGlasses", NV_CTRL_3D_VISION_PRO_UNPAIR_GLASSES, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Tells a specific pair of glasses to unpair."}, + { "3DVisionProDiscoverGlasses", NV_CTRL_3D_VISION_PRO_DISCOVER_GLASSES, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Tells the 3D Vision Pro transceiver about the glasses that have been paired using NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_BEACON."}, + { "3DVisionProIdentifyGlasses", NV_CTRL_3D_VISION_PRO_IDENTIFY_GLASSES, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Causes glasses LEDs to flash for a short period of time."}, + { "3DVisionProGlassesSyncCycle", NV_CTRL_3D_VISION_PRO_GLASSES_SYNC_CYCLE, INT_ATTR, {0,0,0,1,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls the sync cycle duration(in milliseconds) of the glasses."}, + { "3DVisionProGlassesMissedSyncCycles", NV_CTRL_3D_VISION_PRO_GLASSES_MISSED_SYNC_CYCLES, INT_ATTR, {0,0,0,1,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of state sync cycles recently missed by the glasses."}, + { "3DVisionProGlassesBatteryLevel", NV_CTRL_3D_VISION_PRO_GLASSES_BATTERY_LEVEL, INT_ATTR, {0,0,0,1,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the battery level(in percentage) of the glasses."}, + { "3DVisionProTransceiverHardwareRevision", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_HARDWARE_REVISION, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the hardware revision of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverFirmwareVersionA", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_A, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the firmware version of chip A of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverFirmwareDateA", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_A, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the date of the firmware of chip A of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverFirmwareVersionB", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_B, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the firmware version of chip B of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverFirmwareDateB", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_B, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the date of the firmware of chip B of the 3D Vision Pro transceiver."}, + { "3DVisionProTransceiverAddress", NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_ADDRESS, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the RF address of the 3D Vision Pro transceiver."}, + { "3DVisionProGlassesFirmwareVersionA", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_VERSION_A, STR_ATTR, {0,0,0,1,1,0}, {}, "Returns the firmware version of chip A of the glasses."}, + { "3DVisionProGlassesFirmwareDateA", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_DATE_A, STR_ATTR, {0,0,0,1,1,0}, {}, "Returns the date of the firmware of chip A of the glasses."}, + { "3DVisionProGlassesAddress", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_ADDRESS, STR_ATTR, {0,0,0,1,1,0}, {}, "Returns the RF address of the glasses."}, + { "3DVisionProGlassesName", NV_CTRL_STRING_3D_VISION_PRO_GLASSES_NAME, STR_ATTR, {0,0,0,1,1,0}, {}, "Controls the name the glasses should use."}, + + /* Misc */ + { "GTFModeline", NV_CTRL_STRING_OPERATION_GTF_MODELINE, SOP_ATTR, {0,0,0,0,1,1}, { }, "Builds a modeline using the GTF formula." }, + { "CVTModeline", NV_CTRL_STRING_OPERATION_CVT_MODELINE, SOP_ATTR, {0,0,0,0,1,1}, { }, "Builds a modeline using the CVT formula." }, + }; -#undef F -#undef C -#undef N -#undef G -#undef P -#undef D -#undef A -#undef Z -#undef H -#undef K -#undef S -#undef I -#undef W -#undef M -#undef T -#undef V +const int attributeTableLen = ARRAY_LEN(attributeTable); /* - * When new integer attributes are added to NVCtrl.h, an entry should - * be added in the above attributeTable[]. The below #if should also - * be updated to indicate the last attribute that the table knows - * about. + * When new attributes are added to NVCtrl.h, an entry should be added in the + * above attributeTable[]. The below #if should also be updated to indicate + * the last attribute that the table knows about. */ #if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_THERMAL_COOLER_SPEED #warning "Have you forgotten to add a new integer attribute to attributeTable?" #endif +#if NV_CTRL_STRING_LAST_ATTRIBUTE != NV_CTRL_STRING_MULTIGPU_MODE +#warning "Have you forgotten to add a new string attribute to attributeTable?" +#endif + +#if NV_CTRL_STRING_OPERATION_LAST_ATTRIBUTE != NV_CTRL_STRING_OPERATION_PARSE_METAMODE +#warning "Have you forgotten to add a new string operation attribute to attributeTable?" +#endif + + + +/* + * returns the corresponding attribute entry for the given attribute constant. + * + */ +const AttributeTableEntry *nv_get_attribute_entry(const int attr, + const AttributeType type) +{ + int i; + + for (i = 0; i < attributeTableLen; i++) { + const AttributeTableEntry *a = attributeTable + i; + if ((a->attr == attr) && (a->type == type)) { + return a; + } + } + + return NULL; +} + + +/* + * returns the corresponding attribute entry for the given attribute + * name. + * + */ +static const AttributeTableEntry *nv_get_attribute_entry_by_name(const char *name) +{ + int i; + + for (i = 0; i < attributeTableLen; i++) { + const AttributeTableEntry *t = attributeTable + i; + if (nv_strcasecmp(name, t->name)) { + return t; + } + } + + return NULL; +} + /* @@ -580,29 +615,29 @@ int nv_parse_numerical(const char *start, const char *end, int *val) * Parse the string as a (special case) X screen number. * * Return whether the string defined by 'start' and 'end' is a simple numerical - * value that was applied to the ParsedAttribute 'a' as an X screen target + * value that was applied to the ParsedAttribute 'p' as an X screen target * type/id. * * \param[in] start Start of the string to parse. * \param[in] end End of the string to parse, or NULL if the string is NULL- * terminated. - * \param[out] a ParsedAttribute to set as an X screen target if the string + * \param[out] p ParsedAttribute to set as an X screen target if the string * is found to be a simple numeric. * * \return Return NV_TRUE if the string was a simple numerical value and 'a' * was modified; else, return NV_FALSE. */ -static int nv_parse_special_xscreen_target(ParsedAttribute *a, +static int nv_parse_special_xscreen_target(ParsedAttribute *p, const char *start, const char *end) { - if (!nv_parse_numerical(start, end, &(a->target_id))) { + if (!nv_parse_numerical(start, end, &(p->target_id))) { return FALSE; } - a->flags |= NV_PARSER_HAS_TARGET; - a->target_type = NV_CTRL_TARGET_TYPE_X_SCREEN; + p->parser_flags.has_target = NV_TRUE; + p->target_type = NV_CTRL_TARGET_TYPE_X_SCREEN; return NV_TRUE; } @@ -623,7 +658,7 @@ static int nv_parse_special_xscreen_target(ParsedAttribute *a, * * \param[in] start Start of the string to parse. * \param[in] end End of the string to parse. - * \param[out] a ParsedAttribute to be modified with the X Display and/or + * \param[out] p ParsedAttribute to be modified with the X Display and/or * target type + target id or generic specification * information. * @@ -634,7 +669,7 @@ static int nv_parse_special_xscreen_target(ParsedAttribute *a, static int nv_parse_display_and_target(const char *start, const char *end, /* exclusive */ - ParsedAttribute *a) + ParsedAttribute *p) { int len; const char *s, *pOpen, *pClose; @@ -643,20 +678,19 @@ static int nv_parse_display_and_target(const char *start, /* Set target specification related defaults */ - a->display = NULL; - a->target_id = -1; - a->target_type = -1; - a->target_name = NULL; - a->target_specification = NULL; - a->flags &= ~(NV_PARSER_HAS_X_DISPLAY | - NV_PARSER_HAS_TARGET); + p->display = NULL; + p->target_id = -1; + p->target_type = -1; + p->target_specification = NULL; + p->parser_flags.has_x_display = NV_FALSE; + p->parser_flags.has_target = NV_FALSE; /* * If the string consists of digits only, then this is a special case where * the X screen number is being specified. */ - if (nv_parse_special_xscreen_target(a, start, end)) { + if (nv_parse_special_xscreen_target(p, start, end)) { return NV_PARSER_STATUS_SUCCESS; } @@ -694,7 +728,7 @@ static int nv_parse_display_and_target(const char *start, len = pClose - pOpen - 1; - a->target_specification = nvstrndup(pOpen + 1, len); + p->target_specification = nvstrndup(pOpen + 1, len); /* * The X Display name should end on the opening bracket of the target @@ -708,16 +742,16 @@ static int nv_parse_display_and_target(const char *start, if (startDisplayName < endDisplayName) { - a->display = nvstrndup(startDisplayName, + p->display = nvstrndup(startDisplayName, endDisplayName - startDisplayName); - a->flags |= NV_PARSER_HAS_X_DISPLAY; + p->parser_flags.has_x_display = NV_TRUE; /* * this will attempt to parse out any screen number from the * display name */ - nv_assign_default_display(a, NULL); + nv_assign_default_display(p, NULL); } return NV_PARSER_STATUS_SUCCESS; @@ -729,21 +763,24 @@ static int nv_parse_display_and_target(const char *start, * nv_parse_attribute_string() - see comments in parse.h */ -int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *a) +int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *p) { - char *s, *tmp, *name, *start, *display_device_name, *equal_sign, *no_spaces = NULL; + char *s, *tmp, *name, *start, *equal_sign, *no_spaces = NULL; char tmpname[NV_PARSER_MAX_NAME_LEN]; - const AttributeTableEntry *t; int len, ret; + const AttributeTableEntry *a; #define stop(x) { if (no_spaces) free(no_spaces); return (x); } - if (!a) stop(NV_PARSER_STATUS_BAD_ARGUMENT); + + if (!p) { + stop(NV_PARSER_STATUS_BAD_ARGUMENT); + } /* clear the ParsedAttribute struct */ - memset((void *) a, 0, sizeof(ParsedAttribute)); - a->target_id = -1; - a->target_type = -1; + memset((void *) p, 0, sizeof(ParsedAttribute)); + p->target_id = -1; + p->target_type = -1; /* remove any white space from the string, to simplify parsing */ @@ -778,7 +815,7 @@ int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *a) if ((s) && (s != no_spaces)) { - ret = nv_parse_display_and_target(no_spaces, s, a); + ret = nv_parse_display_and_target(no_spaces, s, p); if (ret != NV_PARSER_STATUS_SUCCESS) { stop(ret); @@ -806,112 +843,137 @@ int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *a) strncpy(tmpname, name, len); tmpname[len] = '\0'; - - /* look up the requested name */ - - for (t = attributeTable; t->name; t++) { - if (nv_strcasecmp(tmpname, t->name)) { - a->name = t->name; - a->attr = t->attr; - a->flags |= t->flags; - a->attr_entry = t; - break; - } + + /* look up the requested attribute */ + + a = nv_get_attribute_entry_by_name(tmpname); + if (!a) { + stop(NV_PARSER_STATUS_UNKNOWN_ATTR_NAME); } - - if (!a->name) stop(NV_PARSER_STATUS_UNKNOWN_ATTR_NAME); - - /* read the display device name, if any */ - + + p->attr_entry = a; + + /* read the display device specification */ + if (*s == '[') { + char *mask_str; s++; start = s; - while (*s && *s != ']') s++; - display_device_name = nvstrndup(start, s - start); - a->display_device_mask = - display_device_name_to_display_device_mask(display_device_name); - /* - * stop parsing if the display device mask is invalid (and the - * display device mask is not hijacked for something other than - * display) - */ - - if ((a->display_device_mask == INVALID_DISPLAY_DEVICE_MASK) && - !(a->flags & NV_PARSER_TYPE_HIJACK_DISPLAY_DEVICE)) - stop(NV_PARSER_STATUS_BAD_DISPLAY_DEVICE); - - a->flags |= NV_PARSER_HAS_DISPLAY_DEVICE; - if (*s == ']') s++; + while (*s && *s != ']') { + s++; + } + tmp = nvstrndup(start, s - start); + mask_str = remove_spaces(tmp); + nvfree(tmp); + + p->display_device_mask = strtoul(mask_str, &tmp, 0); + if (*mask_str != '\0' && + tmp && + *tmp == '\0') { + /* specification given as integer */ + nvfree(mask_str); + } else { + /* specification given as string (list of display names) */ + if (a->flags.hijack_display_device) { + /* If the display specification (mask) is being hijacked, the + * value should have been a valid integer. + */ + stop(NV_PARSER_STATUS_BAD_DISPLAY_DEVICE); + } + p->display_device_specification = mask_str; + } + p->parser_flags.has_display_device = NV_TRUE; + if (*s == ']') { + s++; + } } - + if (query == NV_PARSER_ASSIGNMENT) { - + /* there should be an equal sign */ - + if (*s == '=') s++; else stop(NV_PARSER_STATUS_MISSING_EQUAL_SIGN); - + /* read the value */ - + tmp = s; - if (a->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) { - /* color attributes are floating point */ - a->val.f = strtod(s, &tmp); - } else if ((a->flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) || - (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID)) { - a->val.str = strdup(s); - tmp = s + strlen(s); - } else if (a->flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { - /* - * Either a single 32-bit integer or two 16-bit - * integers, separated by ','. - * Passing base as 0 allows packed values to be specified - * in hex (Bug 377242) - */ - a->val.i = strtol(s, &tmp, 0); - - if (tmp && *tmp == ',') { - a->val.i = (a->val.i & 0xffff) << 16; - a->val.i |= strtol((tmp + 1), &tmp, 0) & 0xffff; - } - } else if (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY) { - if (nv_strcasecmp(s, "alldisplays")) { - a->flags |= NV_PARSER_TYPE_ASSIGN_ALL_DISPLAYS; - tmp = s + strlen(s); - } else { - uint32 mask = 0; - mask = display_device_name_to_display_device_mask(s); - if (mask && (mask != INVALID_DISPLAY_DEVICE_MASK) && - ((mask & (DISPLAY_DEVICES_WILDCARD_CRT | - DISPLAY_DEVICES_WILDCARD_TV | - DISPLAY_DEVICES_WILDCARD_DFP)) == 0)) { - a->val.i = mask; + switch (a->type) { + case NV_PARSER_ATTRIBUTE_TYPE_INTEGER: + if (a->f.int_flags.is_packed) { + /* + * Either a single 32-bit integer or two 16-bit integers, + * separated by ','. Passing base as 0 allows packed values to + * be specified in hex. + */ + p->val.i = strtol(s, &tmp, 0); + if (tmp && *tmp == ',') { + p->val.i = (p->val.i & 0xffff) << 16; + p->val.i |= strtol((tmp + 1), &tmp, 0) & 0xffff; + } + } else if (a->f.int_flags.is_display_mask) { + /* Value is a display mask (as a string or integer */ + if (nv_strcasecmp(s, "alldisplays")) { + p->parser_flags.assign_all_displays = NV_TRUE; tmp = s + strlen(s); } else { - a->val.i = strtol(s, &tmp, 0); + uint32 mask = 0; + mask = display_device_name_to_display_device_mask(s); + if (mask && (mask != INVALID_DISPLAY_DEVICE_MASK) && + ((mask & (DISPLAY_DEVICES_WILDCARD_CRT | + DISPLAY_DEVICES_WILDCARD_TV | + DISPLAY_DEVICES_WILDCARD_DFP)) == 0)) { + p->val.i = mask; + tmp = s + strlen(s); + } else { + p->val.i = strtol(s, &tmp, 0); + } } + } else if (a->f.int_flags.is_display_id) { + /* Value is Dispaly ID that can use the display names */ + p->val.str = nvstrdup(s); + tmp = s + strlen(s); + } else { + /* Read just an integer */ + p->val.i = strtol(s, &tmp, 0); } - } else if (a->flags & NV_PARSER_TYPE_SDI_CSC) { + break; + + case NV_PARSER_ATTRIBUTE_TYPE_STRING: + /* Fall through */ + case NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION: + p->val.str = nvstrdup(s); + tmp = s + strlen(s); + break; + + case NV_PARSER_ATTRIBUTE_TYPE_COLOR: + /* color attributes are floating point */ + p->val.f = strtod(s, &tmp); + break; + + case NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC: /* String that names a standard CSC matrix */ - a->val.pf = nv_get_sdi_csc_matrix(s); + p->val.pf = nv_get_sdi_csc_matrix(s); tmp = s + strlen(s); - } else { - /* all other attributes are integer */ - a->val.i = strtol(s, &tmp, 0); + break; + } + + if (tmp && (s != tmp)) { + p->parser_flags.has_value = NV_TRUE; } - - if (tmp && (s != tmp)) a->flags |= NV_PARSER_HAS_VAL; s = tmp; - - if (!(a->flags & NV_PARSER_HAS_VAL)) stop(NV_PARSER_STATUS_NO_VALUE); + + if (!(p->parser_flags.has_value)) { + stop(NV_PARSER_STATUS_NO_VALUE); + } } - + /* this should be the end of the string */ if (*s != '\0') stop(NV_PARSER_STATUS_TRAILING_GARBAGE); stop(NV_PARSER_STATUS_SUCCESS); - + } /* nv_parse_attribute_string() */ @@ -1186,43 +1248,22 @@ char *display_device_mask_to_display_device_name(const uint32 mask) /* - * expand_display_device_mask_wildcards() - build a display mask by - * taking any of the real display mask bits; if there are any wildcard - * flags set, or in all display devices of that type into the display - * mask. - */ - -uint32 expand_display_device_mask_wildcards(const uint32 d) -{ - uint32 mask = d & VALID_DISPLAY_DEVICES_MASK; - - if (d & DISPLAY_DEVICES_WILDCARD_CRT) mask |= BITMASK_ALL_CRT; - if (d & DISPLAY_DEVICES_WILDCARD_TV) mask |= BITMASK_ALL_TV; - if (d & DISPLAY_DEVICES_WILDCARD_DFP) mask |= BITMASK_ALL_DFP; - - return mask; -} - - - -/* * nv_assign_default_display() - assign an X display, if none has been * assigned already. Also, parse the display name to find any * specified X screen. */ -void nv_assign_default_display(ParsedAttribute *a, const char *display) +void nv_assign_default_display(ParsedAttribute *p, const char *display) { char *colon, *dot; - if (!(a->flags & NV_PARSER_HAS_X_DISPLAY)) { - if (display) a->display = strdup(display); - else a->display = NULL; - a->flags |= NV_PARSER_HAS_X_DISPLAY; + if (!(p->parser_flags.has_x_display)) { + p->display = display ? nvstrdup(display) : NULL; + p->parser_flags.has_x_display = NV_TRUE; } - if (!(a->flags & NV_PARSER_HAS_TARGET) && a->display) { - colon = strchr(a->display, ':'); + if (!(p->parser_flags.has_target) && p->display) { + colon = strchr(p->display, ':'); if (colon) { dot = strchr(colon, '.'); if (dot) { @@ -1231,7 +1272,7 @@ void nv_assign_default_display(ParsedAttribute *a, const char *display) * if all characters after the '.' are digits, interpret it as a * screen number. */ - nv_parse_special_xscreen_target(a, dot + 1, NULL); + nv_parse_special_xscreen_target(p, dot + 1, NULL); } } } @@ -1256,26 +1297,46 @@ ParsedAttribute *nv_parsed_attribute_init(void) * linked list */ -void nv_parsed_attribute_add(ParsedAttribute *head, ParsedAttribute *a) +void nv_parsed_attribute_add(ParsedAttribute *head, ParsedAttribute *p) { - ParsedAttribute *p, *t; - - p = nvalloc(sizeof(ParsedAttribute)); + ParsedAttribute *t; for (t = head; t->next; t = t->next); - t->next = p; + t->next = nvalloc(sizeof(ParsedAttribute)); + + t->display = p->display ? nvstrdup(p->display) : NULL; + t->target_specification = p->target_specification; + t->target_type = p->target_type; + t->target_id = p->target_id; + t->attr_entry = p->attr_entry; + t->val = p->val; + t->display_device_mask = p->display_device_mask; + t->parser_flags = p->parser_flags; + t->targets = p->targets; +} + - if (a->display) t->display = strdup(a->display); - else t->display = NULL; - t->target_type = a->target_type; - t->target_id = a->target_id; - t->attr = a->attr; - t->val = a->val; - t->display_device_mask = a->display_device_mask; - t->flags = a->flags; - t->targets = a->targets; +/* + * Frees memory used by the parsed attribute members + */ + +static void nv_parsed_attribute_free_members(ParsedAttribute *p) +{ + const AttributeTableEntry *a = p->attr_entry; + + nvfree(p->display); + nvfree(p->target_specification); + + if (a && + ((a->type == NV_PARSER_ATTRIBUTE_TYPE_STRING) || + ((a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + (a->f.int_flags.is_display_id)))) { + nvfree(p->val.str); + } + + nv_target_list_free(p->targets); } @@ -1288,10 +1349,11 @@ void nv_parsed_attribute_free(ParsedAttribute *p) { ParsedAttribute *n; - while(p) { + while (p) { n = p->next; - if (p->display) free(p->display); - nv_target_list_free(p->targets); + + nv_parsed_attribute_free_members(p); + free(p); p = n; } @@ -1308,9 +1370,7 @@ void nv_parsed_attribute_clean(ParsedAttribute *p) { nv_parsed_attribute_free(p->next); - if (p->display) free(p->display); - if (p->name) free(p->name); - free(p->target_name); + nv_parsed_attribute_free_members(p); memset(p, 0, sizeof(*p)); @@ -1319,29 +1379,6 @@ void nv_parsed_attribute_clean(ParsedAttribute *p) /* - * nv_get_attribute_name() - scan the attributeTable for the name that - * corresponds to the attribute constant. - */ - -const char *nv_get_attribute_name(const int attr, const int flagsMask, - const int flags) -{ - int i; - - for (i = 0; attributeTable[i].name; i++) { - if (attributeTable[i].attr == attr && - (attributeTable[i].flags & flagsMask) == (flags & flagsMask)) { - return attributeTable[i].name; - } - } - - return NULL; - -} /* nv_get_attribute_name() */ - - - -/* * nv_standardize_screen_name() - standardize the X Display name, by * inserting the hostname (if necessary), and using the specified * screen number. If 'screen' is -1, use the screen number already in @@ -1507,7 +1544,7 @@ char *replace_characters(const char *o, const char c, const char r) * memory allocated here. */ -static char **nv_strtok(char *s, char c, int *n) +char **nv_strtok(char *s, char c, int *n) { int count, i, len; char **delims, **tokens, *m; @@ -1556,7 +1593,7 @@ static char **nv_strtok(char *s, char c, int *n) * allocated and returned by nv_strtok() */ -static void nv_free_strtoks(char **s, int n) +void nv_free_strtoks(char **s, int n) { int i; for (i = 0; i < n; i++) free(s[i]); diff --git a/src/parse.h b/src/parse.h index 117c7f4..fd27391 100644 --- a/src/parse.h +++ b/src/parse.h @@ -25,37 +25,6 @@ #define __PARSE_H__ -/* - * Flag values used in the flags field of the ParsedAttribute struct. - */ - -#define NV_PARSER_HAS_X_DISPLAY (1<<0) -#define NV_PARSER_HAS_TARGET (1<<2) -#define NV_PARSER_HAS_DISPLAY_DEVICE (1<<3) -#define NV_PARSER_HAS_VAL (1<<4) - -/* - * Flag values used in the flags field of the AttributeTableEntry struct. - */ - -#define NV_PARSER_TYPE_HIJACK_DISPLAY_DEVICE (1<<15) -#define NV_PARSER_TYPE_FRAMELOCK (1<<16) -#define NV_PARSER_TYPE_COLOR_ATTRIBUTE (1<<17) -#define NV_PARSER_TYPE_NO_CONFIG_WRITE (1<<18) -#define NV_PARSER_TYPE_GUI_ATTRIBUTE (1<<19) -#define NV_PARSER_TYPE_PACKED_ATTRIBUTE (1<<20) -#define NV_PARSER_TYPE_VALUE_IS_DISPLAY (1<<21) -#define NV_PARSER_TYPE_NO_QUERY_ALL (1<<22) -#define NV_PARSER_TYPE_NO_ZERO_VALUE (1<<23) -#define NV_PARSER_TYPE_100Hz (1<<24) -#define NV_PARSER_TYPE_STRING_ATTRIBUTE (1<<25) -#define NV_PARSER_TYPE_ASSIGN_ALL_DISPLAYS (1<<26) -#define NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY (1<<27) -#define NV_PARSER_TYPE_1000Hz (1<<28) -#define NV_PARSER_TYPE_SDI (1<<29) -#define NV_PARSER_TYPE_SDI_CSC (1<<30) -#define NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID (1<<31) - #define NV_PARSER_ASSIGNMENT 0 #define NV_PARSER_QUERY 1 @@ -94,6 +63,49 @@ typedef unsigned int uint32; /* + * attribute types used to know how to access each attribute (eg, to know which + * of the NvCtrlXXX() backend functions to call). + */ + +typedef enum { + NV_PARSER_ATTRIBUTE_TYPE_INTEGER, + NV_PARSER_ATTRIBUTE_TYPE_STRING, + NV_PARSER_ATTRIBUTE_TYPE_COLOR, + NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC, + NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION, +} AttributeType; + + +/* + * flags common to all attributes ('flags' in AttributeTableEntry) + */ + +typedef struct AttributeFlagsRec { + int is_gui_attribute : 1; + int is_framelock_attribute : 1; + int is_sdi_attribute : 1; + int hijack_display_device : 1; + int no_config_write : 1; + int no_query_all : 1; +} AttributeFlags; + + +/* + * flags specific to integer attributes ('type_flags' in AttributeTableEntry) + */ + +typedef struct AttributeIntFlagsRec { + int is_100Hz : 1; + int is_1000Hz : 1; + int is_packed : 1; + int is_display_mask : 1; + int is_display_id : 1; + int no_zero : 1; + int is_switch_display : 1; +} AttributeIntFlags; + + +/* * The valid attribute names, and their corresponding protocol * attribute identifiers are stored in an array of * AttributeTableEntries. @@ -102,7 +114,13 @@ typedef unsigned int uint32; typedef struct _AttributeTableEntry { char *name; int attr; - uint32 flags; + + AttributeType type; + AttributeFlags flags; + union { + AttributeIntFlags int_flags; + } f; + char *desc; } AttributeTableEntry; @@ -113,8 +131,9 @@ typedef struct _AttributeTableEntry { */ typedef struct _ParsedAttribute { + struct _ParsedAttribute *next; + char *display; - char *name; char *target_specification; /* * The target_type and target_id here are mostly set by the GUI to store @@ -126,8 +145,6 @@ typedef struct _ParsedAttribute { */ int target_type; int target_id; - char *target_name; - int attr; const AttributeTableEntry *attr_entry; union { int i; @@ -135,9 +152,17 @@ typedef struct _ParsedAttribute { const float *pf; char *str; } val; + char *display_device_specification; uint32 display_device_mask; - uint32 flags; - struct _ParsedAttribute *next; + + struct { + int has_x_display : 1; + int has_target : 1; + int has_display_device : 1; + int has_value : 1; + int assign_all_displays : 1; + } parser_flags; + /* * Upon being resolved, the ParsedAttribute's target_type and target_id, * and/or target_specification get converted into a list of targets to @@ -153,6 +178,7 @@ typedef struct _ParsedAttribute { */ extern const AttributeTableEntry attributeTable[]; +extern const int attributeTableLen; /* @@ -286,7 +312,7 @@ int nv_parse_attribute_string(const char *, int, ParsedAttribute *); * field, if a screen is specified in the display name. */ -void nv_assign_default_display(ParsedAttribute *a, const char *display); +void nv_assign_default_display(ParsedAttribute *p, const char *display); /* @@ -335,13 +361,13 @@ uint32 expand_display_device_mask_wildcards(const uint32); ParsedAttribute *nv_parsed_attribute_init(void); -void nv_parsed_attribute_add(ParsedAttribute *head, ParsedAttribute *a); +void nv_parsed_attribute_add(ParsedAttribute *head, ParsedAttribute *p); void nv_parsed_attribute_free(ParsedAttribute *p); void nv_parsed_attribute_clean(ParsedAttribute *p); -const char *nv_get_attribute_name(const int attr, const int flagsMask, - const int flags); +const AttributeTableEntry *nv_get_attribute_entry(const int attr, + const AttributeType type); char *nv_standardize_screen_name(const char *display_name, int screen); @@ -360,6 +386,8 @@ const char *parse_read_name(const char *str, char **name, char term); const char *parse_read_display_name(const char *str, unsigned int *mask); const char *parse_read_display_id(const char *str, unsigned int *id); int parse_read_float_range(const char *str, float *min, float *max); +char **nv_strtok(char *s, char c, int *n); +void nv_free_strtoks(char **s, int n); int count_number_of_bits(unsigned int mask); /* Token parsing functions */ diff --git a/src/query-assign.c b/src/query-assign.c index 8b5ec37..845f010 100644 --- a/src/query-assign.c +++ b/src/query-assign.c @@ -26,6 +26,7 @@ #include <stdio.h> #include <stdlib.h> +#include <ctype.h> #include <string.h> #include <inttypes.h> @@ -37,39 +38,33 @@ #include "query-assign.h" #include "common-utils.h" -extern int __verbosity; -extern int __terse; -extern int __display_device_string; -extern int __list_targets; - /* local prototypes */ #define PRODUCT_NAME_LEN 64 -static int process_attribute_queries(int, char**, const char *, +static int process_attribute_queries(const Options *, + int, char**, const char *, CtrlHandlesArray *); -static int process_attribute_assignments(int, char**, const char *, - CtrlHandlesArray *); +static int process_attribute_assignments(const Options *, + int, char**, const char *, + CtrlHandlesArray *); -static int query_all(const char *, CtrlHandlesArray *); +static int query_all(const Options *, const char *, CtrlHandlesArray *); static int query_all_targets(const char *display_name, const int target_index, CtrlHandlesArray *); -static void print_valid_values(const char *, int, uint32, - NVCTRLAttributeValidValuesRec); +static void print_valid_values(const Options *op, const AttributeTableEntry *a, + NVCTRLAttributeValidValuesRec valid); static void print_additional_info(const char *name, int attr, NVCTRLAttributeValidValuesRec valid, const char *indent); -static int validate_value(CtrlHandleTarget *t, ParsedAttribute *a, uint32 d, - int target_type, char *whence); - -static CtrlHandles *nv_alloc_ctrl_handles(const char *display); - -static void nv_free_ctrl_handles(CtrlHandles *h); +static ReturnStatus get_framelock_sync_state(NvCtrlAttributeHandle *t, + CtrlHandles *h, + int *enabled); /* * nv_process_assignments_and_queries() - process any assignments or @@ -77,20 +72,22 @@ static void nv_free_ctrl_handles(CtrlHandles *h); * NV_FALSE. On success return NV_TRUE. */ -int nv_process_assignments_and_queries(const Options *op, +int nv_process_assignments_and_queries(const Options *op, CtrlHandlesArray *handles_array) { int ret; if (op->num_queries) { - ret = process_attribute_queries(op->num_queries, + ret = process_attribute_queries(op, + op->num_queries, op->queries, op->ctrl_display, handles_array); if (!ret) return NV_FALSE; } if (op->num_assignments) { - ret = process_attribute_assignments(op->num_assignments, + ret = process_attribute_assignments(op, + op->num_assignments, op->assignments, op->ctrl_display, handles_array); @@ -329,20 +326,6 @@ NvCtrlAttributeHandle *nv_get_target_handle(const CtrlHandles *handles, /*! - * Returns the first node (sentry) for tracking CtrlHandleTarget lists. - * - * \return Returns the sentry node to be used for tracking CtrlHandleTarget - * list. - */ - -static CtrlHandleTargetNode *nv_target_list_init(void) -{ - return nvalloc(sizeof(CtrlHandleTargetNode)); -} - - - -/*! * Appends the given CtrlHandleTarget 'target' to the end of the * CtrlHandleTarget list 'head' if 'target' is not already in the list. * @@ -351,20 +334,34 @@ static CtrlHandleTargetNode *nv_target_list_init(void) * \param[in] target The CtrlHandleTarget to add to the list. */ -static void nv_target_list_add(CtrlHandleTargetNode *head, +static void nv_target_list_add(CtrlHandleTargetNode **head, CtrlHandleTarget *target) { + CtrlHandleTargetNode *new_t; CtrlHandleTargetNode *t; - for (t = head; t->next; t = t->next) { + new_t = nvalloc(sizeof(CtrlHandleTargetNode)); + new_t->t = target; + + t = *head; + + /* List is empty */ + if (!t) { + *head = new_t; + return; + } + + while (1) { if (t->t == target) { - /* Already in list, ignore */ + nvfree(new_t); + return; + } + if (!t->next) { + t->next = new_t; return; } + t = t->next; } - - t->next = nv_target_list_init(); - t->t = target; } @@ -436,10 +433,15 @@ static void add_target_relationships(const CtrlHandles *h, CtrlHandleTarget *t, r = nv_get_target(h, targetType, targetId); if (r) { - nv_target_list_add(t->relations, r); + nv_target_list_add(&(t->relations), r); + + /* Track connection state of display devices */ + if (attr == NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU) { + r->display.connected = NV_TRUE; + } if (implicit_reciprocal == NV_TRUE) { - nv_target_list_add(r->relations, t); + nv_target_list_add(&(r->relations), t); } } } @@ -496,6 +498,9 @@ static void load_gpu_target_relationships(CtrlHandles *h, CtrlHandleTarget *t) add_target_relationships(h, t, NV_CTRL_TARGET_TYPE_DISPLAY, NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU, NV_TRUE); + add_target_relationships(h, t, NV_CTRL_TARGET_TYPE_DISPLAY, + NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU, + NV_TRUE); } @@ -622,9 +627,7 @@ static int target_has_qualification(const CtrlHandleTarget *t, } /* Look for any matching relationship */ - for (n = t->relations; - n->next; - n = n->next) { + for (n = t->relations; n; n = n->next) { const CtrlHandleTarget *r = n->t; if (matchTargetType >= 0 && @@ -750,9 +753,9 @@ static int parse_single_target_specification(const char *sAAA, * - All the targets named (or target id) AAA of the target type BBB that are * related to targets named (or target id) CCC of the target type DDD. * - * \param[in/ou] a The ParsedAttribute whose target specification string - * should be analyzed and converted into a list of targets. - * \param[in] h The list of targets to choose from. + * \param[in/out] p The ParsedAttribute whose target specification string + * should be analyzed and converted into a list of targets. + * \param[in] h The list of targets to choose from. * * \return Returns NV_PARSER_STATUS_SUCCESS if the ParsedAttribute's target * specification string was successfully parsed into a list of targets @@ -761,7 +764,7 @@ static int parse_single_target_specification(const char *sAAA, * error codes that detail the particular parsing error. */ -static int nv_infer_targets_from_specification(ParsedAttribute *a, +static int nv_infer_targets_from_specification(ParsedAttribute *p, CtrlHandles *h) { int ret = NV_PARSER_STATUS_SUCCESS; @@ -792,10 +795,22 @@ static int nv_infer_targets_from_specification(ParsedAttribute *a, const char *matchQualifierTargetName; - tmp = nvstrdup(a->target_specification); + tmp = nvstrdup(p->target_specification); /* Parse for 'YYY.XXX' or 'XXX' */ s = strchr(tmp, '.'); + + /* Skip over periods that are followed by a numerical value since + * target names and target types cannot start with these, and thus + * these are part of the name. + */ + while (s) { + if (!isdigit(*(s+1))) { + break; + } + s = strchr(s+1, '.'); + } + if (s) { *s = '\0'; sXXX = s+1; @@ -880,8 +895,9 @@ static int nv_infer_targets_from_specification(ParsedAttribute *a, } /* Target matches, add it to the list */ - nv_target_list_add(a->targets, t); - a->flags |= NV_PARSER_HAS_TARGET; + + nv_target_list_add(&(p->targets), t); + p->parser_flags.has_target = NV_TRUE; } } @@ -948,7 +964,19 @@ static void nv_init_target(Display *dpy, CtrlHandleTarget *t, } load_target_proto_names(t); - t->relations = nv_target_list_init(); + t->relations = NULL; + + if (target == DISPLAY_TARGET) { + status = NvCtrlGetAttribute(t->h, NV_CTRL_DISPLAY_ENABLED, &d); + if (status != NvCtrlSuccess) { + nv_error_msg("Error querying enabled state of display %s %d (%s).", + targetTypeTable[target].name, targetId, + NvCtrlAttributesStrError(status)); + d = NV_CTRL_DISPLAY_ENABLED_FALSE; + } + t->display.enabled = (d == NV_CTRL_DISPLAY_ENABLED_TRUE) ? 1 : 0; + } + /* * get the enabled display device mask; for X screens and @@ -1021,7 +1049,7 @@ NvCtrlAttributeHandle *nv_add_target(CtrlHandles *handles, Display *dpy, * FrameLock devices). */ -CtrlHandles *nv_alloc_ctrl_handles(const char *display) +static CtrlHandles *nv_alloc_ctrl_handles(const char *display) { ReturnStatus status; CtrlHandles *h, *pQueryHandle = NULL; @@ -1333,12 +1361,12 @@ CtrlHandles *nv_get_ctrl_handles(const char *display, * Adds all the targets of the target type (specified via a target type index) * to the list of targets to process for the ParsedAttribute. * - * \param[in/out] a The ParsedAttribute to add targets to. + * \param[in/out] p The ParsedAttribute to add targets to. * \param[in] h The list of targets to add from. * \param[in] targetIdx The target type index of the targets to add. */ -static void include_target_idx_targets(ParsedAttribute *a, const CtrlHandles *h, +static void include_target_idx_targets(ParsedAttribute *p, const CtrlHandles *h, int targetIdx) { const CtrlHandleTargets *targets = &(h->targets[targetIdx]); @@ -1346,8 +1374,8 @@ static void include_target_idx_targets(ParsedAttribute *a, const CtrlHandles *h, for (i = 0; i < targets->n; i++) { CtrlHandleTarget *target = &(targets->t[i]); - nv_target_list_add(a->targets, target); - a->flags |= NV_PARSER_HAS_TARGET; + nv_target_list_add(&(p->targets), target); + p->parser_flags.has_target = NV_TRUE; } } @@ -1363,12 +1391,24 @@ static void include_target_idx_targets(ParsedAttribute *a, const CtrlHandles *h, * \return Returns TRUE if the permissions were queried successfully; else, * returns FALSE. */ -Bool nv_get_attribute_perms(CtrlHandles *h, int attr, uint32 flags, +Bool nv_get_attribute_perms(CtrlHandles *h, const AttributeTableEntry *a, NVCTRLAttributePermissionsRec *perms) { memset(perms, 0, sizeof(*perms)); - if (flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) { + switch (a->type) { + + case NV_PARSER_ATTRIBUTE_TYPE_INTEGER: + return XNVCTRLQueryAttributePermissions(h->dpy, a->attr, perms); + + case NV_PARSER_ATTRIBUTE_TYPE_STRING: + return XNVCTRLQueryStringAttributePermissions(h->dpy, a->attr, perms); + + case NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION: + return XNVCTRLQueryStringOperationAttributePermissions(h->dpy, a->attr, + perms); + + case NV_PARSER_ATTRIBUTE_TYPE_COLOR: /* Allow non NV-CONTROL attributes to be read/written on X screen * targets */ @@ -1377,15 +1417,137 @@ Bool nv_get_attribute_perms(CtrlHandles *h, int attr, uint32 flags, ATTRIBUTE_TYPE_READ | ATTRIBUTE_TYPE_WRITE | ATTRIBUTE_TYPE_X_SCREEN; + return TRUE; - return NV_TRUE; + case NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC: + /* Allow SDI CSC matrix to be read/written on X screen targets */ + perms->type = ATTRIBUTE_TYPE_INTEGER; + perms->permissions = + ATTRIBUTE_TYPE_READ | + ATTRIBUTE_TYPE_WRITE | + ATTRIBUTE_TYPE_X_SCREEN; + return TRUE; + } + + /* We shouldn't get here */ + return FALSE; +} + + + +/*! + * Converts the ParsedAttribute 'a''s target list to include the display targets + * (related to the intial non-display targets in the list) as specified by the + * display mask string (or all related displays if the mask is not specified.) + * + * \param[in/out] p ParsedAttribute to resolve. + */ + +static void resolve_display_mask_string(ParsedAttribute *p, const char *whence) +{ + CtrlHandleTargetNode *head = NULL; + CtrlHandleTargetNode *n; + + int bit, i; + + char **name_toks = NULL; + int num_names = 0; + + + /* Resolve the display device specification into a list of display names */ + if (p->parser_flags.has_display_device) { + + if (p->display_device_specification) { + + /* Split up the list of names */ + name_toks = nv_strtok(p->display_device_specification, ',', + &num_names); + + } else if (p->display_device_mask) { + + /* Warn that this usage is deprecated */ + + nv_deprecated_msg("Display mask usage as specified %s has been " + "deprecated and will be removed in the future. " + "Please use display names and/or display target " + "specification instead.", + whence); + + /* Convert the bitmask into a list of names */ + + num_names = count_number_of_bits(p->display_device_mask); + name_toks = nvalloc(num_names * sizeof(char *)); + + i = 0; + for (bit = 0; bit < 24; bit++) { + uint32 mask = (1 << bit); + + if (!(mask & p->display_device_mask)) { + continue; + } + + name_toks[i++] = + display_device_mask_to_display_device_name(mask); + if (i >= num_names) { + break; + } + } + } + } + + /* Look at attribute's target list... */ + for (n = p->targets; n; n = n->next) { + CtrlHandleTarget *t = n->t; + CtrlHandleTargetNode *n_other; + int target_type; + + if (!t->h) { + continue; + } + + target_type = NvCtrlGetTargetType(t->h); + + /* Include display targets that were previously resolved */ + if (target_type == NV_CTRL_TARGET_TYPE_DISPLAY) { + nv_target_list_add(&head, t); + continue; + } + + /* Include non-display target's related display targets, if any */ + for (n_other = t->relations; n_other; n_other = n_other->next) { + CtrlHandleTarget *t_other = n_other->t; + + if (!t_other->h) { + continue; + } + target_type = NvCtrlGetTargetType(t_other->h); + if (target_type != NV_CTRL_TARGET_TYPE_DISPLAY) { + continue; + } + + /* Include all displays if no specification was given */ + if (!p->parser_flags.has_display_device) { + nv_target_list_add(&head, t_other); + continue; + } + + for (i = 0; i < num_names; i++) { + if (nv_target_has_name(t_other, name_toks[i])) { + nv_target_list_add(&head, t_other); + break; + } + } + } } - if (flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) { - return XNVCTRLQueryStringAttributePermissions(h->dpy, attr, perms); + /* Cleanup */ + if (name_toks) { + nv_free_strtoks(name_toks, num_names); } - return XNVCTRLQueryAttributePermissions(h->dpy, attr, perms); + /* Apply the new targets list */ + nv_target_list_free(p->targets); + p->targets = head; } @@ -1401,7 +1563,7 @@ Bool nv_get_attribute_perms(CtrlHandles *h, int attr, uint32 flags, * all non-display targets are further resolved into the corresponding display * targets that match the names represented by the display mask string. * - * \param[in/out] a ParsedAttribute to resolve. + * \param[in/out] p ParsedAttribute to resolve. * \param[in] h CtrlHandles to resolve the target specification against. * * \return Return NV_PARSER_STATUS_SUCCESS if the attribute's target @@ -1410,7 +1572,7 @@ Bool nv_get_attribute_perms(CtrlHandles *h, int attr, uint32 flags, * error codes that detail the particular parsing error. */ -static int resolve_attribute_targets(ParsedAttribute *a, CtrlHandles *h, +static int resolve_attribute_targets(ParsedAttribute *p, CtrlHandles *h, const char *whence) { NVCTRLAttributePermissionsRec perms; @@ -1418,42 +1580,43 @@ static int resolve_attribute_targets(ParsedAttribute *a, CtrlHandles *h, int ret = NV_PARSER_STATUS_SUCCESS; int i; - if (a->targets) { + const AttributeTableEntry *a = p->attr_entry; + + if (p->targets) { // Oops already parsed? // XXX thrown another error here? return NV_PARSER_STATUS_BAD_ARGUMENT; } - - status = nv_get_attribute_perms(h, a->attr, a->flags, &perms); + status = nv_get_attribute_perms(h, a, &perms); if (!status) { // XXX Throw other error here...? return NV_PARSER_STATUS_TARGET_SPEC_NO_TARGETS; } - a->targets = nv_target_list_init(); + p->targets = NULL; /* If a target specification string was given, use that to determine the * list of targets to include. */ - if (a->target_specification) { - ret = nv_infer_targets_from_specification(a, h); + if (p->target_specification) { + ret = nv_infer_targets_from_specification(p, h); goto done; } /* If the target type and target id was given, use that. */ - if (a->target_type >= 0 && a->target_id >= 0) { - CtrlHandleTarget *target = nv_get_target(h, a->target_type, - a->target_id); + if (p->target_type >= 0 && p->target_id >= 0) { + CtrlHandleTarget *target = nv_get_target(h, p->target_type, + p->target_id); if (!target) { return NV_PARSER_STATUS_TARGET_SPEC_NO_TARGETS; } - nv_target_list_add(a->targets, target); - a->flags |= NV_PARSER_HAS_TARGET; + nv_target_list_add(&(p->targets), target); + p->parser_flags.has_target = NV_TRUE; goto done; } @@ -1461,15 +1624,15 @@ static int resolve_attribute_targets(ParsedAttribute *a, CtrlHandles *h, /* If a target type was given, but no target id, process all the targets * of that type. */ - if (a->target_type >= 0) { + if (p->target_type >= 0) { const TargetTypeEntry *targetTypeEntry = - nv_get_target_type_entry_by_nvctrl(a->target_type); + nv_get_target_type_entry_by_nvctrl(p->target_type); if (!targetTypeEntry) { return NV_PARSER_STATUS_TARGET_SPEC_BAD_TARGET; } - include_target_idx_targets(a, h, targetTypeEntry->target_index); + include_target_idx_targets(p, h, targetTypeEntry->target_index); goto done; } @@ -1485,7 +1648,7 @@ static int resolve_attribute_targets(ParsedAttribute *a, CtrlHandles *h, } /* Add all targets of type that are valid for this attribute */ - include_target_idx_targets(a, h, i); + include_target_idx_targets(p, h, i); } done: @@ -1495,104 +1658,14 @@ static int resolve_attribute_targets(ParsedAttribute *a, CtrlHandles *h, * specified via either name string or value, use that to limit the * displays added, otherwise include all related display targets. */ - if (!(a->flags & NV_PARSER_TYPE_HIJACK_DISPLAY_DEVICE) && + if (!(a->flags.hijack_display_device) && (perms.permissions & ATTRIBUTE_TYPE_DISPLAY)) { - CtrlHandleTargetNode *head = nv_target_list_init(); - CtrlHandleTargetNode *n; - - uint32 display_mask; - int bit, i; - - char *name_list[32]; - int num_names = 0; - - - /* Convert user string into display device mask */ - if (a->flags & NV_PARSER_HAS_DISPLAY_DEVICE) { - display_mask = - expand_display_device_mask_wildcards(a->display_device_mask); - - /* Warn that this usage is deprecated */ - - nv_deprecated_msg("Display mask usage as specified %s has been " - "deprecated and will be removed in the future." - "Please use display names and/or display target " - "specification instead.", - whence); - } else { - display_mask = VALID_DISPLAY_DEVICES_MASK; - } - - /* Convert the bitmask into a list of names */ - for (bit = 0; bit < 24; bit++) { - uint32 mask = (1 << bit); - - if (!(mask & display_mask)) { - continue; - } - - name_list[num_names] = display_device_mask_to_display_device_name(mask); - if (name_list[num_names]) { - num_names++; - } - } - - /* Look at attribute's target list... */ - for (n = a->targets; n->next; n = n->next) { - CtrlHandleTarget *t = n->t; - CtrlHandleTargetNode *n_other; - int target_type; - - if (!t->h) { - continue; - } - - target_type = NvCtrlGetTargetType(t->h); - - /* Include display targets */ - if (target_type == NV_CTRL_TARGET_TYPE_DISPLAY) { - /* Make sure to include display targets in final list */ - nv_target_list_add(head, t); - continue; - } - - /* Include non-display target's related display targets, if any */ - for (n_other = t->relations; - n_other->next; - n_other = n_other->next) { - CtrlHandleTarget *t_other = n_other->t; - - if (!t_other->h) { - continue; - } - target_type = NvCtrlGetTargetType(t_other->h); - if (target_type != NV_CTRL_TARGET_TYPE_DISPLAY) { - continue; - } - - for (i = 0; i < num_names; i++) { - if (nv_strcasecmp(name_list[i], - t_other->protoNames[NV_DPY_PROTO_NAME_TYPE_ID])) { - nv_target_list_add(head, t_other); - break; - } - } - } - } - - /* Cleanup */ - for (i = 0; i < num_names; i++) { - nvfree(name_list[i]); - } - - /* Apply the new targets list */ - nv_target_list_free(a->targets); - a->targets = head; + resolve_display_mask_string(p, whence); } /* Make sure at least one target was resolved */ if (ret == NV_PARSER_STATUS_SUCCESS) { - if (!(a->flags & NV_PARSER_HAS_TARGET)) { + if (!(p->parser_flags.has_target)) { return NV_PARSER_STATUS_TARGET_SPEC_NO_TARGETS; } } @@ -1610,7 +1683,8 @@ static int resolve_attribute_targets(ParsedAttribute *a, CtrlHandles *h, * NV_FALSE is returned. Otherwise, NV_TRUE is returned. */ -static int process_attribute_queries(int num, char **queries, +static int process_attribute_queries(const Options *op, + int num, char **queries, const char *display_name, CtrlHandlesArray *handles_array) { @@ -1622,7 +1696,9 @@ static int process_attribute_queries(int num, char **queries, /* print a newline before we begin */ - if (!__terse) nv_msg(NULL, ""); + if (!op->terse) { + nv_msg(NULL, ""); + } /* loop over each requested query */ @@ -1631,7 +1707,7 @@ static int process_attribute_queries(int num, char **queries, /* special case the "all" query */ if (nv_strcasecmp(queries[query], "all")) { - query_all(display_name, handles_array); + query_all(op, display_name, handles_array); continue; } @@ -1707,12 +1783,14 @@ static int process_attribute_queries(int num, char **queries, /* call the processing engine to process the parsed query */ - ret = nv_process_parsed_attribute(&a, h, NV_FALSE, NV_FALSE, + ret = nv_process_parsed_attribute(op, &a, h, NV_FALSE, NV_FALSE, "in query '%s'", queries[query]); if (ret == NV_FALSE) goto done; - + /* print a newline at the end */ - if (!__terse) nv_msg(NULL, ""); + if (!op->terse) { + nv_msg(NULL, ""); + } } /* query */ @@ -1735,7 +1813,8 @@ static int process_attribute_queries(int num, char **queries, * NV_FALSE is returned. Otherwise, NV_TRUE is returned. */ -static int process_attribute_assignments(int num, char **assignments, +static int process_attribute_assignments(const Options *op, + int num, char **assignments, const char *display_name, CtrlHandlesArray *handles_array) { @@ -1777,7 +1856,7 @@ static int process_attribute_assignments(int num, char **assignments, /* call the processing engine to process the parsed assignment */ - ret = nv_process_parsed_attribute(&a, h, NV_TRUE, NV_TRUE, + ret = nv_process_parsed_attribute(op, &a, h, NV_TRUE, NV_TRUE, "in assignment '%s'", assignments[assignment]); if (ret == NV_FALSE) goto done; @@ -1799,12 +1878,13 @@ static int process_attribute_assignments(int num, char **assignments, /* - * validate_value() - query the valid values for the specified + * validate_value() - query the valid values for the specified integer * attribute, and check that the value to be assigned is valid. */ -static int validate_value(CtrlHandleTarget *t, ParsedAttribute *a, uint32 d, - int target_type, char *whence) +static int validate_value(const Options *op, CtrlHandleTarget *t, + ParsedAttribute *p, uint32 d, int target_type, + char *whence) { int bad_val = NV_FALSE; NVCTRLAttributeValidValuesRec valid; @@ -1812,9 +1892,13 @@ static int validate_value(CtrlHandleTarget *t, ParsedAttribute *a, uint32 d, char d_str[256]; char *tmp_d_str; const TargetTypeEntry *targetTypeEntry; + const AttributeTableEntry *a = p->attr_entry; + + if (a->type != NV_PARSER_ATTRIBUTE_TYPE_INTEGER) { + return NV_FALSE; + } status = NvCtrlGetValidDisplayAttributeValues(t->h, d, a->attr, &valid); - if (status != NvCtrlSuccess) { nv_error_msg("Unable to query valid values for attribute %s (%s).", a->name, NvCtrlAttributesStrError(status)); @@ -1836,37 +1920,37 @@ static int validate_value(CtrlHandleTarget *t, ParsedAttribute *a, uint32 d, /* don't do any checks on integer or bitmask values */ break; case ATTRIBUTE_TYPE_BOOL: - if ((a->val.i < 0) || (a->val.i > 1)) { + if ((p->val.i < 0) || (p->val.i > 1)) { bad_val = NV_TRUE; } break; case ATTRIBUTE_TYPE_RANGE: - if (a->flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { - if (((a->val.i >> 16) < (valid.u.range.min >> 16)) || - ((a->val.i >> 16) > (valid.u.range.max >> 16)) || - ((a->val.i & 0xffff) < (valid.u.range.min & 0xffff)) || - ((a->val.i & 0xffff) > (valid.u.range.max & 0xffff))) + 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))) bad_val = NV_TRUE; } else { - if ((a->val.i < valid.u.range.min) || - (a->val.i > valid.u.range.max)) + if ((p->val.i < valid.u.range.min) || + (p->val.i > valid.u.range.max)) bad_val = NV_TRUE; } break; case ATTRIBUTE_TYPE_INT_BITS: - if (a->flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + if (a->f.int_flags.is_packed) { unsigned int u, l; - u = (((unsigned int) a->val.i) >> 16); - l = (a->val.i & 0xffff); + 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)) { bad_val = NV_TRUE; } } else { - if ((a->val.i > 31) || (a->val.i < 0) || - ((valid.u.bits.ints & (1<<a->val.i)) == 0)) { + if ((p->val.i > 31) || (p->val.i < 0) || + ((valid.u.bits.ints & (1<<p->val.i)) == 0)) { bad_val = NV_TRUE; } } @@ -1887,19 +1971,19 @@ static int validate_value(CtrlHandleTarget *t, ParsedAttribute *a, uint32 d, /* if the value is bad, print why */ if (bad_val) { - if (a->flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + if (a->f.int_flags.is_packed) { nv_warning_msg("The value pair %d,%d for attribute '%s' (%s%s) " "specified %s is invalid.", - a->val.i >> 16, a->val.i & 0xffff, + p->val.i >> 16, p->val.i & 0xffff, a->name, t->name, d_str, whence); } else { nv_warning_msg("The value %d for attribute '%s' (%s%s) " "specified %s is invalid.", - a->val.i, a->name, t->name, + p->val.i, a->name, t->name, d_str, whence); } - print_valid_values(a->name, a->attr, a->flags, valid); + print_valid_values(op, a, valid); return NV_FALSE; } return NV_TRUE; @@ -1913,7 +1997,7 @@ static int validate_value(CtrlHandleTarget *t, ParsedAttribute *a, uint32 d, * attribute. */ -static void print_valid_values(const char *name, int attr, uint32 flags, +static void print_valid_values(const Options *op, const AttributeTableEntry *a, NVCTRLAttributeValidValuesRec valid) { int bit, print_bit, last, last2, n, i; @@ -1922,10 +2006,13 @@ static void print_valid_values(const char *name, int attr, uint32 flags, char str2[256]; char *c2; char **at; + const char *name = a->name; /* do not print any valid values information when we are in 'terse' mode */ - if (__terse) return; + if (op->terse) { + return; + } #define INDENT " " @@ -1939,24 +2026,26 @@ static void print_valid_values(const char *name, int attr, uint32 flags, break; case ATTRIBUTE_TYPE_INTEGER: - if (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + if ((a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.is_packed) { nv_msg(INDENT, "'%s' is a packed integer attribute.", name); } else { nv_msg(INDENT, "'%s' is an integer attribute.", name); } break; - + case ATTRIBUTE_TYPE_BITMASK: nv_msg(INDENT, "'%s' is a bitmask attribute.", name); break; - + case ATTRIBUTE_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: - if (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + if ((a->type == NV_PARSER_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).", @@ -1976,7 +2065,9 @@ static void print_valid_values(const char *name, int attr, uint32 flags, for (bit = 0; bit < 32; bit++) { if (valid.u.bits.ints & (1 << bit)) { - if ((bit > 15) && (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE)) { + if ((bit > 15) && + (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.is_packed) { last2 = bit; } else { last = bit; @@ -1991,8 +2082,10 @@ static void print_valid_values(const char *name, int attr, uint32 flags, c = str; c2 = str2; for (bit = 0; bit < 32; bit++) { - - if ((bit > 15) && (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE)) { + + if ((bit > 15) && + (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.is_packed) { print_bit = bit - 16; at = &c2; } else { @@ -2011,7 +2104,8 @@ static void print_valid_values(const char *name, int attr, uint32 flags, } } - if (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + if ((a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.is_packed) { nv_msg(INDENT, "Valid values for '%s' are: [%s], [%s].", name, str2, str); } else { @@ -2046,8 +2140,11 @@ static void print_valid_values(const char *name, int attr, uint32 flags, nv_msg(INDENT, "'%s' can use the following target types: %s.", name, str); - if (__verbosity >= VERBOSITY_ALL) - print_additional_info(name, attr, valid, INDENT); + if (nv_get_verbosity() >= NV_VERBOSITY_ALL) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) { + print_additional_info(name, a->attr, valid, INDENT); + } + } #undef INDENT @@ -2056,7 +2153,7 @@ static void print_valid_values(const char *name, int attr, uint32 flags, /* - * print_queried_value() - print the attribute value that we queried + * print_queried_value() - print the (integer) attribute value that we queried * from NV-CONTROL */ @@ -2066,40 +2163,42 @@ typedef enum { VerboseLevelVerbose, } VerboseLevel; -static void print_queried_value(const CtrlHandles *handles, +static void print_queried_value(const Options *op, + const CtrlHandles *handles, CtrlHandleTarget *t, NVCTRLAttributeValidValuesRec *v, int val, - uint32 flags, - char *name, + const AttributeTableEntry *a, uint32 mask, const char *indent, const VerboseLevel level) { char d_str[64], val_str[64], *tmp_d_str; + if (a->type != NV_PARSER_ATTRIBUTE_TYPE_INTEGER) { + return; + } + /* assign val_str */ - if ((flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID) && - (__display_device_string)) { + if (a->f.int_flags.is_display_id && op->dpy_string) { const char *name = nv_get_display_target_config_name(handles, val); if (name) { snprintf(val_str, 64, "%s", name); } else { snprintf(val_str, 64, "%d", val); } - } else if ((flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY) && - (__display_device_string)) { + } else if (a->f.int_flags.is_display_mask && op->dpy_string) { tmp_d_str = display_device_mask_to_display_device_name(val); snprintf(val_str, 64, "%s", tmp_d_str); free(tmp_d_str); - } else if (flags & NV_PARSER_TYPE_100Hz) { + } else if (a->f.int_flags.is_100Hz) { snprintf(val_str, 64, "%.2f Hz", ((float) val) / 100.0); - } else if (flags & NV_PARSER_TYPE_1000Hz) { + } 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) { snprintf(val_str, 64, "0x%08x", val); - } else if (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + } else if (a->f.int_flags.is_packed) { snprintf(val_str, 64, "%d,%d", val >> 16, val & 0xffff); } else { snprintf(val_str, 64, "%d", val); @@ -2127,7 +2226,7 @@ static void print_queried_value(const CtrlHandles *handles, case VerboseLevelAbbreviated: /* print the value with indentation and the attribute name */ - nv_msg(indent, "%s: %s", name, val_str); + nv_msg(indent, "%s: %s", a->name, val_str); break; case VerboseLevelVerbose: @@ -2136,7 +2235,7 @@ static void print_queried_value(const CtrlHandles *handles, * attribute */ nv_msg(indent, "Attribute '%s' (%s%s): %s.", - name, t->name, d_str, val_str); + a->name, t->name, d_str, val_str); break; } @@ -2145,6 +2244,29 @@ static void print_queried_value(const CtrlHandles *handles, /* + * print_additional_stereo_info() - print the available stereo modes + */ + +static void print_additional_stereo_info(const char *name, + unsigned int valid_stereo_modes, + const char *indent) +{ + int bit; + + nv_msg(indent, "\n"); + nv_msg(indent, "Valid '%s' Values\n", name); + nv_msg(indent, " value - description\n"); + + for (bit = 0; bit < 32; bit++) { + if (valid_stereo_modes & (1 << bit)) { + nv_msg(indent, " %2u - %s\n", + bit, NvCtrlGetStereoModeName(bit)); + } + } +} + + +/* * print_additional_fsaa_info() - print the currently available fsaa * modes with their corresponding names */ @@ -2192,6 +2314,12 @@ static void print_additional_info(const char *name, print_additional_fsaa_info(name, valid.u.bits.ints, indent); break; + case NV_CTRL_STEREO: + if (valid.type == ATTRIBUTE_TYPE_INT_BITS) { + print_additional_stereo_info(name, valid.u.bits.ints, indent); + } + break; + // add more here } @@ -2210,7 +2338,8 @@ static void print_additional_info(const char *name, * returned; if successful, NV_TRUE is returned. */ -static int query_all(const char *display_name, CtrlHandlesArray *handles_array) +static int query_all(const Options *op, const char *display_name, + CtrlHandlesArray *handles_array) { int bit, entry, val, i; uint32 mask; @@ -2242,18 +2371,24 @@ static int query_all(const char *display_name, CtrlHandlesArray *handles_array) nv_msg(NULL, "Attributes queryable via %s:", t->name); - if (!__terse) nv_msg(NULL, ""); + if (!op->terse) { + nv_msg(NULL, ""); + } - for (entry = 0; attributeTable[entry].name; entry++) { + for (entry = 0; entry < attributeTableLen; entry++) { const AttributeTableEntry *a = &attributeTable[entry]; /* skip the color attributes */ - if (a->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) continue; + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_COLOR) { + continue; + } /* skip attributes that shouldn't be queried here */ - if (a->flags & NV_PARSER_TYPE_NO_QUERY_ALL) continue; + if (a->flags.no_query_all) { + continue; + } for (bit = 0; bit < 24; bit++) { mask = 1 << bit; @@ -2267,7 +2402,7 @@ static int query_all(const char *display_name, CtrlHandlesArray *handles_array) if (targetTypeTable[i].uses_display_devices && ((t->d & mask) == 0x0) && (t->d)) continue; - if (a->flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_STRING) { char *tmp_str = NULL; status = NvCtrlGetValidStringDisplayAttributeValues(t->h, mask, @@ -2297,7 +2432,7 @@ static int query_all(const char *display_name, CtrlHandlesArray *handles_array) goto exit_bit_loop; } - if (__terse) { + if (op->terse) { nv_msg(" ", "%s: %s", a->name, tmp_str); } else { nv_msg(" ", "Attribute '%s' (%s%s): %s ", @@ -2331,15 +2466,17 @@ static int query_all(const char *display_name, CtrlHandlesArray *handles_array) goto exit_bit_loop; } - print_queried_value(h, t, &valid, val, a->flags, - a->name, mask, INDENT, __terse ? + print_queried_value(op, h, t, &valid, val, a, mask, + INDENT, op->terse ? VerboseLevelAbbreviated : VerboseLevelVerbose); } - print_valid_values(a->name, a->attr, a->flags, valid); + print_valid_values(op, a, valid); - if (!__terse) nv_msg(NULL,""); + if (!op->terse) { + nv_msg(NULL,""); + } if (valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { continue; @@ -2374,7 +2511,7 @@ exit_bit_loop: static char * get_product_name(NvCtrlAttributeHandle *h, int attr) { - char *product_name; + char *product_name = NULL; ReturnStatus status; status = NvCtrlGetStringAttribute(h, attr, &product_name); @@ -2388,33 +2525,36 @@ static char * get_product_name(NvCtrlAttributeHandle *h, int attr) /* * Returns the (RandR) display device name to use for printing the given - * display target. If 'show_connected_state' is true, "connected" will be - * appended to the name. + * display target. */ -static void get_display_product_name(CtrlHandleTarget *t, char *buf, int len, - Bool show_connect_state) +static char *get_display_product_name(CtrlHandleTarget *t) { - const CtrlHandleTargetNode *n; - const char *connected_str = ""; + return nvstrdup(t->protoNames[NV_DPY_PROTO_NAME_RANDR]); +} - /* Check to see if display is connected (has a GPU relation) */ - if (show_connect_state) { - for (n = t->relations; - n->next; - n = n->next) { - int target_type = NvCtrlGetTargetType(n->t->h); - if (target_type == NV_CTRL_TARGET_TYPE_GPU) { - connected_str = ") (connected"; - break; - } - } + +/* + * Returns the connection and enabled state of the display device as a comma + * separated string. + */ + +static char *get_display_state_str(CtrlHandleTarget *t) +{ + char *str = NULL; + + if (t->display.connected) { + str = nvstrdup("connected"); + } + + if (t->display.enabled) { + nv_append_sprintf(&str, "%s%s", + str ? ", " : "", + "enabled"); } - snprintf(buf, len, "%s%s", - t->protoNames[NV_DPY_PROTO_NAME_RANDR], - connected_str); + return str; } @@ -2428,18 +2568,14 @@ static void get_display_product_name(CtrlHandleTarget *t, char *buf, int len, static int print_target_connections(CtrlHandles *h, CtrlHandleTarget *t, const char *relation_str, + const char *null_relation_str, unsigned int attrib, unsigned int target_index) { int *pData; int len, i; ReturnStatus status; - char *product_name; - char *target_name; const TargetTypeEntry *targetTypeEntry; - Bool show_dpy_connection_state = - (attrib == NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN) ? - NV_TRUE : NV_FALSE; targetTypeEntry = &(targetTypeTable[target_index]); @@ -2453,8 +2589,8 @@ static int print_target_connections(CtrlHandles *h, if (status != NvCtrlSuccess) return NV_FALSE; if (pData[0] == 0) { - nv_msg(" ", "Is not %s any %s.", - relation_str, + nv_msg(" ", "%s any %s.", + null_relation_str, targetTypeEntry->name); nv_msg(NULL, ""); @@ -2462,7 +2598,7 @@ static int print_target_connections(CtrlHandles *h, return NV_TRUE; } - nv_msg(" ", "Is %s the following %s%s:", + nv_msg(" ", "%s the following %s%s:", relation_str, targetTypeEntry->name, ((pData[0] > 1) ? "s" : "")); @@ -2472,6 +2608,11 @@ static int print_target_connections(CtrlHandles *h, for (i = 1; i <= pData[0]; i++) { CtrlHandleTarget *target = nv_get_target(h, targetTypeEntry->nvctrl, pData[i]); + char *target_name = NULL; + char *product_name = NULL; + Bool is_x_name = NV_FALSE; + char *extra_str = NULL; + if (target) { target_name = target->name; @@ -2480,18 +2621,19 @@ static int print_target_connections(CtrlHandles *h, case GPU_TARGET: product_name = get_product_name(target->h, NV_CTRL_STRING_PRODUCT_NAME); + is_x_name = NV_TRUE; break; case VCS_TARGET: product_name = get_product_name(target->h, NV_CTRL_STRING_VCSC_PRODUCT_NAME); + is_x_name = NV_TRUE; break; case DISPLAY_TARGET: - product_name = nvalloc(PRODUCT_NAME_LEN); - get_display_product_name(target, product_name, PRODUCT_NAME_LEN, - show_dpy_connection_state); + product_name = get_display_product_name(target); + extra_str = get_display_state_str(target); break; case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET: @@ -2501,13 +2643,8 @@ static int print_target_connections(CtrlHandles *h, case GVI_TARGET: case X_SCREEN_TARGET: default: - product_name = NULL; break; } - - } else { - target_name = NULL; - product_name = NULL; } if (!target_name) { @@ -2515,9 +2652,11 @@ static int print_target_connections(CtrlHandles *h, targetTypeEntry->name); } else if (product_name) { - nv_msg(" ", "%s (%s)", - target_name, product_name); - + nv_msg(" ", "%s (%s)%s%s%s", + target_name, product_name, + extra_str ? " (" : "", + extra_str ? extra_str : "", + extra_str ? ")" : ""); } else { nv_msg(" ", "%s (%s %d)", target_name, @@ -2525,7 +2664,16 @@ static int print_target_connections(CtrlHandles *h, pData[i]); } - free(product_name); + if (product_name) { + if (is_x_name) { + XFree(product_name); + } else { + nvfree(product_name); + } + } + if (extra_str) { + nvfree(extra_str); + } } nv_msg(NULL, ""); @@ -2585,9 +2733,10 @@ static int query_all_targets(const char *display_name, const int target_index, /* print information per target */ for (i = 0; i < h->targets[target_index].n; i++) { - char product_name[PRODUCT_NAME_LEN]; + char buff[PRODUCT_NAME_LEN]; Bool is_x_name = NV_FALSE; - char *x_name = NULL; + char *product_name = buff; + char *extra_str = NULL; t = &h->targets[target_index].t[i]; @@ -2605,16 +2754,17 @@ static int query_all_targets(const char *display_name, const int target_index, snprintf(product_name, PRODUCT_NAME_LEN, "Quadro Sync %d", i); } else if (target_index == VCS_TARGET) { - x_name = get_product_name(t->h, NV_CTRL_STRING_VCSC_PRODUCT_NAME); + product_name = + get_product_name(t->h, NV_CTRL_STRING_VCSC_PRODUCT_NAME); is_x_name = NV_TRUE; } else if (target_index == GVI_TARGET) { snprintf(product_name, PRODUCT_NAME_LEN, "SDI Input %d", i); } else if (target_index == DISPLAY_TARGET) { - get_display_product_name(t, product_name, PRODUCT_NAME_LEN, - NV_FALSE); + product_name = get_display_product_name(t); + extra_str = get_display_state_str(t); } else { - x_name = get_product_name(t->h, NV_CTRL_STRING_PRODUCT_NAME); + product_name = get_product_name(t->h, NV_CTRL_STRING_PRODUCT_NAME); is_x_name = NV_TRUE; } @@ -2630,46 +2780,63 @@ static int query_all_targets(const char *display_name, const int target_index, name = "Not NVIDIA"; } - nv_msg(" ", "[%d] %s (%s)", i, name, - is_x_name ? x_name : product_name); + nv_msg(" ", "[%d] %s (%s)%s%s%s", + i, name, + product_name, + extra_str ? " (" : "", + extra_str ? extra_str : "", + extra_str ? ")" : ""); nv_msg(NULL, ""); - if (x_name) { - XFree(x_name); + if (product_name != buff) { + if (is_x_name) { + XFree(product_name); + } else { + nvfree(product_name); + } + } + if (extra_str) { + nvfree(extra_str); } /* Print connectivity information */ - if (__verbosity >= VERBOSITY_ALL) { + if (nv_get_verbosity() >= NV_VERBOSITY_ALL) { switch (target_index) { case GPU_TARGET: print_target_connections (h, t, - "driving", + "Is driving", + "Is not driving", NV_CTRL_BINARY_DATA_XSCREENS_USING_GPU, X_SCREEN_TARGET); print_target_connections (h, t, - "connected to", - NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU, + "Supports", + "Does not support", + NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU, DISPLAY_TARGET); print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU, FRAMELOCK_TARGET); print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_VCSCS_USED_BY_GPU, VCS_TARGET); print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU, COOLER_TARGET); print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU, THERMAL_SENSOR_TARGET); break; @@ -2677,12 +2844,14 @@ static int query_all_targets(const char *display_name, const int target_index, case X_SCREEN_TARGET: print_target_connections (h, t, - "driven by", + "Is driven by", + "Is not driven by", NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN, GPU_TARGET); print_target_connections (h, t, - "assigned", + "Is assigned", + "Is not assigned", NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN, DISPLAY_TARGET); break; @@ -2690,7 +2859,8 @@ static int query_all_targets(const char *display_name, const int target_index, case FRAMELOCK_TARGET: print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK, GPU_TARGET); break; @@ -2698,7 +2868,8 @@ static int query_all_targets(const char *display_name, const int target_index, case VCS_TARGET: print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_GPUS_USING_VCSC, GPU_TARGET); break; @@ -2706,7 +2877,8 @@ static int query_all_targets(const char *display_name, const int target_index, case COOLER_TARGET: print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU, COOLER_TARGET); break; @@ -2714,7 +2886,8 @@ static int query_all_targets(const char *display_name, const int target_index, case THERMAL_SENSOR_TARGET: print_target_connections (h, t, - "connected to", + "Is connected to", + "Is not connected to", NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU, THERMAL_SENSOR_TARGET); break; @@ -2739,9 +2912,10 @@ static int query_all_targets(const char *display_name, const int target_index, * returned; if successful, NV_TRUE is returned. */ -static int process_parsed_attribute_internal(const CtrlHandles *handles, +static int process_parsed_attribute_internal(const Options *op, + const CtrlHandles *handles, CtrlHandleTarget *t, - ParsedAttribute *a, uint32 d, + ParsedAttribute *p, uint32 d, int target_type, int assign, int verbose, char *whence, NVCTRLAttributeValidValuesRec @@ -2750,6 +2924,7 @@ static int process_parsed_attribute_internal(const CtrlHandles *handles, ReturnStatus status; char str[32], *tmp_d_str; int ret; + const AttributeTableEntry *a = p->attr_entry; if (target_type != NV_CTRL_TARGET_TYPE_DISPLAY && valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { @@ -2761,39 +2936,40 @@ static int process_parsed_attribute_internal(const CtrlHandles *handles, } if (assign) { - if (a->flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) { - status = NvCtrlSetStringAttribute(t->h, a->attr, a->val.str, NULL); + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_STRING) { + status = NvCtrlSetStringAttribute(t->h, a->attr, p->val.str, NULL); } else { - ret = validate_value(t, a, d, target_type, whence); + ret = validate_value(op, t, p, d, target_type, whence); if (!ret) return NV_FALSE; - status = NvCtrlSetDisplayAttribute(t->h, d, a->attr, a->val.i); + status = NvCtrlSetDisplayAttribute(t->h, d, a->attr, p->val.i); if (status != NvCtrlSuccess) { nv_error_msg("Error assigning value %d to attribute '%s' " "(%s%s) as specified %s (%s).", - a->val.i, a->name, t->name, str, whence, + p->val.i, a->name, t->name, str, whence, NvCtrlAttributesStrError(status)); return NV_FALSE; } if (verbose) { - if (a->flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { + if (a->f.int_flags.is_packed) { nv_msg(" ", "Attribute '%s' (%s%s) assigned value %d,%d.", a->name, t->name, str, - a->val.i >> 16, a->val.i & 0xffff); + p->val.i >> 16, p->val.i & 0xffff); } else { nv_msg(" ", "Attribute '%s' (%s%s) assigned value %d.", - a->name, t->name, str, a->val.i); + a->name, t->name, str, p->val.i); } } } } else { /* query */ - if (a->flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_STRING) { char *tmp_str = NULL; - status = NvCtrlGetStringDisplayAttribute(t->h, d, a->attr, &tmp_str); + status = NvCtrlGetStringDisplayAttribute(t->h, d, a->attr, + &tmp_str); if (status == NvCtrlAttributeNotAvailable) { nv_warning_msg("Error querying attribute '%s' specified %s; " @@ -2808,17 +2984,17 @@ static int process_parsed_attribute_internal(const CtrlHandles *handles, return NV_FALSE; } else { - if (__terse) { + if (op->terse) { nv_msg(NULL, "%s", tmp_str); } else { nv_msg(" ", "Attribute '%s' (%s%s): %s", a->name, t->name, str, tmp_str); } - free(tmp_str); + free(tmp_str); tmp_str = NULL; } } else { - status = NvCtrlGetDisplayAttribute(t->h, d, a->attr, &a->val.i); + status = NvCtrlGetDisplayAttribute(t->h, d, a->attr, &p->val.i); if (status == NvCtrlAttributeNotAvailable) { nv_warning_msg("Error querying attribute '%s' specified %s; " @@ -2832,10 +3008,10 @@ static int process_parsed_attribute_internal(const CtrlHandles *handles, NvCtrlAttributesStrError(status)); return NV_FALSE; } else { - print_queried_value(handles, t, &valid, a->val.i, a->flags, - a->name, d, " ", __terse ? + print_queried_value(op, handles, t, &valid, p->val.i, a, d, + " ", op->terse ? VerboseLevelTerse : VerboseLevelVerbose); - print_valid_values(a->name, a->attr, a->flags, valid); + print_valid_values(op, a, valid); } } } /* query */ @@ -2896,7 +3072,8 @@ static int process_parsed_attribute_internal(const CtrlHandles *handles, * error message will be printed and NV_FALSE will be returned. */ -int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, +int nv_process_parsed_attribute(const Options *op, + ParsedAttribute *p, CtrlHandles *h, int assign, int verbose, char *whence_fmt, ...) { @@ -2905,6 +3082,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, ReturnStatus status; CtrlHandleTargetNode *n; NVCTRLAttributeValidValuesRec valid; + const AttributeTableEntry *a = p->attr_entry; val = NV_FALSE; @@ -2912,7 +3090,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, /* build the whence string */ NV_VSNPRINTF(whence, whence_fmt); - + if (!whence) whence = strdup("\0"); /* if we don't have a Display connection, abort now */ @@ -2925,8 +3103,8 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, } /* Print deprecation messages */ - if (strncmp(a->attr_entry->desc, "DEPRECATED", 10) == 0) { - const char *str = a->attr_entry->desc + 10; + if (strncmp(a->desc, "DEPRECATED", 10) == 0) { + const char *str = a->desc + 10; while (*str && (*str == ':' || *str == '.')) { str++; @@ -2941,11 +3119,11 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * allocated. */ - ret = resolve_attribute_targets(a, h, whence); + ret = resolve_attribute_targets(p, h, whence); if (ret != NV_PARSER_STATUS_SUCCESS) { nv_error_msg("Error resolving target specification '%s' " "(%s), specified %s.", - a->target_specification ? a->target_specification : "", + p->target_specification ? p->target_specification : "", nv_parse_strerror(ret), whence); goto done; @@ -2953,7 +3131,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, /* loop over the requested targets */ - for (n = a->targets; n->next; n = n->next) { + for (n = p->targets; n; n = n->next) { CtrlHandleTarget *t = n->t; int target_type; @@ -2964,7 +3142,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, target_type = NvCtrlGetTargetType(t->h); - if (__list_targets) { + if (op->list_targets) { const char *name = t->protoNames[0]; const char *randr_name = NULL; @@ -2987,7 +3165,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, /* special case the color attributes */ - if (a->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_COLOR) { float v[3]; if (!assign) { nv_error_msg("Cannot query attribute '%s'", a->name); @@ -2995,18 +3173,18 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, } /* - * assign a->val.f to all values in the array; a->attr will + * assign p->val.f to all values in the array; a->attr will * tell NvCtrlSetColorAttributes() which indices in the * array to use */ - v[0] = v[1] = v[2] = a->val.f; + v[0] = v[1] = v[2] = p->val.f; status = NvCtrlSetColorAttributes(t->h, v, v, v, a->attr); if (status != NvCtrlSuccess) { nv_error_msg("Error assigning %f to attribute '%s' on %s " - "specified %s (%s)", a->val.f, a->name, + "specified %s (%s)", p->val.f, a->name, t->name, whence, NvCtrlAttributesStrError(status)); goto done; @@ -3021,18 +3199,20 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * either the mask of enabled display devices or the mask of * connected display devices. */ - - if (assign && (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY)) { + + if (assign && + (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.is_display_mask) { char *display_device_descriptor = NULL; uint32 check_mask; /* use the complete mask if requested */ - if (a->flags & NV_PARSER_TYPE_ASSIGN_ALL_DISPLAYS) { - if (a->flags & NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY) { - a->val.i = t->c; + if (p->parser_flags.assign_all_displays) { + if (a->f.int_flags.is_switch_display) { + p->val.i = t->c; } else { - a->val.i = t->d; + p->val.i = t->d; } } @@ -3042,7 +3222,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * display devices */ - if (a->flags & NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY) { + if (a->f.int_flags.is_switch_display) { check_mask = t->c; display_device_descriptor = "connected"; } else { @@ -3050,10 +3230,10 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, display_device_descriptor = "enabled"; } - if ((check_mask & a->val.i) != a->val.i) { + if ((check_mask & p->val.i) != p->val.i) { tmp_d_str0 = - display_device_mask_to_display_device_name(a->val.i); + display_device_mask_to_display_device_name(p->val.i); tmp_d_str1 = display_device_mask_to_display_device_name(check_mask); @@ -3080,7 +3260,9 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * id, if any, is then fed back into the ParsedAttrinute's value as an * int which is ultimately written out to NV-CONTROL. */ - if (assign && (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY_ID)) { + if (assign && + (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.is_display_id) { CtrlHandleTargets *dpy_targets = &(h->targets[DISPLAY_TARGET]); int i; int found = NV_FALSE; @@ -3091,9 +3273,9 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, /* See if value is a simple number */ - id = strtol(a->val.str, &tmp, 0); + id = strtol(p->val.str, &tmp, 0); is_id = (tmp && - (tmp != a->val.str) && + (tmp != p->val.str) && (*tmp == '\0')); for (i = 0; i < dpy_targets->n; i++) { @@ -3107,7 +3289,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, } } else { /* Value given as display device name */ - if (nv_target_has_name(dpy_target, a->val.str)) { + if (nv_target_has_name(dpy_target, p->val.str)) { if (found) { multi_match = TRUE; break; @@ -3128,7 +3310,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, "assigned the value of '%s' (This name matches " "multiple display devices, please use a non-" "ambiguous name.", - a->name, whence, a->val.str); + a->name, whence, p->val.str); continue; } @@ -3136,12 +3318,12 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, nv_error_msg("The attribute '%s' specified %s cannot be " "assigned the value of '%s' (This does not " "name an available display device).", - a->name, whence, a->val.str); + a->name, whence, p->val.str); continue; } /* Put converted id back into a->val */ - a->val.i = id; + p->val.i = id; } @@ -3150,13 +3332,15 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * not allowed to be zero, check that the value is not zero. */ - if (assign && (a->flags & NV_PARSER_TYPE_NO_ZERO_VALUE)) { - + if (assign && + (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + a->f.int_flags.no_zero) { + /* value must be non-zero */ - if (!a->val.i) { - - if (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY) { + if (!p->val.i) { + + if (a->f.int_flags.is_display_mask) { tmp_d_str0 = "display device"; } else { tmp_d_str0 = "value"; @@ -3169,7 +3353,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, continue; } } - + /* * If we are dealing with a frame lock attribute on a non-frame lock * target type, make sure frame lock is available. @@ -3180,10 +3364,10 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * Signal" attribute.) */ - if ((a->flags & NV_PARSER_TYPE_FRAMELOCK) && + if (a->flags.is_framelock_attribute && (target_type != NV_CTRL_TARGET_TYPE_FRAMELOCK)) { int available; - + status = NvCtrlGetAttribute(t->h, NV_CTRL_FRAMELOCK, &available); if (status != NvCtrlSuccess) { nv_error_msg("The attribute '%s' specified %s cannot be " @@ -3193,7 +3377,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, t->name, NvCtrlAttributesStrError(status)); continue; } - + if (available != NV_CTRL_FRAMELOCK_SUPPORTED) { nv_error_msg("The attribute '%s' specified %s cannot be %s; " "frame lock is not supported/available on %s.", @@ -3204,11 +3388,13 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, /* Do assignments based on the frame lock sync status */ - if (assign && (a->attr != NV_CTRL_FRAMELOCK_SYNC)) { + if (assign && + (a->type == NV_PARSER_ATTRIBUTE_TYPE_INTEGER) && + (a->attr != NV_CTRL_FRAMELOCK_SYNC)) { int enabled; - status = NvCtrlGetAttribute(t->h, NV_CTRL_FRAMELOCK_SYNC, - &enabled); + status = get_framelock_sync_state(t->h, h, &enabled); + if (status != NvCtrlSuccess) { nv_error_msg("The attribute '%s' specified %s cannot be " "assigned; error querying frame lock sync " @@ -3241,7 +3427,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * sure that GVO is supported by the handle. */ - if (a->flags & NV_PARSER_TYPE_SDI && + if (a->flags.is_sdi_attribute && target_type != NV_CTRL_TARGET_TYPE_GVI) { int available; @@ -3265,9 +3451,44 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, } } + /* Handle string operations */ + + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_STRING_OPERATION) { + char *ptrOut = NULL; + + /* NOTE: You can only assign string operations */ + if (!assign) { + nv_error_msg("The attribute '%s' specified %s cannot be " + "queried; String operations can only be " + "assigned.", + a->name, whence); + continue; + } + + status = NvCtrlStringOperation(t->h, 0, a->attr, p->val.str, + &ptrOut); + if (status != NvCtrlSuccess) { + nv_error_msg("Error processing attribute '%s' (%s %s) " + "specified %s (%s).", + a->name, t->name, p->val.str, whence, + NvCtrlAttributesStrError(status)); + continue; + } + if (op->terse) { + nv_msg(NULL, "%s", ptrOut); + } else { + nv_msg(" ", "Attribute '%s' (%s %s): %s", + a->name, t->name, p->val.str, ptrOut); + } + XFree(ptrOut); + continue; + } + + + /* Special case the GVO CSC attribute */ - if (a->flags & NV_PARSER_TYPE_SDI_CSC) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_SDI_CSC) { float colorMatrix[3][3]; float colorOffset[3]; float colorScale[3]; @@ -3276,7 +3497,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, if (assign) { /* Make sure the standard is known */ - if (!a->val.pf) { + if (!p->val.pf) { nv_error_msg("The attribute '%s' specified %s cannot be " "assigned; valid values are \"ITU_601\", " "\"ITU_709\", \"ITU_177\", and \"Identity\".", @@ -3286,10 +3507,10 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, for (r = 0; r < 3; r++) { for (c = 0; c < 3; c++) { - colorMatrix[r][c] = a->val.pf[r*5 + c]; + colorMatrix[r][c] = p->val.pf[r*5 + c]; } - colorOffset[r] = a->val.pf[r*5 + 3]; - colorScale[r] = a->val.pf[r*5 + 4]; + colorOffset[r] = p->val.pf[r*5 + 3]; + colorScale[r] = p->val.pf[r*5 + 4]; } status = NvCtrlSetGvoColorConversion(t->h, @@ -3351,13 +3572,13 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, * process_parsed_attribute_internal() unfiltered */ - if (a->flags & NV_PARSER_TYPE_HIJACK_DISPLAY_DEVICE) { - mask = a->display_device_mask; + if (a->flags.hijack_display_device) { + mask = p->display_device_mask; } else { mask = 0; } - if (a->flags & NV_PARSER_TYPE_STRING_ATTRIBUTE) { + if (a->type == NV_PARSER_ATTRIBUTE_TYPE_STRING) { status = NvCtrlGetValidStringDisplayAttributeValues(t->h, mask, a->attr, @@ -3395,7 +3616,7 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, continue; } - ret = process_parsed_attribute_internal(h, t, a, mask, target_type, + ret = process_parsed_attribute_internal(op, h, t, p, mask, target_type, assign, verbose, whence, valid); if (ret == NV_FALSE) { @@ -3410,3 +3631,51 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, return val; } /* nv_process_parsed_attribute() */ + + + +static ReturnStatus get_framelock_sync_state(NvCtrlAttributeHandle *t, + CtrlHandles *h, + int *enabled) +{ + NVCTRLAttributePermissionsRec perms; + ReturnStatus status; + int permBit; + int target_type = NvCtrlGetTargetType (t); + + /* NV_CTRL_FRAMELOCK_SYNC should be queried on a GPU target, + * so use the display's connected GPU when querying via a display + * target. + */ + if (target_type == NV_CTRL_TARGET_TYPE_DISPLAY) { + CtrlHandleTargetNode *node; + CtrlHandleTarget *dpy_target; + + dpy_target = nv_get_target(h, target_type, NvCtrlGetTargetId (t)); + + for (node = dpy_target->relations; node; node = node->next) { + target_type = NvCtrlGetTargetType(node->t->h); + + if (target_type == NV_CTRL_TARGET_TYPE_GPU) { + t = node->t->h; + goto query; + } + } + return NvCtrlError; + } +query: + status = XNVCTRLQueryAttributePermissions(h->dpy, + NV_CTRL_FRAMELOCK_SYNC, + &perms); + if (status != NvCtrlSuccess) { + return status; + } + + permBit = targetTypeTable[GPU_TARGET].permission_bit; + + if (perms.permissions & permBit) { + return NvCtrlGetAttribute(t, NV_CTRL_FRAMELOCK_SYNC, enabled); + } + return NvCtrlAttributeNotAvailable; +} + diff --git a/src/query-assign.h b/src/query-assign.h index 6cc1538..bf19be8 100644 --- a/src/query-assign.h +++ b/src/query-assign.h @@ -64,6 +64,11 @@ typedef struct { char *name; /* Name for this target */ char *protoNames[NV_PROTO_NAME_MAX]; /* List of valid names for this target */ + struct { + Bool connected; /* Connection state of display device */ + Bool enabled; /* Enabled state of display device */ + } display; + struct _CtrlHandleTargetNode *relations; /* List of associated targets */ } CtrlHandleTarget; @@ -105,11 +110,12 @@ NvCtrlAttributeHandle *nv_get_target_handle(const CtrlHandles *handles, int target_type, int target_id); -Bool nv_get_attribute_perms(CtrlHandles *h, int attr, uint32 flags, +Bool nv_get_attribute_perms(CtrlHandles *h, const AttributeTableEntry *a, NVCTRLAttributePermissionsRec *perms); -int nv_process_parsed_attribute(ParsedAttribute*, CtrlHandles *h, - int, int, char*, ...) NV_ATTRIBUTE_PRINTF(5, 6); +int nv_process_parsed_attribute(const Options *op, + ParsedAttribute*, CtrlHandles *h, + int, int, char*, ...) NV_ATTRIBUTE_PRINTF(6, 7); void nv_target_list_free(CtrlHandleTargetNode *head); @@ -16,7 +16,6 @@ SRC_SRC += command-line.c SRC_SRC += config-file.c SRC_SRC += lscf.c -SRC_SRC += msg.c SRC_SRC += nvidia-settings.c SRC_SRC += parse.c SRC_SRC += query-assign.c @@ -30,7 +29,6 @@ SRC_EXTRA_DIST += command-line.h SRC_EXTRA_DIST += option-table.h SRC_EXTRA_DIST += config-file.h SRC_EXTRA_DIST += lscf.h -SRC_EXTRA_DIST += msg.h SRC_EXTRA_DIST += parse.h SRC_EXTRA_DIST += query-assign.h SRC_EXTRA_DIST += app-profiles.h diff --git a/src/version.mk b/src/version.mk index 2bca142..591ef07 100644 --- a/src/version.mk +++ b/src/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 331.38 +NVIDIA_VERSION = 334.16 @@ -114,6 +114,7 @@ endif TARGET_ARCH_ABI ?= OUTPUTDIR ?= _out/$(TARGET_OS)_$(TARGET_ARCH) +OUTPUTDIR_ABSOLUTE ?= $(CURDIR)/$(OUTPUTDIR) NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX ?= @@ -1 +1 @@ -NVIDIA_VERSION = 331.38 +NVIDIA_VERSION = 334.16 |