diff -urN a/plugin/gtk-vnc-plugin.c b/plugin/gtk-vnc-plugin.c
--- a/plugin/gtk-vnc-plugin.c	2010-05-30 22:03:48.000000000 +0200
+++ b/plugin/gtk-vnc-plugin.c	2010-05-30 14:50:43.000000000 +0200
@@ -46,17 +46,43 @@
 gboolean
 layout_canvas_color(PluginInstance *This, int pos, guchar* color);
 gboolean
-layout_vnc_create(PluginInstance *This, int x, int y, int w, int h, gboolean mouse_grab, gboolean kbd_grab);
+layout_vnc_create(PluginInstance *This, int x, int y, int w, int h, 
+	gboolean mouse_grab, gboolean kbd_grab, gboolean readonly,
+	gboolean shared, gboolean scaling,
+	gboolean lossy_encoding, gboolean pointer_local);
 gboolean
 layout_vnc_connect(PluginInstance *This, char* host, char* port);
 
 static void ContextMenuCallback1(PluginInstance *This);
 static void ContextMenuCallback2(PluginInstance *This);
 static void ContextMenuCallback3(PluginInstance *This);
+static void ContextMenuCallback4(PluginInstance *This);
+static void ContextMenuCallback5(PluginInstance *This);
+static void ContextMenuCallback6(PluginInstance *This);
+static void ContextMenuCallback7(PluginInstance *This);
+static void ContextMenuCallback99(PluginInstance *This);
+/* static void ContextMenuCallbackA(PluginInstance *This); */
 
 static void
 vnc_auth_credential (GtkWidget *vnc, GValueArray *creds, void *Thisv);
 
+
+
+
+/*
+static void
+vnc_desktop_resize (GtkWidget *vnc G_GNUC_UNUSED, void *Thisv)
+{
+  PluginInstance *This = (PluginInstance *) Thisv;
+  int w,h;
+  w=vnc_display_get_width(VNC_DISPLAY(vnc));
+  h=vnc_display_get_height(VNC_DISPLAY(vnc));
+  // maybe unneccessary
+  gtk_widget_set_size_request(This->vnc, w, h);
+  gtk_widget_queue_draw_area (This->vnc,0,0,w,h);
+  NPN_Status(This->instance , "(Click on grey color bar for help)");
+}
+*/
 static void
 vnc_pointer_grab (GtkWidget *vnc G_GNUC_UNUSED, void *Thisv)
 {
@@ -76,12 +102,44 @@
 }
 
 static void
+vnc_keyboard_grab (GtkWidget *vnc G_GNUC_UNUSED, void *Thisv)
+{
+  PluginInstance *This = (PluginInstance *) Thisv;
+  debug ("vnc_connected, This=%p", This);
+  NPN_Status(This->instance , "Press <ctrl> plus <alt> to release keyboard. (Click on grey color bar for help)");
+}
+
+static void
+vnc_keyboard_ungrab (GtkWidget *vnc G_GNUC_UNUSED, void *Thisv)
+{
+  PluginInstance *This = (PluginInstance *) Thisv;
+  debug ("vnc_connected, This=%p", This);
+  NPN_Status(This->instance , "(Click on grey color bar for help)");
+}
+
+static void
 vnc_connected (GtkWidget *vnc G_GNUC_UNUSED, void *Thisv)
 {
   PluginInstance *This = (PluginInstance *) Thisv;
   debug ("vnc_connected, This=%p", This);
   layout_canvas_color(This, 1, (guchar[]){0x00,0xFF,0x00});
+    if(This->readonly)
+	layout_canvas_color(This, 3, (guchar[]){0x40,0x40,0x40});
+    else
+	layout_canvas_color(This, 3, (guchar[]){0xC0,0xC0,0xC0});
   NPN_Status(This->instance , "connected (Click on grey color bar for help)");
+  if(This->focus_on_connect) {
+	// on html page loading vnc does not get the focus automatically 
+	if(!This->dialog_up && This->vnc /* && !This->kbd_grab */) {
+		gtk_widget_grab_focus(This->vnc);
+	    if(This->kbd_grab)
+		NPN_Status(This->instance , "connected - press <ctrl> plus <alt> to release keyboard (Click on grey color bar for help)");
+	    else
+		NPN_Status(This->instance , "connected (Click on grey color bar for help)");
+	}
+  } else {
+    NPN_Status(This->instance , "connected (Click on grey color bar for help)");
+  }
 }
 
 static void
