vnc.c (4db14629c38611061fc19ec6927405923de84f08) vnc.c (1d0d59fe291967533f974e82213656d479475a1e)
1/*
2 * QEMU VNC display driver
3 *
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy

--- 13 unchanged lines hidden (view full) ---

22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27#include "vnc.h"
28#include "vnc-jobs.h"
29#include "trace.h"
1/*
2 * QEMU VNC display driver
3 *
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy

--- 13 unchanged lines hidden (view full) ---

22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27#include "vnc.h"
28#include "vnc-jobs.h"
29#include "trace.h"
30#include "hw/qdev.h"
30#include "sysemu/sysemu.h"
31#include "qemu/sockets.h"
32#include "qemu/timer.h"
33#include "qemu/acl.h"
34#include "qemu/config-file.h"
35#include "qapi/qmp/types.h"
36#include "qmp-commands.h"
37#include "qemu/osdep.h"

--- 1622 unchanged lines hidden (view full) ---

1660 case 0x38: /* Left ALT */
1661 case 0xb8: /* Right ALT */
1662 if (down)
1663 vs->modifiers_state[keycode] = 1;
1664 else
1665 vs->modifiers_state[keycode] = 0;
1666 break;
1667 case 0x02 ... 0x0a: /* '1' to '9' keys */
31#include "sysemu/sysemu.h"
32#include "qemu/sockets.h"
33#include "qemu/timer.h"
34#include "qemu/acl.h"
35#include "qemu/config-file.h"
36#include "qapi/qmp/types.h"
37#include "qmp-commands.h"
38#include "qemu/osdep.h"

--- 1622 unchanged lines hidden (view full) ---

1661 case 0x38: /* Left ALT */
1662 case 0xb8: /* Right ALT */
1663 if (down)
1664 vs->modifiers_state[keycode] = 1;
1665 else
1666 vs->modifiers_state[keycode] = 0;
1667 break;
1668 case 0x02 ... 0x0a: /* '1' to '9' keys */
1668 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1669 if (vs->vd->dcl.con == NULL &&
1670 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1669 /* Reset the modifiers sent to the current console */
1670 reset_keys(vs);
1671 console_select(keycode - 0x02);
1672 return;
1673 }
1674 break;
1675 case 0x3a: /* CapsLock */
1676 case 0x45: /* NumLock */

--- 391 unchanged lines hidden (view full) ---

2068 vs->client_pf.bmask = blue_max << blue_shift;
2069 vs->client_pf.bits_per_pixel = bits_per_pixel;
2070 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2071 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2072 vs->client_be = big_endian_flag;
2073
2074 set_pixel_conversion(vs);
2075
1671 /* Reset the modifiers sent to the current console */
1672 reset_keys(vs);
1673 console_select(keycode - 0x02);
1674 return;
1675 }
1676 break;
1677 case 0x3a: /* CapsLock */
1678 case 0x45: /* NumLock */

--- 391 unchanged lines hidden (view full) ---

2070 vs->client_pf.bmask = blue_max << blue_shift;
2071 vs->client_pf.bits_per_pixel = bits_per_pixel;
2072 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2073 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2074 vs->client_be = big_endian_flag;
2075
2076 set_pixel_conversion(vs);
2077
2076 graphic_hw_invalidate(NULL);
2077 graphic_hw_update(NULL);
2078 graphic_hw_invalidate(vs->vd->dcl.con);
2079 graphic_hw_update(vs->vd->dcl.con);
2078}
2079
2080static void pixel_format_message (VncState *vs) {
2081 char pad[3] = { 0, 0, 0 };
2082
2083 vs->client_pf = qemu_default_pixelformat(32);
2084
2085 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */

--- 710 unchanged lines hidden (view full) ---

2796 VncState *vs, *vn;
2797 int has_dirty, rects = 0;
2798
2799 if (QTAILQ_EMPTY(&vd->clients)) {
2800 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2801 return;
2802 }
2803
2080}
2081
2082static void pixel_format_message (VncState *vs) {
2083 char pad[3] = { 0, 0, 0 };
2084
2085 vs->client_pf = qemu_default_pixelformat(32);
2086
2087 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */

--- 710 unchanged lines hidden (view full) ---

2798 VncState *vs, *vn;
2799 int has_dirty, rects = 0;
2800
2801 if (QTAILQ_EMPTY(&vd->clients)) {
2802 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2803 return;
2804 }
2805
2804 graphic_hw_update(NULL);
2806 graphic_hw_update(vd->dcl.con);
2805
2806 if (vnc_trylock_display(vd)) {
2807 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2808 return;
2809 }
2810
2811 has_dirty = vnc_refresh_server_surface(vd);
2812 vnc_unlock_display(vd);

--- 89 unchanged lines hidden (view full) ---

2902 vs->as.fmt = AUD_FMT_S16;
2903 vs->as.endianness = 0;
2904
2905 qemu_mutex_init(&vs->output_mutex);
2906 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
2907
2908 QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
2909
2807
2808 if (vnc_trylock_display(vd)) {
2809 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2810 return;
2811 }
2812
2813 has_dirty = vnc_refresh_server_surface(vd);
2814 vnc_unlock_display(vd);

--- 89 unchanged lines hidden (view full) ---

2904 vs->as.fmt = AUD_FMT_S16;
2905 vs->as.endianness = 0;
2906
2907 qemu_mutex_init(&vs->output_mutex);
2908 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
2909
2910 QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
2911
2910 graphic_hw_update(NULL);
2912 graphic_hw_update(vd->dcl.con);
2911
2912 vnc_write(vs, "RFB 003.008\n", 12);
2913 vnc_flush(vs);
2914 vnc_read_when(vs, protocol_version, 12);
2915 reset_keys(vs);
2916 if (vs->vd->lock_key_sync)
2917 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
2918

--- 6 unchanged lines hidden (view full) ---

2925static void vnc_listen_read(void *opaque, bool websocket)
2926{
2927 VncDisplay *vs = opaque;
2928 struct sockaddr_in addr;
2929 socklen_t addrlen = sizeof(addr);
2930 int csock;
2931
2932 /* Catch-up */
2913
2914 vnc_write(vs, "RFB 003.008\n", 12);
2915 vnc_flush(vs);
2916 vnc_read_when(vs, protocol_version, 12);
2917 reset_keys(vs);
2918 if (vs->vd->lock_key_sync)
2919 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
2920

--- 6 unchanged lines hidden (view full) ---

2927static void vnc_listen_read(void *opaque, bool websocket)
2928{
2929 VncDisplay *vs = opaque;
2930 struct sockaddr_in addr;
2931 socklen_t addrlen = sizeof(addr);
2932 int csock;
2933
2934 /* Catch-up */
2933 graphic_hw_update(NULL);
2935 graphic_hw_update(vs->dcl.con);
2934#ifdef CONFIG_VNC_WS
2935 if (websocket) {
2936 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
2937 } else
2938#endif /* CONFIG_VNC_WS */
2939 {
2940 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2941 }

--- 143 unchanged lines hidden (view full) ---

3085 .type = QEMU_OPT_STRING,
3086 },{
3087 .name = "x509",
3088 .type = QEMU_OPT_STRING,
3089 },{
3090 .name = "share",
3091 .type = QEMU_OPT_STRING,
3092 },{
2936#ifdef CONFIG_VNC_WS
2937 if (websocket) {
2938 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
2939 } else
2940#endif /* CONFIG_VNC_WS */
2941 {
2942 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2943 }

--- 143 unchanged lines hidden (view full) ---

3087 .type = QEMU_OPT_STRING,
3088 },{
3089 .name = "x509",
3090 .type = QEMU_OPT_STRING,
3091 },{
3092 .name = "share",
3093 .type = QEMU_OPT_STRING,
3094 },{
3095 .name = "display",
3096 .type = QEMU_OPT_STRING,
3097 },{
3098 .name = "head",
3099 .type = QEMU_OPT_NUMBER,
3100 },{
3093 .name = "password",
3094 .type = QEMU_OPT_BOOL,
3095 },{
3096 .name = "reverse",
3097 .type = QEMU_OPT_BOOL,
3098 },{
3099 .name = "lock-key-sync",
3100 .type = QEMU_OPT_BOOL,

--- 19 unchanged lines hidden (view full) ---

3120 { /* end of list */ }
3121 },
3122};
3123
3124void vnc_display_open(const char *id, Error **errp)
3125{
3126 VncDisplay *vs = vnc_display_find(id);
3127 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3101 .name = "password",
3102 .type = QEMU_OPT_BOOL,
3103 },{
3104 .name = "reverse",
3105 .type = QEMU_OPT_BOOL,
3106 },{
3107 .name = "lock-key-sync",
3108 .type = QEMU_OPT_BOOL,

--- 19 unchanged lines hidden (view full) ---

3128 { /* end of list */ }
3129 },
3130};
3131
3132void vnc_display_open(const char *id, Error **errp)
3133{
3134 VncDisplay *vs = vnc_display_find(id);
3135 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3128 const char *display, *websocket, *share;
3136 const char *display, *websocket, *share, *device_id;
3137 QemuConsole *con;
3129 int password = 0;
3130 int reverse = 0;
3131#ifdef CONFIG_VNC_TLS
3132 int tls = 0, x509 = 0;
3133 const char *path;
3134#endif
3135#ifdef CONFIG_VNC_SASL
3136 int sasl = 0;

--- 212 unchanged lines hidden (view full) ---

3349 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3350 error_setg(errp, "Failed to initialize SASL auth: %s",
3351 sasl_errstring(saslErr, NULL, NULL));
3352 goto fail;
3353 }
3354#endif
3355 vs->lock_key_sync = lock_key_sync;
3356
3138 int password = 0;
3139 int reverse = 0;
3140#ifdef CONFIG_VNC_TLS
3141 int tls = 0, x509 = 0;
3142 const char *path;
3143#endif
3144#ifdef CONFIG_VNC_SASL
3145 int sasl = 0;

--- 212 unchanged lines hidden (view full) ---

3358 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3359 error_setg(errp, "Failed to initialize SASL auth: %s",
3360 sasl_errstring(saslErr, NULL, NULL));
3361 goto fail;
3362 }
3363#endif
3364 vs->lock_key_sync = lock_key_sync;
3365
3366 device_id = qemu_opt_get(opts, "display");
3367 if (device_id) {
3368 DeviceState *dev;
3369 int head = qemu_opt_get_number(opts, "head", 0);
3370
3371 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3372 if (dev == NULL) {
3373 error_set(errp, QERR_DEVICE_NOT_FOUND, device_id);
3374 goto fail;
3375 }
3376
3377 con = qemu_console_lookup_by_device(dev, head);
3378 if (con == NULL) {
3379 error_setg(errp, "Device %s is not bound to a QemuConsole",
3380 device_id);
3381 goto fail;
3382 }
3383 } else {
3384 con = NULL;
3385 }
3386
3387 if (con != vs->dcl.con) {
3388 unregister_displaychangelistener(&vs->dcl);
3389 vs->dcl.con = con;
3390 register_displaychangelistener(&vs->dcl);
3391 }
3392
3357 if (reverse) {
3358 /* connect to viewer */
3359 int csock;
3360 vs->lsock = -1;
3361#ifdef CONFIG_VNC_WS
3362 vs->lwebsock = -1;
3363#endif
3364 if (strncmp(display, "unix:", 5) == 0) {

--- 114 unchanged lines hidden ---
3393 if (reverse) {
3394 /* connect to viewer */
3395 int csock;
3396 vs->lsock = -1;
3397#ifdef CONFIG_VNC_WS
3398 vs->lwebsock = -1;
3399#endif
3400 if (strncmp(display, "unix:", 5) == 0) {

--- 114 unchanged lines hidden ---