#!/usr/bin/python3
#
# SPDX-License-Identifier: GPL-3.0+
#
# Author: Guido Günther <agx@sigxcpu.org>

import argparse
import ctypes
import struct
import sys
from fcntl import ioctl

FBIOGET_VSCREENINFO = 0x4600


class FbBitField(ctypes.Structure):
    "See /u/i/linux/fb.h"

    _fields_ = [
        ('offset', ctypes.c_uint32),
        ('length', ctypes.c_uint32),
        ('msb_right', ctypes.c_uint32),
    ]


class VarScreenInfo(ctypes.Structure):
    "See /u/i/linux/fb.h"

    _fields_ = [
        ('xres', ctypes.c_uint32),
        ('yres', ctypes.c_uint32),
        ('xres_virtual', ctypes.c_uint32),
        ('yres_virtual', ctypes.c_uint32),
        ('xoffset', ctypes.c_uint32),
        ('yoffset', ctypes.c_uint32),

        ('bits_per_pixel', ctypes.c_uint32),
        ('grayscale', ctypes.c_uint32),

        ('red', FbBitField),
        ('green', FbBitField),
        ('blue', FbBitField),
        ('transp', FbBitField),

        # ...
    ]


def get_screeninfo(fbdev):
    vsi = VarScreenInfo()

    ioctl(fbdev, FBIOGET_VSCREENINFO, vsi)
    return vsi


def int_with_base(x):
    return int(x, 0)


def main(argv):
    parser = argparse.ArgumentParser(description='Check framebuffer but filling the screen with a single color.')
    parser.add_argument('--fbdev', default='/dev/fb0',
                        help='Framebuffer device to use')
    parser.add_argument('--red', default='0xFF', type=int_with_base,
                        help='Red component')
    parser.add_argument('--green', default='0XFF', type=int_with_base,
                        help='Green component')
    parser.add_argument('--blue', default='0XFF', type=int_with_base,
                        help='Blue component')
    args = parser.parse_args()

    alpha = 0xFF
    with open(args.fbdev, 'wb') as f:
        v = get_screeninfo(f)
        print("Framebuuffer Device {0} {1.xres}x{1.yres}, {1.bits_per_pixel}bpp".format(args.fbdev, v))

        len = v.xres * v.yres
        f.write(struct.pack("BBBB", args.blue, args.green, args.red, alpha) * len)


if __name__ == '__main__':
    sys.exit(main(sys.argv))
