/* returns the value of the sensor */
static gdouble nvidia_plugin_get_sensor_value(const gchar *path,
                                              const gchar *id,
                                              SensorType type,
                                              GError **error) {

    Bool res;
    int temp;
    int i;

    i = g_ascii_strtoll(id + strlen("GPU"), NULL, 10);
    if (g_ascii_strcasecmp(path, THERMAL_SENSOR_TEMP) == 0) {
        res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy,
                          NV_CTRL_TARGET_TYPE_THERMAL_SENSOR,
                          i,
                          0,
                          NV_CTRL_THERMAL_SENSOR_READING,
                          &temp);

    } else if (g_ascii_strcasecmp(path, THERMAL_COOLER_LEVEL) == 0) {
        res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy,
                          NV_CTRL_TARGET_TYPE_COOLER,
                          i,
                          0,
                          NV_CTRL_THERMAL_COOLER_LEVEL,
                          &temp);

    } else if (g_ascii_strcasecmp(path, GPU_CORE_TEMP) == 0) {
        res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy,
                          NV_CTRL_TARGET_TYPE_GPU,
                          i,
                          0,
                          NV_CTRL_GPU_CORE_TEMPERATURE,
                          &temp);

    } else if (g_ascii_strcasecmp(path, AMBIENT_TEMP) == 0) {
        res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy,
                          NV_CTRL_TARGET_TYPE_GPU,
                          i,
                          0,
                          NV_CTRL_AMBIENT_TEMPERATURE,
                          &temp);

    } else {
        g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, 0, "Invalid path string passed to nvidia_plugin_get_sensor_value");
        return 0;
    }

    if (res != True) {
        /* when res isn't true something went wrong */
        g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, 0, "XNVCTRLQueryAttribute returned false");
        return 0;
    }

    /* convert the int to gdouble and return it */
    return (gdouble)temp;
}
Ejemplo n.º 2
0
std::string* glxosdPluginDataProvider(glxosd::GLXOSD *glxosdInstance) {
	if (!errorResult.empty()) {
		return new std::string(errorResult);
	}
	std::stringstream stringBuilder;

	for (int i = 0; i < numberOfGpus; i++) {
		int temperature;

		if ((XNVCTRLQueryTargetAttribute(display,
		NV_CTRL_TARGET_TYPE_GPU, i, 0,
		NV_CTRL_GPU_CORE_TEMPERATURE, &temperature) != True)) {
			stringBuilder
					<< (boost::format(nvidiaGPUFormat)) % "unknown" % i
							% "failed to get the temperature!";
		} else {
			stringBuilder
					<< boost::format(nvidiaGPUFormat) % displayNames[i] % i
							% (boost::format(
									glxosdInstance->getConfigurationManager().getProperty<
											boost::format>(
											"temperature_format")) % temperature);
		}
	}

	return new std::string(stringBuilder.str());
}
Ejemplo n.º 3
0
Bool XNVCTRLQueryAttribute (
    Display *dpy,
    int screen,
    unsigned int display_mask,
    unsigned int attribute,
    int *value
) {
    return XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
                                       screen, display_mask, attribute, value);
}
Ejemplo n.º 4
0
static int
wait_for_perflvl(Display *dpy, uint8_t wanted_perflvl)
{
	unsigned long start_time, get_time;
	struct timeval tv;
	int cur_perflvl = -1, tmp;

	gettimeofday(&tv, NULL);
	start_time = tv.tv_sec;

	fprintf(stderr, "XNVCTRLQueryTargetAttribute\n");
	XNVCTRLQueryTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_GPU, 0, 0, NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE , &tmp);
	if (tmp != NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_ENABLED) {
		fprintf(stderr, "ERROR - Driver not in Adaptive state\n");
		return 1;
	}

	do
	{
		gettimeofday(&tv, NULL);
		get_time = tv.tv_sec;
		if ((start_time + NOUVEAU_TIME_WAIT) < get_time ) {
			fprintf(stderr, "ERROR - Timeout\n");
			return 2;
		}

		XNVCTRLQueryTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 0,
						0, NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, &tmp);
		if (cur_perflvl < 0) {
			cur_perflvl = tmp;
			fprintf(stderr, "NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL = %d\n", cur_perflvl);
		}
		else if (tmp != cur_perflvl) {
			cur_perflvl = tmp;
			fprintf(stderr, "Changed NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL = %d\n", cur_perflvl);
		}

	} while ( cur_perflvl != wanted_perflvl );

	return 0;
}
Ejemplo n.º 5
0
static int
upclock_card(Display *dpy)
{
	unsigned long start_time, get_time;
	struct timeval tv;
	int cur_perflvl = -1, tmp;

	gettimeofday(&tv, NULL);
	start_time = tv.tv_sec;

	XNVCTRLQueryTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 0,
					0, NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, &cur_perflvl);

	pid_t pid = fork();
	if (pid == 0) {
		exit (system("timeout 3 glxgears"));
	} else if (pid == -1) {
		fprintf(stderr, "Fork failed! Abort\n");
		exit (4);
	}

	sleep(1);

	do
	{
		usleep(10000); /* 10 ms */

		gettimeofday(&tv, NULL);
		get_time = tv.tv_sec;

		XNVCTRLQueryTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 0,
						0, NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, &tmp);

	} while ( tmp != NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_MAXPERF && (start_time + 2) < get_time);

	kill(pid, SIGTERM);
	waitpid(pid, NULL, 0);

	return 0;
}
static void
update_sensor_value(IsSensor *sensor,
		    IsNvidiaPlugin *self)
{
	IsNvidiaPluginPrivate *priv;
	const gchar *path;
	guint i;

	priv = self->priv;

	path = is_sensor_get_path(sensor);

	for (i = 0; i < G_N_ELEMENTS(map); i++) {
		Bool ret;
		int value;
		int idx;
		if (g_strrstr(path, map[i].description) == NULL) {
			continue;
		}
		idx = g_ascii_strtoll(g_strrstr(path, map[i].description) +
				      strlen(map[i].description), NULL, 10);

		ret = XNVCTRLQueryTargetAttribute(priv->display,
						  map[i].target,
						  idx,
						  0,
						  map[i].attribute,
						  &value);
		if (!ret) {
			GError *error = g_error_new(g_quark_from_string("nvidia-plugin-error-quark"),
						    0,
						    /* first placeholder is
						     * sensor name */
						    _("Error getting sensor value for sensor %s"),
						    path);
			is_sensor_emit_error(sensor, error);
			g_error_free(error);
			continue;
		}
		if (IS_IS_TEMPERATURE_SENSOR(sensor)) {
			is_temperature_sensor_set_celsius_value(IS_TEMPERATURE_SENSOR(sensor),
								value);
		} else {
			is_sensor_set_value(sensor, value);
		}
	}
}
Ejemplo n.º 7
0
/*
 * do_query()
 *
 * Prints information for all GVI devices found on
 * the given X server.
 *
 */
