/* edid.h
 *
 * Copyright 2007, 2008, Red Hat, Inc.
 *
 * This file is part of the Gnome Library.
 *
 * The Gnome Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * The Gnome Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with the Gnome Library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Author: Soren Sandmann <sandmann@redhat.com>
 */

/* Downloaded from <http://git.gnome.org/browse/gnome-desktop/tree/libgnome-desktop>
   (git commit 42452cada8cf1c4d7a81aded0a3ddbb5e97441de) */

#include <glib.h>

#ifndef EDID_H
#define EDID_H

typedef unsigned char uchar;
typedef struct MonitorInfo MonitorInfo;
typedef struct Timing Timing;
typedef struct DetailedTiming DetailedTiming;

typedef enum
{
    UNDEFINED,
    DVI,
    HDMI_A,
    HDMI_B,
    MDDI,
    DISPLAY_PORT
} Interface;

typedef enum
{
    UNDEFINED_COLOR,
    MONOCHROME,
    RGB,
    OTHER_COLOR
} ColorType;

typedef enum
{
    NO_STEREO,
    FIELD_RIGHT,
    FIELD_LEFT,
    TWO_WAY_RIGHT_ON_EVEN,
    TWO_WAY_LEFT_ON_EVEN,
    FOUR_WAY_INTERLEAVED,
    SIDE_BY_SIDE
} StereoType;

struct Timing
{
    int width;
    int height;
    int frequency;
};

struct DetailedTiming
{
    int         pixel_clock;
    int         h_addr;
    int         h_blank;
    int         h_sync;
    int         h_front_porch;
    int         v_addr;
    int         v_blank;
    int         v_sync;
    int         v_front_porch;
    int         width_mm;
    int         height_mm;
    int         right_border;
    int         top_border;
    int         interlaced;
    StereoType  stereo;

    int         digital_sync;
    union
    {
        struct
        {
            int bipolar;
            int serrations;
            int sync_on_green;
        } analog;

        struct
        {
            int composite;
            int serrations;
            int negative_vsync;
            int negative_hsync;
        } digital;
    } connector;
};

struct MonitorInfo
{
    int         checksum;
    char        manufacturer_code[4];
    int         product_code;
    unsigned int    serial_number;

    int         production_week;    /* -1 if not specified */
    int         production_year;    /* -1 if not specified */
    int         model_year;         /* -1 if not specified */

    int         major_version;
    int         minor_version;

    int         is_digital;

    union
    {
        struct
        {
            int     bits_per_primary;
            Interface   interface;
            int     rgb444;
            int     ycrcb444;
            int     ycrcb422;
        } digital;

        struct
        {
            double  video_signal_level;
            double  sync_signal_level;
            double  total_signal_level;

            int     blank_to_black;

            int     separate_hv_sync;
            int     composite_sync_on_h;
            int     composite_sync_on_green;
            int     serration_on_vsync;
            ColorType   color_type;
        } analog;
    } connector;

    int         width_mm;       /* -1 if not specified */
    int         height_mm;      /* -1 if not specified */
    double      aspect_ratio;   /* -1.0 if not specififed */

    double      gamma;          /* -1.0 if not specified */

    int         standby;
    int         suspend;
    int         active_off;

    int         srgb_is_standard;
    int         preferred_timing_includes_native;
    int         continuous_frequency;

    double      red_x;
    double      red_y;
    double      green_x;
    double      green_y;
    double      blue_x;
    double      blue_y;
    double      white_x;
    double      white_y;

    Timing      established[24];    /* Terminated by 0x0x0 */
    Timing      standard[8];

    int         n_detailed_timings;
    DetailedTiming  detailed_timings[4];    /* If monitor has a preferred
                                             * mode, it is the first one
                                             * (whether it has, is
                                             * determined by the
                                             * preferred_timing_includes
                                             * bit.
                                             */

    /* Optional product description */
    char        dsc_serial_number[14];
    char        dsc_product_name[14];
    char        dsc_string[14];     /* Unspecified ASCII data */
};

MonitorInfo *decode_edid (const uchar *data);
char *make_display_name (const MonitorInfo *info, guint output);

#endif
