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 /src/query-assign.c | |
parent | dfbf9ba4cc36aafd98510c79979571aad3ef905e (diff) |
334.16334.16
Diffstat (limited to 'src/query-assign.c')
-rw-r--r-- | src/query-assign.c | 1015 |
1 files changed, 642 insertions, 373 deletions
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; +} + |