/*
    xrandr support module for gvidm
    Copyright (C) 2004 Matthew Mueller <donut AT dakotacom DOT net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "gvid.h"
#include "vidmode.h"
#include "_types.h"

#ifdef HAVE_LIBXRANDR

static int check_XRR_supported(void) {
	int major,minor;
	return !XRRQueryVersion(display, &major, &minor);
}

XRandRHandler::XRandRHandler() {
	if (check_XRR_supported()) {
		fprintf(stderr, "gvidm: XRandR extension not supported\n");
		exit(1);
	}

	num_screens=get_screen_count();
	screenconfigs = new XRRScreenConfiguration*[num_screens];
	for (int screen=0; screen<num_screens; ++screen) {
		available_modes.push_back(mode_list_t());
		mode_list_t &smodes = available_modes.back();

		Window        root;
		XRRScreenConfiguration *sc;
		int           nsize;
		XRRScreenSize *sizes;
		int           nrate;
		short         *rates;
		SizeID        current_size;
		Rotation      current_rotation;
		short         current_rate;

		root = RootWindow(display, screen);

		sc = XRRGetScreenInfo(display, root);
		screenconfigs[screen]=sc;

		if (sc == NULL)
			continue;
		
		current_size = XRRConfigCurrentConfiguration(sc, &current_rotation);
		current_rate = XRRConfigCurrentRate(sc);

		sizes = XRRConfigSizes(sc, &nsize);

		for (int i = 0; i < nsize; ++i) {
			rates = XRRConfigRates (sc, i, &nrate);
			for (int j = 0; j < nrate; ++j) {
				smodes.push_back(new VidMode(i==current_size && rates[j]==current_rate,
							sizes[i].width, sizes[i].height, rates[j], "",
							(void*)(uintptr_t)((screen<<23)+(i<<11)+rates[j])));
			}
		}

	}

}

XRandRHandler::~XRandRHandler() {
	for (int screen=0; screen<num_screens; ++screen)
		XRRFreeScreenConfigInfo(screenconfigs[screen]);
	delete [] screenconfigs;
}

int XRandRHandler::doevent(gpointer data) {
	SizeID mode=(((uintptr_t)data)>>11)&(0x1000-1);
	int rate=((uintptr_t)data)&(0x800-1);
	int screen=((uintptr_t)data)>>23;
	assert(screen<num_screens);

	Rotation current_rotation;
	XRRConfigCurrentConfiguration(screenconfigs[screen], &current_rotation);

	XRRSetScreenConfigAndRate (display, screenconfigs[screen],
			RootWindow(display, screen), 
			mode, current_rotation, rate, CurrentTime);
	return 1;
}

#endif
