static int xenfb_bind(struct xenfb_device *dev) { struct xenfb *xenfb = dev->xenfb; unsigned long mfn; evtchn_port_t evtchn; if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu", &mfn) < 0) return -1; if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u", &evtchn) < 0) return -1; dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch, dev->otherend_id, evtchn); if (dev->port == -1) return -1; dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id, XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn); if (dev->page == NULL) return -1; return 0; }
/* Process the frontend framebuffer config */ static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) { struct xenfb_page *fb_page; int val; int videoram; if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update", "%d", &val) < 0) val = 0; if (!val) { fprintf(stderr, "feature-update not supported\n"); errno = ENOTSUP; return -1; } if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "protocol", "%63s", xenfb->protocol) < 0) xenfb->protocol[0] = '\0'; xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1"); xenfb->refresh_period = -1; if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d", &videoram) < 0) videoram = 0; fb_page = xenfb->fb.page; if (xenfb_configure_fb(xenfb, videoram * 1024 * 1024U, fb_page->width, fb_page->height, fb_page->depth, fb_page->mem_length, 0, fb_page->line_length) < 0) { errno = EINVAL; return -1; } if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0) return -1; /* Indicate we have the frame buffer resize feature */ xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "feature-resize", "1"); /* Tell kbd pointer the screen geometry */ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "width", "%d", xenfb->width); xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "height", "%d", xenfb->height); if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected)) return -1; if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected)) return -1; return 0; }
/* Process the frontend keyboard config */ static int xenfb_read_frontend_kbd_config(struct xenfb *xenfb) { int val; if (xenfb_xs_scanf1(xenfb->xsh, xenfb->kbd.otherend, "request-abs-pointer", "%d", &val) < 0) val = 0; xenfb->abs_pointer_wanted = val; return 0; }
static enum xenbus_state xenfb_read_state(struct xs_handle *xsh, const char *dir) { int ret, state; ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state); if (ret < 0) return XenbusStateUnknown; if ((unsigned)state > XenbusStateClosed) state = XenbusStateUnknown; return state; }
/* Process the frontend framebuffer config */ static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) { struct xenfb_page *fb_page; int val; if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update", "%d", &val) < 0) val = 0; if (!val) { fprintf(stderr, "feature-update not supported\n"); errno = ENOTSUP; return -1; } if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "protocol", "%63s", xenfb->protocol) < 0) xenfb->protocol[0] = '\0'; xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1"); /* TODO check for permitted ranges */ fb_page = xenfb->fb.page; 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->row_stride = fb_page->line_length; fprintf(stderr, "Framebuffer depth %d width %d height %d line %d\n", fb_page->depth, fb_page->width, fb_page->height, fb_page->line_length); if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0) return -1; if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected)) return -1; if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected)) return -1; return 0; }