
/*
 * Copyright (C) 2007 - Mateus Cesar Groess
 *
 * 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 <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <rfb/rfbclient.h>

#ifdef LIBVNCSERVER_CONFIG_LIBVA
#include <gdk/gdkx.h>
#endif

static rfbClient *cl;
static gchar *server_cut_text = NULL;
static gboolean framebuffer_allocated = FALSE;
static GtkWidget *window;
static GtkWidget *dialog_connecting = NULL;

/* Redraw the screen from the backing pixmap */
static gboolean expose_event (GtkWidget      *widget,
                              GdkEventExpose *event)
{
	static GdkImage *image = NULL;

	if (framebuffer_allocated == FALSE) {

		rfbClientSetClientData (cl, gtk_init, widget);

		image = gdk_drawable_get_image (widget->window, 0, 0,
		                                widget->allocation.width,
		                                widget->allocation.height);

		cl->frameBuffer= image->mem;

		cl->width  = widget->allocation.width;
		cl->height = widget->allocation.height;

		cl->format.bitsPerPixel = image->bits_per_pixel;
		cl->format.redShift     = image->visual->red_shift;
		cl->format.greenShift   = image->visual->green_shift;
		cl->format.blueShift    = image->visual->blue_shift;

		cl->format.redMax   = (1 << image->visual->red_prec) - 1;
		cl->format.greenMax = (1 << image->visual->green_prec) - 1;
		cl->format.blueMax  = (1 << image->visual->blue_prec) - 1;

#ifdef LIBVNCSERVER_CONFIG_LIBVA
		/* Allow libvncclient to use a more efficient way
		 * of putting the framebuffer on the screen when
		 * using the H.264 format.
		 */
		cl->outputWindow = GDK_WINDOW_XID(widget->window);
#endif

		SetFormatAndEncodings (cl);

		framebuffer_allocated = TRUE;

		/* Also disable local cursor */
		GdkCursor* cur = gdk_cursor_new( GDK_BLANK_CURSOR );
		gdk_window_set_cursor (gtk_widget_get_window(GTK_WIDGET(window)), cur);
		gdk_cursor_unref( cur );
	}

#ifndef LIBVNCSERVER_CONFIG_LIBVA
	gdk_draw_image (GDK_DRAWABLE (widget->window),
	                widget->style->fg_gc[gtk_widget_get_state(widget)],
	                image,
	                event->area.x, event->area.y,
	                event->area.x, event->area.y,
	                event->area.width, event->area.height);
#endif

	return FALSE;
}

struct { int gdk; int rfb; } buttonMapping[] = {
	{ GDK_BUTTON1_MASK, rfbButton1Mask },
	{ GDK_BUTTON2_MASK, rfbButton2Mask },
	{ GDK_BUTTON3_MASK, rfbButton3Mask },
	{ 0, 0 }
};

static gboolean button_event (GtkWidget      *widget,
                              GdkEventButton *event)
{
	int x, y;
	GdkModifierType state;
	int i, buttonMask;

	gdk_window_get_pointer (event->window, &x, &y, &state);

	for (buttonMask = 0, i = 0; buttonMapping[i].gdk; i++)
		if (state & buttonMapping[i].gdk)
			buttonMask |= buttonMapping[i].rfb;
	SendPointerEvent (cl, x, y, buttonMask);

	return TRUE;
}

static gboolean motion_notify_event (GtkWidget *widget,
                                     GdkEventMotion *event)
{
	int x, y;
	GdkModifierType state;
	int i, buttonMask;

	if (event->is_hint)
		gdk_window_get_pointer (event->window, &x, &y, &state);
	else {
		x = event->x;
		y = event->y;
		state = event->state;
	}

	for (buttonMask = 0, i = 0; buttonMapping[i].gdk; i++)
		if (state & buttonMapping[i].gdk)
			buttonMask |= buttonMapping[i].rfb;
	SendPointerEvent (cl, x, y, buttonMask);

	return TRUE;
}

static void got_cut_text (rfbClient *cl, const char *text, int textlen)
{
	if (server_cut_text != NULL) {
		g_free (server_cut_text);
		server_cut_text = NULL;
	}

	server_cut_text = g_strdup (text);
}

void received_text_from_clipboard (GtkClipboard *clipboard,
                                   const gchar *text,
                                   gpointer data)
{
	if (text)
		SendClientCutText (cl, (char *) text, strlen (text));
}

static void clipboard_local_to_remote (GtkMenuItem *menuitem,
                                       gpointer     user_data)
{
	GtkClipboard *clipboard;

	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (menuitem),
	                                      GDK_SELECTION_CLIPBOARD);
	gtk_clipboard_request_text (clipboard, received_text_from_clipboard,
	                            NULL);
}

static void clipboard_remote_to_local (GtkMenuItem *menuitem,
                                       gpointer     user_data)
{
	GtkClipboard *clipboard;

	clipboard = gtk_widget_get_clipboard (GTK_WIDGET (menuitem),
	                                      GDK_SELECTION_CLIPBOARD);

	gtk_clipboard_set_text (clipboard, server_cut_text,
	                        strlen (server_cut_text));
}

static void request_screen_refresh (GtkMenuItem *menuitem,
                                    gpointer     user_data)
{
	SendFramebufferUpdateRequest (cl, 0, 0, cl->width, cl->height, FALSE);
}

static void send_f8 (GtkMenuItem *menuitem,
                     gpointer     user_data)
{
	SendKeyEvent(cl, XK_F8, TRUE);
	SendKeyEvent(cl, XK_F8, FALSE);
}

static void send_crtl_alt_del (GtkMenuItem *menuitem,
                               gpointer     user_data)
{
	SendKeyEvent(cl, XK_Control_L, TRUE);
	SendKeyEvent(cl, XK_Alt_L, TRUE);
	SendKeyEvent(cl, XK_Delete, TRUE);
	SendKeyEvent(cl, XK_Alt_L, FALSE);
	SendKeyEvent(cl, XK_Control_L, FALSE);
	SendKeyEvent(cl, XK_Delete, FALSE);
}

static void show_connect_window(int argc, char **argv)
{
	GtkWidget *label;
	char buf[256];

	dialog_connecting = gtk_dialog_new_with_buttons ("VNC Viewer",
	                                       NULL,
	                                       GTK_DIALOG_DESTROY_WITH_PARENT,
	                                       /*GTK_STOCK_CANCEL,
	                                       GTK_RESPONSE_CANCEL,*/
	                                       NULL);

	/* FIXME: this works only when address[:port] is at end of arg list */
	char *server;
	if(argc==1)
	    server = "localhost";
	else
	   server = argv[argc-1];
	snprintf(buf, 255, "Connecting to %s...", server);

	label = gtk_label_new (buf);
	gtk_widget_show (label);

	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog_connecting)->vbox),
	                   label);

	gtk_widget_show (dialog_connecting);

	while (gtk_events_pending ())
		gtk_main_iteration ();
}

static void show_popup_menu()
{
	GtkWidget *popup_menu;
	GtkWidget *menu_item;

	popup_menu = gtk_menu_new ();

	menu_item = gtk_menu_item_new_with_label ("Dismiss popup");
	gtk_widget_show (menu_item);
	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);

	menu_item = gtk_menu_item_new_with_label ("Clipboard: local -> remote");
	g_signal_connect (G_OBJECT (menu_item), "activate",
	                  G_CALLBACK (clipboard_local_to_remote), NULL);
	gtk_widget_show (menu_item);
	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);

	menu_item = gtk_menu_item_new_with_label ("Clipboard: local <- remote");
	g_signal_connect (G_OBJECT (menu_item), "activate",
	                  G_CALLBACK (clipboard_remote_to_local), NULL);
	gtk_widget_show (menu_item);
	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);

	menu_item = gtk_menu_item_new_with_label ("Request refresh");
	g_signal_connect (G_OBJECT (menu_item), "activate",
	                  G_CALLBACK (request_screen_refresh), NULL);
	gtk_widget_show (menu_item);
	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);

	menu_item = gtk_menu_item_new_with_label ("Send ctrl-alt-del");
	g_signal_connect (G_OBJECT (menu_item), "activate",
	                  G_CALLBACK (send_crtl_alt_del), NULL);
	gtk_widget_show (menu_item);
	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);

	menu_item = gtk_menu_item_new_with_label ("Send F8");
	g_signal_connect (G_OBJECT (menu_item), "activate",
	                  G_CALLBACK (send_f8), NULL);
	gtk_widget_show (menu_item);
	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);

	gtk_menu_popup (GTK_MENU (popup_menu), NULL, NULL, NULL, NULL, 0,
	                gtk_get_current_event_time());
}

static rfbKeySym gdkKey2rfbKeySym(guint keyval)
{
	rfbKeySym k = 0;
	switch(keyval) {
	case GDK_BackSpace: k = XK_BackSpace; break;
	case GDK_Tab: k = XK_Tab; break;
	case GDK_Clear: k = XK_Clear; break;
	case GDK_Return: k = XK_Return; break;
	case GDK_Pause: k = XK_Pause; break;
	case GDK_Escape: k = XK_Escape; break;
	case GDK_space: k = XK_space; break;
	case GDK_Delete: k = XK_Delete; break;
	case GDK_KP_0: k = XK_KP_0; break;
	case GDK_KP_1: k = XK_KP_1; break;
	case GDK_KP_2: k = XK_KP_2; break;
	case GDK_KP_3: k = XK_KP_3; break;
	case GDK_KP_4: k = XK_KP_4; break;
	case GDK_KP_5: k = XK_KP_5; break;
	case GDK_KP_6: k = XK_KP_6; break;
	case GDK_KP_7: k = XK_KP_7; break;
	case GDK_KP_8: k = XK_KP_8; break;
	case GDK_KP_9: k = XK_KP_9; break;
	case GDK_KP_Decimal: k = XK_KP_Decimal; break;
	case GDK_KP_Divide: k = XK_KP_Divide; break;
	case GDK_KP_Multiply: k = XK_KP_Multiply; break;
	case GDK_KP_Subtract: k = XK_KP_Subtract; break;
	case GDK_KP_Add: k = XK_KP_Add; break;
	case GDK_KP_Enter: k = XK_KP_Enter; break;
	case GDK_KP_Equal: k = XK_KP_Equal; break;
	case GDK_Up: k = XK_Up; break;
	case GDK_Down: k = XK_Down; break;
	case GDK_Right: k = XK_Right; break;
	case GDK_Left: k = XK_Left; break;
	case GDK_Insert: k = XK_Insert; break;
	case GDK_Home: k = XK_Home; break;
	case GDK_End: k = XK_End; break;
	case GDK_Page_Up: k = XK_Page_Up; break;
	case GDK_Page_Down: k = XK_Page_Down; break;
	case GDK_F1: k = XK_F1; break;
	case GDK_F2: k = XK_F2; break;
	case GDK_F3: k = XK_F3; break;
	case GDK_F4: k = XK_F4; break;
	case GDK_F5: k = XK_F5; break;
	case GDK_F6: k = XK_F6; break;
	case GDK_F7: k = XK_F7; break;
	case GDK_F8: k = XK_F8; break;
	case GDK_F9: k = XK_F9; break;
	case GDK_F10: k = XK_F10; break;
	case GDK_F11: k = XK_F11; break;
	case GDK_F12: k = XK_F12; break;
	case GDK_F13: k = XK_F13; break;
	case GDK_F14: k = XK_F14; break;
	case GDK_F15: k = XK_F15; break;
	case GDK_Num_Lock: k = XK_Num_Lock; break;
	case GDK_Caps_Lock: k = XK_Caps_Lock; break;
	case GDK_Scroll_Lock: k = XK_Scroll_Lock; break;
	case GDK_Shift_R: k = XK_Shift_R; break;
	case GDK_Shift_L: k = XK_Shift_L; break;
	case GDK_Control_R: k = XK_Control_R; break;
	case GDK_Control_L: k = XK_Control_L; break;
	case GDK_Alt_R: k = XK_Alt_R; break;
	case GDK_Alt_L: k = XK_Alt_L; break;
	case GDK_Meta_R: k = XK_Meta_R; break;
	case GDK_Meta_L: k = XK_Meta_L; break;
#if 0
	/* TODO: find out keysyms */
	case GDK_Super_L: k = XK_LSuper; break;      /* left "windows" key */
	case GDK_Super_R: k = XK_RSuper; break;      /* right "windows" key */
	case GDK_Multi_key: k = XK_Compose; break;
#endif
	case GDK_Mode_switch: k = XK_Mode_switch; break;
	case GDK_Help: k = XK_Help; break;
	case GDK_Print: k = XK_Print; break;
	case GDK_Sys_Req: k = XK_Sys_Req; break;
	case GDK_Break: k = XK_Break; break;
	default: break;
	}
	if (k == 0) {
		if (keyval < 0x100)
			k = keyval;
		else
			rfbClientLog ("Unknown keysym: %d\n", keyval);
	}

	return k;
}

static gboolean key_event (GtkWidget *widget, GdkEventKey *event,
                                 gpointer user_data)
{
	if ((event->type == GDK_KEY_PRESS) && (event->keyval == GDK_F8))
		show_popup_menu();
	else
		SendKeyEvent(cl, gdkKey2rfbKeySym (event->keyval),
		             (event->type == GDK_KEY_PRESS) ? TRUE : FALSE);
	return FALSE;
}

void quit ()
{
	exit (0);
}

