aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/kernel.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-02-26 14:47:23 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-02-26 14:47:23 +0000
commit26a1b308f37898b744d3b38477edcfb0a23b93cc (patch)
tree568602b1e4b7c88b844a5758baccdaaacc4b64ea /extras/mini-os/kernel.c
parent2e83dbdb929d8a553ffd2f82404e8169d1fe4134 (diff)
downloadxen-26a1b308f37898b744d3b38477edcfb0a23b93cc.tar.gz
xen-26a1b308f37898b744d3b38477edcfb0a23b93cc.tar.bz2
xen-26a1b308f37898b744d3b38477edcfb0a23b93cc.zip
minios: add PVFB support
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/kernel.c')
-rw-r--r--extras/mini-os/kernel.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c
index a94e743f63..107d0649a5 100644
--- a/extras/mini-os/kernel.c
+++ b/extras/mini-os/kernel.c
@@ -39,6 +39,7 @@
#include <gnttab.h>
#include <netfront.h>
#include <blkfront.h>
+#include <fbfront.h>
#include <fs.h>
#include <xmalloc.h>
#include <fcntl.h>
@@ -248,6 +249,152 @@ static void blkfront_thread(void *p)
}
}
+#define WIDTH 800
+#define HEIGHT 600
+#define DEPTH 32
+
+static uint32_t *fb;
+static struct fbfront_dev *fb_dev;
+static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0);
+
+static void fbfront_drawvert(int x, int y1, int y2, uint32_t color)
+{
+ int y;
+ if (x < 0)
+ return;
+ if (x >= WIDTH)
+ return;
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 >= HEIGHT)
+ y2 = HEIGHT-1;
+ for (y = y1; y <= y2; y++)
+ fb[x + y*WIDTH] ^= color;
+}
+
+static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color)
+{
+ int x;
+ if (y < 0)
+ return;
+ if (y >= HEIGHT)
+ return;
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 >= WIDTH)
+ x2 = WIDTH-1;
+ for (x = x1; x <= x2; x++)
+ fb[x + y*WIDTH] ^= color;
+}
+
+static void fbfront_thread(void *p)
+{
+ size_t line_length = WIDTH * (DEPTH / 8);
+ size_t memsize = HEIGHT * line_length;
+
+ fb = _xmalloc(memsize, PAGE_SIZE);
+ fb_dev = init_fbfront(NULL, fb, WIDTH, HEIGHT, DEPTH, line_length, memsize);
+ if (!fb_dev) {
+ xfree(fb);
+ return;
+ }
+ up(&fbfront_sem);
+}
+
+static void clip_cursor(int *x, int *y)
+{
+ if (*x < 0)
+ *x = 0;
+ if (*x >= WIDTH)
+ *x = WIDTH - 1;
+ if (*y < 0)
+ *y = 0;
+ if (*y >= HEIGHT)
+ *y = HEIGHT - 1;
+}
+
+static void refresh_cursor(int new_x, int new_y)
+{
+ static int old_x = -1, old_y = -1;
+ if (old_x != -1 && old_y != -1) {
+ fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff);
+ fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff);
+ fbfront_update(fb_dev, old_x, old_y, 9, 9);
+ }
+ old_x = new_x;
+ old_y = new_y;
+ fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff);
+ fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff);
+ fbfront_update(fb_dev, new_x, new_y, 9, 9);
+}
+
+static void kbdfront_thread(void *p)
+{
+ struct kbdfront_dev *kbd_dev;
+ DEFINE_WAIT(w);
+ int x = WIDTH / 2, y = HEIGHT / 2, z;
+
+ kbd_dev = init_kbdfront(NULL, 1);
+ if (!kbd_dev)
+ return;
+
+ down(&fbfront_sem);
+ refresh_cursor(x, y);
+ while (1) {
+ union xenkbd_in_event event;
+
+ add_waiter(w, kbdfront_queue);
+
+ if (kbdfront_receive(kbd_dev, &event, 1) == 0)
+ schedule();
+ else switch(event.type) {
+ case XENKBD_TYPE_MOTION:
+ printk("motion x:%d y:%d z:%d\n",
+ event.motion.rel_x,
+ event.motion.rel_y,
+ event.motion.rel_z);
+ x += event.motion.rel_x;
+ y += event.motion.rel_y;
+ z += event.motion.rel_z;
+ clip_cursor(&x, &y);
+ refresh_cursor(x, y);
+ break;
+ case XENKBD_TYPE_POS:
+ printk("pos x:%d y:%d z:%d\n",
+ event.pos.abs_x,
+ event.pos.abs_y,
+ event.pos.abs_z);
+ x = event.pos.abs_x;
+ y = event.pos.abs_y;
+ z = event.pos.abs_z;
+ clip_cursor(&x, &y);
+ refresh_cursor(x, y);
+ break;
+ case XENKBD_TYPE_KEY:
+ printk("key %d %s\n",
+ event.key.keycode,
+ event.key.pressed ? "pressed" : "released");
+ if (event.key.keycode == BTN_LEFT) {
+ printk("mouse %s at (%d,%d,%d)\n",
+ event.key.pressed ? "clic" : "release", x, y, z);
+ if (event.key.pressed) {
+ uint32_t color = rand();
+ fbfront_drawvert(x - 16, y - 16, y + 15, color);
+ fbfront_drawhoriz(x - 16, x + 15, y + 16, color);
+ fbfront_drawvert(x + 16, y - 15, y + 16, color);
+ fbfront_drawhoriz(x - 15, x + 16, y - 16, color);
+ fbfront_update(fb_dev, x - 16, y - 16, 33, 33);
+ }
+ } else if (event.key.keycode == KEY_Q) {
+ struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
+ HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+ do_exit();
+ }
+ break;
+ }
+ }
+}
+
static void fs_thread(void *p)
{
init_fs_frontend();
@@ -261,6 +408,8 @@ __attribute__((weak)) int app_main(start_info_t *si)
create_thread("periodic_thread", periodic_thread, si);
create_thread("netfront", netfront_thread, si);
create_thread("blkfront", blkfront_thread, si);
+ create_thread("fbfront", fbfront_thread, si);
+ create_thread("kbdfront", kbdfront_thread, si);
create_thread("fs-frontend", fs_thread, si);
return 0;
}