[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 | 214 --------------------------------- xenfb.c | 353 +++++++++++++++++++++++++++++++++++++++++++++---------- xenfb.h | 8 - 3 files changed, 294 insertions(+), 281 deletions(-) Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> diff -r 93300915575f tools/ioemu/hw/xen_machine_pv.c --- a/tools/ioemu/hw/xen_machine_pv.c Tue Sep 11 11:53:28 2007 -0400 +++ b/tools/ioemu/hw/xen_machine_pv.c Tue Sep 11 11:53:34 2007 -0400 @@ -24,194 +24,6 @@ #include "vl.h" #include "xenfb.h" -#include <linux/input.h> - -/* - * Tables to map from scancode to Linux input layer keycode. - * Scancodes are hardware-specific. These maps assumes a - * standard AT or PS/2 keyboard which is what QEMU feeds us. - */ -static const unsigned char atkbd_set2_keycode[512] = { - - 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117, - 0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0, - 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183, - 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185, - 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, - 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85, - 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0, - 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, - 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, - 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, - 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, - 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, - 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0, - -}; - -static const unsigned char atkbd_unxlate_table[128] = { - - 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, - 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, - 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, - 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3, - 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105, - 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63, - 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, - 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 - -}; - -static unsigned char scancode2linux[512]; - -/* 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 key event from the client to the guest OS - * QEMU gives us a raw scancode from an AT / PS/2 style keyboard. - * We have to turn this into a Linux Input layer keycode. - * - * Extra complexity from the fact that with extended scancodes - * (like those produced by arrow keys) this method gets called - * twice, but we only want to send a single event. So we have to - * track the '0xe0' scancode state & collapse the extended keys - * as needed. - * - * Wish we could just send scancodes straight to the guest which - * already has code for dealing with this... - */ -static void xen_pvfb_key_event(void *opaque, int scancode) -{ - static int extended = 0; - int down = 1; - if (scancode == 0xe0) { - extended = 1; - return; - } else if (scancode & 0x80) { - scancode &= 0x7f; - down = 0; - } - if (extended) { - scancode |= 0x80; - extended = 0; - } - xenfb_send_key(opaque, down, scancode2linux[scancode]); -} - -/* - * Send a mouse event from the client to the guest OS - * - * The QEMU mouse can be in either relative, or absolute mode. - * Movement is sent separately from button state, which has to - * be encoded as virtual key events. We also don't actually get - * given any button up/down events, so have to track changes in - * the button state. - */ -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 = 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 */ -/* XXX - can we optimize this, or the next func at all ? */ -void xen_pvfb_update(void *opaque) -{ - struct xenfb *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) -{ - xen_pvfb_update(opaque); -} - -/* 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 * - a virtual framebuffer @@ -226,14 +38,6 @@ static void xen_init_pv(uint64_t ram_siz { struct xenfb *xenfb; extern int domid; - int i; - - /* Prepare scancode mapping table */ - for (i = 0; i < 128; i++) { - scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; - scancode2linux[i | 0x80] = - atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; - } /* Prepare PVFB state */ xenfb = xenfb_new(); @@ -244,27 +48,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_key_event, 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); diff -r 93300915575f tools/ioemu/hw/xenfb.c --- a/tools/ioemu/hw/xenfb.c Tue Sep 11 11:53:28 2007 -0400 +++ b/tools/ioemu/hw/xenfb.c Tue Sep 11 11:53:34 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? @@ -43,6 +43,58 @@ struct xenfb_private { char protocol[64]; /* frontend protocol */ }; +/* Functions which tie the PVFB into the QEMU device model */ +static void xenfb_key_event(void *opaque, int keycode); +static void xenfb_mouse_event(void *opaque, + int dx, int dy, int dz, int button_state); +static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h); +static void xenfb_update(void *opaque); +static void xenfb_invalidate(void *opaque); +static void xenfb_screen_dump(void *opaque, const char *name); + +/* + * Tables to map from scancode to Linux input layer keycode. + * Scancodes are hardware-specific. These maps assumes a + * standard AT or PS/2 keyboard which is what QEMU feeds us. + */ +static const unsigned char atkbd_set2_keycode[512] = { + + 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117, + 0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0, + 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183, + 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185, + 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, + 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85, + 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0, + 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, + 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, + 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, + 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, + 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, + 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0, + +}; + +static const unsigned char atkbd_unxlate_table[128] = { + + 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, + 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, + 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, + 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3, + 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105, + 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63, + 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, + 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 + +}; + +static unsigned char scancode2linux[512]; + + static void xenfb_detach_dom(struct xenfb_private *); static char *xenfb_path_in_dom(struct xs_handle *xsh, @@ -158,9 +210,17 @@ struct xenfb *xenfb_new(void) { struct xenfb_private *xenfb = malloc(sizeof(*xenfb)); int serrno; + int i; if (xenfb == NULL) return NULL; + + /* Prepare scancode mapping table */ + for (i = 0; i < 128; i++) { + scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; + scancode2linux[i | 0x80] = + atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; + } memset(xenfb, 0, sizeof(*xenfb)); xenfb->evt_xch = xenfb->xc = -1; @@ -580,6 +640,68 @@ 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); +} + + static void xenfb_dispatch_channel(void *xenfb_pub) { struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; @@ -614,7 +736,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; @@ -702,6 +824,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_key_event, 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: @@ -713,66 +852,154 @@ 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); -} +/* + * Send a key event from the client to the guest OS + * QEMU gives us a raw scancode from an AT / PS/2 style keyboard. + * We have to turn this into a Linux Input layer keycode. + * + * Extra complexity from the fact that with extended scancodes + * (like those produced by arrow keys) this method gets called + * twice, but we only want to send a single event. So we have to + * track the '0xe0' scancode state & collapse the extended keys + * as needed. + * + * Wish we could just send scancodes straight to the guest which + * already has code for dealing with this... + */ +static void xenfb_key_event(void *opaque, int scancode) +{ + static int extended = 0; + int down = 1; + if (scancode == 0xe0) { + extended = 1; + return; + } else if (scancode & 0x80) { + scancode &= 0x7f; + down = 0; + } + if (extended) { + scancode |= 0x80; + extended = 0; + } + xenfb_send_key(opaque, down, scancode2linux[scancode]); +} + +/* + * Send a mouse event from the client to the guest OS + * + * The QEMU mouse can be in either relative, or absolute mode. + * Movement is sent separately from button state, which has to + * be encoded as virtual key events. We also don't actually get + * given any button up/down events, so have to track changes in + * the button state. + */ +static void xenfb_mouse_event(void *opaque, + int dx, int dy, int dz, int button_state) +{ + int i; + struct xenfb *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. + * When shifting between colour depths we preserve the MSB. + */ +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 */ +/* XXX - can we optimize this, or the next func at all ? */ +static void xenfb_update(void *opaque) +{ + struct xenfb *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 = opaque; + xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height); +} + +/* Screen dump is not used in Xen, so no need to impl this....yet */ +static void xenfb_screen_dump(void *opaque, const char *name) { } + + /* * Local variables: * c-indent-level: 8 diff -r 93300915575f tools/ioemu/hw/xenfb.h --- a/tools/ioemu/hw/xenfb.h Tue Sep 11 11:53:28 2007 -0400 +++ b/tools/ioemu/hw/xenfb.h Tue Sep 11 11:53:34 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 |