static rfbBool resize (rfbClient *client) {
	GtkWidget *scrolled_window;
	GtkWidget *drawing_area=NULL;
	static char first=TRUE;
	int tmp_width, tmp_height;

	if (first) {
		first=FALSE;

		/* Create the drawing area */

		drawing_area = gtk_drawing_area_new ();
		gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
		                             client->width, client->height);

		/* Signals used to handle backing pixmap */

		g_signal_connect (G_OBJECT (drawing_area), "expose_event",
		                  G_CALLBACK (expose_event), NULL);

		/* Event signals */

		g_signal_connect (G_OBJECT (drawing_area),
		                  "motion-notify-event",
		                  G_CALLBACK (motion_notify_event), NULL);
		g_signal_connect (G_OBJECT (drawing_area),
		                  "button-press-event",
		                  G_CALLBACK (button_event), NULL);
		g_signal_connect (G_OBJECT (drawing_area),
		                  "button-release-event",
		                  G_CALLBACK (button_event), NULL);

		gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
		                       | GDK_LEAVE_NOTIFY_MASK
		                       | GDK_BUTTON_PRESS_MASK
		                       | GDK_BUTTON_RELEASE_MASK
		                       | GDK_POINTER_MOTION_MASK
		                       | GDK_POINTER_MOTION_HINT_MASK);

		gtk_widget_show (drawing_area);

		scrolled_window = gtk_scrolled_window_new (NULL, NULL);
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
		                                GTK_POLICY_AUTOMATIC,
		                                GTK_POLICY_AUTOMATIC);
		gtk_scrolled_window_add_with_viewport (
		                  GTK_SCROLLED_WINDOW (scrolled_window),
		                  drawing_area);
		g_signal_connect (G_OBJECT (scrolled_window),
		                  "key-press-event", G_CALLBACK (key_event),
		                  NULL);
		g_signal_connect (G_OBJECT (scrolled_window),
		                  "key-release-event", G_CALLBACK (key_event),
		                  NULL);
		gtk_widget_show (scrolled_window);

		window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
		gtk_window_set_title (GTK_WINDOW (window), client->desktopName);
		gtk_container_add (GTK_CONTAINER (window), scrolled_window);
		tmp_width = (int) (
		            gdk_screen_get_width (gdk_screen_get_default ())
		            * 0.85);
		if (client->width > tmp_width) {
			tmp_height = (int) (
			             gdk_screen_get_height (
			                     gdk_screen_get_default ())
			             * 0.85);
			gtk_widget_set_size_request (window,
			                             tmp_width, tmp_height);
		} else {
			gtk_widget_set_size_request (window,
			       client->width + 2,
			       client->height + 2);
		}

		g_signal_connect (G_OBJECT (window), "destroy",
		                  G_CALLBACK (quit), NULL);

		gtk_widget_show (window);
	} else {
		gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
		                             client->width, client->height);
	}

	return TRUE;
}

static void update (rfbClient *cl, int x, int y, int w, int h) {
	if (dialog_connecting != NULL) {
		gtk_widget_destroy (dialog_connecting);
		dialog_connecting = NULL;
	}

#ifndef LIBVNCSERVER_CONFIG_LIBVA
	GtkWidget *drawing_area = rfbClientGetClientData (cl, gtk_init);

	if (drawing_area != NULL)
		gtk_widget_queue_draw_area (drawing_area, x, y, w, h);
#endif
}

static void kbd_leds (rfbClient *cl, int value, int pad) {
        /* note: pad is for future expansion 0=unused */
        fprintf (stderr, "Led State= 0x%02X\n", value);
        fflush (stderr);
}

/* trivial support for textchat */
static void text_chat (rfbClient *cl, int value, char *text) {
        switch (value) {
        case rfbTextChatOpen:
                fprintf (stderr, "TextChat: We should open a textchat window!\n");
                TextChatOpen (cl);
                break;
        case rfbTextChatClose:
                fprintf (stderr, "TextChat: We should close our window!\n");
                break;
        case rfbTextChatFinished:
                fprintf (stderr, "TextChat: We should close our window!\n");
                break;
        default:
                fprintf (stderr, "TextChat: Received \"%s\"\n", text);
                break;
        }
        fflush (stderr);
}

static gboolean on_entry_key_press_event (GtkWidget *widget, GdkEventKey *event,
                                          gpointer user_data)
{
	if (event->keyval == GDK_Escape)
		gtk_dialog_response (GTK_DIALOG(user_data), GTK_RESPONSE_REJECT);
	else if (event->keyval == GDK_Return)
		gtk_dialog_response (GTK_DIALOG(user_data), GTK_RESPONSE_ACCEPT);

	return FALSE;
}

