/* 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) */

#ifndef __EDID_H__
#define __EDID_H__

#include <glib.h>

G_BEGIN_DECLS

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);
gboolean
display_name_is_laptop_name (const gchar *name);
const gchar *
display_name_get_fallback (const gchar *name);

G_END_DECLS

#endif /* !__EDID_H__ */
