graphics port IDs redo.

This commit is contained in:
Harald Hope 2023-11-06 15:57:34 -08:00
parent 1b416a21be
commit 2bdd6d4a24

92
pinxi
View file

@ -51,7 +51,7 @@ use POSIX qw(ceil uname strftime ttyname);
my $self_name='pinxi'; my $self_name='pinxi';
my $self_version='3.3.31'; my $self_version='3.3.31';
my $self_date='2023-11-06'; my $self_date='2023-11-06';
my $self_patch='04'; my $self_patch='06';
## END INXI INFO ## ## END INXI INFO ##
my ($b_pledge,@pledges); my ($b_pledge,@pledges);
@ -17417,10 +17417,21 @@ sub xrandr_data {
my ($diagonal,$diagonal_m,$dpi,$monitor_id,$pos_x,$pos_y,$primary); my ($diagonal,$diagonal_m,$dpi,$monitor_id,$pos_x,$pos_y,$primary);
my ($res_x,$res_x_max,$res_y,$res_y_max); my ($res_x,$res_x_max,$res_y,$res_y_max);
my ($screen_id,$set_as,$size_x,$size_x_i,$size_y,$size_y_i); my ($screen_id,$set_as,$size_x,$size_x_i,$size_y,$size_y_i);
my (@ids,%monitors,@xrandr_screens,$xrandr); my (@ids,%monitors,@xrandr,@xrandr_screens);
# note: --prop support added v 1.2, ~2009 in distros
if (!$fake{'xrandr'}){ if (!$fake{'xrandr'}){
$xrandr = main::grabber("$program $display_opt 2>/dev/null",'','strip','ref'); # @xrandr = main::grabber("$program $display_opt 2>/dev/null",'','strip','arr');
# note: --prop support added v 1.2, ~2009 in distros
@xrandr = qx($program --prop $display_opt 2>&1);
if ($? > 0){
# we only want to rerun if unsupported option
if (grep {/unrecognized/} @xrandr){
@xrandr = qx($program $display_opt 2>/dev/null);
}
else {
@xrandr = ();
}
}
chomp(@xrandr) if @xrandr;
} }
else { else {
# my $file; # my $file;
@ -17429,13 +17440,13 @@ sub xrandr_data {
# $file = "$ENV{HOME}/bin/scripts/inxi/data/xrandr/xrandr-test-1.txt"; # $file = "$ENV{HOME}/bin/scripts/inxi/data/xrandr/xrandr-test-1.txt";
# $file = "$ENV{HOME}/bin/scripts/inxi/data/xrandr/xrandr-test-2.txt"; # $file = "$ENV{HOME}/bin/scripts/inxi/data/xrandr/xrandr-test-2.txt";
# $file = "$ENV{HOME}/bin/scripts/inxi/data/xrandr/xrandr-1-screen-2-in-inxi.txt"; # $file = "$ENV{HOME}/bin/scripts/inxi/data/xrandr/xrandr-1-screen-2-in-inxi.txt";
# $xrandr = main::reader($file,'strip','ref'); # @xrandr = main::reader($file,'strip','arr');
} }
# $graphics{'dimensions'} = (\@dimensions); # $graphics{'dimensions'} = (\@dimensions);
# we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
# multiple screens from different video cards # multiple screens from different video cards
# $graphics{'screens'} = undef; # $graphics{'screens'} = undef;
foreach (@$xrandr){ foreach (@xrandr){
# note: no mm as with xdpyinfo # note: no mm as with xdpyinfo
# Screen 0: minimum 320 x 200, current 2560 x 1024, maximum 8192 x 8192 # Screen 0: minimum 320 x 200, current 2560 x 1024, maximum 8192 x 8192
if (/^Screen ([0-9]+):/){ if (/^Screen ([0-9]+):/){
@ -17494,7 +17505,7 @@ sub xrandr_data {
($res_x,$res_y,$pos_x,$pos_y,$size_x,$size_x_i,$size_y,$size_y_i,$dpi,$diagonal,$diagonal_m) = () ($res_x,$res_y,$pos_x,$pos_y,$size_x,$size_x_i,$size_y,$size_y_i,$dpi,$diagonal,$diagonal_m) = ()
} }
undef $primary; undef $primary;
push(@ids,$monitor_id); push(@ids,[$monitor_id]);
if ($set_as){ if ($set_as){
$primary = $monitor_id; $primary = $monitor_id;
$set_as =~ s/\s$//; $set_as =~ s/\s$//;
@ -17520,18 +17531,31 @@ sub xrandr_data {
# print "x:$size_x y:$size_y rx:$res_x ry:$res_y dpi:$dpi\n"; # print "x:$size_x y:$size_y rx:$res_x ry:$res_y dpi:$dpi\n";
($res_x,$res_y,$size_x,$size_x_i,$size_y,$size_y_i,$set_as) = (0,0,0,0,0,0,0,0,undef); ($res_x,$res_y,$size_x,$size_x_i,$size_y,$size_y_i,$set_as) = (0,0,0,0,0,0,0,0,undef);
} }
else {
my @working = split(/\s+/,$_); my @working = split(/\s+/,$_);
# this is the monitor current dimensions # this is the monitor current dimensions
# 5120x1440 59.98* 29.98 # 5120x1440 59.98* 29.98
if ($working[1] =~ /\*/){ # print Data::Dumper::Dumper \@working;
$working[1] =~ s/\*|\+//g; next if !$working[2];
$working[1] = sprintf("%.0f",$working[1]); if ($working[2] =~ /\*/){
# print "$working[1] :: $working[2]\n";
$working[2] =~ s/\*|\+//g;
$working[2] = sprintf("%.0f",$working[2]);
if ($monitor_id && %monitors){ if ($monitor_id && %monitors){
$monitors{$monitor_id}->{'hz'} = $working[1]; $monitors{$monitor_id}->{'hz'} = $working[2];
} }
($diagonal,$dpi) = ('',''); ($diagonal,$dpi) = ('','');
# print Data::Dumper::Dumper \@monitors; # print Data::Dumper::Dumper \@monitors;
} }
# \tCONNECTOR_ID: 52
elsif ($working[1] eq 'CONNECTOR_ID:'){
# print "$working[1] :: $working[2]\n";
if ($monitor_id && %monitors){
push(@{$ids[$#ids]},$working[2]);
$monitors{$monitor_id}->{'connector-id'} = $working[2];
}
}
}
} }
if (%monitors){ if (%monitors){
push(@xrandr_screens,{%monitors}); push(@xrandr_screens,{%monitors});
@ -18780,8 +18804,12 @@ sub monitor_edid_data {
$monitor_ids->{$port}{'ratio'} = join(', ', @{$edid->{'ratios'}}); $monitor_ids->{$port}{'ratio'} = join(', ', @{$edid->{'ratios'}});
} }
if ($edid->{'detailed_timings'}){ if ($edid->{'detailed_timings'}){
if ($edid->{'detailed_timings'}[0]{'horizontal_active'}){
$monitor_ids->{$port}{'res-x'} = $edid->{'detailed_timings'}[0]{'horizontal_active'}; $monitor_ids->{$port}{'res-x'} = $edid->{'detailed_timings'}[0]{'horizontal_active'};
}
if ($edid->{'detailed_timings'}[0]{'vertical_active'}){
$monitor_ids->{$port}{'res-y'} = $edid->{'detailed_timings'}[0]{'vertical_active'}; $monitor_ids->{$port}{'res-y'} = $edid->{'detailed_timings'}[0]{'vertical_active'};
}
if ($edid->{'detailed_timings'}[0]{'horizontal_image_size'}){ if ($edid->{'detailed_timings'}[0]{'horizontal_image_size'}){
$monitor_ids->{$port}{'size-x'} = $edid->{'detailed_timings'}[0]{'horizontal_image_size'}; $monitor_ids->{$port}{'size-x'} = $edid->{'detailed_timings'}[0]{'horizontal_image_size'};
$monitor_ids->{$port}{'size-x-i'} = $edid->{'detailed_timings'}[0]{'horizontal_image_size_i'}; $monitor_ids->{$port}{'size-x-i'} = $edid->{'detailed_timings'}[0]{'horizontal_image_size_i'};
@ -18968,15 +18996,20 @@ sub set_monitor_layouts {
# This is required to resolve the situation where some xorg drivers change # This is required to resolve the situation where some xorg drivers change
# the kernel ID for the port to something slightly different, amdgpu in particular. # the kernel ID for the port to something slightly different, amdgpu in particular.
# Note: connector_id if available from xrandr and /sys allow for matching.
sub map_monitor_ids { sub map_monitor_ids {
eval $start if $b_log; eval $start if $b_log;
my ($display_ids) = @_; my ($display_ids) = @_;
return if !$monitor_ids; return if !$monitor_ids;
my (@sys_ids,@unmatched_display,@unmatched_sys); my (@sys_ids,@unmatched_display,@unmatched_sys);
@unmatched_display = @$display_ids = sort { lc($a) cmp lc($b) } @$display_ids; @$display_ids = sort {lc($a->[0]) cmp lc($b->[0])} @$display_ids;
foreach my $d_id (@$display_ids){
push(@unmatched_display,$d_id->[0]);
}
foreach my $key (keys %$monitor_ids){ foreach my $key (keys %$monitor_ids){
if ($monitor_ids->{$key}{'status'} eq 'connected'){ if ($monitor_ids->{$key}{'status'} eq 'connected'){
push(@sys_ids,$key); push(@sys_ids,[$key,$monitor_ids->{$key}{'connector-id'}]);
push(@unmatched_sys,$key);
} }
} }
# @sys_ids = ('DVI-I-1','eDP-1','VGA-1'); # @sys_ids = ('DVI-I-1','eDP-1','VGA-1');
@ -18985,7 +19018,8 @@ sub map_monitor_ids {
print 'sys: ', Data::Dumper::Dumper \@sys_ids if $dbg[45]; print 'sys: ', Data::Dumper::Dumper \@sys_ids if $dbg[45];
print 'display: ', Data::Dumper::Dumper $display_ids if $dbg[45]; print 'display: ', Data::Dumper::Dumper $display_ids if $dbg[45];
return if scalar @sys_ids != scalar @$display_ids; return if scalar @sys_ids != scalar @$display_ids;
@unmatched_sys = @sys_ids = sort { lc($a) cmp lc($b) } @sys_ids; @sys_ids = sort {lc($a->[0]) cmp lc($b->[0])} @sys_ids;
@unmatched_sys = sort {lc($a) cmp lc($b)} @unmatched_sys;
$monitor_map = {}; $monitor_map = {};
# known patterns: s: DP-1 d: DisplayPort-0; s: DP-1 d: DP1-1; s: DP-2 d: DP1-2; # known patterns: s: DP-1 d: DisplayPort-0; s: DP-1 d: DP1-1; s: DP-2 d: DP1-2;
# s: HDMI-A-2 d: HDMI-A-1; s: HDMI-A-2 d: HDMI-2; s: DVI-1 d: DVI1; s: HDMI-1 d: HDMI1 # s: HDMI-A-2 d: HDMI-A-1; s: HDMI-A-2 d: HDMI-2; s: DVI-1 d: DVI1; s: HDMI-1 d: HDMI1
@ -18998,16 +19032,26 @@ sub map_monitor_ids {
my $b_single = (scalar @sys_ids == 1) ? 1 : 0; my $b_single = (scalar @sys_ids == 1) ? 1 : 0;
my $pattern = '([A-Z]+)(-[A-Z]-\d+-\d+|-[A-Z]-\d+|-?\d+-\d+|-?\d+|)'; my $pattern = '([A-Z]+)(-[A-Z]-\d+-\d+|-[A-Z]-\d+|-?\d+-\d+|-?\d+|)';
for (my $i=0; $i < scalar @$display_ids; $i++){ for (my $i=0; $i < scalar @$display_ids; $i++){
print "s: $sys_ids[$i] d: $display_ids->[$i]\n" if $dbg[45]; print "s: $sys_ids[$i]->[0] d: $display_ids->[$i][0]\n" if $dbg[45];
my $b_match;
# we're going for the connector match first
if ($display_ids->[$i][1] && $sys_ids[$i]->[1]){
if ($sys_ids[$i]->[1] == $display_ids->[$i][1]){
$b_match = 1;
$monitor_map->{$display_ids->[$i][0]} = $sys_ids[$i]->[0];
@unmatched_display = grep {$_ ne $display_ids->[$i][0]} @unmatched_display;
@unmatched_sys = grep {$_ ne $sys_ids[$i]->[0]} @unmatched_sys;
}
}
# try 1: /^([A-Z]+)(-[AB]|-[ADI]|-[ADI]-\d+?|-\d+?)?(-)?(\d+)$/i # try 1: /^([A-Z]+)(-[AB]|-[ADI]|-[ADI]-\d+?|-\d+?)?(-)?(\d+)$/i
if ($display_ids->[$i] =~ /^$pattern$/i){ if (!$b_match && $display_ids->[$i][0] =~ /^$pattern$/i){
$d_1 = $1; $d_1 = $1;
$d_2 = ($2) ? $2 : ''; $d_2 = ($2) ? $2 : '';
$d_2 =~ /(\d+)?$/; $d_2 =~ /(\d+)?$/;
$d_m = ($1) ? $1 : 0; $d_m = ($1) ? $1 : 0;
$d_1 =~ s/^DisplayPort/DP/i; # amdgpu... $d_1 =~ s/^DisplayPort/DP/i; # amdgpu...
print " d1: $d_1 d2: $d_2 d3: $d_m\n" if $dbg[45]; print " d1: $d_1 d2: $d_2 d3: $d_m\n" if $dbg[45];
if ($sys_ids[$i] =~ /^$pattern$/i){ if ($sys_ids[$i]->[0] =~ /^$pattern$/i){
$s_1 = $1; $s_1 = $1;
$s_2 = ($2) ? $2 : ''; $s_2 = ($2) ? $2 : '';
$s_2 =~ /(\d+)?$/; $s_2 =~ /(\d+)?$/;
@ -19015,21 +19059,21 @@ sub map_monitor_ids {
$d_1 = $s_1 if uc($d_1) eq 'XWAYLAND'; $d_1 = $s_1 if uc($d_1) eq 'XWAYLAND';
print " d1: $d_1 s1: $s_1 dm: $d_m sm: $s_m \n" if $dbg[45]; print " d1: $d_1 s1: $s_1 dm: $d_m sm: $s_m \n" if $dbg[45];
if ($d_1 eq $s_1 && ($d_m == $s_m || $d_m == ($s_m - 1))){ if ($d_1 eq $s_1 && ($d_m == $s_m || $d_m == ($s_m - 1))){
$monitor_map->{$display_ids->[$i]} = $sys_ids[$i]; $monitor_map->{$display_ids->[$i][0]} = $sys_ids[$i]->[0];
@unmatched_display = grep {$_ ne $display_ids->[$i]} @unmatched_display; @unmatched_display = grep {$_ ne $display_ids->[$i][0]} @unmatched_display;
@unmatched_sys = grep {$_ ne $sys_ids[$i]} @unmatched_sys; @unmatched_sys = grep {$_ ne $sys_ids[$i]->[0]} @unmatched_sys;
} }
} }
} }
# in case of one unmatched, we'll dump this, and use the actual unmatched # in case of one unmatched, we'll dump this, and use the actual unmatched
if (!$monitor_map->{$display_ids->[$i]}){ if (!$b_match && !$monitor_map->{$display_ids->[$i][0]}){
# we're not even going to try, if there's 1 sys and 1 display, just use it! # we're not even going to try, if there's 1 sys and 1 display, just use it!
if ($b_single){ if ($b_single){
$monitor_map->{$display_ids->[$i]} = $sys_ids[$i]; $monitor_map->{$display_ids->[$i][0]} = $sys_ids[$i]->[0];
(@unmatched_display,@unmatched_sys) = (); (@unmatched_display,@unmatched_sys) = ();
} }
else { else {
$monitor_map->{$display_ids->[$i]} = main::message('monitor-id'); $monitor_map->{$display_ids->[$i][0]} = main::message('monitor-id');
} }
} }
} }
@ -19039,7 +19083,7 @@ sub map_monitor_ids {
# obviously, if one of the matches was wrong, this will also be wrong, but # obviously, if one of the matches was wrong, this will also be wrong, but
# thats' life when dealing with irrational data. DP is a particular problem. # thats' life when dealing with irrational data. DP is a particular problem.
if (scalar @unmatched_sys == 1){ if (scalar @unmatched_sys == 1){
$monitor_map->{$unmatched_display[0]} = $unmatched_sys[0]; $monitor_map->{$unmatched_display[0]} = $unmatched_sys[0]->[0];
} }
main::log_data('dump','$monitor_map ref',$monitor_map) if $b_log; main::log_data('dump','$monitor_map ref',$monitor_map) if $b_log;
print Data::Dumper::Dumper $monitor_map if $dbg[45]; print Data::Dumper::Dumper $monitor_map if $dbg[45];