qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)


From: Daniel P. Berrange
Subject: Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
Date: Wed, 1 Jul 2009 17:32:37 +0100
User-agent: Mutt/1.4.1i

If anyone wants to actually try this code out, the following patch is
a quick proof of concept hack against GTK-VNC[1] and enables a single data
stream for device 'serial0' just printing the received data to stdout.

eg, start QEMU with

  ./i386-softmmu/qemu -kernel ~/vmlinuz  -serial file:foo.log -append 
'console=ttyS0' -vnc :1

And then start GTK-VNC with

  ./examples/gvncviewer localhost:1

If all goes to plan, gvncviewer should output the kernel boot messages,
and QEMU will be saving them in 'foo.log' as per its config.

Regards,
Daniel

[1] http://git.gnome.org/cgit/gtk-vnc/

diff --git a/src/gvnc.c b/src/gvnc.c
index c3b3163..7cafa0e 100644
--- a/src/gvnc.c
+++ b/src/gvnc.c
@@ -2144,6 +2144,39 @@ static void gvnc_ext_key_event(struct gvnc *gvnc)
        gvnc->keycode_map = x_keycode_to_pc_keycode_map();
 }
 
+static void gvnc_stream_event(struct gvnc *gvnc, int deleted)
+{
+       int n_name = gvnc_read_u32(gvnc);
+       char *name;
+       if (gvnc->has_error)
+               return;
+       if (n_name > 4096) {
+               gvnc->has_error = TRUE;
+               return;
+       }
+       name = g_new(char, n_name + 1);
+       gvnc_read(gvnc, name, n_name);
+       name[n_name] = '\0';
+
+       fprintf(stderr, "Got stream %s '%s'\n", deleted ? "del" : "add", name);
+
+       if (strcmp(name, "serial0") == 0) {
+               gvnc_write_u8(gvnc, 255);
+               gvnc_write_u8(gvnc, 2);
+               if (deleted) {
+                       gvnc_write_u8(gvnc, 1);
+                       gvnc_write_u8(gvnc, 1); /* XXX id */
+               } else {
+                       gvnc_write_u8(gvnc, 0);
+                       gvnc_write_u32(gvnc, strlen(name));
+                       gvnc_write(gvnc, name, strlen(name));
+               }
+               gvnc_flush(gvnc);
+       }
+
+       free(name);
+}
+
 static void gvnc_framebuffer_update(struct gvnc *gvnc, int32_t etype,
                                    uint16_t x, uint16_t y,
                                    uint16_t width, uint16_t height)
@@ -2195,6 +2228,10 @@ static void gvnc_framebuffer_update(struct gvnc *gvnc, 
int32_t etype,
        case GVNC_ENCODING_EXT_KEY_EVENT:
                gvnc_ext_key_event(gvnc);
                break;
+       case GVNC_ENCODING_STREAM_EVENT:
+               fprintf(stderr, "Stream event\n");
+               gvnc_stream_event(gvnc, x);
+               break;
        default:
                GVNC_DEBUG("Received an unknown encoding type: %d\n", etype);
                gvnc->has_error = TRUE;
@@ -2295,6 +2332,58 @@ gboolean gvnc_server_message(struct gvnc *gvnc)
                gvnc_server_cut_text(gvnc, data, n_text);
                g_free(data);
        }       break;
+       case 255: {
+               int subtype;
+               subtype = gvnc_read_u8(gvnc);
+               if (subtype != 2) {
+                       GVNC_DEBUG("Unknown aliguori message type %d\n", 
subtype);
+                       gvnc->has_error = TRUE;
+                       break;
+               }
+               switch (gvnc_read_u8(gvnc)) {
+               case 0: {
+                       int id;
+                       int n_name;
+                       char *name;
+                       id = gvnc_read_u32(gvnc);
+                       n_name = gvnc_read_u32(gvnc);
+                       if (n_name > 4096) {
+                               GVNC_DEBUG("Stream name too long %d", n_name);
+                               gvnc->has_error = TRUE;
+                               break;
+                       }
+                       name = g_new(char, n_name + 1);
+                       gvnc_read(gvnc, name, n_name);
+                       name[n_name] = 0;
+                       fprintf(stderr, "Stream on %d %s\n", id, name);
+                       g_free(name);
+               }       break;
+
+               case 1: {
+                       int id;
+                       id = gvnc_read_u32(gvnc);
+                       fprintf(stderr, "Stream off %d\n", id);
+               }       break;
+
+               case 2: {
+                       int id;
+                       int n_data;
+                       char *data;
+                       id = gvnc_read_u32(gvnc);
+                       n_data = gvnc_read_u32(gvnc);
+                       if (n_data > 4096) {
+                               GVNC_DEBUG("Stream data too long %d", n_data);
+                               gvnc->has_error = TRUE;
+                               break;
+                       }
+                       data = g_new(char, n_data + 1);
+                       gvnc_read(gvnc, data, n_data);
+                       data[n_data] = 0;
+                       fprintf(stderr, "%s", data);
+                       g_free(data);
+               }       break;
+               }
+       }       break;
        default:
                GVNC_DEBUG("Received an unknown message: %u\n", msg);
                gvnc->has_error = TRUE;
diff --git a/src/gvnc.h b/src/gvnc.h
index f748de0..4c3d214 100644
--- a/src/gvnc.h
+++ b/src/gvnc.h
@@ -117,6 +117,7 @@ typedef enum {
 
        GVNC_ENCODING_POINTER_CHANGE = -257,
        GVNC_ENCODING_EXT_KEY_EVENT = -258,
+       GVNC_ENCODING_STREAM_EVENT = -260,
 } gvnc_encoding;
 
 typedef enum {
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 6c7b662..da42434 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -1306,6 +1306,7 @@ static void *vnc_coroutine(void *opaque)
        /* this order is extremely important! */
        int32_t encodings[] = { GVNC_ENCODING_TIGHT_JPEG5,
                                GVNC_ENCODING_TIGHT,
+                               GVNC_ENCODING_STREAM_EVENT,
                                GVNC_ENCODING_EXT_KEY_EVENT,
                                GVNC_ENCODING_DESKTOP_RESIZE,
                                 GVNC_ENCODING_WMVi,


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




reply via email to

[Prev in Thread] Current Thread [Next in Thread]