[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |