/*
 * +-------------------------------------------------------+
 * |                                                       |
 * |     videogen                                          |
 * |                                                       |
 * |     a simple XFree86 Modeline calculator              |
 * |     (c) 1997-2002, Szabolcs Rumi                      |   
 * |                                                       |
 * |     http://www.rtfm.hu/videogen                       |
 * |                                                       |
 * |     the videogen package is distributed under the     |
 * |     GNU General Public License Version 2 (GPLv2)      |
 * |                                                       |
 * +-------------------------------------------------------+   
 */





#include <stdio.h>
#include <string.h>

#include "config.h"
#include "videogen.h"





/*
 * parameter checking functions return values:
 *
 * commit success	retval = 0
 * precedence error	retval = -1
 * overflow error	retval > 0
 * underflow error	retval < 0
 */





int
commit_verbose (int precedence, unsigned int *verbose, unsigned int x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (precedence < current_precedence)
		return (-1);

	*verbose = x;
	current_precedence = precedence;
	return (0);
}





int
commit_fbset (int precedence, unsigned int *fbset, unsigned int x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (precedence < current_precedence)
		return (-1);

	*fbset = x;
	current_precedence = precedence;
	return (0);
}





int
commit_nvidia (int precedence, unsigned int *nvidia, unsigned int x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (precedence < current_precedence)
		return (-1);

	*nvidia = x;
	current_precedence = precedence;
	return (0);
}





int
commit_mode (int precedence, resolution_t (*modes)[], unsigned int *num_modes, unsigned int x, unsigned int y)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_WIDTH_MIN)
		return (-2);

	if (x > CFG_WIDTH_MAX)
		return (2);

	if (y < CFG_HEIGHT_MIN)
		return (-3);

	if (y > CFG_HEIGHT_MAX)
		return (3);

	if ((double)y / x < CFG_ASPECT_RATIO_MIN)
		return (-4);

	if ((double)y / x > CFG_ASPECT_RATIO_MAX)
		return (4);
	
	if ((unsigned int)(x / 8) * 8 != x)
		return (6);

	if (precedence < current_precedence)
		return (-1);

	if (precedence > current_precedence)
		*num_modes = 0;

	if (*num_modes > 255)
		return (5);

	(*modes)[*num_modes].hres = x;
	(*modes)[*num_modes].vres = y;
	(*num_modes)++;
	current_precedence = precedence;
	return (0);
}





int
commit_max_dotclk (int precedence, double *max_dotclk, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_MAX_DOTCLK_MIN)
		return (-2);

	if (x > CFG_MAX_DOTCLK_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*max_dotclk = x;
	current_precedence = precedence;
	return (0);
}





int
commit_max_hfreq (int precedence, double *max_hfreq, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_MAX_HFREQ_MIN)
		return (-2);

	if (x > CFG_MAX_HFREQ_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*max_hfreq = x;
	current_precedence = precedence;
	return (0);
}





int
commit_max_vfreq (int precedence, double *max_vfreq, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_MAX_VFREQ_MIN)
		return (-2);

	if (x > CFG_MAX_VFREQ_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*max_vfreq = x;
	current_precedence = precedence;
	return (0);
}





int
commit_desired_vfreq (int precedence, double *desired_vfreq, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_TARGET_VFREQ_MIN)
		return (-2);

	if (x > CFG_TARGET_VFREQ_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*desired_vfreq = x;
	current_precedence = precedence;
	return (0);
}





int
commit_hvisible (int precedence, double *hvisible, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_HORIZ_VISIBLE_MIN)
		return (-2);

	if (x > CFG_HORIZ_VISIBLE_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*hvisible = x;
	current_precedence = precedence;
	return (0);
}





int
commit_vvisible (int precedence, double *vvisible, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_VERT_VISIBLE_MIN)
		return (-2);

	if (x > CFG_VERT_VISIBLE_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*vvisible = x;
	current_precedence = precedence;
	return (0);
}





int
commit_hfporch (int precedence, double *hfporch, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_HORIZ_FRONT_PORCH_MIN)
		return (-2);

	if (x > CFG_HORIZ_FRONT_PORCH_MAX)
		return (2);

	if ((unsigned int)(x / 8) * 8 != x)
		return (3);

	if (precedence < current_precedence)
		return (-1);

	*hfporch = x;
	current_precedence = precedence;
	return (0);
}





int
commit_hbporch (int precedence, double *hbporch, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_HORIZ_BACK_PORCH_MIN)
		return (-2);

	if (x > CFG_HORIZ_BACK_PORCH_MAX)
		return (2);

	if ((unsigned int)(x / 8) * 8 != x)
		return (3);

	if (precedence < current_precedence)
		return (-1);

	*hbporch = x;
	current_precedence = precedence;
	return (0);
}





int
commit_hsync (int precedence, double *hsync, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_HORIZ_SYNC_PULSE_MIN)
		return (-2);

	if (x > CFG_HORIZ_SYNC_PULSE_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*hsync = x;
	current_precedence = precedence;
	return (0);
}





int
commit_vfporch (int precedence, double *vfporch, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_VERT_FRONT_PORCH_MIN)
		return (-2);

	if (x > CFG_VERT_FRONT_PORCH_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*vfporch = x;
	current_precedence = precedence;
	return (0);
}





int
commit_vbporch (int precedence, double *vbporch, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_VERT_BACK_PORCH_MIN)
		return (-2);

	if (x > CFG_VERT_BACK_PORCH_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*vbporch = x;
	current_precedence = precedence;
	return (0);
}




int
commit_vsync (int precedence, double *vsync, double x)
{
	static int current_precedence = CFG_PREC_DEFAULT;



	if (x < CFG_VERT_SYNC_PULSE_MIN)
		return (-2);

	if (x > CFG_VERT_SYNC_PULSE_MAX)
		return (2);

	if (precedence < current_precedence)
		return (-1);

	*vsync = x;
	current_precedence = precedence;
	return (0);
}





/* EOF */