static void do_query(Display *dpy, int use_gvi)
{
    Bool ret;
    int num_gvi;
    int gvi;
    int last_gvi;

    int value;
    int num_jacks;
    int jack;
    int max_channels_per_jack;
    int channel;

    char *pOut;


    /* Query the number of GVI devices on the server */

    ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_GVI,
                                  &num_gvi);
    if (!ret) {
        printf("Failed to query number of GVI devices!\n");
        return;
    }
    printf("Found %d GVI device(s) on server.\n", num_gvi);
    if ( !num_gvi ) {
        return;
    }

    if (use_gvi >= 0 && use_gvi < num_gvi) {
        /* Only display information about 1 GVI device/ */
        printf("Querying GVI device %d...\n", use_gvi);
        gvi = use_gvi;
        last_gvi = use_gvi;
    } else {
        /* Display all GVI devices */
        printf("Querying all GVI devices...\n");
        gvi = 0;
        last_gvi = num_gvi-1;
    }

    /* Display information about the GVI(s) */

    for (; gvi <= last_gvi; gvi++) {
        
        printf("\n");
        printf("- GVI Board %d :\n", gvi);

        ret = XNVCTRLQueryTargetStringAttribute(dpy,
                                                NV_CTRL_TARGET_TYPE_GVI,
                                                gvi, // target_id
                                                0, // display_mask
                                                NV_CTRL_STRING_GVIO_FIRMWARE_VERSION,
                                                &pOut);
        if (!ret) {
            printf("  - Failed to query firmware version of GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Firmware Version: %s\n", pOut);
        XFree(pOut);
        pOut = NULL;

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVI_GLOBAL_IDENTIFIER,
                                          &value);
        if (!ret) {
            printf("  - Failed to query global ID of GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Global ID: %d\n", value);

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVI_NUM_CAPTURE_SURFACES,
                                          &value);
        if (!ret) {
            printf("  - Failed to number of capture surfaces of GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Number of capture surfaces: %d\n", value);

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT,
                                          &value);
        if (!ret) {
            printf("  - Failed to query requested video format on "
                   "GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Requested video format: %d (%s)\n", value,
               VideoFormatName(value));

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVI_MAX_STREAMS,
                                          &value);
        if (!ret) {
            printf("  - Failed to query max number of streams on "
                   "GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Max number of configurable streams: %d\n", value);

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVI_MAX_LINKS_PER_STREAM,
                                          &value);
        if (!ret) {
            printf("  - Failed to query max number of links per stream on "
                   "GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Max number of links per stream: %d\n", value);

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVI_NUM_JACKS,
                                          &num_jacks);
        if (!ret) {
            printf("  - Failed to query number of input jacks on GVI "
                   "%d.\n", gvi);
            continue;
        } 
        printf("  - Number of input jacks on device: %d\n", num_jacks);

        ret = XNVCTRLQueryTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi, // target_id
                                          0, // display_mask
                                          NV_CTRL_GVI_MAX_CHANNELS_PER_JACK,
                                          &max_channels_per_jack);
        if (!ret) {
            printf("  - Failed to query maximum number of channels per "
                   "jack on GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Maximum number of channels per jack on device: %d\n",
               max_channels_per_jack);

        /* Display per-jack/channel information */

        for (jack = 0; jack < num_jacks; jack++) {
            printf("    - Jack %d\n", jack);

            for (channel = 0; channel < max_channels_per_jack; channel++) {
                printf("      - Channel %d\n", channel);

                unsigned int link_definition = ((channel & 0xFFFF)<<16);
                link_definition |= (jack & 0xFFFF);

                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  link_definition, // display_mask
                                                  NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query detected video format "
                           "on jack %d, channel %d of GVI %d.\n",
                           jack, channel, gvi);
                    continue;
                } 
                printf("        - Detected Video Format: %d (%s)\n", value,
                       VideoFormatName(value)
                       );
            
                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  link_definition, // display_mask
                                                  NV_CTRL_GVI_DETECTED_CHANNEL_SMPTE352_IDENTIFIER,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query detected SMPTE352 "
                           "Identifier on jack %d, channel %d of GVI %d.\n",
                           jack, channel, gvi);
                    continue;
                } 
                printf("        - Detected SMPTE352 Identifier: 0x%08x\n",
                       value);
                
                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  link_definition, // display_mask
                                                  NV_CTRL_GVI_DETECTED_CHANNEL_BITS_PER_COMPONENT,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query detected bits per "
                           "component on jack %d, channel %d of GVI %d.\n",
                           jack, channel, gvi);
                    continue;
                } 
                printf("        - Detected bits per component: ");
                switch (value) {
                case NV_CTRL_GVI_BITS_PER_COMPONENT_8:  printf("8");  break;
                case NV_CTRL_GVI_BITS_PER_COMPONENT_10: printf("10"); break;
                case NV_CTRL_GVI_BITS_PER_COMPONENT_12: printf("12"); break;
                case NV_CTRL_GVI_BITS_PER_COMPONENT_UNKNOWN: /* Fall Through */
                default:
                    printf("Unknown");
                    break;
                }
                printf("\n");
                
                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  link_definition, // display_mask
                                                  NV_CTRL_GVI_DETECTED_CHANNEL_COMPONENT_SAMPLING,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query detected component "
                           "sampling on jack %d, channel %d of GVI %d.\n",
                           jack, channel, gvi);
                    continue;
                } 
                printf("        - Detected component sampling: ");
                switch (value) {
                case NV_CTRL_GVI_COMPONENT_SAMPLING_4444: printf("4:4:4:4"); break;
                case NV_CTRL_GVI_COMPONENT_SAMPLING_4224: printf("4:2:2:4"); break;
                case NV_CTRL_GVI_COMPONENT_SAMPLING_444:  printf("4:4:4");   break;
                case NV_CTRL_GVI_COMPONENT_SAMPLING_422:  printf("4:2:2");   break;
                case NV_CTRL_GVI_COMPONENT_SAMPLING_420:  printf("4:2:0");   break;
                case NV_CTRL_GVI_COMPONENT_SAMPLING_UNKNOWN: /* Fall Through */
                default:
                    printf("Unknown");
                    break;
                }
                printf("\n");
                
                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  link_definition, // display_mask
                                                  NV_CTRL_GVI_DETECTED_CHANNEL_COLOR_SPACE,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query detected color space on "
                           "jack %d, channel %d of GVI %d.\n",
                           jack, channel, gvi);
                    continue;
                } 
                printf("        - Detected color space: ");
                switch (value) {
                case NV_CTRL_GVI_COLOR_SPACE_GBR:    printf("GBR");   break;
                case NV_CTRL_GVI_COLOR_SPACE_GBRA:   printf("GBRA");   break;
                case NV_CTRL_GVI_COLOR_SPACE_GBRD:   printf("GBRD");   break;
                case NV_CTRL_GVI_COLOR_SPACE_YCBCR:  printf("YCbCr"); break;
                case NV_CTRL_GVI_COLOR_SPACE_YCBCRA: printf("YCbCrA"); break;
                case NV_CTRL_GVI_COLOR_SPACE_YCBCRD: printf("YCbCrD"); break;
                case NV_CTRL_GVI_COLOR_SPACE_UNKNOWN: /* Fall Through */
                default:
                    printf("Unknown");
                    break;
                }
                printf("\n");
                
                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  link_definition, // display_mask
                                                  NV_CTRL_GVI_DETECTED_CHANNEL_LINK_ID,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query detected link ID on "
                           "jack %d, channel %d of GVI %d.\n",
                           jack, channel, gvi);
                    continue;
                } 
                printf("        - Detected Link ID: Link %d", value);
                if (value == NV_CTRL_GVI_LINK_ID_UNKNOWN) {
                    printf(" (Unknown)");
                } else if (value < 26) {
                    printf(" (Link%c)", (int)('A')+value);
                }
                printf("\n");

            } /* Done querying per-channel information */
        } /* Done querying per-jack information */


        /* Query stream (link to jack+channel) topology */
        ret = XNVCTRLStringOperation(dpy,
                                     NV_CTRL_TARGET_TYPE_GVI,
                                     gvi, // target_id
                                     0, // display_mask
                                     NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS,
                                     NULL, // pIn
                                     &pOut);
        if (!ret || !pOut) {
            printf("  - Failed to query stream topology configuration of "
                   "GVI %d.\n", gvi);
            continue;
        } 
        printf("  - Topology:\n");
        printf("\n      %s\n\n", pOut ? pOut : "No streams are configured.");


        /* Query per-stream settings */
        if (pOut) {
            char *str = pOut;
            int i = 0;

            while ( (str = strstr(str, "stream=")) )
            {
                printf("    - Stream %d\n", i);

                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  i, // display_mask (stream #)
                                                  NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query requested stream bits per component "
                           "for stream %d of GVI %d.\n",
                           i, gvi);
                    continue;
                } 
                printf("        - Requested bits per component: %d (%s)\n", value,
                       BPCName(value));

                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  i, // display_mask (stream #)
                                                  NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query requested stream component sampling "
                           "for stream %d of GVI %d.\n",
                           i, gvi);
                    continue;
                } 
                printf("        - Requested component sampling: %d (%s)\n", value,
                       SamplingName(value));

                ret = XNVCTRLQueryTargetAttribute(dpy,
                                                  NV_CTRL_TARGET_TYPE_GVI,
                                                  gvi, // target_id
                                                  i, // display_mask (stream #)
                                                  NV_CTRL_GVI_REQUESTED_STREAM_CHROMA_EXPAND,
                                                  &value);
                if (!ret) {
                    printf("        - Failed to query requested stream chroma expand "
                           "for stream %d of GVI %d.\n",
                           i, gvi);
                    continue;
                } 
                printf("        - Requested chroma expand: %s\n",
                       value ? "Enabled" : "Disabled");

                i++;
                str++;
            }
        }

        XFree(pOut);
        pOut = NULL;

    } /* Done Querying information about GVI devices */

} /* do_query() */
/**
 * load initial data
 *
 * TODO:350:M: Implement nvCtrlTable data load
 * This function will also be called by the cache helper to load
 * the container again (after the container free function has been
 * called to free the previous contents).
 *
 * @param container container to which items should be inserted
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
 * @retval MFD_ERROR                : other error.
 *
 *  This function is called to load the index(es) (and data, optionally)
 *  for the every row in the data set.
 *
 * @remark
 *  While loading the data, the only important thing is the indexes.
 *  If access to your data is cheap/fast (e.g. you have a pointer to a
 *  structure in memory), it would make sense to update the data here.
 *  If, however, the accessing the data invovles more work (e.g. parsing
 *  some other existing data, or peforming calculations to derive the data),
 *  then you can limit yourself to setting the indexes and saving any
 *  information you will need later. Then use the saved information in
 *  nvCtrlTable_row_prep() for populating data.
 *
 * @note
 *  If you need consistency between rows (like you want statistics
 *  for each row to be from the same time frame), you should set all
 *  data here.
 *
 */
int
nvCtrlTable_container_load(netsnmp_container *container)
{
    nvCtrlTable_rowreq_ctx *rowreq_ctx;
    size_t                 count = 0;
    Display *dpy;
    Bool ret;
    int event_base, error_base, major, minor, gpus;
    int gpu, retval, len;
    char *str;

    DEBUGMSGTL(("verbose:nvCtrlTable:nvCtrlTable_container_load", "called\n"));

    /*
     * open a connection to the X server indicated by the DISPLAY
     * environment variable
     */

    dpy = XOpenDisplay(NULL);
    if (!dpy) {
	DEBUGMSGTL(("nvCtrlTable:nvCtrlTable_container_load",
		    "Cannot open display '%s'.\n", XDisplayName(NULL)));
        return MFD_RESOURCE_UNAVAILABLE;
    }

    /*
     * check if the NV-CONTROL X extension is present on this X server
     */

    ret = XNVCTRLQueryExtension(dpy, &event_base, &error_base);
    if (ret != True) {
	DEBUGMSGTL(("nvCtrlTable:nvCtrlTable_container_load",
		    "The NV-CONTROL X extension does not exist on '%s'.\n",
		    XDisplayName(NULL)));
        return MFD_RESOURCE_UNAVAILABLE;
    }

    /*
     * query the major and minor extension version
     */

    ret = XNVCTRLQueryVersion(dpy, &major, &minor);
    if (ret != True) {
	DEBUGMSGTL(("nvCtrlTable:nvCtrlTable_container_load",
		    "The NV-CONTROL X extension does not exist on '%s'.\n",
		    XDisplayName(NULL)));
        return MFD_RESOURCE_UNAVAILABLE;
    }

    /*
     * query number of GPUs via the NV-CONTROL X extension; then, allocate
     * a rowreq context, set the index(es) and data, and insert into the
     * container.
     */

    if (!XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_GPU, &gpus)) {
	snmp_log(LOG_ERR, "failed to query number of GPUs\n");
	return MFD_ERROR;
    }

    for (gpu = 0; gpu < gpus; gpu++) {
        rowreq_ctx = nvCtrlTable_allocate_rowreq_ctx();
        if (NULL == rowreq_ctx) {
            snmp_log(LOG_ERR, "memory allocation failed\n");
            return MFD_RESOURCE_UNAVAILABLE;
        }
	if (MFD_SUCCESS != nvCtrlTable_indexes_set(rowreq_ctx, gpu)) {
            snmp_log(LOG_ERR, "error setting index while loading"
		     "nvCtrlTable data.\n");
            nvCtrlTable_release_rowreq_ctx(rowreq_ctx);
            continue;
        }

	/*
	 * setup/save data for nvCtrlProductName
	 * nvCtrlProductName(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H
	 */
	ret = XNVCTRLQueryTargetStringAttribute(dpy,
						NV_CTRL_TARGET_TYPE_GPU,
						gpu,
						0,
						NV_CTRL_STRING_PRODUCT_NAME,
						&str);
	if (ret) {
	    len = strlen(str);
	    if (sizeof(rowreq_ctx->data.nvCtrlProductName) < len) {
		snmp_log(LOG_ERR,"not enough space for value\n");
		return MFD_ERROR;
	    }
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_PRODUCT_NAME_FLAG;
	    rowreq_ctx->data.nvCtrlProductName_len = len;
	    memcpy(rowreq_ctx->data.nvCtrlProductName, str, len);
	    XFree(str);
	}

	/*
	 * setup/save data for nvCtrlVBiosVersion
	 * nvCtrlVBiosVersion(3)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H
	 */
	ret = XNVCTRLQueryTargetStringAttribute(dpy,
						NV_CTRL_TARGET_TYPE_GPU,
						gpu,
						0,
						NV_CTRL_STRING_VBIOS_VERSION,
						&str);
	if (ret) {
	    len = strlen(str);
	    if (sizeof(rowreq_ctx->data.nvCtrlVBiosVersion) < len) {
		snmp_log(LOG_ERR,"not enough space for value\n");
		return MFD_ERROR;
	    }
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_VBIOS_VERSION_FLAG;
	    rowreq_ctx->data.nvCtrlVBiosVersion_len = len;
	    memcpy(rowreq_ctx->data.nvCtrlVBiosVersion, str, len);
	    XFree(str);
	}

	/*
	 * setup/save data for nvCtrlNvidiaDriverVersion
	 * nvCtrlNvidiaDriverVersion(4)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H
	 */
	ret = XNVCTRLQueryTargetStringAttribute(dpy,
						NV_CTRL_TARGET_TYPE_GPU,
						gpu,
						0,
						NV_CTRL_STRING_NVIDIA_DRIVER_VERSION,
						&str);
	if (ret) {
	    len = strlen(str);
	    if (sizeof(rowreq_ctx->data.nvCtrlNvidiaDriverVersion) < len) {
		snmp_log(LOG_ERR,"not enough space for value\n");
		return MFD_ERROR;
	    }
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_NVIDIA_DRIVER_VERSION_FLAG;
	    rowreq_ctx->data.nvCtrlNvidiaDriverVersion_len = len;
	    memcpy(rowreq_ctx->data.nvCtrlNvidiaDriverVersion, str, len);
	    XFree(str);
	}

	/*
	 * setup/save data for nvCtrlVersion
	 * nvCtrlVersion(5)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H
	 */
	rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_VERSION_FLAG;
	snprintf(rowreq_ctx->data.nvCtrlVersion, sizeof(rowreq_ctx->data.nvCtrlVersion), "%d.%d", major, minor);
	rowreq_ctx->data.nvCtrlVersion_len = strlen(rowreq_ctx->data.nvCtrlVersion);

	/*
	 * setup/save data for nvCtrlBusType
	 * nvCtrlBusType(6)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_BUS_TYPE,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_BUS_TYPE_FLAG;
	    rowreq_ctx->data.nvCtrlBusType = retval;
	}

	/*
	 * setup/save data for nvCtrlBusRate
	 * nvCtrlBusRate(7)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_BUS_RATE,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_BUS_RATE_FLAG;
	    rowreq_ctx->data.nvCtrlBusRate = retval;
	}

	/*
	 * setup/save data for nvCtrlVideoRam
	 * nvCtrlVideoRam(8)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_VIDEO_RAM,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_VIDEO_RAM_FLAG;
	    rowreq_ctx->data.nvCtrlVideoRam = retval;
	}

	/*
	 * setup/save data for nvCtrlIrq
	 * nvCtrlIrq(9)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_IRQ,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_IRQ_FLAG;
	    rowreq_ctx->data.nvCtrlIrq = retval;
	}

	/*
	 * setup/save data for nvCtrlGPUCoreTemp
	 * nvCtrlGPUCoreTemp(10)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_CORE_TEMPERATURE,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_CORE_TEMP_FLAG;
	    rowreq_ctx->data.nvCtrlGPUCoreTemp = retval;
	}

	/*
	 * setup/save data for nvCtrlGPUCoreThreshold
	 * nvCtrlGPUCoreThreshold(11)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_CORE_THRESHOLD,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_CORE_THRESHOLD_FLAG;
	    rowreq_ctx->data.nvCtrlGPUCoreThreshold = retval;
	}

	/*
	 * setup/save data for nvCtrlGPUDefaultCoreThreshold
	 * nvCtrlGPUDefaultCoreThreshold(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD_FLAG;
	    rowreq_ctx->data.nvCtrlGPUDefaultCoreThreshold = retval;
	}

	/*
	 * setup/save data for nvCtrlGPUMaxCoreThreshold
	 * nvCtrlGPUMaxCoreThreshold(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_MAX_CORE_THRESHOLD,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_MAX_CORE_THRESHOLD_FLAG;
	    rowreq_ctx->data.nvCtrlGPUMaxCoreThreshold = retval;
	}

	/*
	 * setup/save data for nvCtrlGPUAmbientTemp
	 * nvCtrlGPUAmbientTemp(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_AMBIENT_TEMPERATURE,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_AMBIENT_TEMP_FLAG;
	    rowreq_ctx->data.nvCtrlGPUAmbientTemp = retval;
	}

	/*
	 * setup/save data for nvCtrlGPUOverclockingState
	 * nvCtrlGPUOverclockingState(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_OVERCLOCKING_STATE,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_OVERCLOCKING_STATE_FLAG;
	    rowreq_ctx->data.nvCtrlGPUOverclockingState = retval;
	}

	/*
	 * setup/save data for nvCtrlGPU2DGPUClockFreq
	 * nvCtrlGPU2DGPUClockFreq(16)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_2D_CLOCK_FREQS,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_2D_GPU_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPU2DGPUClockFreq = (retval >> 16) & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPU2DMemClockFreq
	 * nvCtrlGPU2DMemClockFreq(17)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_2D_MEM_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPU2DMemClockFreq = retval & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPU3DGPUClockFreq
	 * nvCtrlGPU3DGPUClockFreq(18)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_3D_CLOCK_FREQS,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_3D_GPU_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPU3DGPUClockFreq = (retval >> 16) & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPU3DMemClockFreq
	 * nvCtrlGPU3DMemClockFreq(19)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_3D_MEM_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPU3DMemClockFreq = retval & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPUDefault2DGPUClockFreq
	 * nvCtrlGPUDefault2DGPUClockFreq(20)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_DEFAULT_2D_CLOCK_FREQS,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_DEFAULT_2D_GPU_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPUDefault2DGPUClockFreq = (retval >> 16) & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPUDefault2DMemClockFreq
	 * nvCtrlGPUDefault2DMemClockFreq(21)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_DEFAULT_2D_MEM_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPUDefault2DMemClockFreq = retval & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPUDefault3DGPUClockFreq
	 * nvCtrlGPUDefault3DGPUClockFreq(22)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_DEFAULT_3D_CLOCK_FREQS,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_DEFAULT_3D_GPU_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPUDefault3DGPUClockFreq = (retval >> 16) & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPUDefault3DMemClockFreq
	 * nvCtrlGPUDefault3DMemClockFreq(23)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_DEFAULT_3D_MEM_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPUDefault3DMemClockFreq = retval & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPUCurrentGPUClockFreq
	 * nvCtrlGPUCurrentGPUClockFreq(24)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	ret = XNVCTRLQueryTargetAttribute(dpy,
					  NV_CTRL_TARGET_TYPE_GPU,
					  gpu,
					  0,
					  NV_CTRL_GPU_CURRENT_CLOCK_FREQS,
					  &retval);
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_CURRENT_GPU_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPUCurrentGPUClockFreq = (retval >> 16) & 0xFFFF;
	}

	/*
	 * setup/save data for nvCtrlGPUCurrentMemClockFreq
	 * nvCtrlGPUCurrentMemClockFreq(25)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
	 */
	if (ret) {
	    rowreq_ctx->column_exists_flags |= COLUMN_NV_CTRL_GPU_CURRENT_MEM_CLOCK_FREQ_FLAG;
	    rowreq_ctx->data.nvCtrlGPUCurrentMemClockFreq = retval & 0xFFFF;
	}

	/*
	 * insert into table container
	 */
	CONTAINER_INSERT(container, rowreq_ctx);
	++count;
    }

    /*
     * close the display connection
     */

    XCloseDisplay(dpy);


    DEBUGMSGT(("verbose:nvCtrlTable:nvCtrlTable_container_load",
               "inserted %d records\n", count));

    return MFD_SUCCESS;
} /* nvCtrlTable_container_load */
static void
is_nvidia_plugin_activate(PeasActivatable *activatable)
{
	IsNvidiaPlugin *self = IS_NVIDIA_PLUGIN(activatable);
	IsNvidiaPluginPrivate *priv = self->priv;
	Bool ret;
	int event_base, error_base;
	gint n;
	int i;

	/* search for sensors and add them to manager */
	if (!priv->inited) {
		is_warning("nvidia", "not inited, unable to find sensors");
		goto out;
	}

	is_debug("nvidia", "searching for sensors");

	/* check if the NV-CONTROL extension is available on this X
         * server */
	ret = XNVCTRLQueryExtension(priv->display, &event_base, &error_base);
	if (!ret) {
		goto out;
	}

	/* get number of GPUs, then for each GPU get any thermal_sensors and
	   coolers used by it */
	ret = XNVCTRLQueryTargetCount(priv->display,
				      NV_CTRL_TARGET_TYPE_GPU,
				      &n);
	if (!ret) {
		goto out;
	}

	for (i = 0; i < n; i++) {
		guint j;
		char *label = NULL;
		ret = XNVCTRLQueryTargetStringAttribute(priv->display,
							NV_CTRL_TARGET_TYPE_GPU,
							i,
							0,
							NV_CTRL_STRING_PRODUCT_NAME,
							&label);
		for (j = 0; j < G_N_ELEMENTS(map); j++) {
			int32_t *data;
			int len;
			int k;

			ret = XNVCTRLQueryTargetBinaryData(priv->display,
							   NV_CTRL_TARGET_TYPE_GPU,
							   i,
							   0,
							   map[j].gpu_attribute,
							   (unsigned char **)&data,
							   &len);
			if (!ret) {
				continue;
			}
			/* data[0] contains number of sensors, and each sensor
			   indice follows */
			for (k = 1; k <= data[0]; k++) {
				int idx = data[k];
				gint value;
				IsSensor *sensor;
				gchar *path;

				ret = XNVCTRLQueryTargetAttribute(priv->display,
								  map[j].target,
								  idx,
								  0,
								  map[j].attribute,
								  &value);
				if (!ret) {
					continue;
				}

				path = g_strdup_printf("nvidia/%s%d", map[j].description, idx);
				if (map[j].target == NV_CTRL_TARGET_TYPE_COOLER) {
					/* fan sensors are given as a percentage
					   from 0 to 100 */
					sensor = is_sensor_new(path);
					is_sensor_set_icon(sensor, IS_STOCK_FAN);
					is_sensor_set_units(sensor, "%");
					is_sensor_set_low_value(sensor, 0.0);
					is_sensor_set_high_value(sensor, 100.0);
				} else {
					sensor = is_temperature_sensor_new(path);
					is_sensor_set_icon(sensor, IS_STOCK_GPU);
				}
				/* no decimal places to display */
				is_sensor_set_digits(sensor, 0);
				is_sensor_set_label(sensor, label);
				/* connect to update-value signal */
				g_signal_connect(sensor, "update-value",
						 G_CALLBACK(update_sensor_value),
						 self);
				is_manager_add_sensor(is_application_get_manager(priv->application),
                                                      sensor);
				g_free(path);
			}
			free(data);
		}
		free(label);
	}

out:
	return;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
{
    Display *dpy;
    Bool ret;
    int screen, major, minor, len, i, j;
    char *str, *start, *str0, *str1;
    int *enabledDpyIds;


    /*
     * Open a display connection, and make sure the NV-CONTROL X
     * extension is present on the screen we want to use.
     */
    
    dpy = XOpenDisplay(NULL);
    if (!dpy) {
        fprintf(stderr, "Cannot open display '%s'.\n\n", XDisplayName(NULL));
        return 1;
    }
    
    screen = GetNvXScreen(dpy);

    ret = XNVCTRLQueryVersion(dpy, &major, &minor);
    if (ret != True) {
        fprintf(stderr, "The NV-CONTROL X extension does not exist "
                "on '%s'.\n\n", XDisplayName(NULL));
        return 1;
    }

    printf("\nUsing NV-CONTROL extension %d.%d on %s\n\n",
           major, minor, XDisplayName(NULL));


    /*
     * query the enabled display devices on this X screen and print basic
     * information about each X screen.
     */

    ret = XNVCTRLQueryTargetBinaryData(dpy,
                                       NV_CTRL_TARGET_TYPE_X_SCREEN,
                                       screen,
                                       0,
                                       NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN,
                                       (unsigned char **) &enabledDpyIds,
                                       &len);
    if (!ret || (len < sizeof(enabledDpyIds[0]))) {
        fprintf(stderr, "Failed to query the enabled Display Devices.\n\n");
        return 1;
    }

    printf("Enabled Display Devices:\n");

    for (i = 0; i < enabledDpyIds[0]; i++) {
        int dpyId = enabledDpyIds[i+1];

        print_display_id_and_name(dpy, dpyId, "  ");
    }

    printf("\n");
    
    
    /*
     * perform the requested action, based on the specified
     * commandline option
     */
    
    if (argc <= 1) goto printHelp;


    /*
     * for each enabled display device on this X screen, query the list of
     * modelines in the mode pool using NV_CTRL_BINARY_DATA_MODELINES, then
     * print the results.
     */

    if (strcmp(argv[1], "--print-modelines") == 0) {

        for (i = 0; i < enabledDpyIds[0]; i++) {
            int dpyId = enabledDpyIds[i+1];

            ret = XNVCTRLQueryTargetBinaryData(dpy,
                                               NV_CTRL_TARGET_TYPE_DISPLAY,
                                               dpyId,
                                               0,
                                               NV_CTRL_BINARY_DATA_MODELINES,
                                               (void *) &str, &len);
            if (!ret) {
                fprintf(stderr, "Failed to query ModeLines.\n\n");
                return 1;
            }

            /*
             * the returned data is in the form:
             *
             *  "ModeLine 1\0ModeLine 2\0ModeLine 3\0Last ModeLine\0\0"
             *
             * so walk from one "\0" to the next to print each ModeLine.
             */

            printf("Modelines for DPY-%d:\n", dpyId);

            start = str;
            for (j = 0; j < len; j++) {
                if (str[j] == '\0') {
                    printf("  %s\n", start);
                    start = &str[j+1];
                }
            }

            XFree(str);
        }
    }


    /*
     * for each enabled display device on this X screen, query the current
     * modeline using NV_CTRL_STRING_CURRENT_MODELINE.
     */

    else if (strcmp(argv[1], "--print-current-modeline") == 0) {

       for (i = 0; i < enabledDpyIds[0]; i++) {
            int dpyId = enabledDpyIds[i+1];

            ret = XNVCTRLQueryTargetStringAttribute(dpy,
                                                    NV_CTRL_TARGET_TYPE_DISPLAY,
                                                    dpyId,
                                                    0,
                                                    NV_CTRL_STRING_CURRENT_MODELINE,
                                                    &str);
            if (!ret) {
                fprintf(stderr, "Failed to query current ModeLine.\n\n");
                return 1;
            }

            printf("Current Modeline for DPY-%d:\n", dpyId);
            printf("  %s\n\n", str);

            XFree(str);
        }
    }
    

    /*
     * add the specified modeline to the mode pool for the specified
     * display device, using NV_CTRL_STRING_ADD_MODELINE
     */
    
    else if ((strcmp(argv[1], "--add-modeline") == 0) &&
             argv[2] && argv[3]) {
        
        int dpyId = strtol(argv[2], NULL, 0);

        ret = XNVCTRLSetTargetStringAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_DISPLAY,
                                              dpyId,
                                              0,
                                              NV_CTRL_STRING_ADD_MODELINE,
                                              argv[3]);
        
        if (!ret) {
            fprintf(stderr, "Failed to add the modeline \"%s\" to DPY-%d's "
                    "mode pool.\n\n", argv[3], dpyId);
            return 1;
        }
        
        printf("Added modeline \"%s\" to DPY-%d's mode pool.\n\n",
               argv[3], dpyId);
    }

    
    /*
     * delete the specified modeline from the mode pool for the
     * specified display device, using NV_CTRL_STRING_DELETE_MODELINE
     */
    
    else if ((strcmp(argv[1], "--delete-modeline") == 0) &&
             argv[2] && argv[3]) {
        
        int dpyId = strtol(argv[2], NULL, 0);
    
        ret = XNVCTRLSetTargetStringAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_DISPLAY,
                                              dpyId,
                                              0,
                                              NV_CTRL_STRING_DELETE_MODELINE,
                                              argv[3]);
        
        if (!ret) {
            fprintf(stderr, "Failed to delete the mode \"%s\" from DPY-%d's "
                    "mode pool.\n\n", argv[3], dpyId);
            return 1;
        }
        
        printf("Deleted modeline \"%s\" from DPY-%d's mode pool.\n\n",
               argv[3], dpyId);
    }
    
    
    /*
     * generate a GTF modeline using NV_CTRL_STRING_OPERATION_GTF_MODELINE
     */
    
    else if ((strcmp(argv[1], "--generate-gtf-modeline") == 0) &&
             argv[2] && argv[3] && argv[4]) {
        
        char pGtfString[128];
        char *pOut;
        
        snprintf(pGtfString, 128, "width=%s, height=%s, refreshrate=%s",
                 argv[2], argv[3], argv[4]);

        ret = XNVCTRLStringOperation(dpy,
                                     NV_CTRL_TARGET_TYPE_X_SCREEN,
                                     screen,
                                     0,
                                     NV_CTRL_STRING_OPERATION_GTF_MODELINE,
                                     pGtfString,
                                     &pOut);

        if (!ret) {
            fprintf(stderr, "Failed to generate GTF ModeLine from "
                    "\"%s\".\n\n", pGtfString);
            return 1;
        }
        
        printf("GTF ModeLine from \"%s\": %s\n\n", pGtfString, pOut);
    }
    
    
    /*
     * generate a CVT modeline using NV_CTRL_STRING_OPERATION_CVT_MODELINE
     */

    else if ((strcmp(argv[1], "--generate-cvt-modeline") == 0) &&
             argv[2] && argv[3] && argv[4] && argv[5]) {

        char pCvtString[128];
        char *pOut;
        
        snprintf(pCvtString, 128, "width=%s, height=%s, refreshrate=%s, "
                 "reduced-blanking=%s",
                 argv[2], argv[3], argv[4], argv[5]);
        
        ret = XNVCTRLStringOperation(dpy,
                                     NV_CTRL_TARGET_TYPE_X_SCREEN,
                                     screen,
                                     0,
                                     NV_CTRL_STRING_OPERATION_CVT_MODELINE,
                                     pCvtString,
                                     &pOut);

        if (!ret) {
            fprintf(stderr, "Failed to generate CVT ModeLine from "
                    "\"%s\".\n\n", pCvtString);
            return 1;
        }

        printf("CVT ModeLine from \"%s\": %s\n\n", pCvtString, pOut);
    }

    
    /*
     * query the MetaModes for the X screen, using
     * NV_CTRL_BINARY_DATA_METAMODES.
     */
    
    else if (strcmp(argv[1], "--print-metamodes") == 0) {

        /* get list of metamodes */
        
        ret = XNVCTRLQueryBinaryData(dpy, screen, 0, // n/a
                                     NV_CTRL_BINARY_DATA_METAMODES,
                                     (void *) &str, &len);
        
        if (!ret) {
            fprintf(stderr, "Failed to query MetaModes.\n\n");
            return 1;
        }
        
        /*
         * the returned data is in the form:
         *
         *   "MetaMode 1\0MetaMode 2\0MetaMode 3\0Last MetaMode\0\0"
         *
         * so walk from one "\0" to the next to print each MetaMode.
         */
        
        printf("MetaModes:\n");
        
        start = str;
        for (j = 0; j < len; j++) {
            if (str[j] == '\0') {
                printf("  %s\n", start);
                start = &str[j+1];
            }
        }
        
        XFree(str);
    }


    /*
     * query the MetaModes for the X screen, using
     * NV_CTRL_BINARY_DATA_METAMODES_VERSION_2.
     */

    else if (strcmp(argv[1], "--print-metamodes-version2") == 0) {

        /* get list of metamodes */

        ret = XNVCTRLQueryBinaryData(dpy, screen, 0, // n/a
                                     NV_CTRL_BINARY_DATA_METAMODES_VERSION_2,
                                     (void *) &str, &len);

        if (!ret) {
            fprintf(stderr, "Failed to query MetaModes.\n\n");
            return 1;
        }

        /*
         * the returned data is in the form:
         *
         *   "MetaMode 1\0MetaMode 2\0MetaMode 3\0Last MetaMode\0\0"
         *
         * so walk from one "\0" to the next to print each MetaMode.
         */

        printf("MetaModes:\n");

        start = str;
        for (j = 0; j < len; j++) {
            if (str[j] == '\0') {
                printf("  %s\n", start);
                start = &str[j+1];
            }
        }

        XFree(str);
    }


    /*
     * query the currently in use MetaMode.  Note that an alternative
     * way to accomplish this is to use XRandR to query the current
     * mode's refresh rate, and then match the refresh rate to the id
     * reported in the returned NV_CTRL_BINARY_DATA_METAMODES data.
     */
    
    else if (strcmp(argv[1], "--print-current-metamode") == 0) {
        
        ret = XNVCTRLQueryStringAttribute(dpy, screen, 0,
                                          NV_CTRL_STRING_CURRENT_METAMODE,
                                          &str);
        
        if (!ret) {
            fprintf(stderr, "Failed to query the current MetaMode.\n\n");
            return 1;
        }
        
        printf("current metamode: \"%s\"\n\n", str);

        XFree(str);
    }


    /*
     * query the currently in use MetaMode.  Note that an alternative
     * way to accomplish this is to use XRandR to query the current
     * mode's refresh rate, and then match the refresh rate to the id
     * reported in the returned NV_CTRL_BINARY_DATA_METAMODES_VERSION_2 data.
     */

    else if (strcmp(argv[1], "--print-current-metamode-version2") == 0) {

        ret = XNVCTRLQueryStringAttribute(dpy, screen, 0,
                                          NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2,
                                          &str);

        if (!ret) {
            fprintf(stderr, "Failed to query the current MetaMode.\n\n");
            return 1;
        }

        printf("current metamode: \"%s\"\n\n", str);

        XFree(str);
    }


    /*
     * add the given MetaMode to X screen's list of MetaModes, using
     * NV_CTRL_STRING_OPERATION_ADD_METAMODE; example MetaMode string:
     *
     * "nvidia-auto-select, nvidia-auto-select"
     *
     * The output string will contain "id=#" which indicates the
     * unique identifier for this MetaMode.  You can then use XRandR
     * to switch to this mode by matching the identifier with the
     * refresh rate reported via XRandR.
     *
     * For example:
     *
     * $ ./nv-control-dpy --add-metamode \
     *                         "nvidia-auto-select, nvidia-auto-select"
     *
     * Using NV-CONTROL extension 1.12 on :0
     * Enabled Display Devices:
     *   DPY-0 : EIZO F931
     *   DPY-1 : ViewSonic P815-4
     *
     * Added MetaMode "nvidia-auto-select, nvidia-auto-select"; 
     * pOut: "id=52"
     *
     * $ xrandr -q
     * SZ:    Pixels          Physical       Refresh
     *  0   3200 x 1200   ( 821mm x 302mm )   51   52  
     * *1   1600 x 600    ( 821mm x 302mm )  *50  
     * Current rotation - normal
     * Current reflection - none
     * Rotations possible - normal 
     * Reflections possible - none
     *
     * $ xrandr -s 0 -r 52
     */
    
    else if ((strcmp(argv[1], "--add-metamode") == 0) && (argv[2])) {
        
        char *pOut;
        
        ret = XNVCTRLStringOperation(dpy,
                                     NV_CTRL_TARGET_TYPE_X_SCREEN,
                                     screen,
                                     0,
                                     NV_CTRL_STRING_OPERATION_ADD_METAMODE,
                                     argv[2],
                                     &pOut);

        if (!ret) {
            fprintf(stderr, "Failed to add the MetaMode \"%s\".\n\n",
                    argv[2]);
            return 1;
        }

        printf("Added MetaMode \"%s\"; pOut: \"%s\"\n\n", argv[2], pOut);
        
        XFree(pOut);
    }
    
    
    /*
     * delete the given MetaMode from the X screen's list of
     * MetaModes, using NV_CTRL_STRING_DELETE_METAMODE
     */

    else if ((strcmp(argv[1], "--delete-metamode") == 0) && (argv[1])) {
        
        ret = XNVCTRLSetStringAttribute(dpy,
                                        screen,
                                        0,
                                        NV_CTRL_STRING_DELETE_METAMODE,
                                        argv[2]);

        if (!ret) {
            fprintf(stderr, "Failed to delete the MetaMode.\n\n");
            return 1;
        }
        
        printf("Deleted MetaMode \"%s\".\n\n", argv[2]);
    }
    
    
    /*
     * query the valid frequency ranges for each display device, using
     * NV_CTRL_STRING_VALID_HORIZ_SYNC_RANGES and
     * NV_CTRL_STRING_VALID_VERT_REFRESH_RANGES
     */
    
    else if (strcmp(argv[1], "--get-valid-freq-ranges") == 0) {

        for (i = 0; i < enabledDpyIds[0]; i++) {
            int dpyId = enabledDpyIds[i+1];

            ret = XNVCTRLQueryTargetStringAttribute
                (dpy, NV_CTRL_TARGET_TYPE_DISPLAY, dpyId, 0,
                 NV_CTRL_STRING_VALID_HORIZ_SYNC_RANGES,
                 &str0);

            if (!ret) {
                fprintf(stderr, "Failed to query HorizSync for DPY-%d.\n\n",
                        dpyId);
                return 1;
            }

            ret = XNVCTRLQueryTargetStringAttribute
                (dpy, NV_CTRL_TARGET_TYPE_DISPLAY, dpyId, 0,
                 NV_CTRL_STRING_VALID_VERT_REFRESH_RANGES,
                 &str1);

            if (!ret) {
                fprintf(stderr, "Failed to query VertRefresh for DPY-%d.\n\n",
                        dpyId);
                XFree(str0);
                return 1;
            }

            printf("frequency information for DPY-%d:\n", dpyId);
            printf("  HorizSync   : \"%s\"\n", str0);
            printf("  VertRefresh : \"%s\"\n\n", str1);

            XFree(str0);
            XFree(str1);
        }
    }
    
    
    /*
     * attempt to build the modepool for each display device; this
     * will fail for any display device that already has a modepool
     */
    
    else if (strcmp(argv[1], "--build-modepool") == 0) {

        for (i = 0; i < enabledDpyIds[0]; i++) {
            int dpyId = enabledDpyIds[i+1];

            ret = XNVCTRLStringOperation
                (dpy,
                 NV_CTRL_TARGET_TYPE_DISPLAY,
                 dpyId,
                 0,
                 NV_CTRL_STRING_OPERATION_BUILD_MODEPOOL,
                 argv[2],
                 &str0);

            if (!ret) {
                fprintf(stderr, "Failed to build modepool for DPY-%d (it most "
                        "likely already has a modepool).\n\n", dpyId);
            } else {
                printf("Built modepool for DPY-%d.\n\n", dpyId);
            }
        }
    }

    
    /*
     * query the assigned display devices on this X screen; these are the
     * display devices that are available to the X screen for use by MetaModes.
     */

    else if (strcmp(argv[1], "--get-assigned-dpys") == 0) {

        int *pData = NULL;
        int len;

        ret = XNVCTRLQueryTargetBinaryData(dpy,
                                           NV_CTRL_TARGET_TYPE_X_SCREEN,
                                           screen,
                                           0,
                                           NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN,
                                           (unsigned char **) &pData,
                                           &len);
        if (!ret || (len < sizeof(pData[0]))) {
            fprintf(stderr, "failed to query the assigned display "
                    "devices.\n\n");
            return 1;
        }

        printf("Assigned display devices:\n");

        for (i = 0; i < pData[0]; i++) {
            int dpyId = pData[i+1];

            printf("  DPY-%d\n", dpyId);
        }

        printf("\n");
        XFree(pData);
    }

    /*
     * query information about the GPUs in the system
     */
    
    else if (strcmp(argv[1], "--query-gpus") == 0) {

        int num_gpus, num_screens, i;
        int *pData;

        printf("GPU Information:\n");

        /* Get the number of gpus in the system */
        
        ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_GPU,
                                      &num_gpus);
        if (!ret) {
            fprintf(stderr, "Failed to query number of gpus.\n\n");
            return 1;
        }

        printf("  number of GPUs: %d\n", num_gpus);

        /* List the X screen number of all X screens driven by each gpu */
        
        for (i = 0; i < num_gpus; i++) {
            
            ret = XNVCTRLQueryTargetBinaryData
                (dpy,
                 NV_CTRL_TARGET_TYPE_GPU,
                 i, // target_id
                 0,
                 NV_CTRL_BINARY_DATA_XSCREENS_USING_GPU,
                 (unsigned char **) &pData,
                 &len);
            
            if (!ret || (len < sizeof(pData[0]))) {
                fprintf(stderr, "Failed to query list of X Screens\n");
                return 1;
            }
            
            printf("  number of X screens using GPU %d: %d\n", i, pData[0]);
            
            /* List X Screen number of all X Screens driven by this GPU. */
            
            printf("    Indices of X screens using GPU %d: ", i);
            
            for (j = 1; j <= pData[0]; j++) {
                printf(" %d", pData[j]);
            }
            printf("\n");
            XFree(pData);
        }
        

        /* Get the number of X Screens in the system 
         *
         * NOTE: If Xinerama is enabled, ScreenCount(dpy) will return 1,
         *       where as querying the screen count information from
         *       NV-CONTROL will return the number of underlying X Screens.
         */
        
        ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
                                      &num_screens);
        if (!ret) {
            fprintf(stderr, "Failed to query number of X Screens\n\n");
            return 1;
        }

        printf("\n");
        printf("  number of X screens (ScreenCount): %d\n",
               ScreenCount(dpy));
        printf("  number of X screens (NV-CONTROL): %d\n\n",
               num_screens);

        for (i = 0; i < num_screens; i++) {
            
            ret = XNVCTRLQueryTargetBinaryData
                (dpy,
                 NV_CTRL_TARGET_TYPE_X_SCREEN,
                 i, // target_id
                 0,
                 NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
                 (unsigned char **) &pData,
                 &len);
            
            if (!ret || (len < sizeof(pData[0]))) {
                fprintf(stderr, "Failed to query list of gpus\n\n");
                return 1;
            }
            
            printf("  number of GPUs used by X screen %d: %d\n", i,
                   pData[0]);

            /* List gpu number of all gpus driven by this X screen */

            printf("    Indices of GPUs used by X screen %d: ", i);
            for (j = 1; j <= pData[0]; j++) {
                printf(" %d", pData[j]);
            }
            printf("\n");
            XFree(pData);
        }
        
        printf("\n");

    }
    
    
    /*
     * probe for any newly connected display devices
     */
    
    else if (strcmp(argv[1], "--probe-dpys") == 0) {

        int num_gpus, i;

        printf("Display Device Probed Information:\n\n");

        /* Get the number of gpus in the system */
        
        ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_GPU,
                                      &num_gpus);
        
        if (!ret) {
            fprintf(stderr, "Failed to query number of gpus\n\n");
            return 1;
        }
        
        printf("  number of GPUs: %d\n", num_gpus);

        /* Probe and list the Display devices */
        
        for (i = 0; i < num_gpus; i++) {
            int deprecated;
            int *pData;
            
            /* Get the gpu name */
            
            ret = XNVCTRLQueryTargetStringAttribute
                (dpy, NV_CTRL_TARGET_TYPE_GPU, i, 0,
                 NV_CTRL_STRING_PRODUCT_NAME, &str);
            
            if (!ret) {
                fprintf(stderr, "Failed to query gpu name\n\n");
                return 1;
            }

            /* Probe the GPU for new/old display devices */
            
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU, i,
                                              0,
                                              NV_CTRL_PROBE_DISPLAYS,
                                              &deprecated);
            
            if (!ret) {
                fprintf(stderr, "Failed to probe the enabled Display "
                        "Devices on GPU-%d (%s).\n\n", i, str);
                return 1;
            }
            
            printf("  display devices on GPU-%d (%s):\n", i, str);
            XFree(str);
        
            /* Report results */

            ret = XNVCTRLQueryTargetBinaryData(dpy,
                                               NV_CTRL_TARGET_TYPE_GPU, i,
                                               0,
                                               NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU,
                                               (unsigned char **) &pData,
                                               &len);
            if (!ret || (len < sizeof(pData[0]))) {
                fprintf(stderr, "Failed to query the connected Display Devices.\n\n");
                return 1;
            }

            for (j = 0; j < pData[0]; j++) {
                int dpyId = pData[j+1];

                print_display_id_and_name(dpy, dpyId, "    ");
            }

            printf("\n");
        }
        
        printf("\n");
    }
    
    
    /*
     * query the nvidiaXineramaInfoOrder
     */
    
    else if (strcmp(argv[1], "--query-nvidia-xinerama-info-order") == 0) {
        
        ret = XNVCTRLQueryTargetStringAttribute
            (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
             NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER, &str);
        
        if (!ret) {
            fprintf(stderr, "Failed to query nvidiaXineramaInfoOrder.\n\n");
            return 1;
        }
        
        printf("nvidiaXineramaInfoOrder: %s\n\n", str);
    }
    
    
    /*
     * assign the nvidiaXineramaInfoOrder
     */
    
    else if ((strcmp(argv[1], "--assign-nvidia-xinerama-info-order")== 0)
             && argv[2]) {
        
        ret = XNVCTRLSetStringAttribute
            (dpy,
             screen,
             0,
             NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER,
             argv[2]);
        
        if (!ret) {
            fprintf(stderr, "Failed to assign "
                    "nvidiaXineramaInfoOrder = \"%s\".\n\n", argv[2]);
            return 1;
        }
        
        printf("assigned nvidiaXineramaInfoOrder: \"%s\"\n\n",
               argv[2]);
    }


    /*
     * use NV_CTRL_MAX_SCREEN_WIDTH and NV_CTRL_MAX_SCREEN_HEIGHT to
     * query the maximum screen dimensions on each GPU in the system
     */
    
    else if (strcmp(argv[1], "--max-screen-size") == 0) {

        int num_gpus, i, width, height;
        
        /* Get the number of gpus in the system */
        
        ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_GPU,
                                      &num_gpus);
        if (!ret) {
            fprintf(stderr, "Failed to query number of gpus.\n\n");
            return 1;
        }
        
        for (i = 0; i < num_gpus; i++) {
            
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              i,
                                              0,
                                              NV_CTRL_MAX_SCREEN_WIDTH,
                                              &width);

            if (!ret) {
                fprintf(stderr, "Failed to query the maximum screen "
                        "width on GPU-%d\n\n", i);
                return 1;
            }
            
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              i,
                                              0,
                                              NV_CTRL_MAX_SCREEN_HEIGHT,
                                              &height);

            if (!ret) {
                fprintf(stderr, "Failed to query the maximum screen "
                        "height on GPU-%d.\n\n", i);
                return 1;
            }
            
            printf("GPU-%d: maximum X screen size: %d x %d.\n\n",
                   i, width, height);
        }
    }


    /*
     * demonstrate how to use NV-CONTROL to query what modelines are
     * used by the MetaModes of the X screen: we first query all the
     * MetaModes, parse out the display device names and mode names,
     * and then lookup the modelines associated with those mode names
     * on those display devices
     *
     * this could be implemented much more efficiently, but
     * demonstrates the general idea
     */
    
    else if (strcmp(argv[1], "--print-used-modelines") == 0) {

        char *pMetaModes, *pModeLines[8], *tmp, *modeString;
        char *modeLine, *modeName, *noWhiteSpace;
        int MetaModeLen, ModeLineLen[8], ModeLineDpyId[8];
        int dpyId;

        /* first, we query the MetaModes on this X screen */
        
        XNVCTRLQueryBinaryData(dpy, screen, 0,
                               NV_CTRL_BINARY_DATA_METAMODES_VERSION_2,
                               (void *) &pMetaModes, &MetaModeLen);
        
        /*
         * then, we query the ModeLines for each display device on
         * this X screen; we'll need these later
         */

        for (i = 0; i < enabledDpyIds[0]; i++) {
            dpyId = enabledDpyIds[i+1];

            XNVCTRLQueryTargetBinaryData(dpy, NV_CTRL_TARGET_TYPE_DISPLAY,
                                         dpyId,
                                         0,
                                         NV_CTRL_BINARY_DATA_MODELINES,
                                         (void *) &str, &len);

            pModeLines[i] = str;
            ModeLineLen[i] = len;
            ModeLineDpyId[i] = dpyId;
        }
        
        /* now, parse each MetaMode */
        
        str = start = pMetaModes;
        
        for (j = 0; j < MetaModeLen - 1; j++) {

            /*
             * if we found the end of a line, treat the string from
             * start to str[j] as a MetaMode
             */

            if ((str[j] == '\0') && (str[j+1] != '\0')) {

                printf("MetaMode: %s\n", start);
                
                /*
                 * remove any white space from the string to make
                 * parsing easier
                 */
                
                noWhiteSpace = remove_whitespace(start);

                /*
                 * the MetaMode may be preceded with "token=value"
                 * pairs, separated by the main MetaMode with "::"; if
                 * "::" exists in the string, skip past it
                 */
                
                tmp = strstr(noWhiteSpace, "::");
                if (tmp) {
                    tmp += 2;
                } else {
                    tmp = noWhiteSpace;
                }

                /* Parse each mode from the metamode */

                for (modeString = mode_strtok(tmp);
                     modeString;
                     modeString = mode_strtok(NULL)) {

                    /*
                     * retrieve the modeName and display device id
                     * for this segment of the Metamode
                     */

                    if (!parse_mode_string(modeString, &modeName, &dpyId)) {
                        fprintf(stderr, "  Failed to parse mode string '%s'."
                                "\n\n",
                                modeString);
                        continue;
                    }

                    /* lookup the modeline that matches */

                    for (i = 0; i < enabledDpyIds[0]; i++) {
                        if (ModeLineDpyId[i] == dpyId) {
                            break;
                        }
                    }
                    if ( i >= enabledDpyIds[0] ) {
                        fprintf(stderr, "  Failed to find modelines for "
                                "DPY-%d.\n\n",
                                dpyId);
                        continue;
                    }

                    modeLine = find_modeline(modeName,
                                             pModeLines[i],
                                             ModeLineLen[i]);

                    printf("  DPY-%d: %s\n", dpyId, modeLine);
                }

                printf("\n");

                free(noWhiteSpace);
                
                /* move to the next MetaMode */
                
                start = &str[j+1];
            }
        }
    }


    /* Display all names each display device goes by
     */
    else if (strcmp(argv[1], "--print-display-names") == 0) {
        int *pData;
        int len, i;

        printf("Display Device Information:\n");

        ret = XNVCTRLQueryTargetBinaryData(dpy,
                                           NV_CTRL_TARGET_TYPE_GPU,
                                           0,
                                           0,
                                           NV_CTRL_BINARY_DATA_DISPLAY_TARGETS,
                                           (unsigned char **) &pData,
                                           &len);
        if (!ret || (len < sizeof(pData[0]))) {
            fprintf(stderr, "Failed to query number of display devices.\n\n");
            return 1;
        }

        printf("  number of display devices: %d\n", pData[0]);

        for (i = 1; i <= pData[0]; i++) {

            printf("\n  Display Device: %d\n", pData[i]);

            print_display_name(dpy, pData[i],
                               NV_CTRL_STRING_DISPLAY_NAME_TYPE_BASENAME,
                               "Type Basename");
            print_display_name(dpy, pData[i],
                               NV_CTRL_STRING_DISPLAY_NAME_TYPE_ID,
                               "Type ID");
            print_display_name(dpy, pData[i],
                               NV_CTRL_STRING_DISPLAY_NAME_DP_GUID,
                               "DP GUID");
            print_display_name(dpy, pData[i],
                               NV_CTRL_STRING_DISPLAY_NAME_EDID_HASH,
                               "EDID HASH");
            print_display_name(dpy, pData[i],
                               NV_CTRL_STRING_DISPLAY_NAME_TARGET_INDEX,
                               "Target Index");
            print_display_name(dpy, pData[i],
                               NV_CTRL_STRING_DISPLAY_NAME_RANDR,
                               "RANDR");
        }
    }

    /*
     * print help information
     */

    else {
        
    printHelp:
        
        printf("\nnv-control-dpy [options]:\n\n");
        
        
        printf(" ModeLine options:\n\n");

        printf("  --print-modelines: print the modelines in the mode pool "
               "for each Display Device.\n\n");
        
        printf("  --print-current-modeline: print the current modeline "
               "for each Display Device.\n\n");

        printf("  --add-modeline [dpy id] [modeline]: "
               "add new modeline.\n\n");
        
        printf("  --delete-modeline [dpy id] [modename]: "
               "delete modeline with modename.\n\n");
        
        printf("  --generate-gtf-modeline [width] [height] [refreshrate]:"
               " use the GTF formula"
               " to generate a modeline for the specified parameters.\n\n");
        
        printf("  --generate-cvt-modeline [width] [height] [refreshrate]"
               " [reduced-blanking]: use the CVT formula"
               " to generate a modeline for the specified parameters.\n\n");
                

        printf(" MetaMode options:\n\n");

        printf("  --print-metamodes: print the current MetaModes for the "
               "X screen\n\n");

        printf("  --print-metamodes-version2: print the current MetaModes for "
               "the X screen with extended information\n\n");

        printf("  --add-metamode [metamode]: add the specified "
               "MetaMode to the X screen's list of MetaModes.\n\n");
        
        printf("  --delete-metamode [metamode]: delete the specified MetaMode "
               "from the X screen's list of MetaModes.\n\n");

        printf("  --print-current-metamode: print the current MetaMode.\n\n");

        printf("  --print-current-metamode-version2: print the current "
               "MetaMode with extended information.\n\n");


        printf(" Misc options:\n\n");
        
        printf("  --get-valid-freq-ranges: query the valid frequency "
               "information for each display device.\n\n");
        
        printf("  --build-modepool: build a modepool for any display device "
               "that does not already have one.\n\n");
                
        printf("  --get-assigned-dpys: query the assigned display device for "
               "this X screen\n\n");
        
        printf("  --query-gpus: print GPU information and relationship to "
               "X screens.\n\n");
        
        printf("  --probe-dpys: probe GPUs for new display devices\n\n");
        
        printf("  --query-nvidia-xinerama-info-order: query the "
               "nvidiaXineramaInfoOrder.\n\n");
        
        printf("  --assign-nvidia-xinerama-info-order [order]: assign the "
               "nvidiaXineramaInfoOrder.\n\n");

        printf("  --max-screen-size: query the maximum screen size "
               "on all GPUs in the system\n\n");

        printf("  --print-used-modelines: print the modeline for each display "
               "device for each MetaMode on the X screen.\n\n");

        printf("  --print-display-names: print all the names associated with "
               "each display device on the server\n\n");
    }

    return 0;

}
Ejemplo n.º 11
0
/*
 * do_query()
 *
 * Prints information for all frame lock (g-sync) devices found on
 * the given X server.
 *
 */
