mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
gst/librfb/: It is now possible to connect to a vncserver. there are still some issues with the ouput of the screen. ...
Original commit message from CVS: * gst/librfb/gstrfbsrc.c: * gst/librfb/rfbdecoder.c: * gst/librfb/rfbdecoder.h: It is now possible to connect to a vncserver. there are still some issues with the ouput of the screen. Looks like some lines are confused
This commit is contained in:
parent
50ed6cc7b2
commit
d785a925c1
4 changed files with 185 additions and 117 deletions
|
@ -1,3 +1,12 @@
|
|||
2007-09-19 Thijs Vermeir <thijsvermeir@gmail.com>
|
||||
|
||||
* gst/librfb/gstrfbsrc.c:
|
||||
* gst/librfb/rfbdecoder.c:
|
||||
* gst/librfb/rfbdecoder.h:
|
||||
It is now possible to connect to a vncserver.
|
||||
there are still some issues with the ouput of
|
||||
the screen. Looks like some lines are confused
|
||||
|
||||
2007-09-19 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* docs/plugins/.cvsignore:
|
||||
|
|
|
@ -410,20 +410,20 @@ gst_rfb_src_paint_rect (RfbDecoder * decoder, gint x, gint y, gint w, gint h,
|
|||
gint width;
|
||||
gint offset;
|
||||
|
||||
// GST_DEBUG ("painting %d,%d (%dx%d)\n", x, y, w, h);
|
||||
GST_DEBUG ("painting %d,%d (%dx%d)\n", x, y, w, h);
|
||||
src = GST_RFB_SRC (decoder->decoder_private);
|
||||
|
||||
frame = src->frame;
|
||||
width = decoder->width;
|
||||
for (j = 0; j < h; j++) {
|
||||
for (i = 0; i < w; i++) {
|
||||
color = data[j * w + i];
|
||||
color = data[(j * w + i) * decoder->bpp / 8];
|
||||
|
||||
offset = ((j + x) * width + (i + x)) * 4;
|
||||
frame[offset + 0] = RGB332_B (color);
|
||||
frame[offset + 1] = RGB332_G (color);
|
||||
frame[offset + 2] = RGB332_R (color);
|
||||
frame[offset + 3] = 0;
|
||||
offset = ((j + y) * width + (i + x)) * decoder->bpp / 8;
|
||||
frame[offset] = data[((j * w + i) * decoder->bpp / 8)];
|
||||
frame[offset + 1] = data[((j * w + i) * decoder->bpp / 8) + 1];
|
||||
frame[offset + 2] = data[((j * w + i) * decoder->bpp / 8) + 2];
|
||||
frame[offset + 3] = data[((j * w + i) * decoder->bpp / 8) + 3];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,26 +95,30 @@ rfb_decoder_use_file_descriptor (RfbDecoder * decoder, gint fd)
|
|||
gboolean
|
||||
rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * addr, guint port)
|
||||
{
|
||||
gint fd;
|
||||
struct sockaddr_in sa;
|
||||
|
||||
GST_DEBUG ("connecting to the rfb server");
|
||||
|
||||
g_return_val_if_fail (decoder != NULL, FALSE);
|
||||
g_return_val_if_fail (decoder->fd == -1, FALSE);
|
||||
g_return_val_if_fail (addr != NULL, FALSE);
|
||||
|
||||
fd = socket (PF_INET, SOCK_STREAM, 0);
|
||||
if (fd == -1)
|
||||
decoder->fd = socket (PF_INET, SOCK_STREAM, 0);
|
||||
if (decoder->fd == -1) {
|
||||
GST_WARNING ("creating socket failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons (port);
|
||||
inet_pton (AF_INET, addr, &sa.sin_addr);
|
||||
if (connect (fd, (struct sockaddr *) &sa, sizeof (struct sockaddr)) == -1) {
|
||||
close (fd);
|
||||
if (connect (decoder->fd, (struct sockaddr *) &sa,
|
||||
sizeof (struct sockaddr)) == -1) {
|
||||
close (decoder->fd);
|
||||
GST_WARNING ("connection failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rfb_decoder_use_file_descriptor (decoder, fd);
|
||||
//rfb_decoder_use_file_descriptor (decoder, fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -143,14 +147,39 @@ rfb_decoder_iterate (RfbDecoder * decoder)
|
|||
return decoder->state (decoder);
|
||||
}
|
||||
|
||||
gint
|
||||
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, gint len)
|
||||
guint8 *
|
||||
rfb_decoder_read (RfbDecoder * decoder, gint len)
|
||||
{
|
||||
g_return_val_if_fail (decoder != NULL, 0);
|
||||
g_return_val_if_fail (decoder->fd != -1, 0);
|
||||
g_return_val_if_fail (buffer != NULL, 0);
|
||||
gint total = 0;
|
||||
gint now = 0;
|
||||
guint8 *address = NULL;
|
||||
|
||||
return decoder->send_data (buffer, len, decoder->buffer_handler_data);
|
||||
g_return_val_if_fail (decoder->fd > 0, NULL);
|
||||
g_return_val_if_fail (len > 0, NULL);
|
||||
|
||||
address = g_malloc (len);
|
||||
g_return_val_if_fail (address, NULL);
|
||||
|
||||
address += total;
|
||||
while (total < len) {
|
||||
now = recv (decoder->fd, address, len - total, 0);
|
||||
if (now <= 0) {
|
||||
GST_WARNING ("rfb read error on socket");
|
||||
return NULL;
|
||||
}
|
||||
total += now;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
static gint
|
||||
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, guint len)
|
||||
{
|
||||
g_return_val_if_fail (decoder->fd != 0, FALSE);
|
||||
g_return_val_if_fail (buffer != NULL, FALSE);
|
||||
g_return_val_if_fail (len > 0, FALSE);
|
||||
|
||||
return write (decoder->fd, buffer, len);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,27 +244,20 @@ rfb_decoder_send_pointer_event (RfbDecoder * decoder,
|
|||
static gboolean
|
||||
rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
guint8 *data;
|
||||
gint ret;
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 12);
|
||||
if (ret < 12)
|
||||
return FALSE;
|
||||
buffer = rfb_decoder_read (decoder, 12);
|
||||
|
||||
data = buffer->data;
|
||||
g_return_val_if_fail (memcmp (buffer, "RFB 003.00", 10) == 0, FALSE);
|
||||
g_return_val_if_fail (*(buffer + 11) == 0x0a, FALSE);
|
||||
|
||||
g_return_val_if_fail (memcmp (buffer->data, "RFB 003.00", 10) == 0, FALSE);
|
||||
g_return_val_if_fail (*(buffer->data + 11) == 0x0a, FALSE);
|
||||
|
||||
GST_DEBUG ("\"%.11s\"", buffer->data);
|
||||
*(buffer->data + 7) = 0x00;
|
||||
*(buffer->data + 11) = 0x00;
|
||||
decoder->protocol_major = atoi ((char *) (buffer->data + 4));
|
||||
decoder->protocol_minor = atoi ((char *) (buffer->data + 8));
|
||||
GST_DEBUG ("\"%.11s\"", buffer);
|
||||
*(buffer + 7) = 0x00;
|
||||
*(buffer + 11) = 0x00;
|
||||
decoder->protocol_major = atoi ((char *) (buffer + 4));
|
||||
decoder->protocol_minor = atoi ((char *) (buffer + 8));
|
||||
GST_DEBUG ("Major version : %d", decoder->protocol_major);
|
||||
GST_DEBUG ("Minor version : %d", decoder->protocol_minor);
|
||||
rfb_buffer_free (buffer);
|
||||
|
||||
if (decoder->protocol_major != 3) {
|
||||
GST_INFO
|
||||
|
@ -254,7 +276,7 @@ rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
|
|||
rfb_decoder_send (decoder, (guint8 *) "RFB 003.003\n", 12);
|
||||
|
||||
decoder->state = rfb_decoder_state_wait_for_security;
|
||||
|
||||
g_free (buffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -265,15 +287,18 @@ rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_reason (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
gint reason_length;
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
rfb_bytestream_read (decoder->bytestream, &buffer, 4);
|
||||
reason_length = RFB_GET_UINT32 (buffer->data);
|
||||
rfb_buffer_free (buffer);
|
||||
rfb_bytestream_read (decoder->bytestream, &buffer, reason_length);
|
||||
GST_WARNING ("Reason by server: %s", buffer->data);
|
||||
rfb_buffer_free (buffer);
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
|
||||
reason_length = RFB_GET_UINT32 (buffer);
|
||||
g_free (buffer);
|
||||
buffer = NULL;
|
||||
buffer = rfb_decoder_read (decoder, reason_length);
|
||||
GST_WARNING ("Reason by server: %s", buffer);
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -281,8 +306,7 @@ rfb_decoder_state_reason (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
gint ret;
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
/**
|
||||
* Version 3.3 The server decides the security type and sends a single word
|
||||
|
@ -292,16 +316,19 @@ rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
|||
* above.
|
||||
*/
|
||||
if (IS_VERSION_3_3 (decoder)) {
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 4);
|
||||
g_return_val_if_fail (ret == 4, FALSE);
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
|
||||
decoder->security_type = RFB_GET_UINT32 (buffer->data);
|
||||
decoder->security_type = RFB_GET_UINT32 (buffer);
|
||||
GST_DEBUG ("security = %d", decoder->security_type);
|
||||
|
||||
g_return_val_if_fail (decoder->security_type < 3, FALSE);
|
||||
g_return_val_if_fail (decoder->security_type != SECURITY_FAIL,
|
||||
rfb_decoder_state_reason (decoder));
|
||||
rfb_buffer_free (buffer);
|
||||
g_free (buffer);
|
||||
buffer = NULL;
|
||||
} else {
|
||||
/* \TODO Add behavoir for the rfb 3.7 and 3.8 servers */
|
||||
GST_WARNING ("Other versions are not yet supported");
|
||||
}
|
||||
|
||||
switch (decoder->security_type) {
|
||||
|
@ -326,11 +353,10 @@ rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 16);
|
||||
g_return_val_if_fail (ret == 16, FALSE);
|
||||
vncEncryptBytes ((unsigned char *) buffer->data, decoder->password);
|
||||
rfb_decoder_send (decoder, buffer->data, 16);
|
||||
rfb_buffer_free (buffer);
|
||||
buffer = rfb_decoder_read (decoder, 16);
|
||||
vncEncryptBytes ((unsigned char *) buffer, decoder->password);
|
||||
rfb_decoder_send (decoder, buffer, 16);
|
||||
g_free (buffer);
|
||||
|
||||
GST_DEBUG ("Encrypted challenge send to server");
|
||||
|
||||
|
@ -351,12 +377,10 @@ rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_security_result (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
gint ret;
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 4);
|
||||
g_return_val_if_fail (ret == 4, FALSE);
|
||||
if (RFB_GET_UINT32 (buffer->data) != 0) {
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
if (RFB_GET_UINT32 (buffer) != 0) {
|
||||
GST_WARNING ("Security handshaking failed");
|
||||
if (IS_VERSION_3_8 (decoder)) {
|
||||
decoder->state = rfb_decoder_state_reason;
|
||||
|
@ -378,6 +402,7 @@ rfb_decoder_state_send_client_initialisation (RfbDecoder * decoder)
|
|||
|
||||
shared_flag = decoder->shared_flag;
|
||||
rfb_decoder_send (decoder, &shared_flag, 1);
|
||||
GST_DEBUG ("shared_flag is %d", shared_flag);
|
||||
|
||||
decoder->state = rfb_decoder_state_wait_for_server_initialisation;
|
||||
return TRUE;
|
||||
|
@ -386,43 +411,45 @@ rfb_decoder_state_send_client_initialisation (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
guint8 *data;
|
||||
gint ret;
|
||||
guint8 *buffer = NULL;
|
||||
guint32 name_length;
|
||||
|
||||
ret = rfb_bytestream_peek (decoder->bytestream, &buffer, 24);
|
||||
if (ret < 24)
|
||||
return FALSE;
|
||||
buffer = rfb_decoder_read (decoder, 24);
|
||||
|
||||
data = buffer->data;
|
||||
decoder->width = RFB_GET_UINT16 (buffer + 0);
|
||||
decoder->height = RFB_GET_UINT16 (buffer + 2);
|
||||
decoder->bpp = RFB_GET_UINT8 (buffer + 4);
|
||||
decoder->depth = RFB_GET_UINT8 (buffer + 5);
|
||||
decoder->big_endian = RFB_GET_UINT8 (buffer + 6);
|
||||
decoder->true_colour = RFB_GET_UINT8 (buffer + 7);
|
||||
decoder->red_max = RFB_GET_UINT16 (buffer + 8);
|
||||
decoder->green_max = RFB_GET_UINT16 (buffer + 10);
|
||||
decoder->blue_max = RFB_GET_UINT16 (buffer + 12);
|
||||
decoder->red_shift = RFB_GET_UINT8 (buffer + 14);
|
||||
decoder->green_shift = RFB_GET_UINT8 (buffer + 15);
|
||||
decoder->blue_shift = RFB_GET_UINT8 (buffer + 16);
|
||||
|
||||
decoder->width = RFB_GET_UINT16 (data + 0);
|
||||
decoder->height = RFB_GET_UINT16 (data + 2);
|
||||
decoder->bpp = RFB_GET_UINT8 (data + 4);
|
||||
decoder->depth = RFB_GET_UINT8 (data + 5);
|
||||
decoder->big_endian = RFB_GET_UINT8 (data + 6);
|
||||
decoder->true_colour = RFB_GET_UINT8 (data + 7);
|
||||
decoder->red_max = RFB_GET_UINT16 (data + 8);
|
||||
decoder->green_max = RFB_GET_UINT16 (data + 10);
|
||||
decoder->blue_max = RFB_GET_UINT16 (data + 12);
|
||||
decoder->red_shift = RFB_GET_UINT8 (data + 14);
|
||||
decoder->green_shift = RFB_GET_UINT8 (data + 15);
|
||||
decoder->blue_shift = RFB_GET_UINT8 (data + 16);
|
||||
GST_DEBUG ("Server Initialization");
|
||||
GST_DEBUG ("width = %d", decoder->width);
|
||||
GST_DEBUG ("height = %d", decoder->height);
|
||||
GST_DEBUG ("bpp = %d", decoder->bpp);
|
||||
GST_DEBUG ("depth = %d", decoder->depth);
|
||||
GST_DEBUG ("big_endian = %d", decoder->big_endian);
|
||||
GST_DEBUG ("true_colour= %d", decoder->true_colour);
|
||||
GST_DEBUG ("red_max = %d", decoder->red_max);
|
||||
GST_DEBUG ("green_max = %d", decoder->green_max);
|
||||
GST_DEBUG ("blue_max = %d", decoder->blue_max);
|
||||
GST_DEBUG ("red_shift = %d", decoder->red_shift);
|
||||
GST_DEBUG ("green_shift= %d", decoder->green_shift);
|
||||
GST_DEBUG ("blue_shift = %d", decoder->blue_shift);
|
||||
|
||||
// g_print ("width: %d\n", decoder->width);
|
||||
// g_print ("height: %d\n", decoder->height);
|
||||
name_length = RFB_GET_UINT32 (buffer + 20);
|
||||
|
||||
name_length = RFB_GET_UINT32 (data + 20);
|
||||
rfb_buffer_free (buffer);
|
||||
buffer = rfb_decoder_read (decoder, name_length);
|
||||
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 24 + name_length);
|
||||
if (ret < 24 + name_length)
|
||||
return FALSE;
|
||||
|
||||
decoder->name = g_strndup ((gchar *) (buffer->data) + 24, name_length);
|
||||
// g_print ("name: %s\n", decoder->name);
|
||||
rfb_buffer_free (buffer);
|
||||
decoder->name = g_strndup ((gchar *) (buffer), name_length);
|
||||
g_free (buffer);
|
||||
GST_DEBUG ("name = %s", decoder->name);
|
||||
|
||||
decoder->state = rfb_decoder_state_normal;
|
||||
decoder->inited = TRUE;
|
||||
|
@ -433,15 +460,15 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_normal (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
gint ret;
|
||||
guint8 *buffer;
|
||||
gint message_type;
|
||||
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 1);
|
||||
message_type = RFB_GET_UINT8 (buffer->data);
|
||||
buffer = rfb_decoder_read (decoder, 1);
|
||||
message_type = RFB_GET_UINT8 (buffer);
|
||||
|
||||
switch (message_type) {
|
||||
case 0:
|
||||
GST_DEBUG ("Receiving framebuffer update");
|
||||
decoder->state = rfb_decoder_state_framebuffer_update;
|
||||
break;
|
||||
case 1:
|
||||
|
@ -458,27 +485,28 @@ rfb_decoder_state_normal (RfbDecoder * decoder)
|
|||
g_critical ("unknown message type %d", message_type);
|
||||
}
|
||||
|
||||
rfb_buffer_free (buffer);
|
||||
|
||||
g_free (buffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
gint ret;
|
||||
guint8 *buffer;
|
||||
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, 3);
|
||||
buffer = rfb_decoder_read (decoder, 3);
|
||||
|
||||
decoder->n_rects = RFB_GET_UINT16 (buffer + 1);
|
||||
GST_DEBUG ("Number of rectangles : %d", decoder->n_rects);
|
||||
|
||||
decoder->n_rects = RFB_GET_UINT16 (buffer->data + 1);
|
||||
decoder->state = rfb_decoder_state_framebuffer_update_rectangle;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
static gboolean
|
||||
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
||||
rfb_decoder_state_framebuffer_update (RfbDecoder *decoder)
|
||||
{
|
||||
RfbBuffer *buffer;
|
||||
gint ret;
|
||||
|
@ -496,22 +524,56 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
|||
h = RFB_GET_UINT16 (buffer->data + 6);
|
||||
encoding = RFB_GET_UINT32 (buffer->data + 8);
|
||||
|
||||
GST_DEBUG(" UPDATE Receiver");
|
||||
GST_DEBUG("x:%d y:%d", x, y);
|
||||
GST_DEBUG("w:%d h:%d", w, h);
|
||||
GST_DEBUG("encoding: %d", encoding);
|
||||
|
||||
switch (encoding)
|
||||
{
|
||||
default:
|
||||
GST_WARNING("encoding type(%d) is not supported", encoding);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
static gboolean
|
||||
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer;
|
||||
gint x, y, w, h;
|
||||
gint encoding;
|
||||
gint size;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 12);
|
||||
|
||||
x = RFB_GET_UINT16 (buffer + 0);
|
||||
y = RFB_GET_UINT16 (buffer + 2);
|
||||
w = RFB_GET_UINT16 (buffer + 4);
|
||||
h = RFB_GET_UINT16 (buffer + 6);
|
||||
encoding = RFB_GET_UINT32 (buffer + 8);
|
||||
|
||||
GST_DEBUG ("update recieved");
|
||||
GST_DEBUG ("x:%d y:%d", x, y);
|
||||
GST_DEBUG ("w:%d h:%d", w, h);
|
||||
GST_DEBUG ("encoding: %d", encoding);
|
||||
|
||||
if (encoding != 0)
|
||||
g_critical ("unimplemented encoding\n");
|
||||
|
||||
rfb_buffer_free (buffer);
|
||||
g_free (buffer);
|
||||
|
||||
size = w * h;
|
||||
ret = rfb_bytestream_read (decoder->bytestream, &buffer, size + 12);
|
||||
if (ret < size)
|
||||
return FALSE;
|
||||
size = w * h * decoder->bpp / 8;
|
||||
GST_DEBUG ("Reading %d bytes", size);
|
||||
buffer = rfb_decoder_read (decoder, size);
|
||||
GST_DEBUG ("Reading %d bytes", size);
|
||||
|
||||
if (decoder->paint_rect) {
|
||||
decoder->paint_rect (decoder, x, y, w, h, buffer->data + 12);
|
||||
decoder->paint_rect (decoder, x, y, w, h, buffer);
|
||||
}
|
||||
|
||||
rfb_buffer_free (buffer);
|
||||
|
||||
g_free (buffer);
|
||||
decoder->n_rects--;
|
||||
if (decoder->n_rects == 0) {
|
||||
decoder->state = rfb_decoder_state_normal;
|
||||
|
|
|
@ -89,9 +89,6 @@ gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder,
|
|||
gchar * addr,
|
||||
guint port);
|
||||
gboolean rfb_decoder_iterate (RfbDecoder * decoder);
|
||||
gint rfb_decoder_send (RfbDecoder * decoder,
|
||||
guint8 *data,
|
||||
gint len);
|
||||
void rfb_decoder_send_update_request (RfbDecoder * decoder,
|
||||
gboolean incremental,
|
||||
gint x,
|
||||
|
|
Loading…
Reference in a new issue