#!/bin/sh
# HFP-123: HDMI Hotplug support

set -u

SYSFS_FB0=/sys/class/graphics/fb0

expand_modestr() {
  # Reformat each mode string and delimit with tabs, as follows:
  #   Input:	D:1920x1080p-60
  #   Output:	1920	1080	60	D:1920x1080p-60	D
  # Width and height are placed first for easy numeric sorting.
  # ModeType (DVSU) is placed last for easy filtering by grep in select_mode
  # Interlaced modes are ignored as we don't support them anyway.
  sed -ne 's/^\([A-Z]\):\([0-9]\+\)x\([0-9]\+\)p-\([0-9]\+\)$/\2\t\3\t\4\t\0\t\1/p'
}

select_mode() {
  # Select the first (i.e. preferred) detailed mode from a list of modes (read from stdin)
    grep "^D:" | head -n 1
}

wait_modelist_change() {
  local prv_mode new_mode prv_modelist new_modelist

  while true; do
    prv_mode=$(cat $SYSFS_FB0/mode)
    prv_modelist=$(cat $SYSFS_FB0/modes)

    # Ideally we'd wait here for an HDMI-plugin event.
    # sysfs and procfs dont support inotify, so the best way is to use udevadm to listen for kernel events.
    # In that case we'd have to read line-by-line, which requires "stdbuf" in the platform - it currently isn't included.
    #	eg: stdbuf -oL udevadm monitor | grep '/devices/mxc_hdmi'
    # For now, just poll for changes in the modelist.
    while true; do
      new_modelist=$(cat $SYSFS_FB0/modes)

      if [ "$prv_modelist" != "$new_modelist" ]; then
	break
      else
	sleep 1
      fi
    done

    [ -x /usr/libexec/hdmi_mode.sh ] && /usr/libexec/hdmi_mode.sh apply
    new_mode=$(cat $SYSFS_FB0/mode)

    echo "New modelist detected (prv_mode=$prv_mode, new_mode=$new_mode):"
    echo "$new_modelist"

    if [ "$new_mode" != "$prv_mode" ]; then

      # Check whether the resolution (only) has changed
      if [ "$(echo "$new_mode" | expand_modestr | cut -f1-2)" \
	!= "$(echo "$prv_mode" | expand_modestr | cut -f1-2)" ]
      then
	echo "Resolution changed"
	break
      fi
    fi
  done >&2
}

wait_modelist_change
exit 0
