Skip to content

Instantly share code, notes, and snippets.

@istefy
Forked from adaugherity/patch-edid.rb
Created December 23, 2021 14:00
Show Gist options
  • Save istefy/90fb6ab9d1e06ebaad26603c57e116e2 to your computer and use it in GitHub Desktop.
Save istefy/90fb6ab9d1e06ebaad26603c57e116e2 to your computer and use it in GitHub Desktop.

Revisions

  1. @adaugherity adaugherity revised this gist Jan 2, 2021. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions patch-edid.rb
    Original file line number Diff line number Diff line change
    @@ -22,6 +22,8 @@
    puts "is giving you problems.","\n"
    elsif displays.length == 0
    puts "No display data found! Are any external displays connected?"
    puts "\nNote: Apple Silicon (arm64) devices are currently unsupported, as the standard"
    puts "method of retrieving display information does not work."
    end
    displays.each do |disp|
    # Retrieve monitor model from EDID display descriptor
  2. @adaugherity adaugherity revised this gist Oct 15, 2019. 1 changed file with 35 additions and 24 deletions.
    59 changes: 35 additions & 24 deletions patch-edid.rb
    100644 → 100755
    Original file line number Diff line number Diff line change
    @@ -20,37 +20,48 @@
    if displays.length > 1
    puts "Found %d displays! You should only install the override file for the one which" % displays.length
    puts "is giving you problems.","\n"
    elsif displays.length == 0
    puts "No display data found! Are any external displays connected?"
    end
    displays.each do |disp|
    # Retrieve monitor model from EDID data
    monitor_name=[disp["edid_hex"].match(/000000fc00(.*?)0a/){|m|m[1]}.to_s].pack("H*")
    if monitor_name.empty?
    monitor_name = "Display"
    end
    # Retrieve monitor model from EDID display descriptor
    i = disp["edid_hex"].index('000000fc00')
    if i.nil?
    monitor_name = "Display"
    else
    # The monitor name is stored in (up to) 13 bytes of text following 00 00 00 fc 00.
    # If the name is shorter than 13 bytes, it is terminated with a newline (0a) and then padded with spaces.
    monitor_name = [disp["edid_hex"][i + 10, 26].to_s].pack("H*")
    monitor_name.rstrip! # remove trailing newline/spaces
    end

    puts "found display '#{monitor_name}': vendorid #{disp["vendorid"]}, productid #{disp["productid"]}, EDID:\n#{disp["edid_hex"]}"
    puts "Found display '#{monitor_name}': vendor ID=#{disp["vendorid"]} (0x%x), product ID=#{disp["productid"]} (0x%x)" %
    [disp["vendorid"], disp["productid"]]
    puts "Raw EDID data:\n#{disp["edid_hex"]}"

    bytes=disp["edid_hex"].scan(/../).map{|x|Integer("0x#{x}")}.flatten
    bytes=disp["edid_hex"].scan(/../).map{|x|Integer("0x#{x}")}.flatten

    puts "Setting color support to RGB 4:4:4 only"
    bytes[24] &= ~(0b11000)
    puts "Setting color support to RGB 4:4:4 only"
    bytes[24] &= ~(0b11000)

    puts "Number of extension blocks: #{bytes[126]}"
    puts "removing extension block"
    bytes = bytes[0..127]
    bytes[126] = 0
    puts "Number of extension blocks: #{bytes[126]}"
    puts "removing extension block"
    bytes = bytes[0..127]
    bytes[126] = 0

    bytes[127] = (0x100-(bytes[0..126].reduce(:+) % 256)) % 256
    puts
    puts "Recalculated checksum: 0x%x" % bytes[127]
    puts "new EDID:\n#{bytes.map{|b|"%02X"%b}.join}"
    bytes[127] = (0x100-(bytes[0..126].reduce(:+) % 256)) % 256
    puts
    puts "Recalculated checksum: 0x%x" % bytes[127]
    puts "new EDID:\n#{bytes.map{|b|"%02X"%b}.join}"

    Dir.mkdir("DisplayVendorID-%x" % disp["vendorid"]) rescue nil
    f = File.open("DisplayVendorID-%x/DisplayProductID-%x" % [disp["vendorid"], disp["productid"]], 'w')
    f.write '<?xml version="1.0" encoding="UTF-8"?>
    Dir.mkdir("DisplayVendorID-%x" % disp["vendorid"]) rescue nil
    filename = "DisplayVendorID-%x/DisplayProductID-%x" % [disp["vendorid"], disp["productid"]]
    puts "Output file: #{Dir.pwd}/#{filename}"
    f = File.open(filename, 'w')
    f.write '<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">'
    f.write "
    f.write "
    <dict>
    <key>DisplayProductName</key>
    <string>#{monitor_name} - forced RGB mode (EDID override)</string>
    @@ -62,6 +73,6 @@
    <integer>#{disp["productid"]}</integer>
    </dict>
    </plist>"
    f.close
    puts "\n"
    end # displays.each
    f.close
    puts "\n"
    end # displays.each
  3. @adaugherity adaugherity revised this gist Feb 25, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion patch-edid.rb
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@
    end
    displays.each do |disp|
    # Retrieve monitor model from EDID data
    monitor_name=[disp["edid_hex"].match(/000000fc00(.*?)0a/){|m|m[1]}].pack("H*")
    monitor_name=[disp["edid_hex"].match(/000000fc00(.*?)0a/){|m|m[1]}.to_s].pack("H*")
    if monitor_name.empty?
    monitor_name = "Display"
    end
  4. @adaugherity adaugherity revised this gist Nov 12, 2013. 1 changed file with 25 additions and 10 deletions.
    35 changes: 25 additions & 10 deletions patch-edid.rb
    Original file line number Diff line number Diff line change
    @@ -6,18 +6,31 @@

    data=`ioreg -l -d0 -w 0 -r -c AppleDisplay`

    edid_hex=data.match(/IODisplayEDID.*?<([a-z0-9]+)>/i)[1]
    vendorid=data.match(/DisplayVendorID.*?([0-9]+)/i)[1].to_i
    productid=data.match(/DisplayProductID.*?([0-9]+)/i)[1].to_i
    edids=data.scan(/IODisplayEDID.*?<([a-z0-9]+)>/i).flatten
    vendorids=data.scan(/DisplayVendorID.*?([0-9]+)/i).flatten
    productids=data.scan(/DisplayProductID.*?([0-9]+)/i).flatten

    displays = []
    edids.each_with_index do |edid, i|
    disp = { "edid_hex"=>edid, "vendorid"=>vendorids[i].to_i, "productid"=>productids[i].to_i }
    displays.push(disp)
    end

    # Process all displays
    if displays.length > 1
    puts "Found %d displays! You should only install the override file for the one which" % displays.length
    puts "is giving you problems.","\n"
    end
    displays.each do |disp|
    # Retrieve monitor model from EDID data
    monitor_name=[edid_hex.match(/000000fc00(.*?)0a/){|m|m[1]}].pack("H*")
    monitor_name=[disp["edid_hex"].match(/000000fc00(.*?)0a/){|m|m[1]}].pack("H*")
    if monitor_name.empty?
    monitor_name = "Display"
    end

    puts "found display '#{monitor_name}': vendorid #{vendorid}, productid #{productid}, EDID:\n#{edid_hex}"
    puts "found display '#{monitor_name}': vendorid #{disp["vendorid"]}, productid #{disp["productid"]}, EDID:\n#{disp["edid_hex"]}"

    bytes=edid_hex.scan(/../).map{|x|Integer("0x#{x}")}.flatten
    bytes=disp["edid_hex"].scan(/../).map{|x|Integer("0x#{x}")}.flatten

    puts "Setting color support to RGB 4:4:4 only"
    bytes[24] &= ~(0b11000)
    @@ -32,8 +45,8 @@
    puts "Recalculated checksum: 0x%x" % bytes[127]
    puts "new EDID:\n#{bytes.map{|b|"%02X"%b}.join}"

    Dir.mkdir("DisplayVendorID-%x" % vendorid) rescue nil
    f = File.open("DisplayVendorID-%x/DisplayProductID-%x" % [vendorid, productid], 'w')
    Dir.mkdir("DisplayVendorID-%x" % disp["vendorid"]) rescue nil
    f = File.open("DisplayVendorID-%x/DisplayProductID-%x" % [disp["vendorid"], disp["productid"]], 'w')
    f.write '<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">'
    @@ -44,9 +57,11 @@
    <key>IODisplayEDID</key>
    <data>#{Base64.encode64(bytes.pack('C*'))}</data>
    <key>DisplayVendorID</key>
    <integer>#{vendorid}</integer>
    <integer>#{disp["vendorid"]}</integer>
    <key>DisplayProductID</key>
    <integer>#{productid}</integer>
    <integer>#{disp["productid"]}</integer>
    </dict>
    </plist>"
    f.close
    puts "\n"
    end # displays.each
  5. @adaugherity adaugherity revised this gist Nov 12, 2013. 1 changed file with 9 additions and 4 deletions.
    13 changes: 9 additions & 4 deletions patch-edid.rb
    Original file line number Diff line number Diff line change
    @@ -6,11 +6,16 @@

    data=`ioreg -l -d0 -w 0 -r -c AppleDisplay`

    puts edid_hex=data.match(/IODisplayEDID.*?<([a-z0-9]+)>/i)[1]
    edid_hex=data.match(/IODisplayEDID.*?<([a-z0-9]+)>/i)[1]
    vendorid=data.match(/DisplayVendorID.*?([0-9]+)/i)[1].to_i
    productid=data.match(/DisplayProductID.*?([0-9]+)/i)[1].to_i
    # Retrieve monitor model from EDID data
    monitor_name=[edid_hex.match(/000000fc00(.*?)0a/){|m|m[1]}].pack("H*")
    if monitor_name.empty?
    monitor_name = "Display"
    end

    puts "found display: vendorid #{vendorid}, productid #{productid}, EDID:\n#{edid_hex}"
    puts "found display '#{monitor_name}': vendorid #{vendorid}, productid #{productid}, EDID:\n#{edid_hex}"

    bytes=edid_hex.scan(/../).map{|x|Integer("0x#{x}")}.flatten

    @@ -35,7 +40,7 @@
    f.write "
    <dict>
    <key>DisplayProductName</key>
    <string>Display with forced RGB mode (EDID override)</string>
    <string>#{monitor_name} - forced RGB mode (EDID override)</string>
    <key>IODisplayEDID</key>
    <data>#{Base64.encode64(bytes.pack('C*'))}</data>
    <key>DisplayVendorID</key>
    @@ -44,4 +49,4 @@
    <integer>#{productid}</integer>
    </dict>
    </plist>"
    f.close
    f.close
  6. @BugRoger BugRoger created this gist May 5, 2013.
    47 changes: 47 additions & 0 deletions patch-edid.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    #!/usr/bin/ruby
    # Create display override file to force Mac OS X to use RGB mode for Display
    # see http://embdev.net/topic/284710

    require 'base64'

    data=`ioreg -l -d0 -w 0 -r -c AppleDisplay`

    puts edid_hex=data.match(/IODisplayEDID.*?<([a-z0-9]+)>/i)[1]
    vendorid=data.match(/DisplayVendorID.*?([0-9]+)/i)[1].to_i
    productid=data.match(/DisplayProductID.*?([0-9]+)/i)[1].to_i

    puts "found display: vendorid #{vendorid}, productid #{productid}, EDID:\n#{edid_hex}"

    bytes=edid_hex.scan(/../).map{|x|Integer("0x#{x}")}.flatten

    puts "Setting color support to RGB 4:4:4 only"
    bytes[24] &= ~(0b11000)

    puts "Number of extension blocks: #{bytes[126]}"
    puts "removing extension block"
    bytes = bytes[0..127]
    bytes[126] = 0

    bytes[127] = (0x100-(bytes[0..126].reduce(:+) % 256)) % 256
    puts
    puts "Recalculated checksum: 0x%x" % bytes[127]
    puts "new EDID:\n#{bytes.map{|b|"%02X"%b}.join}"

    Dir.mkdir("DisplayVendorID-%x" % vendorid) rescue nil
    f = File.open("DisplayVendorID-%x/DisplayProductID-%x" % [vendorid, productid], 'w')
    f.write '<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">'
    f.write "
    <dict>
    <key>DisplayProductName</key>
    <string>Display with forced RGB mode (EDID override)</string>
    <key>IODisplayEDID</key>
    <data>#{Base64.encode64(bytes.pack('C*'))}</data>
    <key>DisplayVendorID</key>
    <integer>#{vendorid}</integer>
    <key>DisplayProductID</key>
    <integer>#{productid}</integer>
    </dict>
    </plist>"
    f.close