mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
rfbsrc: use glib gio sockets for network access
https://bugzilla.gnome.org/show_bug.cgi?id=700038
This commit is contained in:
parent
42783e676e
commit
90e006513a
4 changed files with 148 additions and 90 deletions
|
@ -15,8 +15,8 @@ librfb_la_SOURCES = \
|
||||||
rfbdecoder.c \
|
rfbdecoder.c \
|
||||||
d3des.c \
|
d3des.c \
|
||||||
vncauth.c
|
vncauth.c
|
||||||
librfb_la_CFLAGS = $(GST_CFLAGS) -I$(srcdir)/..
|
librfb_la_CFLAGS = $(GST_CFLAGS) $(GIO_CFLAGS) -I$(srcdir)/..
|
||||||
librfb_la_LIBADD = $(GLIB_LIBS)
|
librfb_la_LIBADD = $(GST_LIBS) $(GIO_LIBS)
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
rfb.h \
|
rfb.h \
|
||||||
|
|
|
@ -34,10 +34,6 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
ARG_0,
|
||||||
|
@ -191,15 +187,6 @@ gst_rfb_src_init (GstRfbSrc * src)
|
||||||
|
|
||||||
src->decoder = rfb_decoder_new ();
|
src->decoder = rfb_decoder_new ();
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
{
|
|
||||||
WSADATA wsa_data;
|
|
||||||
|
|
||||||
if (WSAStartup (MAKEWORD (2, 2), &wsa_data) != 0) {
|
|
||||||
GST_ERROR_OBJECT (src, "WSAStartup failed: 0x%08x", WSAGetLastError ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -217,9 +204,6 @@ gst_rfb_src_finalize (GObject * object)
|
||||||
g_free (src->decoder);
|
g_free (src->decoder);
|
||||||
src->decoder = NULL;
|
src->decoder = NULL;
|
||||||
}
|
}
|
||||||
#ifdef G_OS_WIN32
|
|
||||||
WSACleanup ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -508,7 +492,10 @@ gst_rfb_src_stop (GstBaseSrc * bsrc)
|
||||||
{
|
{
|
||||||
GstRfbSrc *src = GST_RFB_SRC (bsrc);
|
GstRfbSrc *src = GST_RFB_SRC (bsrc);
|
||||||
|
|
||||||
src->decoder->fd = -1;
|
if (src->decoder->socket) {
|
||||||
|
g_object_unref (src->decoder->socket);
|
||||||
|
src->decoder->socket = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (src->decoder->frame) {
|
if (src->decoder->frame) {
|
||||||
g_free (src->decoder->frame);
|
g_free (src->decoder->frame);
|
||||||
|
|
|
@ -2,23 +2,15 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gst/gst.h"
|
#include "rfb.h"
|
||||||
|
|
||||||
#include <rfb.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#ifndef G_OS_WIN32
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#else
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "vncauth.h"
|
#include "vncauth.h"
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define RFB_GET_UINT32(ptr) GST_READ_UINT32_BE(ptr)
|
#define RFB_GET_UINT32(ptr) GST_READ_UINT32_BE(ptr)
|
||||||
#define RFB_GET_UINT16(ptr) GST_READ_UINT16_BE(ptr)
|
#define RFB_GET_UINT16(ptr) GST_READ_UINT16_BE(ptr)
|
||||||
#define RFB_GET_UINT8(ptr) GST_READ_UINT8(ptr)
|
#define RFB_GET_UINT8(ptr) GST_READ_UINT8(ptr)
|
||||||
|
@ -30,13 +22,6 @@
|
||||||
GST_DEBUG_CATEGORY_EXTERN (rfbdecoder_debug);
|
GST_DEBUG_CATEGORY_EXTERN (rfbdecoder_debug);
|
||||||
#define GST_CAT_DEFAULT rfbdecoder_debug
|
#define GST_CAT_DEFAULT rfbdecoder_debug
|
||||||
|
|
||||||
#if 0
|
|
||||||
struct _RfbSocketPrivate
|
|
||||||
{
|
|
||||||
gint fd;
|
|
||||||
sockaddr sa;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static gboolean rfb_decoder_state_wait_for_protocol_version (RfbDecoder *
|
static gboolean rfb_decoder_state_wait_for_protocol_version (RfbDecoder *
|
||||||
decoder);
|
decoder);
|
||||||
|
@ -68,7 +53,8 @@ rfb_decoder_new (void)
|
||||||
{
|
{
|
||||||
RfbDecoder *decoder = g_new0 (RfbDecoder, 1);
|
RfbDecoder *decoder = g_new0 (RfbDecoder, 1);
|
||||||
|
|
||||||
decoder->fd = -1;
|
decoder->socket = NULL;
|
||||||
|
decoder->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
decoder->password = NULL;
|
decoder->password = NULL;
|
||||||
|
|
||||||
|
@ -91,49 +77,102 @@ rfb_decoder_free (RfbDecoder * decoder)
|
||||||
{
|
{
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
|
|
||||||
if (decoder->fd >= 0)
|
if (decoder->cancellable) {
|
||||||
close (decoder->fd);
|
g_cancellable_cancel (decoder->cancellable);
|
||||||
|
g_object_unref (decoder->cancellable);
|
||||||
|
decoder->cancellable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoder->socket) {
|
||||||
|
g_object_unref (decoder->socket);
|
||||||
|
decoder->socket = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (decoder->data)
|
if (decoder->data)
|
||||||
g_free (decoder->data);
|
g_free (decoder->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * addr, guint port)
|
rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * host, guint port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sa;
|
GError *err = NULL;
|
||||||
|
GInetAddress *addr;
|
||||||
|
GSocketAddress *saddr;
|
||||||
|
GResolver *resolver;
|
||||||
|
|
||||||
GST_DEBUG ("connecting to the rfb server");
|
GST_DEBUG ("connecting to the rfb server");
|
||||||
|
|
||||||
g_return_val_if_fail (decoder != NULL, FALSE);
|
g_return_val_if_fail (decoder != NULL, FALSE);
|
||||||
g_return_val_if_fail (decoder->fd == -1, FALSE);
|
g_return_val_if_fail (decoder->socket == NULL, FALSE);
|
||||||
g_return_val_if_fail (addr != NULL, FALSE);
|
g_return_val_if_fail (host != NULL, FALSE);
|
||||||
|
|
||||||
decoder->fd = socket (PF_INET, SOCK_STREAM, 0);
|
/* look up name if we need to */
|
||||||
if (decoder->fd == -1) {
|
addr = g_inet_address_new_from_string (host);
|
||||||
GST_WARNING ("creating socket failed");
|
if (!addr) {
|
||||||
return FALSE;
|
GList *results;
|
||||||
|
|
||||||
|
resolver = g_resolver_get_default ();
|
||||||
|
|
||||||
|
results =
|
||||||
|
g_resolver_lookup_by_name (resolver, host, decoder->cancellable, &err);
|
||||||
|
if (!results)
|
||||||
|
goto name_resolve;
|
||||||
|
addr = G_INET_ADDRESS (g_object_ref (results->data));
|
||||||
|
|
||||||
|
g_resolver_free_addresses (results);
|
||||||
|
g_object_unref (resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.sin_family = AF_INET;
|
saddr = g_inet_socket_address_new (addr, port);
|
||||||
sa.sin_port = htons (port);
|
|
||||||
#ifndef G_OS_WIN32
|
decoder->socket =
|
||||||
inet_pton (AF_INET, addr, &sa.sin_addr);
|
g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM,
|
||||||
#else
|
G_SOCKET_PROTOCOL_TCP, &err);
|
||||||
sa.sin_addr.s_addr = inet_addr (addr);
|
|
||||||
#endif
|
if (!decoder->socket)
|
||||||
if (connect (decoder->fd, (struct sockaddr *) &sa,
|
goto no_socket;
|
||||||
sizeof (struct sockaddr)) == -1) {
|
|
||||||
close (decoder->fd);
|
GST_DEBUG ("opened receiving client socket");
|
||||||
decoder->fd = -1;
|
|
||||||
GST_WARNING ("connection failed");
|
if (!g_socket_connect (decoder->socket, saddr, decoder->cancellable, &err))
|
||||||
return FALSE;
|
goto connect_failed;
|
||||||
}
|
|
||||||
//rfb_decoder_use_file_descriptor (decoder, fd);
|
g_object_unref (saddr);
|
||||||
|
|
||||||
decoder->disconnected = FALSE;
|
decoder->disconnected = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
no_socket:
|
||||||
|
{
|
||||||
|
GST_ERROR ("Failed to create socket: %s", err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
|
g_object_unref (saddr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
name_resolve:
|
||||||
|
{
|
||||||
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||||
|
GST_DEBUG ("Cancelled name resolval");
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Failed to resolve host '%s': %s", host, err->message);
|
||||||
|
}
|
||||||
|
g_clear_error (&err);
|
||||||
|
g_object_unref (resolver);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
connect_failed:
|
||||||
|
{
|
||||||
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||||
|
GST_DEBUG ("Cancelled connecting");
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Failed to connect to host '%s:%d': %s", host, port,
|
||||||
|
err->message);
|
||||||
|
}
|
||||||
|
g_clear_error (&err);
|
||||||
|
g_object_unref (saddr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,7 +187,7 @@ gboolean
|
||||||
rfb_decoder_iterate (RfbDecoder * decoder)
|
rfb_decoder_iterate (RfbDecoder * decoder)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (decoder != NULL, FALSE);
|
g_return_val_if_fail (decoder != NULL, FALSE);
|
||||||
g_return_val_if_fail (decoder->fd != -1, FALSE);
|
g_return_val_if_fail (decoder->socket != NULL, FALSE);
|
||||||
|
|
||||||
if (decoder->state == NULL) {
|
if (decoder->state == NULL) {
|
||||||
GST_DEBUG ("First iteration: set state to -> wait for protocol version");
|
GST_DEBUG ("First iteration: set state to -> wait for protocol version");
|
||||||
|
@ -163,9 +202,10 @@ static guint8 *
|
||||||
rfb_decoder_read (RfbDecoder * decoder, guint32 len)
|
rfb_decoder_read (RfbDecoder * decoder, guint32 len)
|
||||||
{
|
{
|
||||||
guint32 total = 0;
|
guint32 total = 0;
|
||||||
guint32 now = 0;
|
gssize now = 0;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (decoder->fd > 0, NULL);
|
g_return_val_if_fail (decoder->socket != NULL, NULL);
|
||||||
g_return_val_if_fail (len > 0, NULL);
|
g_return_val_if_fail (len > 0, NULL);
|
||||||
|
|
||||||
if (G_UNLIKELY (len > decoder->data_len)) {
|
if (G_UNLIKELY (len > decoder->data_len)) {
|
||||||
|
@ -176,29 +216,58 @@ rfb_decoder_read (RfbDecoder * decoder, guint32 len)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (total < len) {
|
while (total < len) {
|
||||||
#ifndef G_OS_WIN32
|
now = g_socket_receive (decoder->socket, (gchar *) decoder->data + total,
|
||||||
now = recv (decoder->fd, decoder->data + total, len - total, 0);
|
len - total, decoder->cancellable, &err);
|
||||||
#else
|
|
||||||
now = recv (decoder->fd, (char *) decoder->data + total, len - total, 0);
|
if (now < 0)
|
||||||
#endif
|
goto recv_error;
|
||||||
if (now <= 0) {
|
|
||||||
decoder->disconnected = TRUE;
|
|
||||||
GST_WARNING ("rfb read error on socket");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
total += now;
|
total += now;
|
||||||
}
|
}
|
||||||
return decoder->data;
|
return decoder->data;
|
||||||
|
|
||||||
|
recv_error:
|
||||||
|
{
|
||||||
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||||
|
GST_DEBUG ("Read on socket cancelled");
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Read error on socket: %s", err->message);
|
||||||
|
}
|
||||||
|
g_clear_error (&err);
|
||||||
|
decoder->disconnected = TRUE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, guint len)
|
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, guint len)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (decoder->fd != 0, FALSE);
|
gssize now = 0;
|
||||||
g_return_val_if_fail (buffer != NULL, FALSE);
|
GError *err = NULL;
|
||||||
g_return_val_if_fail (len > 0, FALSE);
|
|
||||||
|
|
||||||
return write (decoder->fd, buffer, len);
|
g_return_val_if_fail (decoder->socket != NULL, 0);
|
||||||
|
g_return_val_if_fail (buffer != NULL, 0);
|
||||||
|
g_return_val_if_fail (len > 0, 0);
|
||||||
|
|
||||||
|
now = g_socket_send (decoder->socket, (gchar *) buffer, len,
|
||||||
|
decoder->cancellable, &err);
|
||||||
|
|
||||||
|
if (now < 0)
|
||||||
|
goto send_error;
|
||||||
|
|
||||||
|
done:
|
||||||
|
return now;
|
||||||
|
|
||||||
|
send_error:
|
||||||
|
{
|
||||||
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||||
|
GST_DEBUG ("Send on socket cancelled");
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Send error on socket: %s", err->message);
|
||||||
|
}
|
||||||
|
g_clear_error (&err);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -208,7 +277,7 @@ rfb_decoder_send_update_request (RfbDecoder * decoder,
|
||||||
guint8 data[10];
|
guint8 data[10];
|
||||||
|
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
g_return_if_fail (decoder->fd != -1);
|
g_return_if_fail (decoder->socket != NULL);
|
||||||
|
|
||||||
data[0] = 3;
|
data[0] = 3;
|
||||||
data[1] = incremental;
|
data[1] = incremental;
|
||||||
|
@ -234,7 +303,7 @@ rfb_decoder_send_key_event (RfbDecoder * decoder, guint key, gboolean down_flag)
|
||||||
guint8 data[8];
|
guint8 data[8];
|
||||||
|
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
g_return_if_fail (decoder->fd != -1);
|
g_return_if_fail (decoder->socket != NULL);
|
||||||
|
|
||||||
data[0] = 4;
|
data[0] = 4;
|
||||||
data[1] = down_flag;
|
data[1] = down_flag;
|
||||||
|
@ -251,7 +320,7 @@ rfb_decoder_send_pointer_event (RfbDecoder * decoder,
|
||||||
guint8 data[6];
|
guint8 data[6];
|
||||||
|
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
g_return_if_fail (decoder->fd != -1);
|
g_return_if_fail (decoder->socket != NULL);
|
||||||
|
|
||||||
data[0] = 5;
|
data[0] = 5;
|
||||||
data[1] = button_mask;
|
data[1] = button_mask;
|
||||||
|
@ -653,7 +722,7 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
decoder->n_rects--;
|
decoder->n_rects--;
|
||||||
if (decoder->n_rects == 0 || decoder->disconnected == TRUE) {
|
if (decoder->n_rects == 0 || decoder->disconnected) {
|
||||||
decoder->state = NULL;
|
decoder->state = NULL;
|
||||||
} else {
|
} else {
|
||||||
decoder->state = rfb_decoder_state_framebuffer_update_rectangle;
|
decoder->state = rfb_decoder_state_framebuffer_update_rectangle;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _LIBRFB_DECODER_H_
|
#ifndef _LIBRFB_DECODER_H_
|
||||||
#define _LIBRFB_DECODER_H_
|
#define _LIBRFB_DECODER_H_
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS enum
|
G_BEGIN_DECLS enum
|
||||||
|
@ -38,7 +40,8 @@ struct _RfbDecoder
|
||||||
|
|
||||||
gpointer buffer_handler_data;
|
gpointer buffer_handler_data;
|
||||||
|
|
||||||
gint fd;
|
GSocket *socket;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint32 data_len;
|
guint32 data_len;
|
||||||
|
@ -105,9 +108,8 @@ typedef struct _RfbRect
|
||||||
|
|
||||||
RfbDecoder *rfb_decoder_new (void);
|
RfbDecoder *rfb_decoder_new (void);
|
||||||
void rfb_decoder_free (RfbDecoder * decoder);
|
void rfb_decoder_free (RfbDecoder * decoder);
|
||||||
void rfb_decoder_use_file_descriptor (RfbDecoder * decoder, gint fd);
|
|
||||||
gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder,
|
gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder,
|
||||||
gchar * addr, guint port);
|
gchar * host, guint port);
|
||||||
gboolean rfb_decoder_iterate (RfbDecoder * decoder);
|
gboolean rfb_decoder_iterate (RfbDecoder * decoder);
|
||||||
void rfb_decoder_send_update_request (RfbDecoder * decoder,
|
void rfb_decoder_send_update_request (RfbDecoder * decoder,
|
||||||
gboolean incremental, gint x, gint y, gint width, gint height);
|
gboolean incremental, gint x, gint y, gint width, gint height);
|
||||||
|
|
Loading…
Reference in a new issue