#!/bin/zsh emulate -L zsh zmodload zsh/mathfunc setopt errexit errreturn #setopt xtrace find-supported-ratio() { local x=$1 y=$2 default=$3; shift 3 [ $# -gt 0 ] || set -- 16:10 16:9 4:3 5:4 # supported already in edid.S local -A vals=() local r for r in "$@"; do local -i rx=${r%%:*} ry=${r#*:} local v=$(( abs( $x / $rx - $y / $ry ) )) vals[$v]=$r done local best=${vals[0]} [[ -n $best ]] || best=$default echo $best } template-S() { [[ ${(L)1} = mode(|line) ]] || return 1 echo "-- Found modeline: $@" shift 1 local name="${1//\"}" [[ -z "$name" ]] && echo "Could not parse modeline: $@" >&2 && return 1 [[ "${#name}" -gt 12 ]] && echo "Name cannot be longer than 12 characters: $name is ${#name} characters long" >&2 && return 1 local fn="${name}.S" local -F pixel_clock_mhz=$2 local -i pixel_clock_khz=$((pixel_clock_mhz * 1000)) shift 2 local -i hdisp="$1" hsyncstart="$2" hsyncend="$3" htotal="$4"; shift 4 local -i vdisp="$1" vsyncstart="$2" vsyncend="$3" vtotal="$4"; shift 4 local -i hsync_polarity=0 vsync_polarity=0 dpi=96 vfreq_hz=60 local edid_version="1.3" ratio="compute" local arg for arg in "$@"; do case "${(L)arg}" in [-+]hsync) [[ "${arg:0:1}" == "-" ]] || hsync_polarity=1 ;; [-+]vsync) [[ "${arg:0:1}" == "-" ]] || vsync_polarity=1 ;; ratio=*|xy_ratio=*) ratio="${arg#*=}" ;; dpi=*) dpi="${arg#*=}" ;; edid_version=*) edid_version="${arg#*=}" ;; vfreq=*|vfreq_hz=*) vfreq_hz="${arg#*=}" ;; *) echo "Ignoring unknown modeline option passed: '$arg'" >&2 ;; esac done case $ratio in compute) ratio=$(find-supported-ratio $hdisp $vdisp 'UNKNOWN') printf 'Computed ratio: %s\n' $ratio [[ $ratio != 'UNKNOWN' ]] || return 1 ;; esac local -A defines defines=( TIMING_NAME "${(qqq)name}" CLOCK "$pixel_clock_khz" XPIX "$hdisp" XBLANK "$((htotal - hdisp))" XOFFSET "$((hsyncstart - hdisp))" XPULSE "$((hsyncend - hsyncstart))" YPIX "$vdisp" YBLANK "$((vtotal - vdisp))" YOFFSET "(63+$((vsyncstart - vdisp)))" YPULSE "(63+$((vsyncend - vsyncstart)))" VERSION "${edid_version%%.*}" REVISION "${edid_version#*.}" XY_RATIO "XY_RATIO_${(U)ratio//:/_}" DPI "$dpi" VFREQ "$vfreq_hz" HSYNC_POL "$hsync_polarity" VSYNC_POL "$vsync_polarity" ) local -a lines=('/* '"$name: $REPLY"' */') local k for k in ${(k)defines}; do lines+=("#define $k ${defines[$k]}") done lines+=('#include "edid.S"') echo "${(j:\n:)lines[@]}" > "$fn" echo "Wrote $fn" } local f=${1:-'-'} [[ $f != '-' ]] || f="/dev/stdin" if [[ -z "$f" || "$f" == "-h" ]]; then self=${0:t} cat >&2 <<-EOF ${0:t}, version forever 0.0.1 Help: $self -h Parse modelines from stdin: $self $self - Parse modelines from a file (eg xorg.conf) $self FILENAME EOF exit 1 fi echo "Searching for modelines in '$f'" retcode=0 while read; do # trim REPLY=($=REPLY) [[ -n "$REPLY" ]] || continue if ! template-S ${(@)REPLY} ; then retcode=1 fi done < $f exit $retcode