summaryrefslogtreecommitdiffstats
path: root/gst/librfb/rfbdecoder.c
diff options
context:
space:
mode:
authorThijs Vermeir <thijsvermeir@gmail.com>2007-09-19 20:55:43 +0000
committerThijs Vermeir <thijsvermeir@gmail.com>2007-09-19 20:55:43 +0000
commitd785a925c1339a4783fdedccff42b2de5f4694d3 (patch)
tree01ab2ae1d5c5834f3ead88c707c724c3acd9fe1c /gst/librfb/rfbdecoder.c
parent50ed6cc7b2e593080f4a6407e3c1d05e4476b192 (diff)
downloadgst-plugins-bad-d785a925c1339a4783fdedccff42b2de5f4694d3.tar.gz
gst-plugins-bad-d785a925c1339a4783fdedccff42b2de5f4694d3.tar.bz2
gst-plugins-bad-d785a925c1339a4783fdedccff42b2de5f4694d3.zip
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
Diffstat (limited to 'gst/librfb/rfbdecoder.c')
-rw-r--r--gst/librfb/rfbdecoder.c286
1 files changed, 174 insertions, 112 deletions
diff --git a/gst/librfb/rfbdecoder.c b/gst/librfb/rfbdecoder.c
index 1b56c63c..8c398bec 100644
--- a/gst/librfb/rfbdecoder.c
+++ b/gst/librfb/rfbdecoder.c
@@ -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)
+{
+ gint total = 0;
+ gint now = 0;
+ guint8 *address = NULL;
+
+ 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 != NULL, 0);
- g_return_val_if_fail (decoder->fd != -1, 0);
- g_return_val_if_fail (buffer != NULL, 0);
+ 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 decoder->send_data (buffer, len, decoder->buffer_handler_data);
+ 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;
-
- ret = rfb_bytestream_read (decoder->bytestream, &buffer, 12);
- if (ret < 12)
- return FALSE;
+ guint8 *buffer = NULL;
- data = buffer->data;
+ buffer = rfb_decoder_read (decoder, 12);
- g_return_val_if_fail (memcmp (buffer->data, "RFB 003.00", 10) == 0, FALSE);
- g_return_val_if_fail (*(buffer->data + 11) == 0x0a, FALSE);
+ g_return_val_if_fail (memcmp (buffer, "RFB 003.00", 10) == 0, FALSE);
+ g_return_val_if_fail (*(buffer + 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;
+
+ 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);
- 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);
+ 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;
-
- data = buffer->data;
-
- 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);
-
- // g_print ("width: %d\n", decoder->width);
- // g_print ("height: %d\n", decoder->height);
-
- name_length = RFB_GET_UINT32 (data + 20);
- rfb_buffer_free (buffer);
-
- 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);
+ buffer = rfb_decoder_read (decoder, 24);
+
+ 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);
+
+ 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);
+
+ name_length = RFB_GET_UINT32 (buffer + 20);
+
+ buffer = rfb_decoder_read (decoder, name_length);
+
+ 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,33 +485,34 @@ 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;
+
+ buffer = rfb_decoder_read (decoder, 3);
- ret = rfb_bytestream_read (decoder->bytestream, &buffer, 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;
- gint x, y, w, h;
- gint encoding;
- gint size;
+ RfbBuffer *buffer;
+ gint ret;
+ gint x, y, w, h;
+ gint encoding;
+ gint size;
ret = rfb_bytestream_peek (decoder->bytestream, &buffer, 12);
if (ret < 12)
@@ -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;