Lines Matching +full:x +full:- +full:rc
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
91 /* Client-to-server msg types */
186 #define RFB_ENCODING_RESIZE -223
187 #define RFB_ENCODING_EXT_KEYEVENT -258
211 uint16_t x;
240 uint16_t x;
251 uint16_t x;
272 sinfo.width = htons(gc_image->width);
273 sinfo.height = htons(gc_image->height);
293 rfb_send_resize_update_msg(struct rfb_softc *rc, int cfd)
305 srect_hdr.x = htons(0);
307 srect_hdr.width = htons(rc->width);
308 srect_hdr.height = htons(rc->height);
314 rfb_send_extended_keyevent_update_msg(struct rfb_softc *rc, int cfd)
326 srect_hdr.x = htons(0);
328 srect_hdr.width = htons(rc->width);
329 srect_hdr.height = htons(rc->height);
335 rfb_recv_set_pixfmt_msg(struct rfb_softc *rc __unused, int cfd)
343 sizeof(pixfmt_msg) - 1);
390 pthread_mutex_lock(&rc->pixfmt_mtx);
391 rc->new_pixfmt.red_shift = red_shift;
392 rc->new_pixfmt.green_shift = green_shift;
393 rc->new_pixfmt.blue_shift = blue_shift;
394 rc->new_pixfmt.adjust_pixels = adjust_pixels;
395 pthread_mutex_unlock(&rc->pixfmt_mtx);
398 rc->update_pixfmt = true;
402 rfb_recv_set_encodings_msg(struct rfb_softc *rc, int cfd)
408 (void)stream_read(cfd, (uint8_t *)&enc_msg + 1, sizeof(enc_msg) - 1);
414 rc->enc_raw_ok = true;
417 if (!rc->enc_zlib_ok) {
418 deflateInit(&rc->zstream, Z_BEST_SPEED);
419 rc->enc_zlib_ok = true;
423 rc->enc_resize_ok = true;
426 rc->enc_extkeyevent_ok = true;
441 while (q--) {
454 rfb_send_update_header(struct rfb_softc *rc __unused, int cfd, int numrects)
467 rfb_adjust_pixels(struct rfb_softc *rc, uint32_t *gcptr, int width)
474 if (!rc->pixfmt.adjust_pixels) {
478 for (i = 0, pixelp = rc->pixrow; i < width; i++, pixelp++, gcptr++) {
482 *pixelp = (red << rc->pixfmt.red_shift) |
483 (green << rc->pixfmt.green_shift) |
484 (blue << rc->pixfmt.blue_shift);
487 return (rc->pixrow);
491 rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
492 int x, int y, int w, int h)
502 * Send a single rectangle of the given x, y, w h dimensions.
506 srect_hdr.x = htons(x);
514 if (rc->enc_zlib_ok) {
515 zbufp = rc->zbuf;
516 rc->zstream.total_in = 0;
517 rc->zstream.total_out = 0;
518 for (p = &gc->data[y * gc->width + x]; y < h; y++) {
519 pixelp = rfb_adjust_pixels(rc, p, width);
520 rc->zstream.next_in = (Bytef *)pixelp;
521 rc->zstream.avail_in = w;
522 rc->zstream.next_out = (Bytef *)zbufp;
523 rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16 -
524 rc->zstream.total_out;
525 rc->zstream.data_type = Z_BINARY;
528 err = deflate(&rc->zstream, Z_SYNC_FLUSH);
531 rc->enc_zlib_ok = false;
532 deflateEnd(&rc->zstream);
535 zbufp = rc->zbuf + rc->zstream.total_out;
536 p += gc->width;
544 zlen = htonl(rc->zstream.total_out);
548 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out));
554 zbufp = rc->zbuf;
555 for (p = &gc->data[y * gc->width + x]; y < h; y++) {
556 pixelp = rfb_adjust_pixels(rc, p, width);
560 p += gc->width;
569 total = stream_write(cfd, rc->zbuf, total);
575 rfb_send_all(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc)
596 if (rc->pixfmt.adjust_pixels) {
597 return (rfb_send_rect(rc, cfd, gc, 0, 0,
598 gc->width, gc->height));
602 srect_hdr.x = 0;
604 srect_hdr.width = htons(gc->width);
605 srect_hdr.height = htons(gc->height);
606 if (rc->enc_zlib_ok) {
607 rc->zstream.next_in = (Bytef *)gc->data;
608 rc->zstream.avail_in = gc->width * gc->height *
610 rc->zstream.next_out = (Bytef *)rc->zbuf;
611 rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16;
612 rc->zstream.data_type = Z_BINARY;
614 rc->zstream.total_in = 0;
615 rc->zstream.total_out = 0;
618 err = deflate(&rc->zstream, Z_SYNC_FLUSH);
621 rc->enc_zlib_ok = false;
622 deflateEnd(&rc->zstream);
632 zlen = htonl(rc->zstream.total_out);
636 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out));
646 nwrite = stream_write(cfd, gc->data,
647 gc->width * gc->height * sizeof(uint32_t));
657 rfb_set_pixel_adjustment(struct rfb_softc *rc)
659 pthread_mutex_lock(&rc->pixfmt_mtx);
660 rc->pixfmt = rc->new_pixfmt;
661 pthread_mutex_unlock(&rc->pixfmt_mtx);
665 rfb_send_screen(struct rfb_softc *rc, int cfd)
669 int x, y;
682 if (atomic_compare_exchange_strong(&rc->sending, &expected, true) == false)
688 if (atomic_exchange(&rc->pending, false) == false)
691 if (atomic_exchange(&rc->update_pixfmt, false) == true) {
692 rfb_set_pixel_adjustment(rc);
699 if (rc->crc_width != gc_image->width ||
700 rc->crc_height != gc_image->height) {
701 memset(rc->crc, 0, sizeof(uint32_t) *
704 rc->crc_width = gc_image->width;
705 rc->crc_height = gc_image->height;
709 if (rc->width != gc_image->width ||
710 rc->height != gc_image->height) {
711 rc->width = gc_image->width;
712 rc->height = gc_image->height;
713 if (rc->enc_resize_ok) {
714 rfb_send_resize_update_msg(rc, cfd);
715 rc->update_all = true;
720 if (atomic_exchange(&rc->update_all, false) == true) {
721 retval = rfb_send_all(rc, cfd, gc_image);
730 w = rc->crc_width;
731 h = rc->crc_height;
732 xcells = howmany(rc->crc_width, PIX_PER_CELL);
733 ycells = howmany(rc->crc_height, PIX_PER_CELL);
741 p = gc_image->data;
749 crc_p = rc->crc_tmp - xcells;
750 orig_crc = rc->crc - xcells;
752 memset(rc->crc_tmp, 0, sizeof(uint32_t) * xcells * ycells);
759 for (x = 0; x < xcells; x++) {
760 if (x == (xcells - 1) && rem_x > 0)
765 if (rc->hw_crc)
766 crc_p[x] = fast_crc32(p,
768 crc_p[x]);
770 crc_p[x] = (uint32_t)crc32(crc_p[x],
777 if ((y & PIXCELL_MASK) == PIXCELL_MASK || y == (h-1)) {
778 if (orig_crc[x] != crc_p[x]) {
779 orig_crc[x] = crc_p[x];
780 crc_p[x] = 1;
783 crc_p[x] = 0;
795 rc->pending = true;
801 retval = rfb_send_all(rc, cfd, gc_image);
805 rfb_send_update_header(rc, cfd, changes);
808 crc_p = rc->crc_tmp;
814 for (x = 0; x < xcells; x++) {
818 if (x == (xcells - 1) && rem_x > 0)
822 nwrite = rfb_send_rect(rc, cfd,
824 x * PIX_PER_CELL,
836 rc->sending = false;
843 rfb_recv_update_msg(struct rfb_softc *rc, int cfd)
847 (void)stream_read(cfd, (uint8_t *)&updt_msg + 1 , sizeof(updt_msg) - 1);
849 if (rc->enc_extkeyevent_ok && (!rc->enc_extkeyevent_send)) {
850 rfb_send_extended_keyevent_update_msg(rc, cfd);
851 rc->enc_extkeyevent_send = true;
854 rc->pending = true;
856 rc->update_all = true;
860 rfb_recv_key_msg(struct rfb_softc *rc, int cfd)
864 (void)stream_read(cfd, (uint8_t *)&key_msg + 1, sizeof(key_msg) - 1);
867 rc->input_detected = true;
871 rfb_recv_client_msg(struct rfb_softc *rc, int cfd)
877 sizeof(client_msg) - 1);
881 sizeof(extkey_msg) - 2);
883 rc->input_detected = true;
888 rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd)
892 (void)stream_read(cfd, (uint8_t *)&ptr_msg + 1, sizeof(ptr_msg) - 1);
894 console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y));
895 rc->input_detected = true;
899 rfb_recv_cuttext_msg(struct rfb_softc *rc __unused, int cfd)
905 len = stream_read(cfd, (uint8_t *)&ct_msg + 1, sizeof(ct_msg) - 1);
910 ct_msg.length -= len;
918 n1 = now->tv_sec * 1000000 + now->tv_usec;
919 n2 = prev->tv_sec * 1000000 + prev->tv_usec;
920 return (n1 - n2);
926 struct rfb_softc *rc;
934 rc = arg;
935 cfd = rc->cfd;
939 while (rc->cfd >= 0) {
956 input = atomic_exchange(&rc->input_detected, false);
961 if ((++rc->wrcount & 1) || input) {
962 if (rfb_send_screen(rc, cfd) <= 0) {
968 usleep(SCREEN_POLL_DELAY - tdiff);
976 rfb_handle(struct rfb_softc *rc, int cfd)
997 rc->cfd = cfd;
1005 strncmp(vbuf, buf, VERSION_LENGTH - 2) != 0) {
1009 client_ver = buf[VERSION_LENGTH - 2];
1018 /* In versions 3.7 & 3.8, it's 2-way handshake */
1021 if (rc->password) {
1063 * The client then sends the resulting 16-bytes response.
1066 strncpy(keystr, rc->password, PASSWD_LENGTH);
1081 /* Initialize a 16-byte random challenge */
1085 /* Receive the 16-byte challenge response */
1143 /* 3a. Read client shared-flag byte */
1146 /* 4a. Write server-init info */
1149 if (!rc->zbuf) {
1150 rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16);
1151 assert(rc->zbuf != NULL);
1154 perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
1168 rfb_recv_set_pixfmt_msg(rc, cfd);
1171 rfb_recv_set_encodings_msg(rc, cfd);
1174 rfb_recv_update_msg(rc, cfd);
1177 rfb_recv_key_msg(rc, cfd);
1180 rfb_recv_ptr_msg(rc, cfd);
1183 rfb_recv_cuttext_msg(rc, cfd);
1186 rfb_recv_client_msg(rc, cfd);
1189 WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff));
1194 rc->cfd = -1;
1197 if (rc->enc_zlib_ok)
1198 deflateEnd(&rc->zstream);
1204 struct rfb_softc *rc;
1209 rc = arg;
1219 rc->enc_raw_ok = false;
1220 rc->enc_zlib_ok = false;
1221 rc->enc_resize_ok = false;
1222 rc->enc_extkeyevent_ok = false;
1224 rc->enc_extkeyevent_send = false;
1226 cfd = accept(rc->sfd, NULL, NULL);
1227 if (rc->conn_wait) {
1228 pthread_mutex_lock(&rc->mtx);
1229 pthread_cond_signal(&rc->cond);
1230 pthread_mutex_unlock(&rc->mtx);
1231 rc->conn_wait = 0;
1233 rfb_handle(rc, cfd);
1258 struct rfb_softc *rc;
1267 rc = calloc(1, sizeof(struct rfb_softc));
1271 rc->crc = calloc(cnt, sizeof(uint32_t));
1272 rc->crc_tmp = calloc(cnt, sizeof(uint32_t));
1273 rc->crc_width = RFB_MAX_WIDTH;
1274 rc->crc_height = RFB_MAX_HEIGHT;
1275 rc->sfd = -1;
1277 rc->password = password;
1279 rc->pixrow = malloc(RFB_MAX_WIDTH * sizeof(uint32_t));
1280 if (rc->pixrow == NULL) {
1304 rc->sfd = socket(ai->ai_family, ai->ai_socktype, 0);
1305 if (rc->sfd < 0) {
1310 setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1312 if (bind(rc->sfd, ai->ai_addr, ai->ai_addrlen) < 0) {
1317 if (listen(rc->sfd, 1) < 0) {
1324 if (caph_rights_limit(rc->sfd, &rights) == -1)
1328 rc->hw_crc = sse42_supported();
1330 rc->conn_wait = wait;
1332 pthread_mutex_init(&rc->mtx, NULL);
1333 pthread_cond_init(&rc->cond, NULL);
1336 pthread_mutex_init(&rc->pixfmt_mtx, NULL);
1337 pthread_create(&rc->tid, NULL, rfb_thr, rc);
1338 pthread_set_name_np(rc->tid, "rfb");
1342 pthread_mutex_lock(&rc->mtx);
1343 pthread_cond_wait(&rc->cond, &rc->mtx);
1344 pthread_mutex_unlock(&rc->mtx);
1352 if (rc->pixfmt_mtx)
1353 pthread_mutex_destroy(&rc->pixfmt_mtx);
1356 if (rc->sfd != -1)
1357 close(rc->sfd);
1358 free(rc->crc);
1359 free(rc->crc_tmp);
1360 free(rc->pixrow);
1361 free(rc);
1362 return (-1);