Lines Matching +full:5 +full:vs

71 static int vnc_cursor_define(VncState *vs);
72 static void vnc_update_throttle_offset(VncState *vs);
74 static void vnc_set_share_mode(VncState *vs, VncShareMode mode) in vnc_set_share_mode() argument
85 vs->ioc, mn[vs->share_mode], mn[mode]); in vnc_set_share_mode()
88 switch (vs->share_mode) { in vnc_set_share_mode()
90 vs->vd->num_connecting--; in vnc_set_share_mode()
93 vs->vd->num_shared--; in vnc_set_share_mode()
96 vs->vd->num_exclusive--; in vnc_set_share_mode()
102 vs->share_mode = mode; in vnc_set_share_mode()
104 switch (vs->share_mode) { in vnc_set_share_mode()
106 vs->vd->num_connecting++; in vnc_set_share_mode()
109 vs->vd->num_shared++; in vnc_set_share_mode()
112 vs->vd->num_exclusive++; in vnc_set_share_mode()
290 static void vnc_qmp_event(VncState *vs, QAPIEvent event) in vnc_qmp_event() argument
294 if (!vs->info) { in vnc_qmp_event()
298 si = vnc_server_info_get(vs->vd); in vnc_qmp_event()
305 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info)); in vnc_qmp_event()
308 qapi_event_send_vnc_initialized(si, vs->info); in vnc_qmp_event()
311 qapi_event_send_vnc_disconnected(si, vs->info); in vnc_qmp_event()
615 static int vnc_update_client(VncState *vs, int has_dirty);
616 static void vnc_disconnect_start(VncState *vs);
618 static void vnc_colordepth(VncState *vs);
619 static void framebuffer_update_request(VncState *vs, int incremental,
674 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, in vnc_framebuffer_update() argument
677 vnc_write_u16(vs, x); in vnc_framebuffer_update()
678 vnc_write_u16(vs, y); in vnc_framebuffer_update()
679 vnc_write_u16(vs, w); in vnc_framebuffer_update()
680 vnc_write_u16(vs, h); in vnc_framebuffer_update()
682 vnc_write_s32(vs, encoding); in vnc_framebuffer_update()
685 static void vnc_desktop_resize_ext(VncState *vs, int reject_reason) in vnc_desktop_resize_ext() argument
688 vs, vs->ioc, vs->client_width, vs->client_height, reject_reason); in vnc_desktop_resize_ext()
690 vnc_lock_output(vs); in vnc_desktop_resize_ext()
691 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in vnc_desktop_resize_ext()
692 vnc_write_u8(vs, 0); in vnc_desktop_resize_ext()
693 vnc_write_u16(vs, 1); /* number of rects */ in vnc_desktop_resize_ext()
694 vnc_framebuffer_update(vs, in vnc_desktop_resize_ext()
697 vs->client_width, vs->client_height, in vnc_desktop_resize_ext()
699 vnc_write_u8(vs, 1); /* number of screens */ in vnc_desktop_resize_ext()
700 vnc_write_u8(vs, 0); /* padding */ in vnc_desktop_resize_ext()
701 vnc_write_u8(vs, 0); /* padding */ in vnc_desktop_resize_ext()
702 vnc_write_u8(vs, 0); /* padding */ in vnc_desktop_resize_ext()
703 vnc_write_u32(vs, 0); /* screen id */ in vnc_desktop_resize_ext()
704 vnc_write_u16(vs, 0); /* screen x-pos */ in vnc_desktop_resize_ext()
705 vnc_write_u16(vs, 0); /* screen y-pos */ in vnc_desktop_resize_ext()
706 vnc_write_u16(vs, vs->client_width); in vnc_desktop_resize_ext()
707 vnc_write_u16(vs, vs->client_height); in vnc_desktop_resize_ext()
708 vnc_write_u32(vs, 0); /* screen flags */ in vnc_desktop_resize_ext()
709 vnc_unlock_output(vs); in vnc_desktop_resize_ext()
710 vnc_flush(vs); in vnc_desktop_resize_ext()
713 static void vnc_desktop_resize(VncState *vs) in vnc_desktop_resize() argument
715 if (vs->ioc == NULL || (!vnc_has_feature(vs, VNC_FEATURE_RESIZE) && in vnc_desktop_resize()
716 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) { in vnc_desktop_resize()
719 if (vs->client_width == vs->vd->true_width && in vnc_desktop_resize()
720 vs->client_height == pixman_image_get_height(vs->vd->server)) { in vnc_desktop_resize()
724 assert(vs->vd->true_width < 65536 && in vnc_desktop_resize()
725 vs->vd->true_width >= 0); in vnc_desktop_resize()
726 assert(pixman_image_get_height(vs->vd->server) < 65536 && in vnc_desktop_resize()
727 pixman_image_get_height(vs->vd->server) >= 0); in vnc_desktop_resize()
728 vs->client_width = vs->vd->true_width; in vnc_desktop_resize()
729 vs->client_height = pixman_image_get_height(vs->vd->server); in vnc_desktop_resize()
731 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) { in vnc_desktop_resize()
732 vnc_desktop_resize_ext(vs, 0); in vnc_desktop_resize()
737 vs, vs->ioc, vs->client_width, vs->client_height); in vnc_desktop_resize()
739 vnc_lock_output(vs); in vnc_desktop_resize()
740 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in vnc_desktop_resize()
741 vnc_write_u8(vs, 0); in vnc_desktop_resize()
742 vnc_write_u16(vs, 1); /* number of rects */ in vnc_desktop_resize()
743 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height, in vnc_desktop_resize()
745 vnc_unlock_output(vs); in vnc_desktop_resize()
746 vnc_flush(vs); in vnc_desktop_resize()
751 VncState *vs; in vnc_abort_display_jobs() local
753 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_abort_display_jobs()
754 vnc_lock_output(vs); in vnc_abort_display_jobs()
755 vs->abort = true; in vnc_abort_display_jobs()
756 vnc_unlock_output(vs); in vnc_abort_display_jobs()
758 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_abort_display_jobs()
759 vnc_jobs_join(vs); in vnc_abort_display_jobs()
761 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_abort_display_jobs()
762 vnc_lock_output(vs); in vnc_abort_display_jobs()
763 if (vs->update == VNC_STATE_UPDATE_NONE && in vnc_abort_display_jobs()
764 vs->job_update != VNC_STATE_UPDATE_NONE) { in vnc_abort_display_jobs()
766 vs->update = vs->job_update; in vnc_abort_display_jobs()
767 vs->job_update = VNC_STATE_UPDATE_NONE; in vnc_abort_display_jobs()
769 vs->abort = false; in vnc_abort_display_jobs()
770 vnc_unlock_output(vs); in vnc_abort_display_jobs()
828 VncState *vs; in vnc_dpy_switch() local
857 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_dpy_switch()
858 vnc_colordepth(vs); in vnc_dpy_switch()
859 vnc_desktop_resize(vs); in vnc_dpy_switch()
860 vnc_cursor_define(vs); in vnc_dpy_switch()
861 memset(vs->dirty, 0x00, sizeof(vs->dirty)); in vnc_dpy_switch()
862 vnc_set_area_dirty(vs->dirty, vd, 0, 0, in vnc_dpy_switch()
865 vnc_update_throttle_offset(vs); in vnc_dpy_switch()
870 static void vnc_write_pixels_copy(VncState *vs, in vnc_write_pixels_copy() argument
873 vnc_write(vs, pixels, size); in vnc_write_pixels_copy()
877 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) in vnc_convert_pixel() argument
882 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8; in vnc_convert_pixel()
883 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8; in vnc_convert_pixel()
884 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8; in vnc_convert_pixel()
888 v = (r << vs->client_pf.rshift) | in vnc_convert_pixel()
889 (g << vs->client_pf.gshift) | in vnc_convert_pixel()
890 (b << vs->client_pf.bshift); in vnc_convert_pixel()
891 switch (vs->client_pf.bytes_per_pixel) { in vnc_convert_pixel()
896 if (vs->client_be) { in vnc_convert_pixel()
906 if (vs->client_be) { in vnc_convert_pixel()
921 static void vnc_write_pixels_generic(VncState *vs, in vnc_write_pixels_generic() argument
931 vnc_convert_pixel(vs, buf, pixels[i]); in vnc_write_pixels_generic()
932 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel); in vnc_write_pixels_generic()
937 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) in vnc_raw_send_framebuffer_update() argument
941 VncDisplay *vd = vs->vd; in vnc_raw_send_framebuffer_update()
945 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES); in vnc_raw_send_framebuffer_update()
951 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) in vnc_send_framebuffer_update() argument
955 switch(vs->vnc_encoding) { in vnc_send_framebuffer_update()
957 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
960 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); in vnc_send_framebuffer_update()
961 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
964 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
967 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
970 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
973 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
976 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW); in vnc_send_framebuffer_update()
977 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h); in vnc_send_framebuffer_update()
989 static int vnc_cursor_define(VncState *vs) in vnc_cursor_define() argument
991 QEMUCursor *c = qemu_console_get_cursor(vs->vd->dcl.con); in vnc_cursor_define()
998 if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) { in vnc_cursor_define()
999 vnc_lock_output(vs); in vnc_cursor_define()
1000 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in vnc_cursor_define()
1001 vnc_write_u8(vs, 0); /* padding */ in vnc_cursor_define()
1002 vnc_write_u16(vs, 1); /* # of rects */ in vnc_cursor_define()
1003 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height, in vnc_cursor_define()
1005 vnc_write_s32(vs, VNC_ENCODING_RAW); in vnc_cursor_define()
1006 vnc_write(vs, c->data, c->width * c->height * 4); in vnc_cursor_define()
1007 vnc_unlock_output(vs); in vnc_cursor_define()
1010 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) { in vnc_cursor_define()
1011 vnc_lock_output(vs); in vnc_cursor_define()
1012 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in vnc_cursor_define()
1013 vnc_write_u8(vs, 0); /* padding */ in vnc_cursor_define()
1014 vnc_write_u16(vs, 1); /* # of rects */ in vnc_cursor_define()
1015 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height, in vnc_cursor_define()
1017 isize = c->width * c->height * vs->client_pf.bytes_per_pixel; in vnc_cursor_define()
1018 vnc_write_pixels_generic(vs, c->data, isize); in vnc_cursor_define()
1019 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize); in vnc_cursor_define()
1020 vnc_unlock_output(vs); in vnc_cursor_define()
1030 VncState *vs; in vnc_dpy_cursor_define() local
1037 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_dpy_cursor_define()
1038 vnc_cursor_define(vs); in vnc_dpy_cursor_define()
1042 static int find_and_clear_dirty_height(VncState *vs, in find_and_clear_dirty_height() argument
1048 if (!test_bit(last_x, vs->dirty[y + h])) { in find_and_clear_dirty_height()
1051 bitmap_clear(vs->dirty[y + h], last_x, x - last_x); in find_and_clear_dirty_height()
1067 static void vnc_update_throttle_offset(VncState *vs) in vnc_update_throttle_offset() argument
1070 vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel; in vnc_update_throttle_offset()
1072 if (vs->audio_cap) { in vnc_update_throttle_offset()
1074 switch (vs->as.fmt) { in vnc_update_throttle_offset()
1089 offset += vs->as.freq * bps * vs->as.nchannels; in vnc_update_throttle_offset()
1098 if (vs->throttle_output_offset != offset) { in vnc_update_throttle_offset()
1100 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width, in vnc_update_throttle_offset()
1101 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap); in vnc_update_throttle_offset()
1104 vs->throttle_output_offset = offset; in vnc_update_throttle_offset()
1107 static bool vnc_should_update(VncState *vs) in vnc_should_update() argument
1109 switch (vs->update) { in vnc_should_update()
1117 if (vs->output.offset < vs->throttle_output_offset && in vnc_should_update()
1118 vs->job_update == VNC_STATE_UPDATE_NONE) { in vnc_should_update()
1122 vs, vs->ioc, vs->job_update, vs->output.offset); in vnc_should_update()
1133 if (vs->force_update_offset == 0 && in vnc_should_update()
1134 vs->job_update == VNC_STATE_UPDATE_NONE) { in vnc_should_update()
1138 vs, vs->ioc, vs->job_update, vs->force_update_offset); in vnc_should_update()
1144 static int vnc_update_client(VncState *vs, int has_dirty) in vnc_update_client() argument
1146 VncDisplay *vd = vs->vd; in vnc_update_client()
1152 if (vs->disconnecting) { in vnc_update_client()
1153 vnc_disconnect_finish(vs); in vnc_update_client()
1157 vs->has_dirty += has_dirty; in vnc_update_client()
1158 if (!vnc_should_update(vs)) { in vnc_update_client()
1162 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) { in vnc_update_client()
1172 job = vnc_job_new(vs); in vnc_update_client()
1181 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty, in vnc_update_client()
1182 height * VNC_DIRTY_BPL(vs), in vnc_update_client()
1183 y * VNC_DIRTY_BPL(vs)); in vnc_update_client()
1184 if (offset == height * VNC_DIRTY_BPL(vs)) { in vnc_update_client()
1188 y = offset / VNC_DIRTY_BPL(vs); in vnc_update_client()
1189 x = offset % VNC_DIRTY_BPL(vs); in vnc_update_client()
1190 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y], in vnc_update_client()
1191 VNC_DIRTY_BPL(vs), x); in vnc_update_client()
1192 bitmap_clear(vs->dirty[y], x, x2 - x); in vnc_update_client()
1193 h = find_and_clear_dirty_height(vs, y, x, x2, height); in vnc_update_client()
1207 vs->job_update = vs->update; in vnc_update_client()
1208 vs->update = VNC_STATE_UPDATE_NONE; in vnc_update_client()
1210 vs->has_dirty = 0; in vnc_update_client()
1217 VncState *vs = opaque; in audio_capture_notify() local
1219 assert(vs->magic == VNC_MAGIC); in audio_capture_notify()
1222 trace_vnc_msg_server_audio_end(vs, vs->ioc); in audio_capture_notify()
1223 vnc_lock_output(vs); in audio_capture_notify()
1224 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU); in audio_capture_notify()
1225 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO); in audio_capture_notify()
1226 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END); in audio_capture_notify()
1227 vnc_unlock_output(vs); in audio_capture_notify()
1228 vnc_flush(vs); in audio_capture_notify()
1232 trace_vnc_msg_server_audio_begin(vs, vs->ioc); in audio_capture_notify()
1233 vnc_lock_output(vs); in audio_capture_notify()
1234 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU); in audio_capture_notify()
1235 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO); in audio_capture_notify()
1236 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN); in audio_capture_notify()
1237 vnc_unlock_output(vs); in audio_capture_notify()
1238 vnc_flush(vs); in audio_capture_notify()
1249 VncState *vs = opaque; in audio_capture() local
1251 assert(vs->magic == VNC_MAGIC); in audio_capture()
1252 trace_vnc_msg_server_audio_data(vs, vs->ioc, buf, size); in audio_capture()
1253 vnc_lock_output(vs); in audio_capture()
1254 if (vs->output.offset < vs->throttle_output_offset) { in audio_capture()
1255 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU); in audio_capture()
1256 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO); in audio_capture()
1257 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA); in audio_capture()
1258 vnc_write_u32(vs, size); in audio_capture()
1259 vnc_write(vs, buf, size); in audio_capture()
1261 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset); in audio_capture()
1263 vnc_unlock_output(vs); in audio_capture()
1264 vnc_flush(vs); in audio_capture()
1267 static void audio_add(VncState *vs) in audio_add() argument
1271 if (vs->audio_cap) { in audio_add()
1280 vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs); in audio_add()
1281 if (!vs->audio_cap) { in audio_add()
1286 static void audio_del(VncState *vs) in audio_del() argument
1288 if (vs->audio_cap) { in audio_del()
1289 AUD_del_capture(vs->audio_cap, vs); in audio_del()
1290 vs->audio_cap = NULL; in audio_del()
1294 static void vnc_disconnect_start(VncState *vs) in vnc_disconnect_start() argument
1296 if (vs->disconnecting) { in vnc_disconnect_start()
1299 trace_vnc_client_disconnect_start(vs, vs->ioc); in vnc_disconnect_start()
1300 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED); in vnc_disconnect_start()
1301 if (vs->ioc_tag) { in vnc_disconnect_start()
1302 g_source_remove(vs->ioc_tag); in vnc_disconnect_start()
1303 vs->ioc_tag = 0; in vnc_disconnect_start()
1305 qio_channel_close(vs->ioc, NULL); in vnc_disconnect_start()
1306 vs->disconnecting = TRUE; in vnc_disconnect_start()
1309 void vnc_disconnect_finish(VncState *vs) in vnc_disconnect_finish() argument
1313 trace_vnc_client_disconnect_finish(vs, vs->ioc); in vnc_disconnect_finish()
1315 vnc_jobs_join(vs); /* Wait encoding jobs */ in vnc_disconnect_finish()
1317 vnc_lock_output(vs); in vnc_disconnect_finish()
1318 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED); in vnc_disconnect_finish()
1320 buffer_free(&vs->input); in vnc_disconnect_finish()
1321 buffer_free(&vs->output); in vnc_disconnect_finish()
1323 qapi_free_VncClientInfo(vs->info); in vnc_disconnect_finish()
1325 vnc_zlib_clear(vs); in vnc_disconnect_finish()
1326 vnc_tight_clear(vs); in vnc_disconnect_finish()
1327 vnc_zrle_clear(vs); in vnc_disconnect_finish()
1330 vnc_sasl_client_cleanup(vs); in vnc_disconnect_finish()
1332 audio_del(vs); in vnc_disconnect_finish()
1333 qkbd_state_lift_all_keys(vs->vd->kbd); in vnc_disconnect_finish()
1335 if (vs->mouse_mode_notifier.notify != NULL) { in vnc_disconnect_finish()
1336 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier); in vnc_disconnect_finish()
1338 QTAILQ_REMOVE(&vs->vd->clients, vs, next); in vnc_disconnect_finish()
1339 if (QTAILQ_EMPTY(&vs->vd->clients)) { in vnc_disconnect_finish()
1341 vnc_update_server_surface(vs->vd); in vnc_disconnect_finish()
1343 vnc_unlock_output(vs); in vnc_disconnect_finish()
1345 if (vs->cbpeer.notifier.notify) { in vnc_disconnect_finish()
1346 qemu_clipboard_peer_unregister(&vs->cbpeer); in vnc_disconnect_finish()
1349 qemu_mutex_destroy(&vs->output_mutex); in vnc_disconnect_finish()
1350 if (vs->bh != NULL) { in vnc_disconnect_finish()
1351 qemu_bh_delete(vs->bh); in vnc_disconnect_finish()
1353 buffer_free(&vs->jobs_buffer); in vnc_disconnect_finish()
1356 g_free(vs->lossy_rect[i]); in vnc_disconnect_finish()
1358 g_free(vs->lossy_rect); in vnc_disconnect_finish()
1360 object_unref(OBJECT(vs->ioc)); in vnc_disconnect_finish()
1361 vs->ioc = NULL; in vnc_disconnect_finish()
1362 object_unref(OBJECT(vs->sioc)); in vnc_disconnect_finish()
1363 vs->sioc = NULL; in vnc_disconnect_finish()
1364 vs->magic = 0; in vnc_disconnect_finish()
1365 g_free(vs->zrle); in vnc_disconnect_finish()
1366 g_free(vs->tight); in vnc_disconnect_finish()
1367 g_free(vs); in vnc_disconnect_finish()
1370 size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err) in vnc_client_io_error() argument
1374 trace_vnc_client_eof(vs, vs->ioc); in vnc_client_io_error()
1375 vnc_disconnect_start(vs); in vnc_client_io_error()
1377 trace_vnc_client_io_error(vs, vs->ioc, in vnc_client_io_error()
1379 vnc_disconnect_start(vs); in vnc_client_io_error()
1389 void vnc_client_error(VncState *vs) in vnc_client_error() argument
1392 vnc_disconnect_start(vs); in vnc_client_error()
1411 size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen) in vnc_client_write_buf() argument
1415 ret = qio_channel_write(vs->ioc, (const char *)data, datalen, &err); in vnc_client_write_buf()
1417 return vnc_client_io_error(vs, ret, err); in vnc_client_write_buf()
1431 static size_t vnc_client_write_plain(VncState *vs) in vnc_client_write_plain() argument
1438 vs->output.buffer, vs->output.capacity, vs->output.offset, in vnc_client_write_plain()
1439 vs->sasl.waitWriteSSF); in vnc_client_write_plain()
1441 if (vs->sasl.conn && in vnc_client_write_plain()
1442 vs->sasl.runSSF && in vnc_client_write_plain()
1443 vs->sasl.waitWriteSSF) { in vnc_client_write_plain()
1444 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF); in vnc_client_write_plain()
1446 vs->sasl.waitWriteSSF -= ret; in vnc_client_write_plain()
1449 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset); in vnc_client_write_plain()
1453 if (ret >= vs->force_update_offset) { in vnc_client_write_plain()
1454 if (vs->force_update_offset != 0) { in vnc_client_write_plain()
1455 trace_vnc_client_unthrottle_forced(vs, vs->ioc); in vnc_client_write_plain()
1457 vs->force_update_offset = 0; in vnc_client_write_plain()
1459 vs->force_update_offset -= ret; in vnc_client_write_plain()
1461 offset = vs->output.offset; in vnc_client_write_plain()
1462 buffer_advance(&vs->output, ret); in vnc_client_write_plain()
1463 if (offset >= vs->throttle_output_offset && in vnc_client_write_plain()
1464 vs->output.offset < vs->throttle_output_offset) { in vnc_client_write_plain()
1465 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset); in vnc_client_write_plain()
1468 if (vs->output.offset == 0) { in vnc_client_write_plain()
1469 if (vs->ioc_tag) { in vnc_client_write_plain()
1470 g_source_remove(vs->ioc_tag); in vnc_client_write_plain()
1472 vs->ioc_tag = qio_channel_add_watch( in vnc_client_write_plain()
1473 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, in vnc_client_write_plain()
1474 vnc_client_io, vs, NULL); in vnc_client_write_plain()
1486 static void vnc_client_write_locked(VncState *vs) in vnc_client_write_locked() argument
1489 if (vs->sasl.conn && in vnc_client_write_locked()
1490 vs->sasl.runSSF && in vnc_client_write_locked()
1491 !vs->sasl.waitWriteSSF) { in vnc_client_write_locked()
1492 vnc_client_write_sasl(vs); in vnc_client_write_locked()
1496 vnc_client_write_plain(vs); in vnc_client_write_locked()
1500 static void vnc_client_write(VncState *vs) in vnc_client_write() argument
1502 assert(vs->magic == VNC_MAGIC); in vnc_client_write()
1503 vnc_lock_output(vs); in vnc_client_write()
1504 if (vs->output.offset) { in vnc_client_write()
1505 vnc_client_write_locked(vs); in vnc_client_write()
1506 } else if (vs->ioc != NULL) { in vnc_client_write()
1507 if (vs->ioc_tag) { in vnc_client_write()
1508 g_source_remove(vs->ioc_tag); in vnc_client_write()
1510 vs->ioc_tag = qio_channel_add_watch( in vnc_client_write()
1511 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, in vnc_client_write()
1512 vnc_client_io, vs, NULL); in vnc_client_write()
1514 vnc_unlock_output(vs); in vnc_client_write()
1517 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting) in vnc_read_when() argument
1519 vs->read_handler = func; in vnc_read_when()
1520 vs->read_handler_expect = expecting; in vnc_read_when()
1539 size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen) in vnc_client_read_buf() argument
1543 ret = qio_channel_read(vs->ioc, (char *)data, datalen, &err); in vnc_client_read_buf()
1545 return vnc_client_io_error(vs, ret, err); in vnc_client_read_buf()
1558 static size_t vnc_client_read_plain(VncState *vs) in vnc_client_read_plain() argument
1562 vs->input.buffer, vs->input.capacity, vs->input.offset); in vnc_client_read_plain()
1563 buffer_reserve(&vs->input, 4096); in vnc_client_read_plain()
1564 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096); in vnc_client_read_plain()
1567 vs->input.offset += ret; in vnc_client_read_plain()
1573 VncState *vs = opaque; in vnc_jobs_bh() local
1575 assert(vs->magic == VNC_MAGIC); in vnc_jobs_bh()
1576 vnc_jobs_consume_buffer(vs); in vnc_jobs_bh()
1585 static int vnc_client_read(VncState *vs) in vnc_client_read() argument
1590 if (vs->sasl.conn && vs->sasl.runSSF) in vnc_client_read()
1591 sz = vnc_client_read_sasl(vs); in vnc_client_read()
1594 sz = vnc_client_read_plain(vs); in vnc_client_read()
1596 if (vs->disconnecting) { in vnc_client_read()
1597 vnc_disconnect_finish(vs); in vnc_client_read()
1603 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) { in vnc_client_read()
1604 size_t len = vs->read_handler_expect; in vnc_client_read()
1607 ret = vs->read_handler(vs, vs->input.buffer, len); in vnc_client_read()
1608 if (vs->disconnecting) { in vnc_client_read()
1609 vnc_disconnect_finish(vs); in vnc_client_read()
1614 buffer_advance(&vs->input, len); in vnc_client_read()
1616 vs->read_handler_expect = ret; in vnc_client_read()
1625 VncState *vs = opaque; in vnc_client_io() local
1627 assert(vs->magic == VNC_MAGIC); in vnc_client_io()
1630 vnc_disconnect_start(vs); in vnc_client_io()
1635 if (vnc_client_read(vs) < 0) { in vnc_client_io()
1636 /* vs is free()ed here */ in vnc_client_io()
1641 vnc_client_write(vs); in vnc_client_io()
1644 if (vs->disconnecting) { in vnc_client_io()
1645 if (vs->ioc_tag != 0) { in vnc_client_io()
1646 g_source_remove(vs->ioc_tag); in vnc_client_io()
1648 vs->ioc_tag = 0; in vnc_client_io()
1655 * Scale factor to apply to vs->throttle_output_offset when checking for
1661 #define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1663 void vnc_write(VncState *vs, const void *data, size_t len) in vnc_write() argument
1665 assert(vs->magic == VNC_MAGIC); in vnc_write()
1666 if (vs->disconnecting) { in vnc_write()
1680 if (vs->throttle_output_offset != 0 && in vnc_write()
1681 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) > in vnc_write()
1682 vs->throttle_output_offset) { in vnc_write()
1683 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset, in vnc_write()
1684 vs->throttle_output_offset); in vnc_write()
1685 vnc_disconnect_start(vs); in vnc_write()
1688 buffer_reserve(&vs->output, len); in vnc_write()
1690 if (vs->ioc != NULL && buffer_empty(&vs->output)) { in vnc_write()
1691 if (vs->ioc_tag) { in vnc_write()
1692 g_source_remove(vs->ioc_tag); in vnc_write()
1694 vs->ioc_tag = qio_channel_add_watch( in vnc_write()
1695 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT, in vnc_write()
1696 vnc_client_io, vs, NULL); in vnc_write()
1699 buffer_append(&vs->output, data, len); in vnc_write()
1702 void vnc_write_s32(VncState *vs, int32_t value) in vnc_write_s32() argument
1704 vnc_write_u32(vs, *(uint32_t *)&value); in vnc_write_s32()
1707 void vnc_write_u32(VncState *vs, uint32_t value) in vnc_write_u32() argument
1716 vnc_write(vs, buf, 4); in vnc_write_u32()
1719 void vnc_write_u16(VncState *vs, uint16_t value) in vnc_write_u16() argument
1726 vnc_write(vs, buf, 2); in vnc_write_u16()
1729 void vnc_write_u8(VncState *vs, uint8_t value) in vnc_write_u8() argument
1731 vnc_write(vs, (char *)&value, 1); in vnc_write_u8()
1734 void vnc_flush(VncState *vs) in vnc_flush() argument
1736 vnc_lock_output(vs); in vnc_flush()
1737 if (vs->ioc != NULL && vs->output.offset) { in vnc_flush()
1738 vnc_client_write_locked(vs); in vnc_flush()
1740 if (vs->disconnecting) { in vnc_flush()
1741 if (vs->ioc_tag != 0) { in vnc_flush()
1742 g_source_remove(vs->ioc_tag); in vnc_flush()
1744 vs->ioc_tag = 0; in vnc_flush()
1746 vnc_unlock_output(vs); in vnc_flush()
1773 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier); in check_pointer_type_change() local
1774 int absolute = qemu_input_is_absolute(vs->vd->dcl.con); in check_pointer_type_change()
1776 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) { in check_pointer_type_change()
1777 vnc_lock_output(vs); in check_pointer_type_change()
1778 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in check_pointer_type_change()
1779 vnc_write_u8(vs, 0); in check_pointer_type_change()
1780 vnc_write_u16(vs, 1); in check_pointer_type_change()
1781 vnc_framebuffer_update(vs, absolute, 0, in check_pointer_type_change()
1782 pixman_image_get_width(vs->vd->server), in check_pointer_type_change()
1783 pixman_image_get_height(vs->vd->server), in check_pointer_type_change()
1785 vnc_unlock_output(vs); in check_pointer_type_change()
1786 vnc_flush(vs); in check_pointer_type_change()
1788 vs->absolute = absolute; in check_pointer_type_change()
1791 static void pointer_event(VncState *vs, int button_mask, int x, int y) in pointer_event() argument
1800 QemuConsole *con = vs->vd->dcl.con; in pointer_event()
1801 int width = pixman_image_get_width(vs->vd->server); in pointer_event()
1802 int height = pixman_image_get_height(vs->vd->server); in pointer_event()
1804 if (vs->last_bmask != button_mask) { in pointer_event()
1805 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask); in pointer_event()
1806 vs->last_bmask = button_mask; in pointer_event()
1809 if (vs->absolute) { in pointer_event()
1812 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) { in pointer_event()
1816 if (vs->last_x != -1) { in pointer_event()
1817 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x); in pointer_event()
1818 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y); in pointer_event()
1820 vs->last_x = x; in pointer_event()
1821 vs->last_y = y; in pointer_event()
1826 static void press_key(VncState *vs, QKeyCode qcode) in press_key() argument
1828 qkbd_state_key_event(vs->vd->kbd, qcode, true); in press_key()
1829 qkbd_state_key_event(vs->vd->kbd, qcode, false); in press_key()
1832 static void vnc_led_state_change(VncState *vs) in vnc_led_state_change() argument
1834 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) { in vnc_led_state_change()
1838 vnc_lock_output(vs); in vnc_led_state_change()
1839 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in vnc_led_state_change()
1840 vnc_write_u8(vs, 0); in vnc_led_state_change()
1841 vnc_write_u16(vs, 1); in vnc_led_state_change()
1842 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE); in vnc_led_state_change()
1843 vnc_write_u8(vs, vs->vd->ledstate); in vnc_led_state_change()
1844 vnc_unlock_output(vs); in vnc_led_state_change()
1845 vnc_flush(vs); in vnc_led_state_change()
1868 static void do_key_event(VncState *vs, int down, int keycode, int sym) in do_key_event() argument
1876 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) && in do_key_event()
1877 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) { in do_key_event()
1880 unregister_displaychangelistener(&vs->vd->dcl); in do_key_event()
1881 qkbd_state_switch_console(vs->vd->kbd, con); in do_key_event()
1882 vs->vd->dcl.con = con; in do_key_event()
1883 register_displaychangelistener(&vs->vd->dcl); in do_key_event()
1894 if (down && vs->vd->lock_key_sync && in do_key_event()
1895 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) && in do_key_event()
1896 keycode_is_keypad(vs->vd->kbd_layout, keycode)) { in do_key_event()
1901 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) { in do_key_event()
1902 if (!qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) { in do_key_event()
1904 press_key(vs, Q_KEY_CODE_NUM_LOCK); in do_key_event()
1907 if (qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) { in do_key_event()
1909 press_key(vs, Q_KEY_CODE_NUM_LOCK); in do_key_event()
1914 if (down && vs->vd->lock_key_sync && in do_key_event()
1915 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) && in do_key_event()
1922 bool shift = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_SHIFT); in do_key_event()
1923 bool capslock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CAPSLOCK); in do_key_event()
1927 press_key(vs, Q_KEY_CODE_CAPS_LOCK); in do_key_event()
1932 press_key(vs, Q_KEY_CODE_CAPS_LOCK); in do_key_event()
1937 qkbd_state_key_event(vs->vd->kbd, qcode, down); in do_key_event()
1938 if (QEMU_IS_TEXT_CONSOLE(vs->vd->dcl.con)) { in do_key_event()
1939 QemuTextConsole *con = QEMU_TEXT_CONSOLE(vs->vd->dcl.con); in do_key_event()
1940 bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK); in do_key_event()
1941 bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL); in do_key_event()
1993 qemu_text_console_put_keysym(con, '5'); in do_key_event()
2047 static void key_event(VncState *vs, int down, uint32_t sym) in key_event() argument
2052 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(vs->vd->dcl.con)) { in key_event()
2056 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF, in key_event()
2057 vs->vd->kbd, down) & SCANCODE_KEYMASK; in key_event()
2059 do_key_event(vs, down, keycode, sym); in key_event()
2062 static void ext_key_event(VncState *vs, int down, in ext_key_event() argument
2067 key_event(vs, down, sym); in ext_key_event()
2070 do_key_event(vs, down, keycode, sym); in ext_key_event()
2074 static void framebuffer_update_request(VncState *vs, int incremental, in framebuffer_update_request() argument
2078 if (vs->update != VNC_STATE_UPDATE_FORCE) { in framebuffer_update_request()
2079 vs->update = VNC_STATE_UPDATE_INCREMENTAL; in framebuffer_update_request()
2082 vs->update = VNC_STATE_UPDATE_FORCE; in framebuffer_update_request()
2083 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h); in framebuffer_update_request()
2084 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) { in framebuffer_update_request()
2085 vnc_desktop_resize_ext(vs, 0); in framebuffer_update_request()
2090 static void send_ext_key_event_ack(VncState *vs) in send_ext_key_event_ack() argument
2092 vnc_lock_output(vs); in send_ext_key_event_ack()
2093 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in send_ext_key_event_ack()
2094 vnc_write_u8(vs, 0); in send_ext_key_event_ack()
2095 vnc_write_u16(vs, 1); in send_ext_key_event_ack()
2096 vnc_framebuffer_update(vs, 0, 0, in send_ext_key_event_ack()
2097 pixman_image_get_width(vs->vd->server), in send_ext_key_event_ack()
2098 pixman_image_get_height(vs->vd->server), in send_ext_key_event_ack()
2100 vnc_unlock_output(vs); in send_ext_key_event_ack()
2101 vnc_flush(vs); in send_ext_key_event_ack()
2104 static void send_ext_audio_ack(VncState *vs) in send_ext_audio_ack() argument
2106 vnc_lock_output(vs); in send_ext_audio_ack()
2107 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in send_ext_audio_ack()
2108 vnc_write_u8(vs, 0); in send_ext_audio_ack()
2109 vnc_write_u16(vs, 1); in send_ext_audio_ack()
2110 vnc_framebuffer_update(vs, 0, 0, in send_ext_audio_ack()
2111 pixman_image_get_width(vs->vd->server), in send_ext_audio_ack()
2112 pixman_image_get_height(vs->vd->server), in send_ext_audio_ack()
2114 vnc_unlock_output(vs); in send_ext_audio_ack()
2115 vnc_flush(vs); in send_ext_audio_ack()
2118 static void send_xvp_message(VncState *vs, int code) in send_xvp_message() argument
2120 vnc_lock_output(vs); in send_xvp_message()
2121 vnc_write_u8(vs, VNC_MSG_SERVER_XVP); in send_xvp_message()
2122 vnc_write_u8(vs, 0); /* pad */ in send_xvp_message()
2123 vnc_write_u8(vs, 1); /* version */ in send_xvp_message()
2124 vnc_write_u8(vs, code); in send_xvp_message()
2125 vnc_unlock_output(vs); in send_xvp_message()
2126 vnc_flush(vs); in send_xvp_message()
2129 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) in set_encodings() argument
2134 vs->features = 0; in set_encodings()
2135 vs->vnc_encoding = 0; in set_encodings()
2136 vs->tight->compression = 9; in set_encodings()
2137 vs->tight->quality = -1; /* Lossless by default */ in set_encodings()
2138 vs->absolute = -1; in set_encodings()
2149 vs->vnc_encoding = enc; in set_encodings()
2152 vnc_set_feature(vs, VNC_FEATURE_HEXTILE); in set_encodings()
2153 vs->vnc_encoding = enc; in set_encodings()
2156 vnc_set_feature(vs, VNC_FEATURE_TIGHT); in set_encodings()
2157 vs->vnc_encoding = enc; in set_encodings()
2161 vnc_set_feature(vs, VNC_FEATURE_TIGHT_PNG); in set_encodings()
2162 vs->vnc_encoding = enc; in set_encodings()
2171 if (!vnc_has_feature(vs, VNC_FEATURE_ZRLE)) { in set_encodings()
2172 vnc_set_feature(vs, VNC_FEATURE_ZLIB); in set_encodings()
2173 vs->vnc_encoding = enc; in set_encodings()
2177 vnc_set_feature(vs, VNC_FEATURE_ZRLE); in set_encodings()
2178 vs->vnc_encoding = enc; in set_encodings()
2181 vnc_set_feature(vs, VNC_FEATURE_ZYWRLE); in set_encodings()
2182 vs->vnc_encoding = enc; in set_encodings()
2185 vnc_set_feature(vs, VNC_FEATURE_RESIZE); in set_encodings()
2188 vnc_set_feature(vs, VNC_FEATURE_RESIZE_EXT); in set_encodings()
2191 vnc_set_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE); in set_encodings()
2194 vnc_set_feature(vs, VNC_FEATURE_RICH_CURSOR); in set_encodings()
2197 vnc_set_feature(vs, VNC_FEATURE_ALPHA_CURSOR); in set_encodings()
2200 send_ext_key_event_ack(vs); in set_encodings()
2203 if (vs->vd->audio_state) { in set_encodings()
2204 vnc_set_feature(vs, VNC_FEATURE_AUDIO); in set_encodings()
2205 send_ext_audio_ack(vs); in set_encodings()
2209 vnc_set_feature(vs, VNC_FEATURE_WMVI); in set_encodings()
2212 vnc_set_feature(vs, VNC_FEATURE_LED_STATE); in set_encodings()
2215 if (vs->vd->power_control) { in set_encodings()
2216 vnc_set_feature(vs, VNC_FEATURE_XVP); in set_encodings()
2217 send_xvp_message(vs, VNC_XVP_CODE_INIT); in set_encodings()
2221 vnc_set_feature(vs, VNC_FEATURE_CLIPBOARD_EXT); in set_encodings()
2222 vnc_server_cut_text_caps(vs); in set_encodings()
2225 vs->tight->compression = (enc & 0x0F); in set_encodings()
2228 if (vs->vd->lossy) { in set_encodings()
2229 vs->tight->quality = (enc & 0x0F); in set_encodings()
2237 vnc_desktop_resize(vs); in set_encodings()
2238 check_pointer_type_change(&vs->mouse_mode_notifier, NULL); in set_encodings()
2239 vnc_led_state_change(vs); in set_encodings()
2240 vnc_cursor_define(vs); in set_encodings()
2243 static void set_pixel_conversion(VncState *vs) in set_pixel_conversion() argument
2245 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf); in set_pixel_conversion()
2248 vs->write_pixels = vnc_write_pixels_copy; in set_pixel_conversion()
2249 vnc_hextile_set_pixel_conversion(vs, 0); in set_pixel_conversion()
2251 vs->write_pixels = vnc_write_pixels_generic; in set_pixel_conversion()
2252 vnc_hextile_set_pixel_conversion(vs, 1); in set_pixel_conversion()
2256 static void send_color_map(VncState *vs) in send_color_map() argument
2260 vnc_lock_output(vs); in send_color_map()
2261 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES); in send_color_map()
2262 vnc_write_u8(vs, 0); /* padding */ in send_color_map()
2263 vnc_write_u16(vs, 0); /* first color */ in send_color_map()
2264 vnc_write_u16(vs, 256); /* # of colors */ in send_color_map()
2267 PixelFormat *pf = &vs->client_pf; in send_color_map()
2269 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits))); in send_color_map()
2270 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits))); in send_color_map()
2271 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits))); in send_color_map()
2273 vnc_unlock_output(vs); in send_color_map()
2276 static void set_pixel_format(VncState *vs, int bits_per_pixel, in set_pixel_format() argument
2298 vnc_client_error(vs); in set_pixel_format()
2302 vs->client_pf.rmax = red_max ? red_max : 0xFF; in set_pixel_format()
2303 vs->client_pf.rbits = ctpopl(red_max); in set_pixel_format()
2304 vs->client_pf.rshift = red_shift; in set_pixel_format()
2305 vs->client_pf.rmask = red_max << red_shift; in set_pixel_format()
2306 vs->client_pf.gmax = green_max ? green_max : 0xFF; in set_pixel_format()
2307 vs->client_pf.gbits = ctpopl(green_max); in set_pixel_format()
2308 vs->client_pf.gshift = green_shift; in set_pixel_format()
2309 vs->client_pf.gmask = green_max << green_shift; in set_pixel_format()
2310 vs->client_pf.bmax = blue_max ? blue_max : 0xFF; in set_pixel_format()
2311 vs->client_pf.bbits = ctpopl(blue_max); in set_pixel_format()
2312 vs->client_pf.bshift = blue_shift; in set_pixel_format()
2313 vs->client_pf.bmask = blue_max << blue_shift; in set_pixel_format()
2314 vs->client_pf.bits_per_pixel = bits_per_pixel; in set_pixel_format()
2315 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8; in set_pixel_format()
2316 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel; in set_pixel_format()
2317 vs->client_be = big_endian_flag; in set_pixel_format()
2320 send_color_map(vs); in set_pixel_format()
2323 set_pixel_conversion(vs); in set_pixel_format()
2325 graphic_hw_invalidate(vs->vd->dcl.con); in set_pixel_format()
2326 graphic_hw_update(vs->vd->dcl.con); in set_pixel_format()
2329 static void pixel_format_message (VncState *vs) { in pixel_format_message() argument
2332 vs->client_pf = qemu_default_pixelformat(32); in pixel_format_message()
2334 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */ in pixel_format_message()
2335 vnc_write_u8(vs, vs->client_pf.depth); /* depth */ in pixel_format_message()
2338 vnc_write_u8(vs, 1); /* big-endian-flag */ in pixel_format_message()
2340 vnc_write_u8(vs, 0); /* big-endian-flag */ in pixel_format_message()
2342 vnc_write_u8(vs, 1); /* true-color-flag */ in pixel_format_message()
2343 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */ in pixel_format_message()
2344 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */ in pixel_format_message()
2345 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */ in pixel_format_message()
2346 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */ in pixel_format_message()
2347 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */ in pixel_format_message()
2348 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */ in pixel_format_message()
2349 vnc_write(vs, pad, 3); /* padding */ in pixel_format_message()
2351 vnc_hextile_set_pixel_conversion(vs, 0); in pixel_format_message()
2352 vs->write_pixels = vnc_write_pixels_copy; in pixel_format_message()
2355 static void vnc_colordepth(VncState *vs) in vnc_colordepth() argument
2357 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) { in vnc_colordepth()
2359 vnc_lock_output(vs); in vnc_colordepth()
2360 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); in vnc_colordepth()
2361 vnc_write_u8(vs, 0); in vnc_colordepth()
2362 vnc_write_u16(vs, 1); /* number of rects */ in vnc_colordepth()
2363 vnc_framebuffer_update(vs, 0, 0, in vnc_colordepth()
2364 vs->client_width, in vnc_colordepth()
2365 vs->client_height, in vnc_colordepth()
2367 pixel_format_message(vs); in vnc_colordepth()
2368 vnc_unlock_output(vs); in vnc_colordepth()
2369 vnc_flush(vs); in vnc_colordepth()
2371 set_pixel_conversion(vs); in vnc_colordepth()
2375 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) in protocol_client_msg() argument
2380 VncDisplay *vd = vs->vd; in protocol_client_msg()
2391 set_pixel_format(vs, read_u8(data, 4), in protocol_client_msg()
2413 set_encodings(vs, (int32_t *)(data + 4), limit); in protocol_client_msg()
2419 framebuffer_update_request(vs, in protocol_client_msg()
2427 key_event(vs, read_u8(data, 1), read_u32(data, 4)); in protocol_client_msg()
2433 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4)); in protocol_client_msg()
2444 vnc_client_error(vs); in protocol_client_msg()
2453 if (!vnc_has_feature(vs, VNC_FEATURE_CLIPBOARD_EXT)) { in protocol_client_msg()
2455 vnc_client_error(vs); in protocol_client_msg()
2461 vnc_client_error(vs); in protocol_client_msg()
2464 vnc_client_cut_text_ext(vs, dlen, read_u32(data, 8), data + 12); in protocol_client_msg()
2467 vnc_client_cut_text(vs, read_u32(data, 4), data + 8); in protocol_client_msg()
2470 if (!vnc_has_feature(vs, VNC_FEATURE_XVP)) { in protocol_client_msg()
2472 vnc_client_error(vs); in protocol_client_msg()
2485 vnc_client_error(vs); in protocol_client_msg()
2494 send_xvp_message(vs, VNC_XVP_CODE_FAIL); in protocol_client_msg()
2500 send_xvp_message(vs, VNC_XVP_CODE_FAIL); in protocol_client_msg()
2514 ext_key_event(vs, read_u16(data, 2), in protocol_client_msg()
2518 if (!vnc_has_feature(vs, VNC_FEATURE_AUDIO)) { in protocol_client_msg()
2520 vnc_client_error(vs); in protocol_client_msg()
2529 trace_vnc_msg_client_audio_enable(vs, vs->ioc); in protocol_client_msg()
2530 audio_add(vs); in protocol_client_msg()
2533 trace_vnc_msg_client_audio_disable(vs, vs->ioc); in protocol_client_msg()
2534 audio_del(vs); in protocol_client_msg()
2540 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break; in protocol_client_msg()
2541 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break; in protocol_client_msg()
2542 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break; in protocol_client_msg()
2543 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break; in protocol_client_msg()
2544 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break; in protocol_client_msg()
2545 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break; in protocol_client_msg()
2548 vnc_client_error(vs); in protocol_client_msg()
2551 vs->as.nchannels = read_u8(data, 5); in protocol_client_msg()
2552 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) { in protocol_client_msg()
2554 read_u8(data, 5)); in protocol_client_msg()
2555 vnc_client_error(vs); in protocol_client_msg()
2561 * protects calculations involving 'vs->as.freq' later. in protocol_client_msg()
2565 vnc_client_error(vs); in protocol_client_msg()
2568 vs->as.freq = freq; in protocol_client_msg()
2570 vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq); in protocol_client_msg()
2574 vnc_client_error(vs); in protocol_client_msg()
2581 vnc_client_error(vs); in protocol_client_msg()
2603 trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens); in protocol_client_msg()
2604 if (dpy_ui_info_supported(vs->vd->dcl.con)) { in protocol_client_msg()
2609 dpy_set_ui_info(vs->vd->dcl.con, &info, false); in protocol_client_msg()
2610 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */); in protocol_client_msg()
2612 vnc_desktop_resize_ext(vs, 3 /* Invalid screen layout */); in protocol_client_msg()
2619 vnc_client_error(vs); in protocol_client_msg()
2623 vnc_update_throttle_offset(vs); in protocol_client_msg()
2624 vnc_read_when(vs, protocol_client_msg, 1); in protocol_client_msg()
2628 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) in protocol_client_init() argument
2635 switch (vs->vd->share_policy) { in protocol_client_init()
2657 QTAILQ_FOREACH(client, &vs->vd->clients, next) { in protocol_client_init()
2658 if (vs == client) { in protocol_client_init()
2669 if (vs->vd->num_exclusive > 0) { in protocol_client_init()
2670 vnc_disconnect_start(vs); in protocol_client_init()
2685 vnc_disconnect_start(vs); in protocol_client_init()
2690 vnc_set_share_mode(vs, mode); in protocol_client_init()
2692 if (vs->vd->num_shared > vs->vd->connections_limit) { in protocol_client_init()
2693 vnc_disconnect_start(vs); in protocol_client_init()
2697 assert(pixman_image_get_width(vs->vd->server) < 65536 && in protocol_client_init()
2698 pixman_image_get_width(vs->vd->server) >= 0); in protocol_client_init()
2699 assert(pixman_image_get_height(vs->vd->server) < 65536 && in protocol_client_init()
2700 pixman_image_get_height(vs->vd->server) >= 0); in protocol_client_init()
2701 vs->client_width = pixman_image_get_width(vs->vd->server); in protocol_client_init()
2702 vs->client_height = pixman_image_get_height(vs->vd->server); in protocol_client_init()
2703 vnc_write_u16(vs, vs->client_width); in protocol_client_init()
2704 vnc_write_u16(vs, vs->client_height); in protocol_client_init()
2706 pixel_format_message(vs); in protocol_client_init()
2717 vnc_write_u32(vs, size); in protocol_client_init()
2718 vnc_write(vs, buf, size); in protocol_client_init()
2719 vnc_flush(vs); in protocol_client_init()
2721 vnc_client_cache_auth(vs); in protocol_client_init()
2722 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED); in protocol_client_init()
2724 vnc_read_when(vs, protocol_client_msg, 1); in protocol_client_init()
2729 void start_client_init(VncState *vs) in start_client_init() argument
2731 vnc_read_when(vs, protocol_client_init, 1); in start_client_init()
2734 static void authentication_failed(VncState *vs) in authentication_failed() argument
2736 vnc_write_u32(vs, 1); /* Reject auth */ in authentication_failed()
2737 if (vs->minor >= 8) { in authentication_failed()
2739 vnc_write_u32(vs, sizeof(err)); in authentication_failed()
2740 vnc_write(vs, err, sizeof(err)); in authentication_failed()
2742 vnc_flush(vs); in authentication_failed()
2743 vnc_client_error(vs); in authentication_failed()
2759 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) in protocol_client_auth_vnc() argument
2768 if (!vs->vd->password) { in protocol_client_auth_vnc()
2769 trace_vnc_auth_fail(vs, vs->auth, "password is not set", ""); in protocol_client_auth_vnc()
2772 if (vs->vd->expires < now) { in protocol_client_auth_vnc()
2773 trace_vnc_auth_fail(vs, vs->auth, "password is expired", ""); in protocol_client_auth_vnc()
2777 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE); in protocol_client_auth_vnc()
2780 pwlen = strlen(vs->vd->password); in protocol_client_auth_vnc()
2782 key[i] = i<pwlen ? vs->vd->password[i] : 0; in protocol_client_auth_vnc()
2791 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher", in protocol_client_auth_vnc()
2798 vs->challenge, in protocol_client_auth_vnc()
2802 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response", in protocol_client_auth_vnc()
2808 /* Compare expected vs actual challenge response */ in protocol_client_auth_vnc()
2810 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", ""); in protocol_client_auth_vnc()
2813 trace_vnc_auth_pass(vs, vs->auth); in protocol_client_auth_vnc()
2814 vnc_write_u32(vs, 0); /* Accept auth */ in protocol_client_auth_vnc()
2815 vnc_flush(vs); in protocol_client_auth_vnc()
2817 start_client_init(vs); in protocol_client_auth_vnc()
2824 authentication_failed(vs); in protocol_client_auth_vnc()
2829 void start_auth_vnc(VncState *vs) in start_auth_vnc() argument
2833 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) { in start_auth_vnc()
2834 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes", in start_auth_vnc()
2837 authentication_failed(vs); in start_auth_vnc()
2842 vnc_write(vs, vs->challenge, sizeof(vs->challenge)); in start_auth_vnc()
2843 vnc_flush(vs); in start_auth_vnc()
2845 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge)); in start_auth_vnc()
2849 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) in protocol_client_auth() argument
2853 if (data[0] != vs->auth) { /* Reject auth */ in protocol_client_auth()
2854 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]); in protocol_client_auth()
2855 authentication_failed(vs); in protocol_client_auth()
2857 trace_vnc_auth_start(vs, vs->auth); in protocol_client_auth()
2858 switch (vs->auth) { in protocol_client_auth()
2860 if (vs->minor >= 8) { in protocol_client_auth()
2861 vnc_write_u32(vs, 0); /* Accept auth completion */ in protocol_client_auth()
2862 vnc_flush(vs); in protocol_client_auth()
2864 trace_vnc_auth_pass(vs, vs->auth); in protocol_client_auth()
2865 start_client_init(vs); in protocol_client_auth()
2869 start_auth_vnc(vs); in protocol_client_auth()
2873 start_auth_vencrypt(vs); in protocol_client_auth()
2878 start_auth_sasl(vs); in protocol_client_auth()
2883 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", ""); in protocol_client_auth()
2884 authentication_failed(vs); in protocol_client_auth()
2890 static int protocol_version(VncState *vs, uint8_t *version, size_t len) in protocol_version() argument
2897 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) { in protocol_version()
2899 vnc_client_error(vs); in protocol_version()
2902 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor); in protocol_version()
2903 if (vs->major != 3 || in protocol_version()
2904 (vs->minor != 3 && in protocol_version()
2905 vs->minor != 4 && in protocol_version()
2906 vs->minor != 5 && in protocol_version()
2907 vs->minor != 7 && in protocol_version()
2908 vs->minor != 8)) { in protocol_version()
2910 vnc_write_u32(vs, VNC_AUTH_INVALID); in protocol_version()
2911 vnc_flush(vs); in protocol_version()
2912 vnc_client_error(vs); in protocol_version()
2915 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated in protocol_version()
2918 if (vs->minor == 4 || vs->minor == 5) in protocol_version()
2919 vs->minor = 3; in protocol_version()
2921 if (vs->minor == 3) { in protocol_version()
2922 trace_vnc_auth_start(vs, vs->auth); in protocol_version()
2923 if (vs->auth == VNC_AUTH_NONE) { in protocol_version()
2924 vnc_write_u32(vs, vs->auth); in protocol_version()
2925 vnc_flush(vs); in protocol_version()
2926 trace_vnc_auth_pass(vs, vs->auth); in protocol_version()
2927 start_client_init(vs); in protocol_version()
2928 } else if (vs->auth == VNC_AUTH_VNC) { in protocol_version()
2930 vnc_write_u32(vs, vs->auth); in protocol_version()
2931 vnc_flush(vs); in protocol_version()
2932 start_auth_vnc(vs); in protocol_version()
2934 trace_vnc_auth_fail(vs, vs->auth, in protocol_version()
2936 vnc_write_u32(vs, VNC_AUTH_INVALID); in protocol_version()
2937 vnc_flush(vs); in protocol_version()
2938 vnc_client_error(vs); in protocol_version()
2941 vnc_write_u8(vs, 1); /* num auth */ in protocol_version()
2942 vnc_write_u8(vs, vs->auth); in protocol_version()
2943 vnc_read_when(vs, protocol_client_auth, 1); in protocol_version()
2944 vnc_flush(vs); in protocol_version()
2952 struct VncSurface *vs = &vd->guest; in vnc_stat_rect() local
2954 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT]; in vnc_stat_rect()
2957 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h) in vnc_sent_lossy_rect() argument
2968 vs->lossy_rect[j][i] = 1; in vnc_sent_lossy_rect()
2975 VncState *vs; in vnc_refresh_lossy_rect() local
2983 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_refresh_lossy_rect()
2987 if (vs->output.offset) { in vnc_refresh_lossy_rect()
2991 if (!vs->lossy_rect[sty][stx]) { in vnc_refresh_lossy_rect()
2995 vs->lossy_rect[sty][stx] = 0; in vnc_refresh_lossy_rect()
2997 bitmap_set(vs->dirty[y + j], in vnc_refresh_lossy_rect()
3064 double vnc_update_freq(VncState *vs, int x, int y, int w, int h) in vnc_update_freq() argument
3075 total += vnc_stat_rect(vs->vd, i, j)->freq; in vnc_update_freq()
3108 VncState *vs; in vnc_refresh_server_surface() local
3184 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_refresh_server_surface()
3185 set_bit(x, vs->dirty[y]); in vnc_refresh_server_surface()
3206 VncState *vs, *vn; in vnc_refresh() local
3224 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) { in vnc_refresh()
3225 rects += vnc_update_client(vs, has_dirty); in vnc_refresh()
3226 /* vs might be free()ed here */ in vnc_refresh()
3245 VncState *vs = g_new0(VncState, 1); in vnc_connect() local
3249 trace_vnc_client_connect(vs, sioc); in vnc_connect()
3250 vs->zrle = g_new0(VncZrle, 1); in vnc_connect()
3251 vs->tight = g_new0(VncTight, 1); in vnc_connect()
3252 vs->magic = VNC_MAGIC; in vnc_connect()
3253 vs->sioc = sioc; in vnc_connect()
3254 object_ref(OBJECT(vs->sioc)); in vnc_connect()
3255 vs->ioc = QIO_CHANNEL(sioc); in vnc_connect()
3256 object_ref(OBJECT(vs->ioc)); in vnc_connect()
3257 vs->vd = vd; in vnc_connect()
3259 buffer_init(&vs->input, "vnc-input/%p", sioc); in vnc_connect()
3260 buffer_init(&vs->output, "vnc-output/%p", sioc); in vnc_connect()
3261 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc); in vnc_connect()
3263 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc); in vnc_connect()
3264 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc); in vnc_connect()
3265 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc); in vnc_connect()
3267 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc); in vnc_connect()
3270 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc); in vnc_connect()
3272 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc); in vnc_connect()
3273 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc); in vnc_connect()
3274 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc); in vnc_connect()
3275 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc); in vnc_connect()
3278 vs->auth = VNC_AUTH_NONE; in vnc_connect()
3279 vs->subauth = VNC_AUTH_INVALID; in vnc_connect()
3282 vs->auth = vd->ws_auth; in vnc_connect()
3283 vs->subauth = VNC_AUTH_INVALID; in vnc_connect()
3285 vs->auth = vd->auth; in vnc_connect()
3286 vs->subauth = vd->subauth; in vnc_connect()
3290 sioc, websocket, vs->auth, vs->subauth); in vnc_connect()
3292 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect)); in vnc_connect()
3294 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS); in vnc_connect()
3297 VNC_DEBUG("New client on socket %p\n", vs->sioc); in vnc_connect()
3299 qio_channel_set_blocking(vs->ioc, false, NULL); in vnc_connect()
3300 if (vs->ioc_tag) { in vnc_connect()
3301 g_source_remove(vs->ioc_tag); in vnc_connect()
3304 vs->websocket = 1; in vnc_connect()
3306 vs->ioc_tag = qio_channel_add_watch( in vnc_connect()
3307 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, in vnc_connect()
3308 vncws_tls_handshake_io, vs, NULL); in vnc_connect()
3310 vs->ioc_tag = qio_channel_add_watch( in vnc_connect()
3311 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, in vnc_connect()
3312 vncws_handshake_io, vs, NULL); in vnc_connect()
3315 vs->ioc_tag = qio_channel_add_watch( in vnc_connect()
3316 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, in vnc_connect()
3317 vnc_client_io, vs, NULL); in vnc_connect()
3320 vnc_client_cache_addr(vs); in vnc_connect()
3321 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED); in vnc_connect()
3322 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING); in vnc_connect()
3324 vs->last_x = -1; in vnc_connect()
3325 vs->last_y = -1; in vnc_connect()
3327 vs->as.freq = 44100; in vnc_connect()
3328 vs->as.nchannels = 2; in vnc_connect()
3329 vs->as.fmt = AUDIO_FORMAT_S16; in vnc_connect()
3330 vs->as.endianness = 0; in vnc_connect()
3332 qemu_mutex_init(&vs->output_mutex); in vnc_connect()
3333 vs->bh = qemu_bh_new(vnc_jobs_bh, vs); in vnc_connect()
3335 QTAILQ_INSERT_TAIL(&vd->clients, vs, next); in vnc_connect()
3342 if (!vs->websocket) { in vnc_connect()
3343 vnc_start_protocol(vs); in vnc_connect()
3347 QTAILQ_FOREACH(vs, &vd->clients, next) { in vnc_connect()
3348 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) { in vnc_connect()
3349 vnc_disconnect_start(vs); in vnc_connect()
3356 void vnc_start_protocol(VncState *vs) in vnc_start_protocol() argument
3358 vnc_write(vs, "RFB 003.008\n", 12); in vnc_start_protocol()
3359 vnc_flush(vs); in vnc_start_protocol()
3360 vnc_read_when(vs, protocol_version, 12); in vnc_start_protocol()
3362 vs->mouse_mode_notifier.notify = check_pointer_type_change; in vnc_start_protocol()
3363 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier); in vnc_start_protocol()
3635 * 5. tls + anon + vnc in vnc_display_setup_auth()
3656 * VNC auth mechs for plain VNC vs websockets VNC, the end in vnc_display_setup_auth()
3732 if (strncmp(addrstr, "unix:", 5) == 0) { in vnc_display_get_address()
3734 addr->u.q_unix.path = g_strdup(addrstr + 5); in vnc_display_get_address()