⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xenfb.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (ret)		return; /* Still waiting */	if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename, "feature-abs-pointer", "1")) {		xenfb_shutdown(dev->xenfb);		exit(1);	}	fprintf(stderr, "FB: Waiting for FB backend creation\n");	xenfb_wait_for_backend(&dev->xenfb->fb, xenfb_backend_created_fb);}/* Callback invoked while waiting for FB backend to change * to the created state */static void xenfb_backend_created_fb(void *opaque){	struct xenfb_device *dev = (struct xenfb_device *)opaque;	int ret = xenfb_backend_created(dev);	if (ret < 0) {		xenfb_shutdown(dev->xenfb);		exit(1);	}	if (ret)		return; /* Still waiting */	fprintf(stderr, "FB: Waiting for KBD frontend initialization\n");	xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_initialized_kbd);}/* Callback invoked while waiting for KBD frontend to change * to the initialized state */static void xenfb_frontend_initialized_kbd(void *opaque){	struct xenfb_device *dev = (struct xenfb_device *)opaque;	int ret = xenfb_frontend_initialized(dev);	if (ret < 0) {		xenfb_shutdown(dev->xenfb);		exit(1);	}	if (ret)		return; /* Still waiting */        fprintf(stderr, "FB: Waiting for FB frontend initialization\n");	xenfb_wait_for_frontend(&dev->xenfb->fb, xenfb_frontend_initialized_fb);}/* Callback invoked while waiting for FB frontend to change * to the initialized state */static void xenfb_frontend_initialized_fb(void *opaque){	struct xenfb_device *dev = (struct xenfb_device *)opaque;	int ret = xenfb_frontend_initialized(dev);	if (ret < 0) {		xenfb_shutdown(dev->xenfb);		exit(1);	}	if (ret)		return; /* Still waiting */	if (xenfb_read_frontend_fb_config(dev->xenfb)) {		xenfb_shutdown(dev->xenfb);	        exit(1);	}        fprintf(stderr, "FB: Waiting for KBD frontend connection\n");	xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_connected_kbd);}/* Callback invoked while waiting for KBD frontend to change * to the connected state */static void xenfb_frontend_connected_kbd(void *opaque){	struct xenfb_device *dev = (struct xenfb_device *)opaque;	int ret = xenfb_frontend_connected(dev);	if (ret < 0) {		xenfb_shutdown(dev->xenfb);		exit(1);	}	if (ret)		return; /* Still waiting */	if (xenfb_read_frontend_kbd_config(dev->xenfb) < 0) {		xenfb_shutdown(dev->xenfb);	        exit(1);	}	xenfb_register_console(dev->xenfb);}/**************************************************************** * * Helper functions for checking state of frontend/backend devices * ****************************************************************//* Helper to determine if a frontend device is in Connected state */static int xenfb_frontend_connected(struct xenfb_device *dev){	unsigned int state;	unsigned int dummy;	char **vec;	vec = xs_read_watch(dev->xenfb->xsh, &dummy);	if (!vec)		return -1;	free(vec);	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);	if (!((1 <<state) & ((1 << XenbusStateUnknown) |			     (1 << XenbusStateConnected)))) {		fprintf(stderr, "FB: Carry on waiting\n");		return 1;	}	/* Don't unwatch frontend - we need to detect shutdown */	/*xs_unwatch(dev->xenfb->xsh, dev->otherend, "");*/	switch (state) {	case XenbusStateConnected:		break;	default:		return -1;	}	return 0;}/* Helper to determine if a frontend device is in Initialized state */static int xenfb_frontend_initialized(struct xenfb_device *dev){	unsigned int state;	unsigned int dummy;	char **vec;	vec = xs_read_watch(dev->xenfb->xsh, &dummy);	if (!vec)		return -1;	free(vec);	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);	if (!((1 << state) & ((1 << XenbusStateUnknown)			      | (1 << XenbusStateInitialised)#if 1 /* TODO fudging state to permit restarting; to be removed */			      | (1 << XenbusStateConnected)#endif			      ))) {		fprintf(stderr, "FB: Carry on waiting\n");		return 1;	}	xs_unwatch(dev->xenfb->xsh, dev->otherend, "");	switch (state) {#if 1	case XenbusStateConnected:                printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */#endif        case XenbusStateInitialised:                break;        default:                return -1;        }	if (xenfb_bind(dev) < 0)		return -1;	return 0;}/* Helper to determine if a backend device is in Created state */static int xenfb_backend_created(struct xenfb_device *dev){	unsigned int state;	unsigned int dummy;	char **vec;	vec = xs_read_watch(dev->xenfb->xsh, &dummy);	if (!vec)		return -1;	free(vec);	state = xenfb_read_state(dev->xenfb->xsh, dev->nodename);	if (!((1 <<state) & ((1 << XenbusStateUnknown)			     | (1 << XenbusStateInitialising)			     | (1 << XenbusStateClosed)#if 1 /* TODO fudging state to permit restarting; to be removed */			     | (1 << XenbusStateInitWait)			     | (1 << XenbusStateConnected)			     | (1 << XenbusStateClosing)#endif			     ))) {		fprintf(stderr, "FB: Carry on waiting\n");		return 1;	}	xs_unwatch(dev->xenfb->xsh, dev->nodename, "");        switch (state) {#if 1        case XenbusStateInitWait:        case XenbusStateConnected:                printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */#endif        case XenbusStateInitialising:        case XenbusStateClosing:        case XenbusStateClosed:                break;        default:                fprintf(stderr, "Wrong state %d\n", state);                return -1;        }        xenfb_switch_state(dev, XenbusStateInitWait);        if (xenfb_hotplug(dev) < 0)                return -1;        return 0;}/**************************************************************** *  * QEMU device model integration functions * ****************************************************************//*  * 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;    if (xenfb->abs_pointer_wanted)	    xenfb_send_position(xenfb,                                dx * (xenfb->ds->width - 1) / 0x7fff,                                dy * (xenfb->ds->height - 1) / 0x7fff,				dz);    else	    xenfb_send_motion(xenfb, dx, dy, dz);    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 *)(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) |                      \                (((*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){    int line;    if (xenfb->depth == xenfb->ds->depth) { /* Perfect match can use fast path */        for (line = y ; line < (y+h) ; line++) {            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 (xenfb->ds->depth == 16) {                BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);            } 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 (xenfb->ds->depth == 8) {                BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);            } 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 (xenfb->ds->depth == 8) {                BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 255);            } else if (xenfb->ds->depth == 16) {                BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 255);            }        }    }    dpy_update(xenfb->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) { }/* Register a QEMU graphical console, and key/mouse handler, * connecting up their events to the frontend */static int xenfb_register_console(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->abs_pointer_wanted,  				     "Xen PVFB Mouse");    	/* Tell QEMU to allocate a graphical console */	graphic_console_init(xenfb->ds,			     xenfb_update,			     xenfb_invalidate,			     xenfb_screen_dump,			     xenfb);	dpy_resize(xenfb->ds, xenfb->width, xenfb->height);	if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)	        return -1;	if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)		return -1;        fprintf(stderr, "Xen Framebuffer registered\n");        return 0;}/* * Local variables: *  c-indent-level: 8 *  c-basic-offset: 8 *  tab-width: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -