/* 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; }
static int xenfb_hotplug(struct xenfb_device *dev) { if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename, "hotplug-status", "connected")) return -1; return 0; }
static int xenfb_switch_state(struct xenfb_device *dev, enum xenbus_state state) { struct xs_handle *xsh = dev->xenfb->xsh; if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0) return -1; dev->state = state; return 0; }
/* Callback invoked while waiting for KBD backend to change * to the created state */ static void xenfb_backend_created_kbd(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 */ 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); }
/* 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; }