@@ -103,26 +161,191 @@
   NPN_Status(This->instance , "disconnected - (Click on grey color bar for help)");
 }
 
+/*
+static gboolean VncEventCallback(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+{
+
+    gboolean handled = 0;
+    char string[256];
+    PluginInstance *This = (PluginInstance *)user_data;
+
+    GdkEventButton *button;
+
+    if (event->type != GDK_BUTTON_PRESS)
+        return handled;
+
+    switch(event->type) {
+
+
+    case GDK_BUTTON_PRESS:
+        button = (GdkEventButton *)event;
+	if(This && This->menu) { // hide ungrab menu
+	    gtk_widget_destroy(This->menu);
+	    This->menu = NULL;
+	}
+snprintf(string, sizeof string, "t1: x=%u, y=%u", (uint32_t)button->x, (uint32_t)button->y);
+NPN_Status(This->instance , string);
+        if (button->button == 1 && (uint32_t)button->y <= 2 &&
+            (uint32_t)button->x >= 2*(This->width  / 4) &&
+            (uint32_t)button->x <= 3*(This->width / 4) &&
+            vnc_display_get_pointer_grab(VNC_DISPLAY(This->vnc))
+           )
+        {
+NPN_Status(This->instance , "t2");
+            // ungrab menu (bottom of blue field in color toolbar)
+            GtkWidget *menu;
+            GtkWidget *menu_item;
+
+            menu = gtk_menu_new();
+
+            menu_item = gtk_menu_item_new_with_label ("ungrab pointer");
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+                G_CALLBACK(ContextMenuCallbackA), This);
+            gtk_widget_show (menu_item);
+            gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+                0, gtk_get_current_event_time());
+            This->menu = menu;
+    	    handled = 1;
+        }
+
+	// all mouseclicks on toolbar, ecept dialog and menu, lead tofocus on vnc 
+	if(!This->dialog_up && This->vnc && !This->kbd_grab) {
+		gtk_widget_grab_focus(This->vnc);
+	}
+        handled = 0;
+        break;
+    }
+
+    return handled;
+}
+*/
+
 static void ContextMenuCallback1(PluginInstance *This)
 {
     vnc_display_set_pointer_grab(VNC_DISPLAY(This->vnc),! vnc_display_get_pointer_grab(VNC_DISPLAY(This->vnc)));
     This->mouse_grab=vnc_display_get_pointer_grab(VNC_DISPLAY(This->vnc));
-    layout_canvas_color(This, 3, (guchar[]){0xC0,0xC0,0xC0}); // test
 }
 
 static void ContextMenuCallback2(PluginInstance *This)
 {
     vnc_display_set_keyboard_grab(VNC_DISPLAY(This->vnc),! vnc_display_get_keyboard_grab(VNC_DISPLAY(This->vnc)));
     This->kbd_grab=vnc_display_get_keyboard_grab(VNC_DISPLAY(This->vnc));
-    layout_canvas_color(This, 3, (guchar[]){0xC0,0xC0,0xC0}); // test
 }
 
 static void ContextMenuCallback3(PluginInstance *This)
 {
-    ;
+    vnc_display_set_read_only(VNC_DISPLAY(This->vnc),! vnc_display_get_read_only(VNC_DISPLAY(This->vnc)));
+    This->readonly=vnc_display_get_read_only(VNC_DISPLAY(This->vnc));
+    if(This->readonly)
+	layout_canvas_color(This, 3, (guchar[]){0x40,0x40,0x40});
+    else
+	layout_canvas_color(This, 3, (guchar[]){0xC0,0xC0,0xC0});
+}
+
+static void ContextMenuCallback4(PluginInstance *This)
+{
+    vnc_display_set_shared_flag(VNC_DISPLAY(This->vnc),! vnc_display_get_shared_flag(VNC_DISPLAY(This->vnc)));
+    This->shared=vnc_display_get_shared_flag(VNC_DISPLAY(This->vnc));
+}
+
+static void ContextMenuCallback5(PluginInstance *This)
+{
+    vnc_display_set_scaling(VNC_DISPLAY(This->vnc),! vnc_display_get_scaling(VNC_DISPLAY(This->vnc)));
+    This->scaling=vnc_display_get_scaling(VNC_DISPLAY(This->vnc));
+}
+
+static void ContextMenuCallback6(PluginInstance *This)
+{
+    vnc_display_set_lossy_encoding(VNC_DISPLAY(This->vnc),! vnc_display_get_lossy_encoding(VNC_DISPLAY(This->vnc)));
+    This->lossy_encoding=vnc_display_get_lossy_encoding(VNC_DISPLAY(This->vnc));
+}
+
+static void ContextMenuCallback7(PluginInstance *This)
+{
+    vnc_display_set_pointer_local(VNC_DISPLAY(This->vnc),! vnc_display_get_pointer_local(VNC_DISPLAY(This->vnc)));
+    This->pointer_local=vnc_display_get_pointer_local(VNC_DISPLAY(This->vnc));
+}
+
+static void ContextMenuCallback99(PluginInstance *This G_GNUC_UNUSED)
+{
+    ; // Close Menu
+}
+
+static void send_keys(PluginInstance *This, guint *keys, guint keycount)
+{
+	if(This->vnc)
+		vnc_display_send_keys(VNC_DISPLAY(This->vnc), keys, keycount);
+}
+static void send_caf1(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F1}, 3);
+}
+static void send_caf2(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F2}, 3);
+}
+static void send_caf3(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F3}, 3);
+}
+static void send_caf4(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F4}, 3);
+}
+static void send_caf5(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F5}, 3);
+}
+static void send_caf6(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F6}, 3);
+}
+static void send_caf7(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F7}, 3);
+}
+static void send_caf8(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_F8}, 3);
+}
+static void send_cab(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_BackSpace}, 3);
+}
+static void send_cad(PluginInstance *This)
+{
+	send_keys(This, (guint[]){GDK_Control_L, GDK_Alt_L, GDK_Delete}, 3);
 }
