@ -2,9 +2,11 @@
# include <drm_fourcc.h>
# include <drm_mode.h>
# include <drm.h>
# include <libudev.h>
# include <stdio.h>
# include <string.h>
# include <wlr/util/log.h>
# include "backend/drm/drm.h"
# include "backend/drm/util.h"
int32_t calculate_refresh_rate ( const drmModeModeInfo * mode ) {
@ -26,94 +28,51 @@ int32_t calculate_refresh_rate(const drmModeModeInfo *mode) {
return refresh ;
}
// Constructed from http://edid.tv/manufacturer
static const char * get_manufacturer ( uint16_t id ) {
# define ID(a, b, c) ((a & 0x1f) << 10) | ((b & 0x1f) << 5) | (c & 0x1f)
switch ( id ) {
case ID ( ' A ' , ' A ' , ' A ' ) : return " Avolites Ltd " ;
case ID ( ' A ' , ' C ' , ' I ' ) : return " Ancor Communications Inc " ;
case ID ( ' A ' , ' C ' , ' R ' ) : return " Acer Technologies " ;
case ID ( ' A ' , ' D ' , ' A ' ) : return " Addi-Data GmbH " ;
case ID ( ' A ' , ' P ' , ' P ' ) : return " Apple Computer Inc " ;
case ID ( ' A ' , ' S ' , ' K ' ) : return " Ask A/S " ;
case ID ( ' A ' , ' V ' , ' T ' ) : return " Avtek (Electronics) Pty Ltd " ;
case ID ( ' B ' , ' N ' , ' O ' ) : return " Bang & Olufsen " ;
case ID ( ' B ' , ' N ' , ' Q ' ) : return " BenQ Corporation " ;
case ID ( ' C ' , ' M ' , ' N ' ) : return " Chimei Innolux Corporation " ;
case ID ( ' C ' , ' M ' , ' O ' ) : return " Chi Mei Optoelectronics corp. " ;
case ID ( ' C ' , ' R ' , ' O ' ) : return " Extraordinary Technologies PTY Limited " ;
case ID ( ' D ' , ' E ' , ' L ' ) : return " Dell Inc. " ;
case ID ( ' D ' , ' G ' , ' C ' ) : return " Data General Corporation " ;
case ID ( ' D ' , ' O ' , ' N ' ) : return " DENON, Ltd. " ;
case ID ( ' E ' , ' N ' , ' C ' ) : return " Eizo Nanao Corporation " ;
case ID ( ' E ' , ' P ' , ' H ' ) : return " Epiphan Systems Inc. " ;
case ID ( ' E ' , ' X ' , ' P ' ) : return " Data Export Corporation " ;
case ID ( ' F ' , ' N ' , ' I ' ) : return " Funai Electric Co., Ltd. " ;
case ID ( ' F ' , ' U ' , ' S ' ) : return " Fujitsu Siemens Computers GmbH " ;
case ID ( ' G ' , ' S ' , ' M ' ) : return " Goldstar Company Ltd " ;
case ID ( ' H ' , ' I ' , ' Q ' ) : return " Kaohsiung Opto Electronics Americas, Inc. " ;
case ID ( ' H ' , ' S ' , ' D ' ) : return " HannStar Display Corp " ;
case ID ( ' H ' , ' T ' , ' C ' ) : return " Hitachi Ltd " ;
case ID ( ' H ' , ' W ' , ' P ' ) : return " Hewlett Packard " ;
case ID ( ' I ' , ' N ' , ' T ' ) : return " Interphase Corporation " ;
case ID ( ' I ' , ' N ' , ' X ' ) : return " Communications Supply Corporation (A division of WESCO) " ;
case ID ( ' I ' , ' T ' , ' E ' ) : return " Integrated Tech Express Inc " ;
case ID ( ' I ' , ' V ' , ' M ' ) : return " Iiyama North America " ;
case ID ( ' L ' , ' E ' , ' N ' ) : return " Lenovo Group Limited " ;
case ID ( ' M ' , ' A ' , ' X ' ) : return " Rogen Tech Distribution Inc " ;
case ID ( ' M ' , ' E ' , ' G ' ) : return " Abeam Tech Ltd " ;
case ID ( ' M ' , ' E ' , ' I ' ) : return " Panasonic Industry Company " ;
case ID ( ' M ' , ' T ' , ' C ' ) : return " Mars-Tech Corporation " ;
case ID ( ' M ' , ' T ' , ' X ' ) : return " Matrox " ;
case ID ( ' N ' , ' E ' , ' C ' ) : return " NEC Corporation " ;
case ID ( ' N ' , ' E ' , ' X ' ) : return " Nexgen Mediatech Inc. " ;
case ID ( ' O ' , ' N ' , ' K ' ) : return " ONKYO Corporation " ;
case ID ( ' O ' , ' R ' , ' N ' ) : return " ORION ELECTRIC CO., LTD. " ;
case ID ( ' O ' , ' T ' , ' M ' ) : return " Optoma Corporation " ;
case ID ( ' O ' , ' V ' , ' R ' ) : return " Oculus VR, Inc. " ;
case ID ( ' P ' , ' H ' , ' L ' ) : return " Philips Consumer Electronics Company " ;
case ID ( ' P ' , ' I ' , ' O ' ) : return " Pioneer Electronic Corporation " ;
case ID ( ' P ' , ' N ' , ' R ' ) : return " Planar Systems, Inc. " ;
case ID ( ' Q ' , ' D ' , ' S ' ) : return " Quanta Display Inc. " ;
case ID ( ' R ' , ' A ' , ' T ' ) : return " Rent-A-Tech " ;
case ID ( ' R ' , ' E ' , ' N ' ) : return " Renesas Technology Corp. " ;
case ID ( ' S ' , ' A ' , ' M ' ) : return " Samsung Electric Company " ;
case ID ( ' S ' , ' A ' , ' N ' ) : return " Sanyo Electric Co., Ltd. " ;
case ID ( ' S ' , ' E ' , ' C ' ) : return " Seiko Epson Corporation " ;
case ID ( ' S ' , ' H ' , ' P ' ) : return " Sharp Corporation " ;
case ID ( ' S ' , ' I ' , ' I ' ) : return " Silicon Image, Inc. " ;
case ID ( ' S ' , ' N ' , ' Y ' ) : return " Sony " ;
case ID ( ' S ' , ' T ' , ' D ' ) : return " STD Computer Inc " ;
case ID ( ' S ' , ' V ' , ' S ' ) : return " SVSI " ;
case ID ( ' S ' , ' Y ' , ' N ' ) : return " Synaptics Inc " ;
case ID ( ' T ' , ' C ' , ' L ' ) : return " Technical Concepts Ltd " ;
case ID ( ' T ' , ' O ' , ' P ' ) : return " Orion Communications Co., Ltd. " ;
case ID ( ' T ' , ' S ' , ' B ' ) : return " Toshiba America Info Systems Inc " ;
case ID ( ' T ' , ' S ' , ' T ' ) : return " Transtream Inc " ;
case ID ( ' U ' , ' N ' , ' K ' ) : return " Unknown " ;
case ID ( ' V ' , ' E ' , ' S ' ) : return " Vestel Elektronik Sanayi ve Ticaret A. S. " ;
case ID ( ' V ' , ' I ' , ' T ' ) : return " Visitech AS " ;
case ID ( ' V ' , ' I ' , ' Z ' ) : return " VIZIO, Inc " ;
case ID ( ' V ' , ' L ' , ' V ' ) : return " Valve " ;
case ID ( ' V ' , ' S ' , ' C ' ) : return " ViewSonic Corporation " ;
case ID ( ' Y ' , ' M ' , ' H ' ) : return " Yamaha Corporation " ;
default : return " Unknown " ;
static const char * get_manufacturer ( struct udev_hwdb * hwdb , uint16_t code ) {
static char pnp_id [ 4 ] ;
// The ASCII 3-letter manufacturer PnP ID is encoded in 5-bit codes
pnp_id [ 0 ] = ( ( code > > 10 ) & 0x1F ) + ' @ ' ;
pnp_id [ 1 ] = ( ( code > > 5 ) & 0x1F ) + ' @ ' ;
pnp_id [ 2 ] = ( ( code > > 0 ) & 0x1F ) + ' @ ' ;
pnp_id [ 3 ] = ' \0 ' ;
if ( hwdb = = NULL ) {
return pnp_id ;
}
# undef ID
char query [ 32 ] ;
snprintf ( query , sizeof ( query ) , " acpi:%s: " , pnp_id ) ;
struct udev_list_entry * acpi_entry =
udev_hwdb_get_properties_list_entry ( hwdb , query , 0 ) ;
if ( acpi_entry = = NULL ) {
return pnp_id ;
}
struct udev_list_entry * vendor_entry =
udev_list_entry_get_by_name ( acpi_entry , " ID_VENDOR_FROM_DATABASE " ) ;
if ( vendor_entry = = NULL ) {
return pnp_id ;
}
return udev_list_entry_get_value ( vendor_entry ) ;
}
/* 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_output * restrict output , size_t len , const uint8_t * data ) {
void parse_edid ( struct wlr_drm_connector * conn , size_t len , const uint8_t * data ) {
struct wlr_output * output = & conn - > output ;
if ( ! data | | len < 128 ) {
snprintf ( output - > make , sizeof ( output - > make ) , " <Unknown> " ) ;
snprintf ( output - > model , sizeof ( output - > model ) , " <Unknown> " ) ;
snprintf ( output - > make , sizeof ( output - > make ) , " Unknown " ) ;
snprintf ( output - > model , sizeof ( output - > model ) , " Unknown " ) ;
return ;
}
uint16_t id = ( data [ 8 ] < < 8 ) | data [ 9 ] ;
snprintf ( output - > make , sizeof ( output - > make ) , " %s " , get_manufacturer ( id ) ) ;
snprintf ( output - > make , sizeof ( output - > make ) , " %s " ,
get_manufacturer ( conn - > backend - > hwdb , id ) ) ;
uint16_t model = data [ 10 ] | ( data [ 11 ] < < 8 ) ;
snprintf ( output - > model , sizeof ( output - > model ) , " 0x%04X " , model ) ;