/*
    gvidm - X11 video mode changer with a minimal interface
    Copyright (C) 2001-2004 Matthew Mueller <donut AT dakotacom DOT net>
    based on gvid:
    Copyright (C) 1999-2001 Keith Vanderline <kvand@mit.edu>

    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"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif



Handler *handler;
Display *display;


int get_screen_count(void) {
#ifdef HAVE_LIBXINERAMA
	if (XineramaIsActive(display))
	{
		int screen_exists[1024], i;
		XineramaScreenInfo *screen = XineramaQueryScreens(display, screen_exists);
		for (i=0; i==screen[i].screen_number; i++){}
		XFree(screen);
		return i;
	}
	else
	{
#endif
		return XScreenCount(display);
#ifdef HAVE_LIBXINERAMA
	}
#endif
}

int get_current_screen(void) {
	return DefaultScreen(display);
}

void MenuEvent (GtkWidget *widget, gpointer data)
{
	handler->doevent(data);
}

void on_deactivate(void) {
	gtk_main_quit();
}

GtkWidget *create_root_menu() {
	GtkWidget *menu_ptr = gtk_menu_new();
	gtk_signal_connect (GTK_OBJECT (menu_ptr), "deactivate", GTK_SIGNAL_FUNC (on_deactivate), NULL);
	return menu_ptr;
}

GtkWidget *create_menuitem_with_accel(const char *label_str, GtkWidget *menu_ptr) {
#if GTK_MAJOR_VERSION<2
	GtkWidget *menuitem_ptr = gtk_menu_item_new_with_label("");
	guint tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem_ptr)->child), label_str);
	if (tmp_key!=GDK_VoidSymbol) {
		GtkAccelGroup *menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (menu_ptr));
		gtk_widget_add_accelerator (menuitem_ptr, "activate_item", menu_accels, tmp_key, 0, (GtkAccelFlags)0);
	}
	return menuitem_ptr;
#else
	return gtk_menu_item_new_with_mnemonic(label_str);
#endif
}

void add_menuitem_with_accel(const char *label_str, void *data, GtkWidget *menu_ptr) {
	GtkWidget *menuitem_ptr = create_menuitem_with_accel(label_str, menu_ptr);
	gtk_signal_connect(GTK_OBJECT (menuitem_ptr), "activate", GTK_SIGNAL_FUNC (MenuEvent), data);
	gtk_menu_append(GTK_MENU (menu_ptr), menuitem_ptr);
	gtk_widget_show(menuitem_ptr);
#if GTK_MAJOR_VERSION<2
	gtk_widget_lock_accelerators(menuitem_ptr);
#endif
}



void show_help_and_exit(int code) {
	printf("gvidm "M_VERSION" (C) 2001-2004 Matthew Mueller <donut@dakotacom.net>\n"
			"based on gvid "VERSION" (C) 1999-2001 Keith Vanderline <kvand@mit.edu>\n"
			"Distributed under the terms of the GPL\n");
	printf("USAGE: gvidm [modes...]\n"
			"  -h/--help   show this info\n"
			"  -q/--query  print current resolutions\n"
			"  -l/--list   print list of available resolutions\n"
			"  -r/--resize change root window size\n"
			"\n"
			" Modes are specified as [screen:]<resolution>\n"
			"   screen may be a number or the keyword \"cur\" or \"all\".\n"
			"   resolution may be <width>x<height>[@hz] or the keyword \"max\", \"best\" or \"all\"\n"
			" If no modes are specified, a menu of all available resolutions is shown.\n"
			" If one mode(per screen) is specified, it is switched to immediatly.\n"
			" If multiple modes are specified, a menu with only those modes is shown.\n"
	);
	exit(code);
}

int main(int argc,char **argv)
{
#ifdef HAVE_GETOPT_LONG
	static struct option long_options[] = {
		{"help", 0, 0, 'h'},
		{"list", 0, 0, 'l'},
		{"query", 0, 0, 'q'},
		{"resize", 0, 0, 'r'},
		{0, 0, 0 ,0}
	};
#else
#define getopt_long(argc,argv,shopt,lopt,lidx) getopt(argc,argv,shopt)
#endif
	int c;
	enum {
		ACTION_SET,
		ACTION_LIST,
		ACTION_LIST_CURRENT,
	} action = ACTION_SET;
	enum {
		MODE_VIDMODE,
		MODE_RESIZE,
	} mode = MODE_VIDMODE;

	if ((display=XOpenDisplay(""))==NULL) {
		fprintf(stderr, "gvidm: Error opening display\n");
		exit(1);
	}

	gtk_init (&argc, &argv);
	while (-1 != (c=getopt_long(argc, argv, "hlqr", long_options, NULL))) {
		switch (c) {
			case ':':
			case '?':
				show_help_and_exit(1);
				break;
			case 'l':
				action = ACTION_LIST;
				break;
			case 'q':
				action = ACTION_LIST_CURRENT;
				break;
			case 'r':
				mode = MODE_RESIZE;
				break;
			case 'h':
				show_help_and_exit(0);
				break;
			default:
				assert(0);
		}
	}

	switch (mode) {
		case MODE_VIDMODE:
#ifdef HAVE_LIBXXF86VM
			handler = new XVidModeHandler();
#else
			fprintf(stderr, "gvidm: XVidMode support not compiled in\n");
			exit(1);
#endif
			break;
		case MODE_RESIZE:
#ifdef HAVE_LIBXRANDR
			handler = new XRandRHandler();
#else
			fprintf(stderr, "gvidm: XRandR support not compiled in\n");
			exit(1);
#endif
			break;
	}

	int errs=0;
	char **argbegin=argv+optind, **argend=argv+argc;

	if (action==ACTION_LIST)
		errs += handler->list(argbegin, argend);
	else if (action==ACTION_LIST_CURRENT)
		errs += handler->list_current(argbegin, argend);
	else if (action==ACTION_SET)
		errs += handler->set(argbegin, argend);
	else
		assert(0);

	return errs?1:0;
}
