Exemple #1
0
/* Just read ranges from the EDID. */
void vbe_get_edid_ranges(struct vbe_edid1_info *edid,
			 unsigned char *hmin, unsigned char *hmax,
			 unsigned char *vmin, unsigned char *vmax)
{
	struct vbe_edid_monitor_descriptor *monitor;
	int i;

	*hmin = *hmax = *vmin = *vmax = 0;

	if (edid == NULL) {
		if((edid = vbe_get_edid_info(NULL, NULL)) == NULL) {
			return;
		}
	}

	for(i = 0; i < 4; i++) {
		monitor = &edid->monitor_details.monitor_descriptor[i];
		if(monitor->type == vbe_edid_monitor_descriptor_range) {
			*hmin = monitor->data.range_data.horizontal_min;
			*hmax = monitor->data.range_data.horizontal_max;
			*vmin = monitor->data.range_data.vertical_min;
			*vmax = monitor->data.range_data.vertical_max;
		}
	}
}
Exemple #2
0
PyObject*
ddc_query(PyObject *self, PyObject *args)
{
	PyObject *ret;
	int adapter;
	struct vbe_edid1_info *edid;
	
	unsigned char hmin, hmax, vmin, vmax;
	char eisa_id[8] = {0};
	char manufacturer[4];

	if (!PyArg_ParseTuple(args, "i", &adapter))
		return NULL;

	if (!vbe_get_edid_supported(adapter)) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	
	if ((edid = vbe_get_edid_info(adapter)) == NULL) {
		Py_INCREF(Py_None);
		return Py_None;
	}

	if (!is_valid(edid)) {
		free(edid);
		Py_INCREF(Py_None);
		return Py_None;
	}

	if (edid->version == 255 && edid->revision == 255) {
		free(edid);
		Py_INCREF(Py_None);
		return Py_None;
	}

	manufacturer[0] = edid->manufacturer_name.char1 + 'A' - 1;
	manufacturer[1] = edid->manufacturer_name.char2 + 'A' - 1;
	manufacturer[2] = edid->manufacturer_name.char3 + 'A' - 1;
	manufacturer[3] = '\0';
	snprintf(eisa_id, 8, "%s%04x", manufacturer, edid->product_code);

	if(edid->serial_number != 0xffffffff) {
		if(strcmp(manufacturer, "MAG") == 0) {
			edid->serial_number -= 0x7000000;
		}
		if(strcmp(manufacturer, "OQI") == 0) {
			edid->serial_number -= 456150000;
		}
		if(strcmp(manufacturer, "VSC") == 0) {
			edid->serial_number -= 640000000;
		}
	}

	ret = Py_BuildValue(
		"{s:i,"		/* version */
		"s:i,"		/* revision */
		"s:i,"		/* serial_number */
		"s:i,"		/* week */
		"s:i,"		/* year */
		"s:O,"		/* input_separate_sync */
		"s:O,"		/* input_composite_sync */
		"s:O,"		/* input_sync_on_green */
		"s:O,"		/* input_digital */
		"s:i,"		/* max_size_horizontal */
		"s:i,"		/* max_size_vertical */
		"s:f,"		/* gamma */
		"s:O,"		/* dpms_active_off */
		"s:O,"		/* dpms_suspend */
		"s:O,"		/* dpms_standby */
		"s:O,"		/* established_timings */
		"s:O,"		/* standard_timings */
		"s:O,"		/* detailed_timing */
		"s:s}",		/* eisa_id */

		"version", edid->version,
		"revision", edid->revision,
		"serial_number", edid->serial_number,
		"week", edid->week,
		"year", edid->year + 1990,
		"input_separate_sync", PyBool_FromLong(edid->video_input_definition.separate_sync),
		"input_composite_sync", PyBool_FromLong(edid->video_input_definition.composite_sync),
		"input_sync_on_green", PyBool_FromLong(edid->video_input_definition.sync_on_green),
		"input_digital", PyBool_FromLong(edid->video_input_definition.digital),
		"max_size_horizontal", edid->max_size_horizontal,
		"max_size_vertical", edid->max_size_vertical,
		"gamma", edid->gamma / 100.0 + 1,
		"dpms_active_off", PyBool_FromLong(edid->feature_support.active_off),
		"dpms_suspend", PyBool_FromLong(edid->feature_support.suspend),
		"dpms_standby", PyBool_FromLong(edid->feature_support.standby),
		"established_timings", get_established_timings(edid),
		"standard_timings", get_standard_timings(edid),
		"detailed_timing", get_detailed_timing_info(edid),
		"eisa_id", eisa_id
	);

	free(edid);
	return ret;
}
Exemple #3
0
struct vbe_modeline *vbe_get_edid_modelines(struct vbe_edid1_info *edid)
{
	struct vbe_modeline *ret;
	char buf[LINE_MAX];
	int modeline_count = 0, i, j;

