[gnome-boxes] Add VNC display



commit e95d0e6b9e3ee94583f6d739b2716ad5386ee466
Author: Marc-Andrà Lureau <marcandre lureau gmail com>
Date:   Tue Oct 25 21:05:30 2011 +0200

    Add VNC display

 configure.ac           |   10 ++++--
 src/Makefile.am        |    2 +
 src/display-page.vala  |    1 +
 src/display.vala       |    2 +-
 src/machine.vala       |   45 ++++++++++++++++------------
 src/spice-display.vala |    2 +-
 src/vnc-display.vala   |   75 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/wizard.vala        |   20 ++++++++++--
 8 files changed, 129 insertions(+), 28 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d0005bf..2117e70 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,19 +34,21 @@ AC_PROG_LIBTOOL
 
 GLIB_GSETTINGS
 
+CLUTTER_GTK_MIN_VERSION=1.0.1
 GLIB_MIN_VERSION=2.29.90
-GTK_MIN_VERSION=3.1.13
 GOBJECT_INTROSPECTION_MIN_VERSION=0.9.6
-CLUTTER_GTK_MIN_VERSION=1.0.1
-SPICE_GTK_MIN_VERSION=0.7
+GTK_MIN_VERSION=3.1.13
+GTK_VNC_MIN_VERSION=0.4.3
 LIBVIRT_GLIB_MIN_VERSION=0.0.1
 LIBXML2_MIN_VERSION=2.7.8
+SPICE_GTK_MIN_VERSION=0.7
 
 PKG_CHECK_MODULES(BOXES, [
   clutter-gtk-1.0 >= $CLUTTER_GTK_MIN_VERSION
   glib-2.0 >= $GLIB_MIN_VERSION
   gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
   gtk+-3.0 >= $GTK_MIN_VERSION
+  gtk-vnc-2.0 >= $GTK_VNC_MIN_VERSION
   libvirt-gobject-1.0 >= $LIBVIRT_GLIB_MIN_VERSION
   libxml-2.0 >= $LIBXML2_MIN_VERSION
   spice-client-gtk-3.0 >= $SPICE_GTK_MIN_VERSION
@@ -57,6 +59,8 @@ VALA_CHECK_PACKAGES([
   cogl-1.0
   gdk-pixbuf-2.0
   glib-2.0
+  gtk+-3.0
+  gtk-vnc-2.0
   libvirt-gobject-1.0
   libxml-2.0
   posix
diff --git a/src/Makefile.am b/src/Makefile.am
index 1211a12..0da1a0d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,6 +19,7 @@ AM_VALAFLAGS =						\
 	--pkg libxml-2.0				\
 	--pkg posix					\
 	--pkg spice-client-gtk-3.0			\
+	--pkg gtk-vnc-2.0				\
 	$(NULL)
 
 bin_PROGRAMS = gnome-boxes
@@ -36,6 +37,7 @@ gnome_boxes_SOURCES =				\
 	spice-display.vala			\
 	topbar.vala				\
 	util.vala				\
+	vnc-display.vala			\
 	wizard.vala				\
 	$(NULL)
 BUILT_SOURCES = dirs.h
diff --git a/src/display-page.vala b/src/display-page.vala
index deabcc9..55588ff 100644
--- a/src/display-page.vala
+++ b/src/display-page.vala
@@ -38,6 +38,7 @@ private class Boxes.DisplayPage: GLib.Object {
 
             if (event_box.get_child () != null)
                 event_box.get_child ().event (event);
+
             return false;
         });
         overlay = new Overlay ();
diff --git a/src/display.vala b/src/display.vala
index ad73f80..d2d8993 100644
--- a/src/display.vala
+++ b/src/display.vala
@@ -8,7 +8,7 @@ private abstract class Boxes.Display: GLib.Object {
     public signal void hide (int display_id);
     public signal void disconnected ();
 
-    public abstract Gtk.Widget get_display (int n) throws Boxes.Error;
+    public abstract Gtk.Widget? get_display (int n) throws Boxes.Error;
     public abstract void connect_it ();
     public abstract void disconnect_it ();
 
diff --git a/src/machine.vala b/src/machine.vala
index 377b5c4..df36982 100644
--- a/src/machine.vala
+++ b/src/machine.vala
@@ -37,18 +37,17 @@ private abstract class Boxes.Machine: Boxes.CollectionItem {
 
             show_id = _display.show.connect ((id) => {
                 app.ui_state = Boxes.UIState.DISPLAY;
-                try {
-                    var widget = display.get_display (0);
-
-                    Timeout.add (Boxes.App.duration, () => {
+                Timeout.add (Boxes.App.duration, () => {
+                    try {
+                        var widget = display.get_display (0);
                         app.display_page.show_display (this, widget);
                         widget.grab_focus ();
+                    } catch (Boxes.Error error) {
+                        warning (error.message);
+                    }
 
-                        return false;
-                    });
-                } catch (Boxes.Error error) {
-                    warning (error.message);
-                }
+                    return false;
+                });
             });
 
             hide_id = _display.hide.connect ((id) => {
@@ -59,11 +58,14 @@ private abstract class Boxes.Machine: Boxes.CollectionItem {
                 app.ui_state = Boxes.UIState.COLLECTION;
             });
 
-            need_password_id = display.notify["need-password"].connect (() => {
+            need_password_id = _display.notify["need-password"].connect (() => {
                 machine_actor.set_password_needed (display.need_password);
             });
 
-            display.password = machine_actor.get_password ();
+            _display.password = machine_actor.get_password ();
+
+            if (_connect_display)
+                display.connect_it ();
         }
     }
 
@@ -292,17 +294,22 @@ private class Boxes.LibvirtMachine: Boxes.Machine {
             return;
         }
 
-        if (type == "spice") {
-            if (display != null)
-                display.disconnect_it ();
+        if (display != null)
+            display.disconnect_it ();
+
+        switch (type) {
+        case "spice":
             display = new SpiceDisplay (ghost, int.parse (gport));
-        } else {
+            break;
+
+        case "vnc":
+            display = new VncDisplay (ghost, int.parse (gport));
+            break;
+
+        default:
             warning ("unsupported display of type " + type);
-            return;
+            break;
         }
-
-        if (_connect_display)
-            display.connect_it ();
     }
 
     public override string get_screenshot_prefix () {
diff --git a/src/spice-display.vala b/src/spice-display.vala
index 3d12bf2..3a5d212 100644
--- a/src/spice-display.vala
+++ b/src/spice-display.vala
@@ -22,7 +22,7 @@ private class Boxes.SpiceDisplay: Boxes.Display {
         session.uri = uri;
     }
 
-    public override Gtk.Widget get_display (int n) throws Boxes.Error {
+    public override Gtk.Widget? get_display (int n) throws Boxes.Error {
         var display = displays.lookup (n) as Spice.Display;
 
         if (display == null) {
diff --git a/src/vnc-display.vala b/src/vnc-display.vala
new file mode 100644
index 0000000..179c709
--- /dev/null
+++ b/src/vnc-display.vala
@@ -0,0 +1,75 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+using Gtk;
+using Vnc;
+
+private class Boxes.VncDisplay: Boxes.Display {
+    private Vnc.Display display;
+    private string host;
+    private int port;
+    private Gtk.Window window;
+
+    construct {
+        need_password = false;
+
+        display = new Vnc.Display ();
+        display.set_keyboard_grab (true);
+        display.set_pointer_grab (true);
+        display.set_force_size (false);
+        display.set_scaling (true);
+
+        // the VNC widget doesn't like not to have a realized window,
+        // so we put it into a window temporarily
+        window = new Gtk.Window ();
+        window.add (display);
+        display.realize ();
+
+        display.vnc_connected.connect (() => {
+            show (0);
+        });
+        display.vnc_disconnected.connect (() => {
+            hide (0);
+        });
+        display.vnc_initialized.connect (() => {
+            debug ("initialized");
+        });
+        display.vnc_auth_failure.connect (() => {
+            debug ("auth failure");
+        });
+        display.vnc_auth_unsupported.connect (() => {
+            debug ("auth unsupported");
+        });
+        display.vnc_auth_credential.connect (() => {
+            debug ("auth credentials");
+        });
+    }
+
+    public VncDisplay (string host, int port) {
+        this.host = host;
+        this.port = port;
+    }
+
+    public VncDisplay.with_uri (string _uri) throws Boxes.Error {
+        var uri = Xml.URI.parse (_uri);
+
+        if (uri.scheme != "vnc")
+            throw new Boxes.Error.INVALID ("the URI is not vnc://");
+
+        if (uri.server == null)
+            throw new Boxes.Error.INVALID ("the URI is missing a server");
+
+        this.host = uri.server;
+        this.port = uri.port == -1 ? 5900 : uri.port;
+    }
+
+    public override Gtk.Widget? get_display (int n) throws Boxes.Error {
+        window.remove (display);
+        return display;
+    }
+
+    public override void connect_it () {
+        display.open_host (host, port.to_string ());
+    }
+
+    public override void disconnect_it () {
+    }
+}
diff --git a/src/wizard.vala b/src/wizard.vala
index 49eef8e..acfc3c6 100644
--- a/src/wizard.vala
+++ b/src/wizard.vala
@@ -246,13 +246,25 @@ private class Boxes.Wizard: Boxes.UI {
                 throw new Boxes.Error.INVALID ("the URI is invalid");
 
             if (uri.scheme == "spice" || uri.scheme == "vnc") {
-                var query = new Query (uri.query_raw ?? uri.query);
-
                 source = new CollectionSource (uri.server, uri.scheme, text);
                 summary.add_property (_("Type"), uri.scheme.up ());
                 summary.add_property (_("Host"), uri.server.down ());
-                summary.add_property (_("Port"), query.get ("port"));
-                summary.add_property (_("TLS Port"), query.get ("tls-port"));
+
+                if (uri.scheme == "spice") {
+                    if (uri.query_raw == null && uri.query == null)
+                        throw new Boxes.Error.INVALID ("the Spice URI is incomplete");
+
+                    var query = new Query (uri.query_raw ?? uri.query);
+
+                    if (uri.port != -1)
+                        throw new Boxes.Error.INVALID ("the Spice URI is invalid");
+
+                    summary.add_property (_("Port"), query.get ("port"));
+                    summary.add_property (_("TLS Port"), query.get ("tls-port"));
+                } else {
+                    if (uri.port != -1)
+                        summary.add_property (_("Port"), uri.port.to_string ());
+                }
             } else
                 throw new Boxes.Error.INVALID ("Unsupported protocol");
         } else {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]