WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] PATCH: 5/10: Refactor QEMU console integration

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: Re: [Xen-devel] PATCH: 5/10: Refactor QEMU console integration
From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>
Date: Wed, 22 Aug 2007 23:31:09 +0100
Delivery-date: Wed, 22 Aug 2007 15:32:03 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20070822222653.GR18061@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070822222653.GR18061@xxxxxxxxxx>
Reply-to: "Daniel P. Berrange" <berrange@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.1i
This patch moves a bunch of code out of the xen_machine_pv.c file and into
the xenfb.c file. This is simply a re-factoring to facilitate the two patches
which follow.


 xen_machine_pv.c |  132 ----------------------------
 xenfb.c          |  254 +++++++++++++++++++++++++++++++++++++++++--------------
 xenfb.h          |    8 -
 3 files changed, 195 insertions(+), 199 deletions(-)


   Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>

Dan.


diff -r c2aa6c7965a3 tools/ioemu/hw/xen_machine_pv.c
--- a/tools/ioemu/hw/xen_machine_pv.c   Wed Aug 15 14:17:30 2007 -0400
+++ b/tools/ioemu/hw/xen_machine_pv.c   Tue Aug 21 22:03:27 2007 -0400
@@ -24,117 +24,6 @@
 
 #include "vl.h"
 #include "xenfb.h"
-#include <linux/input.h>
-
-/* A convenient function for munging pixels between different depths */
-#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
-    for (line = y ; line < h ; line++) {                                \
-        SRC_T *src = (SRC_T *)(xenfb->pixels + (line*xenfb->row_stride) + 
(x*xenfb->depth/8)); \
-        DST_T *dst = (DST_T *)(ds->data + (line*ds->linesize) + 
(x*ds->depth/8)); \
-        int col;                                                        \
-        for (col = x ; col < w ; col++) {                               \
-            *dst = (((*src >> RRS)&RM) << RLS) |                        \
-                (((*src >> GRS)&GM) << GLS) |                           \
-                (((*src >> GRS)&BM) << BLS);                            \
-            src++;                                                      \
-            dst++;                                                      \
-        }                                                               \
-    }
-
-
-/* This copies data from the guest framebuffer region, into QEMU's copy
- * NB. QEMU's copy is stored in the pixel format of a) the local X server (SDL 
case)
- * or b) the current VNC client pixel format.
- */
-static void xen_pvfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int 
h)
-{
-    DisplayState *ds = (DisplayState *)xenfb->user_data;
-    int line;
-
-    if (xenfb->depth == ds->depth) { /* Perfect match can use fast path */
-        for (line = y ; line < (y+h) ; line++) {
-            memcpy(ds->data + (line * ds->linesize) + (x*ds->depth/8),
-                   xenfb->pixels + (line*xenfb->row_stride) + 
(x*xenfb->depth/8),
-                   w * xenfb->depth/8);
-        }
-    } else { /* Mismatch requires slow pixel munging */
-        if (xenfb->depth == 8) {
-            /* 8 bit source == r:3 g:3 b:2 */
-            if (ds->depth == 16) {
-                BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
-            } else if (ds->depth == 32) {
-                BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
-            }
-        } else if (xenfb->depth == 16) {
-            /* 16 bit source == r:5 g:6 b:5 */
-            if (ds->depth == 8) {
-                BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
-            } else if (ds->depth == 32) {
-                BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
-            }
-        } else if (xenfb->depth == 32) {
-            /* 32 bit source == r:8 g:8 b:8 (padding:8) */
-            if (ds->depth == 8) {
-                BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 
255);
-            } else if (ds->depth == 16) {
-                BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 
255);
-            }
-        }
-    }
-    dpy_update(ds, x, y, w, h);
-}
-
-
-/* Send a keypress from the client to the guest OS */
-static void xen_pvfb_put_keycode(void *opaque, int keycode)
-{
-    struct xenfb *xenfb = (struct xenfb*)opaque;
-    xenfb_send_key(xenfb, keycode & 0x80 ? 0 : 1, keycode & 0x7f);
-}
-
-/* Send a mouse event from the client to the guest OS */
-static void xen_pvfb_mouse_event(void *opaque,
-                                 int dx, int dy, int dz, int button_state)
-{
-    static int old_state = 0;
-    int i;
-    struct xenfb *xenfb = (struct xenfb*)opaque;
-    DisplayState *ds = (DisplayState *)xenfb->user_data;
-    if (xenfb->abs_pointer_wanted)
-        xenfb_send_position(xenfb,
-                            dx*ds->width/0x7fff,
-                            dy*ds->height/0x7fff);
-    else
-        xenfb_send_motion(xenfb, dx, dy);
-
-       for (i = 0 ; i < 8 ; i++) {
-               int lastDown = old_state & (1 << i);
-               int down = button_state & (1 << i);
-               if (down == lastDown)
-                       continue;
-
-               if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
-                       return;
-       }
-    old_state = button_state;
-}
-
-/* QEMU display state changed, so refresh the framebuffer copy */
-void xen_pvfb_update(void *opaque)
-{
-    struct xenfb *xenfb = (struct xenfb *)opaque;
-    xen_pvfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
-}
-
-/* QEMU display state changed, so refresh the framebuffer copy */
-void xen_pvfb_invalidate(void *opaque)
-{
-    struct xenfb *xenfb = (struct xenfb *)opaque;
-    xen_pvfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
-}
-
-/* Screen dump is not used in Xen, so no need to impl this ? */
-void xen_pvfb_screen_dump(void *opaque, const char *name) { }
 
 
 /* The Xen PV machine currently provides
@@ -160,30 +49,11 @@ static void xen_init_pv(uint64_t ram_siz
     }
 
     /* Talk to the guest */
-    if (xenfb_attach_dom(xenfb, domid) < 0) {
+    if (xenfb_attach_dom(xenfb, domid, ds) < 0) {
         fprintf(stderr, "Could not connect to domain (%s)\n",
                 strerror(errno));
         exit(1);
     }
-    xenfb->update = xen_pvfb_guest_copy;
-    xenfb->user_data = ds;
-
-    /* Tell QEMU to allocate a graphical console */
-    graphic_console_init(ds,
-                         xen_pvfb_update,
-                         xen_pvfb_invalidate,
-                         xen_pvfb_screen_dump,
-                         xenfb);
-
-    /* Register our keyboard & mouse handlers */
-    qemu_add_kbd_event_handler(xen_pvfb_put_keycode, xenfb);
-    qemu_add_mouse_event_handler(xen_pvfb_mouse_event, xenfb,
-                                 xenfb->abs_pointer_wanted,
-                                 "Xen PVFB Mouse");
-
-
-    /* Setup QEMU display */
-    dpy_resize(ds, xenfb->width, xenfb->height);
 }
 
 QEMUMachine xenpv_machine = {
diff -r c2aa6c7965a3 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Wed Aug 15 14:17:30 2007 -0400
+++ b/tools/ioemu/hw/xenfb.c    Tue Aug 21 22:04:25 2007 -0400
@@ -16,8 +16,8 @@
 #include <string.h>
 #include <time.h>
 #include <xs.h>
-
-#include "vl.h"
+#include <linux/input.h>
+
 #include "xenfb.h"
 
 // FIXME defend against malicious frontend?
@@ -586,6 +586,177 @@ static int xenfb_on_state_change(struct 
        return 0;
 }
 
+static int xenfb_kbd_event(struct xenfb_private *xenfb,
+                          union xenkbd_in_event *event)
+{
+       uint32_t prod;
+       struct xenkbd_page *page = xenfb->kbd.page;
+
+       if (xenfb->kbd.state != XenbusStateConnected)
+               return 0;
+
+       prod = page->in_prod;
+       if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
+               errno = EAGAIN;
+               return -1;
+       }
+
+       mb();                   /* ensure ring space available */
+       XENKBD_IN_RING_REF(page, prod) = *event;
+       wmb();                  /* ensure ring contents visible */
+       page->in_prod = prod + 1;
+       return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
+}
+
+static int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
+{
+       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+       union xenkbd_in_event event;
+
+       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+       event.type = XENKBD_TYPE_KEY;
+       event.key.pressed = down ? 1 : 0;
+       event.key.keycode = keycode;
+
+       return xenfb_kbd_event(xenfb, &event);
+}
+
+static int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
+{
+       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+       union xenkbd_in_event event;
+
+       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+       event.type = XENKBD_TYPE_MOTION;
+       event.motion.rel_x = rel_x;
+       event.motion.rel_y = rel_y;
+
+       return xenfb_kbd_event(xenfb, &event);
+}
+
+static int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
+{
+       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+       union xenkbd_in_event event;
+
+       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+       event.type = XENKBD_TYPE_POS;
+       event.pos.abs_x = abs_x;
+       event.pos.abs_y = abs_y;
+
+       return xenfb_kbd_event(xenfb, &event);
+}
+
+/* Send a keypress from the client to the guest OS */
+static void xenfb_put_keycode(void *opaque, int keycode)
+{
+       struct xenfb *xenfb = (struct xenfb*)opaque;
+       xenfb_send_key(xenfb, keycode & 0x80 ? 0 : 1, keycode & 0x7f);
+}
+
+/* Send a mouse event from the client to the guest OS */
+static void xenfb_mouse_event(void *opaque,
+                             int dx, int dy, int dz, int button_state)
+{
+       int i;
+       struct xenfb *xenfb = (struct xenfb*)opaque;
+       DisplayState *ds = (DisplayState *)xenfb->user_data;
+       if (xenfb->abs_pointer_wanted)
+               xenfb_send_position(xenfb,
+                                   dx*ds->width/0x7fff,
+                                   dy*ds->height/0x7fff);
+       else
+               xenfb_send_motion(xenfb, dx, dy);
+
+       for (i = 0 ; i < 8 ; i++) {
+               int lastDown = xenfb->button_state & (1 << i);
+               int down = button_state & (1 << i);
+               if (down == lastDown)
+                       continue;
+
+               if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
+                       return;
+       }
+       xenfb->button_state = button_state;
+}
+
+/* A convenient function for munging pixels between different depths */
+#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
+       for (line = y ; line < h ; line++) {                            \
+               SRC_T *src = (SRC_T *)(xenfb->pixels + (line*xenfb->row_stride) 
+ (x*xenfb->depth/8)); \
+               DST_T *dst = (DST_T *)(ds->data + (line*ds->linesize) + 
(x*ds->depth/8)); \
+               int col;                                                \
+               for (col = x ; col < w ; col++) {                       \
+                       *dst = (((*src >> RRS)&RM) << RLS) |            \
+                               (((*src >> GRS)&GM) << GLS) |           \
+                               (((*src >> GRS)&BM) << BLS);            \
+                       src++;                                          \
+                       dst++;                                          \
+               }                                                       \
+       }
+
+
+/* This copies data from the guest framebuffer region, into QEMU's copy
+ * NB. QEMU's copy is stored in the pixel format of a) the local X server (SDL 
case)
+ * or b) the current VNC client pixel format.
+ */
+static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
+{
+       DisplayState *ds = (DisplayState *)xenfb->user_data;
+       int line;
+
+       if (xenfb->depth == ds->depth) { /* Perfect match can use fast path */
+               for (line = y ; line < (y+h) ; line++) {
+                       memcpy(ds->data + (line * ds->linesize) + 
(x*ds->depth/8),
+                              xenfb->pixels + (line*xenfb->row_stride) + 
(x*xenfb->depth/8),
+                              w * xenfb->depth/8);
+               }
+       } else { /* Mismatch requires slow pixel munging */
+               if (xenfb->depth == 8) {
+                       /* 8 bit source == r:3 g:3 b:2 */
+                       if (ds->depth == 16) {
+                               BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   
7, 7, 3);
+                       } else if (ds->depth == 32) {
+                               BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   
7, 7, 3);
+                       }
+               } else if (xenfb->depth == 16) {
+                       /* 16 bit source == r:5 g:6 b:5 */
+                       if (ds->depth == 8) {
+                               BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,  
  31, 63, 31);
+                       } else if (ds->depth == 32) {
+                               BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0, 
  31, 63, 31);