+/*
+static void send_caf1(GtkWidget *menu G_GNUC_UNUSED, GtkWidget *vncdisplay)
+{
+	guint keys[] = { GDK_Control_L, GDK_Alt_L, GDK_F1 };
+	printf("Sending Ctrl+Alt+F1\n");
+	vnc_display_send_keys(VNC_DISPLAY(vncdisplay), keys,
+		sizeof(keys)/sizeof(keys[0]));
+}
+*/
+
 
-static gboolean CanvasEventCallback(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+/*
+static void ContextMenuCallbackA(PluginInstance *This)
+{
+  layout_canvas_color(This, 2, (guchar[]){0x00,0x00,0x80});
+  // disable grabbing of keyboard and pointer
+  if (This && This->vnc) {
+    gboolean flag; 
+    // force_grab(...,FALSE) ungrabs keyboard only with set_keyboard_grab(...,FALSE)
+    flag=vnc_display_get_keyboard_grab(VNC_DISPLAY(This->vnc));
+    vnc_display_set_keyboard_grab(VNC_DISPLAY(This->vnc), FALSE);
+    vnc_display_force_grab (VNC_DISPLAY(This->vnc), FALSE);
+    // restore keyboard grab setting
+    vnc_display_set_keyboard_grab(VNC_DISPLAY(This->vnc), flag);
+  }
+}
+*/
+
+static gboolean CanvasEventCallback(GtkWidget *widget G_GNUC_UNUSED, GdkEvent *event, gpointer user_data)
 {
 
     gboolean handled = 0;
@@ -174,6 +397,7 @@
 			layout_canvas_color(This, 0, (guchar[]){0x80,0x00,0x00}); // vnc off
 			layout_canvas_color(This, 1, (guchar[]){0x00,0x80,0x00}); // vnc disconnected
 		}
+		NPN_Status(This->instance , "disconnected - (Click on grey color bar for help)");
 
             }
             else
