WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH] Paravirt framebuffer kernel infrastructure [1/6]

To: Jeremy Katz <katzj@xxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH] Paravirt framebuffer kernel infrastructure [1/6]
From: Laurent Vivier <Laurent.Vivier@xxxxxxxx>
Date: Tue, 29 Aug 2006 16:39:29 +0200
Cc: Ian Pratt <ian.pratt@xxxxxxxxxxxxx>, Anthony Liguori <aliguori@xxxxxxxxxx>, xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>, Markus Armbruster <armbru@xxxxxxxxxx>, Christian Limpach <chris@xxxxxxxxxxxxx>
Delivery-date: Tue, 29 Aug 2006 07:40:25 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <1155935110.11663.49.camel@xxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Organization: Bull S.A.S.
References: <1155935110.11663.49.camel@xxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5.0.2 (X11/20060420)
Hi,

IMHO, I think it should be better to move the refresh timer from kernel to user
space, and to know which part of the image to refresh, a bitmap array should be
easy to use than an event ring.

I propose following patches to do this.

Any comments ?

Regards,
Laurent

Index: xen-3.0-testing.hg/linux-2.6.16.13-xen/drivers/xen/xenfb/xenfb.c
===================================================================
--- xen-3.0-testing.hg.orig/linux-2.6.16.13-xen/drivers/xen/xenfb/xenfb.c
2006-08-29 12:16:49.000000000 +0200
+++ xen-3.0-testing.hg/linux-2.6.16.13-xen/drivers/xen/xenfb/xenfb.c    
2006-08-29
16:15:04.000000000 +0200
@@ -24,118 +24,33 @@
 #include <linux/xenfb.h>
 #include <linux/kthread.h>

-static int xenfb_fps = 20;
-static unsigned long xenfb_mem_len = 2 * 1024 * 1024;
+static unsigned long xenfb_mem_len = XENFB_VIDEOMEM_SIZE;

 struct xenfb_mapping
 {
-       struct list_head        next;
        struct vm_area_struct   *vma;
        atomic_t                map_refs;
-       int                     faults;
        struct xenfb_info       *info;
 };

 struct xenfb_info
 {
-       struct task_struct              *kthread;
-       wait_queue_head_t               wq;
-
        unsigned char                   *fb;
        struct fb_fix_screeninfo        *fix;
        struct fb_var_screeninfo        *var;
        struct fb_info                  *fb_info;
-       struct timer_list               refresh;
-       int                             dirty;
        int                             y1, y2;
        int                             x1, x2;

        struct semaphore                mm_lock;
        int                             nr_pages;
        struct page                     **pages;
-       struct list_head                mappings;

        unsigned                        evtchn;
        struct xenfb_page               *page;
        unsigned long                   *mfns;
 };

-static void xenfb_do_update(struct xenfb_info *info,
-                           int x, int y, int w, int h)
-{
-       union xenfb_out_event event;
-       __u32 prod;
-
-       event.type = XENFB_TYPE_UPDATE;
-       event.update.x = x;
-       event.update.y = y;
-       event.update.width = w;
-       event.update.height = h;
-
-       prod = info->page->out_prod;
-       if (prod - info->page->out_cons == XENFB_RING_SIZE(info->page->out))
-               return;         /* ring buffer full, event lost */
-       XENFB_RING_REF(info->page->out, prod) = event;
-       info->page->out_prod = prod + 1;
-
-       notify_remote_via_evtchn(info->evtchn);
-}
-
-static int xenfb_queue_full(struct xenfb_info *info)
-{
-       __u32 cons, prod;
-
-       prod = info->page->out_prod;
-       cons = info->page->out_cons;
-       return prod - cons == XENFB_RING_SIZE(info->page->out);
-}
-
-static void xenfb_update_screen(struct xenfb_info *info)
-{
-       int y1, y2, x1, x2;
-       struct list_head *item;
-       struct xenfb_mapping *map;
-
-       if (xenfb_queue_full(info))
-               return;
-
-       y1 = info->y1;
-       y2 = info->y2;
-       x1 = info->x1;
-       x2 = info->x2;
-       info->dirty = info->y1 = info->y2 = info->x1 = info->x2 = 0;
-       down(&info->mm_lock);
-       list_for_each(item, &info->mappings) {
-               map = list_entry(item, struct xenfb_mapping, next);
-               if (!map->faults)
-                       continue;
-               zap_page_range(map->vma, map->vma->vm_start,
-                              map->vma->vm_end - map->vma->vm_start, NULL);
-               map->faults = 0;
-       }
-       up(&info->mm_lock);
-
-       xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
-}
-
-static int xenfb_thread(void *data)
-{
-       struct xenfb_info *info = data;
-       DECLARE_WAITQUEUE(wait, current);
-
-       add_wait_queue(&info->wq, &wait);
-       for (;;) {
-               if (kthread_should_stop())
-                       break;
-               if (info->dirty)
-                       xenfb_update_screen(info);
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule();
-       }
-       remove_wait_queue(&info->wq, &wait);
-       return 0;
-}
-
 static int xenfb_setcolreg(unsigned regno, unsigned red, unsigned green,
                           unsigned blue, unsigned transp,
                           struct fb_info *info)
@@ -164,50 +79,24 @@ static int xenfb_setcolreg(unsigned regn
        return 0;
 }

-static void xenfb_timer(unsigned long data)
+static void xenfb_update_pages(struct xenfb_info *info, int x, int y, int w, 
int h)
 {
-       struct xenfb_info *info = (struct xenfb_info *)data;
-       info->dirty++;
-       wake_up(&info->wq);
-}
-
-static void xenfb_refresh(struct xenfb_info *info,
-                         int x1, int y1, int w, int h)
-{
-       int y2, x2;
-
-       y2 = y1 + h;
-       x2 = x1 + w;
-       if (info->y2 == 0) {
-               info->y1 = y1;
-               info->y2 = y2;
-       }
-       if (info->x2 == 0) {
-               info->x1 = x1;
-               info->x2 = x2;
-       }
+       int begin, end;
+       int pgnr;

-       if (info->y1 > y1)
-               info->y1 = y1;
-       if (info->y2 < y2)
-               info->y2 = y2;
-       if (info->x1 > x1)
-               info->x1 = x1;
-       if (info->x2 < x2)
-               info->x2 = x2;
+       begin = (y * info->page->line_length + x * (info->page->depth / 8)) >> 
PAGE_SHIFT;
+       end = ((y + h - 1) * info->page->line_length +
+                               ((x + w - 1) * (info->page->depth / 8))) >> 
PAGE_SHIFT;

-       if (timer_pending(&info->refresh))
-               return;
-
-       mod_timer(&info->refresh, jiffies + HZ/xenfb_fps);
+       for (pgnr = begin; pgnr <= end; pgnr++)
+               set_bit(pgnr, &info->page->dirty_pages);
 }

 static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
 {
        struct xenfb_info *info = p->par;
-
        cfb_fillrect(p, rect);
-       xenfb_refresh(info, rect->dx, rect->dy, rect->width, rect->height);
+       xenfb_update_pages(info, rect->dx, rect->dy, rect->width, rect->height);
 }

 static void xenfb_imageblit(struct fb_info *p, const struct fb_image *image)
@@ -215,7 +104,7 @@ static void xenfb_imageblit(struct fb_in
        struct xenfb_info *info = p->par;

        cfb_imageblit(p, image);
-       xenfb_refresh(info, image->dx, image->dy, image->width, image->height);
+       xenfb_update_pages(info, image->dx, image->dy, image->width, 
image->height);
 }

 static void xenfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
@@ -223,7 +112,7 @@ static void xenfb_copyarea(struct fb_inf
        struct xenfb_info *info = p->par;

        cfb_copyarea(p, area);
-       xenfb_refresh(info, area->dx, area->dy, area->width, area->height);
+       xenfb_update_pages(info, area->dx, area->dy, area->width, area->height);
 }

 static void xenfb_vm_open(struct vm_area_struct *vma)
@@ -239,7 +128,7 @@ static void xenfb_vm_close(struct vm_are

        down(&info->mm_lock);
        if (atomic_dec_and_test(&map->map_refs)) {
-               list_del(&map->next);
+               vma->vm_private_data = NULL;
                kfree(map);
        }
        up(&info->mm_lock);
@@ -252,7 +141,6 @@ static struct page *xenfb_vm_nopage(stru
        struct xenfb_info *info = map->info;
        int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
        struct page *page;
-       int y1, y2;

        if (pgnr >= info->nr_pages)
                return NOPAGE_SIGBUS;
@@ -260,13 +148,10 @@ static struct page *xenfb_vm_nopage(stru
        down(&info->mm_lock);
        page = info->pages[pgnr];
        get_page(page);
-       map->faults++;

-       y1 = pgnr * PAGE_SIZE / info->fix->line_length;
-       y2 = (pgnr * PAGE_SIZE + PAGE_SIZE - 1) / info->fix->line_length;
-       if (y2 > info->var->yres)
-               y2 = info->var->yres;
-       xenfb_refresh(info, 0, y1, info->var->xres, y2 - y1);
+       set_bit(pgnr, &info->page->dirty_pages);
+       zap_page_range(map->vma, map->vma->vm_start, map->vma->vm_end -
map->vma->vm_start, NULL);
+
        up(&info->mm_lock);

        if (type)
@@ -309,10 +194,8 @@ static int xenfb_mmap(struct fb_info *fb
        memset(map, 0, sizeof(*map));

        map->vma = vma;
-       map->faults = 0;
        map->info = info;
        atomic_set(&map->map_refs, 1);
-       list_add(&map->next, &info->mappings);
        vma->vm_ops = &xenfb_vm_ops;
        vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
        vma->vm_private_data = map;
@@ -375,8 +258,6 @@ static int __init xenfb_probe(void)
                return -ENOMEM;
        memset(info, 0, sizeof(*info));

-       INIT_LIST_HEAD(&info->mappings);
-
        info->fb = vmalloc(xenfb_mem_len);
        if (info->fb == NULL)
                goto error;
@@ -416,6 +297,8 @@ static int __init xenfb_probe(void)
        info->page->mem_length = xenfb_mem_len;
        info->page->in_cons = info->page->in_prod = 0;
        info->page->out_cons = info->page->out_prod = 0;
+       for (i = 0; i < XENFB_DIRTY_PAGES_SIZE; i++)
+               info->page->dirty_pages[i] = 0xFF;

        ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler,
                                        0, "xenfb", info);
@@ -464,12 +347,6 @@ static int __init xenfb_probe(void)
        info->var = &fb_info->var;

        init_MUTEX(&info->mm_lock);
-       init_waitqueue_head(&info->wq);
-       init_timer(&info->refresh);
-       info->refresh.function = xenfb_timer;
-       info->refresh.data = (unsigned long)info;
-
-       info->kthread = kthread_run(xenfb_thread, info, "xenfb thread");

        ret = register_framebuffer(fb_info);
        if (ret)
@@ -518,30 +395,6 @@ static int __init xenfb_probe(void)
        return -ENODEV;
 }

-void xenfb_resume(void)
-{
-#if 0 /* FIXME */
-       int i, ret;
-
-       xenfb_info->page = mfn_to_virt(xen_start_info->fbdev_mfn);
-       for (i = 0; i < xenfb_info->nr_pages; i++)
-               xenfb_info->mfns[i] = vmalloc_to_mfn(xenfb_info->fb + i * 
PAGE_SIZE);
-       xenfb_info->page->pd[0] = vmalloc_to_mfn(xenfb_info->mfns);
-
-       if (xenfb_irq)
-               unbind_from_irqhandler(xenfb_irq, NULL);
-
-       printk("xenfb: resume(%d)\n", xen_start_info->fbdev_evtchn);
-       ret = bind_evtchn_to_irqhandler(xen_start_info->fbdev_evtchn,
-                                       xenfb_event_handler, 0, "xenfb", 
xenfb_info);
-       if (ret <= 0)
-               return;
-       xenfb_irq = ret;
-#else
-       printk(KERN_DEBUG "xenfb_resume not implemented\n");
-#endif
-}
-
 static int __init xenfb_init(void)
 {
        return xenfb_probe();
Index: xen-3.0-testing.hg/linux-2.6.16.13-xen/include/linux/xenfb.h
===================================================================
--- xen-3.0-testing.hg.orig/linux-2.6.16.13-xen/include/linux/xenfb.h   
2006-08-29
12:16:49.000000000 +0200
+++ xen-3.0-testing.hg/linux-2.6.16.13-xen/include/linux/xenfb.h        
2006-08-29
12:36:06.000000000 +0200
@@ -27,20 +27,10 @@ struct xenfb_motion
        __u16 y;            /* The new y coordinate */
 };

-struct xenfb_update
-{
-       __u8 type;          /* XENFB_TYPE_UPDATE */
-       __u16 x;            /* source x */
-       __u16 y;            /* source y */
-       __u16 width;        /* rect width */
-       __u16 height;       /* rect height */
-};
-
 union xenfb_out_event
 {
        __u8 type;
        struct xenfb_motion motion;
-       struct xenfb_update update;
        char _[40];
 };

@@ -69,11 +59,14 @@ union xenfb_in_event
 /* shared page */

 #define XENFB_IN_RING_SIZE (1024 / 40)
-#define XENFB_OUT_RING_SIZE (2048 / 40)
+#define XENFB_OUT_RING_SIZE (1024 / 40)

 #define XENFB_RING_SIZE(ring) (sizeof((ring)) / sizeof(*(ring)))
 #define XENFB_RING_REF(ring, idx) (ring)[(idx) % XENFB_RING_SIZE((ring))]

+#define XENFB_VIDEOMEM_SIZE    (2 * 1024 * 1024)
+#define XENFB_DIRTY_PAGES_SIZE ((((XENFB_VIDEOMEM_SIZE + 4096 - 1)/ 4096) + 7) 
/ 8)
+
 struct xenfb_page
 {
        __u8 initialized;
@@ -90,6 +83,8 @@ struct xenfb_page

        union xenfb_in_event in[XENFB_IN_RING_SIZE];
        union xenfb_out_event out[XENFB_OUT_RING_SIZE];
+
+       __u8 dirty_pages[XENFB_DIRTY_PAGES_SIZE];
 };

 void xenfb_resume(void);

Index: vncfb/sdlfb.c
===================================================================
--- vncfb.orig/sdlfb.c  2006-08-29 12:17:02.000000000 +0200
+++ vncfb/sdlfb.c       2006-08-29 14:16:33.000000000 +0200
@@ -7,13 +7,17 @@ typedef unsigned long kernel_ulong_t;
 #include <linux/input.h>
 #include "xenfb.h"

+extern char *get_bitmap(struct xenfb *xenfb, int *size);
+
+#define IPS    (30)
+
 struct data
 {
        SDL_Surface *dst;
        SDL_Surface *src;
 };

-void sdl_update(struct xenfb *xenfb, int x, int y, int width, int height)
+static void sdl_update(struct xenfb *xenfb, int x, int y, int width, int 
height)
 {
        struct data *data = xenfb->user_data;
        SDL_Rect r = { x, y, width, height };
@@ -21,6 +25,65 @@ void sdl_update(struct xenfb *xenfb, int
        SDL_UpdateRect(data->dst, x, y, width, height);
 }

+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+       __asm__ __volatile__( "lock ; "
+                       "btrl %2,%1\n\tsbbl %0,%0"
+                       :"=r" (oldbit),"+m" (*(volatile long *) addr)
+                       :"Ir" (nr) : "memory");
+       return oldbit;
+}
+
+static void sdl_memory_udpate(struct xenfb *xenfb, int begin, int end)
+{
+       int y1, y2;
+       begin *= 4096;
+       end *= 4096;
+
+       y1 = begin / xenfb->row_stride;
+       y2 = end / xenfb->row_stride;
+
+       if (y1 != y2)
+               sdl_update(xenfb, 0, y1, xenfb->width, y2 - y1);
+       else {
+               int x1, x2;
+               x1 = (begin - y1 * xenfb->row_stride) / (xenfb->depth / 8);
+               x2 = (begin - y2 * xenfb->row_stride) / (xenfb->depth / 8);
+               sdl_update(xenfb, x1, y1, xenfb->width - x1, 1);
+               sdl_update(xenfb, x1, y1 + 1, x2 - x1 + 1, y2 - y1 - 1);
+               sdl_update(xenfb, 0, y2, x2 - 1, 1);
+       }
+}
+
+static Uint32 refresh_handler(Uint32 interval, void *param)
+{
+#define WSIZE  (sizeof(unsigned long)*8)
+       struct xenfb * xenfb = param;
+       int size;
+       unsigned long *bitmap;
+       int i, j;
+       int begin = -1;
+       bitmap = (unsigned long*)get_bitmap(xenfb, &size);
+       for (i = 0; i < size / sizeof(unsigned long); i++) {
+               for (j = 0; j < WSIZE; j++) {
+                       if (test_and_clear_bit(j, bitmap + i)) {
+                               if (begin == -1)
+                                       begin = i * WSIZE + j;
+                       } else if (begin != -1) {
+                               sdl_memory_udpate(xenfb,
+                                               begin,
+                                               i * WSIZE + j);
+                               begin = -1;
+                       }
+               }
+       }
+       if (begin != -1) {
+               sdl_memory_udpate(xenfb, begin, size * WSIZE - 1);
+       }
+       return interval;        
+}
+
 int sdl2linux[1024] = {
        [9] = KEY_ESC,
        [67] = KEY_F1,
@@ -132,13 +195,11 @@ int sdl2linux[1024] = {
 int main(int argc, char **argv)
 {
        struct xenfb *xenfb;
-       int fd;
        int domid;
-       fd_set readfds;
        struct data data;
        SDL_Rect r;
-       struct timeval tv = { 0, 500 };
        int do_quit = 0;
+       SDL_TimerID refreshTimer;


        if (argc != 2)
@@ -153,12 +214,10 @@ int main(int argc, char **argv)
        if (!xenfb_set_domid(xenfb, domid))
                return 1;

-       SDL_Init(SDL_INIT_VIDEO);
-
-       fd = xenfb_get_fileno(xenfb);
+       SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);

        data.dst = SDL_SetVideoMode(xenfb->width, xenfb->height, xenfb->depth,
-                                   SDL_SWSURFACE);
+                                   SDL_HWSURFACE);
        data.src = SDL_CreateRGBSurfaceFrom(xenfb->pixels,
                                            xenfb->width, xenfb->height,
                                            xenfb->depth, xenfb->row_stride,
@@ -170,15 +229,12 @@ int main(int argc, char **argv)
        SDL_BlitSurface(data.src, &r, data.dst, &r);
        SDL_UpdateRect(data.dst, 0, 0, xenfb->width, xenfb->height);

-       xenfb->update = sdl_update;
        xenfb->user_data = &data;

-       FD_ZERO(&readfds);
-       FD_SET(fd, &readfds);
-
        SDL_ShowCursor(0);

-       while (!do_quit && select(fd + 1, &readfds, NULL, NULL, &tv) != -1) {
+       refreshTimer = SDL_AddTimer(1000 / IPS, refresh_handler, xenfb);
+       while (!do_quit) {
                SDL_Event event;

                while (SDL_PollEvent(&event)) {
@@ -207,15 +263,9 @@ int main(int argc, char **argv)
                                break;
                        }
                }
-               if (FD_ISSET(fd, &readfds))
-                       xenfb_on_incoming(xenfb);
-
-               FD_ZERO(&readfds);
-               FD_SET(fd, &readfds);
-
-               tv = (struct timeval){0, 500};
        }

+       SDL_RemoveTimer(refreshTimer);
        xenfb_delete(xenfb);

        SDL_Quit();
Index: vncfb/vncfb.c
===================================================================
--- vncfb.orig/vncfb.c  2006-08-28 18:20:00.000000000 +0200
+++ vncfb/vncfb.c       2006-08-29 14:45:52.000000000 +0200
@@ -1,7 +1,15 @@
+#include <signal.h>
+#include <sys/time.h>
 #include <malloc.h>
 #include <rfb/rfb.h>
 #include "xenfb.h"

+static struct xenfb *xenfb;
+
+extern char *get_bitmap(struct xenfb *xenfb, int *size);
+
+#define IPS    (30)
+
 static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
 {
        extern uint32_t gdk_linux_mapping[0x10000];
@@ -23,7 +31,6 @@ static void on_ptr_event(int buttonMask,
                for (i = 0; i < 8; i++) {
                        if ((last_button & (1 << i)) !=
                            (buttonMask & (1 << i))) {
-                               printf("%d %d\n", buttonMask & (1 << i), i);
                                xenfb_send_button(xenfb, buttonMask & (1 << i),
                                                  2 - i);
                        }
@@ -52,16 +59,72 @@ static void vnc_update(struct xenfb *xen
        rfbMarkRectAsModified(server, x, y, x + w, y + h);
 }

+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+       __asm__ __volatile__( "lock ; "
+                       "btrl %2,%1\n\tsbbl %0,%0"
+                       :"=r" (oldbit),"+m" (*(volatile long *) addr)
+                       :"Ir" (nr) : "memory");
+       return oldbit;
+}
+
+static void vnc_memory_udpate(struct xenfb *xenfb, int begin, int end)
+{
+       int y1, y2;
+       begin *= 4096;
+       end *= 4096;
+
+       y1 = begin / xenfb->row_stride;
+       y2 = end / xenfb->row_stride;
+
+       if (y1 != y2)
+               vnc_update(xenfb, 0, y1, xenfb->width, y2 - y1);
+       else {
+               int x1, x2;
+               x1 = (begin - y1 * xenfb->row_stride) / (xenfb->depth / 8);
+               x2 = (begin - y2 * xenfb->row_stride) / (xenfb->depth / 8);
+               vnc_update(xenfb, x1, y1, xenfb->width - x1, 1);
+               vnc_update(xenfb, x1, y1 + 1, x2 - x1 + 1, y2 - y1 - 1);
+               vnc_update(xenfb, 0, y2, x2 - 1, 1);
+       }
+}
+
+static void refresh_handler(int sig, siginfo_t *info, void* env)
+{
+#define WSIZE  (sizeof(unsigned long)*8)
+       int size;
+       unsigned long *bitmap;
+       int i, j;
+       int begin = -1;
+       bitmap = (unsigned long*)get_bitmap(xenfb, &size);
+       for (i = 0; i < size / sizeof(unsigned long); i++) {
+               for (j = 0; j < WSIZE; j++) {
+                       if (test_and_clear_bit(j, bitmap + i)) {
+                               if (begin == -1)
+                                       begin = i * WSIZE + j;
+                       } else if (begin != -1) {
+                               vnc_memory_udpate(xenfb,
+                                               begin,
+                                               i * WSIZE + j);
+                               begin = -1;
+                       }
+               }
+       }
+       if (begin != -1) {
+               vnc_memory_udpate(xenfb, begin, size * WSIZE - 1);
+       }
+}
+
 int main(int argc, char **argv)
 {
        rfbScreenInfoPtr server;
        char *fake_argv[3] = { "vncfb", "-rfbport", "5901" };
        int fake_argc = sizeof(fake_argv) / sizeof(fake_argv[0]);
        int domid;
-       struct xenfb *xenfb;
-       fd_set readfds;
-       int fd;
        char buffer[1024];
+       struct sigaction action;
+       struct itimerval timer;

        if (argc != 2)
                BUG();
@@ -85,7 +148,6 @@ int main(int argc, char **argv)
                BUG();

        xenfb->user_data = server;
-       xenfb->update = vnc_update;

        server->serverFormat.redShift = 16;
        server->serverFormat.greenShift = 8;
@@ -96,21 +158,20 @@ int main(int argc, char **argv)
        server->screenData = xenfb;
        rfbInitServer(server);

-       rfbRunEventLoop(server, -1, TRUE);
-
-       fd = xenfb_get_fileno(xenfb);

-       FD_ZERO(&readfds);
-       FD_SET(fd, &readfds);
+       memset(&action, 0, sizeof(action));
+       action.sa_sigaction = refresh_handler;
+       action.sa_flags = SA_RESTART;
+       sigemptyset(&action.sa_mask);
+       sigaction(SIGALRM, &action, NULL);
+
+       timer.it_value.tv_sec = 0;
+       timer.it_value.tv_usec = 100000 / IPS;
+       timer.it_interval.tv_sec = timer.it_value.tv_sec;
+       timer.it_interval.tv_usec = timer.it_value.tv_usec;
+       setitimer(ITIMER_REAL, &timer, NULL);

-       while (select(fd + 1, &readfds, NULL, NULL, NULL) != -1) {
-               if (FD_ISSET(fd, &readfds)) {
-                       xenfb_on_incoming(xenfb);
-               }
-               
-               FD_ZERO(&readfds);
-               FD_SET(fd, &readfds);
-       }
+       rfbRunEventLoop(server, 100000 / IPS, FALSE);

        rfbScreenCleanup(server);
        xenfb_delete(xenfb);
Index: vncfb/xenfb.c
===================================================================
--- vncfb.orig/xenfb.c  2006-08-29 12:17:02.000000000 +0200
+++ vncfb/xenfb.c       2006-08-29 14:42:41.000000000 +0200
@@ -69,15 +69,6 @@ struct xenfb *xenfb_new(void)
        return &xenfb->pub;
 }

-int xenfb_get_fileno(struct xenfb *xenfb_pub)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       if (xenfb->domid == -1)
-               return -1;
-
-       return xenfb->fd;
-}
-
 static void xenfb_unset_domid(struct xenfb_private *xenfb)
 {
        struct ioctl_evtchn_unbind unbind;
@@ -357,10 +348,10 @@ bool xenfb_set_domid(struct xenfb *xenfb
        return false;
 }

-static void xenfb_update(struct xenfb_private *xenfb, int x, int y, int width,
int height)
+char *get_bitmap(struct xenfb_private *xenfb, int *size)
 {
-       if (xenfb->pub.update)
-               xenfb->pub.update(&xenfb->pub, x, y, width, height);
+       *size = XENFB_DIRTY_PAGES_SIZE;
+       return xenfb->fb_info->dirty_pages;
 }

 static void xenfb_on_fb_event(struct xenfb_private *xenfb)
@@ -375,7 +366,6 @@ static void xenfb_on_fb_event(struct xen

                switch (event->type) {
                case XENFB_TYPE_UPDATE:
-                       xenfb_update(xenfb, event->update.x, event->update.y, 
event->update.width,
event->update.height);
                        break;
                }
        }
Index: vncfb/xenfb.h
===================================================================
--- vncfb.orig/xenfb.h  2006-07-21 18:21:33.000000000 +0200
+++ vncfb/xenfb.h       2006-08-29 13:53:20.000000000 +0200
@@ -14,8 +14,6 @@ struct xenfb
        int height;

        void *user_data;
-
-       void (*update)(struct xenfb *xenfb, int x, int y, int width, int 
height);
 };

 struct xenfb *xenfb_new(void);

-- 
                Laurent.Vivier@xxxxxxxx
         Bull, Architect of an Open World (TM)
+----- "Any sufficiently advanced technology is ----+
| indistinguishable from magic." - Arthur C. Clarke |

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>