summaryrefslogtreecommitdiff
path: root/src/query-assign.c
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2014-02-09 11:36:20 -0800
committerAaron Plattner <aplattner@nvidia.com>2014-02-09 11:36:20 -0800
commitd968a4fe6080617367369cdabebeb9b8b5b9f408 (patch)
tree9ffa943a8c1d949d178ed923dc1a177fcea68056 /src/query-assign.c
parentdfbf9ba4cc36aafd98510c79979571aad3ef905e (diff)
334.16334.16
Diffstat (limited to 'src/query-assign.c')
-rw-r--r--src/query-assign.c1015
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;
+}
+