This patch merges the public & private structs from the paravirt FB
into a single struct. Since QEMU is the only consumer of this code
there is no need for the artifical pub/priv split. Merging the two
will make it possible to more tightly integrate with QEMU's event
loop and do asynchronous non-blocking negoiation with the frontend
devices (see next patch).
xen_machine_pv.c | 3
xenfb.c | 166 ++++++++++++++++++++++++++-----------------------------
xenfb.h | 16 -----
3 files changed, 82 insertions(+), 103 deletions(-)
Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
diff -r 58cc6fb7824c tools/ioemu/hw/xen_machine_pv.c
--- a/tools/ioemu/hw/xen_machine_pv.c Tue Sep 11 11:53:35 2007 -0400
+++ b/tools/ioemu/hw/xen_machine_pv.c Tue Sep 11 11:55:15 2007 -0400
@@ -53,9 +53,6 @@ static void xen_init_pv(uint64_t ram_siz
strerror(errno));
exit(1);
}
-
- /* Setup QEMU display */
- dpy_resize(ds, xenfb->width, xenfb->height);
}
QEMUMachine xenpv_machine = {
diff -r 58cc6fb7824c tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c Tue Sep 11 11:53:35 2007 -0400
+++ b/tools/ioemu/hw/xenfb.c Tue Sep 11 11:55:15 2007 -0400
@@ -22,6 +22,8 @@
// FIXME defend against malicious frontend?
+struct xenfb;
+
struct xenfb_device {
const char *devicetype;
char nodename[64]; /* backend xenstore dir */
@@ -30,16 +32,23 @@ struct xenfb_device {
enum xenbus_state state; /* backend state */
void *page; /* shared page */
evtchn_port_t port;
- struct xenfb_private *xenfb;
+ struct xenfb *xenfb;
};
-struct xenfb_private {
- struct xenfb pub;
+struct xenfb {
+ DisplayState *ds; /* QEMU graphical console state */
int evt_xch; /* event channel driver handle */
int xc; /* hypervisor interface handle */
struct xs_handle *xsh; /* xs daemon handle */
struct xenfb_device fb, kbd;
+ void *pixels; /* guest framebuffer data */
size_t fb_len; /* size of framebuffer */
+ int row_stride; /* width of one row in framebuffer */
+ int depth; /* colour depth of guest framebuffer */
+ int width; /* pixel width of guest framebuffer */
+ int height; /* pixel height of guest framebuffer */
+ int abs_pointer_wanted; /* Whether guest supports absolute pointer */
+ int button_state; /* Last seen pointer button state */
char protocol[64]; /* frontend protocol */
};
@@ -95,7 +104,7 @@ static unsigned char scancode2linux[512]
static unsigned char scancode2linux[512];
-static void xenfb_detach_dom(struct xenfb_private *);
+static void xenfb_detach_dom(struct xenfb *);
static char *xenfb_path_in_dom(struct xs_handle *xsh,
char *buf, size_t size,
@@ -176,7 +185,7 @@ static int xenfb_xs_printf(struct xs_han
static void xenfb_device_init(struct xenfb_device *dev,
const char *type,
- struct xenfb_private *xenfb)
+ struct xenfb *xenfb)
{
dev->devicetype = type;
dev->otherend_id = -1;
@@ -184,19 +193,17 @@ static void xenfb_device_init(struct xen
dev->xenfb = xenfb;
}
-int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
-{
- struct xenfb_private *xenfb = dev->xenfb;
-
+static int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
+{
dev->otherend_id = domid;
- if (!xenfb_path_in_dom(xenfb->xsh,
+ if (!xenfb_path_in_dom(dev->xenfb->xsh,
dev->otherend, sizeof(dev->otherend),
domid, "device/%s/0", dev->devicetype)) {
errno = ENOENT;
return -1;
}
- if (!xenfb_path_in_dom(xenfb->xsh,
+ if (!xenfb_path_in_dom(dev->xenfb->xsh,
dev->nodename, sizeof(dev->nodename),
0, "backend/%s/%d/0", dev->devicetype, domid)) {
errno = ENOENT;
@@ -208,7 +215,7 @@ int xenfb_device_set_domain(struct xenfb
struct xenfb *xenfb_new(void)
{
- struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
+ struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
int serrno;
int i;
@@ -239,30 +246,26 @@ struct xenfb *xenfb_new(void)
if (!xenfb->xsh)
goto fail;
- return &xenfb->pub;
+ return xenfb;
fail:
serrno = errno;
- xenfb_delete(&xenfb->pub);
+ xenfb_delete(xenfb);
errno = serrno;
return NULL;
}
/* Remove the backend area in xenbus since the framebuffer really is
going away. */
-void xenfb_teardown(struct xenfb *xenfb_pub)
-{
- struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
+void xenfb_teardown(struct xenfb *xenfb)
+{
xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
}
-void xenfb_delete(struct xenfb *xenfb_pub)
-{
- struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
+void xenfb_delete(struct xenfb *xenfb)
+{
xenfb_detach_dom(xenfb);
if (xenfb->xc >= 0)
xc_interface_close(xenfb->xc);
@@ -394,7 +397,7 @@ static void xenfb_copy_mfns(int mode, in
dst[i] = (mode == 32) ? src32[i] : src64[i];
}
-static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
+static int xenfb_map_fb(struct xenfb *xenfb, int domid)
{
struct xenfb_page *page = xenfb->fb.page;
int n_fbmfns;
@@ -466,9 +469,9 @@ static int xenfb_map_fb(struct xenfb_pri
xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
munmap(map, n_fbdirs * XC_PAGE_SIZE);
- xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
+ xenfb->pixels = xc_map_foreign_pages(xenfb->xc, domid,
PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
- if (xenfb->pub.pixels == NULL)
+ if (xenfb->pixels == NULL)
goto out;
ret = 0; /* all is fine */
@@ -483,7 +486,7 @@ static int xenfb_map_fb(struct xenfb_pri
static int xenfb_bind(struct xenfb_device *dev)
{
- struct xenfb_private *xenfb = dev->xenfb;
+ struct xenfb *xenfb = dev->xenfb;
unsigned long mfn;
evtchn_port_t evtchn;
@@ -566,17 +569,18 @@ static void xenfb_dev_fatal(struct xenfb
}
-static void xenfb_detach_dom(struct xenfb_private *xenfb)
+static void xenfb_detach_dom(struct xenfb *xenfb)
{
xenfb_unbind(&xenfb->fb);
xenfb_unbind(&xenfb->kbd);
- if (xenfb->pub.pixels) {
- munmap(xenfb->pub.pixels, xenfb->fb_len);
- xenfb->pub.pixels = NULL;
- }
-}
-
-static void xenfb_on_fb_event(struct xenfb_private *xenfb)
+ if (xenfb->pixels) {
+ munmap(xenfb->pixels, xenfb->fb_len);
+ xenfb->pixels = NULL;
+ }
+}
+
+
+static void xenfb_on_fb_event(struct xenfb *xenfb)
{
uint32_t prod, cons;
struct xenfb_page *page = xenfb->fb.page;
@@ -590,11 +594,10 @@ static void xenfb_on_fb_event(struct xen
switch (event->type) {
case XENFB_TYPE_UPDATE:
- if (xenfb->pub.update)
- xenfb->pub.update(&xenfb->pub,
- event->update.x, event->update.y,
- event->update.width,
event->update.height);
- break;
+ xenfb_guest_copy(xenfb,
+ event->update.x, event->update.y,
+ event->update.width,
event->update.height);
+ break;
}
}
mb(); /* ensure we're done with ring contents */
@@ -602,7 +605,7 @@ static void xenfb_on_fb_event(struct xen
xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
}
-static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
+static void xenfb_on_kbd_event(struct xenfb *xenfb)
{
struct xenkbd_page *page = xenfb->kbd.page;
@@ -640,7 +643,7 @@ static int xenfb_on_state_change(struct
return 0;
}
-static int xenfb_kbd_event(struct xenfb_private *xenfb,
+static int xenfb_kbd_event(struct xenfb *xenfb,
union xenkbd_in_event *event)
{
uint32_t prod;
@@ -662,9 +665,8 @@ static int xenfb_kbd_event(struct xenfb_
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;
+static int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode)
+{
union xenkbd_in_event event;
memset(&event, 0, XENKBD_IN_EVENT_SIZE);
@@ -675,9 +677,8 @@ static int xenfb_send_key(struct xenfb *
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;
+static int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y)
+{
union xenkbd_in_event event;
memset(&event, 0, XENKBD_IN_EVENT_SIZE);
@@ -688,9 +689,8 @@ static int xenfb_send_motion(struct xenf
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;
+static int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y)
+{
union xenkbd_in_event event;
memset(&event, 0, XENKBD_IN_EVENT_SIZE);
@@ -702,9 +702,9 @@ static int xenfb_send_position(struct xe
}
-static void xenfb_dispatch_channel(void *xenfb_pub)
-{
- struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static void xenfb_dispatch_channel(void *opaque)
+{
+ struct xenfb *xenfb = (struct xenfb *)opaque;
evtchn_port_t port;
port = xc_evtchn_pending(xenfb->evt_xch);
if (port == -1)
@@ -719,9 +719,9 @@ static void xenfb_dispatch_channel(void
exit(1);
}
-static void xenfb_dispatch_store(void *xenfb_pub)
-{
- struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+static void xenfb_dispatch_store(void *opaque)
+{
+ struct xenfb *xenfb = (struct xenfb *)opaque;
unsigned dummy;
char **vec;
int r;
@@ -736,9 +736,8 @@ static void xenfb_dispatch_store(void *x
}
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid, DisplayState *ds)
-{
- struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds)
+{
struct xs_handle *xsh = xenfb->xsh;
int val, serrno;
struct xenfb_page *fb_page;
@@ -794,12 +793,12 @@ int xenfb_attach_dom(struct xenfb *xenfb
/* TODO check for permitted ranges */
fb_page = xenfb->fb.page;
- xenfb->pub.depth = fb_page->depth;
- xenfb->pub.width = fb_page->width;
- xenfb->pub.height = fb_page->height;
+ xenfb->depth = fb_page->depth;
+ xenfb->width = fb_page->width;
+ xenfb->height = fb_page->height;
/* TODO check for consistency with the above */
xenfb->fb_len = fb_page->mem_length;
- xenfb->pub.row_stride = fb_page->line_length;
+ xenfb->row_stride = fb_page->line_length;
if (xenfb_map_fb(xenfb, domid) < 0)
goto error;
@@ -814,7 +813,7 @@ int xenfb_attach_dom(struct xenfb *xenfb
if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
"%d", &val) < 0)
val = 0;
- xenfb->pub.abs_pointer_wanted = val;
+ xenfb->abs_pointer_wanted = val;
/* Listen for events from xenstore */
if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL,
xenfb_dispatch_store, NULL, xenfb) < 0)
@@ -827,19 +826,18 @@ int xenfb_attach_dom(struct xenfb *xenfb
/* 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,
+ xenfb->abs_pointer_wanted,
"Xen PVFB Mouse");
- xenfb_pub->update = xenfb_guest_copy;
- xenfb_pub->user_data = ds;
+ xenfb->ds = 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);
+ xenfb);
+ dpy_resize(ds, xenfb->width, xenfb->height);
return 0;
@@ -898,11 +896,10 @@ static void xenfb_mouse_event(void *opaq
{
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);
+ dx * xenfb->ds->width / 0x7fff,
+ dy * xenfb->ds->height / 0x7fff);
else
xenfb_send_motion(xenfb, dx, dy);
@@ -924,9 +921,9 @@ static void xenfb_mouse_event(void *opaq
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)); \
+ DST_T *dst = (DST_T *)(xenfb->ds->data
\
+ + (line * xenfb->ds->linesize)
\
+ + (x * xenfb->ds->depth / 8));
\
int col; \
for (col = x ; col < w ; col++) { \
*dst = (((*src >> RRS) & RM) << RLS) | \
@@ -945,40 +942,39 @@ static void xenfb_mouse_event(void *opaq
*/
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 */
+ if (xenfb->depth == xenfb->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),
+ memcpy(xenfb->ds->data + (line * xenfb->ds->linesize) + (x *
xenfb->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) {
+ if (xenfb->ds->depth == 16) {
BLT(uint8_t, uint16_t, 5, 2, 0, 11, 5, 0, 7, 7, 3);
- } else if (ds->depth == 32) {
+ } else if (xenfb->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) {
+ if (xenfb->ds->depth == 8) {
BLT(uint16_t, uint8_t, 11, 5, 0, 5, 2, 0, 31, 63, 31);
- } else if (ds->depth == 32) {
+ } else if (xenfb->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) {
+ if (xenfb->ds->depth == 8) {
BLT(uint32_t, uint8_t, 16, 8, 0, 5, 2, 0, 255, 255,
255);
- } else if (ds->depth == 16) {
+ } else if (xenfb->ds->depth == 16) {
BLT(uint32_t, uint16_t, 16, 8, 0, 11, 5, 0, 255, 255,
255);
}
}
}
- dpy_update(ds, x, y, w, h);
+ dpy_update(xenfb->ds, x, y, w, h);
}
/* QEMU display state changed, so refresh the framebuffer copy */
diff -r 58cc6fb7824c tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h Tue Sep 11 11:53:35 2007 -0400
+++ b/tools/ioemu/hw/xenfb.h Tue Sep 11 11:55:15 2007 -0400
@@ -5,21 +5,7 @@
#include <stdbool.h>
#include <sys/types.h>
-struct xenfb
-{
- void *pixels;
-
- int row_stride;
- int depth;
- int width;
- int height;
- int abs_pointer_wanted;
- int button_state;
-
- void *user_data;
-
- void (*update)(struct xenfb *xenfb, int x, int y, int width, int
height);
-};
+struct xenfb;
struct xenfb *xenfb_new(void);
void xenfb_delete(struct xenfb *xenfb);
--
|=- 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
|