+                       }
+               } else if (xenfb->depth == 32) {
+                       /* 32 bit source == r:8 g:8 b:8 (padding:8) */
+                       if (ds->depth == 8) {
+                               BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,  
  255, 255, 255);
+                       } else if (ds->depth == 16) {
+                               BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0, 
  255, 255, 255);
+                       }
+               }
+       }
+       dpy_update(ds, x, y, w, h);
+}
+
+/* QEMU display state changed, so refresh the framebuffer copy */
+static void xenfb_update(void *opaque)
+{
+       struct xenfb *xenfb = (struct xenfb *)opaque;
+       xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+}
+
+/* QEMU display state changed, so refresh the framebuffer copy */
+static void xenfb_invalidate(void *opaque)
+{
+       struct xenfb *xenfb = (struct xenfb *)opaque;
+       xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+}
+
+/* Screen dump is not used in Xen, so no need to impl this ? */
+static void xenfb_screen_dump(void *opaque, const char *name) { }
+
+
+
 static void xenfb_dispatch_channel(void *xenfb_pub)
 {
        struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
@@ -620,7 +791,7 @@ static void xenfb_dispatch_store(void *x
 }
 
 
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
+int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid, DisplayState *ds)
 {
        struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
        struct xs_handle *xsh = xenfb->xsh;
@@ -708,6 +879,23 @@ int xenfb_attach_dom(struct xenfb *xenfb
        if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, 
xenfb_dispatch_channel, NULL, xenfb) < 0)
                goto error;
 