	if (edid == NULL) {
		if((edid = vbe_get_edid_info(NULL, NULL)) == NULL) {
			return NULL;
		}
	}

	memcpy(buf, &edid->established_timings,
	       sizeof(edid->established_timings));
	for(i = 0; i < (8 * sizeof(edid->established_timings)); i++) {
		if(buf[i / 8] & (1 << (i % 8))) {
			modeline_count++;
		}
	}

	/* Count the number of standard timings. */
	for(i = 0; i < 8; i++) {
		int x, v;
		x = edid->standard_timing[i].xresolution;
		v = edid->standard_timing[i].vfreq;
		if(((edid->standard_timing[i].xresolution & 0x01) != x) &&
		   ((edid->standard_timing[i].vfreq & 0x01) != v)) {
			modeline_count++;
		}
	}

	ret = malloc(sizeof(struct vbe_modeline) * (modeline_count + 1));
	if(ret == NULL) {
		return NULL;
	}
	memset(ret, 0, sizeof(struct vbe_modeline) * (modeline_count + 1));

	modeline_count = 0;

	/* Fill out established timings. */
	if(edid->established_timings.timing_720x400_70) {
		ret[modeline_count].width = 720;
		ret[modeline_count].height = 400;
		ret[modeline_count].refresh = 70;
		modeline_count++;
	}
	if(edid->established_timings.timing_720x400_88) {
		ret[modeline_count].width = 720;
		ret[modeline_count].height = 400;
		ret[modeline_count].refresh = 88;
		modeline_count++;
	}
	if(edid->established_timings.timing_640x480_60) {
		ret[modeline_count].width = 640;
		ret[modeline_count].height = 480;
		ret[modeline_count].refresh = 60;
		modeline_count++;
	}
	if(edid->established_timings.timing_640x480_67) {
		ret[modeline_count].width = 640;
		ret[modeline_count].height = 480;
		ret[modeline_count].refresh = 67;
		modeline_count++;
	}
	if(edid->established_timings.timing_640x480_72) {
		ret[modeline_count].width = 640;
		ret[modeline_count].height = 480;
		ret[modeline_count].refresh = 72;
		modeline_count++;
	}
	if(edid->established_timings.timing_640x480_75) {
		ret[modeline_count].width = 640;
		ret[modeline_count].height = 480;
		ret[modeline_count].refresh = 75;
		modeline_count++;
	}
	if(edid->established_timings.timing_800x600_56) {
		ret[modeline_count].width = 800;
		ret[modeline_count].height = 600;
		ret[modeline_count].refresh = 56;
		modeline_count++;
	}
	if(edid->established_timings.timing_800x600_60) {
		ret[modeline_count].width = 800;
		ret[modeline_count].height = 600;
		ret[modeline_count].refresh = 60;
		modeline_count++;
	}
	if(edid->established_timings.timing_800x600_72) {
		ret[modeline_count].width = 800;
		ret[modeline_count].height = 600;
		ret[modeline_count].refresh = 72;
		modeline_count++;
	}
	if(edid->established_timings.timing_800x600_75) {
		ret[modeline_count].width = 800;
		ret[modeline_count].height = 600;
		ret[modeline_count].refresh = 75;
		modeline_count++;
	}
	if(edid->established_timings.timing_832x624_75) {
		ret[modeline_count].width = 832;
		ret[modeline_count].height = 624;
		ret[modeline_count].refresh = 75;
		modeline_count++;
	}
	if(edid->established_timings.timing_1024x768_87i) {
		ret[modeline_count].width = 1024;
		ret[modeline_count].height = 768;
		ret[modeline_count].refresh = 87;
		ret[modeline_count].interlaced = 1;
		modeline_count++;
	}
	if(edid->established_timings.timing_1024x768_60){
		ret[modeline_count].width = 1024;
		ret[modeline_count].height = 768;
		ret[modeline_count].refresh = 60;
		modeline_count++;
	}
	if(edid->established_timings.timing_1024x768_70){
		ret[modeline_count].width = 1024;
		ret[modeline_count].height = 768;
		ret[modeline_count].refresh = 70;
		modeline_count++;
	}
	if(edid->established_timings.timing_1024x768_75){
		ret[modeline_count].width = 1024;
		ret[modeline_count].height = 768;
		ret[modeline_count].refresh = 75;
		modeline_count++;
	}
	if(edid->established_timings.timing_1280x1024_75) {
		ret[modeline_count].width = 1280;
		ret[modeline_count].height = 1024;
		ret[modeline_count].refresh = 75;
		modeline_count++;
	}

