ia64/xen-unstable
changeset 16231:93938fee0bf5
pv-qemu 4/10: Refactor xenfb event handlers
This patch is a simple code re-factoring to move the event loop
integration directly into the xenfb.c file. It is to facilitate
the patches which follow.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This patch is a simple code re-factoring to move the event loop
integration directly into the xenfb.c file. It is to facilitate
the patches which follow.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
author | Keir Fraser <keir@xensource.com> |
---|---|
date | Thu Oct 25 14:38:47 2007 +0100 (2007-10-25) |
parents | 1ed990bc8da9 |
children | 54b72f14eb25 |
files | tools/ioemu/hw/xen_machine_pv.c tools/ioemu/hw/xenfb.c tools/ioemu/hw/xenfb.h |
line diff
1.1 --- a/tools/ioemu/hw/xen_machine_pv.c Thu Oct 25 14:37:23 2007 +0100 1.2 +++ b/tools/ioemu/hw/xen_machine_pv.c Thu Oct 25 14:38:47 2007 +0100 1.3 @@ -213,22 +213,6 @@ void xen_pvfb_invalidate(void *opaque) 1.4 /* Screen dump is not used in Xen, so no need to impl this ? */ 1.5 void xen_pvfb_screen_dump(void *opaque, const char *name) { } 1.6 1.7 -void xen_pvfb_dispatch_store(void *opaque) { 1.8 - int ret; 1.9 - if ((ret = xenfb_dispatch_store(opaque)) < 0) { 1.10 - fprintf(stderr, "Failure while dispatching store: %d\n", ret); 1.11 - exit(1); 1.12 - } 1.13 -} 1.14 - 1.15 -void xen_pvfb_dispatch_channel(void *opaque) { 1.16 - int ret; 1.17 - if ((ret = xenfb_dispatch_channel(opaque)) < 0) { 1.18 - fprintf(stderr, "Failure while dispatching store: %d\n", ret); 1.19 - exit(1); 1.20 - } 1.21 -} 1.22 - 1.23 /* The Xen PV machine currently provides 1.24 * - a virtual framebuffer 1.25 * - .... 1.26 @@ -242,7 +226,7 @@ static void xen_init_pv(uint64_t ram_siz 1.27 { 1.28 struct xenfb *xenfb; 1.29 extern int domid; 1.30 - int fd, i; 1.31 + int i; 1.32 1.33 /* Prepare scancode mapping table */ 1.34 for (i = 0; i < 128; i++) { 1.35 @@ -281,19 +265,6 @@ static void xen_init_pv(uint64_t ram_siz 1.36 xenfb->abs_pointer_wanted, 1.37 "Xen PVFB Mouse"); 1.38 1.39 - /* Listen for events from xenstore */ 1.40 - fd = xenfb_get_store_fd(xenfb); 1.41 - if (qemu_set_fd_handler2(fd, NULL, xen_pvfb_dispatch_store, NULL, xenfb) < 0) { 1.42 - fprintf(stderr, "Could not register event handler (%s)\n", 1.43 - strerror(errno)); 1.44 - } 1.45 - 1.46 - /* Listen for events from the event channel */ 1.47 - fd = xenfb_get_channel_fd(xenfb); 1.48 - if (qemu_set_fd_handler2(fd, NULL, xen_pvfb_dispatch_channel, NULL, xenfb) < 0) { 1.49 - fprintf(stderr, "Could not register event handler (%s)\n", 1.50 - strerror(errno)); 1.51 - } 1.52 1.53 /* Setup QEMU display */ 1.54 dpy_resize(ds, xenfb->width, xenfb->height);
2.1 --- a/tools/ioemu/hw/xenfb.c Thu Oct 25 14:37:23 2007 +0100 2.2 +++ b/tools/ioemu/hw/xenfb.c Thu Oct 25 14:38:47 2007 +0100 2.3 @@ -8,7 +8,6 @@ 2.4 #include <xen/io/fbif.h> 2.5 #include <xen/io/kbdif.h> 2.6 #include <xen/io/protocols.h> 2.7 -#include <sys/select.h> 2.8 #include <stdbool.h> 2.9 #include <xen/event_channel.h> 2.10 #include <sys/mman.h> 2.11 @@ -18,6 +17,7 @@ 2.12 #include <time.h> 2.13 #include <xs.h> 2.14 2.15 +#include "vl.h" 2.16 #include "xenfb.h" 2.17 2.18 // FIXME defend against malicious frontend? 2.19 @@ -505,6 +505,115 @@ static void xenfb_dev_fatal(struct xenfb 2.20 xenfb_switch_state(dev, XenbusStateClosing); 2.21 } 2.22 2.23 + 2.24 +static void xenfb_detach_dom(struct xenfb_private *xenfb) 2.25 +{ 2.26 + xenfb_unbind(&xenfb->fb); 2.27 + xenfb_unbind(&xenfb->kbd); 2.28 + if (xenfb->pub.pixels) { 2.29 + munmap(xenfb->pub.pixels, xenfb->fb_len); 2.30 + xenfb->pub.pixels = NULL; 2.31 + } 2.32 +} 2.33 + 2.34 +static void xenfb_on_fb_event(struct xenfb_private *xenfb) 2.35 +{ 2.36 + uint32_t prod, cons; 2.37 + struct xenfb_page *page = xenfb->fb.page; 2.38 + 2.39 + prod = page->out_prod; 2.40 + if (prod == page->out_cons) 2.41 + return; 2.42 + rmb(); /* ensure we see ring contents up to prod */ 2.43 + for (cons = page->out_cons; cons != prod; cons++) { 2.44 + union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); 2.45 + 2.46 + switch (event->type) { 2.47 + case XENFB_TYPE_UPDATE: 2.48 + if (xenfb->pub.update) 2.49 + xenfb->pub.update(&xenfb->pub, 2.50 + event->update.x, event->update.y, 2.51 + event->update.width, event->update.height); 2.52 + break; 2.53 + } 2.54 + } 2.55 + mb(); /* ensure we're done with ring contents */ 2.56 + page->out_cons = cons; 2.57 + xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); 2.58 +} 2.59 + 2.60 +static void xenfb_on_kbd_event(struct xenfb_private *xenfb) 2.61 +{ 2.62 + struct xenkbd_page *page = xenfb->kbd.page; 2.63 + 2.64 + /* We don't understand any keyboard events, so just ignore them. */ 2.65 + if (page->out_prod == page->out_cons) 2.66 + return; 2.67 + page->out_cons = page->out_prod; 2.68 + xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port); 2.69 +} 2.70 + 2.71 +static int xenfb_on_state_change(struct xenfb_device *dev) 2.72 +{ 2.73 + enum xenbus_state state; 2.74 + 2.75 + state = xenfb_read_state(dev->xenfb->xsh, dev->otherend); 2.76 + 2.77 + switch (state) { 2.78 + case XenbusStateUnknown: 2.79 + /* There was an error reading the frontend state. The 2.80 + domain has probably gone away; in any case, there's 2.81 + not much point in us continuing. */ 2.82 + return -1; 2.83 + case XenbusStateInitialising: 2.84 + case XenbusStateInitWait: 2.85 + case XenbusStateInitialised: 2.86 + case XenbusStateConnected: 2.87 + break; 2.88 + case XenbusStateClosing: 2.89 + xenfb_unbind(dev); 2.90 + xenfb_switch_state(dev, state); 2.91 + break; 2.92 + case XenbusStateClosed: 2.93 + xenfb_switch_state(dev, state); 2.94 + } 2.95 + return 0; 2.96 +} 2.97 + 2.98 +static void xenfb_dispatch_channel(void *xenfb_pub) 2.99 +{ 2.100 + struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.101 + evtchn_port_t port; 2.102 + port = xc_evtchn_pending(xenfb->evt_xch); 2.103 + if (port == -1) 2.104 + exit(1); 2.105 + 2.106 + if (port == xenfb->fb.port) 2.107 + xenfb_on_fb_event(xenfb); 2.108 + else if (port == xenfb->kbd.port) 2.109 + xenfb_on_kbd_event(xenfb); 2.110 + 2.111 + if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1) 2.112 + exit(1); 2.113 +} 2.114 + 2.115 +static void xenfb_dispatch_store(void *xenfb_pub) 2.116 +{ 2.117 + struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.118 + unsigned dummy; 2.119 + char **vec; 2.120 + int r; 2.121 + 2.122 + vec = xs_read_watch(xenfb->xsh, &dummy); 2.123 + free(vec); 2.124 + r = xenfb_on_state_change(&xenfb->fb); 2.125 + if (r == 0) 2.126 + r = xenfb_on_state_change(&xenfb->kbd); 2.127 + if (r == -1) 2.128 + exit(1); 2.129 +} 2.130 + 2.131 + 2.132 int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid) 2.133 { 2.134 struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.135 @@ -585,6 +694,14 @@ int xenfb_attach_dom(struct xenfb *xenfb 2.136 val = 0; 2.137 xenfb->pub.abs_pointer_wanted = val; 2.138 2.139 + /* Listen for events from xenstore */ 2.140 + if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0) 2.141 + goto error; 2.142 + 2.143 + /* Listen for events from the event channel */ 2.144 + if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0) 2.145 + goto error; 2.146 + 2.147 return 0; 2.148 2.149 error: 2.150 @@ -596,160 +713,6 @@ int xenfb_attach_dom(struct xenfb *xenfb 2.151 return -1; 2.152 } 2.153 2.154 -static void xenfb_detach_dom(struct xenfb_private *xenfb) 2.155 -{ 2.156 - xenfb_unbind(&xenfb->fb); 2.157 - xenfb_unbind(&xenfb->kbd); 2.158 - if (xenfb->pub.pixels) { 2.159 - munmap(xenfb->pub.pixels, xenfb->fb_len); 2.160 - xenfb->pub.pixels = NULL; 2.161 - } 2.162 -} 2.163 - 2.164 -static void xenfb_on_fb_event(struct xenfb_private *xenfb) 2.165 -{ 2.166 - uint32_t prod, cons; 2.167 - struct xenfb_page *page = xenfb->fb.page; 2.168 - 2.169 - prod = page->out_prod; 2.170 - if (prod == page->out_cons) 2.171 - return; 2.172 - rmb(); /* ensure we see ring contents up to prod */ 2.173 - for (cons = page->out_cons; cons != prod; cons++) { 2.174 - union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); 2.175 - 2.176 - switch (event->type) { 2.177 - case XENFB_TYPE_UPDATE: 2.178 - if (xenfb->pub.update) 2.179 - xenfb->pub.update(&xenfb->pub, 2.180 - event->update.x, event->update.y, 2.181 - event->update.width, event->update.height); 2.182 - break; 2.183 - } 2.184 - } 2.185 - mb(); /* ensure we're done with ring contents */ 2.186 - page->out_cons = cons; 2.187 - xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); 2.188 -} 2.189 - 2.190 -static void xenfb_on_kbd_event(struct xenfb_private *xenfb) 2.191 -{ 2.192 - struct xenkbd_page *page = xenfb->kbd.page; 2.193 - 2.194 - /* We don't understand any keyboard events, so just ignore them. */ 2.195 - if (page->out_prod == page->out_cons) 2.196 - return; 2.197 - page->out_cons = page->out_prod; 2.198 - xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port); 2.199 -} 2.200 - 2.201 -static int xenfb_on_state_change(struct xenfb_device *dev) 2.202 -{ 2.203 - enum xenbus_state state; 2.204 - 2.205 - state = xenfb_read_state(dev->xenfb->xsh, dev->otherend); 2.206 - 2.207 - switch (state) { 2.208 - case XenbusStateUnknown: 2.209 - /* There was an error reading the frontend state. The 2.210 - domain has probably gone away; in any case, there's 2.211 - not much point in us continuing. */ 2.212 - return -1; 2.213 - case XenbusStateInitialising: 2.214 - case XenbusStateInitWait: 2.215 - case XenbusStateInitialised: 2.216 - case XenbusStateConnected: 2.217 - break; 2.218 - case XenbusStateClosing: 2.219 - xenfb_unbind(dev); 2.220 - xenfb_switch_state(dev, state); 2.221 - break; 2.222 - case XenbusStateClosed: 2.223 - xenfb_switch_state(dev, state); 2.224 - } 2.225 - return 0; 2.226 -} 2.227 - 2.228 -int xenfb_dispatch_channel(struct xenfb *xenfb_pub) 2.229 -{ 2.230 - struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.231 - evtchn_port_t port; 2.232 - port = xc_evtchn_pending(xenfb->evt_xch); 2.233 - if (port == -1) 2.234 - return -1; 2.235 - 2.236 - if (port == xenfb->fb.port) 2.237 - xenfb_on_fb_event(xenfb); 2.238 - else if (port == xenfb->kbd.port) 2.239 - xenfb_on_kbd_event(xenfb); 2.240 - 2.241 - if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1) 2.242 - return -1; 2.243 - 2.244 - return 0; 2.245 -} 2.246 - 2.247 -int xenfb_dispatch_store(struct xenfb *xenfb_pub) 2.248 -{ 2.249 - struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.250 - unsigned dummy; 2.251 - char **vec; 2.252 - int r; 2.253 - 2.254 - vec = xs_read_watch(xenfb->xsh, &dummy); 2.255 - free(vec); 2.256 - r = xenfb_on_state_change(&xenfb->fb); 2.257 - if (r == 0) 2.258 - r = xenfb_on_state_change(&xenfb->kbd); 2.259 - if (r == -1) 2.260 - return -2; 2.261 - 2.262 - return 0; 2.263 -} 2.264 - 2.265 - 2.266 -/* Returns 0 normally, -1 on error, or -2 if the domain went away. */ 2.267 -int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds) 2.268 -{ 2.269 - struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.270 - int ret; 2.271 - 2.272 - if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) { 2.273 - if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0) 2.274 - return ret; 2.275 - } 2.276 - 2.277 - if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) { 2.278 - if ((ret = xenfb_dispatch_store(xenfb_pub)) < 0) 2.279 - return ret; 2.280 - } 2.281 - 2.282 - return 0; 2.283 -} 2.284 - 2.285 -int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds) 2.286 -{ 2.287 - struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.288 - int fd1 = xc_evtchn_fd(xenfb->evt_xch); 2.289 - int fd2 = xs_fileno(xenfb->xsh); 2.290 - 2.291 - FD_SET(fd1, readfds); 2.292 - FD_SET(fd2, readfds); 2.293 - return fd1 > fd2 ? fd1 + 1 : fd2 + 1; 2.294 -} 2.295 - 2.296 -int xenfb_get_store_fd(struct xenfb *xenfb_pub) 2.297 -{ 2.298 - struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.299 - return xs_fileno(xenfb->xsh); 2.300 -} 2.301 - 2.302 -int xenfb_get_channel_fd(struct xenfb *xenfb_pub) 2.303 -{ 2.304 - struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; 2.305 - return xc_evtchn_fd(xenfb->evt_xch); 2.306 -} 2.307 - 2.308 static int xenfb_kbd_event(struct xenfb_private *xenfb, 2.309 union xenkbd_in_event *event) 2.310 {
3.1 --- a/tools/ioemu/hw/xenfb.h Thu Oct 25 14:37:23 2007 +0100 3.2 +++ b/tools/ioemu/hw/xenfb.h Thu Oct 25 14:38:47 2007 +0100 3.3 @@ -25,13 +25,6 @@ void xenfb_teardown(struct xenfb *xenfb) 3.4 3.5 int xenfb_attach_dom(struct xenfb *xenfb, int domid); 3.6 3.7 -int xenfb_dispatch_store(struct xenfb *xenfb_pub); 3.8 -int xenfb_dispatch_channel(struct xenfb *xenfb_pub); 3.9 -int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds); 3.10 -int xenfb_poll(struct xenfb *xenfb, fd_set *readfds); 3.11 -int xenfb_get_store_fd(struct xenfb *xenfb_pub); 3.12 -int xenfb_get_channel_fd(struct xenfb *xenfb_pub); 3.13 - 3.14 int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode); 3.15 int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y); 3.16 int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);