Skip to content

Instantly share code, notes, and snippets.

@joevt
Last active September 3, 2022 15:30
Show Gist options
  • Save joevt/e862b0088ef58b9144877d01401bcee8 to your computer and use it in GitHub Desktop.
Save joevt/e862b0088ef58b9144877d01401bcee8 to your computer and use it in GitHub Desktop.
List the display timings on an M1 Mac
#!/bin/bash
# by joevt Jan 7/2021
dodump=1
if [[ "$1" == "-s" ]]; then
dodump=0
shift
fi
plisttojson () {
local theparam=""
if [[ "$1" == "-r" ]]; then
theparam="$1"
shift
fi
local sedscript='
/^'$'\t''*<data>/,/^'$'\t''*<\/data>/ {
/^('$'\t''*)<data>(.*)/ { s//\1<string>_data:\2/; h; d; };
/^'$'\t''*<\/data>(.*)/! { s/^'$'\t''+(.*)/\1/; H; d; };
/^'$'\t''*<\/data>(.*)/ { s//:data_<\/string>\1/; H; g; s/\n//g; };
}
'
{
if [[ -n "$1" ]]; then
sed -E "$sedscript" "$1"
else
sed -E "$sedscript"
fi || { echo "# sed failed" 1>&2 ; return 1 ; }
} | { plutil -convert json $theparam - -o - || { echo "# plutil failed" 1>&2 ; return 1 ; } ; }
return 0
}
dumpM1MacTimings () {
local theplist="$1"
if [[ -z "$theplist" ]]; then
theplist="$(mktemp)"
ioreg -alr -k "display-timing-info" > "$theplist"
fi
local st_size=0
eval "$(stat -s "$theplist")"
if ((st_size == 0)); then
echo "# Error: display-timing-info not found" 1>&2
exit 1
fi
plisttojson "$theplist" | { perl -e '
use JSON::PP;
my $ioreg = decode_json (<>);
my $parentname;
sub donode {
my $node = $_[0];
if ($node->{"IOObjectClass"} eq "AppleCLCD2") {
print "\n$parentname:\n";
for my $timingelement (@{$node->{"TimingElements"}}) {
printf(
"%s%dx%d%s@%.3fHz %.3fkHz %.2fMHz h(%d %d %d %s) v(%d %d %d %s) %s%s%s%s%s\n",
((exists $node->{"DPTimingModeId"}) && $timingelement->{"ID"} eq $node->{"DPTimingModeId"}) ? " -> " : " ",
$timingelement->{"HorizontalAttributes"}{"Active"},
$timingelement->{"VerticalAttributes"}{"Active"},
$timingelement->{"IsInterlaced"} ? "i" : "",
$timingelement->{"VerticalAttributes"}{"PreciseSyncRate"} / 65536.0,
$timingelement->{"HorizontalAttributes"}{"PreciseSyncRate"} / 65536.0,
$timingelement->{"HorizontalAttributes"}{"PreciseSyncRate"} * $timingelement->{"HorizontalAttributes"}{"Total"} / 65536000.0,
$timingelement->{"HorizontalAttributes"}{"FrontPorch"},
$timingelement->{"HorizontalAttributes"}{"SyncWidth"},
$timingelement->{"HorizontalAttributes"}{"BackPorch"},
$timingelement->{"HorizontalAttributes"}{"SyncPolarity"} ? "+" : "-",
$timingelement->{"VerticalAttributes"}{"FrontPorch"},
$timingelement->{"VerticalAttributes"}{"SyncWidth"},
$timingelement->{"VerticalAttributes"}{"BackPorch"},
$timingelement->{"VerticalAttributes"}{"SyncPolarity"} ? "+" : "-",
$timingelement->{"IsOverscanned"} ? " (overscan)" : "",
$timingelement->{"IsPreferred"} ? " (preferred)" : "",
$timingelement->{"IsPromoted"} ? " (promoted)" : "",
$timingelement->{"IsSplit"} ? " (tiled)" : "",
$timingelement->{"IsVirtual"} ? " (virtual)" : ""
);
}
}
else
{
$parentname = $node->{"IORegistryEntryName"};
foreach my $childnode (@{$node->{"IORegistryEntryChildren"}}) {
donode($childnode);
}
}
}
foreach my $node (@{$ioreg}) {
donode($node);
}
' \
|| echo "# perl failed" 1>&2 ; }
}
if ((dodump)); then
dumpM1MacTimings "$1"
fi
@joevt
Copy link
Author

joevt commented Jan 1, 2021

Download

curl -L https://gist.github.com/joevt/e862b0088ef58b9144877d01401bcee8/raw -o ~/Downloads/M1MacTimings.sh

Run

# on an M1 Mac, get the ioreg info for the displays:
ioreg -alr -k "display-timing-info" > ioreg_M1.plist

# then use the downloaded script to list the timings:
bash ~/Downloads/M1MacTimings.sh ioreg_M1.plist

# or run the script with no parameters to get the current timings:
bash ~/Downloads/M1MacTimings.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment