Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144350384
D46402.id142324.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D46402.id142324.diff
View Options
diff --git a/usr.sbin/bhyve/rfb.c b/usr.sbin/bhyve/rfb.c
--- a/usr.sbin/bhyve/rfb.c
+++ b/usr.sbin/bhyve/rfb.c
@@ -139,6 +139,11 @@
uint32_t *crc; /* WxH crc cells */
uint32_t *crc_tmp; /* buffer to store single crc row */
int crc_width, crc_height;
+
+ uint32_t *pixrow;
+ uint8_t red_shift;
+ uint8_t green_shift;
+ uint8_t blue_shift;
};
struct rfb_pixfmt {
@@ -179,6 +184,10 @@
#define RFB_MAX_HEIGHT 1200
#define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4
+#define PIXEL_RED_SHIFT 16
+#define PIXEL_GREEN_SHIFT 8
+#define PIXEL_BLUE_SHIFT 0
+
/* percentage changes to screen before sending the entire screen */
#define RFB_SEND_ALL_THRESH 25
@@ -261,9 +270,9 @@
sinfo.pixfmt.red_max = htons(255);
sinfo.pixfmt.green_max = htons(255);
sinfo.pixfmt.blue_max = htons(255);
- sinfo.pixfmt.red_shift = 16;
- sinfo.pixfmt.green_shift = 8;
- sinfo.pixfmt.blue_shift = 0;
+ sinfo.pixfmt.red_shift = PIXEL_RED_SHIFT;
+ sinfo.pixfmt.green_shift = PIXEL_GREEN_SHIFT;
+ sinfo.pixfmt.blue_shift = PIXEL_BLUE_SHIFT;
sinfo.pixfmt.pad[0] = 0;
sinfo.pixfmt.pad[1] = 0;
sinfo.pixfmt.pad[2] = 0;
@@ -318,9 +327,54 @@
rfb_recv_set_pixfmt_msg(struct rfb_softc *rc __unused, int cfd)
{
struct rfb_pixfmt_msg pixfmt_msg;
+ uint32_t *pixelp;
+ uint8_t red_shift, green_shift, blue_shift;
(void)stream_read(cfd, (uint8_t *)&pixfmt_msg + 1,
sizeof(pixfmt_msg) - 1);
+
+ /*
+ * The framebuffer is fixed at 32 bit and orders the colors
+ * as RGB bytes. However, some VNC clients request a different
+ * ordering. We will still require the same bit depth and size
+ * but allow the colors to be shifted when sent to the client.
+ */
+ if ((pixfmt_msg.pixfmt.bpp != 32) || (pixfmt_msg.pixfmt.truecolor != 1))
+ return;
+
+ /* Check for valid max values */
+ if ((htons(pixfmt_msg.pixfmt.red_max) != 255) ||
+ (htons(pixfmt_msg.pixfmt.green_max) != 255) ||
+ (htons(pixfmt_msg.pixfmt.blue_max) != 255))
+ return;
+
+ red_shift = pixfmt_msg.pixfmt.red_shift;
+ green_shift = pixfmt_msg.pixfmt.green_shift;
+ blue_shift = pixfmt_msg.pixfmt.blue_shift;
+
+ /* Check if this is already our default shift */
+ if ((red_shift == PIXEL_RED_SHIFT) &&
+ (green_shift == PIXEL_GREEN_SHIFT) &&
+ (blue_shift == PIXEL_BLUE_SHIFT))
+ return;
+
+ /* Check shifts are 8 bit aligned */
+ if (((red_shift & 0x7) != 0) ||
+ ((green_shift & 0x7) != 0) ||
+ ((blue_shift & 0x7) != 0))
+ return;
+
+ /* Allocate a pixel array to contain the swapped values */
+ if (rc->pixrow == NULL) {
+ /* Will be using rfb_send_rect which does a row at a time */
+ pixelp = malloc(RFB_MAX_WIDTH * sizeof(uint32_t));
+ if (pixelp != NULL) {
+ rc->red_shift = red_shift;
+ rc->green_shift = green_shift;
+ rc->blue_shift = blue_shift;
+ rc->pixrow = pixelp;
+ }
+ }
}
static void
@@ -388,6 +442,30 @@
sizeof(struct rfb_srvr_updt_msg));
}
+static uint32_t *
+rfb_adjust_pixels(struct rfb_softc *rc, uint32_t *gcptr, int width, int height)
+{
+ uint32_t *zp;
+ uint32_t red, green, blue;
+ int i;
+
+ /* If no pixrow allocated, send in server format */
+ if (rc->pixrow == NULL) {
+ return (gcptr);
+ }
+
+ for (i = 0, zp = rc->pixrow; i < width * height; i++, zp++, gcptr++) {
+ red = (*gcptr >> 16) & 0xFF;
+ green = (*gcptr >> 8) & 0xFF;
+ blue = (*gcptr & 0xFF);
+ *zp = (red << rc->red_shift) |
+ (green << rc->green_shift) |
+ (blue << rc->blue_shift);
+ }
+
+ return (rc->pixrow);
+}
+
static int
rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
int x, int y, int w, int h)
@@ -395,8 +473,8 @@
struct rfb_srvr_rect_hdr srect_hdr;
unsigned long zlen;
ssize_t nwrite, total;
- int err;
- uint32_t *p;
+ int err, width;
+ uint32_t *p, *pixelp;
uint8_t *zbufp;
/*
@@ -409,6 +487,7 @@
srect_hdr.width = htons(w);
srect_hdr.height = htons(h);
+ width = w;
h = y + h;
w *= sizeof(uint32_t);
if (rc->enc_zlib_ok) {
@@ -416,7 +495,8 @@
rc->zstream.total_in = 0;
rc->zstream.total_out = 0;
for (p = &gc->data[y * gc->width + x]; y < h; y++) {
- rc->zstream.next_in = (Bytef *)p;
+ pixelp = rfb_adjust_pixels(rc, p, width, 1);
+ rc->zstream.next_in = (Bytef *)pixelp;
rc->zstream.avail_in = w;
rc->zstream.next_out = (Bytef *)zbufp;
rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16 -
@@ -452,7 +532,8 @@
total = 0;
zbufp = rc->zbuf;
for (p = &gc->data[y * gc->width + x]; y < h; y++) {
- memcpy(zbufp, p, w);
+ pixelp = rfb_adjust_pixels(rc, p, width, 1);
+ memcpy(zbufp, pixelp, w);
zbufp += w;
total += w;
p += gc->width;
@@ -491,6 +572,11 @@
if (nwrite <= 0)
return (nwrite);
+ if (rc->pixrow != 0) {
+ return (rfb_send_rect(rc, cfd, gc, 0, 0,
+ gc->width, gc->height));
+ }
+
/* Rectangle header */
srect_hdr.x = 0;
srect_hdr.y = 0;
@@ -1229,6 +1315,8 @@
close(rc->sfd);
free(rc->crc);
free(rc->crc_tmp);
+ free(rc->zbuf);
+ free(rc->pixrow);
free(rc);
return (-1);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 12:03 AM (14 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28513039
Default Alt Text
D46402.id142324.diff (4 KB)
Attached To
Mode
D46402: bhyve: support noVNC SetPixelFormat request
Attached
Detach File
Event Timeline
Log In to Comment