microblaze: Add petalogix s3a1800dsp MMU linux ref-design.
[qemu] / vnc.c
diff --git a/vnc.c b/vnc.c
index de9edea..3f5d622 100644 (file)
--- a/vnc.c
+++ b/vnc.c
@@ -86,7 +86,6 @@ char *vnc_socket_local_addr(const char *format, int fd) {
     return addr_to_string(format, &sa, salen);
 }
 
-
 char *vnc_socket_remote_addr(const char *format, int fd) {
     struct sockaddr_storage sa;
     socklen_t salen;
@@ -366,17 +365,13 @@ static void vnc_resize(VncState *vs)
     memset(vs->guest.dirty, 0xFF, sizeof(vs->guest.dirty));
 
     /* server surface */
-    if (!vs->server.ds) {
-        vs->server.ds = default_allocator.create_displaysurface(ds_get_width(ds),
-                                                                ds_get_height(ds));
-    } else {
-        default_allocator.resize_displaysurface(vs->server.ds,
-                                                ds_get_width(ds), ds_get_height(ds));
-    }
-    if (vs->server.ds->data == NULL) {
-        fprintf(stderr, "vnc: memory allocation failed\n");
-        exit(1);
-    }
+    if (!vs->server.ds)
+        vs->server.ds = qemu_mallocz(sizeof(*vs->server.ds));
+    if (vs->server.ds->data)
+        qemu_free(vs->server.ds->data);
+    *(vs->server.ds) = *(ds->surface);
+    vs->server.ds->data = qemu_mallocz(vs->server.ds->linesize *
+                                       vs->server.ds->height);
     memset(vs->server.dirty, 0xFF, sizeof(vs->guest.dirty));
 }
 
@@ -657,6 +652,7 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
 
 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
 {
+    vs->force_update = 1;
     vnc_update_client(vs);
 
     vnc_write_u8(vs, 0);  /* msg id */
@@ -686,7 +682,7 @@ static int find_and_clear_dirty_height(struct VncSurface *s,
 {
     int h;
 
-    for (h = 1; h < (s->ds->height - y) && h < 1; h++) {
+    for (h = 1; h < (s->ds->height - y); h++) {
         int tmp_x;
         if (!vnc_get_bit(s->dirty[y + h], last_x))
             break;
@@ -704,12 +700,18 @@ static void vnc_update_client(void *opaque)
         int y;
         uint8_t *guest_row;
         uint8_t *server_row;
-        int cmp_bytes = 16 * ds_get_bytes_per_pixel(vs->ds);
+        int cmp_bytes;
         uint32_t width_mask[VNC_DIRTY_WORDS];
         int n_rectangles;
         int saved_offset;
         int has_dirty = 0;
 
+        if (vs->output.offset && !vs->audio_cap && !vs->force_update) {
+            /* kernel send buffers are full -> drop frames to throttle */
+            qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
+            return;
+        }
+
         vga_hw_update();
 
         /*
@@ -718,6 +720,7 @@ static void vnc_update_client(void *opaque)
          * Update server dirty map.
          */
         vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
+        cmp_bytes = 16 * ds_get_bytes_per_pixel(vs->ds);
         guest_row  = vs->guest.ds->data;
         server_row = vs->server.ds->data;
         for (y = 0; y < vs->guest.ds->height; y++) {
@@ -745,7 +748,7 @@ static void vnc_update_client(void *opaque)
             server_row += ds_get_linesize(vs->ds);
         }
 
-        if (!has_dirty && !vs->audio_cap) {
+        if (!has_dirty && !vs->audio_cap && !vs->force_update) {
             qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
             return;
         }
@@ -789,6 +792,7 @@ static void vnc_update_client(void *opaque)
         vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
         vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
         vnc_flush(vs);
+        vs->force_update = 0;
 
     }
 
@@ -850,7 +854,7 @@ static void audio_add(VncState *vs)
     ops.destroy = audio_capture_destroy;
     ops.capture = audio_capture;
 
-    vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
+    vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
     if (!vs->audio_cap) {
         monitor_printf(mon, "Failed to add audio capture\n");
     }
@@ -910,7 +914,8 @@ int vnc_client_io_error(VncState *vs, int ret, int last_errno)
         if (!vs->vd->clients)
             dcl->idle = 1;
 
-        default_allocator.free_displaysurface(vs->server.ds);
+        qemu_free(vs->server.ds->data);
+        qemu_free(vs->server.ds);
         qemu_free(vs->guest.ds);
         qemu_free(vs);
 
@@ -1337,30 +1342,39 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
             case 0xb8:                          /* Right ALT */
                 break;
             case 0xc8:
+            case 0x48:
                 kbd_put_keysym(QEMU_KEY_UP);
                 break;
             case 0xd0:
+            case 0x50:
                 kbd_put_keysym(QEMU_KEY_DOWN);
                 break;
             case 0xcb:
+            case 0x4b:
                 kbd_put_keysym(QEMU_KEY_LEFT);
                 break;
             case 0xcd:
+            case 0x4d:
                 kbd_put_keysym(QEMU_KEY_RIGHT);
                 break;
             case 0xd3:
+            case 0x53:
                 kbd_put_keysym(QEMU_KEY_DELETE);
                 break;
             case 0xc7:
+            case 0x47:
                 kbd_put_keysym(QEMU_KEY_HOME);
                 break;
             case 0xcf:
+            case 0x4f:
                 kbd_put_keysym(QEMU_KEY_END);
                 break;
             case 0xc9:
+            case 0x49:
                 kbd_put_keysym(QEMU_KEY_PAGEUP);
                 break;
             case 0xd1:
+            case 0x51:
                 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
                 break;
             default:
@@ -1408,6 +1422,7 @@ static void framebuffer_update_request(VncState *vs, int incremental,
     int i;
     vs->need_update = 1;
     if (!incremental) {
+        vs->force_update = 1;
         for (i = 0; i < h; i++) {
             vnc_set_bits(vs->guest.dirty[y_position + i],
                          (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
@@ -1589,7 +1604,7 @@ static void pixel_format_message (VncState *vs) {
     else if (vs->ds->surface->pf.bits_per_pixel == 8)
         vs->send_hextile_tile = send_hextile_tile_8;
     vs->clientds = *(vs->ds->surface);
-    vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
+    vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
     vs->write_pixels = vnc_write_pixels_copy;
 
     vnc_write(vs, pad, 3);           /* padding */
@@ -2085,6 +2100,13 @@ int vnc_display_password(DisplayState *ds, const char *password)
     return 0;
 }
 
+char *vnc_display_local_addr(DisplayState *ds)
+{
+    VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+    
+    return vnc_socket_local_addr("%s:%s", vs->lsock);
+}
+
 int vnc_display_open(DisplayState *ds, const char *display)
 {
     VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;