+       /* Register our keyboard & mouse handlers */
+       qemu_add_kbd_event_handler(xenfb_put_keycode, xenfb);
+       qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
+                                    xenfb_pub->abs_pointer_wanted,
+                                    "Xen PVFB Mouse");
+
+       xenfb_pub->update = xenfb_guest_copy;
+       xenfb_pub->user_data = ds;
+
+       /* Tell QEMU to allocate a graphical console */
+       graphic_console_init(ds,
+                            xenfb_update,
+                            xenfb_invalidate,
+                            xenfb_screen_dump,
+                            xenfb_pub);
+       dpy_resize(ds, xenfb_pub->width, xenfb_pub->height);
+
        return 0;
 
  error:
@@ -719,66 +907,6 @@ int xenfb_attach_dom(struct xenfb *xenfb
         return -1;
 }
 
-static int xenfb_kbd_event(struct xenfb_private *xenfb,
-                          union xenkbd_in_event *event)
-{
-       uint32_t prod;
-       struct xenkbd_page *page = xenfb->kbd.page;
-
-       if (xenfb->kbd.state != XenbusStateConnected)
-               return 0;
-
-       prod = page->in_prod;
-       if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
-               errno = EAGAIN;
-               return -1;
-       }
-
-       mb();                   /* ensure ring space available */
-       XENKBD_IN_RING_REF(page, prod) = *event;
-       wmb();                  /* ensure ring contents visible */
-       page->in_prod = prod + 1;
-       return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       union xenkbd_in_event event;
-
-       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-       event.type = XENKBD_TYPE_KEY;
-       event.key.pressed = down ? 1 : 0;
-       event.key.keycode = keycode;
-
-       return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       union xenkbd_in_event event;
-
-       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-       event.type = XENKBD_TYPE_MOTION;
-       event.motion.rel_x = rel_x;
-       event.motion.rel_y = rel_y;
-
-       return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       union xenkbd_in_event event;
-
-       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-       event.type = XENKBD_TYPE_POS;
-       event.pos.abs_x = abs_x;
-       event.pos.abs_y = abs_y;
-
-       return xenfb_kbd_event(xenfb, &event);
-}
 /*
  * Local variables:
  *  c-indent-level: 8
diff -r c2aa6c7965a3 tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h    Wed Aug 15 14:17:30 2007 -0400
+++ b/tools/ioemu/hw/xenfb.h    Tue Aug 21 22:03:27 2007 -0400
@@ -1,6 +1,7 @@
 #ifndef _XENFB_H_
 #define _XENFB_H_
 
+#include "vl.h"
 #include <stdbool.h>
 #include <sys/types.h>
 
@@ -13,6 +14,7 @@ struct xenfb
        int width;
        int height;
        int abs_pointer_wanted;
+       int button_state;
 
        void *user_data;
 
@@ -23,10 +25,6 @@ void xenfb_delete(struct xenfb *xenfb);
 void xenfb_delete(struct xenfb *xenfb);
 void xenfb_teardown(struct xenfb *xenfb);
 
-int xenfb_attach_dom(struct xenfb *xenfb, int domid);
-
-int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
-int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
-int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
+int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds);
 
 #endif

-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel