#!/usr/bin/env python3

# Copyright (C) 2016 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

import os
import sys
import re

if len(sys.argv) != 2:
  print("Usage: %s [output file]"%sys.argv[0])
  exit(1)

common_resolutions = [
    # 4:3
    (800, 600),
    (1024, 768),
    (1152, 864),
    (1280, 960),
    (1400, 1050),
    (1440, 1080),
    (1600, 1200),
    (1920, 1440),
    (2048, 1536),
    # 16:10
    (1280, 800),
    (1440, 900),
    (1680, 1050),
    (1920, 1200),
    (2560, 1600),
    # 16:9
    (1280, 720),
    (1366, 768),
    (1600, 900),
    (1920, 1080),
    (2048, 1152),
    (2560, 1440),
    (2880, 1620),
    (3200, 1800),
    (3840, 2160),
    (4096, 2304),
    (5120, 2880),
]

common_refresh_rates = [
    60,
    90,
    120,
    144,
    165,
    240,
]

output_lines = [
    "/* Generated by gen-default-modes.py */\n",
    "static const drmModeModeInfo meta_default_landscape_drm_mode_infos[] = {",
]

def sync_flags(hsync, vsync):
    flags = "DRM_MODE_FLAG_"
    flags += "NHSYNC" if hsync[0] == '-' else "PHSYNC"
    flags += " | DRM_MODE_FLAG_"
    flags += "NVSYNC" if vsync[0] == '-' else "PVSYNC"
    return flags

def drm_mode_info_from_modeline(line):
    sline = line.split()
    return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, %s }," % \
        (int(float(sline[2]) * 1000),
         int(sline[3]),
         int(sline[4]),
         int(sline[5]),
         int(sline[6]),
         int(sline[7]),
         int(sline[8]),
         int(sline[9]),
         int(sline[10]),
         sync_flags(sline[11], sline[12]),
         sline[1])

def portrait_drm_mode_info_from_modeline(line):
    sline = line.split()
    return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, \"%dx%d%s\" }," % \
        (int(float(sline[2]) * 1000),
         int(sline[7]),
         int(sline[8]),
         int(sline[9]),
         int(sline[10]),
         int(sline[3]),
         int(sline[4]),
         int(sline[5]),
         int(sline[6]),
         sync_flags(sline[12], sline[11]),
         int(sline[7]), int(sline[3]), re.match(r'^"[0-9]+x[0-9]+(.*)"$', sline[1]).group(1))

for resolution in common_resolutions:
    for refresh_rate in common_refresh_rates:
        cvt = os.popen("%s %s %s %s" % ('cvt', resolution[0], resolution[1], refresh_rate))
        cvt.readline() # discard comment line
        line = cvt.readline()
        cvt.close()

        if refresh_rate % 60 == 0:
            cvt_rb = os.popen("%s %s %s %s %s" % ('cvt', '-r', resolution[0], resolution[1], refresh_rate))
            cvt_rb.readline() # discard comment line
            line_rb = cvt_rb.readline()
            output_lines.append(drm_mode_info_from_modeline(line_rb))
            cvt_rb.close()

        output_lines.append(drm_mode_info_from_modeline(line))

output_lines.append("};")

output_lines.append("")
output_lines.append("static const drmModeModeInfo meta_default_portrait_drm_mode_infos[] = {")
for resolution in common_resolutions:
    for refresh_rate in common_refresh_rates:
        cvt = os.popen("%s %s %s %s" % ('cvt', resolution[0], resolution[1], refresh_rate))
        cvt.readline() # discard comment line
        line = cvt.readline()
        cvt.close()

        if refresh_rate % 60 == 0:
            cvt_rb = os.popen("%s %s %s %s %s" % ('cvt', '-r', resolution[0], resolution[1], refresh_rate))
            cvt_rb.readline() # discard comment line
            line_rb = cvt_rb.readline()
            output_lines.append(portrait_drm_mode_info_from_modeline(line_rb))
            cvt_rb.close()

        output_lines.append(portrait_drm_mode_info_from_modeline(line))

output_lines.append("};")

try:
  output_file = open(sys.argv[1], 'w')

  for line in output_lines:
      output_file.write(line + "\n")
  output_file.flush()
  output_file.close()
except:
  print("Failed to generate modelines:", sys.exc_info()[0])
  exit(1)