static void do_query(Display *dpy)
{
    Bool ret;
    int num_framelocks;
    int framelock;
    int gpu;
    int mask;
    char *name;
    
    int *data;
    int len;
    int i;

    int enabled;


    /* Query the number of frame lock devices on the server */

    ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK,
                                  &num_framelocks);
    if (!ret) {
        printf("Failed to query number of frame lock devices!\n");
        return;
    }
    printf("Found %d frame lock device(s) on server.\n", num_framelocks);
    if ( !num_framelocks ) {
        return;
    }

    /* Display information for all frame lock devices found */

    for (framelock = 0; framelock < num_framelocks; framelock++) {
        
        printf("\n");
        printf("- Frame Lock Board %d :\n", framelock);

        /* Query the GPUs connected to this frame lock device */

        ret = XNVCTRLQueryTargetBinaryData
            (dpy,
             NV_CTRL_TARGET_TYPE_FRAMELOCK,
             framelock, // target_id
             0, // display_mask
             NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK,
             (unsigned char **) &data,
             &len);
        if (!ret) {
            printf("  - Failed to query list of GPUs!\n");
            continue;
        }

        /* Display information for all GPUs connected to frame lock device */

        if ( !data[0] ) {
            printf("  - No GPUs found!\n");
        } else {
            printf("  - Found %d GPU(s).\n", data[0]);
        }

        for (i = 1; i <= data[0]; i++) {
            gpu = data[i];
        
            /* Query GPU product name */
            
            ret = XNVCTRLQueryTargetStringAttribute(dpy,
                                                    NV_CTRL_TARGET_TYPE_GPU,
                                                    gpu, // target_id
                                                    0, // display_mask
                                                    NV_CTRL_STRING_PRODUCT_NAME,
                                                    &name);
            if (!ret) {
                printf("  - Failed to query GPU %d product name.\n", gpu);
                continue;
            } 
            printf("  - GPU %d (%s) :\n", gpu, name);

            /* Query GPU sync state */

            printf("    - Sync          : ");
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              0, // display_mask
                                              NV_CTRL_FRAMELOCK_SYNC,
                                              &enabled);
            if (!ret) {
                printf("Failed to query sync state.\n");
            } else {
                printf("%sabled\n", enabled ? "En" : "Dis");
            }

            /* Query GPU displays */

            printf("    - Displays Mask : ");
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              0, // display_mask
                                              NV_CTRL_ENABLED_DISPLAYS,
                                              &mask);
            if (!ret) {
                printf("Failed to query enabled displays.\n");
            } else {
                printf("0x%08x\n", mask);
            }

            /* Query GPU server (master) */

            printf("    - Server Mask   : ");
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              0, // display_mask
                                              NV_CTRL_FRAMELOCK_MASTER,
                                              &mask);
            if (!ret) {
                printf("Failed to query server mask.\n");
            } else {
                printf("0x%08x\n", mask);
            }

            /* Query GPU clients (slaves) */

            printf("    - Clients Mask  : ");
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              0, // display_mask
                                              NV_CTRL_FRAMELOCK_SLAVES,
                                              &mask);
            if (!ret) {
                printf("Failed to query clients mask.\n");
            } else {
                printf("0x%08x\n", mask);
            }

        } /* Done disabling GPUs */

        XFree(data);

    } /* Done disabling Frame Lock Devices */

} /* do_query() */
Ejemplo n.º 12
0
int main(int argc, char *argv[])
{
    Display *dpy;
    Bool ret;
    int screen, display_devices, mask, major, minor;
    char *str;
    int nDisplayDevice;


    /*
* Open a display connection, and make sure the NV-CONTROL X
* extension is present on the screen we want to use.
*/

    dpy = XOpenDisplay(NULL);
    if (!dpy) {
        fprintf(stderr, "Cannot open display '%s'.\n\n", XDisplayName(NULL));
        return 1;
    }

    screen = GetNvXScreen(dpy);

    ret = XNVCTRLQueryVersion(dpy, &major, &minor);
    if (ret != True) {
        fprintf(stderr, "The NV-CONTROL X extension does not exist on '%s'.\n\n", XDisplayName(NULL));
        return 1;
    }

    /*
	* query the connected display devices on this X screen and print
	* basic information about each X screen
	*/

    ret = XNVCTRLQueryAttribute(dpy, screen, 0,
                                NV_CTRL_CONNECTED_DISPLAYS, &display_devices);

    if (!ret) {
        fprintf(stderr, "Failed to query the enabled Display Devices.\n\n");
        return 1;
    }

    int pci_bus;
    int pci_device;
    int pci_func;
    ret = XNVCTRLQueryTargetAttribute(dpy,
										NV_CTRL_TARGET_TYPE_GPU, 0 /* Just query first GPU */,
										0,
										NV_CTRL_PCI_BUS,
										&pci_bus);
	ret = XNVCTRLQueryTargetAttribute(dpy,
										NV_CTRL_TARGET_TYPE_GPU, 0 /* Just query first GPU */,
										0,
										NV_CTRL_PCI_DEVICE,
										&pci_device);
	ret = XNVCTRLQueryTargetAttribute(dpy,
										NV_CTRL_TARGET_TYPE_GPU, 0 /* Just query first GPU */,
										0,
										NV_CTRL_PCI_FUNCTION,
										&pci_func);
	dbset("system.hardware.nvidia.busid=%i:%i:%i", pci_bus, pci_device, pci_func);

    nDisplayDevice = 0;
    for (mask = 1; mask < (1 << 24); mask <<= 1) {
        if (display_devices & mask) {
            XNVCTRLQueryStringAttribute(dpy, screen, mask,
                                        NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
                                        &str);

            dbset("system.x11.display.%i.device=%s" , nDisplayDevice, display_device_name(mask));
            dbset("system.x11.display.%i.mode.0=nvidia-auto-select", nDisplayDevice);
            dbset("system.x11.display.%i.default=nvidia-auto-select", nDisplayDevice);

            printf("%i:%s:0x%08x:%s\n", nDisplayDevice, display_device_name(mask), mask, str);

            nDisplayDevice++;
        }
    }

    if (nDisplayDevice > 1) { // more than one screen found
    	dbset("system.x11.dualhead.enabled=1");
    } else {
    	dbset("system.x11.dualhead.enabled=0");
    }

    char *dummy;
    for (; nDisplayDevice <= 3; nDisplayDevice++) {
    	if (asprintf(&dummy, "system.x11.display.%i", nDisplayDevice) >= 0) {
    		dbremove(dummy);
    		free(dummy);
    	}
    }

    return 0;
}
/* creates the connection to the X server and checks whether the
 * NV-CONTROL extension is loaded */
static GList *nvidia_plugin_init(void) {
    int dummy;
    int event_base, error_base;
    GList *sensors = NULL;

    /* create the connection to the X server */
    if (!(nvidia_sensors_dpy = XOpenDisplay(NULL))) {
        /* no connection to the X server avaible */
        return sensors;
    }

    /* check if the NV-CONTROL extension is available on this X
         * server - if so add the two sensors if they exist */
    if (XNVCTRLQueryExtension(nvidia_sensors_dpy, &event_base, &error_base)) {
        int i, cnt;

        if (XNVCTRLQueryTargetCount(nvidia_sensors_dpy,
                        NV_CTRL_TARGET_TYPE_THERMAL_SENSOR,
                        &cnt)) {

            for (i = 0; i < cnt; i++) {
                gchar *id = g_strdup_printf("GPU%d%s", i, THERMAL_SENSOR_TEMP);

                sensors_applet_plugin_add_sensor(&sensors,
                                                 THERMAL_SENSOR_TEMP,
                                                 id,
                                                 _("GPU"),
                                                 TEMP_SENSOR,
                                                 TRUE,
                                                 GPU_ICON,
                                                 DEFAULT_GRAPH_COLOR);

                g_free(id);
            }
        }

        if (XNVCTRLQueryTargetCount(nvidia_sensors_dpy,
                        NV_CTRL_TARGET_TYPE_COOLER,
                        &cnt)) {

            for (i = 0; i < cnt; i++) {
                gchar *id = g_strdup_printf("GPU%d%s", i, THERMAL_COOLER_LEVEL);

                sensors_applet_plugin_add_sensor(&sensors,
                                                 THERMAL_COOLER_LEVEL,
                                                 id,
                                                 _("GPU"),
                                                 FAN_SENSOR,
                                                 TRUE,
                                                 FAN_ICON,
                                                 DEFAULT_GRAPH_COLOR);

                g_free(id);
            }
        }

        if (XNVCTRLQueryTargetCount(nvidia_sensors_dpy,
                        NV_CTRL_TARGET_TYPE_GPU,
                        &cnt)) {

            for (i = 0; i < cnt; i++) {
                if (XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy,
                                NV_CTRL_TARGET_TYPE_GPU,
                                i,
                                       0, NV_CTRL_GPU_CORE_TEMPERATURE, &dummy)) {

                    gchar *id = g_strdup_printf("GPU%d%s", i, GPU_CORE_TEMP);

                    sensors_applet_plugin_add_sensor(&sensors,
                                                     GPU_CORE_TEMP,
                                                     id,
                                                     _("GPU"),
                                                     TEMP_SENSOR,
                                                     TRUE,
                                                     GPU_ICON,
                                                     DEFAULT_GRAPH_COLOR);
                    g_free(id);
                }

                if (XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy,
                                NV_CTRL_TARGET_TYPE_GPU,
                                i,
                                       0, NV_CTRL_AMBIENT_TEMPERATURE, &dummy)) {
                    gchar *id = g_strdup_printf("GPU%d%s", i, AMBIENT_TEMP);

                    sensors_applet_plugin_add_sensor(&sensors,
                                                     AMBIENT_TEMP,
                                                     id,
                                                     _("Ambient"),
                                                     TEMP_SENSOR,
                                                     FALSE,
                                                     GENERIC_ICON,
                                                     DEFAULT_GRAPH_COLOR);
                    g_free(id);
                }
            }
        }

    }
    return sensors;
}
Ejemplo n.º 14
0
static int
hwloc_gl_discover(struct hwloc_backend *backend)
{
  struct hwloc_topology *topology = backend->topology;
  unsigned i, res = 0;
  int err;

  if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
    return 0;

  if (!hwloc_topology_is_thissystem(topology)) {
    hwloc_debug("%s", "\nno GL detection (not thissystem)\n");
    return 0;
  }

  for (i = 0; i < HWLOC_GL_SERVER_MAX; ++i) {
    Display* display;
    char displayName[10];
    int opcode, event, error;
    unsigned j;

    /* open X server */
    snprintf(displayName, sizeof(displayName), ":%u", i);
    display = XOpenDisplay(displayName);
    if (!display)
      continue;

    /* Check for NV-CONTROL extension (it's per server) */
    if(!XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error)) {
      XCloseDisplay(display);
      continue;
    }

    for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
      hwloc_obj_t osdev, parent;
      const int screen = j;
      unsigned int *ptr_binary_data;
      int data_length;
      int gpu_number;
      int nv_ctrl_pci_bus;
      int nv_ctrl_pci_device;
      int nv_ctrl_pci_domain;
      int nv_ctrl_pci_func;
      char *productname;
      char name[64];

      /* the server supports NV-CONTROL but it may contain non-NVIDIA screen that don't support it */
      if (!XNVCTRLIsNvScreen(display, screen))
        continue;

      /* Gets the GPU number attached to the default screen. */
      /* For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetBinaryData (display, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
                                          NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
                                          (unsigned char **) &ptr_binary_data, &data_length);
      if (!err)
        continue;

      gpu_number = ptr_binary_data[1];
      free(ptr_binary_data);

#ifdef NV_CTRL_PCI_DOMAIN
      /* Gets the ID's of the GPU defined by gpu_number
       * For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DOMAIN, &nv_ctrl_pci_domain);
      if (!err)
        continue;
#else
      nv_ctrl_pci_domain = 0;
#endif

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_BUS, &nv_ctrl_pci_bus);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DEVICE, &nv_ctrl_pci_device);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_FUNCTION, &nv_ctrl_pci_func);
      if (!err)
        continue;

      productname = NULL;
      err = XNVCTRLQueryTargetStringAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                              NV_CTRL_STRING_PRODUCT_NAME, &productname);

      snprintf(name, sizeof(name), ":%u.%u", i, j);

      osdev = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1);
      osdev->name = strdup(name);
      osdev->logical_index = -1;
      osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
      hwloc_obj_add_info(osdev, "Backend", "GL");
      hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
      if (productname)
	hwloc_obj_add_info(osdev, "GPUModel", productname);

      parent = hwloc_pci_belowroot_find_by_busid(topology, nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
      if (!parent)
	parent = hwloc_pci_find_busid_parent(topology, nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
      if (!parent)
	parent = hwloc_get_root_obj(topology);

      hwloc_insert_object_by_parent(topology, parent, osdev);

      hwloc_debug("GL device %s (product %s) on PCI 0000:%02x:%02x.%u\n", name, productname,
		  nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
      res++;
    }
    XCloseDisplay(display);
  }

  return res;
}
Ejemplo n.º 15
0
// List the configuration space of the GVI device.
void do_listconfig(Display *dpy, int gvi)
{
    NVCTRLAttributeValidValuesRec values;

    unsigned int fmts[3];
    int i;
    char *pOut = NULL;
    Bool ret;

    // Assume GVI device has been configured already.
    if (gvi < 0) {
        gvi = 0;
    }

    printf("Querying Valid Configuring Space of GVI device %d:\n\n", gvi);

    /* Query stream (link to jack+channel) topology */
    ret = XNVCTRLStringOperation(dpy,
                                 NV_CTRL_TARGET_TYPE_GVI,
                                 gvi, // target_id
                                 0, // display_mask
                                 NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS,
                                 NULL, // pIn
                                 &pOut);
    if (!ret || !pOut) {
        printf("  - Failed to query stream topology configuration of "
               "GVI %d.\n", gvi);
        return;
    } 
    printf("- Current Topology:\n\n");
    printf("      %s\n\n", pOut ? pOut : "No streams are configured.");
    XFree(pOut);
    pOut = NULL;


    ret = XNVCTRLQueryValidTargetAttributeValues(dpy,
                                                 NV_CTRL_TARGET_TYPE_GVI,
                                                 gvi,
                                                 0, // display_mask
                                                 NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT,
                                                 &values);
    if (!ret) {
        printf("- Failed to query valid video format values(1) of "
               "GVI %d.\n", gvi);
        return;
    }
    fmts[0] = values.u.bits.ints;

    ret = XNVCTRLQueryValidTargetAttributeValues(dpy,
                                                 NV_CTRL_TARGET_TYPE_GVI,
                                                 gvi,
                                                 0, // display_mask
                                                 NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2,
                                                 &values);
    if (!ret) {
        printf("- Failed to query valid video format values(2) of "
               "GVI %d.\n", gvi);
        return;
    }
    fmts[1] = values.u.bits.ints;

    ret = XNVCTRLQueryValidTargetAttributeValues(dpy,
                                                 NV_CTRL_TARGET_TYPE_GVI,
                                                 gvi,
                                                 0, // display_mask
                                                 NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3,
                                                 &values);
    if (!ret) {
        printf("- Failed to query valid video format values(3) of "
               "GVI %d.\n", gvi);
        return;
    }
    fmts[2] = values.u.bits.ints;



    printf("- Valid Formats (NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT): %08x\n", fmts[0]);
    printf("- Valid Formats (NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2): %08x\n", fmts[1]);
    printf("- Valid Formats (NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3): %08x\n", fmts[2]);

    printf("\n");
    for (i = 0; i < 3; i++) {
        unsigned int fmt_list = fmts[i];
        unsigned int fmt_bit;
        unsigned int fmt;
        unsigned int fmt_flags;

        unsigned int bpcs;
        unsigned int bpc_bit;
        unsigned int bpc;

        unsigned int samplings;
        unsigned int smp_bit;
        unsigned int sampling;


        while (fmt_list) {
            fmt_bit = firstbit(fmt_list);
            fmt_list &= (~fmt_bit);
            fmt = ffs(fmt_bit) - 1 + (32*i);

            printf("\n%s", VideoFormatName(fmt));
            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GVI,
                                              gvi,
                                              fmt, // display_mask
                                              NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS,
                                              (int *)&fmt_flags);
            if (!ret) {
                printf(" - Failed to query flag bits for video format for "
                       "GVI %d.\n", gvi);
            } else if (fmt_flags == NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_NONE) {
                printf(" (No flags set): \n");
            } else {
                printf(" (Flags:");
                printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_INTERLACED)        ? 'I' : '_');
                printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PROGRESSIVE)       ? 'P' : '_');
                printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PSF)               ? 'F' : '_');
                printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_A)        ? 'A' : '_');
                printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_B)        ? 'B' : '_');
                printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_1080P_NO_12BPC) ? 'N' : '_');
                printf("):\n");
            }


            // Set the video format
            XNVCTRLSetTargetAttribute(dpy,
                                      NV_CTRL_TARGET_TYPE_GVI,
                                      gvi,
                                      0, // display_mask
                                      NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT,
                                      fmt);

            // Get all bits per component (on first jack/channel)
            ret = XNVCTRLQueryValidTargetAttributeValues(dpy,
                                                         NV_CTRL_TARGET_TYPE_GVI,
                                                         gvi,
                                                         0, // jack 0, channel 0
                                                         NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT,
                                                         &values);
            if (!ret) {
                printf("  - Failed to query valid bits per component "
                       "of GVI %d.\n", gvi);
                continue;
            }

            bpcs = values.u.bits.ints;
            while (bpcs) {
                bpc_bit = firstbit(bpcs);
                bpcs &= (~bpc_bit);
                bpc = ffs(bpc_bit) -1;
                    
                printf("    %s:\n", BPCName(bpc));

                // Set the bits per component
                XNVCTRLSetTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GVI,
                                          gvi,
                                          0, // jack 0, channel 0
                                          NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT,
                                          bpc);


                // Get all component samplings (on first jack/channel)
                ret = XNVCTRLQueryValidTargetAttributeValues(dpy,
                                                             NV_CTRL_TARGET_TYPE_GVI,
                                                             gvi,
                                                             0, // display_mask
                                                             NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING,
                                                             &values);
                if (!ret) {
                    printf("  - Failed to query valid component sampling "
                           "values of GVI %d.\n", gvi);
                    continue;
                }

                samplings = values.u.bits.ints;
                while (samplings) {
                    smp_bit = firstbit(samplings);
                    samplings &= (~smp_bit);
                    sampling = ffs(smp_bit) -1;

                    printf("        %s\n", SamplingName(sampling));

                } // All component samplings
            } // Add BPC
        } // All formats
    } // All format lists

} /* do_listconfig() */
Ejemplo n.º 16
0
static void
hwloc_gl_query_devices(struct hwloc_gl_backend_data_s *data)
{
  int err;
  unsigned i,j;

  /* mark the number of display as 0 in case we fail below,
   * so that we don't try again later.
   */
  data->nr_display = 0;

  for (i = 0; i < HWLOC_GL_SERVER_MAX; ++i) {
    Display* display;
    char displayName[10];
    int opcode, event, error;

    /* open X server */
    snprintf(displayName, sizeof(displayName), ":%u", i);
    display = XOpenDisplay(displayName);
    if (!display)
      continue;

    /* Check for NV-CONTROL extension (it's per server) */
    if(!XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error)) {
      XCloseDisplay(display);
      continue;
    }

    for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
      struct hwloc_gl_display_info_s *info = &data->display[data->nr_display];
      const int screen = j;
      unsigned int *ptr_binary_data;
      int data_length;
      int gpu_number;
      int nv_ctrl_pci_bus;
      int nv_ctrl_pci_device;
      int nv_ctrl_pci_domain;
      int nv_ctrl_pci_func;
      char *productname;

      /* the server supports NV-CONTROL but it may contain non-NVIDIA screen that don't support it */
      if (!XNVCTRLIsNvScreen(display, screen))
        continue;

      /* Gets the GPU number attached to the default screen. */
      /* For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetBinaryData (display, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
                                          NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
                                          (unsigned char **) &ptr_binary_data, &data_length);
      if (!err)
        continue;

      gpu_number = ptr_binary_data[1];
      free(ptr_binary_data);

#ifdef NV_CTRL_PCI_DOMAIN
      /* Gets the ID's of the GPU defined by gpu_number
       * For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DOMAIN, &nv_ctrl_pci_domain);
      if (!err)
        continue;
#else
      nv_ctrl_pci_domain = 0;
#endif

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_BUS, &nv_ctrl_pci_bus);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DEVICE, &nv_ctrl_pci_device);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_FUNCTION, &nv_ctrl_pci_func);
      if (!err)
        continue;

      productname = NULL;
      err = XNVCTRLQueryTargetStringAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                              NV_CTRL_STRING_PRODUCT_NAME, &productname);

      snprintf(info->name, sizeof(info->name), ":%u.%u", i, j);
      info->port = i;
      info->device = j;
      info->pcidomain = nv_ctrl_pci_domain;
      info->pcibus = nv_ctrl_pci_bus;
      info->pcidevice = nv_ctrl_pci_device;
      info->pcifunc = nv_ctrl_pci_func;
      info->productname = productname;

      hwloc_debug("GL device %s (product %s) on PCI 0000:%02x:%02x.%u\n", info->name, productname,
		  nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);

      /* validate this device */
      data->nr_display++;
    }
    XCloseDisplay(display);
  }
}
Ejemplo n.º 17
0
/*
 * do_enable()
 *
 * Enables frame lock on the X Server by setting the first capable/available
 * display device as the frame lock server (master) and setting all other
 * display devices as clients (slaves).
 *
 * NOTE: It is up to the user to ensure that each display device is set with
 *       the same refresh rate (mode timings).
 *
 */
static void do_enable(Display *dpy)
{
    Bool ret;
    int num_framelocks;
    int framelock;
    int gpu;
    unsigned int mask;

    int *data;
    int len;
    int i;

    int enabled;
    int masterable;
    int pick_server = 1;
    int server_set = 0;


    /* Query the number of frame lock devices to enable */

    ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK,
                                  &num_framelocks);
    if (!ret) {
        printf("Failed to query number of frame lock devices!\n");
        return;
    }
    printf("Found %d frame lock device(s) on server.\n", num_framelocks);
    if ( !num_framelocks ) {
        return;
    }

    /* Enable frame lock on all GPUs connected to each frame lock device */
    
    for (framelock = 0; framelock < num_framelocks; framelock++) {
        
        printf("\n");
        printf("- Frame Lock Board %d :\n", framelock);

        /* Query the GPUs connected to this frame lock device */
        
        ret = XNVCTRLQueryTargetBinaryData
            (dpy,
             NV_CTRL_TARGET_TYPE_FRAMELOCK,
             framelock, // target_id
             0, // display_mask
             NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK,
             (unsigned char **) &data,
             &len);
        if (!ret) {
            printf("  - Failed to query list of GPUs!\n");
            continue;
        }
        
        /* Enable frame lock on all GPUs connected to the frame lock device */
        
        if ( !data[0] ) {
            printf("  - No GPUs found!\n");
        } else {
            printf("  - Found %d GPU(s).\n", data[0]);
        }

        for (i = 1; i <= data[0]; i++) {
            gpu = data[i];
        
            printf("  - Enabling G-Sync Device %d - GPU %d... ",
                   framelock, gpu);
            
            /* Make sure frame lock is disabled */

            XNVCTRLQueryTargetAttribute(dpy,
                                        NV_CTRL_TARGET_TYPE_GPU,
                                        gpu, // target_id
                                        0, // display_mask
                                        NV_CTRL_FRAMELOCK_SYNC,
                                        &enabled);
            if (enabled != NV_CTRL_FRAMELOCK_SYNC_DISABLE) {
                printf("Frame lock already enabled!\n");
                continue;
            }

            /* Get the list of displays to enable */

            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              0, // display_mask
                                              NV_CTRL_ENABLED_DISPLAYS,
                                              (int *)&mask);
            if (!ret) {
                printf("Failed to query enabled displays!\n");
                continue;
            }

            /* Query if any of the enabled displays can be set as a
             * master on this GPU.
             */

            ret = XNVCTRLQueryTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              mask, // display_mask
                                              NV_CTRL_FRAMELOCK_MASTERABLE,
                                              &masterable);
            if (!ret) {
                printf("Failed to query masterable!\n");
                continue;
            }
            
            /* Clear the master setting if any */
            
            if (masterable) {
                XNVCTRLSetTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GPU,
                                          gpu, // target_id
                                          0, // display_mask
                                          NV_CTRL_FRAMELOCK_MASTER,
                                          0);
            }
            
            /* Clear the slaves setting if any */

            XNVCTRLSetTargetAttribute(dpy,
                                      NV_CTRL_TARGET_TYPE_GPU,
                                      gpu, // target_id
                                      0, // display_mask
                                      NV_CTRL_FRAMELOCK_SLAVES,
                                      0);

            printf("\n");
            
            /* Pick the first available/capable display device as master */

            if (pick_server && masterable) {
                
                /* Just pick the first enabled display */
                
                unsigned int master = (1<<31);
                while (master && !(master & masterable)) {
                    master >>= 1;
                }
                
                if (master) {
                    mask &= ~master;

                    /* Make sure we're not using the House Sync signal. */
                    
                    XNVCTRLSetTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_FRAMELOCK,
                                              framelock, // target_id
                                              0, // display_mask
                                              NV_CTRL_USE_HOUSE_SYNC,
                                              NV_CTRL_USE_HOUSE_SYNC_FALSE);
                    
                    /* Set the master */
                    
                    XNVCTRLSetTargetAttribute(dpy,
                                              NV_CTRL_TARGET_TYPE_GPU,
                                              gpu, // target_id
                                              0, // display_mask
                                              NV_CTRL_FRAMELOCK_MASTER,
                                              master);

                    printf("    - Set Server Display    : 0x%08x\n", master);
                    pick_server = 0;
                    server_set = 1;
                }
            }

            /* Set rest of enabled display devices as clients (slaves) */

            if (mask) {
                XNVCTRLSetTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GPU,
                                          gpu, // target_id
                                          0, // display_mask
                                          NV_CTRL_FRAMELOCK_SLAVES,
                                          mask);
                printf("    - Set Client Display(s) : 0x%08x\n", mask);
            }

            /* Enable frame lock */

            XNVCTRLSetTargetAttribute(dpy,
                                      NV_CTRL_TARGET_TYPE_GPU,
                                      gpu, // target_id
                                      0, // display_mask
                                      NV_CTRL_FRAMELOCK_SYNC,
                                      NV_CTRL_FRAMELOCK_SYNC_ENABLE);
            XFlush(dpy);
            printf("    - Frame Lock Sync Enabled.\n");
            
            /* If we just enabled the server, also toggle the test signal
             * to guarentee accuracy of the universal frame count (as
             * returned by the glXQueryFrameCountNV() function in the
             * GLX_NV_swap_group extension).
             */
            if (server_set) {
                XNVCTRLSetTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GPU,
                                          gpu, // target_id
                                          0, // display_mask
                                          NV_CTRL_FRAMELOCK_TEST_SIGNAL,
                                          NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE);
                                          
                XNVCTRLSetTargetAttribute(dpy,
                                          NV_CTRL_TARGET_TYPE_GPU,
                                          gpu, // target_id
                                          0, // display_mask
                                          NV_CTRL_FRAMELOCK_TEST_SIGNAL,
                                          NV_CTRL_FRAMELOCK_TEST_SIGNAL_DISABLE);

                printf("    - Frame Lock Test Signal Toggled.\n");
                server_set = 0;
            }

        } /* Done enabling GPUs */

        XFree(data);

    } /* Done enabling framelocks */