static void GtkErrorLog (const char *format, ...)
{
	GtkWidget *dialog, *label;
	va_list args;
	char buf[256];

	if (dialog_connecting != NULL) {
		gtk_widget_destroy (dialog_connecting);
		dialog_connecting = NULL;
	}

	va_start (args, format);
	vsnprintf (buf, 255, format, args);
	va_end (args);

	if (g_utf8_validate (buf, strlen (buf), NULL)) {
		label = gtk_label_new (buf);
	} else {
		const gchar *charset;
		gchar       *utf8;

		(void) g_get_charset (&charset);
		utf8 = g_convert_with_fallback (buf, strlen (buf), "UTF-8",
		                                charset, NULL, NULL, NULL, NULL);

		if (utf8) {
			label = gtk_label_new (utf8);
			g_free (utf8);
		} else {
			label = gtk_label_new (buf);
			g_warning ("Message Output is not in UTF-8"
			           "nor in locale charset.\n");
		}
	}

	dialog = gtk_dialog_new_with_buttons ("Error",
	                                       NULL,
	                                       GTK_DIALOG_DESTROY_WITH_PARENT,
	                                       GTK_STOCK_OK,
	                                       GTK_RESPONSE_ACCEPT,
	                                       NULL);
	label = gtk_label_new (buf);
	gtk_widget_show (label);

	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
	                   label);
	gtk_widget_show (dialog);

	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
	case GTK_RESPONSE_ACCEPT:
		break;
	default:
		break;
	}
	gtk_widget_destroy (dialog);
}

static void GtkDefaultLog (const char *format, ...)
{
	va_list args;
	char buf[256];
	time_t log_clock;

	va_start (args, format);

	time (&log_clock);
	strftime (buf, 255, "%d/%m/%Y %X ", localtime (&log_clock));
	fprintf (stdout, buf);

	vfprintf (stdout, format, args);
	fflush (stdout);

	va_end (args);
}

static char * get_password (rfbClient *client)
{
	GtkWidget *dialog, *entry;
	char *password;

	gtk_widget_destroy (dialog_connecting);
	dialog_connecting = NULL;

	dialog = gtk_dialog_new_with_buttons ("Password",
	                                       NULL,
	                                       GTK_DIALOG_DESTROY_WITH_PARENT,
	                                       GTK_STOCK_CANCEL,
	                                       GTK_RESPONSE_REJECT,
	                                       GTK_STOCK_OK,
	                                       GTK_RESPONSE_ACCEPT,
	                                       NULL);
	entry = gtk_entry_new ();
	gtk_entry_set_visibility (GTK_ENTRY (entry),
	                          FALSE);
	g_signal_connect (GTK_OBJECT(entry), "key-press-event",
	                    G_CALLBACK(on_entry_key_press_event),
	                    GTK_OBJECT (dialog));
	gtk_widget_show (entry);

	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
	                   entry);
	gtk_widget_show (dialog);

	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
	case GTK_RESPONSE_ACCEPT:
		password = strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
		break;
	default:
		password = NULL;
		break;
	}
	gtk_widget_destroy (dialog);
	return password;
}

int main (int argc, char *argv[])
{
	int i;
	GdkImage *image;

	rfbClientLog = GtkDefaultLog;
	rfbClientErr = GtkErrorLog;

	gtk_init (&argc, &argv);

	/* create a dummy image just to make use of its properties */
	image = gdk_image_new (GDK_IMAGE_FASTEST, gdk_visual_get_system(),
				200, 100);

	cl = rfbGetClient (image->depth / 3, 3, image->bpp);

	cl->format.redShift     = image->visual->red_shift;
	cl->format.greenShift   = image->visual->green_shift;
	cl->format.blueShift    = image->visual->blue_shift;

	cl->format.redMax   = (1 << image->visual->red_prec) - 1;
	cl->format.greenMax = (1 << image->visual->green_prec) - 1;
	cl->format.blueMax  = (1 << image->visual->blue_prec) - 1;

	g_object_unref (image);

	cl->MallocFrameBuffer = resize;
	cl->canHandleNewFBSize = TRUE;
	cl->GotFrameBufferUpdate = update;
	cl->GotXCutText = got_cut_text;
	cl->HandleKeyboardLedState = kbd_leds;
	cl->HandleTextChat = text_chat;
	cl->GetPassword = get_password;

	show_connect_window (argc, argv);

	if (!rfbInitClient (cl, &argc, argv))
		return 1;

	while (1) {
		while (gtk_events_pending ())
			gtk_main_iteration ();
		i = WaitForMessage (cl, 500);
		if (i < 0)
			return 0;
		if (i && framebuffer_allocated == TRUE)
			if (!HandleRFBServerMessage(cl))
				return 0;
	}

	gtk_main ();

	return 0;
}

