Lines Matching refs:vs
215 static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
216 return (vs->features & (1 << feature));
227 static void vnc_disconnect_start(VncState *vs);
228 static void vnc_disconnect_finish(VncState *vs);
230 static void vnc_colordepth(VncState *vs);
273 static void vnc_update(VncState *vs, int x, int y, int w, int h)
275 struct VncSurface *s = &vs->guest;
300 VncState *vs = vd->clients;
301 while (vs != NULL) {
302 vnc_update(vs, x, y, w, h);
303 vs = vs->next;
307 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
310 vnc_write_u16(vs, x);
311 vnc_write_u16(vs, y);
312 vnc_write_u16(vs, w);
313 vnc_write_u16(vs, h);
315 vnc_write_s32(vs, encoding);
351 static void vnc_resize(VncState *vs)
353 DisplayState *ds = vs->ds;
357 if (!vs->guest.ds)
358 vs->guest.ds = g_malloc0(sizeof(*vs->guest.ds));
359 if (ds_get_bytes_per_pixel(ds) != vs->guest.ds->pf.bytes_per_pixel)
361 vnc_colordepth(vs);
362 size_changed = ds_get_width(ds) != vs->guest.ds->width ||
363 ds_get_height(ds) != vs->guest.ds->height;
364 *(vs->guest.ds) = *(ds->surface);
366 if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
367 vnc_write_u8(vs, 0); /* msg id */
368 vnc_write_u8(vs, 0);
369 vnc_write_u16(vs, 1); /* number of rects */
370 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
372 vnc_flush(vs);
375 memset(vs->guest.dirty, 0xFF, sizeof(vs->guest.dirty));
378 if (!vs->server.ds)
379 vs->server.ds = g_malloc0(sizeof(*vs->server.ds));
380 if (vs->server.ds->data)
381 g_free(vs->server.ds->data);
382 *(vs->server.ds) = *(ds->surface);
383 vs->server.ds->data = g_malloc0(vs->server.ds->linesize *
384 vs->server.ds->height);
385 memset(vs->server.dirty, 0xFF, sizeof(vs->guest.dirty));
391 VncState *vs = vd->clients;
392 while (vs != NULL) {
393 vnc_resize(vs);
394 vs = vs->next;
399 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
401 vnc_write(vs, pixels, size);
405 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
409 r = ((((v & vs->server.ds->pf.rmask) >> vs->server.ds->pf.rshift) << vs->clientds.pf.rbits) >>
410 vs->server.ds->pf.rbits);
411 g = ((((v & vs->server.ds->pf.gmask) >> vs->server.ds->pf.gshift) << vs->clientds.pf.gbits) >>
412 vs->server.ds->pf.gbits);
413 b = ((((v & vs->server.ds->pf.bmask) >> vs->server.ds->pf.bshift) << vs->clientds.pf.bbits) >>
414 vs->server.ds->pf.bbits);
415 v = (r << vs->clientds.pf.rshift) |
416 (g << vs->clientds.pf.gshift) |
417 (b << vs->clientds.pf.bshift);
418 switch(vs->clientds.pf.bytes_per_pixel) {
423 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
433 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
448 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
452 if (vs->server.ds->pf.bytes_per_pixel == 4) {
457 vnc_convert_pixel(vs, buf, pixels[i]);
458 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
460 } else if (vs->server.ds->pf.bytes_per_pixel == 2) {
465 vnc_convert_pixel(vs, buf, pixels[i]);
466 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
468 } else if (vs->server.ds->pf.bytes_per_pixel == 1) {
473 vnc_convert_pixel(vs, buf, pixels[i]);
474 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
481 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
486 row = vs->server.ds->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
488 vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
489 row += ds_get_linesize(vs->ds);
529 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
535 last_fg = (uint8_t *) g_malloc(vs->server.ds->pf.bytes_per_pixel);
536 last_bg = (uint8_t *) g_malloc(vs->server.ds->pf.bytes_per_pixel);
540 vs->send_hextile_tile(vs, i, j,
550 static void vnc_zlib_init(VncState *vs)
553 for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
554 vs->zlib_stream[i].opaque = NULL;
557 static void vnc_zlib_start(VncState *vs)
559 buffer_reset(&vs->zlib);
562 vs->zlib_tmp = vs->output;
563 vs->output = vs->zlib;
566 static int vnc_zlib_stop(VncState *vs, int stream_id)
568 z_streamp zstream = &vs->zlib_stream[stream_id];
572 vs->zlib = vs->output;
573 vs->output = vs->zlib_tmp;
579 if (zstream->opaque != vs) {
583 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
587 err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
595 zstream->opaque = vs;
601 buffer_reserve(&vs->output, vs->zlib.offset + 64);
604 zstream->next_in = vs->zlib.buffer;
605 zstream->avail_in = vs->zlib.offset;
606 zstream->next_out = vs->output.buffer + vs->output.offset;
607 zstream->avail_out = vs->output.capacity - vs->output.offset;
617 vs->output.offset = vs->output.capacity - zstream->avail_out;
621 static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
625 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
628 old_offset = vs->output.offset;
629 vnc_write_s32(vs, 0);
632 vnc_zlib_start(vs);
633 send_framebuffer_update_raw(vs, x, y, w, h);
634 bytes_written = vnc_zlib_stop(vs, 0);
640 new_offset = vs->output.offset;
641 vs->output.offset = old_offset;
642 vnc_write_u32(vs, bytes_written);
643 vs->output.offset = new_offset;
646 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
648 switch(vs->vnc_encoding) {
650 send_framebuffer_update_zlib(vs, x, y, w, h);
653 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
654 send_framebuffer_update_hextile(vs, x, y, w, h);
657 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
658 send_framebuffer_update_raw(vs, x, y, w, h);
663 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
665 vnc_write_u8(vs, 0); /* msg id */
666 vnc_write_u8(vs, 0);
667 vnc_write_u16(vs, 1); /* number of rects */
668 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
669 vnc_write_u16(vs, src_x);
670 vnc_write_u16(vs, src_y);
671 vnc_flush(vs);
677 VncState *vs, *vn;
679 for (vs = vd->clients; vs != NULL; vs = vn) {
680 vn = vs->next;
681 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
682 vs->force_update = 1;
683 vnc_update_client(vs);
684 /* vs might be free()ed here */
688 for (vs = vd->clients; vs != NULL; vs = vs->next) {
689 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
690 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
692 vnc_update(vs, dst_x, dst_y, w, h);
714 VncState *vs = opaque;
715 if (vs->need_update && vs->csock != -1) {
725 if (vs->output.offset && !vs->audio_cap && !vs->force_update) {
727 timer_mod(vs->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + VNC_REFRESH_INTERVAL);
738 vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
739 cmp_bytes = 16 * ds_get_bytes_per_pixel(vs->ds);
740 guest_row = vs->guest.ds->data;
741 server_row = vs->server.ds->data;
742 for (y = 0; y < vs->guest.ds->height; y++) {
743 if (vnc_and_bits(vs->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
751 for (x = 0; x < vs->guest.ds->width;
753 if (!vnc_get_bit(vs->guest.dirty[y], (x / 16)))
755 vnc_clear_bit(vs->guest.dirty[y], (x / 16));
759 vnc_set_bit(vs->server.dirty[y], (x / 16));
763 guest_row += ds_get_linesize(vs->ds);
764 server_row += ds_get_linesize(vs->ds);
767 if (!has_dirty && !vs->audio_cap && !vs->force_update) {
768 timer_mod(vs->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + VNC_REFRESH_INTERVAL);
779 vnc_write_u8(vs, 0); /* msg id */
780 vnc_write_u8(vs, 0);
781 saved_offset = vs->output.offset;
782 vnc_write_u16(vs, 0);
784 for (y = 0; y < vs->server.ds->height; y++) {
787 for (x = 0; x < vs->server.ds->width / 16; x++) {
788 if (vnc_get_bit(vs->server.dirty[y], x)) {
792 vnc_clear_bit(vs->server.dirty[y], x);
795 int h = find_and_clear_dirty_height(&vs->server, y, last_x, x);
796 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
803 int h = find_and_clear_dirty_height(&vs->server, y, last_x, x);
804 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
808 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
809 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
810 vnc_flush(vs);
811 vs->force_update = 0;
815 if (vs->csock != -1) {
816 timer_mod(vs->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + VNC_REFRESH_INTERVAL);
818 vnc_disconnect_finish(vs);
826 VncState *vs = opaque;
830 vnc_write_u8(vs, 255);
831 vnc_write_u8(vs, 1);
832 vnc_write_u16(vs, 0);
833 vnc_flush(vs);
837 vnc_write_u8(vs, 255);
838 vnc_write_u8(vs, 1);
839 vnc_write_u16(vs, 1);
840 vnc_flush(vs);
851 VncState *vs = opaque;
853 vnc_write_u8(vs, 255);
854 vnc_write_u8(vs, 1);
855 vnc_write_u16(vs, 2);
856 vnc_write_u32(vs, size);
857 vnc_write(vs, buf, size);
858 vnc_flush(vs);
861 static void audio_add(VncState *vs)
866 if (vs->audio_cap) {
875 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
876 if (!vs->audio_cap) {
881 static void audio_del(VncState *vs)
883 if (vs->audio_cap) {
884 AUD_del_capture(vs->audio_cap, vs);
885 vs->audio_cap = NULL;
889 static void vnc_disconnect_start(VncState *vs)
891 if (vs->csock == -1)
893 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
894 closesocket(vs->csock);
895 vs->csock = -1;
898 static void vnc_disconnect_finish(VncState *vs)
900 timer_del(vs->timer);
901 timer_free(vs->timer);
902 if (vs->input.buffer) g_free(vs->input.buffer);
903 if (vs->output.buffer) g_free(vs->output.buffer);
905 vnc_tls_client_cleanup(vs);
908 vnc_sasl_client_cleanup(vs);
910 audio_del(vs);
913 for (p = vs->vd->clients; p != NULL; p = p->next) {
914 if (p == vs) {
918 vs->vd->clients = p->next;
923 if (!vs->vd->clients)
926 g_free(vs->server.ds->data);
927 g_free(vs->server.ds);
928 g_free(vs->guest.ds);
929 g_free(vs);
932 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
950 vnc_disconnect_start(vs);
958 void vnc_client_error(VncState *vs)
961 vnc_disconnect_start(vs);
980 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
984 if (vs->tls.session) {
985 ret = gnutls_write(vs->tls.session, data, datalen);
995 ret = socket_send(vs->csock, data, datalen);
997 return vnc_client_io_error(vs, ret, socket_error());
1011 static long vnc_client_write_plain(VncState *vs)
1017 vs->output.buffer, vs->output.capacity, vs->output.offset,
1018 vs->sasl.waitWriteSSF);
1020 if (vs->sasl.conn &&
1021 vs->sasl.runSSF &&
1022 vs->sasl.waitWriteSSF) {
1023 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1025 vs->sasl.waitWriteSSF -= ret;
1028 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1032 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
1033 vs->output.offset -= ret;
1035 if (vs->output.offset == 0) {
1036 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1050 VncState *vs = opaque;
1053 if (vs->sasl.conn &&
1054 vs->sasl.runSSF &&
1055 !vs->sasl.waitWriteSSF) {
1056 vnc_client_write_sasl(vs);
1059 vnc_client_write_plain(vs);
1062 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1064 vs->read_handler = func;
1065 vs->read_handler_expect = expecting;
1084 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1088 if (vs->tls.session) {
1089 ret = gnutls_read(vs->tls.session, data, datalen);
1099 ret = socket_recv(vs->csock, data, datalen);
1101 return vnc_client_io_error(vs, ret, socket_error());
1113 static long vnc_client_read_plain(VncState *vs)
1117 vs->input.buffer, vs->input.capacity, vs->input.offset);
1118 buffer_reserve(&vs->input, 4096);
1119 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1122 vs->input.offset += ret;
1134 VncState *vs = opaque;
1138 if (vs->sasl.conn && vs->sasl.runSSF)
1139 ret = vnc_client_read_sasl(vs);
1142 ret = vnc_client_read_plain(vs);
1144 if (vs->csock == -1)
1145 vnc_disconnect_finish(vs);
1149 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1150 vs->read_handler_expect;
1153 ret = vs->read_handler(vs, vs->input.buffer, len);
1154 if (vs->csock == -1) {
1155 vnc_disconnect_finish(vs);
1160 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1161 vs->input.offset -= len;
1163 vs->read_handler_expect = ret;
1168 void vnc_write(VncState *vs, const void *data, size_t len)
1170 buffer_reserve(&vs->output, len);
1172 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1173 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1176 buffer_append(&vs->output, data, len);
1179 void vnc_write_s32(VncState *vs, int32_t value)
1181 vnc_write_u32(vs, *(uint32_t *)&value);
1184 void vnc_write_u32(VncState *vs, uint32_t value)
1193 vnc_write(vs, buf, 4);
1196 void vnc_write_u16(VncState *vs, uint16_t value)
1203 vnc_write(vs, buf, 2);
1206 void vnc_write_u8(VncState *vs, uint8_t value)
1208 vnc_write(vs, (char *)&value, 1);
1211 void vnc_flush(VncState *vs)
1213 if (vs->csock != -1 && vs->output.offset)
1214 vnc_client_write(vs);
1239 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1243 static void check_pointer_type_change(VncState *vs, int absolute)
1245 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1246 vnc_write_u8(vs, 0);
1247 vnc_write_u8(vs, 0);
1248 vnc_write_u16(vs, 1);
1249 vnc_framebuffer_update(vs, absolute, 0,
1250 ds_get_width(vs->ds), ds_get_height(vs->ds),
1252 vnc_flush(vs);
1254 vs->absolute = absolute;
1257 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1273 if (vs->absolute) {
1274 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
1275 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1277 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1283 if (vs->last_x != -1)
1284 kbd_mouse_event(x - vs->last_x,
1285 y - vs->last_y,
1287 vs->last_x = x;
1288 vs->last_y = y;
1291 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1294 static void reset_keys(VncState *vs)
1298 if (vs->modifiers_state[i]) {
1302 vs->modifiers_state[i] = 0;
1307 static void press_key(VncState *vs, int keysym)
1309 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
1310 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1313 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1324 vs->modifiers_state[keycode] = 1;
1326 vs->modifiers_state[keycode] = 0;
1329 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1331 reset_keys(vs);
1339 vs->modifiers_state[keycode] ^= 1;
1343 if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1348 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1349 if (!vs->modifiers_state[0x45]) {
1350 vs->modifiers_state[0x45] = 1;
1351 press_key(vs, 0xff7f);
1354 if (vs->modifiers_state[0x45]) {
1355 vs->modifiers_state[0x45] = 0;
1356 press_key(vs, 0xff7f);
1371 int numlock = vs->modifiers_state[0x45];
1466 static void key_event(VncState *vs, int down, uint32_t sym)
1473 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
1474 do_key_event(vs, down, keycode, sym);
1477 static void ext_key_event(VncState *vs, int down,
1482 key_event(vs, down, sym);
1484 do_key_event(vs, down, keycode, sym);
1487 static void framebuffer_update_request(VncState *vs, int incremental,
1491 if (x_position > ds_get_width(vs->ds))
1492 x_position = ds_get_width(vs->ds);
1493 if (y_position > ds_get_height(vs->ds))
1494 y_position = ds_get_height(vs->ds);
1495 if (x_position + w >= ds_get_width(vs->ds))
1496 w = ds_get_width(vs->ds) - x_position;
1497 if (y_position + h >= ds_get_height(vs->ds))
1498 h = ds_get_height(vs->ds) - y_position;
1501 vs->need_update = 1;
1503 vs->force_update = 1;
1505 vnc_set_bits(vs->guest.dirty[y_position + i],
1506 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1507 vnc_set_bits(vs->server.dirty[y_position + i],
1508 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1513 static void send_ext_key_event_ack(VncState *vs)
1515 vnc_write_u8(vs, 0);
1516 vnc_write_u8(vs, 0);
1517 vnc_write_u16(vs, 1);
1518 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1520 vnc_flush(vs);
1523 static void send_ext_audio_ack(VncState *vs)
1525 vnc_write_u8(vs, 0);
1526 vnc_write_u8(vs, 0);
1527 vnc_write_u16(vs, 1);
1528 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1530 vnc_flush(vs);
1533 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1538 vnc_zlib_init(vs);
1539 vs->features = 0;
1540 vs->vnc_encoding = 0;
1541 vs->tight_compression = 9;
1542 vs->tight_quality = 9;
1543 vs->absolute = -1;
1549 vs->vnc_encoding = enc;
1552 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1555 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1556 vs->vnc_encoding = enc;
1559 vs->features |= VNC_FEATURE_ZLIB_MASK;
1560 vs->vnc_encoding = enc;
1563 vs->features |= VNC_FEATURE_RESIZE_MASK;
1566 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1569 send_ext_key_event_ack(vs);
1572 send_ext_audio_ack(vs);
1575 vs->features |= VNC_FEATURE_WMVI_MASK;
1578 vs->tight_compression = (enc & 0x0F);
1581 vs->tight_quality = (enc & 0x0F);
1589 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1592 static void set_pixel_conversion(VncState *vs)
1594 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1595 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1596 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1597 vs->write_pixels = vnc_write_pixels_copy;
1598 switch (vs->ds->surface->pf.bits_per_pixel) {
1600 vs->send_hextile_tile = send_hextile_tile_8;
1603 vs->send_hextile_tile = send_hextile_tile_16;
1606 vs->send_hextile_tile = send_hextile_tile_32;
1610 vs->write_pixels = vnc_write_pixels_generic;
1611 switch (vs->ds->surface->pf.bits_per_pixel) {
1613 vs->send_hextile_tile = send_hextile_tile_generic_8;
1616 vs->send_hextile_tile = send_hextile_tile_generic_16;
1619 vs->send_hextile_tile = send_hextile_tile_generic_32;
1625 static void set_pixel_format(VncState *vs,
1632 vnc_client_error(vs);
1636 vs->clientds = *(vs->guest.ds);
1637 vs->clientds.pf.rmax = red_max;
1638 count_bits(vs->clientds.pf.rbits, red_max);
1639 vs->clientds.pf.rshift = red_shift;
1640 vs->clientds.pf.rmask = red_max << red_shift;
1641 vs->clientds.pf.gmax = green_max;
1642 count_bits(vs->clientds.pf.gbits, green_max);
1643 vs->clientds.pf.gshift = green_shift;
1644 vs->clientds.pf.gmask = green_max << green_shift;
1645 vs->clientds.pf.bmax = blue_max;
1646 count_bits(vs->clientds.pf.bbits, blue_max);
1647 vs->clientds.pf.bshift = blue_shift;
1648 vs->clientds.pf.bmask = blue_max << blue_shift;
1649 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1650 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1651 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1652 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1654 set_pixel_conversion(vs);
1660 static void pixel_format_message (VncState *vs) {
1663 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1664 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
1667 vnc_write_u8(vs, 1); /* big-endian-flag */
1669 vnc_write_u8(vs, 0); /* big-endian-flag */
1671 vnc_write_u8(vs, 1); /* true-color-flag */
1672 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1673 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1674 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1675 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1676 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1677 vs, vs->ds->surface->pf.bshift); /* blue-shift */
1678 if (vs->ds->surface->pf.bits_per_pixel == 32)
1679 vs->send_hextile_tile = send_hextile_tile_32;
1680 else if (vs->ds->surface->pf.bits_per_pixel == 16)
1681 vs->send_hextile_tile = send_hextile_tile_16;
1682 else if (vs->ds->surface->pf.bits_per_pixel == 8)
1683 vs->send_hextile_tile = send_hextile_tile_8;
1684 vs->clientds = *(vs->ds->surface);
1685 vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
1686 vs->write_pixels = vnc_write_pixels_copy;
1688 vnc_write(vs, pad, 3); /* padding */
1696 static void vnc_colordepth(VncState *vs)
1698 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
1700 vnc_write_u8(vs, 0); /* msg id */
1701 vnc_write_u8(vs, 0);
1702 vnc_write_u16(vs, 1); /* number of rects */
1703 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1704 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
1705 pixel_format_message(vs);
1706 vnc_flush(vs);
1708 set_pixel_conversion(vs);
1712 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1722 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1744 set_encodings(vs, (int32_t *)(data + 4), limit);
1750 framebuffer_update_request(vs,
1758 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1764 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1776 client_cut_text(vs, read_u32(data, 4), data + 8);
1787 ext_key_event(vs, read_u16(data, 2),
1796 audio_add(vs);
1799 audio_del(vs);
1805 case 0: vs->as.fmt = AUD_FMT_U8; break;
1806 case 1: vs->as.fmt = AUD_FMT_S8; break;
1807 case 2: vs->as.fmt = AUD_FMT_U16; break;
1808 case 3: vs->as.fmt = AUD_FMT_S16; break;
1809 case 4: vs->as.fmt = AUD_FMT_U32; break;
1810 case 5: vs->as.fmt = AUD_FMT_S32; break;
1813 vnc_client_error(vs);
1816 vs->as.nchannels = read_u8(data, 5);
1817 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1820 vnc_client_error(vs);
1823 vs->as.freq = read_u32(data, 6);
1827 vnc_client_error(vs);
1834 vnc_client_error(vs);
1840 vnc_client_error(vs);
1844 vnc_read_when(vs, protocol_client_msg, 1);
1848 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1853 vnc_write_u16(vs, ds_get_width(vs->ds));
1854 vnc_write_u16(vs, ds_get_height(vs->ds));
1856 pixel_format_message(vs);
1863 vnc_write_u32(vs, size);
1864 vnc_write(vs, buf, size);
1865 vnc_flush(vs);
1867 vnc_read_when(vs, protocol_client_msg, 1);
1872 void start_client_init(VncState *vs)
1874 vnc_read_when(vs, protocol_client_init, 1);
1877 static void make_challenge(VncState *vs)
1883 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1884 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1887 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1893 if (!vs->vd->password || !vs->vd->password[0]) {
1895 vnc_write_u32(vs, 1); /* Reject auth */
1896 if (vs->minor >= 8) {
1898 vnc_write_u32(vs, sizeof(err));
1899 vnc_write(vs, err, sizeof(err));
1901 vnc_flush(vs);
1902 vnc_client_error(vs);
1906 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1909 pwlen = strlen(vs->vd->password);
1911 key[i] = i<pwlen ? vs->vd->password[i] : 0;
1916 /* Compare expected vs actual challenge response */
1919 vnc_write_u32(vs, 1); /* Reject auth */
1920 if (vs->minor >= 8) {
1922 vnc_write_u32(vs, sizeof(err));
1923 vnc_write(vs, err, sizeof(err));
1925 vnc_flush(vs);
1926 vnc_client_error(vs);
1929 vnc_write_u32(vs, 0); /* Accept auth */
1930 vnc_flush(vs);
1932 start_client_init(vs);
1937 void start_auth_vnc(VncState *vs)
1939 make_challenge(vs);
1941 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1942 vnc_flush(vs);
1944 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1948 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1952 if (data[0] != vs->vd->auth) { /* Reject auth */
1954 vnc_write_u32(vs, 1);
1955 if (vs->minor >= 8) {
1957 vnc_write_u32(vs, sizeof(err));
1958 vnc_write(vs, err, sizeof(err));
1960 vnc_client_error(vs);
1963 switch (vs->vd->auth) {
1966 if (vs->minor >= 8) {
1967 vnc_write_u32(vs, 0); /* Accept auth completion */
1968 vnc_flush(vs);
1970 start_client_init(vs);
1975 start_auth_vnc(vs);
1981 start_auth_vencrypt(vs);
1988 start_auth_sasl(vs);
1993 VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
1994 vnc_write_u8(vs, 1);
1995 if (vs->minor >= 8) {
1997 vnc_write_u32(vs, sizeof(err));
1998 vnc_write(vs, err, sizeof(err));
2000 vnc_client_error(vs);
2006 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2013 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2015 vnc_client_error(vs);
2018 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2019 if (vs->major != 3 ||
2020 (vs->minor != 3 &&
2021 vs->minor != 4 &&
2022 vs->minor != 5 &&
2023 vs->minor != 7 &&
2024 vs->minor != 8)) {
2026 vnc_write_u32(vs, VNC_AUTH_INVALID);
2027 vnc_flush(vs);
2028 vnc_client_error(vs);
2034 if (vs->minor == 4 || vs->minor == 5)
2035 vs->minor = 3;
2037 if (vs->minor == 3) {
2038 if (vs->vd->auth == VNC_AUTH_NONE) {
2040 vnc_write_u32(vs, vs->vd->auth);
2041 vnc_flush(vs);
2042 start_client_init(vs);
2043 } else if (vs->vd->auth == VNC_AUTH_VNC) {
2045 vnc_write_u32(vs, vs->vd->auth);
2046 vnc_flush(vs);
2047 start_auth_vnc(vs);
2049 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
2050 vnc_write_u32(vs, VNC_AUTH_INVALID);
2051 vnc_flush(vs);
2052 vnc_client_error(vs);
2055 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
2056 vnc_write_u8(vs, 1); /* num auth */
2057 vnc_write_u8(vs, vs->vd->auth);
2058 vnc_read_when(vs, protocol_client_auth, 1);
2059 vnc_flush(vs);
2067 VncState *vs = g_malloc0(sizeof(VncState));
2068 vs->csock = csock;
2072 socket_set_nonblock(vs->csock);
2073 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2075 vs->vd = vd;
2076 vs->ds = vd->ds;
2077 vs->timer = timer_new(QEMU_CLOCK_REALTIME, SCALE_MS, vnc_update_client, vs);
2078 vs->last_x = -1;
2079 vs->last_y = -1;
2081 vs->as.freq = 44100;
2082 vs->as.nchannels = 2;
2083 vs->as.fmt = AUD_FMT_S16;
2084 vs->as.endianness = 0;
2086 vnc_resize(vs);
2087 vnc_write(vs, "RFB 003.008\n", 12);
2088 vnc_flush(vs);
2089 vnc_read_when(vs, protocol_version, 12);
2090 reset_keys(vs);
2092 vs->next = vd->clients;
2093 vd->clients = vs;
2095 vnc_update_client(vs);
2096 /* vs might be free()ed here */
2101 VncDisplay *vs = opaque;
2106 int csock = socket_accept(vs->lsock, NULL);
2108 vnc_connect(vs, csock);
2114 VncDisplay *vs = g_malloc0(sizeof(*vs));
2118 ds->opaque = vs;
2120 vnc_display = vs;
2122 vs->lsock = -1;
2124 vs->ds = ds;
2127 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
2129 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
2131 if (!vs->kbd_layout)
2144 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2146 if (!vs)
2148 if (vs->display) {
2149 g_free(vs->display);
2150 vs->display = NULL;
2152 if (vs->lsock != -1) {
2153 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2154 close(vs->lsock);
2155 vs->lsock = -1;
2157 vs->auth = VNC_AUTH_INVALID;
2159 vs->subauth = VNC_AUTH_INVALID;
2160 vs->tls.x509verify = 0;
2166 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2168 if (vs->password) {
2169 g_free(vs->password);
2170 vs->password = NULL;
2173 if (!(vs->password = g_strdup(password)))
2182 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2184 return vnc_socket_local_addr("%s:%s", vs->lsock);
2189 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2208 if (!(vs->display = strdup(display)))
2231 vs->tls.x509verify = 1; /* ...and verify client certs */
2242 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2245 g_free(vs->display);
2246 vs->display = NULL;
2252 g_free(vs->display);
2253 vs->display = NULL;
2265 if (acl && x509 && vs->tls.x509verify) {
2266 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
2274 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
2300 vs->auth = VNC_AUTH_VENCRYPT;
2303 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2306 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2311 vs->auth = VNC_AUTH_VNC;
2313 vs->subauth = VNC_AUTH_INVALID;
2320 vs->auth = VNC_AUTH_VENCRYPT;
2323 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2326 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2331 vs->auth = VNC_AUTH_SASL;
2333 vs->subauth = VNC_AUTH_INVALID;
2340 vs->auth = VNC_AUTH_VENCRYPT;
2343 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2346 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2351 vs->auth = VNC_AUTH_NONE;
2353 vs->subauth = VNC_AUTH_INVALID;
2362 free(vs->display);
2363 vs->display = NULL;
2371 vs->lsock = unix_connect(display+5);
2373 vs->lsock = inet_connect(display, SOCKET_STREAM);
2374 if (-1 == vs->lsock) {
2375 free(vs->display);
2376 vs->display = NULL;
2379 int csock = vs->lsock;
2380 vs->lsock = -1;
2381 vnc_connect(vs, csock);
2391 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
2393 vs->lsock = inet_listen(display, dpy, 256, SOCKET_STREAM, 5900);
2395 if (-1 == vs->lsock) {
2399 free(vs->display);
2400 vs->display = dpy;
2403 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);