Merge remote-tracking branch 'kraxel/pixman.v3' into staging
[sdk/emulator/qemu.git] / hw / xenfb.c
1 /*
2  *  xen paravirt framebuffer backend
3  *
4  *  Copyright IBM, Corp. 2005-2006
5  *  Copyright Red Hat, Inc. 2006-2008
6  *
7  *  Authors:
8  *       Anthony Liguori <aliguori@us.ibm.com>,
9  *       Markus Armbruster <armbru@redhat.com>,
10  *       Daniel P. Berrange <berrange@redhat.com>,
11  *       Pat Campbell <plc@novell.com>,
12  *       Gerd Hoffmann <kraxel@redhat.com>
13  *
14  *  This program is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by
16  *  the Free Software Foundation; under version 2 of the License.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License along
24  *  with this program; if not, see <http://www.gnu.org/licenses/>.
25  */
26
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <sys/mman.h>
33 #include <errno.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <time.h>
37
38 #include "hw.h"
39 #include "console.h"
40 #include "qemu-char.h"
41 #include "xen_backend.h"
42
43 #include <xen/event_channel.h>
44 #include <xen/io/fbif.h>
45 #include <xen/io/kbdif.h>
46 #include <xen/io/protocols.h>
47
48 #ifndef BTN_LEFT
49 #define BTN_LEFT 0x110 /* from <linux/input.h> */
50 #endif
51
52 /* -------------------------------------------------------------------- */
53
54 struct common {
55     struct XenDevice  xendev;  /* must be first */
56     void              *page;
57     DisplayState      *ds;
58 };
59
60 struct XenInput {
61     struct common c;
62     int abs_pointer_wanted; /* Whether guest supports absolute pointer */
63     int button_state;       /* Last seen pointer button state */
64     int extended;
65     QEMUPutMouseEntry *qmouse;
66 };
67
68 #define UP_QUEUE 8
69
70 struct XenFB {
71     struct common     c;
72     size_t            fb_len;
73     int               row_stride;
74     int               depth;
75     int               width;
76     int               height;
77     int               offset;
78     void              *pixels;
79     int               fbpages;
80     int               feature_update;
81     int               refresh_period;
82     int               bug_trigger;
83     int               have_console;
84     int               do_resize;
85
86     struct {
87         int x,y,w,h;
88     } up_rects[UP_QUEUE];
89     int               up_count;
90     int               up_fullscreen;
91 };
92
93 /* -------------------------------------------------------------------- */
94
95 static int common_bind(struct common *c)
96 {
97     int mfn;
98
99     if (xenstore_read_fe_int(&c->xendev, "page-ref", &mfn) == -1)
100         return -1;
101     if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
102         return -1;
103
104     c->page = xc_map_foreign_range(xen_xc, c->xendev.dom,
105                                    XC_PAGE_SIZE,
106                                    PROT_READ | PROT_WRITE, mfn);
107     if (c->page == NULL)
108         return -1;
109
110     xen_be_bind_evtchn(&c->xendev);
111     xen_be_printf(&c->xendev, 1, "ring mfn %d, remote-port %d, local-port %d\n",
112                   mfn, c->xendev.remote_port, c->xendev.local_port);
113
114     return 0;
115 }
116
117 static void common_unbind(struct common *c)
118 {
119     xen_be_unbind_evtchn(&c->xendev);
120     if (c->page) {
121         munmap(c->page, XC_PAGE_SIZE);
122         c->page = NULL;
123     }
124 }
125
126 /* -------------------------------------------------------------------- */
127
128 #if 0
129 /*
130  * These two tables are not needed any more, but left in here
131  * intentionally as documentation, to show how scancode2linux[]
132  * was generated.
133  *
134  * Tables to map from scancode to Linux input layer keycode.
135  * Scancodes are hardware-specific.  These maps assumes a
136  * standard AT or PS/2 keyboard which is what QEMU feeds us.
137  */
138 const unsigned char atkbd_set2_keycode[512] = {
139
140      0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
141      0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
142      0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
143      0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
144      0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
145      0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
146      0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
147     82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
148
149       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
150     217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
151     173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
152     159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
153     157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
154     226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
155       0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
156     110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
157
158 };
159
160 const unsigned char atkbd_unxlate_table[128] = {
161
162       0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
163      21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
164      35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
165      50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
166      11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
167     114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
168      71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
169      19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
170
171 };
172 #endif
173
174 /*
175  * for (i = 0; i < 128; i++) {
176  *     scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
177  *     scancode2linux[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
178  * }
179  */
180 static const unsigned char scancode2linux[512] = {
181       0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
182      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
183      32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
184      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
185      64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
186      80, 81, 82, 83, 99,  0, 86, 87, 88,117,  0,  0, 95,183,184,185,
187       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
188      93,  0,  0, 89,  0,  0, 85, 91, 90, 92,  0, 94,  0,124,121,  0,
189
190       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
191     165,  0,  0,  0,  0,  0,  0,  0,  0,163,  0,  0, 96, 97,  0,  0,
192     113,140,164,  0,166,  0,  0,  0,  0,  0,255,  0,  0,  0,114,  0,
193     115,  0,150,  0,  0, 98,255, 99,100,  0,  0,  0,  0,  0,  0,  0,
194       0,  0,  0,  0,  0,119,119,102,103,104,  0,105,112,106,118,107,
195     108,109,110,111,  0,  0,  0,  0,  0,  0,  0,125,126,127,116,142,
196       0,  0,  0,143,  0,217,156,173,128,159,158,157,155,226,  0,112,
197       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
198 };
199
200 /* Send an event to the keyboard frontend driver */
201 static int xenfb_kbd_event(struct XenInput *xenfb,
202                            union xenkbd_in_event *event)
203 {
204     struct xenkbd_page *page = xenfb->c.page;
205     uint32_t prod;
206
207     if (xenfb->c.xendev.be_state != XenbusStateConnected)
208         return 0;
209     if (!page)
210         return 0;
211
212     prod = page->in_prod;
213     if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
214         errno = EAGAIN;
215         return -1;
216     }
217
218     xen_mb();           /* ensure ring space available */
219     XENKBD_IN_RING_REF(page, prod) = *event;
220     xen_wmb();          /* ensure ring contents visible */
221     page->in_prod = prod + 1;
222     return xen_be_send_notify(&xenfb->c.xendev);
223 }
224
225 /* Send a keyboard (or mouse button) event */
226 static int xenfb_send_key(struct XenInput *xenfb, bool down, int keycode)
227 {
228     union xenkbd_in_event event;
229
230     memset(&event, 0, XENKBD_IN_EVENT_SIZE);
231     event.type = XENKBD_TYPE_KEY;
232     event.key.pressed = down ? 1 : 0;
233     event.key.keycode = keycode;
234
235     return xenfb_kbd_event(xenfb, &event);
236 }
237
238 /* Send a relative mouse movement event */
239 static int xenfb_send_motion(struct XenInput *xenfb,
240                              int rel_x, int rel_y, int rel_z)
241 {
242     union xenkbd_in_event event;
243
244     memset(&event, 0, XENKBD_IN_EVENT_SIZE);
245     event.type = XENKBD_TYPE_MOTION;
246     event.motion.rel_x = rel_x;
247     event.motion.rel_y = rel_y;
248 #if __XEN_LATEST_INTERFACE_VERSION__ >= 0x00030207
249     event.motion.rel_z = rel_z;
250 #endif
251
252     return xenfb_kbd_event(xenfb, &event);
253 }
254
255 /* Send an absolute mouse movement event */
256 static int xenfb_send_position(struct XenInput *xenfb,
257                                int abs_x, int abs_y, int z)
258 {
259     union xenkbd_in_event event;
260
261     memset(&event, 0, XENKBD_IN_EVENT_SIZE);
262     event.type = XENKBD_TYPE_POS;
263     event.pos.abs_x = abs_x;
264     event.pos.abs_y = abs_y;
265 #if __XEN_LATEST_INTERFACE_VERSION__ == 0x00030207
266     event.pos.abs_z = z;
267 #endif
268 #if __XEN_LATEST_INTERFACE_VERSION__ >= 0x00030208
269     event.pos.rel_z = z;
270 #endif
271
272     return xenfb_kbd_event(xenfb, &event);
273 }
274
275 /*
276  * Send a key event from the client to the guest OS
277  * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
278  * We have to turn this into a Linux Input layer keycode.
279  *
280  * Extra complexity from the fact that with extended scancodes
281  * (like those produced by arrow keys) this method gets called
282  * twice, but we only want to send a single event. So we have to
283  * track the '0xe0' scancode state & collapse the extended keys
284  * as needed.
285  *
286  * Wish we could just send scancodes straight to the guest which
287  * already has code for dealing with this...
288  */
289 static void xenfb_key_event(void *opaque, int scancode)
290 {
291     struct XenInput *xenfb = opaque;
292     int down = 1;
293
294     if (scancode == 0xe0) {
295         xenfb->extended = 1;
296         return;
297     } else if (scancode & 0x80) {
298         scancode &= 0x7f;
299         down = 0;
300     }
301     if (xenfb->extended) {
302         scancode |= 0x80;
303         xenfb->extended = 0;
304     }
305     xenfb_send_key(xenfb, down, scancode2linux[scancode]);
306 }
307
308 /*
309  * Send a mouse event from the client to the guest OS
310  *
311  * The QEMU mouse can be in either relative, or absolute mode.
312  * Movement is sent separately from button state, which has to
313  * be encoded as virtual key events. We also don't actually get
314  * given any button up/down events, so have to track changes in
315  * the button state.
316  */
317 static void xenfb_mouse_event(void *opaque,
318                               int dx, int dy, int dz, int button_state)
319 {
320     struct XenInput *xenfb = opaque;
321     int dw = ds_get_width(xenfb->c.ds);
322     int dh = ds_get_height(xenfb->c.ds);
323     int i;
324
325     if (xenfb->abs_pointer_wanted)
326         xenfb_send_position(xenfb,
327                             dx * (dw - 1) / 0x7fff,
328                             dy * (dh - 1) / 0x7fff,
329                             dz);
330     else
331         xenfb_send_motion(xenfb, dx, dy, dz);
332
333     for (i = 0 ; i < 8 ; i++) {
334         int lastDown = xenfb->button_state & (1 << i);
335         int down = button_state & (1 << i);
336         if (down == lastDown)
337             continue;
338
339         if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
340             return;
341     }
342     xenfb->button_state = button_state;
343 }
344
345 static int input_init(struct XenDevice *xendev)
346 {
347     xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
348     return 0;
349 }
350
351 static int input_initialise(struct XenDevice *xendev)
352 {
353     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
354     int rc;
355
356     if (!in->c.ds) {
357         char *vfb = xenstore_read_str(NULL, "device/vfb");
358         if (vfb == NULL) {
359             /* there is no vfb, run vkbd on its own */
360             in->c.ds = get_displaystate();
361         } else {
362             g_free(vfb);
363             xen_be_printf(xendev, 1, "ds not set (yet)\n");
364             return -1;
365         }
366     }
367
368     rc = common_bind(&in->c);
369     if (rc != 0)
370         return rc;
371
372     qemu_add_kbd_event_handler(xenfb_key_event, in);
373     return 0;
374 }
375
376 static void input_connected(struct XenDevice *xendev)
377 {
378     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
379
380     if (xenstore_read_fe_int(xendev, "request-abs-pointer",
381                              &in->abs_pointer_wanted) == -1) {
382         in->abs_pointer_wanted = 0;
383     }
384
385     if (in->qmouse) {
386         qemu_remove_mouse_event_handler(in->qmouse);
387     }
388     in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
389                                               in->abs_pointer_wanted,
390                                               "Xen PVFB Mouse");
391 }
392
393 static void input_disconnect(struct XenDevice *xendev)
394 {
395     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
396
397     if (in->qmouse) {
398         qemu_remove_mouse_event_handler(in->qmouse);
399         in->qmouse = NULL;
400     }
401     qemu_add_kbd_event_handler(NULL, NULL);
402     common_unbind(&in->c);
403 }
404
405 static void input_event(struct XenDevice *xendev)
406 {
407     struct XenInput *xenfb = container_of(xendev, struct XenInput, c.xendev);
408     struct xenkbd_page *page = xenfb->c.page;
409
410     /* We don't understand any keyboard events, so just ignore them. */
411     if (page->out_prod == page->out_cons)
412         return;
413     page->out_cons = page->out_prod;
414     xen_be_send_notify(&xenfb->c.xendev);
415 }
416
417 /* -------------------------------------------------------------------- */
418
419 static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
420 {
421     uint32_t *src32 = src;
422     uint64_t *src64 = src;
423     int i;
424
425     for (i = 0; i < count; i++)
426         dst[i] = (mode == 32) ? src32[i] : src64[i];
427 }
428
429 static int xenfb_map_fb(struct XenFB *xenfb)
430 {
431     struct xenfb_page *page = xenfb->c.page;
432     char *protocol = xenfb->c.xendev.protocol;
433     int n_fbdirs;
434     unsigned long *pgmfns = NULL;
435     unsigned long *fbmfns = NULL;
436     void *map, *pd;
437     int mode, ret = -1;
438
439     /* default to native */
440     pd = page->pd;
441     mode = sizeof(unsigned long) * 8;
442
443     if (!protocol) {
444         /*
445          * Undefined protocol, some guesswork needed.
446          *
447          * Old frontends which don't set the protocol use
448          * one page directory only, thus pd[1] must be zero.
449          * pd[1] of the 32bit struct layout and the lower
450          * 32 bits of pd[0] of the 64bit struct layout have
451          * the same location, so we can check that ...
452          */
453         uint32_t *ptr32 = NULL;
454         uint32_t *ptr64 = NULL;
455 #if defined(__i386__)
456         ptr32 = (void*)page->pd;
457         ptr64 = ((void*)page->pd) + 4;
458 #elif defined(__x86_64__)
459         ptr32 = ((void*)page->pd) - 4;
460         ptr64 = (void*)page->pd;
461 #endif
462         if (ptr32) {
463             if (ptr32[1] == 0) {
464                 mode = 32;
465                 pd   = ptr32;
466             } else {
467                 mode = 64;
468                 pd   = ptr64;
469             }
470         }
471 #if defined(__x86_64__)
472     } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
473         /* 64bit dom0, 32bit domU */
474         mode = 32;
475         pd   = ((void*)page->pd) - 4;
476 #elif defined(__i386__)
477     } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
478         /* 32bit dom0, 64bit domU */
479         mode = 64;
480         pd   = ((void*)page->pd) + 4;
481 #endif
482     }
483
484     if (xenfb->pixels) {
485         munmap(xenfb->pixels, xenfb->fbpages * XC_PAGE_SIZE);
486         xenfb->pixels = NULL;
487     }
488
489     xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
490     n_fbdirs = xenfb->fbpages * mode / 8;
491     n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
492
493     pgmfns = g_malloc0(sizeof(unsigned long) * n_fbdirs);
494     fbmfns = g_malloc0(sizeof(unsigned long) * xenfb->fbpages);
495
496     xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
497     map = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
498                                PROT_READ, pgmfns, n_fbdirs);
499     if (map == NULL)
500         goto out;
501     xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
502     munmap(map, n_fbdirs * XC_PAGE_SIZE);
503
504     xenfb->pixels = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
505                                          PROT_READ | PROT_WRITE, fbmfns, xenfb->fbpages);
506     if (xenfb->pixels == NULL)
507         goto out;
508
509     ret = 0; /* all is fine */
510
511 out:
512     g_free(pgmfns);
513     g_free(fbmfns);
514     return ret;
515 }
516
517 static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
518                               int width, int height, int depth,
519                               size_t fb_len, int offset, int row_stride)
520 {
521     size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
522     size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
523     size_t fb_pages = pd_len * XC_PAGE_SIZE / mfn_sz;
524     size_t fb_len_max = fb_pages * XC_PAGE_SIZE;
525     int max_width, max_height;
526
527     if (fb_len_lim > fb_len_max) {
528         xen_be_printf(&xenfb->c.xendev, 0, "fb size limit %zu exceeds %zu, corrected\n",
529                       fb_len_lim, fb_len_max);
530         fb_len_lim = fb_len_max;
531     }
532     if (fb_len_lim && fb_len > fb_len_lim) {
533         xen_be_printf(&xenfb->c.xendev, 0, "frontend fb size %zu limited to %zu\n",
534                       fb_len, fb_len_lim);
535         fb_len = fb_len_lim;
536     }
537     if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
538         xen_be_printf(&xenfb->c.xendev, 0, "can't handle frontend fb depth %d\n",
539                       depth);
540         return -1;
541     }
542     if (row_stride <= 0 || row_stride > fb_len) {
543         xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n", row_stride);
544         return -1;
545     }
546     max_width = row_stride / (depth / 8);
547     if (width < 0 || width > max_width) {
548         xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend width %d limited to %d\n",
549                       width, max_width);
550         width = max_width;
551     }
552     if (offset < 0 || offset >= fb_len) {
553         xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend offset %d (max %zu)\n",
554                       offset, fb_len - 1);
555         return -1;
556     }
557     max_height = (fb_len - offset) / row_stride;
558     if (height < 0 || height > max_height) {
559         xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend height %d limited to %d\n",
560                       height, max_height);
561         height = max_height;
562     }
563     xenfb->fb_len = fb_len;
564     xenfb->row_stride = row_stride;
565     xenfb->depth = depth;
566     xenfb->width = width;
567     xenfb->height = height;
568     xenfb->offset = offset;
569     xenfb->up_fullscreen = 1;
570     xenfb->do_resize = 1;
571     xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride %d\n",
572                   width, height, depth, offset, row_stride);
573     return 0;
574 }
575
576 /* A convenient function for munging pixels between different depths */
577 #define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB)                        \
578     for (line = y ; line < (y+h) ; line++) {                            \
579         SRC_T *src = (SRC_T *)(xenfb->pixels                            \
580                                + xenfb->offset                          \
581                                + (line * xenfb->row_stride)             \
582                                + (x * xenfb->depth / 8));               \
583         DST_T *dst = (DST_T *)(data                                     \
584                                + (line * linesize)                      \
585                                + (x * bpp / 8));                        \
586         int col;                                                        \
587         const int RSS = 32 - (RSB + GSB + BSB);                         \
588         const int GSS = 32 - (GSB + BSB);                               \
589         const int BSS = 32 - (BSB);                                     \
590         const uint32_t RSM = (~0U) << (32 - RSB);                       \
591         const uint32_t GSM = (~0U) << (32 - GSB);                       \
592         const uint32_t BSM = (~0U) << (32 - BSB);                       \
593         const int RDS = 32 - (RDB + GDB + BDB);                         \
594         const int GDS = 32 - (GDB + BDB);                               \
595         const int BDS = 32 - (BDB);                                     \
596         const uint32_t RDM = (~0U) << (32 - RDB);                       \
597         const uint32_t GDM = (~0U) << (32 - GDB);                       \
598         const uint32_t BDM = (~0U) << (32 - BDB);                       \
599         for (col = x ; col < (x+w) ; col++) {                           \
600             uint32_t spix = *src;                                       \
601             *dst = (((spix << RSS) & RSM & RDM) >> RDS) |               \
602                 (((spix << GSS) & GSM & GDM) >> GDS) |                  \
603                 (((spix << BSS) & BSM & BDM) >> BDS);                   \
604             src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8);   \
605             dst = (DST_T *) ((unsigned long) dst + bpp / 8);            \
606         }                                                               \
607     }
608
609
610 /*
611  * This copies data from the guest framebuffer region, into QEMU's
612  * displaysurface. qemu uses 16 or 32 bpp.  In case the pv framebuffer
613  * uses something else we must convert and copy, otherwise we can
614  * supply the buffer directly and no thing here.
615  */
616 static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
617 {
618     int line, oops = 0;
619     int bpp = ds_get_bits_per_pixel(xenfb->c.ds);
620     int linesize = ds_get_linesize(xenfb->c.ds);
621     uint8_t *data = ds_get_data(xenfb->c.ds);
622
623     if (!is_buffer_shared(xenfb->c.ds->surface)) {
624         switch (xenfb->depth) {
625         case 8:
626             if (bpp == 16) {
627                 BLT(uint8_t, uint16_t,   3, 3, 2,   5, 6, 5);
628             } else if (bpp == 32) {
629                 BLT(uint8_t, uint32_t,   3, 3, 2,   8, 8, 8);
630             } else {
631                 oops = 1;
632             }
633             break;
634         case 24:
635             if (bpp == 16) {
636                 BLT(uint32_t, uint16_t,  8, 8, 8,   5, 6, 5);
637             } else if (bpp == 32) {
638                 BLT(uint32_t, uint32_t,  8, 8, 8,   8, 8, 8);
639             } else {
640                 oops = 1;
641             }
642             break;
643         default:
644             oops = 1;
645         }
646     }
647     if (oops) /* should not happen */
648         xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
649                       __FUNCTION__, xenfb->depth, bpp);
650
651     dpy_update(xenfb->c.ds, x, y, w, h);
652 }
653
654 #ifdef XENFB_TYPE_REFRESH_PERIOD
655 static int xenfb_queue_full(struct XenFB *xenfb)
656 {
657     struct xenfb_page *page = xenfb->c.page;
658     uint32_t cons, prod;
659
660     if (!page)
661         return 1;
662
663     prod = page->in_prod;
664     cons = page->in_cons;
665     return prod - cons == XENFB_IN_RING_LEN;
666 }
667
668 static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
669 {
670     uint32_t prod;
671     struct xenfb_page *page = xenfb->c.page;
672
673     prod = page->in_prod;
674     /* caller ensures !xenfb_queue_full() */
675     xen_mb();                   /* ensure ring space available */
676     XENFB_IN_RING_REF(page, prod) = *event;
677     xen_wmb();                  /* ensure ring contents visible */
678     page->in_prod = prod + 1;
679
680     xen_be_send_notify(&xenfb->c.xendev);
681 }
682
683 static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
684 {
685     union xenfb_in_event event;
686
687     memset(&event, 0, sizeof(event));
688     event.type = XENFB_TYPE_REFRESH_PERIOD;
689     event.refresh_period.period = period;
690     xenfb_send_event(xenfb, &event);
691 }
692 #endif
693
694 /*
695  * Periodic update of display.
696  * Also transmit the refresh interval to the frontend.
697  *
698  * Never ever do any qemu display operations
699  * (resize, screen update) outside this function.
700  * Our screen might be inactive.  When asked for
701  * an update we know it is active.
702  */
703 static void xenfb_update(void *opaque)
704 {
705     struct XenFB *xenfb = opaque;
706     int i;
707
708     if (xenfb->c.xendev.be_state != XenbusStateConnected)
709         return;
710
711     if (xenfb->feature_update) {
712 #ifdef XENFB_TYPE_REFRESH_PERIOD
713         struct DisplayChangeListener *l;
714         int period = 99999999;
715         int idle = 1;
716
717         if (xenfb_queue_full(xenfb))
718             return;
719
720         QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
721             if (l->idle)
722                 continue;
723             idle = 0;
724             if (!l->gui_timer_interval) {
725                 if (period > GUI_REFRESH_INTERVAL)
726                     period = GUI_REFRESH_INTERVAL;
727             } else {
728                 if (period > l->gui_timer_interval)
729                     period = l->gui_timer_interval;
730             }
731         }
732         if (idle)
733             period = XENFB_NO_REFRESH;
734
735         if (xenfb->refresh_period != period) {
736             xenfb_send_refresh_period(xenfb, period);
737             xenfb->refresh_period = period;
738             xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
739         }
740 #else
741         ; /* nothing */
742 #endif
743     } else {
744         /* we don't get update notifications, thus use the
745          * sledge hammer approach ... */
746         xenfb->up_fullscreen = 1;
747     }
748
749     /* resize if needed */
750     if (xenfb->do_resize) {
751         xenfb->do_resize = 0;
752         switch (xenfb->depth) {
753         case 16:
754         case 32:
755             /* console.c supported depth -> buffer can be used directly */
756             qemu_free_displaysurface(xenfb->c.ds);
757             xenfb->c.ds->surface = qemu_create_displaysurface_from
758                 (xenfb->width, xenfb->height, xenfb->depth,
759                  xenfb->row_stride, xenfb->pixels + xenfb->offset);
760             break;
761         default:
762             /* we must convert stuff */
763             qemu_resize_displaysurface(xenfb->c.ds, xenfb->width, xenfb->height);
764             break;
765         }
766         xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n",
767                       xenfb->width, xenfb->height, xenfb->depth,
768                       is_buffer_shared(xenfb->c.ds->surface) ? " (shared)" : "");
769         dpy_resize(xenfb->c.ds);
770         xenfb->up_fullscreen = 1;
771     }
772
773     /* run queued updates */
774     if (xenfb->up_fullscreen) {
775         xen_be_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
776         xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
777     } else if (xenfb->up_count) {
778         xen_be_printf(&xenfb->c.xendev, 3, "update: %d rects\n", xenfb->up_count);
779         for (i = 0; i < xenfb->up_count; i++)
780             xenfb_guest_copy(xenfb,
781                              xenfb->up_rects[i].x,
782                              xenfb->up_rects[i].y,
783                              xenfb->up_rects[i].w,
784                              xenfb->up_rects[i].h);
785     } else {
786         xen_be_printf(&xenfb->c.xendev, 3, "update: nothing\n");
787     }
788     xenfb->up_count = 0;
789     xenfb->up_fullscreen = 0;
790 }
791
792 /* QEMU display state changed, so refresh the framebuffer copy */
793 static void xenfb_invalidate(void *opaque)
794 {
795     struct XenFB *xenfb = opaque;
796     xenfb->up_fullscreen = 1;
797 }
798
799 static void xenfb_handle_events(struct XenFB *xenfb)
800 {
801     uint32_t prod, cons;
802     struct xenfb_page *page = xenfb->c.page;
803
804     prod = page->out_prod;
805     if (prod == page->out_cons)
806         return;
807     xen_rmb();          /* ensure we see ring contents up to prod */
808     for (cons = page->out_cons; cons != prod; cons++) {
809         union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
810         int x, y, w, h;
811
812         switch (event->type) {
813         case XENFB_TYPE_UPDATE:
814             if (xenfb->up_count == UP_QUEUE)
815                 xenfb->up_fullscreen = 1;
816             if (xenfb->up_fullscreen)
817                 break;
818             x = MAX(event->update.x, 0);
819             y = MAX(event->update.y, 0);
820             w = MIN(event->update.width, xenfb->width - x);
821             h = MIN(event->update.height, xenfb->height - y);
822             if (w < 0 || h < 0) {
823                 xen_be_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
824                 break;
825             }
826             if (x != event->update.x ||
827                 y != event->update.y ||
828                 w != event->update.width ||
829                 h != event->update.height) {
830                 xen_be_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
831             }
832             if (w == xenfb->width && h > xenfb->height / 2) {
833                 /* scroll detector: updated more than 50% of the lines,
834                  * don't bother keeping track of the rectangles then */
835                 xenfb->up_fullscreen = 1;
836             } else {
837                 xenfb->up_rects[xenfb->up_count].x = x;
838                 xenfb->up_rects[xenfb->up_count].y = y;
839                 xenfb->up_rects[xenfb->up_count].w = w;
840                 xenfb->up_rects[xenfb->up_count].h = h;
841                 xenfb->up_count++;
842             }
843             break;
844 #ifdef XENFB_TYPE_RESIZE
845         case XENFB_TYPE_RESIZE:
846             if (xenfb_configure_fb(xenfb, xenfb->fb_len,
847                                    event->resize.width,
848                                    event->resize.height,
849                                    event->resize.depth,
850                                    xenfb->fb_len,
851                                    event->resize.offset,
852                                    event->resize.stride) < 0)
853                 break;
854             xenfb_invalidate(xenfb);
855             break;
856 #endif
857         }
858     }
859     xen_mb();           /* ensure we're done with ring contents */
860     page->out_cons = cons;
861 }
862
863 static int fb_init(struct XenDevice *xendev)
864 {
865     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
866
867     fb->refresh_period = -1;
868
869 #ifdef XENFB_TYPE_RESIZE
870     xenstore_write_be_int(xendev, "feature-resize", 1);
871 #endif
872     return 0;
873 }
874
875 static int fb_initialise(struct XenDevice *xendev)
876 {
877     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
878     struct xenfb_page *fb_page;
879     int videoram;
880     int rc;
881
882     if (xenstore_read_fe_int(xendev, "videoram", &videoram) == -1)
883         videoram = 0;
884
885     rc = common_bind(&fb->c);
886     if (rc != 0)
887         return rc;
888
889     fb_page = fb->c.page;
890     rc = xenfb_configure_fb(fb, videoram * 1024 * 1024U,
891                             fb_page->width, fb_page->height, fb_page->depth,
892                             fb_page->mem_length, 0, fb_page->line_length);
893     if (rc != 0)
894         return rc;
895
896     rc = xenfb_map_fb(fb);
897     if (rc != 0)
898         return rc;
899
900 #if 0  /* handled in xen_init_display() for now */
901     if (!fb->have_console) {
902         fb->c.ds = graphic_console_init(xenfb_update,
903                                         xenfb_invalidate,
904                                         NULL,
905                                         NULL,
906                                         fb);
907         fb->have_console = 1;
908     }
909 #endif
910
911     if (xenstore_read_fe_int(xendev, "feature-update", &fb->feature_update) == -1)
912         fb->feature_update = 0;
913     if (fb->feature_update)
914         xenstore_write_be_int(xendev, "request-update", 1);
915
916     xen_be_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
917                   fb->feature_update, videoram);
918     return 0;
919 }
920
921 static void fb_disconnect(struct XenDevice *xendev)
922 {
923     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
924
925     /*
926      * FIXME: qemu can't un-init gfx display (yet?).
927      *   Replacing the framebuffer with anonymous shared memory
928      *   instead.  This releases the guest pages and keeps qemu happy.
929      */
930     fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
931                       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
932                       -1, 0);
933     common_unbind(&fb->c);
934     fb->feature_update = 0;
935     fb->bug_trigger    = 0;
936 }
937
938 static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
939 {
940     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
941
942     /*
943      * Set state to Connected *again* once the frontend switched
944      * to connected.  We must trigger the watch a second time to
945      * workaround a frontend bug.
946      */
947     if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
948         xendev->fe_state == XenbusStateConnected &&
949         xendev->be_state == XenbusStateConnected) {
950         xen_be_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
951         xen_be_set_state(xendev, XenbusStateConnected);
952         fb->bug_trigger = 1; /* only once */
953     }
954 }
955
956 static void fb_event(struct XenDevice *xendev)
957 {
958     struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
959
960     xenfb_handle_events(xenfb);
961     xen_be_send_notify(&xenfb->c.xendev);
962 }
963
964 /* -------------------------------------------------------------------- */
965
966 struct XenDevOps xen_kbdmouse_ops = {
967     .size       = sizeof(struct XenInput),
968     .init       = input_init,
969     .initialise = input_initialise,
970     .connected  = input_connected,
971     .disconnect = input_disconnect,
972     .event      = input_event,
973 };
974
975 struct XenDevOps xen_framebuffer_ops = {
976     .size       = sizeof(struct XenFB),
977     .init       = fb_init,
978     .initialise = fb_initialise,
979     .disconnect = fb_disconnect,
980     .event      = fb_event,
981     .frontend_changed = fb_frontend_changed,
982 };
983
984 /*
985  * FIXME/TODO: Kill this.
986  * Temporary needed while DisplayState reorganization is in flight.
987  */
988 void xen_init_display(int domid)
989 {
990     struct XenDevice *xfb, *xin;
991     struct XenFB *fb;
992     struct XenInput *in;
993     int i = 0;
994
995 wait_more:
996     i++;
997     main_loop_wait(true);
998     xfb = xen_be_find_xendev("vfb", domid, 0);
999     xin = xen_be_find_xendev("vkbd", domid, 0);
1000     if (!xfb || !xin) {
1001         if (i < 256) {
1002             usleep(10000);
1003             goto wait_more;
1004         }
1005         xen_be_printf(NULL, 1, "displaystate setup failed\n");
1006         return;
1007     }
1008
1009     /* vfb */
1010     fb = container_of(xfb, struct XenFB, c.xendev);
1011     fb->c.ds = graphic_console_init(xenfb_update,
1012                                     xenfb_invalidate,
1013                                     NULL,
1014                                     NULL,
1015                                     fb);
1016     fb->have_console = 1;
1017
1018     /* vkbd */
1019     in = container_of(xin, struct XenInput, c.xendev);
1020     in->c.ds = fb->c.ds;
1021
1022     /* retry ->init() */
1023     xen_be_check_state(xin);
1024     xen_be_check_state(xfb);
1025 }