summaryrefslogtreecommitdiff
path: root/gst/librfb
diff options
context:
space:
mode:
authorThijs Vermeir <thijsvermeir@gmail.com>2007-10-31 14:09:25 +0000
committerThijs Vermeir <thijsvermeir@gmail.com>2007-10-31 14:09:25 +0000
commitaac84ad1c721c8db84b729d2b265aa62c3f1b5c9 (patch)
treef8798f6df436f53f6c175d9233d9d9f62497194e /gst/librfb
parent1571bc2336eb4e35df921d6a80cc9d53e096e0c8 (diff)
gst/librfb/: Added copyrect encoding
Original commit message from CVS: * gst/librfb/d3des.h: * gst/librfb/gstrfbsrc.c: * gst/librfb/gstrfbsrc.h: * gst/librfb/rfbbuffer.h: * gst/librfb/rfbcontext.h: * gst/librfb/rfbdecoder.c: * gst/librfb/rfbdecoder.h: * gst/librfb/rfbutil.h: * gst/librfb/vncauth.h: Added copyrect encoding
Diffstat (limited to 'gst/librfb')
-rw-r--r--gst/librfb/d3des.h17
-rw-r--r--gst/librfb/gstrfbsrc.c59
-rw-r--r--gst/librfb/gstrfbsrc.h4
-rw-r--r--gst/librfb/rfbbuffer.h11
-rw-r--r--gst/librfb/rfbcontext.h5
-rw-r--r--gst/librfb/rfbdecoder.c110
-rw-r--r--gst/librfb/rfbdecoder.h59
-rw-r--r--gst/librfb/rfbutil.h5
-rw-r--r--gst/librfb/vncauth.h9
9 files changed, 156 insertions, 123 deletions
diff --git a/gst/librfb/d3des.h b/gst/librfb/d3des.h
index e647fc12c..7988eef35 100644
--- a/gst/librfb/d3des.h
+++ b/gst/librfb/d3des.h
@@ -19,28 +19,32 @@
* (GEnie : OUTER; CIS : [71755,204])
*/
-#define EN0 0 /* MODE == encrypt */
-#define DE1 1 /* MODE == decrypt */
+#define EN0 0 /* MODE == encrypt */
+#define DE1 1 /* MODE == decrypt */
+
+extern void deskey (unsigned char *, int);
-extern void deskey(unsigned char *, int);
/* hexkey[8] MODE
* Sets the internal key register according to the hexadecimal
* key contained in the 8 bytes of hexkey, according to the DES,
* for encryption or decryption according to MODE.
*/
-extern void usekey(unsigned long *);
+extern void usekey (unsigned long *);
+
/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/
-extern void cpkey(unsigned long *);
+extern void cpkey (unsigned long *);
+
/* cookedkey[32]
* Copies the contents of the internal key register into the storage
* located at &cookedkey[0].
*/
-extern void des(unsigned char *, unsigned char *);
+extern void des (unsigned char *, unsigned char *);
+
/* from[8] to[8]
* Encrypts/Decrypts (according to the key currently loaded in the
* internal key register) one block of eight bytes at address 'from'
@@ -49,4 +53,3 @@ extern void des(unsigned char *, unsigned char *);
/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
********************************************************************/
-
diff --git a/gst/librfb/gstrfbsrc.c b/gst/librfb/gstrfbsrc.c
index 626a5ff69..37757156a 100644
--- a/gst/librfb/gstrfbsrc.c
+++ b/gst/librfb/gstrfbsrc.c
@@ -84,8 +84,6 @@ static gboolean gst_rfb_src_stop (GstBaseSrc * bsrc);
static gboolean gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event);
static GstFlowReturn gst_rfb_src_create (GstPushSrc * psrc,
GstBuffer ** outbuf);
-static void gst_rfb_src_paint_rect (RfbDecoder * decoder, gint x, gint y,
- gint w, gint h, guint8 * data);
GST_BOILERPLATE (GstRfbSrc, gst_rfb_src, GstPushSrc, GST_TYPE_PUSH_SRC);
@@ -327,11 +325,16 @@ gst_rfb_src_start (GstBaseSrc * bsrc)
rfb_decoder_iterate (decoder);
}
+ decoder->rect_width =
+ (decoder->rect_width ? decoder->rect_width : decoder->width);
+ decoder->rect_height =
+ (decoder->rect_height ? decoder->rect_height : decoder->height);
+
g_object_set (bsrc, "blocksize",
src->decoder->width * src->decoder->height * (decoder->bpp / 8), NULL);
- src->frame = g_malloc (bsrc->blocksize);
- decoder->paint_rect = gst_rfb_src_paint_rect;
+ decoder->frame = g_malloc (bsrc->blocksize);
+ decoder->prev_frame = g_malloc (bsrc->blocksize);
decoder->decoder_private = src;
GST_DEBUG_OBJECT (src, "setting caps width to %d and height to %d",
@@ -356,9 +359,14 @@ gst_rfb_src_stop (GstBaseSrc * bsrc)
src->decoder->fd = -1;
- if (src->frame) {
- g_free (src->frame);
- src->frame = NULL;
+ if (src->decoder->frame) {
+ g_free (src->decoder->frame);
+ src->decoder->frame = NULL;
+ }
+
+ if (src->decoder->prev_frame) {
+ g_free (src->decoder->prev_frame);
+ src->decoder->prev_frame = NULL;
}
return TRUE;
@@ -373,13 +381,10 @@ gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
GstFlowReturn ret;
rfb_decoder_send_update_request (decoder, src->incremental_update,
- decoder->offset_x, decoder->offset_y,
- (decoder->rect_width ? decoder->rect_width : decoder->width),
- (decoder->rect_height ? decoder->rect_height : decoder->height));
- // src->inter = TRUE;
+ decoder->offset_x, decoder->offset_y, decoder->rect_width,
+ decoder->rect_height);
- src->go = TRUE;
- while (src->go) {
+ while (decoder->state != NULL) {
rfb_decoder_iterate (decoder);
}
@@ -394,7 +399,7 @@ gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
return GST_FLOW_ERROR;
}
- memcpy (GST_BUFFER_DATA (*outbuf), src->frame, newsize);
+ memcpy (GST_BUFFER_DATA (*outbuf), decoder->frame, newsize);
GST_BUFFER_SIZE (*outbuf) = newsize;
return GST_FLOW_OK;
@@ -449,32 +454,6 @@ gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event)
return TRUE;
}
-static void
-gst_rfb_src_paint_rect (RfbDecoder * decoder, gint start_x, gint start_y,
- gint rect_w, gint rect_h, guint8 * data)
-{
- gint pos_y;
- guint8 *frame;
- GstRfbSrc *src;
- gint width;
- guint32 src_offset;
- guint32 dst_offset;
-
- //printf ("painting %d,%d (%dx%d)\n", start_x, start_y, rect_w, rect_h);
- src = GST_RFB_SRC (decoder->decoder_private);
-
- frame = src->frame;
- width = decoder->width;
-
- for (pos_y = start_y; pos_y < (start_y + rect_h); pos_y++) {
- src_offset = (pos_y - start_y) * rect_w * decoder->bpp / 8;
- dst_offset = ((pos_y * width) + start_x) * decoder->bpp / 8;
- memcpy (frame + dst_offset, data + src_offset, rect_w * decoder->bpp / 8);
- }
-
- src->go = FALSE;
-}
-
static gboolean
plugin_init (GstPlugin * plugin)
{
diff --git a/gst/librfb/gstrfbsrc.h b/gst/librfb/gstrfbsrc.h
index 13f79287d..72af58cb7 100644
--- a/gst/librfb/gstrfbsrc.h
+++ b/gst/librfb/gstrfbsrc.h
@@ -27,7 +27,6 @@
#include <librfb/rfb.h>
G_BEGIN_DECLS
-
#define GST_TYPE_RFB_SRC \
(gst_rfb_src_get_type())
#define GST_RFB_SRC(obj) \
@@ -38,7 +37,6 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RFB_SRC))
#define GST_IS_RFB_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RFB_SRC))
-
typedef struct _GstRfbSrc GstRfbSrc;
typedef struct _GstRfbSrcClass GstRfbSrcClass;
@@ -55,7 +53,6 @@ struct _GstRfbSrc
gint port;
RfbDecoder *decoder;
- guint8 *frame;
gboolean go;
gboolean incremental_update;
@@ -70,5 +67,4 @@ struct _GstRfbSrc
GType gst_rfb_src_get_type (void);
G_END_DECLS
-
#endif
diff --git a/gst/librfb/rfbbuffer.h b/gst/librfb/rfbbuffer.h
index 5c09c77c7..6250ad463 100644
--- a/gst/librfb/rfbbuffer.h
+++ b/gst/librfb/rfbbuffer.h
@@ -3,10 +3,8 @@
#include <glib.h>
-G_BEGIN_DECLS
-
-typedef struct _RfbBuffer RfbBuffer;
-typedef void(*RfbBufferFreeFunc)(guint8 *data, gpointer priv);
+G_BEGIN_DECLS typedef struct _RfbBuffer RfbBuffer;
+typedef void (*RfbBufferFreeFunc) (guint8 * data, gpointer priv);
struct _RfbBuffer
{
@@ -17,10 +15,9 @@ struct _RfbBuffer
gint length;
};
-RfbBuffer *rfb_buffer_new (void);
+RfbBuffer *rfb_buffer_new (void);
RfbBuffer *rfb_buffer_new_and_alloc (gint len);
-void rfb_buffer_free (RfbBuffer *buffer);
+void rfb_buffer_free (RfbBuffer * buffer);
G_END_DECLS
-
#endif
diff --git a/gst/librfb/rfbcontext.h b/gst/librfb/rfbcontext.h
index fb41aa0c6..4c72bc653 100644
--- a/gst/librfb/rfbcontext.h
+++ b/gst/librfb/rfbcontext.h
@@ -3,9 +3,7 @@
#include <glib.h>
-G_BEGIN_DECLS
-
-typedef struct _RfbContext
+G_BEGIN_DECLS typedef struct _RfbContext
{
RfbConnection *connection;
@@ -34,5 +32,4 @@ typedef struct _RfbRect
} RfbRect;
G_END_DECLS
-
#endif
diff --git a/gst/librfb/rfbdecoder.c b/gst/librfb/rfbdecoder.c
index 85658bd4b..bd13569be 100644
--- a/gst/librfb/rfbdecoder.c
+++ b/gst/librfb/rfbdecoder.c
@@ -48,6 +48,10 @@ static gboolean rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder *
decoder);
static gboolean rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder);
static gboolean rfb_decoder_state_server_cut_text (RfbDecoder * decoder);
+static void rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x,
+ gint start_y, gint rect_w, gint rect_h);
+static void rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x,
+ gint start_y, gint rect_w, gint rect_h);
RfbDecoder *
rfb_decoder_new (void)
@@ -181,6 +185,12 @@ rfb_decoder_send_update_request (RfbDecoder * decoder,
RFB_SET_UINT16 (data + 8, height);
rfb_decoder_send (decoder, data, 10);
+
+ /* create a backup of the prev frame for copyrect encoding */
+ memcpy (decoder->prev_frame, decoder->frame,
+ decoder->rect_width * decoder->rect_height * decoder->bpp / 8);
+
+ decoder->state = rfb_decoder_state_normal;
}
void
@@ -388,18 +398,24 @@ rfb_decoder_state_security_result (RfbDecoder * decoder)
static gboolean
rfb_decoder_state_set_encodings (RfbDecoder * decoder)
{
- guint8 *buffer = g_malloc0 (8); // 4 + 4 * nr_of_encodings
+ guint8 *buffer = g_malloc0 (12); // 4 + 4 * nr_of_encodings
+
+ GST_DEBUG ("Sending encoding types to server");
buffer[0] = 2; // message-type
- buffer[3] = 1; // number of encodings
+ buffer[3] = 2; // number of encodings
/* RAW encoding (0) */
- rfb_decoder_send (decoder, buffer, 8);
+ /* CopyRect encoding (1) */
+ buffer[11] = 1;
+
+ rfb_decoder_send (decoder, buffer, 12);
g_free (buffer);
decoder->state = rfb_decoder_state_normal;
+ decoder->inited = TRUE;
return TRUE;
}
@@ -492,8 +508,6 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
}
decoder->state = rfb_decoder_state_set_encodings;
- decoder->inited = TRUE;
-
return TRUE;
}
@@ -503,11 +517,13 @@ rfb_decoder_state_normal (RfbDecoder * decoder)
guint8 *buffer;
gint message_type;
+ GST_DEBUG ("decoder_state_normal");
+
buffer = rfb_decoder_read (decoder, 1);
message_type = RFB_GET_UINT8 (buffer);
switch (message_type) {
- case 0:
+ case MESSAGE_TYPE_FRAMEBUFFER_UPDATE:
GST_DEBUG ("Receiving framebuffer update");
decoder->state = rfb_decoder_state_framebuffer_update;
break;
@@ -584,7 +600,6 @@ 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);
@@ -599,26 +614,85 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
GST_DEBUG ("w:%d h:%d", w, h);
GST_DEBUG ("encoding: %d", encoding);
- if (encoding != 0)
- g_critical ("unimplemented encoding\n");
-
+ switch (encoding) {
+ case ENCODING_TYPE_RAW:
+ rfb_decoder_raw_encoding (decoder, x, y, w, h);
+ break;
+ case ENCODING_TYPE_COPYRECT:
+ rfb_decoder_copyrect_encoding (decoder, x, y, w, h);
+ break;
+ default:
+ g_critical ("unimplemented encoding\n");
+ break;
+ }
g_free (buffer);
+ decoder->n_rects--;
+ if (decoder->n_rects == 0) {
+ decoder->state = NULL;
+ } else {
+ decoder->state = rfb_decoder_state_framebuffer_update_rectangle;
+ }
+ return TRUE;
+}
- size = w * h * decoder->bpp / 8;
+static void
+rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
+ gint rect_w, gint rect_h)
+{
+ gint pos_y, size;
+ guint8 *frame, *buffer;
+ gint width;
+ guint32 src_offset;
+ guint32 dst_offset;
+
+ /* read the data */
+ size = rect_h * rect_w * 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);
+ frame = decoder->frame;
+ width = decoder->rect_width;
+
+ for (pos_y = start_y; pos_y < (start_y + rect_h); pos_y++) {
+ src_offset = (pos_y - start_y) * rect_w * decoder->bpp / 8;
+ dst_offset = ((pos_y * width) + start_x) * decoder->bpp / 8;
+ memcpy (frame + dst_offset, buffer + src_offset, rect_w * decoder->bpp / 8);
}
g_free (buffer);
- decoder->n_rects--;
- if (decoder->n_rects == 0) {
- decoder->state = rfb_decoder_state_normal;
+}
+
+static void
+rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
+ gint rect_w, gint rect_h)
+{
+ guint16 src_x, src_y;
+ guint32 src_offset;
+ guint32 dst_offset;
+ gint pos_y, max_y, line_width, copyrect_width;
+ guint8 *buffer;
+
+ buffer = rfb_decoder_read (decoder, 4);
+ max_y = start_y + rect_h;
+
+ src_x = RFB_GET_UINT16 (buffer);
+ src_y = RFB_GET_UINT16 (buffer + 2);
+ GST_DEBUG ("Copyrect from %d %d", src_x, src_y);
+
+ dst_offset =
+ (((start_y - 1) * decoder->rect_width) + start_x) * decoder->bpp / 8;
+ src_offset = (((src_y - 1) * decoder->rect_width) + src_x) * decoder->bpp / 8;
+ line_width = decoder->rect_width * decoder->bpp / 8;
+ copyrect_width = rect_w * decoder->bpp / 8;
+
+ for (pos_y = start_y; pos_y < max_y; pos_y++) {
+ dst_offset += line_width;
+ src_offset += line_width;
+ memcpy (decoder->frame + dst_offset, decoder->prev_frame + src_offset,
+ copyrect_width);
}
- return TRUE;
+
+ g_free (buffer);
}
static gboolean
diff --git a/gst/librfb/rfbdecoder.h b/gst/librfb/rfbdecoder.h
index 5d7d983e9..8ec94bd2b 100644
--- a/gst/librfb/rfbdecoder.h
+++ b/gst/librfb/rfbdecoder.h
@@ -3,12 +3,11 @@
#include <glib.h>
-G_BEGIN_DECLS
-
-enum {
- SECURITY_FAIL = 0,
- SECURITY_NONE,
- SECURITY_VNC,
+G_BEGIN_DECLS enum
+{
+ SECURITY_FAIL = 0,
+ SECURITY_NONE,
+ SECURITY_VNC,
};
#define IS_VERSION(x, ma, mi) ((x->protocol_major == ma) && (x->protocol_minor == mi))
@@ -16,23 +15,25 @@ enum {
#define IS_VERSION_3_7(x) IS_VERSION(x, 3, 7)
#define IS_VERSION_3_8(x) IS_VERSION(x, 3, 8)
+#define MESSAGE_TYPE_FRAMEBUFFER_UPDATE 0
+
+#define ENCODING_TYPE_RAW 0
+#define ENCODING_TYPE_COPYRECT 1
+
typedef struct _RfbDecoder RfbDecoder;
struct _RfbDecoder
{
/* callbacks */
- gint (*send_data) (guint8 *buffer, gint length, gpointer user_data);
- void (*paint_rect) (RfbDecoder *decoder, gint x, gint y, gint w, gint h,
- guint8 *data);
- void (*copy_rect) (RfbDecoder *decoder, gint x, gint y, gint w, gint h,
- gint src_x, gint src_y);
- gboolean (*state) (RfbDecoder *decoder);
+ gboolean (*state) (RfbDecoder * decoder);
gpointer buffer_handler_data;
gint fd;
gpointer decoder_private;
+ guint8 *frame;
+ guint8 *prev_frame;
/* settable properties */
gboolean shared_flag;
@@ -85,28 +86,18 @@ typedef struct _RfbRect
} RfbRect;
#endif
-RfbDecoder *rfb_decoder_new (void);
-void rfb_decoder_free (RfbDecoder * decoder);
-void rfb_decoder_use_file_descriptor (RfbDecoder * decoder,
- gint fd);
-gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder,
- gchar * addr,
- guint port);
-gboolean rfb_decoder_iterate (RfbDecoder * decoder);
-void rfb_decoder_send_update_request (RfbDecoder * decoder,
- gboolean incremental,
- gint x,
- gint y,
- gint width,
- gint height);
-void rfb_decoder_send_key_event (RfbDecoder * decoder,
- guint key,
- gboolean down_flag);
-void rfb_decoder_send_pointer_event (RfbDecoder * decoder,
- gint button_mask,
- gint x,
- gint y);
+RfbDecoder *rfb_decoder_new (void);
+void rfb_decoder_free (RfbDecoder * decoder);
+void rfb_decoder_use_file_descriptor (RfbDecoder * decoder, gint fd);
+gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder,
+ gchar * addr, guint port);
+gboolean rfb_decoder_iterate (RfbDecoder * decoder);
+void rfb_decoder_send_update_request (RfbDecoder * decoder,
+ gboolean incremental, gint x, gint y, gint width, gint height);
+void rfb_decoder_send_key_event (RfbDecoder * decoder,
+ guint key, gboolean down_flag);
+void rfb_decoder_send_pointer_event (RfbDecoder * decoder,
+ gint button_mask, gint x, gint y);
G_END_DECLS
-
#endif
diff --git a/gst/librfb/rfbutil.h b/gst/librfb/rfbutil.h
index c816bcd4b..b1ac9462b 100644
--- a/gst/librfb/rfbutil.h
+++ b/gst/librfb/rfbutil.h
@@ -3,8 +3,5 @@
#include <glib.h>
-G_BEGIN_DECLS
-
-G_END_DECLS
-
+G_BEGIN_DECLS G_END_DECLS
#endif
diff --git a/gst/librfb/vncauth.h b/gst/librfb/vncauth.h
index 2a4deaebc..6420dbc8d 100644
--- a/gst/librfb/vncauth.h
+++ b/gst/librfb/vncauth.h
@@ -24,8 +24,7 @@
#define MAXPWLEN 8
#define CHALLENGESIZE 16
-extern int vncEncryptAndStorePasswd(char *passwd, char *fname);
-extern char *vncDecryptPasswdFromFile(char *fname);
-extern void vncRandomBytes(unsigned char *bytes);
-extern void vncEncryptBytes(unsigned char *bytes, char *passwd);
-
+extern int vncEncryptAndStorePasswd (char *passwd, char *fname);
+extern char *vncDecryptPasswdFromFile (char *fname);
+extern void vncRandomBytes (unsigned char *bytes);
+extern void vncEncryptBytes (unsigned char *bytes, char *passwd);