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

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



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.