Port librfb to 0.10 (#376106).
authorAndre Moreira Magalhaes <andrunko@gmail.com>
Fri, 17 Nov 2006 03:15:40 +0000 (03:15 +0000)
committerDavid Schleef <ds@schleef.org>
Fri, 17 Nov 2006 03:15:40 +0000 (03:15 +0000)
Original commit message from CVS:
Patch by: Andre Moreira Magalhaes <andrunko@gmail.com>
* configure.ac:
* gst/librfb/Makefile.am:
* gst/librfb/gstrfbsrc.c:
* gst/librfb/rfb.c:
* gst/librfb/rfb.h:
* gst/librfb/rfbbuffer.c:
* gst/librfb/rfbbuffer.h:
* gst/librfb/rfbbytestream.c:
* gst/librfb/rfbbytestream.h:
* gst/librfb/rfbcontext.h:
* gst/librfb/rfbdecoder.c:
* gst/librfb/rfbdecoder.h:
* gst/librfb/rfbutil.h:
Port librfb to 0.10 (#376106).

14 files changed:
ChangeLog
configure.ac
gst/librfb/Makefile.am
gst/librfb/gstrfbsrc.c
gst/librfb/rfb.c
gst/librfb/rfb.h
gst/librfb/rfbbuffer.c
gst/librfb/rfbbuffer.h
gst/librfb/rfbbytestream.c
gst/librfb/rfbbytestream.h
gst/librfb/rfbcontext.h
gst/librfb/rfbdecoder.c
gst/librfb/rfbdecoder.h
gst/librfb/rfbutil.h

index 1a45fc6..823908e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-11-16  David Schleef  <ds@schleef.org>
+
+       Patch by: Andre Moreira Magalhaes <andrunko@gmail.com>
+
+       * configure.ac:
+       * gst/librfb/Makefile.am:
+       * gst/librfb/gstrfbsrc.c:
+       * gst/librfb/rfb.c:
+       * gst/librfb/rfb.h:
+       * gst/librfb/rfbbuffer.c:
+       * gst/librfb/rfbbuffer.h:
+       * gst/librfb/rfbbytestream.c:
+       * gst/librfb/rfbbytestream.h:
+       * gst/librfb/rfbcontext.h:
+       * gst/librfb/rfbdecoder.c:
+       * gst/librfb/rfbdecoder.h:
+       * gst/librfb/rfbutil.h:
+         Port librfb to 0.10 (#376106).
+
 2006-11-16  Tim-Philipp Müller  <tim at centricular dot net>
 
        * ext/spc/gstspc.c: (spc_play):
index b41c05a..3a1b63d 100644 (file)
@@ -81,6 +81,7 @@ GST_PLUGINS_ALL="\
   filter \
   freeze \
   h264parse \
+  librfb \
   nuvdemux \
   modplug \
   multifile \
@@ -807,6 +808,7 @@ gst/deinterlace/Makefile
 gst/filter/Makefile
 gst/freeze/Makefile
 gst/h264parse/Makefile
+gst/librfb/Makefile
 gst/modplug/Makefile
 gst/nuvdemux/Makefile
 gst/modplug/libmodplug/Makefile
index 7c80112..b93291d 100644 (file)
@@ -1,4 +1,3 @@
-
 # please keep librfb easily extractable
 
 noinst_LTLIBRARIES = librfb.la
@@ -6,26 +5,21 @@ plugin_LTLIBRARIES = libgstrfbsrc.la
 
 libgstrfbsrc_la_SOURCES = gstrfbsrc.c
 libgstrfbsrc_la_CFLAGS = $(GST_CFLAGS) -I$(srcdir)/..
-libgstrfbsrc_la_LIBADD = librfb.la
+libgstrfbsrc_la_LIBADD = $(GST_BASE_LIBS) librfb.la
 libgstrfbsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
+librfb_la_SOURCES = \
+       rfbbuffer.c \
+       rfbdecoder.c \
+       rfbbytestream.c
+librfb_la_CFLAGS = $(GST_CFLAGS) -I$(srcdir)/..
+librfb_la_LIBADD = $(GLIB_LIBS)
 
 noinst_HEADERS = \
        rfb.h \
        rfbdecoder.h \
        rfbbuffer.h \
-       rfbbytestream.h
-
-librfb_la_SOURCES = \
-       rfb.h \
-       rfbdecoder.c \
-       rfbdecoder.h \
-       rfbbuffer.c \
-       rfbbuffer.h \
-       rfbbytestream.c \
        rfbbytestream.h \
-       gstrfbsrc.c
-
-librfb_la_CFLAGS = $(GST_CFLAGS) -I$(srcdir)/..
-librfb_la_LIBADD = $(GLIB_LIBS)
-
+       rfbcontext.h \
+       rfbutil.h \
+       gstrfbsrc.h
index 85dfe35..66214f1 100644 (file)
@@ -1,4 +1,5 @@
 /* GStreamer
+ * Copyright (C) <2006> Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
  * Copyright (C) <2004> David A. Schleef <ds@schleef.org>
  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
  *
 #include "config.h"
 #endif
 
-#include <gst/gst.h>
+#include "gstrfbsrc.h"
+
 #include <gst/video/video.h>
 
 #include <string.h>
 #include <stdlib.h>
 
-#include <librfb/rfb.h>
-
-
-#define GST_TYPE_RFBSRC \
-  (gst_rfbsrc_get_type())
-#define GST_RFBSRC(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RFBSRC,GstRfbsrc))
-#define GST_RFBSRC_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RFBSRC,GstRfbsrc))
-#define GST_IS_RFBSRC(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RFBSRC))
-#define GST_IS_RFBSRC_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RFBSRC))
-
-typedef struct _GstRfbsrc GstRfbsrc;
-typedef struct _GstRfbsrcClass GstRfbsrcClass;
-
-struct _GstRfbsrc
-{
-  GstElement element;
-
-  GstPad *srcpad;
-
-  RfbDecoder *decoder;
-
-  char *server;
-  int port;
-
-  guint8 *frame;
-  gboolean go;
-  gboolean inter;
-
-  unsigned int button_mask;
-
-  double framerate;
-};
-
-struct _GstRfbsrcClass
-{
-  GstElementClass parent_class;
-};
-
-GType gst_rfbsrc_get_type (void);
-
-
-static const GstElementDetails rfbsrc_details =
-GST_ELEMENT_DETAILS ("Video test source",
-    "Source/Video",
-    "Creates a test video stream",
-    "David A. Schleef <ds@schleef.org>");
-
-/* GstRfbsrc signals and args */
-enum
-{
-  /* FILL ME */
-  LAST_SIGNAL
-};
-
 enum
 {
   ARG_0,
-  ARG_SERVER,
+  ARG_HOST,
   ARG_PORT,
-  /* FILL ME */
 };
 
-static void gst_rfbsrc_base_init (gpointer g_class);
-static void gst_rfbsrc_class_init (GstRfbsrcClass * klass);
-static void gst_rfbsrc_init (GstRfbsrc * rfbsrc);
-static GstStateChangeReturn gst_rfbsrc_change_state (GstElement * element);
-
-static void gst_rfbsrc_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_rfbsrc_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static GstData *gst_rfbsrc_get (GstPad * pad);
-
-static const GstQueryType *gst_rfbsrc_get_query_types (GstPad * pad);
-static gboolean gst_rfbsrc_src_query (GstPad * pad,
-    GstQueryType type, GstFormat * format, gint64 * value);
-static void gst_rfbsrc_paint_rect (RfbDecoder * decoder, int x, int y,
-    int w, int h, guint8 * data);
-static gboolean gst_rfbsrc_handle_src_event (GstPad * pad, GstEvent * event);
-
-static GstCaps *gst_rfbsrc_getcaps (GstPad * pad);
-static GstPadLinkReturn gst_rfbsrc_link (GstPad * pad, const GstCaps * caps);
-static GstCaps *gst_rfbsrc_fixate (GstPad * pad, const GstCaps * caps);
+#define RGB332_R(x)  ((((x)&0x07) * 0x124)>>3)
+#define RGB332_G(x)  ((((x)&0x38) * 0x124)>>6)
+#define RGB332_B(x)  ((((x)&0xc0) * 0x149)>>8)
 
-static GstElementClass *parent_class = NULL;
+GST_DEBUG_CATEGORY_STATIC (rfbsrc_debug);
+#define GST_CAT_DEFAULT rfbsrc_debug
 
+static const GstElementDetails gst_rfb_src_details =
+GST_ELEMENT_DETAILS ("Rfb source",
+    "Source/Video",
+    "Creates a rfb video stream",
+    "David A. Schleef <ds@schleef.org>, "
+    "Andre Moreira Magalhaes <andre.magalhaes@indt.org.br");
 
-static GstStaticPadTemplate gst_rfbsrc_src_template =
+static GstStaticPadTemplate gst_rfb_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("video/x-raw-rgb, "
         "bpp = (int) 32, "
         "depth = (int) 24, "
-        "endianness = (int) BIG_ENDIAN, "
+        "endianness = (int) 4321, "
         "red_mask = (int) 0x0000ff00, "
         "green_mask = (int) 0x00ff0000, "
         "blue_mask = (int) 0xff000000, "
-        "width = [ 16, 4096 ], "
-        "height = [ 16, 4096 ], " "framerate = [ 1.0, 60.0] ")
+        "width = (int) [ 16, 4096 ], "
+        "height = (int) [ 16, 4096 ], " "framerate = (fraction) 30/1")
     );
 
-GType
-gst_rfbsrc_get_type (void)
-{
-  static GType rfbsrc_type = 0;
-
-  if (!rfbsrc_type) {
-    static const GTypeInfo rfbsrc_info = {
-      sizeof (GstRfbsrcClass),
-      gst_rfbsrc_base_init,
-      NULL,
-      (GClassInitFunc) gst_rfbsrc_class_init,
-      NULL,
-      NULL,
-      sizeof (GstRfbsrc),
-      0,
-      (GInstanceInitFunc) gst_rfbsrc_init,
-    };
-
-    rfbsrc_type =
-        g_type_register_static (GST_TYPE_ELEMENT, "GstRfbsrc", &rfbsrc_info, 0);
-  }
-  return rfbsrc_type;
-}
+static void gst_rfb_src_base_init (gpointer g_class);
+static void gst_rfb_src_class_init (GstRfbSrcClass * klass);
+static void gst_rfb_src_dispose (GObject * object);
+static void gst_rfb_src_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_rfb_src_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static gboolean gst_rfb_src_start (GstBaseSrc * bsrc);
+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);
 
 static void
-gst_rfbsrc_base_init (gpointer g_class)
+gst_rfb_src_base_init (gpointer g_class)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
 
-  gst_element_class_set_details (element_class, &rfbsrc_details);
-
   gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_rfbsrc_src_template));
+      gst_static_pad_template_get (&gst_rfb_src_template));
+
+  gst_element_class_set_details (element_class, &gst_rfb_src_details);
 }
 
 static void
-gst_rfbsrc_class_init (GstRfbsrcClass * klass)
+gst_rfb_src_class_init (GstRfbSrcClass * klass)
 {
   GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
+  GstBaseSrcClass *gstbasesrc_class;
+  GstPushSrcClass *gstpushsrc_class;
 
   gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
-
-#if 0
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WIDTH,
-      g_param_spec_int ("width", "width", "Default width",
-          1, G_MAXINT, 320, G_PARAM_READWRITE));
-#endif
+  gstbasesrc_class = (GstBaseSrcClass *) klass;
+  gstpushsrc_class = (GstPushSrcClass *) klass;
 
-  parent_class = g_type_class_peek_parent (klass);
+  gobject_class->dispose = gst_rfb_src_dispose;
+  gobject_class->set_property = gst_rfb_src_set_property;
+  gobject_class->get_property = gst_rfb_src_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_SERVER,
-      g_param_spec_string ("server", "Server", "Server",
+  g_object_class_install_property (gobject_class, ARG_HOST,
+      g_param_spec_string ("host", "Host to connect to", "Host to connect to",
           "127.0.0.1", G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class, ARG_PORT,
       g_param_spec_int ("port", "Port", "Port",
           1, 65535, 5900, G_PARAM_READWRITE));
 
-  gobject_class->set_property = gst_rfbsrc_set_property;
-  gobject_class->get_property = gst_rfbsrc_get_property;
+  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_rfb_src_start);
+  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_rfb_src_stop);
+  gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_rfb_src_event);
+  gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_rfb_src_create);
 
-  gstelement_class->change_state = gst_rfbsrc_change_state;
+  GST_DEBUG_CATEGORY_INIT (rfbsrc_debug, "rfbsrc", 0, "Rfb source");
 }
 
-static GstStateChangeReturn
-gst_rfbsrc_change_state (GstElement * element, GstStateChange transition)
+static void
+gst_rfb_src_init (GstRfbSrc * src, GstRfbSrcClass * klass)
 {
-  GstRfbsrc *rfbsrc;
+  GstBaseSrc *bsrc = GST_BASE_SRC (src);
 
-  rfbsrc = GST_RFBSRC (element);
+  gst_pad_use_fixed_caps (GST_BASE_SRC_PAD (bsrc));
+  gst_base_src_set_live (bsrc, TRUE);
+  gst_base_src_set_format (bsrc, GST_FORMAT_TIME);
 
-  switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      rfbsrc->decoder = rfb_decoder_new ();
-      rfb_decoder_connect_tcp (rfbsrc->decoder, rfbsrc->server, rfbsrc->port);
-      rfbsrc->decoder->paint_rect = gst_rfbsrc_paint_rect;
-      rfbsrc->decoder->decoder_private = rfbsrc;
-      break;
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      break;
-    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+  src->host = g_strdup ("127.0.0.1");
+  src->port = 5900;
+}
+
+static void
+gst_rfb_src_dispose (GObject * object)
+{
+  GstRfbSrc *src = GST_RFB_SRC (object);
+
+  g_free (src->host);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_rfb_src_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRfbSrc *src = GST_RFB_SRC (object);
+
+  switch (prop_id) {
+    case ARG_HOST:
+      src->host = g_strdup (g_value_get_string (value));
       break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      //rfbsrc->timestamp_offset = 0;
-      //rfbsrc->n_frames = 0;
+    case ARG_PORT:
+      src->port = g_value_get_int (value);
       break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      if (rfbsrc->frame) {
-        g_free (rfbsrc->frame);
-        rfbsrc->frame = NULL;
-      }
+    default:
       break;
   }
-
-  return parent_class->change_state (element, transition);
 }
 
 static void
-gst_rfbsrc_init (GstRfbsrc * rfbsrc)
+gst_rfb_src_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
 {
-  GST_DEBUG ("gst_rfbsrc_init");
-
-  rfbsrc->srcpad =
-      gst_pad_new_from_template (gst_static_pad_template_get
-      (&gst_rfbsrc_src_template), "src");
-  gst_element_add_pad (GST_ELEMENT (rfbsrc), rfbsrc->srcpad);
-  gst_pad_set_getcaps_function (rfbsrc->srcpad, gst_rfbsrc_getcaps);
-  gst_pad_set_link_function (rfbsrc->srcpad, gst_rfbsrc_link);
-  gst_pad_set_fixate_function (rfbsrc->srcpad, gst_rfbsrc_fixate);
-  gst_pad_set_get_function (rfbsrc->srcpad, gst_rfbsrc_get);
-  gst_pad_set_query_function (rfbsrc->srcpad, gst_rfbsrc_src_query);
-  gst_pad_set_query_type_function (rfbsrc->srcpad, gst_rfbsrc_get_query_types);
-  gst_pad_set_event_function (rfbsrc->srcpad, gst_rfbsrc_handle_src_event);
-
-  rfbsrc->server = g_strdup ("127.0.0.1");
-  rfbsrc->port = 5900;
+  GstRfbSrc *src = GST_RFB_SRC (object);
+
+  switch (prop_id) {
+    case ARG_HOST:
+      g_value_set_string (value, src->host);
+      break;
+    case ARG_PORT:
+      g_value_set_int (value, src->port);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
 }
 
-static GstCaps *
-gst_rfbsrc_getcaps (GstPad * pad)
+static gboolean
+gst_rfb_src_start (GstBaseSrc * bsrc)
 {
-  GstRfbsrc *rfbsrc;
+  GstRfbSrc *src = GST_RFB_SRC (bsrc);
+  RfbDecoder *decoder;
   GstCaps *caps;
 
-  rfbsrc = GST_RFBSRC (gst_pad_get_parent (pad));
+  decoder = rfb_decoder_new ();
 
-  caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
-
-  if (rfbsrc->decoder && rfbsrc->decoder->inited) {
-    gst_caps_set_simple (caps,
-        "width", G_TYPE_INT, rfbsrc->decoder->width,
-        "height", G_TYPE_INT, rfbsrc->decoder->height, NULL);
+  GST_DEBUG_OBJECT (src, "connecting to host %s on port %d",
+      src->host, src->port);
+  if (!rfb_decoder_connect_tcp (decoder, src->host, src->port)) {
+    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
+        ("Could not connect to host %s on port %d", src->host, src->port));
+    rfb_decoder_free (decoder);
+    return FALSE;
   }
 
-  return caps;
-}
+  src->decoder = decoder;
+  src->inter = FALSE;
 
-static GstCaps *
-gst_rfbsrc_fixate (GstPad * pad, const GstCaps * caps)
-{
-  GstStructure *structure;
-  GstCaps *newcaps;
+  while (!decoder->inited) {
+    rfb_decoder_iterate (decoder);
+  }
 
-  if (gst_caps_get_size (caps) > 1)
-    return NULL;
+  g_object_set (bsrc, "blocksize",
+      src->decoder->width * src->decoder->height * 4, NULL);
 
-  newcaps = gst_caps_copy (caps);
-  structure = gst_caps_get_structure (newcaps, 0);
+  src->frame = g_malloc (bsrc->blocksize);
+  decoder->paint_rect = gst_rfb_src_paint_rect;
+  decoder->decoder_private = src;
 
-  if (gst_structure_fixate_field_nearest_double (structure, "framerate", 30.0)) {
-    return newcaps;
-  }
+  GST_DEBUG_OBJECT (src, "setting caps width to %d and height to %d",
+      decoder->width, decoder->height);
+
+  caps =
+      gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc)));
+  gst_caps_set_simple (caps, "width", G_TYPE_INT, decoder->width, "height",
+      G_TYPE_INT, decoder->height, NULL);
+  gst_pad_set_caps (GST_BASE_SRC_PAD (bsrc), caps);
+  gst_caps_unref (caps);
 
-  gst_caps_free (newcaps);
-  return NULL;
+  return TRUE;
 }
 
-static GstPadLinkReturn
-gst_rfbsrc_link (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_rfb_src_stop (GstBaseSrc * bsrc)
 {
-  GstRfbsrc *rfbsrc;
-  GstStructure *structure;
+  GstRfbSrc *src = GST_RFB_SRC (bsrc);
 
-  rfbsrc = GST_RFBSRC (gst_pad_get_parent (pad));
+  rfb_decoder_free (src->decoder);
 
-  structure = gst_caps_get_structure (caps, 0);
-
-  gst_structure_get_double (structure, "framerate", &rfbsrc->framerate);
+  if (src->frame) {
+    g_free (src->frame);
+    src->frame = NULL;
+  }
 
-  return GST_PAD_LINK_OK;
+  return TRUE;
 }
 
-static const GstQueryType *
-gst_rfbsrc_get_query_types (GstPad * pad)
+static GstFlowReturn
+gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
 {
-  static const GstQueryType query_types[] = {
-    GST_QUERY_POSITION,
-    0,
-  };
+  GstRfbSrc *src = GST_RFB_SRC (psrc);
+  RfbDecoder *decoder = src->decoder;
+  gulong newsize;
+  GstFlowReturn ret;
 
-  return query_types;
-}
+  rfb_decoder_send_update_request (decoder, src->inter, 0, 0,
+      decoder->width, decoder->height);
+  // src->inter = TRUE;
 
-static gboolean
-gst_rfbsrc_src_query (GstPad * pad,
-    GstQueryType type, GstFormat * format, gint64 * value)
-{
-  gboolean res = FALSE;
-
-  //GstRfbsrc *rfbsrc = GST_RFBSRC (gst_pad_get_parent (pad));
-
-  switch (type) {
-    case GST_QUERY_POSITION:
-      switch (*format) {
-        case GST_FORMAT_TIME:
-          //*value = rfbsrc->n_frames * GST_SECOND / (double) rfbsrc->rate;
-          res = TRUE;
-          break;
-        case GST_FORMAT_DEFAULT:       /* frames */
-          //*value = rfbsrc->n_frames;
-          res = TRUE;
-          break;
-        default:
-          break;
-      }
-      break;
-    default:
-      break;
+  src->go = TRUE;
+  while (src->go) {
+    rfb_decoder_iterate (decoder);
   }
 
-  return res;
+  newsize = GST_BASE_SRC (psrc)->blocksize;
+
+  /* Create the buffer. */
+  ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
+      GST_BUFFER_OFFSET_NONE, newsize,
+      GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf);
+
+  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
+    return GST_FLOW_ERROR;
+  }
+
+  memcpy (GST_BUFFER_DATA (*outbuf), src->frame, newsize);
+  GST_BUFFER_SIZE (*outbuf) = newsize;
+
+  return GST_FLOW_OK;
 }
 
 static gboolean
