diff --git a/ChangeLog b/ChangeLog index 86d96e5535..d788df2d53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-09-19 Thijs Vermeir + + * 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 * docs/plugins/.cvsignore: diff --git a/gst/librfb/gstrfbsrc.c b/gst/librfb/gstrfbsrc.c index 38560b8b1c..d0398dc9e8 100644 --- a/gst/librfb/gstrfbsrc.c +++ b/gst/librfb/gstrfbsrc.c @@ -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]; } } diff --git a/gst/librfb/rfbdecoder.c b/gst/librfb/rfbdecoder.c index 1b56c63ca5..8c398becfb 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) { - 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,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; - 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; - 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; diff --git a/gst/librfb/rfbdecoder.h b/gst/librfb/rfbdecoder.h index 2f423341ce..9d1778f6ca 100644 --- a/gst/librfb/rfbdecoder.h +++ b/gst/librfb/rfbdecoder.h @@ -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,