@@ -181,7 +405,11 @@
                 ((uint32_t)button->x <= 2*(This->width / 4)))
             {   // "green"
                 // (re)create vnc widget (removes existing widget)
-            	if(layout_vnc_create(This, 0, This->canvas_h, This->vnc_w, This->vnc_w, This->mouse_grab, This->kbd_grab))
+            	if(layout_vnc_create(This, 0, This->canvas_h, This->vnc_w, This->vnc_w, 
+            				This->mouse_grab, This->kbd_grab, This->readonly,
+            				This->shared, This->scaling,
+            				This->lossy_encoding, This->pointer_local
+            				))
 		    layout_canvas_color(This, 0, (guchar[]){0xFF,0x00,0x00}); // vnc off
             	else
 		    layout_canvas_color(This, 0, (guchar[]){0x80,0x00,0x00}); // vnc on
@@ -218,15 +446,19 @@
                 GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
                 GtkWidget *label = gtk_label_new (
             		"Gtk vnc plugin with toolbar (color bar)"
+            		"\n"
             		"\n - red: stop vnc"
+            		"\n      (light red = vnc viewer active; dark red = viewer not active)"
             		"\n - green: (re)start vnc"
-            		"\n - blue: mouse grabbed/not grabbed"
-            		"\n      (to release grabbed mouse press <ctrl> plus <alt> keys)"
+            		"\n      (light green = connected; dark green = disconnected)"
+            		"\n - blue: light blue = mouse grabbed/ dark = not grabbed"
+            		"\n      (to release the mouse press <ctrl> plus <alt> keys)"
             		"\n - grey: this dialog"
+            		"\n      (dark grey = readonly; light grey = not readonly)"
             		"\n"
             		"\nUrl: http://spblinux.de/blog (Category Virtualization/Xen)"
             		"\n"
-            		"\n(Settings for mouse/keyboard: right click on color bar)"
+            		"\n(Settings for mouse/keyboard/... : right click on color bar)"
             		);
                 gtk_container_add (GTK_CONTAINER (content_area), label);
                 gtk_widget_show_all(content_area);
@@ -242,8 +474,7 @@
         if (button->button == 3)
         {
             // context menu
-            GtkWidget *menu;
-            GtkWidget *menu_item;
+            GtkWidget *menu, *menu_item, *submenu, *submenu_item;
 
             menu = gtk_menu_new();
 
@@ -261,6 +492,125 @@
                 G_CALLBACK(ContextMenuCallback2), This);
             gtk_widget_show (menu_item);
 
+            menu_item = gtk_check_menu_item_new_with_label ("vnc readonly");
+            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), vnc_display_get_read_only(VNC_DISPLAY(This->vnc)));
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+                G_CALLBACK(ContextMenuCallback3), This);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_separator_menu_item_new();
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_check_menu_item_new_with_label ("vnc shared");
+            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), vnc_display_get_shared_flag(VNC_DISPLAY(This->vnc)));
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+                G_CALLBACK(ContextMenuCallback4), This);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_check_menu_item_new_with_label ("vnc scaling");
+            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), vnc_display_get_scaling(VNC_DISPLAY(This->vnc)));
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+                G_CALLBACK(ContextMenuCallback5), This);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_check_menu_item_new_with_label ("vnc lossy encoding");
+            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), vnc_display_get_lossy_encoding(VNC_DISPLAY(This->vnc)));
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+                G_CALLBACK(ContextMenuCallback6), This);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_check_menu_item_new_with_label ("vnc local mouse pointer");
+            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), vnc_display_get_pointer_local(VNC_DISPLAY(This->vnc)));
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+                G_CALLBACK(ContextMenuCallback7), This);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_check_menu_item_new_with_label ("[focus on connect]");
+            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), This->focus_on_connect);
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+//            g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
+//                G_CALLBACK(ContextMenuCallback7), This);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_separator_menu_item_new();
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+            gtk_widget_show (menu_item);
+
+            menu_item = gtk_menu_item_new_with_mnemonic("_Send Key");
+            gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+
+    	    submenu = gtk_menu_new();
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_1");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf1), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_2");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf2), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_3");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf3), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_4");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf4), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_5");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf5), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_6");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf6), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_7");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf7), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+F_8");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_caf8), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+_Del");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_cad), This);
+        	gtk_widget_show (submenu_item);
+
+        	submenu_item = gtk_menu_item_new_with_mnemonic("Ctrl+Alt+_Backspace");
+        	gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
+        	g_signal_connect_swapped(G_OBJECT(submenu_item), "activate",
+            	    G_CALLBACK(send_cab), This);
+        	gtk_widget_show (submenu_item);
+
+            gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
+            gtk_widget_show (menu_item);
+
+
             menu_item = gtk_separator_menu_item_new();
             gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
             gtk_widget_show (menu_item);
@@ -268,7 +618,7 @@
             menu_item = gtk_menu_item_new_with_label ("Close menu");
             gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
             g_signal_connect_swapped(G_OBJECT(menu_item), "activate",
-                G_CALLBACK(ContextMenuCallback3), This);
+                G_CALLBACK(ContextMenuCallback99), This);
             gtk_widget_show (menu_item);
 
             gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
@@ -419,8 +769,6 @@
     This->four_quads = (guchar *)NPN_MemAlloc(w * h * 3);
     if (!This->four_quads)
         return FALSE;
-    This->canvas_w=w;
-    This->canvas_h=h;
     /* draw the toolbar */
     for (quads = 0; quads < 4; quads++) {
         row = This->four_quads + (quads * w / 4 ) * 3;
@@ -530,7 +878,10 @@
 }
 
 gboolean
-layout_vnc_create(PluginInstance *This, int x, int y, int w, int h, gboolean mouse_grab, gboolean kbd_grab)
+layout_vnc_create(PluginInstance *This, int x, int y, int w, int h, 
+	gboolean mouse_grab, gboolean kbd_grab, gboolean readonly,
+	gboolean shared, gboolean scaling,
+	gboolean lossy_encoding, gboolean pointer_local)
 {
   if(This->vnc)
 	gtk_widget_destroy(This->vnc);
@@ -554,6 +905,9 @@
      GDK_FOCUS_CHANGE_MASK);
 
   /* Connect up the signals. */
+//  g_signal_connect(G_OBJECT(This->vnc), "event",
+//		    G_CALLBACK(VncEventCallback), This);
+
   g_signal_connect (G_OBJECT(This->vnc), "vnc-connected",
 		    G_CALLBACK(vnc_connected), This);
   g_signal_connect (G_OBJECT(This->vnc), "vnc-disconnected",
@@ -574,6 +928,10 @@
 		    G_CALLBACK(vnc_pointer_grab), This);
   g_signal_connect (G_OBJECT(This->vnc), "vnc-pointer-ungrab",
 		    G_CALLBACK(vnc_pointer_ungrab), This);
+  g_signal_connect (G_OBJECT(This->vnc), "vnc-keyboard-grab",
+		    G_CALLBACK(vnc_keyboard_grab), This);
+  g_signal_connect (G_OBJECT(This->vnc), "vnc-keyboard-ungrab",
+		    G_CALLBACK(vnc_keyboard_ungrab), This);
 #if 0
   g_signal_connect (G_OBJECT(This->vnc), "key-press-event",
 		    G_CALLBACK(vnc_screenshow), This);
