diff options
26 files changed, 953 insertions, 12 deletions
@@ -1,5 +1,34 @@ 2005-11-06 Julien MOUTTE <julien@moutte.net> + * Makefile.am: + * autogen.sh: + * configure.ac: + * docs/Makefile.am: + * docs/plugins/.cvsignore: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-decl-list.txt: + * docs/plugins/gst-plugins-bad-plugins-decl.txt: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * docs/plugins/gst-plugins-bad-plugins-undocumented.txt: + * docs/plugins/gst-plugins-bad-plugins.args: + * docs/plugins/gst-plugins-bad-plugins.hierarchy: + * docs/plugins/gst-plugins-bad-plugins.interfaces: + * docs/plugins/gst-plugins-bad-plugins.prerequisites: + * docs/plugins/gst-plugins-bad-plugins.signals: + * docs/plugins/gst-plugins-bad-plugins.types: + * docs/plugins/inspect/plugin-dfbvideosink.xml: + * docs/version.entities.in: Enable documentation. + * examples/Makefile.am: + * examples/directfb/Makefile.am: + * examples/directfb/decker.ttf: + * examples/directfb/dfblogo.png: + * examples/directfb/gstdfb.c: (myclock), (dynamic_link), + (size_changed), (setup_dynamic_link), (main): Add an example + application for DirectFB. + +2005-11-06 Julien MOUTTE <julien@moutte.net> + * ext/directfb/Makefile.am: Add the example application. * ext/directfb/dfb-example.c: (get_me_out), (main): Here is an example application that runs videotestsrc for 20 diff --git a/Makefile.am b/Makefile.am index b98fbf65..0eccbb0f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,8 @@ +DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc + SUBDIRS = \ gst sys ext \ - m4 common + m4 common docs EXTRA_DIST = \ gst-plugins-bad.spec depcomp \ @@ -25,7 +25,7 @@ then fi . common/gst-autogen.sh -CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-plugin-builddir --enable-debug --enable-DEBUG' +CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc' autogen_options $@ diff --git a/configure.ac b/configure.ac index e25b82c8..aee90dc0 100644 --- a/configure.ac +++ b/configure.ac @@ -427,6 +427,13 @@ GST_CFLAGS="-I\$(top_srcdir)/gst-libs -I\$(top_builddir)/gst-libs $GST_CFLAGS $G AC_SUBST(GST_LIBS) AC_SUBST(GST_CFLAGS) +dnl ###################### +dnl # Checks for gtk-doc # +dnl ###################### + +GTK_DOC_CHECK([1.3]) +AS_PATH_PYTHON([2.1]) + dnl ############################ dnl # Set up some more defines # dnl ############################ @@ -481,12 +488,17 @@ gst/speed/Makefile gst/qtdemux/Makefile gst/tta/Makefile sys/Makefile +examples/Makefile +examples/directfb/Makefile ext/Makefile ext/directfb/Makefile ext/faac/Makefile ext/faad/Makefile ext/gsm/Makefile ext/sdl/Makefile +docs/Makefile +docs/plugins/Makefile +docs/version.entities common/Makefile common/m4/Makefile m4/Makefile diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..2b9075b7 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,12 @@ +if ENABLE_GTK_DOC +GTK_DOC_DIRS = plugins +else +GTK_DOC_DIRS = +endif + +SUBDIRS = $(GTK_DOC_DIRS) +DIST_SUBDIRS = plugins + +EXTRA_DIST = \ + random/ChangeLog-0.8 \ + version.entities.in diff --git a/docs/plugins/.gitignore b/docs/plugins/.gitignore new file mode 100644 index 00000000..2ef1402d --- /dev/null +++ b/docs/plugins/.gitignore @@ -0,0 +1,18 @@ +Makefile +Makefile.in + +*-decl.txt +*-decl-list.txt +*-undocumented.txt +*-unused.txt + +*.args +*.hierarchy +*.interfaces +*.prerequisites +*.signals + +html +sgml +xml +*.stamp diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am new file mode 100644 index 00000000..3ac322d5 --- /dev/null +++ b/docs/plugins/Makefile.am @@ -0,0 +1,113 @@ +GST_DOC_SCANOBJ = $(top_srcdir)/common/gstdoc-scangobj + +## Process this file with automake to produce Makefile.in + +# The name of the module, e.g. 'glib'. +#DOC_MODULE=gst-plugins-libs-@GST_MAJORMINOR@ +MODULE=gst-plugins-bad +DOC_MODULE=$(MODULE)-plugins + +# for upload.mak +DOC=$(MODULE)-plugins +FORMATS=html +html: html-build.stamp +include $(top_srcdir)/common/upload-doc.mak + +# generated basefiles +#basefiles = \ +## $(DOC_MODULE).types \ +# $(DOC_MODULE)-sections.txt \ +# $(DOC_MODULE)-docs.sgml + +# ugly hack to make -unused.sgml work +#unused-build.stamp: +# BUILDDIR=`pwd` && \ +# cd $(srcdir)/tmpl && \ +# ln -sf gstreamer-libs-unused.sgml \ +# $$BUILDDIR/tmpl/gstreamer-libs-@GST_MAJORMINOR@-unused.sgml +# touch unused-build.stamp + +# these rules are added to create parallel docs using GST_MAJORMINOR +#$(basefiles): gstreamer-libs-@GST_MAJORMINOR@%: gstreamer-libs% +# cp $< $@ + +#CLEANFILES = $(basefiles) + +# The top-level SGML file. Change it if you want. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml + +# The directory containing the source code. Relative to $(top_srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting functions and macros. +DOC_SOURCE_DIR = $(top_srcdir) + +# Extra options to supply to gtkdoc-scan. +SCAN_OPTIONS= + +# FIXME : +# there's something wrong with gstreamer-sections.txt not being in the dist +# maybe it doesn't resolve; we're adding it below for now +#EXTRA_DIST = gstreamer.types.in gstreamer.hierarchy $(DOC_MODULE)-sections.txt gstreamer-sections.txt $(DOC_MAIN_SGML_FILE) + +# Extra options to supply to gtkdoc-mkdb. +MKDB_OPTIONS=--sgml-mode + +# Extra options to supply to gtkdoc-fixref. +# FIXME get the location of the installed gstreamer docs +#FIXXREF_OPTIONS=--extra-dir=../gst/html + +# Used for dependencies. +HFILE_GLOB=$(DOC_SOURCE_DIR)/*/*/*.h +CFILE_GLOB=$(DOC_SOURCE_DIR)/*/*/*.c + +# this is a wingo addition +# thomasvs: another nice wingo addition would be an explanation on why +# this is useful ;) + +SCANOBJ_DEPS = + +# Header files to ignore when scanning. +IGNORE_HFILES = +IGNORE_CFILES = + +# we add all .h files of elements that have signals/args we want +# sadly this also pulls in the private methods - maybe we should +# move those around in the source ? +# also, we should add some stuff here conditionally based on whether +# or not the plugin will actually build +# but I'm not sure about that - it might be this Just Works given that +# the registry won't have the element + +# FIXME: not ported yet +# $(top_srcdir)/ext/gnomevfs/gstgnomevfssink.c + +# example code that needs to be converted to xml and placed in xml/ +EXAMPLE_CFILES = \ + $(top_srcdir)/ext/directfb/dfb-example.c + +EXTRA_HFILES = \ + $(top_srcdir)/ext/directfb/dfbvideosink.h + +# Images to copy into HTML directory. +HTML_IMAGES = + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +content_files = + +# Other files to distribute. +extra_files = + +# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib +# contains GtkObjects/GObjects and you want to document signals and properties. +GTKDOC_CFLAGS = $(GST_BASE_CFLAGS) -I$(top_builddir) +GTKDOC_LIBS = $(SCANOBJ_DEPS) $(GST_BASE_LIBS) + +GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC) +GTKDOC_LD=$(LIBTOOL) --mode=link $(CC) + +# If you need to override some of the declarations, place them in this file +# and uncomment this line. +#DOC_OVERRIDES = $(DOC_MODULE)-overrides.txt +DOC_OVERRIDES = + +include $(top_srcdir)/common/gtk-doc-plugins.mak diff --git a/docs/plugins/gst-plugins-bad-plugins-decl-list.txt b/docs/plugins/gst-plugins-bad-plugins-decl-list.txt new file mode 100644 index 00000000..ad63ed4b --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins-decl-list.txt @@ -0,0 +1,18 @@ +<SECTION> +<FILE>dfbvideosink</FILE> +GST_TYPE_DFBSURFACE +GST_IS_DFBSURFACE +GST_DFBSURFACE +GstDfbSurface +GstDfbVMode +<TITLE>GstDfbVideoSink</TITLE> +gst_dfbsurface_get_type +<SUBSECTION Standard> +GST_DFBVIDEOSINK +GST_IS_DFBVIDEOSINK +GST_TYPE_DFBVIDEOSINK +gst_dfbvideosink_get_type +GST_DFBVIDEOSINK_CLASS +GST_IS_DFBVIDEOSINK_CLASS +</SECTION> + diff --git a/docs/plugins/gst-plugins-bad-plugins-decl.txt b/docs/plugins/gst-plugins-bad-plugins-decl.txt new file mode 100644 index 00000000..4e7cf514 --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins-decl.txt @@ -0,0 +1,119 @@ +<MACRO> +<NAME>GST_TYPE_DFBVIDEOSINK</NAME> +#define GST_TYPE_DFBVIDEOSINK (gst_dfbvideosink_get_type()) +</MACRO> +<MACRO> +<NAME>GST_DFBVIDEOSINK</NAME> +#define GST_DFBVIDEOSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DFBVIDEOSINK, GstDfbVideoSink)) +</MACRO> +<MACRO> +<NAME>GST_DFBVIDEOSINK_CLASS</NAME> +#define GST_DFBVIDEOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DFBVIDEOSINK, GstDfbVideoSink)) +</MACRO> +<MACRO> +<NAME>GST_IS_DFBVIDEOSINK</NAME> +#define GST_IS_DFBVIDEOSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DFBVIDEOSINK)) +</MACRO> +<MACRO> +<NAME>GST_IS_DFBVIDEOSINK_CLASS</NAME> +#define GST_IS_DFBVIDEOSINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DFBVIDEOSINK)) +</MACRO> +<STRUCT> +<NAME>GstDfbVideoSink</NAME> +</STRUCT> +<STRUCT> +<NAME>GstDfbVideoSinkClass</NAME> +</STRUCT> +<MACRO> +<NAME>GST_TYPE_DFBSURFACE</NAME> +#define GST_TYPE_DFBSURFACE (gst_dfbsurface_get_type()) +</MACRO> +<MACRO> +<NAME>GST_IS_DFBSURFACE</NAME> +#define GST_IS_DFBSURFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DFBSURFACE)) +</MACRO> +<MACRO> +<NAME>GST_DFBSURFACE</NAME> +#define GST_DFBSURFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DFBSURFACE, GstDfbSurface)) +</MACRO> +<STRUCT> +<NAME>GstDfbSurface</NAME> +</STRUCT> +<STRUCT> +<NAME>GstDfbSurface</NAME> +struct _GstDfbSurface { + GstBuffer buffer; /* We extend GstBuffer */ + + IDirectFBSurface *surface; + + gint width; + gint height; + + gboolean locked; + + DFBSurfacePixelFormat pixel_format; + + GstDfbVideoSink *dfbvideosink; +}; +</STRUCT> +<STRUCT> +<NAME>GstDfbVMode</NAME> +</STRUCT> +<STRUCT> +<NAME>GstDfbVMode</NAME> +struct _GstDfbVMode { + gint width; + gint height; + gint bpp; +}; +</STRUCT> +<STRUCT> +<NAME>GstDfbVideoSink</NAME> +struct _GstDfbVideoSink { + /* Our element stuff */ + GstVideoSink videosink; + + GSList *buffer_pool; + + gdouble framerate; + gint video_width, video_height; /* size of incoming video */ + gint out_width, out_height; + + /* Standalone */ + IDirectFB *dfb; + + GSList *vmodes; /* Video modes */ + + gint layer_id; + IDirectFBDisplayLayer *layer; + IDirectFBSurface *primary; + IDirectFBEventBuffer *event_buffer; + GThread *event_thread; + + /* Embedded */ + IDirectFBSurface *ext_surface; + + DFBSurfacePixelFormat pixel_format; + + gboolean hw_scaling; + gboolean backbuffer; + gboolean setup; + gboolean running; +}; +</STRUCT> +<STRUCT> +<NAME>GstDfbVideoSinkClass</NAME> +struct _GstDfbVideoSinkClass { + GstVideoSinkClass parent_class; +}; +</STRUCT> +<FUNCTION> +<NAME>gst_dfbvideosink_get_type</NAME> +<RETURNS>GType </RETURNS> +void +</FUNCTION> +<FUNCTION> +<NAME>gst_dfbsurface_get_type</NAME> +<RETURNS>GType </RETURNS> +void +</FUNCTION> diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml new file mode 100644 index 00000000..44c115fa --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ +<!ENTITY % version-entities SYSTEM "version.entities"> +%version-entities; +]> + +<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude"> + <bookinfo> + <title>GStreamer Bad Plugins &GST_MAJORMINOR; Plugins Reference Manual</title> + </bookinfo> + + <chapter> + <title>gst-plugins-bad Elements</title> + + <xi:include href="xml/element-dfbvideosink.xml" /> + </chapter> + + <chapter> + <title>gst-plugins-bad Plugins</title> + + <xi:include href="xml/plugin-dfbvideosink.xml" /> + + </chapter> +</book> diff --git a/docs/plugins/gst-plugins-bad-plugins-overrides.txt b/docs/plugins/gst-plugins-bad-plugins-overrides.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins-overrides.txt diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt new file mode 100644 index 00000000..da82aa0c --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -0,0 +1,8 @@ +<SECTION> +<FILE>element-dfbvideosink</FILE> +GstDfbVideoSink +<TITLE>dfbvideosink</TITLE> +<SUBSECTION Standard> +GstDfbVideoSinkClass +</SECTION> + diff --git a/docs/plugins/gst-plugins-bad-plugins-undocumented.txt b/docs/plugins/gst-plugins-bad-plugins-undocumented.txt new file mode 100644 index 00000000..298053be --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins-undocumented.txt @@ -0,0 +1,9 @@ +75% symbol docs coverage. +3 symbols documented. +0 symbols incomplete. +1 not documented. + + +GstDfbVideoSink + + diff --git a/docs/plugins/gst-plugins-bad-plugins.args b/docs/plugins/gst-plugins-bad-plugins.args new file mode 100644 index 00000000..91294e2a --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins.args @@ -0,0 +1,9 @@ +<ARG> +<NAME>GstDfbVideoSink::surface</NAME> +<TYPE>gpointer</TYPE> +<RANGE></RANGE> +<FLAGS>w</FLAGS> +<NICK>Destination surface</NICK> +<BLURB>Render video frames to this surface. The pointer you pass here has to point to an IDirectFBSurface * interface</BLURB> +<DEFAULT>NULL</DEFAULT> +</ARG> diff --git a/docs/plugins/gst-plugins-bad-plugins.hierarchy b/docs/plugins/gst-plugins-bad-plugins.hierarchy new file mode 100644 index 00000000..5f18922a --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins.hierarchy @@ -0,0 +1,20 @@ +GObject + GstObject + GstPad + GstPluginFeature + GstElementFactory + GstTypeFindFactory + GstIndexFactory + GstElement + GstBin + GstPipeline + GstQueue + GstBaseSink + GstVideoSink + GstDfbVideoSink + GstPlugin + GstRegistry + GstPadTemplate + GstSignalObject +GInterface + GstChildProxy diff --git a/docs/plugins/gst-plugins-bad-plugins.interfaces b/docs/plugins/gst-plugins-bad-plugins.interfaces new file mode 100644 index 00000000..fc9ba12c --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins.interfaces @@ -0,0 +1,2 @@ +GstBin GstChildProxy +GstPipeline GstChildProxy diff --git a/docs/plugins/gst-plugins-bad-plugins.prerequisites b/docs/plugins/gst-plugins-bad-plugins.prerequisites new file mode 100644 index 00000000..f526a9f6 --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins.prerequisites @@ -0,0 +1 @@ +GstChildProxy GstObject diff --git a/docs/plugins/gst-plugins-bad-plugins.signals b/docs/plugins/gst-plugins-bad-plugins.signals new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins.signals @@ -0,0 +1 @@ + diff --git a/docs/plugins/gst-plugins-bad-plugins.types b/docs/plugins/gst-plugins-bad-plugins.types new file mode 100644 index 00000000..9f4950e7 --- /dev/null +++ b/docs/plugins/gst-plugins-bad-plugins.types @@ -0,0 +1 @@ +#include <gst/gst.h> diff --git a/docs/plugins/inspect/plugin-dfbvideosink.xml b/docs/plugins/inspect/plugin-dfbvideosink.xml new file mode 100644 index 00000000..83f5fb4e --- /dev/null +++ b/docs/plugins/inspect/plugin-dfbvideosink.xml @@ -0,0 +1,20 @@ +<plugin> + <name>dfbvideosink</name> + <description>DirectFB video sink</description> + <filename>../../ext/directfb/.libs/libgstdfbvideosink.so</filename> + <basename>libgstdfbvideosink.so</basename> + <version>0.9.4</version> + <license>LGPL</license> + <source>gst-plugins-bad</source> + <package>GStreamer source release</package> + <origin>http://gstreamer.freedesktop.org/</origin> + <elements> + <element> + <name>dfbvideosink</name> + <longname>DirectFB video sink</longname> + <class>Sink/Video</class> + <description>DirectFB video sink</description> + <author>Julien Moutte <julien@moutte.net></author> + </element> + </elements> +</plugin> diff --git a/docs/version.entities.in b/docs/version.entities.in new file mode 100644 index 00000000..79a68981 --- /dev/null +++ b/docs/version.entities.in @@ -0,0 +1,2 @@ +<!ENTITY GST_MAJORMINOR "@GST_MAJORMINOR@"> +<!ENTITY GST_VERSION "@VERSION@"> diff --git a/examples/Makefile.am b/examples/Makefile.am index 4620963e..8606cf8a 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,14 +1,14 @@ -if HAVE_GTK -GTK_SUBDIRS=dynparams level $(FT2_SUBDIRS) -else -GTK_SUBDIRS= -endif +#if HAVE_GTK +#GTK_SUBDIRS=dynparams level $(FT2_SUBDIRS) +#else +#GTK_SUBDIRS= +#endif -if USE_GCONF -GCONF_SUBDIRS=gstplay +if USE_DIRECTFB +DIRECTFB_DIR=directfb else -GCONF_SUBDIRS= +DIRECTFB_DIR= endif -SUBDIRS=$(GTK_SUBDIRS) $(GCONF_SUBDIRS) switch -DIST_SUBDIRS=capsfilter dynparams indexing gstplay switch level +SUBDIRS=$(GTK_SUBDIRS) $(GCONF_SUBDIRS) $(DIRECTFB_DIR) +DIST_SUBDIRS=capsfilter dynparams indexing gstplay directfb switch level diff --git a/examples/directfb/Makefile.am b/examples/directfb/Makefile.am new file mode 100644 index 00000000..a9111488 --- /dev/null +++ b/examples/directfb/Makefile.am @@ -0,0 +1,6 @@ +noinst_PROGRAMS = gstdfb + +gstdfb_SOURCES = gstdfb.c +gstdfb_CFLAGS = $(GST_CFLAGS) $(DIRECTFB_CFLAGS) +gstdfb_LDFLAGS = $(GST_LIBS) $(DIRECTFB_LIBS) + diff --git a/examples/directfb/decker.ttf b/examples/directfb/decker.ttf Binary files differnew file mode 100644 index 00000000..5e721cfd --- /dev/null +++ b/examples/directfb/decker.ttf diff --git a/examples/directfb/dfblogo.png b/examples/directfb/dfblogo.png Binary files differnew file mode 100644 index 00000000..8b7d8833 --- /dev/null +++ b/examples/directfb/dfblogo.png diff --git a/examples/directfb/gstdfb.c b/examples/directfb/gstdfb.c new file mode 100644 index 00000000..58114204 --- /dev/null +++ b/examples/directfb/gstdfb.c @@ -0,0 +1,514 @@ +/* + (c) Copyright 2000-2002 convergence integrated media GmbH. + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org> and + Julien Moutte <julien@moutte.net>. + + This file is subject to the terms and conditions of the MIT License: + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <math.h> +#include <time.h> + +#include <directfb.h> +#include <gst/gst.h> +#include <string.h> + +/* macro for a safe call to DirectFB functions */ +#define DFBCHECK(x...) \ + { \ + err = x; \ + if (err != DFB_OK) { \ + fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + DirectFBErrorFatal( #x, err ); \ + } \ + } + +typedef struct +{ + const gchar *padname; + GstPad *target; + GstElement *bin; +} dyn_link; + +static inline long +myclock () +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +static void +dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data) +{ + dyn_link *connect = (dyn_link *) data; + + if (connect->padname == NULL || + !strcmp (gst_pad_get_name (newpad), connect->padname)) { + gst_pad_link (newpad, connect->target); + } +} + +static void +size_changed (GObject * obj, GParamSpec * pspec, IDirectFBWindow * window) +{ + GstPad *pad = GST_PAD (obj); + GstStructure *s; + GstCaps *caps; + + if (!(caps = gst_pad_get_negotiated_caps (pad))) + return; + + s = gst_caps_get_structure (caps, 0); + if (s) { + gint width, height; + + if (!(gst_structure_get_int (s, "width", &width) && + gst_structure_get_int (s, "height", &height))) + return; + + window->Resize (window, width, height); + } +} + +static void +setup_dynamic_link (GstElement * element, const gchar * padname, + GstPad * target, GstElement * bin) +{ + dyn_link *connect; + + connect = g_new0 (dyn_link, 1); + connect->padname = g_strdup (padname); + connect->target = target; + connect->bin = bin; + + g_signal_connect (G_OBJECT (element), "pad-added", G_CALLBACK (dynamic_link), + connect); +} + +int +main (int argc, char *argv[]) +{ + IDirectFB *dfb; + IDirectFBDisplayLayer *layer; + + IDirectFBImageProvider *provider; + IDirectFBVideoProvider *video_provider; + + IDirectFBSurface *bgsurface; + + IDirectFBWindow *window1; + IDirectFBWindow *window2; + IDirectFBWindow *window3; + IDirectFBSurface *window_surface1; + IDirectFBSurface *window_surface2; + IDirectFBSurface *window_surface3; + + GstElement *pipeline; + + IDirectFBEventBuffer *buffer; + + IDirectFBFont *font; + + DFBDisplayLayerConfig layer_config; + DFBGraphicsDeviceDescription gdesc; + DFBWindowID id1; + DFBWindowID id2; + DFBWindowID id3; + + int fontheight; + int err; + int quit = 0; + + + DFBCHECK (DirectFBInit (&argc, &argv)); + gst_init (&argc, &argv); + DFBCHECK (DirectFBCreate (&dfb)); + + dfb->GetDeviceDescription (dfb, &gdesc); + + DFBCHECK (dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer)); + + layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE); + + if (!((gdesc.blitting_flags & DSBLIT_BLEND_ALPHACHANNEL) && + (gdesc.blitting_flags & DSBLIT_BLEND_COLORALPHA))) { + layer_config.flags = DLCONF_BUFFERMODE; + layer_config.buffermode = DLBM_BACKSYSTEM; + + layer->SetConfiguration (layer, &layer_config); + } + + layer->GetConfiguration (layer, &layer_config); + layer->EnableCursor (layer, 1); + + { + DFBFontDescription desc; + + desc.flags = DFDESC_HEIGHT; + desc.height = layer_config.width / 50; + + DFBCHECK (dfb->CreateFont (dfb, "decker.ttf", &desc, &font)); + font->GetHeight (font, &fontheight); + } + + if (argc < 2 || + dfb->CreateVideoProvider (dfb, argv[1], &video_provider) != DFB_OK) { + video_provider = NULL; + } + + { + DFBSurfaceDescription desc; + + desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT; + desc.width = layer_config.width; + desc.height = layer_config.height; + + DFBCHECK (dfb->CreateSurface (dfb, &desc, &bgsurface)); + + DFBCHECK (bgsurface->SetFont (bgsurface, font)); + + bgsurface->SetColor (bgsurface, 0xCF, 0xCF, 0xFF, 0xFF); + bgsurface->DrawString (bgsurface, + "Move the mouse over a window to activate it.", + -1, 0, 0, DSTF_LEFT | DSTF_TOP); + + bgsurface->SetColor (bgsurface, 0xCF, 0xDF, 0xCF, 0xFF); + bgsurface->DrawString (bgsurface, + "Press left mouse button and drag to move the window.", + -1, 0, fontheight, DSTF_LEFT | DSTF_TOP); + + bgsurface->SetColor (bgsurface, 0xCF, 0xEF, 0x9F, 0xFF); + bgsurface->DrawString (bgsurface, + "Press middle mouse button to raise/lower the window.", + -1, 0, fontheight * 2, DSTF_LEFT | DSTF_TOP); + + bgsurface->SetColor (bgsurface, 0xCF, 0xFF, 0x6F, 0xFF); + bgsurface->DrawString (bgsurface, + "Press right mouse button when you are done.", -1, + 0, fontheight * 3, DSTF_LEFT | DSTF_TOP); + + layer->SetBackgroundImage (layer, bgsurface); + layer->SetBackgroundMode (layer, DLBM_IMAGE); + } + + { + DFBSurfaceDescription sdsc; + DFBWindowDescription desc; + + desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT); + + if (!video_provider) { + desc.caps = DWCAPS_ALPHACHANNEL; + desc.flags |= DWDESC_CAPS; + + sdsc.width = 300; + sdsc.height = 200; + } else { + video_provider->GetSurfaceDescription (video_provider, &sdsc); + + if (sdsc.flags & DSDESC_CAPS) { + desc.flags |= DWDESC_SURFACE_CAPS; + desc.surface_caps = sdsc.caps; + } + } + + desc.posx = 20; + desc.posy = 120; + desc.width = sdsc.width; + desc.height = sdsc.height; + + DFBCHECK (layer->CreateWindow (layer, &desc, &window2)); + window2->GetSurface (window2, &window_surface2); + + window2->SetOpacity (window2, 0xFF); + + window2->GetID (window2, &id2); + + window2->CreateEventBuffer (window2, &buffer); + + if (video_provider) { + video_provider->PlayTo (video_provider, window_surface2, + NULL, NULL, NULL); + } else { + window_surface2->SetColor (window_surface2, 0x00, 0x30, 0x10, 0xc0); + window_surface2->DrawRectangle (window_surface2, + 0, 0, desc.width, desc.height); + window_surface2->SetColor (window_surface2, 0x80, 0xa0, 0x00, 0x90); + window_surface2->FillRectangle (window_surface2, + 1, 1, desc.width - 2, desc.height - 2); + } + + window_surface2->Flip (window_surface2, NULL, 0); + } + + { + DFBWindowDescription desc; + + desc.flags = (DWDESC_POSX | DWDESC_POSY | + DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS); + desc.posx = 200; + desc.posy = 200; + desc.width = 512; + desc.height = 145; + desc.caps = DWCAPS_ALPHACHANNEL; + + DFBCHECK (layer->CreateWindow (layer, &desc, &window1)); + window1->GetSurface (window1, &window_surface1); + + DFBCHECK (dfb->CreateImageProvider (dfb, "dfblogo.png", &provider)); + provider->RenderTo (provider, window_surface1, NULL); + + window_surface1->SetColor (window_surface1, 0xFF, 0x20, 0x20, 0x90); + window_surface1->DrawRectangle (window_surface1, + 0, 0, desc.width, desc.height); + + window_surface1->Flip (window_surface1, NULL, 0); + + provider->Release (provider); + + window1->AttachEventBuffer (window1, buffer); + + window1->SetOpacity (window1, 0xFF); + + window1->GetID (window1, &id1); + } + + { + DFBWindowDescription desc; + GstElement *src, *decode; + GstElement *v_queue, *v_scale, *cs, *v_sink; + GstElement *a_queue, *conv, *a_sink; + GstPad *v_pad, *a_pad; + + desc.flags = (DWDESC_POSX | DWDESC_POSY | + DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS); + desc.posx = 10; + desc.posy = 10; + desc.width = 100; + desc.height = 100; + desc.caps = DWCAPS_ALPHACHANNEL; + + DFBCHECK (layer->CreateWindow (layer, &desc, &window3)); + window3->GetSurface (window3, &window_surface3); + + window3->AttachEventBuffer (window3, buffer); + + window3->SetOpacity (window3, 0xFF); + + window3->GetID (window3, &id3); + + pipeline = gst_pipeline_new ("pipeline"); + + src = gst_element_factory_make ("gnomevfssrc", "src"); + g_object_set (src, "location", argv[1], NULL); + decode = gst_element_factory_make ("decodebin", "decode"); + + v_queue = gst_element_factory_make ("queue", "v_queue"); + v_scale = gst_element_factory_make ("videoscale", "v_scale"); + cs = gst_element_factory_make ("ffmpegcolorspace", "cs"); + v_sink = gst_element_factory_make ("dfbvideosink", "v_sink"); + g_object_set (v_sink, "surface", window_surface3, NULL); + + a_queue = gst_element_factory_make ("queue", "a_queue"); + conv = gst_element_factory_make ("audioconvert", "conv"); + a_sink = gst_element_factory_make ("alsasink", "a_sink"); + + gst_bin_add_many (GST_BIN (pipeline), src, decode, NULL); + gst_bin_add_many (GST_BIN (pipeline), v_queue, v_scale, cs, v_sink, NULL); + gst_bin_add_many (GST_BIN (pipeline), a_queue, conv, a_sink, NULL); + + gst_element_link (src, decode); + gst_element_link_many (v_queue, v_scale, cs, v_sink, NULL); + gst_element_link_many (a_queue, conv, a_sink, NULL); + + v_pad = gst_element_get_pad (v_queue, "sink"); + a_pad = gst_element_get_pad (a_queue, "sink"); + + setup_dynamic_link (decode, NULL, v_pad, NULL); + setup_dynamic_link (decode, NULL, a_pad, NULL); + + /* We want to know when the size is defined */ + g_signal_connect (v_pad, "notify::caps", G_CALLBACK (size_changed), + window3); + + gst_object_unref (a_pad); + gst_object_unref (v_pad); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + } + + window1->RequestFocus (window1); + window1->RaiseToTop (window1); + + while (!quit) { + static IDirectFBWindow *active = NULL; + static int grabbed = 0; + static int startx = 0; + static int starty = 0; + static int endx = 0; + static int endy = 0; + DFBWindowEvent evt; + + buffer->WaitForEventWithTimeout (buffer, 0, 10); + + while (buffer->GetEvent (buffer, DFB_EVENT (&evt)) == DFB_OK) { + IDirectFBWindow *window; + + if (evt.window_id == id1) + window = window1; + else if (evt.window_id == id3) + window = window3; + else + window = window2; + + if (evt.type == DWET_GOTFOCUS) { + active = window; + } else if (active) { + switch (evt.type) { + + case DWET_BUTTONDOWN: + if (!grabbed && evt.button == DIBI_LEFT) { + grabbed = 1; + startx = evt.cx; + starty = evt.cy; + window->GrabPointer (window); + } + break; + + case DWET_BUTTONUP: + switch (evt.button) { + case DIBI_LEFT: + if (grabbed) { + window->UngrabPointer (window); + grabbed = 0; + } + break; + case DIBI_MIDDLE: + active->RaiseToTop (active); + break; + case DIBI_RIGHT: + quit = DIKS_DOWN; + break; + default: + break; + } + break; + + case DWET_KEYDOWN: + if (grabbed) + break; + switch (evt.key_id) { + case DIKI_RIGHT: + active->Move (active, 1, 0); + break; + case DIKI_LEFT: + active->Move (active, -1, 0); + break; + case DIKI_UP: + active->Move (active, 0, -1); + break; + case DIKI_DOWN: + active->Move (active, 0, 1); + break; + default: + break; + } + break; + + case DWET_LOSTFOCUS: + if (!grabbed && active == window) + active = NULL; + break; + + default: + break; + + } + } + + switch (evt.type) { + + case DWET_MOTION: + endx = evt.cx; + endy = evt.cy; + break; + + case DWET_KEYDOWN: + switch (evt.key_symbol) { + case DIKS_ESCAPE: + case DIKS_SMALL_Q: + case DIKS_CAPITAL_Q: + case DIKS_BACK: + case DIKS_STOP: + quit = 1; + break; + default: + break; + } + break; + + default: + break; + } + } + + if (video_provider) + window_surface2->Flip (window_surface2, NULL, 0); + + if (active) { + if (grabbed) { + active->Move (active, endx - startx, endy - starty); + startx = endx; + starty = endy; + } + active->SetOpacity (active, (sin (myclock () / 300.0) * 85) + 170); + } + } + + if (video_provider) + video_provider->Release (video_provider); + + gst_element_set_state (pipeline, GST_STATE_NULL); + + buffer->Release (buffer); + font->Release (font); + window_surface2->Release (window_surface2); + window_surface1->Release (window_surface1); + window_surface3->Release (window_surface3); + window2->Release (window2); + window1->Release (window1); + window3->Release (window3); + layer->Release (layer); + bgsurface->Release (bgsurface); + dfb->Release (dfb); + + return 42; +} |