ia64/xen-unstable

changeset 17872:3d99b9d82208

ioemu: move xenfb frontend (used by stubdom) to its own file, since it
does not really belong to hw/, but to /, like sdl.c and vnc.c.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 17 09:35:36 2008 +0100 (2008-06-17)
parents 0df3bf8aac1e
children 7e00ebe2b7fd
files tools/ioemu/Makefile.target tools/ioemu/hw/xenfb.c tools/ioemu/hw/xenfb.h tools/ioemu/xenfbfront.c
line diff
     1.1 --- a/tools/ioemu/Makefile.target	Mon Jun 16 16:35:17 2008 +0100
     1.2 +++ b/tools/ioemu/Makefile.target	Tue Jun 17 09:35:36 2008 +0100
     1.3 @@ -444,6 +444,9 @@ VL_OBJS+= xen_platform.o
     1.4  VL_OBJS+= xen_machine_fv.o
     1.5  VL_OBJS+= xen_machine_pv.o
     1.6  VL_OBJS+= xenfb.o
     1.7 +ifdef CONFIG_STUBDOM
     1.8 +VL_OBJS+= xenfbfront.o
     1.9 +endif
    1.10  VL_OBJS+= xen_console.o
    1.11  ifndef CONFIG_STUBDOM
    1.12  VL_OBJS+= tpm_tis.o
     2.1 --- a/tools/ioemu/hw/xenfb.c	Mon Jun 16 16:35:17 2008 +0100
     2.2 +++ b/tools/ioemu/hw/xenfb.c	Tue Jun 17 09:35:36 2008 +0100
     2.3 @@ -19,12 +19,6 @@
     2.4  
     2.5  #include "xenfb.h"
     2.6  
     2.7 -#ifdef CONFIG_STUBDOM
     2.8 -#include <semaphore.h>
     2.9 -#include <sched.h>
    2.10 -#include <fbfront.h>
    2.11 -#endif
    2.12 -
    2.13  #ifndef BTN_LEFT
    2.14  #define BTN_LEFT 0x110 /* from <linux/input.h> */
    2.15  #endif
    2.16 @@ -90,7 +84,7 @@ static int xenfb_register_console(struct
    2.17   * Scancodes are hardware-specific.  These maps assumes a 
    2.18   * standard AT or PS/2 keyboard which is what QEMU feeds us.
    2.19   */
    2.20 -static const unsigned char atkbd_set2_keycode[512] = {
    2.21 +const unsigned char atkbd_set2_keycode[512] = {
    2.22  
    2.23  	  0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
    2.24  	  0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
    2.25 @@ -112,7 +106,7 @@ static const unsigned char atkbd_set2_ke
    2.26  
    2.27  };
    2.28  
    2.29 -static const unsigned char atkbd_unxlate_table[128] = {
    2.30 +const unsigned char atkbd_unxlate_table[128] = {
    2.31  
    2.32  	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
    2.33  	 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
    2.34 @@ -1338,313 +1332,6 @@ static int xenfb_register_console(struct
    2.35          return 0;
    2.36  }
    2.37  
    2.38 -#ifdef CONFIG_STUBDOM
    2.39 -typedef struct XenFBState {
    2.40 -    struct semaphore kbd_sem;
    2.41 -    struct kbdfront_dev *kbd_dev;
    2.42 -    struct fbfront_dev *fb_dev;
    2.43 -    void *vga_vram, *nonshared_vram;
    2.44 -    DisplayState *ds;
    2.45 -} XenFBState;
    2.46 -
    2.47 -XenFBState *xs;
    2.48 -
    2.49 -static char *kbd_path, *fb_path;
    2.50 -
    2.51 -static unsigned char linux2scancode[KEY_MAX + 1];
    2.52 -
    2.53 -int xenfb_connect_vkbd(const char *path)
    2.54 -{
    2.55 -    kbd_path = strdup(path);
    2.56 -    return 0;
    2.57 -}
    2.58 -
    2.59 -int xenfb_connect_vfb(const char *path)
    2.60 -{
    2.61 -    fb_path = strdup(path);
    2.62 -    return 0;
    2.63 -}
    2.64 -
    2.65 -static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
    2.66 -{
    2.67 -    XenFBState *xs = ds->opaque;
    2.68 -    struct fbfront_dev *fb_dev = xs->fb_dev;
    2.69 -    if (!fb_dev)
    2.70 -        return;
    2.71 -    fbfront_update(fb_dev, x, y, w, h);
    2.72 -}
    2.73 -
    2.74 -static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
    2.75 -{
    2.76 -    XenFBState *xs = ds->opaque;
    2.77 -    struct fbfront_dev *fb_dev = xs->fb_dev;
    2.78 -    int offset;
    2.79 -
    2.80 -    fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
    2.81 -    ds->width = w;
    2.82 -    ds->height = h;
    2.83 -    if (!depth) {
    2.84 -        ds->shared_buf = 0;
    2.85 -        ds->depth = 32;
    2.86 -    } else {
    2.87 -        ds->shared_buf = 1;
    2.88 -        ds->depth = depth;
    2.89 -    }
    2.90 -    if (!linesize)
    2.91 -        ds->shared_buf = 0;
    2.92 -    if (!ds->shared_buf)
    2.93 -        linesize = w * 4;
    2.94 -    ds->linesize = linesize;
    2.95 -    if (!fb_dev)
    2.96 -        return;
    2.97 -    if (ds->shared_buf) {
    2.98 -        offset = pixels - xs->vga_vram;
    2.99 -        ds->data = pixels;
   2.100 -        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
   2.101 -    } else {
   2.102 -        ds->data = xs->nonshared_vram;
   2.103 -        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
   2.104 -    }
   2.105 -}
   2.106 -
   2.107 -static void xenfb_pv_resize(DisplayState *ds, int w, int h)
   2.108 -{
   2.109 -    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
   2.110 -}
   2.111 -
   2.112 -static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
   2.113 -{
   2.114 -    XenFBState *xs = ds->opaque;
   2.115 -    struct fbfront_dev *fb_dev = xs->fb_dev;
   2.116 -    int offset = pixels - xs->vga_vram;
   2.117 -    ds->data = pixels;
   2.118 -    if (!fb_dev)
   2.119 -        return;
   2.120 -    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
   2.121 -}
   2.122 -
   2.123 -static void xenfb_pv_refresh(DisplayState *ds)
   2.124 -{
   2.125 -    vga_hw_update();
   2.126 -}
   2.127 -
   2.128 -static void xenfb_fb_handler(void *opaque)
   2.129 -{
   2.130 -#define FB_NUM_BATCH 4
   2.131 -    union xenfb_in_event buf[FB_NUM_BATCH];
   2.132 -    int n, i;
   2.133 -    XenFBState *xs = opaque;
   2.134 -    DisplayState *ds = xs->ds;
   2.135 -
   2.136 -    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
   2.137 -    for (i = 0; i < n; i++) {
   2.138 -        switch (buf[i].type) {
   2.139 -        case XENFB_TYPE_REFRESH_PERIOD:
   2.140 -            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
   2.141 -                /* Sleeping interval */
   2.142 -                ds->idle = 1;
   2.143 -                ds->gui_timer_interval = 500;
   2.144 -            } else {
   2.145 -                /* Set interval */
   2.146 -                ds->idle = 0;
   2.147 -                ds->gui_timer_interval = buf[i].refresh_period.period;
   2.148 -            }
   2.149 -        default:
   2.150 -            /* ignore unknown events */
   2.151 -            break;
   2.152 -        }
   2.153 -    }
   2.154 -}
   2.155 -
   2.156 -static void xenfb_kbd_handler(void *opaque)
   2.157 -{
   2.158 -#define KBD_NUM_BATCH 64
   2.159 -    union xenkbd_in_event buf[KBD_NUM_BATCH];
   2.160 -    int n, i;
   2.161 -    XenFBState *xs = opaque;
   2.162 -    DisplayState *s = xs->ds;
   2.163 -    static int buttons;
   2.164 -    static int x, y;
   2.165 -
   2.166 -    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
   2.167 -    for (i = 0; i < n; i++) {
   2.168 -        switch (buf[i].type) {
   2.169 -
   2.170 -            case XENKBD_TYPE_MOTION:
   2.171 -                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
   2.172 -                break;
   2.173 -
   2.174 -            case XENKBD_TYPE_POS:
   2.175 -            {
   2.176 -                int new_x = buf[i].pos.abs_x;
   2.177 -                int new_y = buf[i].pos.abs_y;
   2.178 -                if (new_x >= s->width)
   2.179 -                    new_x = s->width - 1;
   2.180 -                if (new_y >= s->height)
   2.181 -                    new_y = s->height - 1;
   2.182 -                if (kbd_mouse_is_absolute()) {
   2.183 -                    kbd_mouse_event(
   2.184 -                            new_x * 0x7FFF / (s->width - 1),
   2.185 -                            new_y * 0x7FFF / (s->height - 1),
   2.186 -                            buf[i].pos.rel_z,
   2.187 -                            buttons);
   2.188 -                } else {
   2.189 -                    kbd_mouse_event(
   2.190 -                            new_x - x,
   2.191 -                            new_y - y,
   2.192 -                            buf[i].pos.rel_z,
   2.193 -                            buttons);
   2.194 -                }
   2.195 -                x = new_x;
   2.196 -                y = new_y;
   2.197 -                break;
   2.198 -            }
   2.199 -
   2.200 -            case XENKBD_TYPE_KEY:
   2.201 -            {
   2.202 -                int keycode = buf[i].key.keycode;
   2.203 -                int button = 0;
   2.204 -
   2.205 -                if (keycode == BTN_LEFT)
   2.206 -                    button = MOUSE_EVENT_LBUTTON;
   2.207 -                else if (keycode == BTN_RIGHT)
   2.208 -                    button = MOUSE_EVENT_RBUTTON;
   2.209 -                else if (keycode == BTN_MIDDLE)
   2.210 -                    button = MOUSE_EVENT_MBUTTON;
   2.211 -
   2.212 -                if (button) {
   2.213 -                    if (buf[i].key.pressed)
   2.214 -                        buttons |=  button;
   2.215 -                    else
   2.216 -                        buttons &= ~button;
   2.217 -                    if (kbd_mouse_is_absolute())
   2.218 -                        kbd_mouse_event(
   2.219 -                                x * 0x7FFF / (s->width - 1),
   2.220 -                                y * 0x7FFF / (s->height - 1),
   2.221 -                                0,
   2.222 -                                buttons);
   2.223 -                    else
   2.224 -                        kbd_mouse_event(0, 0, 0, buttons);
   2.225 -                } else {
   2.226 -                    int scancode = linux2scancode[keycode];
   2.227 -                    if (!scancode) {
   2.228 -                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
   2.229 -                        break;
   2.230 -                    }
   2.231 -                    if (scancode & 0x80) {
   2.232 -                        kbd_put_keycode(0xe0);
   2.233 -                        scancode &= 0x7f;
   2.234 -                    }
   2.235 -                    if (!buf[i].key.pressed)
   2.236 -                        scancode |= 0x80;
   2.237 -                    kbd_put_keycode(scancode);
   2.238 -                }
   2.239 -                break;
   2.240 -            }
   2.241 -        }
   2.242 -    }
   2.243 -}
   2.244 -
   2.245 -static void kbdfront_thread(void *p)
   2.246 -{
   2.247 -    int scancode, keycode;
   2.248 -    XenFBState *xs = p;
   2.249 -    xs->kbd_dev = init_kbdfront(kbd_path, 1);
   2.250 -    if (!xs->kbd_dev) {
   2.251 -        fprintf(stderr,"can't open keyboard\n");
   2.252 -        exit(1);
   2.253 -    }
   2.254 -    up(&xs->kbd_sem);
   2.255 -    for (scancode = 0; scancode < 128; scancode++) {
   2.256 -        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
   2.257 -        linux2scancode[keycode] = scancode;
   2.258 -        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
   2.259 -        linux2scancode[keycode] = scancode | 0x80;
   2.260 -    }
   2.261 -}
   2.262 -
   2.263 -int xenfb_pv_display_init(DisplayState *ds)
   2.264 -{
   2.265 -    if (!fb_path || !kbd_path)
   2.266 -        return -1;
   2.267 -
   2.268 -    xs = qemu_mallocz(sizeof(XenFBState));
   2.269 -    if (!xs)
   2.270 -        return -1;
   2.271 -
   2.272 -    init_SEMAPHORE(&xs->kbd_sem, 0);
   2.273 -    xs->ds = ds;
   2.274 -
   2.275 -    create_thread("kbdfront", kbdfront_thread, (void*) xs);
   2.276 -
   2.277 -    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
   2.278 -    memset(ds->data, 0, VGA_RAM_SIZE);
   2.279 -    ds->opaque = xs;
   2.280 -    ds->depth = 32;
   2.281 -    ds->bgr = 0;
   2.282 -    ds->width = 640;
   2.283 -    ds->height = 400;
   2.284 -    ds->linesize = 640 * 4;
   2.285 -    ds->dpy_update = xenfb_pv_update;
   2.286 -    ds->dpy_resize = xenfb_pv_resize;
   2.287 -    ds->dpy_resize_shared = xenfb_pv_resize_shared;
   2.288 -    ds->dpy_setdata = xenfb_pv_setdata;
   2.289 -    ds->dpy_refresh = xenfb_pv_refresh;
   2.290 -    return 0;
   2.291 -}
   2.292 -
   2.293 -int xenfb_pv_display_start(void *data)
   2.294 -{
   2.295 -    DisplayState *ds;
   2.296 -    struct fbfront_dev *fb_dev;
   2.297 -    int kbd_fd, fb_fd;
   2.298 -    int offset = 0;
   2.299 -    unsigned long *mfns;
   2.300 -    int n = VGA_RAM_SIZE / PAGE_SIZE;
   2.301 -    int i;
   2.302 -
   2.303 -    if (!fb_path || !kbd_path)
   2.304 -        return 0;
   2.305 -
   2.306 -    ds = xs->ds;
   2.307 -    xs->vga_vram = data;
   2.308 -    mfns = malloc(2 * n * sizeof(*mfns));
   2.309 -    for (i = 0; i < n; i++)
   2.310 -        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
   2.311 -    for (i = 0; i < n; i++)
   2.312 -        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
   2.313 -
   2.314 -    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
   2.315 -    free(mfns);
   2.316 -    if (!fb_dev) {
   2.317 -        fprintf(stderr,"can't open frame buffer\n");
   2.318 -        exit(1);
   2.319 -    }
   2.320 -    free(fb_path);
   2.321 -
   2.322 -    if (ds->shared_buf) {
   2.323 -        offset = (void*) ds->data - xs->vga_vram;
   2.324 -    } else {
   2.325 -        offset = VGA_RAM_SIZE;
   2.326 -        ds->data = xs->nonshared_vram;
   2.327 -    }
   2.328 -    if (offset)
   2.329 -        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
   2.330 -
   2.331 -    down(&xs->kbd_sem);
   2.332 -    free(kbd_path);
   2.333 -
   2.334 -    kbd_fd = kbdfront_open(xs->kbd_dev);
   2.335 -    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
   2.336 -
   2.337 -    fb_fd = fbfront_open(fb_dev);
   2.338 -    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
   2.339 -
   2.340 -    xs->fb_dev = fb_dev;
   2.341 -    return 0;
   2.342 -}
   2.343 -#endif
   2.344 -
   2.345  /*
   2.346   * Local variables:
   2.347   *  c-indent-level: 8
     3.1 --- a/tools/ioemu/hw/xenfb.h	Mon Jun 16 16:35:17 2008 +0100
     3.2 +++ b/tools/ioemu/hw/xenfb.h	Tue Jun 17 09:35:36 2008 +0100
     3.3 @@ -9,5 +9,7 @@ struct xenfb;
     3.4  
     3.5  struct xenfb *xenfb_new(int domid, DisplayState *ds);
     3.6  void xenfb_shutdown(struct xenfb *xenfb);
     3.7 +extern const unsigned char atkbd_set2_keycode[512];
     3.8 +extern const unsigned char atkbd_unxlate_table[128];
     3.9  
    3.10  #endif
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/ioemu/xenfbfront.c	Tue Jun 17 09:35:36 2008 +0100
     4.3 @@ -0,0 +1,315 @@
     4.4 +#include <stdint.h>
     4.5 +#include <xen/io/fbif.h>
     4.6 +#include <xen/io/kbdif.h>
     4.7 +#include <semaphore.h>
     4.8 +#include <sched.h>
     4.9 +#include <fbfront.h>
    4.10 +
    4.11 +#include <hw/xenfb.h>
    4.12 +
    4.13 +#include "vl.h"
    4.14 +
    4.15 +typedef struct XenFBState {
    4.16 +    struct semaphore kbd_sem;
    4.17 +    struct kbdfront_dev *kbd_dev;
    4.18 +    struct fbfront_dev *fb_dev;
    4.19 +    void *vga_vram, *nonshared_vram;
    4.20 +    DisplayState *ds;
    4.21 +} XenFBState;
    4.22 +
    4.23 +XenFBState *xs;
    4.24 +
    4.25 +static char *kbd_path, *fb_path;
    4.26 +
    4.27 +static unsigned char linux2scancode[KEY_MAX + 1];
    4.28 +
    4.29 +int xenfb_connect_vkbd(const char *path)
    4.30 +{
    4.31 +    kbd_path = strdup(path);
    4.32 +    return 0;
    4.33 +}
    4.34 +
    4.35 +int xenfb_connect_vfb(const char *path)
    4.36 +{
    4.37 +    fb_path = strdup(path);
    4.38 +    return 0;
    4.39 +}
    4.40 +
    4.41 +static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
    4.42 +{
    4.43 +    XenFBState *xs = ds->opaque;
    4.44 +    struct fbfront_dev *fb_dev = xs->fb_dev;
    4.45 +    if (!fb_dev)
    4.46 +        return;
    4.47 +    fbfront_update(fb_dev, x, y, w, h);
    4.48 +}
    4.49 +
    4.50 +static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
    4.51 +{
    4.52 +    XenFBState *xs = ds->opaque;
    4.53 +    struct fbfront_dev *fb_dev = xs->fb_dev;
    4.54 +    int offset;
    4.55 +
    4.56 +    fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
    4.57 +    ds->width = w;
    4.58 +    ds->height = h;
    4.59 +    if (!depth) {
    4.60 +        ds->shared_buf = 0;
    4.61 +        ds->depth = 32;
    4.62 +    } else {
    4.63 +        ds->shared_buf = 1;
    4.64 +        ds->depth = depth;
    4.65 +    }
    4.66 +    if (!linesize)
    4.67 +        ds->shared_buf = 0;
    4.68 +    if (!ds->shared_buf)
    4.69 +        linesize = w * 4;
    4.70 +    ds->linesize = linesize;
    4.71 +    if (!fb_dev)
    4.72 +        return;
    4.73 +    if (ds->shared_buf) {
    4.74 +        offset = pixels - xs->vga_vram;
    4.75 +        ds->data = pixels;
    4.76 +        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
    4.77 +    } else {
    4.78 +        ds->data = xs->nonshared_vram;
    4.79 +        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
    4.80 +    }
    4.81 +}
    4.82 +
    4.83 +static void xenfb_pv_resize(DisplayState *ds, int w, int h)
    4.84 +{
    4.85 +    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
    4.86 +}
    4.87 +
    4.88 +static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
    4.89 +{
    4.90 +    XenFBState *xs = ds->opaque;
    4.91 +    struct fbfront_dev *fb_dev = xs->fb_dev;
    4.92 +    int offset = pixels - xs->vga_vram;
    4.93 +    ds->data = pixels;
    4.94 +    if (!fb_dev)
    4.95 +        return;
    4.96 +    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
    4.97 +}
    4.98 +
    4.99 +static void xenfb_pv_refresh(DisplayState *ds)
   4.100 +{
   4.101 +    vga_hw_update();
   4.102 +}
   4.103 +
   4.104 +static void xenfb_fb_handler(void *opaque)
   4.105 +{
   4.106 +#define FB_NUM_BATCH 4
   4.107 +    union xenfb_in_event buf[FB_NUM_BATCH];
   4.108 +    int n, i;
   4.109 +    XenFBState *xs = opaque;
   4.110 +    DisplayState *ds = xs->ds;
   4.111 +
   4.112 +    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
   4.113 +    for (i = 0; i < n; i++) {
   4.114 +        switch (buf[i].type) {
   4.115 +        case XENFB_TYPE_REFRESH_PERIOD:
   4.116 +            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
   4.117 +                /* Sleeping interval */
   4.118 +                ds->idle = 1;
   4.119 +                ds->gui_timer_interval = 500;
   4.120 +            } else {
   4.121 +                /* Set interval */
   4.122 +                ds->idle = 0;
   4.123 +                ds->gui_timer_interval = buf[i].refresh_period.period;
   4.124 +            }
   4.125 +        default:
   4.126 +            /* ignore unknown events */
   4.127 +            break;
   4.128 +        }
   4.129 +    }
   4.130 +}
   4.131 +
   4.132 +static void xenfb_kbd_handler(void *opaque)
   4.133 +{
   4.134 +#define KBD_NUM_BATCH 64
   4.135 +    union xenkbd_in_event buf[KBD_NUM_BATCH];
   4.136 +    int n, i;
   4.137 +    XenFBState *xs = opaque;
   4.138 +    DisplayState *s = xs->ds;
   4.139 +    static int buttons;
   4.140 +    static int x, y;
   4.141 +
   4.142 +    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
   4.143 +    for (i = 0; i < n; i++) {
   4.144 +        switch (buf[i].type) {
   4.145 +
   4.146 +            case XENKBD_TYPE_MOTION:
   4.147 +                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
   4.148 +                break;
   4.149 +
   4.150 +            case XENKBD_TYPE_POS:
   4.151 +            {
   4.152 +                int new_x = buf[i].pos.abs_x;
   4.153 +                int new_y = buf[i].pos.abs_y;
   4.154 +                if (new_x >= s->width)
   4.155 +                    new_x = s->width - 1;
   4.156 +                if (new_y >= s->height)
   4.157 +                    new_y = s->height - 1;
   4.158 +                if (kbd_mouse_is_absolute()) {
   4.159 +                    kbd_mouse_event(
   4.160 +                            new_x * 0x7FFF / (s->width - 1),
   4.161 +                            new_y * 0x7FFF / (s->height - 1),
   4.162 +                            buf[i].pos.rel_z,
   4.163 +                            buttons);
   4.164 +                } else {
   4.165 +                    kbd_mouse_event(
   4.166 +                            new_x - x,
   4.167 +                            new_y - y,
   4.168 +                            buf[i].pos.rel_z,
   4.169 +                            buttons);
   4.170 +                }
   4.171 +                x = new_x;
   4.172 +                y = new_y;
   4.173 +                break;
   4.174 +            }
   4.175 +
   4.176 +            case XENKBD_TYPE_KEY:
   4.177 +            {
   4.178 +                int keycode = buf[i].key.keycode;
   4.179 +                int button = 0;
   4.180 +
   4.181 +                if (keycode == BTN_LEFT)
   4.182 +                    button = MOUSE_EVENT_LBUTTON;
   4.183 +                else if (keycode == BTN_RIGHT)
   4.184 +                    button = MOUSE_EVENT_RBUTTON;
   4.185 +                else if (keycode == BTN_MIDDLE)
   4.186 +                    button = MOUSE_EVENT_MBUTTON;
   4.187 +
   4.188 +                if (button) {
   4.189 +                    if (buf[i].key.pressed)
   4.190 +                        buttons |=  button;
   4.191 +                    else
   4.192 +                        buttons &= ~button;
   4.193 +                    if (kbd_mouse_is_absolute())
   4.194 +                        kbd_mouse_event(
   4.195 +                                x * 0x7FFF / (s->width - 1),
   4.196 +                                y * 0x7FFF / (s->height - 1),
   4.197 +                                0,
   4.198 +                                buttons);
   4.199 +                    else
   4.200 +                        kbd_mouse_event(0, 0, 0, buttons);
   4.201 +                } else {
   4.202 +                    int scancode = linux2scancode[keycode];
   4.203 +                    if (!scancode) {
   4.204 +                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
   4.205 +                        break;
   4.206 +                    }
   4.207 +                    if (scancode & 0x80) {
   4.208 +                        kbd_put_keycode(0xe0);
   4.209 +                        scancode &= 0x7f;
   4.210 +                    }
   4.211 +                    if (!buf[i].key.pressed)
   4.212 +                        scancode |= 0x80;
   4.213 +                    kbd_put_keycode(scancode);
   4.214 +                }
   4.215 +                break;
   4.216 +            }
   4.217 +        }
   4.218 +    }
   4.219 +}
   4.220 +
   4.221 +static void kbdfront_thread(void *p)
   4.222 +{
   4.223 +    int scancode, keycode;
   4.224 +    XenFBState *xs = p;
   4.225 +    xs->kbd_dev = init_kbdfront(kbd_path, 1);
   4.226 +    if (!xs->kbd_dev) {
   4.227 +        fprintf(stderr,"can't open keyboard\n");
   4.228 +        exit(1);
   4.229 +    }
   4.230 +    up(&xs->kbd_sem);
   4.231 +    for (scancode = 0; scancode < 128; scancode++) {
   4.232 +        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
   4.233 +        linux2scancode[keycode] = scancode;
   4.234 +        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
   4.235 +        linux2scancode[keycode] = scancode | 0x80;
   4.236 +    }
   4.237 +}
   4.238 +
   4.239 +int xenfb_pv_display_init(DisplayState *ds)
   4.240 +{
   4.241 +    if (!fb_path || !kbd_path)
   4.242 +        return -1;
   4.243 +
   4.244 +    xs = qemu_mallocz(sizeof(XenFBState));
   4.245 +    if (!xs)
   4.246 +        return -1;
   4.247 +
   4.248 +    init_SEMAPHORE(&xs->kbd_sem, 0);
   4.249 +    xs->ds = ds;
   4.250 +
   4.251 +    create_thread("kbdfront", kbdfront_thread, (void*) xs);
   4.252 +
   4.253 +    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
   4.254 +    memset(ds->data, 0, VGA_RAM_SIZE);
   4.255 +    ds->opaque = xs;
   4.256 +    ds->depth = 32;
   4.257 +    ds->bgr = 0;
   4.258 +    ds->width = 640;
   4.259 +    ds->height = 400;
   4.260 +    ds->linesize = 640 * 4;
   4.261 +    ds->dpy_update = xenfb_pv_update;
   4.262 +    ds->dpy_resize = xenfb_pv_resize;
   4.263 +    ds->dpy_resize_shared = xenfb_pv_resize_shared;
   4.264 +    ds->dpy_setdata = xenfb_pv_setdata;
   4.265 +    ds->dpy_refresh = xenfb_pv_refresh;
   4.266 +    return 0;
   4.267 +}
   4.268 +
   4.269 +int xenfb_pv_display_start(void *data)
   4.270 +{
   4.271 +    DisplayState *ds;
   4.272 +    struct fbfront_dev *fb_dev;
   4.273 +    int kbd_fd, fb_fd;
   4.274 +    int offset = 0;
   4.275 +    unsigned long *mfns;
   4.276 +    int n = VGA_RAM_SIZE / PAGE_SIZE;
   4.277 +    int i;
   4.278 +
   4.279 +    if (!fb_path || !kbd_path)
   4.280 +        return 0;
   4.281 +
   4.282 +    ds = xs->ds;
   4.283 +    xs->vga_vram = data;
   4.284 +    mfns = malloc(2 * n * sizeof(*mfns));
   4.285 +    for (i = 0; i < n; i++)
   4.286 +        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
   4.287 +    for (i = 0; i < n; i++)
   4.288 +        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
   4.289 +
   4.290 +    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
   4.291 +    free(mfns);
   4.292 +    if (!fb_dev) {
   4.293 +        fprintf(stderr,"can't open frame buffer\n");
   4.294 +        exit(1);
   4.295 +    }
   4.296 +    free(fb_path);
   4.297 +
   4.298 +    if (ds->shared_buf) {
   4.299 +        offset = (void*) ds->data - xs->vga_vram;
   4.300 +    } else {
   4.301 +        offset = VGA_RAM_SIZE;
   4.302 +        ds->data = xs->nonshared_vram;
   4.303 +    }
   4.304 +    if (offset)
   4.305 +        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
   4.306 +
   4.307 +    down(&xs->kbd_sem);
   4.308 +    free(kbd_path);
   4.309 +
   4.310 +    kbd_fd = kbdfront_open(xs->kbd_dev);
   4.311 +    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
   4.312 +
   4.313 +    fb_fd = fbfront_open(fb_dev);
   4.314 +    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
   4.315 +
   4.316 +    xs->fb_dev = fb_dev;
   4.317 +    return 0;
   4.318 +}