diff options
Diffstat (limited to 'backend')
| -rwxr-xr-x | backend/drm/gen_pnpids.sh | 7 | ||||
| -rw-r--r-- | backend/drm/meson.build | 10 | ||||
| -rw-r--r-- | backend/drm/util.c | 67 | 
3 files changed, 28 insertions, 56 deletions
| diff --git a/backend/drm/gen_pnpids.sh b/backend/drm/gen_pnpids.sh index 80e5542d..5a9547ae 100755 --- a/backend/drm/gen_pnpids.sh +++ b/backend/drm/gen_pnpids.sh @@ -13,12 +13,11 @@ gen_pnps()  }  cat << EOF -#include <stdint.h> -#include <stddef.h>  #include "backend/drm/util.h" +  #define PNP_ID(a, b, c) ((a & 0x1f) << 10) | ((b & 0x1f) << 5) | (c & 0x1f) -const char *get_pnp_manufacturer(uint16_t code) { -	switch (code) { +const char *get_pnp_manufacturer(const char code[static 3]) { +	switch (PNP_ID(code[0], code[1], code[2])) {  $(gen_pnps)  	}  	return NULL; diff --git a/backend/drm/meson.build b/backend/drm/meson.build index 3fb011c1..824134fe 100644 --- a/backend/drm/meson.build +++ b/backend/drm/meson.build @@ -5,6 +5,13 @@ hwdata = dependency(  	not_found_message: 'Required for the DRM backend.',  ) +libdisplay_info = dependency( +	'libdisplay-info', +	required: 'drm' in backends, +	fallback: 'libdisplay-info', +	not_found_message: 'Required for the DRM backend.', +) +  libliftoff = dependency(  	'libliftoff',  	version: '>=0.4.0', @@ -12,7 +19,7 @@ libliftoff = dependency(  	required: false,  ) -if not (hwdata.found() and features['session']) +if not (hwdata.found() and libdisplay_info.found() and features['session'])  	subdir_done()  endif @@ -45,4 +52,5 @@ endif  features += { 'drm-backend': true }  internal_features += { 'libliftoff': libliftoff.found() } +wlr_deps += libdisplay_info  wlr_deps += libliftoff diff --git a/backend/drm/util.c b/backend/drm/util.c index adb9306e..d4ece1f9 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -3,6 +3,8 @@  #include <drm_fourcc.h>  #include <drm_mode.h>  #include <drm.h> +#include <libdisplay-info/edid.h> +#include <libdisplay-info/info.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> @@ -48,9 +50,6 @@ enum wlr_output_mode_aspect_ratio get_picture_aspect_ratio(const drmModeModeInfo  	}  } -/* See https://en.wikipedia.org/wiki/Extended_Display_Identification_Data for layout of EDID data. - * We don't parse the EDID properly. We just expect to receive valid data. - */  void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) {  	struct wlr_output *output = &conn->output; @@ -61,62 +60,28 @@ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data)  	output->model = NULL;  	output->serial = NULL; -	if (!data || len < 128) { +	struct di_info *info = di_info_parse_edid(data, len); +	if (info == NULL) { +		wlr_log(WLR_ERROR, "Failed to parse EDID");  		return;  	} -	uint16_t id = (data[8] << 8) | data[9]; -	const char *manu = get_pnp_manufacturer(id); -	char pnp_id[4]; +	const struct di_edid *edid = di_info_get_edid(info); +	const struct di_edid_vendor_product *vendor_product = di_edid_get_vendor_product(edid); +	char pnp_id[] = { +		vendor_product->manufacturer[0], +		vendor_product->manufacturer[1], +		vendor_product->manufacturer[2], +		'\0', +	}; +	const char *manu = get_pnp_manufacturer(vendor_product->manufacturer);  	if (!manu) { -		// The ASCII 3-letter manufacturer PnP ID is encoded in 5-bit codes -		pnp_id[0] = ((id >> 10) & 0x1F) + '@'; -		pnp_id[1] = ((id >> 5) & 0x1F) + '@'; -		pnp_id[2] = ((id >> 0) & 0x1F) + '@'; -		pnp_id[3] = '\0';  		manu = pnp_id;  	}  	output->make = strdup(manu); -	uint16_t model = data[10] | (data[11] << 8); -	char model_str[32]; -	snprintf(model_str, sizeof(model_str), "0x%04" PRIX16, model); - -	uint32_t serial = data[12] | (data[13] << 8) | (data[14] << 8) | (data[15] << 8); -	char serial_str[32]; -	if (serial != 0) { -		snprintf(serial_str, sizeof(serial_str), "0x%08" PRIX32, serial); -	} else { -		serial_str[0] = '\0'; -	} - -	for (size_t i = 72; i <= 108; i += 18) { -		uint16_t flag = (data[i] << 8) | data[i + 1]; -		if (flag == 0 && data[i + 3] == 0xFC) { -			snprintf(model_str, sizeof(model_str), "%.13s", &data[i + 5]); - -			// Monitor names are terminated by newline if they're too short -			char *nl = strchr(model_str, '\n'); -			if (nl) { -				*nl = '\0'; -			} -		} else if (flag == 0 && data[i + 3] == 0xFF) { -			snprintf(serial_str, sizeof(serial_str), "%.13s", &data[i + 5]); - -			// Monitor serial numbers are terminated by newline if they're too -			// short -			char* nl = strchr(serial_str, '\n'); - -			if (nl) { -				*nl = '\0'; -			} -		} -	} - -	output->model = strdup(model_str); -	if (serial_str[0] != '\0') { -		output->serial = strdup(serial_str); -	} +	output->model = di_info_get_model(info); +	output->serial = di_info_get_serial(info);  }  const char *drm_connector_status_str(drmModeConnection status) { | 
