aboutsummaryrefslogtreecommitdiff
path: root/vnc.c
diff options
context:
space:
mode:
Diffstat (limited to 'vnc.c')
-rw-r--r--vnc.c220
1 files changed, 12 insertions, 208 deletions
diff --git a/vnc.c b/vnc.c
index d332099..5241a6a 100644
--- a/vnc.c
+++ b/vnc.c
@@ -468,8 +468,8 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
vnc_set_bit(s->dirty[y], (x + i) / 16);
}
-static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding)
+void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
+ int32_t encoding)
{
vnc_write_u16(vs, x);
vnc_write_u16(vs, y);
@@ -560,7 +560,7 @@ static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
}
/* slowest but generic code. */
-static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
+void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
{
uint8_t r, g, b;
VncDisplay *vd = vs->vd;
@@ -638,7 +638,7 @@ static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
}
}
-static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
+void vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
{
int i;
uint8_t *row;
@@ -651,192 +651,19 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h
}
}
-static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
-{
- ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
- ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
-}
-
-#define BPP 8
-#include "vnchextile.h"
-#undef BPP
-
-#define BPP 16
-#include "vnchextile.h"
-#undef BPP
-
-#define BPP 32
-#include "vnchextile.h"
-#undef BPP
-
-#define GENERIC
-#define BPP 8
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 16
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 32
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
-{
- int i, j;
- int has_fg, has_bg;
- uint8_t *last_fg, *last_bg;
- VncDisplay *vd = vs->vd;
-
- last_fg = (uint8_t *) qemu_malloc(vd->server->pf.bytes_per_pixel);
- last_bg = (uint8_t *) qemu_malloc(vd->server->pf.bytes_per_pixel);
- has_fg = has_bg = 0;
- for (j = y; j < (y + h); j += 16) {
- for (i = x; i < (x + w); i += 16) {
- vs->send_hextile_tile(vs, i, j,
- MIN(16, x + w - i), MIN(16, y + h - j),
- last_bg, last_fg, &has_bg, &has_fg);
- }
- }
- free(last_fg);
- free(last_bg);
-
-}
-
-#define ZALLOC_ALIGNMENT 16
-
-static void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p;
-
- size *= items;
- size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
-
- p = qemu_mallocz(size);
-
- return (p);
-}
-
-static void zfree(void *x, void *addr)
-{
- qemu_free(addr);
-}
-
-static void vnc_zlib_init(VncState *vs)
-{
- int i;
- for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
- vs->zlib_stream[i].opaque = NULL;
-}
-
-static void vnc_zlib_start(VncState *vs)
-{
- buffer_reset(&vs->zlib);
-
- // make the output buffer be the zlib buffer, so we can compress it later
- vs->zlib_tmp = vs->output;
- vs->output = vs->zlib;
-}
-
-static int vnc_zlib_stop(VncState *vs, int stream_id)
-{
- z_streamp zstream = &vs->zlib_stream[stream_id];
- int previous_out;
-
- // switch back to normal output/zlib buffers
- vs->zlib = vs->output;
- vs->output = vs->zlib_tmp;
-
- // compress the zlib buffer
-
- // initialize the stream
- // XXX need one stream per session
- if (zstream->opaque != vs) {
- int err;
-
- VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
- VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
- zstream->zalloc = zalloc;
- zstream->zfree = zfree;
-
- err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
- MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-
- if (err != Z_OK) {
- fprintf(stderr, "VNC: error initializing zlib\n");
- return -1;
- }
-
- zstream->opaque = vs;
- }
-
- // XXX what to do if tight_compression changed in between?
-
- // reserve memory in output buffer
- buffer_reserve(&vs->output, vs->zlib.offset + 64);
-
- // set pointers
- zstream->next_in = vs->zlib.buffer;
- zstream->avail_in = vs->zlib.offset;
- zstream->next_out = vs->output.buffer + vs->output.offset;
- zstream->avail_out = vs->output.capacity - vs->output.offset;
- zstream->data_type = Z_BINARY;
- previous_out = zstream->total_out;
-
- // start encoding
- if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
- fprintf(stderr, "VNC: error during zlib compression\n");
- return -1;
- }
-
- vs->output.offset = vs->output.capacity - zstream->avail_out;
- return zstream->total_out - previous_out;
-}
-
-static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
-{
- int old_offset, new_offset, bytes_written;
-
- vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
-
- // remember where we put in the follow-up size
- old_offset = vs->output.offset;
- vnc_write_s32(vs, 0);
-
- // compress the stream
- vnc_zlib_start(vs);
- send_framebuffer_update_raw(vs, x, y, w, h);
- bytes_written = vnc_zlib_stop(vs, 0);
-
- if (bytes_written == -1)
- return;
-
- // hack in the size
- new_offset = vs->output.offset;
- vs->output.offset = old_offset;
- vnc_write_u32(vs, bytes_written);
- vs->output.offset = new_offset;
-}
-
static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
{
switch(vs->vnc_encoding) {
case VNC_ENCODING_ZLIB:
- send_framebuffer_update_zlib(vs, x, y, w, h);
+ vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
break;
case VNC_ENCODING_HEXTILE:
vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
- send_framebuffer_update_hextile(vs, x, y, w, h);
+ vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
break;
default:
vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
- send_framebuffer_update_raw(vs, x, y, w, h);
+ vnc_raw_send_framebuffer_update(vs, x, y, w, h);
break;
}
}
@@ -1823,30 +1650,10 @@ static void set_pixel_conversion(VncState *vs)
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
!memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
vs->write_pixels = vnc_write_pixels_copy;
- switch (vs->ds->surface->pf.bits_per_pixel) {
- case 8:
- vs->send_hextile_tile = send_hextile_tile_8;
- break;
- case 16:
- vs->send_hextile_tile = send_hextile_tile_16;
- break;
- case 32:
- vs->send_hextile_tile = send_hextile_tile_32;
- break;
- }
+ vnc_hextile_set_pixel_conversion(vs, 0);
} else {
vs->write_pixels = vnc_write_pixels_generic;
- switch (vs->ds->surface->pf.bits_per_pixel) {
- case 8:
- vs->send_hextile_tile = send_hextile_tile_generic_8;
- break;
- case 16:
- vs->send_hextile_tile = send_hextile_tile_generic_16;
- break;
- case 32:
- vs->send_hextile_tile = send_hextile_tile_generic_32;
- break;
- }
+ vnc_hextile_set_pixel_conversion(vs, 1);
}
}
@@ -1903,12 +1710,9 @@ static void pixel_format_message (VncState *vs) {
vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
- if (vs->ds->surface->pf.bits_per_pixel == 32)
- vs->send_hextile_tile = send_hextile_tile_32;
- else if (vs->ds->surface->pf.bits_per_pixel == 16)
- vs->send_hextile_tile = send_hextile_tile_16;
- else if (vs->ds->surface->pf.bits_per_pixel == 8)
- vs->send_hextile_tile = send_hextile_tile_8;
+
+ vnc_hextile_set_pixel_conversion(vs, 0);
+
vs->clientds = *(vs->ds->surface);
vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
vs->write_pixels = vnc_write_pixels_copy;