/*
 * monitors: a database built from /usr/X11/lib/X11/doc/Monitors
 */
#ifndef _MONITORS_D
#define _MONITORS_D

extern "C" {
#include <stdio.h>
}


#if 0
#define FREE(x)	do { puts("free " ## #x); if (x) free(x); x = 0; } while(0)
#define STRDUP(x) ((char*)puts("strdup " ## #x), (x ? strdup(x) : (char*)0))
#else
#define FREE(x) do { if (x) free(x); x = 0; } while (0)
#define STRDUP(x) (x ? strdup(x) : 0)
#endif


class ModeLine {
public:
    int hsize;		/* horizontal resolution (xsize) */
    int vsize;		/* vertical resolution (ysize) */
    float clock;	/* dot clock */
    char *modedata;	/* framing data (htimings vtimings) */
    int selected;

    int scan(char *header, FILE *f);
    int print(FILE *f);

    inline ModeLine() {     modedata = 0;
			    hsize = vsize = selected = 0;
			    clock = 0.0; }

    inline void is(int x, int y, float clk, char *data) {
			    hsize = x;
			    vsize = y;
			    clock = clk;
			    modedata = STRDUP(data);
			    selected = 0; }

    inline ModeLine(int x, int y, float clk, char *data) { is(x,y,clk,data); }

    inline ~ModeLine() { FREE(modedata); }
};

class Monitor {
private:
    char     *_vendor;			/* VendorName line */
    char     *_model;			/* ModelName line */
    char     *_bandwidth;		/* BandWidth line */
    char     *_hsync;			/* HorizSync line */
    char     *_vref;			/* VertRefresh line */
    int       _hrez, _vrez;		/* if set, fixed resolution */
    int       _custom;			/* can be customised by user */
    int       _autoconfigured;		/* generated by monitor autoconfig */
    int       _nrmodes;
    ModeLine *_modes;			/* graphics modes */
public:

    inline int custom()             {   return _custom; }
    inline int autoconfigured()     {   return _autoconfigured; }
    inline int autoconfigured(int a){   return _autoconfigured = a; }
    inline ModeLine *modes()        {   return _modes; }
    inline int nrmodes()            {   return _nrmodes; }
    inline char *vendor()	    {   return _vendor; }
    inline char *vendor(char *v)    {   FREE(_vendor);
					return _vendor = STRDUP(v); }
    inline char *product()	    {   return _model; }
    inline char *product(char *p)   {   FREE(_model);
					return _model = STRDUP(p); }
    inline char *bandwidth()	    {   return _bandwidth; }
    inline char *bandwidth(char *p) {	FREE(_bandwidth);
					return _bandwidth = STRDUP(p); }
    inline char *hsync()	    {   return _hsync; }
    inline char *hsync(char *p) {	FREE(_hsync);
					return _hsync = STRDUP(p); }
    inline char *vsync()	    {   return _vref; }
    inline char *vsync(char *p) {	FREE(_vref);
					return _vref = STRDUP(p); }

    inline int good(ModeLine& m) {	if (_vrez && _hrez)
					    return (_hrez == m.hsize
						 && _vrez == m.vsize);
					return 1; }
    typedef void (messagefunc)(char*fmt, ...);
    static int parse_database(messagefunc);
    int scan(FILE *f);
    int print(FILE *f);

    inline void Erase(){_vendor = _model = _bandwidth = _hsync = _vref = 0;
			_custom = _nrmodes = 0;
			_modes = 0; }

    inline Monitor()  { Erase(); _autoconfigured = 0; }
    inline Monitor(char *vendor, char *model) {
			Erase();
			_vendor = STRDUP(vendor);
			_model = STRDUP(model); }
    inline is(Monitor &rhs) {
			_vendor = rhs._vendor;
			_model  = rhs._model;
			_bandwidth = rhs._bandwidth;
			_hsync = rhs._hsync;
			_vref = rhs._vref;
			_custom = rhs._custom;
			_autoconfigured = rhs._autoconfigured;
			_nrmodes = rhs._nrmodes;
			_modes = rhs._modes;
			rhs.Erase(); }
    inline ~Monitor() { FREE(_vendor);
			FREE(_model);
			FREE(_bandwidth);
			FREE(_hsync);
			FREE(_vref);
			FREE(_modes); }
} ;

#ifndef MONITOR_FILE
#define MONITOR_FILE "/usr/X11R6/lib/X11/doc/Monitors"
#endif/*MONITOR_FILE*/

extern int get_monitordb();

extern struct Monitor *monitor;
extern int nr_monitor;

#endif/*_MONITORS_D*/
