]> Git Repo - qemu.git/blobdiff - vnc.c
multiboot: Use signed type for negative error numbers
[qemu.git] / vnc.c
diff --git a/vnc.c b/vnc.c
index 9dbe82ac06a77c7f93e5cda851aaa9b88bcffcf1..32c467880bb30f7ff8656210a3d6f02add667386 100644 (file)
--- a/vnc.c
+++ b/vnc.c
@@ -538,6 +538,25 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i
 
 }
 
+#define ZALLOC_ALIGNMENT 16
+
+static void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p;
+
+    size *= items;
+    size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
+
+    p = qemu_mallocz(size);
+
+    return (p);
+}
+
+static void zfree(void *x, void *addr)
+{
+    qemu_free(addr);
+}
+
 static void vnc_zlib_init(VncState *vs)
 {
     int i;
@@ -572,8 +591,8 @@ static int vnc_zlib_stop(VncState *vs, int stream_id)
 
         VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
         VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
-        zstream->zalloc = Z_NULL;
-        zstream->zfree = Z_NULL;
+        zstream->zalloc = zalloc;
+        zstream->zfree = zfree;
 
         err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
                            MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
@@ -894,8 +913,14 @@ static void vnc_disconnect_start(VncState *vs)
 
 static void vnc_disconnect_finish(VncState *vs)
 {
-    if (vs->input.buffer) qemu_free(vs->input.buffer);
-    if (vs->output.buffer) qemu_free(vs->output.buffer);
+    if (vs->input.buffer) {
+        qemu_free(vs->input.buffer);
+        vs->input.buffer = NULL;
+    }
+    if (vs->output.buffer) {
+        qemu_free(vs->output.buffer);
+        vs->output.buffer = NULL;
+    }
 #ifdef CONFIG_VNC_TLS
     vnc_tls_client_cleanup(vs);
 #endif /* CONFIG_VNC_TLS */
@@ -918,8 +943,8 @@ static void vnc_disconnect_finish(VncState *vs)
     if (!vs->vd->clients)
         dcl->idle = 1;
 
-    qemu_free(vs);
     vnc_remove_timer(vs->vd);
+    qemu_free(vs);
 }
 
 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
@@ -1352,6 +1377,27 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
         }
     }
 
+    if ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z')) {
+        /* If the capslock state needs to change then simulate an additional
+           keypress before sending this one.  This will happen if the user
+           toggles capslock away from the VNC window.
+        */
+        int uppercase = !!(sym >= 'A' && sym <= 'Z');
+        int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
+        int capslock = !!(vs->modifiers_state[0x3a]);
+        if (capslock) {
+            if (uppercase == shift) {
+                vs->modifiers_state[0x3a] = 0;
+                press_key(vs, 0xffe5);
+            }
+        } else {
+            if (uppercase != shift) {
+                vs->modifiers_state[0x3a] = 1;
+                press_key(vs, 0xffe5);
+            }
+        }
+    }
+
     if (is_graphic_console()) {
         if (keycode & 0x80)
             kbd_put_keycode(0xe0);
@@ -2201,7 +2247,7 @@ static void vnc_listen_read(void *opaque)
     /* Catch-up */
     vga_hw_update();
 
-    int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
+    int csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
     if (csock != -1) {
         vnc_connect(vs, csock);
     }
@@ -2274,6 +2320,11 @@ int vnc_display_password(DisplayState *ds, const char *password)
     if (password && password[0]) {
         if (!(vs->password = qemu_strdup(password)))
             return -1;
+        if (vs->auth == VNC_AUTH_NONE) {
+            vs->auth = VNC_AUTH_VNC;
+        }
+    } else {
+        vs->auth = VNC_AUTH_NONE;
     }
 
     return 0;
This page took 0.026286 seconds and 4 git commands to generate.