@@ -586,6 +944,15 @@
 
   vnc_display_set_keyboard_grab(VNC_DISPLAY(This->vnc), kbd_grab);
   vnc_display_set_pointer_grab(VNC_DISPLAY(This->vnc), mouse_grab);
+  vnc_display_set_read_only(VNC_DISPLAY(This->vnc), readonly);
+  if(This->readonly)
+	layout_canvas_color(This, 3, (guchar[]){0x40,0x40,0x40});
+  else
+	layout_canvas_color(This, 3, (guchar[]){0x80,0x80,0x80});
+  vnc_display_set_shared_flag(VNC_DISPLAY(This->vnc), shared);
+  vnc_display_set_scaling(VNC_DISPLAY(This->vnc), scaling);
+  vnc_display_set_lossy_encoding(VNC_DISPLAY(This->vnc), lossy_encoding);
+  vnc_display_set_pointer_local(VNC_DISPLAY(This->vnc), pointer_local);
   return TRUE;
 }
 
@@ -618,6 +985,8 @@
   if (This == NULL)
     return NPERR_INVALID_INSTANCE_ERROR;
 
+  This->instance = instance;  // used by NPN_Status(...)
+
   ws_info = (NPSetWindowCallbackStruct *)window->ws_info;
 
   /* Mozilla likes to re-run its greatest hits */
@@ -634,34 +1003,47 @@
   This->x = window->x;
   This->y = window->y;
 
-  This->four_quads=NULL;
-  This->canvas=NULL;
-  This->vnc=NULL;
-  This->menu=NULL;
+  This->four_quads = NULL;
+  This->canvas = NULL;
+  This->vnc = NULL;
+  This->menu = NULL;
 
   This->width = window->width;
   This->height = window->height;
 
-  vnc_w = NULL==This->vnc_w_string ? 800 : strtol(This->vnc_w_string, NULL, 10);
-  vnc_w = vnc_w>0 ? vnc_w : 800; // default
-  vnc_w = vnc_w<This->width ? vnc_w : This->width; // limit to window width
-
-  vnc_h = NULL==This->vnc_h_string ? 600 : strtol(This->vnc_h_string, NULL, 10);
-  vnc_h = vnc_h>0 ? vnc_h : 600; // default
-  vnc_h = (vnc_h+4)<This->height ? vnc_h : This->height-4; // limit to window height - 4px toolbar
-
-  This->vnc_w=vnc_w;
-  This->vnc_h=vnc_h;
+  vnc_w = NULL == This->vnc_w_string ? 800 : strtol(This->vnc_w_string, NULL, 10);
+  vnc_w = vnc_w > 0 ? vnc_w : 800; // default
+  vnc_w = vnc_w < This->width ? vnc_w : This->width; // limit to window width
+
+  vnc_h = NULL == This->vnc_h_string ? 600 : strtol(This->vnc_h_string, NULL, 10);
+  vnc_h = vnc_h > 0 ? vnc_h : 600; // default
+  // minimal height of toolbar: 4px ==> maximal height of vnc: window height - 4px
+  vnc_h = (vnc_h + 4) < This->height ? vnc_h : This->height - 4;
+
+  This->vnc_w = vnc_w;
+  This->vnc_h = vnc_h;
+  // maximal height of toolbar: 16px
+  This->canvas_w = This->width;
+  This->canvas_h = This->height - This->vnc_h > 16 ? 16 : This->height - This->vnc_h;
 
   /* Create a GtkPlug container and a Gtk-VNC widget inside it. */
   This->container = gtk_plug_new ((GdkNativeWindow)(long)window->window);
 
   This->layout = gtk_fixed_new();
 