	/* Add in standard timings. */
	for(i = 0; i < 8; i++) {
		float aspect = 1;
		int x, v;
		x = edid->standard_timing[i].xresolution;
		v = edid->standard_timing[i].vfreq;
		if(((edid->standard_timing[i].xresolution & 0x01) != x) &&
		   ((edid->standard_timing[i].vfreq & 0x01) != v)) {
			switch(edid->standard_timing[i].aspect) {
				case aspect_75: aspect = 0.7500; break;
				case aspect_8: aspect = 0.8000; break;
				case aspect_5625: aspect = 0.5625; break;
				default: aspect = 1; break;
			}
			x = (edid->standard_timing[i].xresolution + 31) * 8;
			ret[modeline_count].width = x;
			ret[modeline_count].height = x * aspect;
			ret[modeline_count].refresh =
				edid->standard_timing[i].vfreq + 60;
			modeline_count++;
		}
	}

	/* Now tack on any matching modelines. */
	for(i = 0; ret[i].refresh != 0; i++) {
		struct vesa_timing_t *t = NULL;
		for(j = 0; known_vesa_timings[j].refresh != 0; j++) {
			t = &known_vesa_timings[j];
			if(ret[i].width == t->x)
			if(ret[i].height == t->y)
			if(ret[i].refresh == t->refresh) {
				snprintf(buf, sizeof(buf),
					 "ModeLine \"%dx%d\"\t%6.2f "
					 "%4d %4d %4d %4d %4d %4d %4d %4d %s %s"
					 , t->x, t->y, t->dotclock,
					 t->timings[0],
					 t->timings[0] + t->timings[1],
					 t->timings[0] + t->timings[1] +
					 t->timings[2],
					 t->timings[0] + t->timings[1] +
					 t->timings[2] + t->timings[3],
					 t->timings[4],
					 t->timings[4] + t->timings[5],
					 t->timings[4] + t->timings[5] +
					 t->timings[6],
					 t->timings[4] + t->timings[5] +
					 t->timings[6] + t->timings[7],
					 t->hsync == hsync_pos ?
					 "+hsync" : "-hsync",
					 t->vsync == vsync_pos ?
					 "+vsync" : "-vsync");
				ret[i].modeline = strdup(buf);
				ret[i].hfreq = t->hfreq;
				ret[i].vfreq = t->vfreq;
			}
		}
	}

	modeline_count = 0;
	for(i = 0; ret[i].refresh != 0; i++) {
		modeline_count++;
	}
	qsort(ret, modeline_count, sizeof(ret[0]), compare_vbe_modelines);

	return ret;
}