-gst_rfbsrc_handle_src_event (GstPad * pad, GstEvent * event)
+gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event)
 {
-  GstRfbsrc *rfbsrc;
-  double x, y;
-  int button;
+  GstRfbSrc *src = GST_RFB_SRC (bsrc);
+  gdouble x, y;
+  gint button;
   GstStructure *structure;
-  const char *event_type;
-
-  rfbsrc = GST_RFBSRC (gst_pad_get_parent (pad));
+  const gchar *event_type;
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_NAVIGATION:
-      structure = event->event_data.structure.structure;
+      structure = event->structure;
       event_type = gst_structure_get_string (structure, "event");
       gst_structure_get_double (structure, "pointer_x", &x);
       gst_structure_get_double (structure, "pointer_y", &y);
       button = 0;
 
       if (strcmp (event_type, "key-press") == 0) {
-        const char *key = gst_structure_get_string (structure, "key");
+        const gchar *key = gst_structure_get_string (structure, "key");
 
-        rfb_decoder_send_key_event (rfbsrc->decoder, key[0], 1);
-        rfb_decoder_send_key_event (rfbsrc->decoder, key[0], 0);
+        GST_LOG_OBJECT (src, "sending key event for key %d", key[0]);
+        rfb_decoder_send_key_event (src->decoder, key[0], 1);
+        rfb_decoder_send_key_event (src->decoder, key[0], 0);
       } else if (strcmp (event_type, "mouse-move") == 0) {
-        rfb_decoder_send_pointer_event (rfbsrc->decoder, rfbsrc->button_mask,
-            (int) x, (int) y);
+        GST_LOG_OBJECT (src, "sending mouse-move event "
+            "button_mask=%d, x=%d, y=%d", src->button_mask, (gint) x, (gint) y);
+        rfb_decoder_send_pointer_event (src->decoder, src->button_mask,
+            (gint) x, (gint) y);
       } else if (strcmp (event_type, "mouse-button-release") == 0) {
-        rfbsrc->button_mask &= ~(1 << button);
-        rfb_decoder_send_pointer_event (rfbsrc->decoder, rfbsrc->button_mask,
-            (int) x, (int) y);
+        src->button_mask &= ~(1 << button);
+        GST_LOG_OBJECT (src, "sending mouse-button-release event "
+            "button_mask=%d, x=%d, y=%d", src->button_mask, (gint) x, (gint) y);
+        rfb_decoder_send_pointer_event (src->decoder, src->button_mask,
+            (gint) x, (gint) y);
       } else if (strcmp (event_type, "mouse-button-press") == 0) {
-        rfbsrc->button_mask |= (1 << button);
-        rfb_decoder_send_pointer_event (rfbsrc->decoder, rfbsrc->button_mask,
-            (int) x, (int) y);
+        src->button_mask |= (1 << button);
+        GST_LOG_OBJECT (src, "sending mouse-button-press event "
+            "button_mask=%d, x=%d, y=%d", src->button_mask, (gint) x, (gint) y);
+        rfb_decoder_send_pointer_event (src->decoder, src->button_mask,
+            (gint) x, (gint) y);
       }
       break;
     default:
@@ -396,28 +329,25 @@ gst_rfbsrc_handle_src_event (GstPad * pad, GstEvent * event)
 }
 
 static void