-  // limit height of toolbar to 10px
-  if (!layout_vnc_create(This, 0, -2 + This->height-vnc_h>10 ? 10 : This->height-vnc_h, This->vnc_w, This->vnc_h, This->mouse_grab, This->kbd_grab))
+  if (!layout_vnc_create(This, 
+		0, This->canvas_h,
+		This->vnc_w, This->vnc_h, 
+		This->mouse_grab, This->kbd_grab, This->readonly,
+		This->shared, This->scaling,
+		This->lossy_encoding, This->pointer_local
+		))
         return NPERR_GENERIC_ERROR;
-  if (!layout_canvas_create(This, This->width, This->height-vnc_h>10 ? 10 : This->height-vnc_h, (guchar[]){0x80,0x00,0x00}, (guchar[]){0x00,0x80,0x00}, (guchar[]){0x00,0x00,0x80}, (guchar[]){0x80,0x80,0x80}))
+
+  if (!layout_canvas_create(This, 
+	This->width, This->canvas_h, 
+	(guchar[]){0x80,0x00,0x00}, (guchar[]){0x00,0x80,0x00}, (guchar[]){0x00,0x00,0x80}, 
+	This->readonly ? ((guchar[]){0x40,0x40,0x40}) : ((guchar[]){0xC0,0xC0,0xC0})))
         return NPERR_GENERIC_ERROR;
 
   layout_canvas_color(This, 0, (guchar[]){0xFF,0x00,0x00});
diff -urN a/plugin/gtk-vnc-plugin.h b/plugin/gtk-vnc-plugin.h
--- a/plugin/gtk-vnc-plugin.h	2010-05-30 22:03:48.000000000 +0200
+++ b/plugin/gtk-vnc-plugin.h	2010-05-30 11:23:52.000000000 +0200
@@ -60,7 +60,8 @@
   GtkWidget *canvas;
   GtkWidget *menu;
   guchar *four_quads;
-  gboolean dialog_up, kbd_grab, mouse_grab;
+  gboolean dialog_up, kbd_grab, mouse_grab, readonly, focus_on_connect;
+  gboolean shared, scaling, lossy_encoding, pointer_local;
 
   char *host, *port, *vnc_w_string, *vnc_h_string;
 } PluginInstance;
diff -urN a/plugin/npshell.c b/plugin/npshell.c
--- a/plugin/npshell.c	2010-05-30 22:03:48.000000000 +0200
+++ b/plugin/npshell.c	2010-05-30 11:27:29.000000000 +0200
@@ -198,7 +198,9 @@
   This->host = This->port = NULL;
 
   /* Read the parameters passed to the plugin. */
-  This->mouse_grab = This->kbd_grab = FALSE;
+  This->mouse_grab = This->kbd_grab = This->readonly = This->shared = FALSE;
+  This->scaling = This->lossy_encoding = This->pointer_local = FALSE;
+  This->focus_on_connect = TRUE;
   for (i = 0; i < argc; i++)
     {
       key = argn[i];
@@ -216,6 +218,18 @@
         This->mouse_grab = ! ('0' == argv[i][0]);
       else if (strcmp (argn[i], "kbd_grab") == 0)
         This->kbd_grab = ! ('0' == argv[i][0]);
+      else if (strcmp (argn[i], "readonly") == 0)
+        This->readonly = ! ('0' == argv[i][0]);
+      else if (strcmp (argn[i], "focus_on_connect") == 0)
+        This->focus_on_connect = ! ('0' == argv[i][0]);
+      else if (strcmp (argn[i], "shared") == 0)
+        This->shared = ! ('0' == argv[i][0]);
+      else if (strcmp (argn[i], "scaling") == 0)
+        This->scaling = ! ('0' == argv[i][0]);
+      else if (strcmp (argn[i], "lossy_encoding") == 0)
+        This->lossy_encoding = ! ('0' == argv[i][0]);
+      else if (strcmp (argn[i], "pointer_local") == 0)
+        This->pointer_local = ! ('0' == argv[i][0]);
     }
 
   return NPERR_NO_ERROR;
