+ #include <gtk/gtk.h>
+# include <gdk/gdkx.h> // for GDK_WINDOW_XWINDOW
+#endif
+
+//-----------------------------------------------------------------------------
+// Discussion of internals
+//-----------------------------------------------------------------------------
+
+/*
+ This is the GStreamer backend for unix. Currently we require 0.8 or
+ 0.10. Here we use the "playbin" GstElement for ease of use.
+
+ Note that now we compare state change functions to GST_STATE_FAILURE
+ now rather than GST_STATE_SUCCESS as newer gstreamer versions return
+ non-success values for returns that are otherwise successful but not
+ immediate.
+
+ Also this probably doesn't work with anything other than wxGTK at the
+ moment but with a tad bit of work it could theorectically work in
+ straight wxX11 et al.
+
+ One last note is that resuming from pausing/seeking can result
+ in erratic video playback (GStreamer-based bug, happens in totem as well)
+ - this is better in 0.10, however. One thing that might make it worse
+ here is that we don't preserve the aspect ratio of the video and stretch
+ it to the whole window.
+
+ Note that there are some things used here that could be undocumented -
+ for reference see the media player Kiss and Totem as well as some
+ other sources. There was a backend for a kde media player as well
+ that attempted thread-safety...
+
+ Then there is the issue of m_asynclock. This serves several purposes:
+ 1) It prevents the C callbacks from sending wx state change events
+ so that we don't get duplicate ones in 0.8
+ 2) It makes the sync and async handlers in 0.10 not drop any
+ messages so that while we are polling it we get the messages in
+ SyncStateChange instead of the queue.
+ 3) Keeps the pausing in Stop() synchronous
+
+ RN: Note that I've tried to follow the wxGTK conventions here as close
+ as possible. In the implementation the C Callbacks come first, then
+ the internal functions, then the public ones. Set your vi to 80
+ characters people :).
+*/
+
+//=============================================================================
+// Declarations
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// GStreamer (most version compatability) macros
+//-----------------------------------------------------------------------------
+
+// In 0.9 there was a HUGE change to GstQuery and the
+// gst_element_query function changed dramatically and split off
+// into two seperate ones
+#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8
+# define wxGst_element_query_duration(e, f, p) \
+ gst_element_query(e, GST_QUERY_TOTAL, f, p)
+# define wxGst_element_query_position(e, f, p) \
+ gst_element_query(e, GST_QUERY_POSITION, f, p)
+#elif GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 9
+// However, the actual 0.9 version has a slightly different definition
+// and instead of gst_element_query_duration it has two parameters to
+// gst_element_query_position instead
+# define wxGst_element_query_duration(e, f, p) \
+ gst_element_query_position(e, f, 0, p)
+# define wxGst_element_query_position(e, f, p) \
+ gst_element_query_position(e, f, p, 0)
+#else
+# define wxGst_element_query_duration \
+ gst_element_query_duration
+# define wxGst_element_query_position \
+ gst_element_query_position
+#endif
+
+// Other 0.10 macros
+#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
+# define GST_STATE_FAILURE GST_STATE_CHANGE_FAILURE
+# define GST_STATE_SUCCESS GST_STATE_CHANGE_SUCCESS
+# define GstElementState GstState
+# define gst_gconf_get_default_video_sink() \
+ gst_element_factory_make ("gconfvideosink", "video-sink");
+# define gst_gconf_get_default_audio_sink() \
+ gst_element_factory_make ("gconfaudiosink", "audio-sink");