-gst_rfbsrc_paint_rect (RfbDecoder * decoder, int x, int y, int w, int h,
+gst_rfb_src_paint_rect (RfbDecoder * decoder, gint x, gint y, gint w, gint h,
     guint8 * data)
 {
-  int i, j;
+  gint i, j;
   guint8 *frame;
   guint8 color;
-  GstRfbsrc *rfbsrc;
-  int width;
-  int offset;
+  GstRfbSrc *src;
+  gint width;
+  gint offset;
 
-  GST_DEBUG ("painting %d,%d (%dx%d)\n", x, y, w, h);
-  rfbsrc = GST_RFBSRC (decoder->decoder_private);
+  // GST_DEBUG ("painting %d,%d (%dx%d)\n", x, y, w, h);
+  src = GST_RFB_SRC (decoder->decoder_private);
 
-  frame = rfbsrc->frame;
+  frame = src->frame;
   width = decoder->width;
   for (j = 0; j < h; j++) {
     for (i = 0; i < w; i++) {
       color = data[j * w + i];
 
-#define RGB332_R(x)  ((((x)&0x07) * 0x124)>>3)
-#define RGB332_G(x)  ((((x)&0x38) * 0x124)>>6)
-#define RGB332_B(x)  ((((x)&0xc0) * 0x149)>>8)
       offset = ((j + x) * width + (i + x)) * 4;
       frame[offset + 0] = RGB332_B (color);
       frame[offset + 1] = RGB332_G (color);
@@ -426,116 +356,14 @@ gst_rfbsrc_paint_rect (RfbDecoder * decoder, int x, int y, int w, int h,
     }
   }
 
-  rfbsrc->go = FALSE;
+  src->go = FALSE;
 }
 
-static GstData *
-gst_rfbsrc_get (GstPad * pad)
-{
-  GstRfbsrc *rfbsrc;
-  gulong newsize;
-  GstBuffer *buf;
-  RfbDecoder *decoder;
-
-  GST_DEBUG ("gst_rfbsrc_get");
-
-  g_return_val_if_fail (pad != NULL, NULL);
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  rfbsrc = GST_RFBSRC (gst_pad_get_parent (pad));
-  decoder = rfbsrc->decoder;
-
-  if (!decoder->inited) {
-    while (!decoder->inited) {
-      rfb_decoder_iterate (decoder);
-    }
-
-    gst_pad_renegotiate (rfbsrc->srcpad);
-
-    if (rfbsrc->frame)
-      g_free (rfbsrc->frame);
-    rfbsrc->frame = g_malloc (decoder->width * decoder->height * 4);
-
-    GST_DEBUG ("red_mask = %08x\n", decoder->red_max << decoder->red_shift);
-    GST_DEBUG ("green_mask = %08x\n",
-        decoder->green_max << decoder->green_shift);
-    GST_DEBUG ("blue_mask = %08x\n", decoder->blue_max << decoder->blue_shift);
-    rfbsrc->inter = FALSE;
-  }
-
-  rfb_decoder_send_update_request (decoder, rfbsrc->inter, 0, 0, decoder->width,
-      decoder->height);
-  //rfbsrc->inter = TRUE;
-
-  rfbsrc->go = TRUE;
-  while (rfbsrc->go) {
-    rfb_decoder_iterate (decoder);
-    GST_DEBUG ("iterate...\n");
-  }
-
-  newsize = decoder->width * decoder->height * 4;
-  g_return_val_if_fail (newsize > 0, NULL);
-
-  GST_DEBUG ("size=%ld %dx%d", newsize, decoder->width, decoder->height);
-
-  buf = gst_buffer_new_and_alloc (newsize);
-  g_return_val_if_fail (GST_BUFFER_DATA (buf) != NULL, NULL);
-
-  memcpy (GST_BUFFER_DATA (buf), rfbsrc->frame, newsize);
-
-  return GST_DATA (buf);
-}
-
-static void
-gst_rfbsrc_set_property (GObject * object, guint prop_id, const GValue * value,
-    GParamSpec * pspec)
-{
-  GstRfbsrc *src;
-
-  g_return_if_fail (GST_IS_RFBSRC (object));
-  src = GST_RFBSRC (object);
-
-  GST_DEBUG ("gst_rfbsrc_set_property");
-  switch (prop_id) {
-    case ARG_SERVER:
-      src->server = g_strdup (g_value_get_string (value));
-      break;
-    case ARG_PORT:
-      src->port = g_value_get_int (value);
-      break;
-    default:
-      break;
-  }
-}
-
-static void
-gst_rfbsrc_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
-{
-  GstRfbsrc *src;
-
-  g_return_if_fail (GST_IS_RFBSRC (object));
-  src = GST_RFBSRC (object);
-
-  switch (prop_id) {
-    case ARG_SERVER:
-      g_value_set_string (value, src->server);
-      break;
-    case ARG_PORT:
-      g_value_set_int (value, src->port);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
   return gst_element_register (plugin, "rfbsrc", GST_RANK_NONE,
-      GST_TYPE_RFBSRC);
+      GST_TYPE_RFB_SRC);
 }
 
 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
index ceed185..cd9f9bc 100644 (file)
@@ -1,22 +1,19 @@
-
-
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "rfb.h"
 
-
 int
 main (int argc, char *argv[])
 {
   RfbDecoder *decoder;
 
-  //int fd = 0;
+  // int fd = 0;
 
   decoder = rfb_decoder_new ();
 
   rfb_decoder_connect_tcp (decoder, "127.0.0.1", 5901);
-  //rfb_decoder_use_file_descriptor (decoder, fd);
+  // rfb_decoder_use_file_descriptor (decoder, fd);
 
   while (!decoder->inited)
     rfb_decoder_iterate (decoder);
index 2754314..68b6292 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef _RFB_RFB_H_
 #define _RFB_RFB_H_
 
@@ -7,4 +6,3 @@
 #include <librfb/rfbbuffer.h>
 
 #endif
-
index e38def3..4ab4eb0 100644 (file)
@@ -1,11 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
-#include <rfbbuffer.h>
+#include "rfbbuffer.h"
 
 RfbBuffer *
 rfb_buffer_new (void)
 {
   return g_new0 (RfbBuffer, 1);
-
 }
 
 RfbBuffer *
@@ -22,6 +24,7 @@ rfb_buffer_new_and_alloc (int len)
 void
 rfb_buffer_free (RfbBuffer * buffer)
 {
-  buffer->free_data (buffer->data, buffer->buffer_private);
+  g_return_if_fail (buffer != NULL);
 
+  buffer->free_data (buffer->data, buffer->buffer_private);
 }
index 7c4d40b..f220c0e 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef _LIBRFB_BUFFER_H_
 #define _LIBRFB_BUFFER_H_
 
@@ -10,16 +9,16 @@ typedef struct _RfbBuffer RfbBuffer;
 
 struct _RfbBuffer
 {
-  guint8 *data;
-  int length;
-
   void (*free_data) (guint8 *data, gpointer priv);
   gpointer buffer_private;
+
+  guint8 *data;
+  gint length;
 };
 
-RfbBuffer *rfb_buffer_new (void);
-RfbBuffer *rfb_buffer_new_and_alloc (int len);
-void rfb_buffer_free (RfbBuffer *buffer);
+RfbBuffer *rfb_buffer_new           (void);
+RfbBuffer *rfb_buffer_new_and_alloc (gint len);
+void       rfb_buffer_free          (RfbBuffer *buffer);
 
 G_END_DECLS
 
index bcdc1b0..b33a33a 100644 (file)
@@ -1,23 +1,40 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <rfbbytestream.h>
 #include <string.h>
 
+static gint rfb_bytestream_copy_nocheck (RfbBytestream * bs,
+    RfbBuffer * buffer, gint len);
+
 RfbBytestream *
 rfb_bytestream_new (void)
 {
   return g_new0 (RfbBytestream, 1);
 }
 
-int
-rfb_bytestream_get (RfbBytestream * bs, int len)
+void
+rfb_bytestream_free (RfbBytestream * bs)
+{
+  g_return_if_fail (bs != NULL);
+
+  g_slist_free (bs->buffer_list);
+  g_free (bs);
+}
+
+gint
+rfb_bytestream_get (RfbBytestream * bs, gint len)
 {
   RfbBuffer *buffer;
 
+  g_return_val_if_fail (bs != NULL, 0);
+
   buffer = bs->get_buffer (len, bs->user_data);
 
   if (buffer) {
-    g_print ("got buffer (%d bytes)\n", buffer->length);
-    bs->buffer_list = g_list_append (bs->buffer_list, buffer);
+    // g_print ("got buffer (%d bytes)\n", buffer->length);
+    bs->buffer_list = g_slist_append (bs->buffer_list, buffer);
 
     bs->length += buffer->length;
 
@@ -28,46 +45,24 @@ rfb_bytestream_get (RfbBytestream * bs, int len)
 }
 
 gboolean
-rfb_bytestream_check (RfbBytestream * bs, int len)
+rfb_bytestream_check (RfbBytestream * bs, gint len)
 {
+  g_return_val_if_fail (bs != NULL, FALSE);
+
   while (bs->length < len) {
     rfb_bytestream_get (bs, len - bs->length);
   }
   return TRUE;
 }
 
-static int
-rfb_bytestream_copy_nocheck (RfbBytestream * bs, RfbBuffer * buffer, int len)
-{
-  GList *item;
-  int offset;
-  int first_offset;
-  RfbBuffer *frombuf;
-  int n;
-
-  offset = 0;
-  first_offset = bs->offset;
-  for (item = bs->buffer_list; item; item = g_list_next (item)) {
-    frombuf = (RfbBuffer *) item->data;
-    n = MIN (len, frombuf->length - first_offset);
-    g_print ("copying %d bytes from %p\n", n, frombuf);
-    memcpy (buffer->data + offset, frombuf->data + first_offset, n);
-    first_offset = 0;
-    len -= n;
-    offset += n;
-    if (len == 0)
-      return len;
-  }
-
-  g_assert_not_reached ();
-  return 0;
-}
-
-int
-rfb_bytestream_read (RfbBytestream * bs, RfbBuffer ** buffer, int len)
+gint
+rfb_bytestream_read (RfbBytestream * bs, RfbBuffer ** buffer, gint len)
 {
   RfbBuffer *buf;
 
+  g_return_val_if_fail (bs != NULL, 0);
+  g_return_val_if_fail (buffer != NULL, 0);
+
   rfb_bytestream_check (bs, len);
 
   buf = rfb_buffer_new_and_alloc (len);
@@ -79,11 +74,14 @@ rfb_bytestream_read (RfbBytestream * bs, RfbBuffer ** buffer, int len)
   return len;
 }
 
-int
-rfb_bytestream_peek (RfbBytestream * bs, RfbBuffer ** buffer, int len)
+gint
+rfb_bytestream_peek (RfbBytestream * bs, RfbBuffer ** buffer, gint len)
 {
   RfbBuffer *buf;
 
+  g_return_val_if_fail (bs != NULL, 0);
+  g_return_val_if_fail (buffer != NULL, 0);
+
   rfb_bytestream_check (bs, len);
 
   buf = rfb_buffer_new_and_alloc (len);
@@ -93,12 +91,14 @@ rfb_bytestream_peek (RfbBytestream * bs, RfbBuffer ** buffer, int len)
   return len;
 }
 
-int
-rfb_bytestream_flush (RfbBytestream * bs, int len)
+gint
+rfb_bytestream_flush (RfbBytestream * bs, gint len)
 {
-  GList *item;
+  GSList *item;
   RfbBuffer *buf;
-  int n;
+  gint n;
+
+  g_return_val_if_fail (bs != NULL, 0);
 
   while ((item = bs->buffer_list)) {
     buf = (RfbBuffer *) item->data;
@@ -106,7 +106,7 @@ rfb_bytestream_flush (RfbBytestream * bs, int len)
     n = MIN (buf->length - bs->offset, len);
     if (n <= len) {
       bs->offset = 0;
-      bs->buffer_list = g_list_delete_link (bs->buffer_list, item);
+      bs->buffer_list = g_slist_delete_link (bs->buffer_list, item);
       rfb_buffer_free (buf);
     } else {
       bs->offset = bs->offset + len;
@@ -120,3 +120,30 @@ rfb_bytestream_flush (RfbBytestream * bs, int len)
   g_assert_not_reached ();
   return 0;
 }
+
+static gint
+rfb_bytestream_copy_nocheck (RfbBytestream * bs, RfbBuffer * buffer, gint len)
+{
+  GSList *item;
+  gint offset;
+  gint first_offset;
+  RfbBuffer *frombuf;
+  gint n;
+
+  offset = 0;
+  first_offset = bs->offset;
+  for (item = bs->buffer_list; item; item = item->next) {
+    frombuf = (RfbBuffer *) item->data;
+    n = MIN (len, frombuf->length - first_offset);
+    // g_print ("copying %d bytes from %p\n", n, frombuf);
+    memcpy (buffer->data + offset, frombuf->data + first_offset, n);
+    first_offset = 0;
+    len -= n;
+    offset += n;
+    if (len == 0)
+      return len;
+  }
+
+  g_assert_not_reached ();
+  return 0;
+}
index 8304169..65b936d 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef _LIBRFB_BYTESTREAM_H_
 #define _LIBRFB_BYTESTREAM_H_
 
@@ -12,21 +11,26 @@ typedef struct _RfbBytestream RfbBytestream;
 
 struct _RfbBytestream
 {
-  RfbBuffer * (*get_buffer) (int length, gpointer user_data);
+  RfbBuffer * (* get_buffer) (gint length, gpointer user_data);
+
   gpointer user_data;
   
-  GList *buffer_list;
-  int length;
-  int offset;
+  GSList *buffer_list;
+  gint length;
+  gint offset;
 };
 
-
-RfbBytestream * rfb_bytestream_new (void);
-
-int rfb_bytestream_read (RfbBytestream *bs, RfbBuffer **buffer, int len);
-int rfb_bytestream_peek (RfbBytestream *bs, RfbBuffer **buffer, int len);
-int rfb_bytestream_flush (RfbBytestream *bs, int len);
-
+RfbBytestream *rfb_bytestream_new     (void);
+void           rfb_bytestream_free    (RfbBytestream * bs);
+
+gint           rfb_bytestream_read    (RfbBytestream * bs,
+                                       RfbBuffer ** buffer,
+                                       gint len);
+gint           rfb_bytestream_peek    (RfbBytestream * bs,
+                                       RfbBuffer ** buffer,
+                                       gint len);
+gint           rfb_bytestream_flush   (RfbBytestream * bs,
+                                       gint len);
 
 G_END_DECLS
 
index df9ec1d..fb41aa0 100644 (file)
@@ -1,41 +1,38 @@
-
 #ifndef _LIBRFB_RFBCONTEXT_H_
 #define _LIBRFB_RFBCONTEXT_H_
 
-G_BEGIN_DECLS
-
 #include <glib.h>
 
+G_BEGIN_DECLS
+
 typedef struct _RfbContext
 {
   RfbConnection *connection;
 
   guint8 *buffer1;
-  void *buffer1_alloc;
-  unsigned int buffer1_len;
+  gpointer buffer1_alloc;
+  guint buffer1_len;
 
   guint8 *buffer2;
-  void *buffer2_alloc;
-  unsigned int buffer2_len;
+  gpointer buffer2_alloc;
+  guint buffer2_len;
 
-  char *name;
+  gchar *name;
 } RfbContext;
 
 typedef struct _RfbRect
 {
   RfbContext *context;
 
-  unsigned int x_pos;
-  unsigned int y_pos;
-  unsigned int width;
-  unsigned int height;
-  unsigned int encoding_type;
+  guint x_pos;
+  guint y_pos;
+  guint width;
+  guint height;
+  guint encoding_type;
 
-  char *data;
+  gchar *data;
 } RfbRect;
 
-
-
 G_END_DECLS
 
 #endif
index e8de9b0..01f1b7e 100644 (file)
@@ -1,3 +1,8 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rfbdecoder.h"
 
 #include <rfb.h>
 #include <unistd.h>
 #include <arpa/inet.h>
 #include <errno.h>
 
+#define RFB_GET_UINT32(ptr) GUINT32_FROM_BE (*(guint32 *)(ptr))
+#define RFB_GET_UINT16(ptr) GUINT16_FROM_BE (*(guint16 *)(ptr))
+#define RFB_GET_UINT8(ptr) (*(guint8 *)(ptr))
+
+#define RFB_SET_UINT32(ptr, val) (*(guint32 *)(ptr) = GUINT32_TO_BE (val))
+#define RFB_SET_UINT16(ptr, val) (*(guint16 *)(ptr) = GUINT16_TO_BE (val))
+#define RFB_SET_UINT8(ptr, val) (*(guint8 *)(ptr) = val)
 
 #if 0
 struct _RfbSocketPrivate
 {
-  int fd;
+  gint fd;
   sockaddr sa;
 }
 #endif
 
-
-static RfbBuffer *
-rfb_socket_get_buffer (int length, gpointer user_data)
-{
-  RfbBuffer *buffer;
-  int fd = (int) user_data;
-  int ret;
-
-  buffer = rfb_buffer_new ();
-
-  buffer->data = g_malloc (length);
-  buffer->free_data = (void *) g_free;
-
-  g_print ("calling read(%d, %p, %d)\n", fd, buffer->data, length);
-  ret = read (fd, buffer->data, length);
-  if (ret <= 0) {
-    g_critical ("read: %s", strerror (errno));
-    rfb_buffer_free (buffer);
-    return NULL;
-  }
-
-  buffer->length = ret;
-
-  return buffer;
-}
-
-static int
-rfb_socket_send_buffer (guint8 * buffer, int length, gpointer user_data)
-{
-  int fd = (int) user_data;
-  int ret;
-
-  g_print ("calling write(%d, %p, %d)\n", fd, buffer, length);
-  ret = write (fd, buffer, length);
-  if (ret < 0) {
-    g_critical ("write: %s", strerror (errno));
-    return 0;
-  }
-
-  g_assert (ret == length);
-
-  return ret;
-}
-
+static gboolean rfb_decoder_state_wait_for_protocol_version (RfbDecoder *
+    decoder);
+static gboolean rfb_decoder_state_wait_for_security (RfbDecoder * decoder);
+static gboolean rfb_decoder_state_send_client_initialisation (RfbDecoder *
+    decoder);
+static gboolean rfb_decoder_state_wait_for_server_initialisation (RfbDecoder *
+    decoder);
+static gboolean rfb_decoder_state_normal (RfbDecoder * decoder);
+static gboolean rfb_decoder_state_framebuffer_update (RfbDecoder * decoder);
+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 RfbBuffer *rfb_socket_get_buffer (gint length, gpointer user_data);
+static gint rfb_socket_send_buffer (guint8 * buffer, gint length,
+    gpointer user_data);
 
 RfbDecoder *
 rfb_decoder_new (void)
 {
   RfbDecoder *decoder = g_new0 (RfbDecoder, 1);
 
+  decoder->fd = -1;
   decoder->bytestream = rfb_bytestream_new ();
 
   return decoder;
 }
 
 void
-rfb_decoder_use_file_descriptor (RfbDecoder * decoder, int fd)
+rfb_decoder_free (RfbDecoder * decoder)
+{
+  g_return_if_fail (decoder != NULL);
+
+  rfb_bytestream_free (decoder->bytestream);
+  if (decoder->fd >= 0)
+    close (decoder->fd);
+}
+
+void
+rfb_decoder_use_file_descriptor (RfbDecoder * decoder, gint fd)
 {
   g_return_if_fail (decoder != NULL);
+  g_return_if_fail (decoder->fd == -1);
   g_return_if_fail (!decoder->inited);
   g_return_if_fail (fd >= 0);
 
+  decoder->fd = fd;
+
   decoder->bytestream->get_buffer = rfb_socket_get_buffer;
   decoder->bytestream->user_data = (void *) fd;
 
@@ -85,65 +83,114 @@ rfb_decoder_use_file_descriptor (RfbDecoder * decoder, int fd)
   decoder->buffer_handler_data = (void *) fd;
 }
 
-void
-rfb_decoder_connect_tcp (RfbDecoder * decoder, char *addr, unsigned int port)
+gboolean
+rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * addr, guint port)
 {
-  int fd;
+  gint fd;
   struct sockaddr_in sa;
 
+  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)
+    return FALSE;
 
   sa.sin_family = AF_INET;
   sa.sin_port = htons (port);
   inet_pton (AF_INET, addr, &sa.sin_addr);
-  connect (fd, (struct sockaddr *) &sa, sizeof (struct sockaddr));
+  if (connect (fd, (struct sockaddr *) &sa, sizeof (struct sockaddr)) == -1) {
+    close (fd);
+    return FALSE;
+  }
 
   rfb_decoder_use_file_descriptor (decoder, fd);
+  return TRUE;
 }
 
-
-static gboolean rfb_decoder_state_wait_for_protocol_version (RfbDecoder *
-    decoder);
-static gboolean rfb_decoder_state_wait_for_security (RfbDecoder * decoder);
-static gboolean rfb_decoder_state_send_client_initialisation (RfbDecoder *
-    decoder);
-static gboolean rfb_decoder_state_wait_for_server_initialisation (RfbDecoder *
-    decoder);
-static gboolean rfb_decoder_state_normal (RfbDecoder * decoder);
-static gboolean rfb_decoder_state_framebuffer_update (RfbDecoder * decoder);
-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);
-
 gboolean
 rfb_decoder_iterate (RfbDecoder * decoder)
 {
   g_return_val_if_fail (decoder != NULL, FALSE);
+  g_return_val_if_fail (decoder->fd != -1, FALSE);
 
   if (decoder->state == NULL) {
     decoder->state = rfb_decoder_state_wait_for_protocol_version;
   }
-
-  g_print ("iterating...\n");
+  // g_print ("iterating...\n");
 
   return decoder->state (decoder);
 }
 
-#define RFB_GET_UINT32(ptr) GUINT32_FROM_BE (*(guint32 *)(ptr))
-#define RFB_GET_UINT16(ptr) GUINT16_FROM_BE (*(guint16 *)(ptr))
-#define RFB_GET_UINT8(ptr) (*(guint8 *)(ptr))
+gint
+rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, 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);
 
-#define RFB_SET_UINT32(ptr, val) (*(guint32 *)(ptr) = GUINT32_TO_BE (val))
-#define RFB_SET_UINT16(ptr, val) (*(guint16 *)(ptr) = GUINT16_TO_BE (val))
-#define RFB_SET_UINT8(ptr, val) (*(guint8 *)(ptr) = val)
+  return decoder->send_data (buffer, len, decoder->buffer_handler_data);
+}
+
+void
+rfb_decoder_send_update_request (RfbDecoder * decoder,
+    gboolean incremental, gint x, gint y, gint width, gint height)
+{
+  guint8 data[10];
+
+  g_return_if_fail (decoder != NULL);
+  g_return_if_fail (decoder->fd != -1);
+
+  data[0] = 3;
+  data[1] = incremental;
+  RFB_SET_UINT16 (data + 2, x);
+  RFB_SET_UINT16 (data + 4, y);
+  RFB_SET_UINT16 (data + 6, width);
+  RFB_SET_UINT16 (data + 8, height);
+
+  rfb_decoder_send (decoder, data, 10);
+}
+
+void
+rfb_decoder_send_key_event (RfbDecoder * decoder, guint key, gboolean down_flag)
+{
+  guint8 data[8];
+
+  g_return_if_fail (decoder != NULL);
+  g_return_if_fail (decoder->fd != -1);
+
+  data[0] = 4;
+  data[1] = down_flag;
+  RFB_SET_UINT16 (data + 2, 0);
+  RFB_SET_UINT32 (data + 4, key);
+
+  rfb_decoder_send (decoder, data, 8);
+}
+
+void
+rfb_decoder_send_pointer_event (RfbDecoder * decoder,
+    gint button_mask, gint x, gint y)
+{
+  guint8 data[6];
+
+  g_return_if_fail (decoder != NULL);
+  g_return_if_fail (decoder->fd != -1);
+
+  data[0] = 5;
+  data[1] = button_mask;
+  RFB_SET_UINT16 (data + 2, x);
+  RFB_SET_UINT16 (data + 4, y);
+
+  rfb_decoder_send (decoder, data, 6);
+}
 
 static gboolean
 rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
 {
   RfbBuffer *buffer;
   guint8 *data;
-  int ret;
+  gint ret;
 
   ret = rfb_bytestream_read (decoder->bytestream, &buffer, 12);
   if (ret < 12)
@@ -152,10 +199,10 @@ rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
   data = buffer->data;
 
   g_assert (memcmp (buffer->data, "RFB 003.00", 10) == 0);
-  g_print ("\"%.11s\"\n", buffer->data);
+  // g_print ("\"%.11s\"\n", buffer->data);
   rfb_buffer_free (buffer);
 
-  rfb_decoder_send (decoder, "RFB 003.003\n", 12);
+  rfb_decoder_send (decoder, (guint8 *) "RFB 003.003\n", 12);
 
   decoder->state = rfb_decoder_state_wait_for_security;
 
@@ -166,14 +213,14 @@ static gboolean
 rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
 {
   RfbBuffer *buffer;
-  int ret;
+  gint ret;
 
   ret = rfb_bytestream_read (decoder->bytestream, &buffer, 4);
   if (ret < 4)
     return FALSE;
 
   decoder->security_type = RFB_GET_UINT32 (buffer->data);
-  g_print ("security = %d\n", decoder->security_type);
+  // g_print ("security = %d\n", decoder->security_type);
 
   rfb_buffer_free (buffer);
 
@@ -198,7 +245,7 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
 {
   RfbBuffer *buffer;
   guint8 *data;
-  int ret;
+  gint ret;
   guint32 name_length;
 
   ret = rfb_bytestream_peek (decoder->bytestream, &buffer, 24);
@@ -220,8 +267,8 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
   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);
+  // 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);
@@ -230,8 +277,8 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
   if (ret < 24 + name_length)
     return FALSE;
 
-  decoder->name = g_strndup ((char *) (buffer->data) + 24, name_length);
-  g_print ("name: %s\n", decoder->name);
+  decoder->name = g_strndup ((gchar *) (buffer->data) + 24, name_length);
+  // g_print ("name: %s\n", decoder->name);
   rfb_buffer_free (buffer);
 
   decoder->state = rfb_decoder_state_normal;
@@ -244,8 +291,8 @@ static gboolean
 rfb_decoder_state_normal (RfbDecoder * decoder)
 {
   RfbBuffer *buffer;
-  int ret;
-  int message_type;
+  gint ret;
+  gint message_type;
 
   ret = rfb_bytestream_read (decoder->bytestream, &buffer, 1);
   message_type = RFB_GET_UINT8 (buffer->data);
@@ -277,7 +324,7 @@ static gboolean
 rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
 {
   RfbBuffer *buffer;
-  int ret;
+  gint ret;
 
   ret = rfb_bytestream_read (decoder->bytestream, &buffer, 3);
 
@@ -291,10 +338,10 @@ static gboolean
 rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
 {
   RfbBuffer *buffer;
-  int ret;
-  int x, y, w, h;
-  int encoding;
-  int size;
+  gint ret;
+  gint x, y, w, h;
+  gint encoding;
+  gint size;
 
   ret = rfb_bytestream_peek (decoder->bytestream, &buffer, 12);
   if (ret < 12)
@@ -345,53 +392,45 @@ rfb_decoder_state_server_cut_text (RfbDecoder * decoder)
   return FALSE;
 }
 
-
-void
-rfb_decoder_send_update_request (RfbDecoder * decoder,
-    gboolean incremental, int x, int y, int width, int height)
+static RfbBuffer *
+rfb_socket_get_buffer (gint length, gpointer user_data)
 {
-  guint8 data[10];
+  RfbBuffer *buffer;
+  gint fd = (gint) user_data;
+  gint ret;
 
-  data[0] = 3;
-  data[1] = incremental;
-  RFB_SET_UINT16 (data + 2, x);
-  RFB_SET_UINT16 (data + 4, y);
-  RFB_SET_UINT16 (data + 6, width);
-  RFB_SET_UINT16 (data + 8, height);
+  buffer = rfb_buffer_new ();
 
-  rfb_decoder_send (decoder, data, 10);
-}
+  buffer->data = g_malloc (length);
+  buffer->free_data = (void *) g_free;
 
-void
-rfb_decoder_send_key_event (RfbDecoder * decoder, unsigned int key,
-    gboolean down_flag)
-{
-  guint8 data[8];
+  // g_print ("calling read(%d, %p, %d)\n", fd, buffer->data, length);
+  ret = read (fd, buffer->data, length);
+  if (ret <= 0) {
+    g_critical ("read: %s", strerror (errno));
+    rfb_buffer_free (buffer);
+    return NULL;
+  }
 
-  data[0] = 4;
-  data[1] = down_flag;
-  RFB_SET_UINT16 (data + 2, 0);
-  RFB_SET_UINT32 (data + 4, key);
+  buffer->length = ret;
 
-  rfb_decoder_send (decoder, data, 8);
+  return buffer;
 }
 
-void
-rfb_decoder_send_pointer_event (RfbDecoder * decoder,
-    int button_mask, int x, int y)
+static gint
+rfb_socket_send_buffer (guint8 * buffer, gint length, gpointer user_data)
 {
-  guint8 data[6];
+  gint fd = (gint) user_data;
+  gint ret;
 
-  data[0] = 5;
-  data[1] = button_mask;
-  RFB_SET_UINT16 (data + 2, x);
-  RFB_SET_UINT16 (data + 4, y);
+  // g_print ("calling write(%d, %p, %d)\n", fd, buffer, length);
+  ret = write (fd, buffer, length);
+  if (ret < 0) {
+    g_critical ("write: %s", strerror (errno));
+    return 0;
+  }
 
-  rfb_decoder_send (decoder, data, 6);
-}
+  g_assert (ret == length);
 
-int
-rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, int len)
-{
-  return decoder->send_data (buffer, len, decoder->buffer_handler_data);
+  return ret;
 }
index db16cb2..4163efe 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef _LIBRFB_DECODER_H_
 #define _LIBRFB_DECODER_H_
 
@@ -11,46 +10,47 @@ typedef struct _RfbDecoder RfbDecoder;
 
 struct _RfbDecoder
 {
-  int (*send_data) (guint8 *buffer, int length, gpointer user_data);
+  /* 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);
+
   gpointer buffer_handler_data;
 
+  gint fd;
   RfbBytestream *bytestream;
 
   gpointer decoder_private;
 
-  void (*paint_rect) (RfbDecoder *decoder, int x, int y, int w, int h,
-      guint8 *data);
-  void (*copy_rect) (RfbDecoder *decoder, int x, int y, int w, int h,
-      int src_x, int src_y);
-
   /* settable properties */
   gboolean shared_flag;
 
   /* readable properties */
   gboolean inited;
 
-  int protocol_major;
-  int protocol_minor;
-  unsigned int security_type;
+  gint protocol_major;
+  gint protocol_minor;
+  guint security_type;
 
-  unsigned int width;
-  unsigned int height;
-  unsigned int bpp;
-  unsigned int depth;
+  guint width;
+  guint height;
+  guint bpp;
+  guint depth;
   gboolean big_endian;
   gboolean true_colour;
-  unsigned int red_max;
-  unsigned int green_max;
-  unsigned int blue_max;
-  unsigned int red_shift;
-  unsigned int green_shift;
-  unsigned int blue_shift;
+  guint red_max;
+  guint green_max;
+  guint blue_max;
+  guint red_shift;
+  guint green_shift;
+  guint blue_shift;
 
-  char *name;
+  gchar *name;
 
-  /* state information */
-  gboolean (*state) (RfbDecoder *decoder);
-  int n_rects;
+  gint n_rects;
 };
 
 #if 0
@@ -58,29 +58,40 @@ typedef struct _RfbRect
 {
   RfbConnection *connection;
 
-  unsigned int x_pos;
-  unsigned int y_pos;
-  unsigned int width;
-  unsigned int height;
-  unsigned int encoding_type;
+  guint x_pos;
+  guint y_pos;
+  guint width;
+  guint height;
+  guint encoding_type;
 
-  char *data;
+  gchar *data;
 } RfbRect;
 #endif
 
-
-RfbDecoder *rfb_decoder_new (void);
-void rfb_decoder_use_file_descriptor (RfbDecoder * decoder, int fd);
-void rfb_decoder_connect_tcp (RfbDecoder *decoder, char * addr, unsigned int port);
-void rfb_decoder_set_peer (RfbDecoder * decoder);
-gboolean rfb_decoder_iterate (RfbDecoder * decoder);
-int rfb_decoder_send (RfbDecoder * decoder, guint8 *data, int len);
-void rfb_decoder_send_update_request (RfbDecoder * decoder,
-    gboolean incremental, int x, int y, int width, int height);
-void rfb_decoder_send_key_event (RfbDecoder * decoder, unsigned int key,
-    gboolean down_flag);
-void rfb_decoder_send_pointer_event (RfbDecoder * decoder,
-    int button_mask, int x, int 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);
+gint        rfb_decoder_send                (RfbDecoder * decoder,
+                                             guint8 *data,
+                                             gint len);
+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
 
index 2b9b95d..c816bcd 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef _LIBRFB_UTIL_H_
 #define _LIBRFB_UTIL_H_
 
@@ -6,8 +5,6 @@
 
 G_BEGIN_DECLS
 
-
-
 G_END_DECLS
 
 #endif