diff options
author | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2008-10-23 20:01:57 -0700 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2008-10-23 23:04:03 -0700 |
commit | dcd2f6b4f0a89dd884e3d741dae055e53e4c08ac (patch) | |
tree | abd440eebf3728a32f4fc0dea3d3e09623bbf25a | |
parent | 3ada7b1b24851081bb4209885887f346afe69b19 (diff) | |
download | telepathy-farstream-dcd2f6b4f0a89dd884e3d741dae055e53e4c08ac.tar.gz |
Remove stream-engine and keep only the library
54 files changed, 15 insertions, 10187 deletions
diff --git a/Makefile.am b/Makefile.am index 8ac9d26..617df65 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,6 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = tools telepathy-farsight api src test doc data - -confdir = $(sysconfdir)/stream-engine -conf_DATA = gstcodecs.conf +SUBDIRS = telepathy-farsight doc EXTRA_DIST = $(conf_DATA) @@ -1,4 +0,0 @@ -general tidyup -add reporting when the max no streams/sessions are allocated -preallocate elements/pipelines -att watch for session/stream handlers falling off the bus diff --git a/api/Makefile.am b/api/Makefile.am deleted file mode 100644 index 4a32b2b..0000000 --- a/api/Makefile.am +++ /dev/null @@ -1,127 +0,0 @@ -tools_dir = $(top_srcdir)/tools - -AM_CFLAGS = \ - -I${top_srcdir} -I${top_builddir} \ - $(ERROR_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(TELEPATHY_CFLAGS) - -EXTRA_DIST = \ - all.xml \ - misc.xml \ - Stream_Engine.xml - -noinst_LTLIBRARIES = libstream-engine-api.la - -libstream_engine_api_la_LIBADD = \ - $(TELEPATHY_LIBS) - -# The client-specific parts are built into a separate .o file, so the linker -# can discard them when linking services. The service-specific parts are -# in svc-*.c, so we don't need an extensions-svc.c. -libstream_engine_api_la_SOURCES = \ - api.c \ - api-cli.c \ - api.h - -nodist_libstream_engine_api_la_SOURCES = \ - _gen/signals-marshal.c \ - _gen/signals-marshal.h \ - _gen/signals-marshal.list \ - _gen/register-dbus-glib-marshallers-body.h \ - _gen/enums.h \ - _gen/gtypes.h \ - _gen/gtypes-body.h \ - _gen/interfaces.h \ - _gen/interfaces-body.h \ - _gen/cli-misc.h \ - _gen/cli-misc-body.h \ - _gen/svc-misc.h \ - _gen/svc-misc.c - -BUILT_SOURCES = \ - _gen/all.xml \ - _gen/misc.xml \ - $(nodist_libstream_engine_api_la_SOURCES) \ - api.html - -CLEANFILES = $(BUILT_SOURCES) - -XSLTPROCFLAGS = --nonet --novalid - -_gen/%.xml: %.xml $(wildcard *.xml) Makefile.am - $(mkdir_p) _gen - $(XSLTPROC) $(XSLTPROCFLAGS) --xinclude $(tools_dir)/identity.xsl \ - $< > $@ - -# Generated files which can be generated for all categories simultaneously - -api.html: _gen/all.xml $(tools_dir)/doc-generator.xsl Makefile.am - $(XSLTPROC) $(XSLTPROCFLAGS) \ - $(tools_dir)/doc-generator.xsl \ - $< > $@ - -_gen/gtypes.h _gen/gtypes-body.h: _gen/all.xml \ - $(top_srcdir)/tools/glib-gtypes-generator.py Makefile.am - $(PYTHON) $(top_srcdir)/tools/glib-gtypes-generator.py \ - $< _gen/gtypes Stream_Engine - -_gen/signals-marshal.list: _gen/all.xml \ - $(tools_dir)/glib-signals-marshal-gen.py Makefile.am - $(PYTHON) $(tools_dir)/glib-signals-marshal-gen.py $< > $@ - -_gen/signals-marshal.h: _gen/signals-marshal.list Makefile.am - $(GLIB_GENMARSHAL) --header --prefix=_se_api_marshal $< > $@ - -_gen/signals-marshal.c: _gen/signals-marshal.list Makefile.am - { echo '#include "_gen/signals-marshal.h"' && \ - $(GLIB_GENMARSHAL) --body --prefix=_se_api_marshal $< ; } > $@ - -_gen/register-dbus-glib-marshallers-body.h: _gen/all.xml \ - $(tools_dir)/glib-client-marshaller-gen.py Makefile.am - $(PYTHON) $(tools_dir)/glib-client-marshaller-gen.py $< \ - _se_api > $@ - -_gen/enums.h: _gen/all.xml $(tools_dir)/c-constants-generator.xsl Makefile.am - $(XSLTPROC) $(XSLTPROCFLAGS) \ - --stringparam mixed-case-prefix Stream_Engine \ - $(tools_dir)/c-constants-generator.xsl \ - $< > $@ - -_gen/interfaces.h: _gen/all.xml \ - $(tools_dir)/glib-interfaces-generator.xsl \ - $(tools_dir)/c-interfaces-generator.xsl Makefile.am - $(XSLTPROC) $(XSLTPROCFLAGS) \ - --stringparam mixed-case-prefix Stream_Engine \ - $(tools_dir)/glib-interfaces-generator.xsl \ - $< > $@ - -_gen/interfaces-body.h: _gen/all.xml \ - $(tools_dir)/glib-interfaces-body-generator.xsl \ - $(tools_dir)/c-interfaces-generator.xsl Makefile.am - $(XSLTPROC) $(XSLTPROCFLAGS) \ - --stringparam mixed-case-prefix Stream_Engine \ - $(tools_dir)/glib-interfaces-body-generator.xsl \ - $< > $@ - -# Generated files which must be generated per "category". Each TpProxy -# subclass you want to use with --subclass will need to have its own category, -# although you can subdivide further if you want. - -_gen/svc-%.c _gen/svc-%.h: _gen/%.xml \ - $(tools_dir)/glib-ginterface-gen.py \ - Makefile.am - $(PYTHON) $(tools_dir)/glib-ginterface-gen.py \ - --filename=_gen/svc-$* --signal-marshal-prefix=_se_api \ - --include='<telepathy-glib/dbus.h>' \ - --include='"_gen/signals-marshal.h"' \ - --not-implemented-func='tp_dbus_g_method_return_not_implemented' \ - $< Stream_Engine/Svc_ - -_gen/cli-misc-body.h _gen/cli-misc.h: _gen/misc.xml \ - $(tools_dir)/glib-client-gen.py Makefile.am - $(PYTHON) $(tools_dir)/glib-client-gen.py \ - --group=misc \ - --iface-quark-prefix=STREAM_ENGINE_IFACE_QUARK \ - $< Stream_Engine_Cli _gen/cli-misc diff --git a/api/Stream_Engine.xml b/api/Stream_Engine.xml deleted file mode 100644 index 3e105e5..0000000 --- a/api/Stream_Engine.xml +++ /dev/null @@ -1,75 +0,0 @@ -<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> -<node name="/Stream_Engine" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - <interface name="org.maemo.Telepathy.StreamEngine"> - <method name="SetOutputVolume"> - <arg direction="in" type="o" name="channel_path" /> - <arg direction="in" type="u" name="stream_id" /> - <arg direction="in" type="u" name="volume" /> - </method> - <method name="SetInputVolume"> - <arg direction="in" type="o" name="channel_path" /> - <arg direction="in" type="u" name="stream_id" /> - <arg direction="in" type="u" name="volume" /> - </method> - <method name="MuteInput"> - <arg direction="in" type="o" name="channel_path" /> - <arg direction="in" type="u" name="stream_id" /> - <arg direction="in" type="b" name="mute_state" /> - </method> - <method name="MuteOutput"> - <arg direction="in" type="o" name="channel_path" /> - <arg direction="in" type="u" name="stream_id" /> - <arg direction="in" type="b" name="mute_state" /> - </method> - <method name="GetOutputWindow"> - <arg direction="in" type="o" name="channel_path" /> - <arg direction="in" type="u" name="stream_id" /> - <arg direction="out" type="u" name="window" /> - </method> - <method name="CreatePreviewWindow"> - <arg direction="out" type="u" name="window" /> - </method> - <signal name="Receiving"> - <arg type="o" name="channel_path" /> - <arg type="u" name="stream_id" /> - <arg type="b" name="state" /> - </signal> - <method name="Shutdown"> - </method> - - <method name="AttachToChannel"> - <arg direction="in" type="s" name="Bus_Name" tp:type="DBus_Bus_Name"> - <tp:docstring> - The bus name of the connection and channel - </tp:docstring> - </arg> - <arg direction="in" type="o" name="Connection"> - <tp:docstring> - The object-path of the connection that owns the channel - </tp:docstring> - </arg> - <arg direction="in" type="s" tp:type="DBus_Interface" name="Channel_Type"> - <tp:docstring> - The channel type - </tp:docstring> - </arg> - <arg direction="in" type="o" name="Channel"> - <tp:docstring> - The object-path of the channel - </tp:docstring> - </arg> - <arg direction="in" type="u" tp:type="Handle_Type" name="Handle_Type"> - <tp:docstring>The type of the handle that the channel communicates - with, or 0 if there is no associated handle</tp:docstring> - </arg> - <arg direction="in" type="u" tp:type="Handle" name="Handle"> - <tp:docstring>The handle that the channel communicates with, - or 0 if there is no associated handle</tp:docstring> - </arg> - <tp:docstring> - Called to tell Stream Engine to Attach itself to a channel. - </tp:docstring> - <!-- FIXME: possible errors? --> - </method> - </interface> -</node> diff --git a/api/all.xml b/api/all.xml deleted file mode 100644 index 4cc9b7c..0000000 --- a/api/all.xml +++ /dev/null @@ -1,9 +0,0 @@ -<tp:spec - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - xmlns:xi="http://www.w3.org/2001/XInclude"> - -<tp:title>Stream Engine API and extensions</tp:title> - -<xi:include href="misc.xml"/> - -</tp:spec> diff --git a/api/api-cli.c b/api/api-cli.c deleted file mode 100644 index b56255d..0000000 --- a/api/api-cli.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "api/api.h" - -#include <telepathy-glib/proxy-subclass.h> - -static void _se_api_register_dbus_glib_marshallers (void); - -/* include auto-generated stubs for client-specific code */ -#include "_gen/signals-marshal.h" -#include "_gen/cli-misc-body.h" -#include "_gen/register-dbus-glib-marshallers-body.h" - -static gpointer -stream_engine_cli_once (gpointer data G_GNUC_UNUSED) -{ - _se_api_register_dbus_glib_marshallers (); - - tp_proxy_or_subclass_hook_on_interface_add (TP_TYPE_PROXY, - stream_engine_cli_misc_add_signals); - - return NULL; -} - -void -stream_engine_cli_init (void) -{ - static GOnce once = G_ONCE_INIT; - - g_once (&once, stream_engine_cli_once, NULL); -} diff --git a/api/api.c b/api/api.c deleted file mode 100644 index 8218122..0000000 --- a/api/api.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "api/api.h" - -#include <telepathy-glib/proxy.h> - -/* include auto-generated stubs for things common to service and client */ -#include "api/_gen/gtypes-body.h" -#include "api/_gen/interfaces-body.h" -#include "api/_gen/signals-marshal.h" diff --git a/api/api.h b/api/api.h deleted file mode 100644 index 2600a4a..0000000 --- a/api/api.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef STREAM_ENGINE_API_H -#define STREAM_ENGINE_API_H - -#include <glib-object.h> - -#include <telepathy-glib/proxy.h> - -#include "api/_gen/enums.h" -#include "api/_gen/cli-misc.h" -#include "api/_gen/svc-misc.h" - -G_BEGIN_DECLS - -#include "api/_gen/gtypes.h" -#include "api/_gen/interfaces.h" - -void stream_engine_cli_init (void); - -G_END_DECLS - -#endif diff --git a/api/misc.xml b/api/misc.xml deleted file mode 100644 index c73e6ea..0000000 --- a/api/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ -<tp:spec - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - xmlns:xi="http://www.w3.org/2001/XInclude"> - -<tp:title>Stream Engine API</tp:title> - -<xi:include href="Stream_Engine.xml"/> - -</tp:spec> diff --git a/configure.ac b/configure.ac index da249e4..55381d6 100644 --- a/configure.ac +++ b/configure.ac @@ -5,12 +5,12 @@ AC_PREREQ([2.59]) # odd minor -> development series # even minor -> stable series # increment micro for each release within a series -# set stream_engine_release to 1. +# set tp_farsight_release to 1 -m4_define([stream_engine_major_version], [0]) -m4_define([stream_engine_minor_version], [5]) -m4_define([stream_engine_micro_version], [0]) -m4_define([stream_engine_nano_version], [1]) +m4_define([tp_farsight_major_version], [0]) +m4_define([tp_farsight_minor_version], [0]) +m4_define([tp_farsight_micro_version], [0]) +m4_define([tp_farsight_nano_version], [1]) m4_define([tp_farsight_lt_current], [0]) m4_define([tp_farsight_lt_revision], [0]) @@ -18,13 +18,13 @@ m4_define([tp_farsight_lt_age], [0]) # Some magic -m4_define([stream_engine_base_version], - [stream_engine_major_version.stream_engine_minor_version.stream_engine_micro_version]) -m4_define([stream_engine_version], - [m4_if(stream_engine_nano_version, 0, [stream_engine_base_version], - [stream_engine_base_version].[stream_engine_nano_version])]) +m4_define([tp_farsight_base_version], + [tp_farsight_major_version.tp_farsight_minor_version.tp_farsight_micro_version]) +m4_define([tp_farsight_version], + [m4_if(tp_farsight_nano_version, 0, [tp_farsight_base_version], + [tp_farsight_base_version].[tp_farsight_nano_version])]) -AC_INIT([Telepathy Stream Engine], [stream_engine_version], +AC_INIT([Telepathy-Farsight], [tp_farsight_version], [https://bugs.freedesktop.org/enter_bug.cgi?product=Telepathy]) AC_CONFIG_MACRO_DIR([m4]) @@ -38,18 +38,6 @@ AC_PROG_CC_STDC AC_PROG_INSTALL AC_PROG_LIBTOOL -dnl Check for code generation tools -XSLTPROC= -AC_CHECK_PROGS([XSLTPROC], [xsltproc]) -if test -z "$XSLTPROC"; then - AC_MSG_ERROR([xsltproc (from the libxslt source package) is required]) -fi -PYTHON= -AC_CHECK_PROGS([PYTHON], [python2.3 python2.4 python2.5 python]) -if test -z "$PYTHON"; then - AC_MSG_ERROR([Python is required to compile this package]) -fi - dnl decide error flags AS_COMPILER_FLAG(-Wall, ERROR_CFLAGS="-Wall", ERROR_CFLAGS="") AS_COMPILER_FLAG(-Werror, werror=yes, werror=no) @@ -66,7 +54,7 @@ AS_COMPILER_FLAG(-Wno-unused-parameter, wno_unused_parameter=yes, wno_unused_parameter=no) -ifelse(stream_engine_nano_version, 0, [], +ifelse(tp_farsight_nano_version, 0, [], [ if test x$werror = xyes; then ERROR_CFLAGS="$ERROR_CFLAGS -Werror" @@ -85,9 +73,6 @@ if test "x$enable_coverage" = "xyes"; then CFLAGS="$CFLAGS -g -fprofile-arcs -ftest-coverage" fi -dnl options for building sequence diagrams -SEQ_DIAS - dnl Check for Glib PKG_CHECK_MODULES(GLIB, gobject-2.0 >= 2.4) @@ -102,11 +87,6 @@ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.60, dbus-glib-1 >= 0.60]) AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) -AS_AC_EXPAND(DATADIR, $datadir) -DBUS_SERVICES_DIR="$DATADIR/dbus-1/services" -AC_SUBST(DBUS_SERVICES_DIR) -AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [DBus services directory]) - dnl Check for Telepathy libraries PKG_CHECK_MODULES([TELEPATHY], [telepathy-glib >= 0.7.8]) @@ -125,26 +105,6 @@ PKG_CHECK_MODULES(GST_INTERFACES, [gstreamer-interfaces-0.10 >= 0.10.18],[], AC_SUBST(GST_INTERFACES_CFLAGS) AC_SUBST(GST_INTERFACES_LIBS) - -dnl libx11 -PKG_CHECK_MODULES(X11, [x11 gtk+-2.0]) -AC_SUBST(X11_CFLAGS) -AC_SUBST(X11_LIBS) - -AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) -AC_DEFINE_UNQUOTED(SYSCONFDIR, "$SYSCONFDIR", [System configuration directory]) - -dnl maemo support -AC_ARG_ENABLE( maemo-support, - AC_HELP_STRING([--enable-maemo-support],[compile with Maemo support]), - maemo_support=$enableval, maemo_support=no ) - -if test x$maemo_support = xyes; then - AC_DEFINE(MAEMO_OSSO_SUPPORT, , [Enable Maemo support]) -fi - -AM_CONDITIONAL(MAEMO_OSSO_SUPPORT, test x$MAEMO_OSSO_SUPPORT = xyes) - GTK_DOC_CHECK([1.10]) LT_CURRENT=tp_farsight_lt_current @@ -156,15 +116,9 @@ AC_SUBST([LT_AGE]) AC_OUTPUT( Makefile \ - api/Makefile \ - data/Makefile \ doc/Makefile \ doc/lib/Makefile \ telepathy-farsight/Makefile \ - telepathy-farsight/telepathy-farsight.pc \ - src/Makefile \ - test/Makefile \ - test/python/Makefile \ - tools/Makefile + telepathy-farsight/telepathy-farsight.pc ) diff --git a/data/Makefile.am b/data/Makefile.am deleted file mode 100644 index d8deeb4..0000000 --- a/data/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -# Dbus service file -servicedir = $(DBUS_SERVICES_DIR) -service_in_files = org.maemo.Telepathy.StreamEngine.service.in -EXTRA_DIST=$(service_in_files) -service_DATA = $(service_in_files:.service.in=.service) -CLEANFILES=$(service_DATA) - -# Rule to make the service file with libexecdir expanded -$(service_DATA): $(service_in_files) Makefile.in - sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ diff --git a/data/org.maemo.Telepathy.StreamEngine.service.in b/data/org.maemo.Telepathy.StreamEngine.service.in deleted file mode 100644 index 6f2e334..0000000 --- a/data/org.maemo.Telepathy.StreamEngine.service.in +++ /dev/null @@ -1,3 +0,0 @@ -[D-BUS Service] -Name=org.maemo.Telepathy.StreamEngine -Exec=@libexecdir@/telepathy-stream-engine diff --git a/doc/Makefile.am b/doc/Makefile.am index 14c63ab..0262e4d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,24 +1 @@ SUBDIRS = lib - -CLEANFILES = -EXTRA_DIST = make-call.pic sequence.pic - -if MAKE_SEQ_DIAS - -SEQ_DIA_PICS = make-call.pic -SEQ_DIA_PNGS = $(patsubst %.pic,%.png,$(SEQ_DIA_PICS)) -CLEANFILES += $(SEQ_DIA_PNGS) log.sh test - -all-local: $(SEQ_DIA_PNGS) - -# pic2plot wants sequence.pic in the build dir, so use a hack - copy it in -%.png: %.pic sequence.pic - if ! test -e sequence.pic; then \ - touch copied-sequence-pic && \ - cp $(srcdir)/sequence.pic .; \ - fi - set -o pipefail; $(PIC2PLOT) -Tps --font-name AvantGarde-Book $< | $(CONVERT) -density 112 - $@ ; rm .sequence.temp - if test -e copied-sequence-pic; then \ - rm -f copied-sequence-pic sequence.pic; \ - fi -endif diff --git a/doc/make-call.pic b/doc/make-call.pic deleted file mode 100644 index ff5bbbb..0000000 --- a/doc/make-call.pic +++ /dev/null @@ -1,136 +0,0 @@ -.PS -copy "sequence.pic"; - -# Define the objects -object(Remote,"Remote GTalk"); move; -object(Connmgr,"Gabble");move; -placeholder_object(Channel,"StreamedMediaChannel");move; -placeholder_object(SessionHandler,"SessionHandler");move; -placeholder_object(StreamHandler,"StreamHandler"); -move;move; -placeholder_object(Client,"Stream engine"); -move; -placeholder_object(Session); -move; -placeholder_object(Stream); -step(); - -# Message sequences -active(Remote); -step(); -active(Connmgr); -message(Remote,Connmgr,"jingle initiate") -message(Connmgr,Remote,"prelim accept") -create_message(Connmgr,Channel,"StreamedMediaChannel"); -active(Channel) -create_message(Channel,Client, "StreamEngine"); -create_message(Channel,SessionHandler, "SessionHandler"); -active(Client); -message(Channel,Client,"NewMediaSessionHandler(member,StreamHandler)"); -create_message(Client,Session, "FarsightSession"); -inactive(Client); -step; - -active(SessionHandler) -create_message(SessionHandler,StreamHandler, "StreamHandler"); -active(Client); -message(SessionHandler,Client,"NewMediaStreamHandler(member,StreamHandler)"); -message(Client,Session,"create_stream()"); -create_message(Session,Stream,"FarsightStream"); -return_message(Session,Client); -inactive(SessionHandler); -inactive(Session); - -active(StreamHandler); -message(StreamHandler,Client,"set-remote-codecs(...)"); -active(Stream); -message(Client,Stream,"set_remote_codecs(...)"); -return_message(Stream,Client) -message(Client,Stream,"list_codecs()"); -return_message(Stream,Client); -message(Client,StreamHandler,"codecs(...)"); -return_message(StreamHandler,Client); - -message(Client,Stream,"prepare_transports()"); -return_message(Stream,Client); - -message(Remote,StreamHandler,"jingle candidate"); -message(StreamHandler,Client,"new-candidate(...)"); -message(Client,Stream,"new_remote_candidiate(...)"); -return_message(Stream,Client); - -message(Stream,Client,"new-native-candidate(id)"); -message(Client,Stream,"get_native_candidate(id)"); -return_message(Stream,Client); -message(Client,StreamHandler,"new_native_candidate(...)"); -return_message(StreamHandler,Client); -message(StreamHandler,Remote,"jingle candidiate"); -step; -message(Remote,StreamHandler,"jingle candidate"); -message(StreamHandler,Client,"new-candidate(...)"); -message(Client,Stream,"new_remote_candidiate(...)"); -return_message(Stream,Client); - -message(Stream,Client,"new-native-candidate(id)"); -message(Client,Stream,"get_native_candidate(id)"); -return_message(Stream,Client); -message(Client,StreamHandler,"new_native_candidate(...)"); -return_message(StreamHandler,Client); -message(StreamHandler,Remote,"jingle candidiate"); - -step; - -message(Stream,Client,"native-candidates-prepared"); -message(Client,StreamHandler,"native_candidates_prepared"); -return_message(StreamHandler,Client); - -message(Remote,StreamHandler,"ack candidates"); - -step; -message(Remote,Stream,"STUN") -message(Stream,Remote,"STUN") -step; - -message(Stream,Client,"new-active-candidate-pair"); -message(Client,Stream,"get_native_candidate"); -return_message(Stream,Client); -message(Client,StreamHandler,"new_active_candidate_pair(...)") -message(StreamHandler,Remote,"jingle accept"); -return_message(StreamHandler,Client); -step(); -message(Remote,StreamHandler,"ack accept"); - - -step; -message(Remote,Stream,"RTP+STUN") -message(Stream,Remote,"RTP+STUN") -step; - -message(Remote,StreamHandler,"terminate"); -message(StreamHandler,Client,"stop"); -message(Client,Stream,"state_playing(stopped)"); -return_message(Stream,Client); - -message(StreamHandler,Remote,"ack termianate"); - -inactive(Stream); -inactive(Session); -inactive(StreamHandler); -inactive(SessionHandler); -destroy_message(Client,Stream); -destroy_message(Client,Session); -destroy_message(StreamHandler,SessionHandler); -destroy_message(SessionHandler,Channel); -inactive(Client); - -# Complete the lifelines -step(); -complete(Remote); -complete(Connmgr); -complete(Channel); -complete(SessionHandler); -complete(StreamHandler); - -complete(Client); -complete(Session); -.PE diff --git a/doc/sequence.pic b/doc/sequence.pic deleted file mode 100644 index bd8764b..0000000 --- a/doc/sequence.pic +++ /dev/null @@ -1,486 +0,0 @@ -#/usr/bin/pic2plot -Tps -# -# Pic macros for drawing UML sequence diagrams -# -# (C) Copyright 2004-2005 Diomidis Spinellis. -# -# Permission to use, copy, and distribute this software and its -# documentation for any purpose and without fee is hereby granted, -# provided that the above copyright notice appear in all copies and that -# both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -# -# $Id: sequence.pic 1.10 2005/10/19 18:36:08 dds Exp $ -# - - -# Default parameters (can be redefined) - -# Spacing between messages -spacing = 0.25; -# Active box width -awid = .1; -# Box height -boxht = 0.3; -# Commend folding -corner_fold=awid -# Comment distance -define comment_default_move {up 0.25 right 0.25}; -# Comment height -comment_default_ht=0.5; -# Comment width -comment_default_wid=1; -#Default Object width -object_default_width = 0.75 - -# set 2 to the width of a string(text) -define getwidth { - print "getwidth(" $1 - sh X - for i in $1; do - foo=$i; bar=0; - if (( ${#i} > $bar)); then - bar=${#i}; - fi; - echo "$i $bar" >> test; - done; - echo " w= ($bar * 0.75) / 6;" > .sequence.temp - cat .sequence.temp >> log.sh - X - copy ".sequence.temp"; - if (w < object_default_width) then { - w = object_default_width; - } - print "width of " $1" is " w -} - -# Create a new object with custom width (name, text) -define object { - getwidth($2); - $1: box $2 wid w; move; - - # Could also underline text with \mk\ul\ul\ul...\rt - { - line from $1.w + (.1, -.07) to $1.e + (-.1, -.07); - } - move to $1.e; - move right; - # Active is the level of activations of the object - # 0 : inactive : draw thin line swimlane - # 1 : active : draw thick swimlane - # > 1: nested : draw nested swimlane - active_$1 = 0; - lifestart_$1 = $1.s.y; -} - -# Create a new external actor(name,text) -define actor { - getwidth($2) - $1: [ - XSEQC: circle rad w; - XSEQL: line from XSEQC.s down 2*w; - line from XSEQL.start - (.15,.02) to XSEQL.start + (.15,-.02); - XSEQL1: line from XSEQL.end left .02+w down .15; - XSEQL2: line from XSEQL.end right .0+w down .15; - line at XSEQC.n invis "" "" "" $2; - ] - move to $1.e; - move right; - active_$1 = 0; - lifestart_$1 = $1.s.y - .05; -} - -# Create a new placeholder object(name) -define placeholder_object { - $1: box invisible; - move; - move to $1.e; - move right; - active_$1 = 0; - lifestart_$1 = $1.s.y; -} - -define pobject { - placeholder_object($1); -} - -define extend_lifeline { - if (active_$1 > 0) then { - # draw the left edges of the boxes - move to ($1.x - awid/2, Here.y); - for level = 1 to active_$1 do { - line from (Here.x, lifestart_$1) to Here; - move right awid/2 - } - - # draw the right edge of the innermost box - move right awid/2; - line from (Here.x, lifestart_$1) to Here; - } else { - line from ($1.x, lifestart_$1) to ($1.x, Here.y) dashed; - } - lifestart_$1 = Here.y; -} - -# complete(name) -# Complete the lifeline of the object with the given name -define complete { - extend_lifeline($1) - if (active_$1) then { - # draw bottom of all active boxes - line right ((active_$1 + 1) * awid/2) from ($1.x - awid/2, Here.y); - } -} - -# Draw a message (from_object,to_object,label) -define message { - down; - move spacing; - getwidth($3); - # adjust object position so text fits - # add buffer of awid on either side for clarity - - # Adjust so that lines and arrows do not fall into the - # active box. Should be .5, but the arrow heads tend to - # overshoot. - if ($1.x <= $2.x) then { - off_from = awid * .6; - off_to = -awid * .6; - } else { - off_from = -awid * .6; - off_to = awid * .6; - } - # add half a box width for each level of nesting - if (active_$1 > 1) then { - off_from = off_from + (active_$1 - 1) * awid/2; - } - - # add half a box width for each level of nesting - if (active_$2 > 1) then { - off_to = off_to + (active_$2 - 1) * awid/2; - } - - if ($1.x == $2.x) then { - arrow from ($1.x + off_from, Here.y) right then down .25 then left $3 ljust " " " " " " ; - } else { - arrow from ($1.x + off_from, Here.y) to ($2.x + off_to, Here.y); - #draw the text seperatly to work around arrow bug - #add a small offset of awid for clarity - if ($1.x < $2.x) then { - sh X - rm .sequence.temp; - c=0 - for i in $3; do - ((c++)); - if ((c>1)); then - echo -n " \"$i\" below ljust " >> .sequence.temp; - else - echo -n " \"$i\" above ljust " >> .sequence.temp; - echo " at ($1.x + off_from + awid, Here.y)" >> .sequence.temp; - fi - done; - if ((c>1)); then - echo " at ($1.x + off_from + awid, Here.y - $((c>1?c-2:1))*8/72)" >> .sequence.temp; - fi - cat .sequence.temp >> log.sh - X - copy ".sequence.temp" - } else { - sh X - rm .sequence.temp; - c=0 - for i in $3; do - ((c++)); - if ((c>1)); then - echo -n " \"$i\" below rjust " >> .sequence.temp; - else - echo -n " \"$i\" above rjust " >> .sequence.temp; - echo " at ($1.x + off_from - awid, Here.y)" >> .sequence.temp; - fi - done; - if ((c>1)); then - echo " at ($1.x + off_from - awid, Here.y - $((c>1?c-2:1))*8/72)" >> .sequence.temp; - fi - cat .sequence.temp >> log.sh - X - copy ".sequence.temp" - } - } -} - -# Display a lifeline constraint(object,label) -define lifeline_constraint { - off_from = awid; - # add half a box width for each level of nesting - if (active_$1 > 1) then { - off_from = off_from + (active_$1 - 1) * awid/2; - } - - box at ($1.x + off_from, Here.y) invis $2 ljust " " ; -} - -define lconstraint { - lifeline_constraint($1,$2); -} - -# Display an object constraint(label) -# for the last object drawn -define object_constraint { - { box invis with .s at last box .nw $1 ljust; } -} - -define oconstraint { - object_constraint($1); -} - -# Draw a creation message(from_object,to_object,object_label) -define create_message { - down; - move spacing; - if ($1.x <= $2.x) then { - off_from = awid * .6; - off_to = -boxwid * .51; - } else { - off_from = -awid * .6; - off_to = boxwid * .51; - } - - # add half a box width for each level of nesting - if (active_$1 > 1) then { - off_from = off_from + (active_$1 - 1) * awid/2; - } - - #we shouldnt need to adjust object positioning for this message - #as it fits within the minimal defaults - # See comment in destroy_message - XSEQA: arrow from ($1.x + off_from, Here.y) to ($2.x + off_to, Here.y) " "; - #draw the text seperatly to work around arrow bug - #add a small offset of awid for clarity - if ($1.x < $2.x) then { - "«create»" above ljust at ($1.x + off_from + awid, Here.y) ; - } else { - "«create»" above rjust at ($1.x + off_from - awid, Here.y) ; - } - - getwidth($3); - if ($1.x <= $2.x) then { - { XSEQB: box $3 wid w with .w at XSEQA.end; } - } else { - { XSEQB: box $3 wid w with .e at XSEQA.end; } - } - { - line from XSEQB.w + (.1, -.07) to XSEQB.e + (-.1, -.07); - } - lifestart_$2 = XSEQB.s.y; - move (spacing + boxht) / 2; -} - -define cmessage { - create_message($1,$2,$3); -} - -# Draw an X for a given object -define drawx { - { - line from($1.x - awid, lifestart_$1 - awid) to ($1.x + awid, lifestart_$1 + awid); - line from($1.x - awid, lifestart_$1 + awid) to ($1.x + awid, lifestart_$1 - awid); - } -} - -# Draw a destroy message(from_object,to_object) -define destroy_message { - down; - move spacing; - # The troff code is \(Fo \(Fc - # The groff code is also \[Fo] \[Fc] - # The pic2plot code is \Fo \Fc - # See http://www.delorie.com/gnu/docs/plotutils/plotutils_71.html - # To stay compatible with all we have to hardcode the characters - message($1,$2,"«destroy»"); - complete($2); - drawx($2); -} - -define dmessage { - destroy_message($1,$2); -} - -# An object deletes itself: delete(object) -define delete { - complete($1); - lifestart_$1 = lifestart_$1 - awid; - drawx($1); -} - -# Draw a message return(from_object,to_object,label) -define return_message { - down; - move spacing; - # See comment in message - if ($1.x <= $2.x) then { - off_from = awid * .6; - off_to = -awid * .6; - } else { - off_from = -awid * .6; - off_to = awid * .6; - } - - # add half a box width for each level of nesting - if (active_$1 > 1) then { - off_from = off_from + (active_$1 - 1) * awid/2; - } - - # add half a box width for each level of nesting - if (active_$2 > 1) then { - off_to = off_to + (active_$2 - 1) * awid/2; - } - - arrow from ($1.x + off_from, Here.y) to ($2.x + off_to, Here.y) dashed $3 " "; -} - -define rmessage { - return_message($1,$2,$3); -} - -# Object becomes active -# Can be nested to show recursion -define active { - extend_lifeline($1); - # draw top of new active box - line right awid from ($1.x + (active_$1 - 1) * awid/2, Here.y); - active_$1 = active_$1 + 1; -} - -# Object becomes inactive -# Can be nested to show recursion -define inactive { - extend_lifeline($1); - active_$1 = active_$1 - 1; - # draw bottom of innermost active box - line right awid from ($1.x + (active_$1 - 1) * awid/2, Here.y); -} - -# Time step -# Useful at the beginning and the end -# to show object states -define step { - down; - move spacing; -} - -# Switch to asynchronous messages -define async { - arrowhead = 0; - arrowwid = arrowwid * 2; -} - -# Switch to synchronous messages -define sync { - arrowhead = 1; - arrowwid = arrowwid / 2; -} - -# same as lifeline_constraint, but Text and empty string are exchanged. -define lconstraint_below{ - off_from = awid; - # add half a box width for each level of nesting - if (active_$1 > 1) then { - off_from = off_from + (active_$1 - 1) * awid/2; - } - - box at ($1.x + off_from, Here.y) invis "" $2 ljust; -} - -# begin_frame(left_object,name,label_text); -define begin_frame { - # The lifeline will be cut here - extend_lifeline($1); - # draw the frame-label - $2: box $3 invis with .n at ($1.x, Here.y); - d = $2.e.y - $2.se.y; - line from $2.ne to $2.e then down d left d then to $2.sw; - # continue the lifeline below the frame-label - move to $2.s; - lifestart_$1 = Here.y; -} - -# end_frame(right_object,name); -define end_frame { - # dummy-box for the lower right corner: - box invis "" with .s at ($1.x, Here.y); - # draw the frame - frame_wid = last box.se.x - $2.nw.x - frame_ht = - last box.se.y + $2.nw.y - box with .nw at $2.nw wid frame_wid ht frame_ht; - # restore Here.y - move to last box.s; -} - -# comment(object,[name],[line_movement], [box_size] text); -define comment { - old_y = Here.y - # draw the first connecting line, at which's end the box wil be positioned - move to ($1.x, Here.y) - if "$3" == "" then { - line comment_default_move() dashed; - } else { - line $3 dashed; - } - - # draw the box, use comment_default_xx if no explicit - # size is given together with the text in parameter 4 - old_boxht=boxht; - old_boxwid=boxwid; - boxht=comment_default_ht; - boxwid=comment_default_wid; - if "$2" == "" then { - box invis $4; - } else { - $2: box invis $4; - } - boxht=old_boxht; - boxwid=old_boxwid; - - # draw the frame of the comment - line from last box.nw \ - to last box.ne - (corner_fold, 0) \ - then to last box.ne - (0, corner_fold) \ - then to last box.se \ - then to last box.sw \ - then to last box.nw ; - line from last box.ne - (corner_fold, 0) \ - to last box.ne - (corner_fold, corner_fold) \ - then to last box.ne - (0, corner_fold) ; - - # restore Here.y - move to ($1.x, old_y) -} - -# connect_to_comment(object,name); -define connect_to_comment { - old_y = Here.y - # start at the object - move to ($1.x, Here.y) - # find the best connection-point of the comment to use as line-end - if $1.x < $2.w.x then { - line to $2.w dashed; - } else { - if $1.x > $2.e.x then { - line to $2.e dashed; - } else { - if Here.y < $2.s.y then { - line to $2.s dashed; - } else { - if Here.y > $2.n.y then { - line to $2.n dashed; - } - } - } - } - # restore Here.y - move to ($1.x, old_y) -} diff --git a/gstcodecs.conf b/gstcodecs.conf deleted file mode 100644 index adcaa50..0000000 --- a/gstcodecs.conf +++ /dev/null @@ -1,39 +0,0 @@ -[audio/iLBC] -mode=30 -clock-rate=8000 - -[audio/AMR] -clock-rate=8000 - -[audio/GSM] -clock-rate=8000 - -[audio/G729] -clock-rate=8000 - -[audio/PCMA] -clock-rate=8000 - -[audio/PCMU] -clock-rate=8000 - -[audio/speex] -id=-1 - -[video/THEORA] -id=-1 - -[audio/VORBIS] -id=-1 - -[audio/MPA] -id=-1 - -[audio/MPV] -id=-1 - -[video/H263] - -[video/H264] - -[video/H263-1998] diff --git a/m4/Makefile.am b/m4/Makefile.am index 52aac8f..259e3c3 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -1,5 +1,4 @@ EXTRA_DIST = \ as-compiler-flag.m4 \ as-version.m4 \ -as-ac-expand.m4 \ -seq-dias.m4 +as-ac-expand.m4 diff --git a/m4/seq-dias.m4 b/m4/seq-dias.m4 deleted file mode 100644 index dddd8ee..0000000 --- a/m4/seq-dias.m4 +++ /dev/null @@ -1,33 +0,0 @@ -AC_DEFUN([SEQ_DIAS], -[ -dnl check for tools for drawing sequence diagrams -AC_ARG_ENABLE(seq-dias, - AC_HELP_STRING([--enable-seq-dias], - [use plotutils to draw sequence diagrams [default=yes]]),, - enable_seq_dias=yes) - -MAKE_SEQ_DIAS=no -if test x$enable_seq_dias = xyes; then - MAKE_SEQ_DIAS=yes - AC_PATH_PROG(PIC2PLOT, pic2plot, no) - AC_PATH_PROG(GS, gs, no) - AC_PATH_PROG(CONVERT, convert, no) - if test "$CONVERT" == "no"; then - AC_MSG_WARN([Imagemagick not found, drawing sequence diagrams will be disabled.]) - MAKE_SEQ_DIAS=no - fi - if test "$GS" == "no"; then - AC_MSG_WARN([Ghostscript not found, drawing sequence diagrams will be disabled.]) - MAKE_SEQ_DIAS=no - fi - if test "$PIC2PLOT" == "no"; then - AC_MSG_WARN([GNU plotutils not found, drawing sequence diagrams will be disabled.]) - MAKE_SEQ_DIAS=no - fi - AC_SUBST(PIC2PLOT) - AC_SUBST(CONVERT) - -fi -AC_SUBST(MAKE_SEQ_DIAS) -AM_CONDITIONAL(MAKE_SEQ_DIAS, test x$MAKE_SEQ_DIAS == xyes) -]) diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 3f4c7d3..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -BUILT_SOURCES = \ - tp-stream-engine-signals-marshal.h \ - tp-stream-engine-signals-marshal.c - -CLEANFILES = $(BUILT_SOURCES) tp-stream-engine-signals-marshal.list - - -libexec_PROGRAMS = telepathy-stream-engine - -telepathy_stream_engine_SOURCES = \ - stream-engine-main.c \ - tp-stream-engine.h \ - tp-stream-engine.c \ - util.h \ - util.c \ - audiostream.c \ - audiostream.h \ - videostream.c \ - videostream.h \ - videosink.c \ - videosink.h \ - videopreview.c \ - videopreview.h - -nodist_telepathy_stream_engine_SOURCES = $(BUILT_SOURCES) - -AM_CFLAGS = \ - $(ERROR_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(X11_CFLAGS) \ - $(GST_CFLAGS) \ - $(GST_INTERFACES_CFLAGS) \ - $(FARSIGHT2_CFLAGS) \ - $(TELEPATHY_CFLAGS) \ - -I$(top_srcdir) \ - -I$(top_builddir) - -AM_LDFLAGS = \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) \ - $(X11_LIBS) \ - $(GST_LIBS) \ - $(GST_INTERFACES_LIBS) \ - $(TELEPATHY_LIBS) \ - $(FARSIGHT2_LIBS) \ - $(top_builddir)/api/libstream-engine-api.la \ - $(top_builddir)/telepathy-farsight/libtelepathy-farsight.la - -# rules to generate signal marshallers -tp-stream-engine-signals-marshal.list: $(telepathy_stream_engine_SOURCES) Makefile.am - ( cd $(srcdir) && \ - sed -n -e 's/.*tp_stream_engine_marshal_\([[:upper:][:digit:]]*__[[:upper:][:digit:]_]*\).*/\1/p' \ - $(telepathy_stream_engine_SOURCES) ) \ - | sed -e 's/__/:/' -e 'y/_/,/' | sort -u > $@.tmp - if cmp -s $@.tmp $@; then \ - rm $@.tmp; \ - touch $@; \ - else \ - mv $@.tmp $@; \ - fi - -%-signals-marshal.h: %-signals-marshal.list Makefile.in - glib-genmarshal --header --prefix=$(subst -,_,$*)_marshal $< > $*-signals-marshal.h - -%-signals-marshal.c: %-signals-marshal.list Makefile.in - glib-genmarshal --body --prefix=$(subst -,_,$*)_marshal $< > $*-signals-marshal.c diff --git a/src/audiostream.c b/src/audiostream.c deleted file mode 100644 index 39cc6a8..0000000 --- a/src/audiostream.c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * stream.c - Source for TpStreamEngineAudioStream - * Copyright (C) 2006-2008 Collabora Ltd. - * Copyright (C) 2006-2008 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -#include <gst/farsight/fs-conference-iface.h> - -#include "tp-stream-engine.h" - -#include "audiostream.h" -#include "tp-stream-engine-signals-marshal.h" -#include "util.h" - -G_DEFINE_TYPE (TpStreamEngineAudioStream, tp_stream_engine_audio_stream, - G_TYPE_OBJECT); - -#define DEBUG(stream, format, ...) \ - g_debug ("stream %d (audio) %s: " format, \ - ((TfStream *)stream)->stream_id, \ - G_STRFUNC, \ - ##__VA_ARGS__) - -#define WARNING(stream, format, ...) \ - g_warning ("stream %d (audio) %s: " format, \ - ((TfStream *)stream)->stream_id, \ - G_STRFUNC, \ - ##__VA_ARGS__) - - -struct _TpStreamEngineAudioStreamPrivate -{ - TfStream *stream; - - GstElement *srcbin; - - gdouble output_volume; - gboolean output_mute; - - GstPad *pad; - - GstElement *bin; - - gulong src_pad_added_handler_id; - - GError *construction_error; - - GMutex *mutex; - /* Everything below this line is protected by the mutex */ - guint error_idle_id; - GList *sinkbins; -}; - - -/* properties */ -enum -{ - PROP_0, - PROP_STREAM, - PROP_BIN, - PROP_PAD, - PROP_OUTPUT_VOLUME, - PROP_OUTPUT_MUTE, - PROP_INPUT_VOLUME, - PROP_INPUT_MUTE -}; - -/* signals */ -enum -{ - REQUEST_PAD, - RELEASE_PAD, - SIGNAL_COUNT -}; - -static guint signals[SIGNAL_COUNT] = {0}; - -static GstElement * -tp_stream_engine_audio_stream_make_src_bin (TpStreamEngineAudioStream *self, - GError **error); - - -static void tp_stream_engine_audio_stream_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); - -static void tp_stream_engine_audio_stream_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); - -static void src_pad_added_cb (TfStream *stream, GstPad *pad, - FsCodec *codec, gpointer user_data); - -static void -tp_stream_engine_audio_stream_init (TpStreamEngineAudioStream *self) -{ - TpStreamEngineAudioStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - TP_STREAM_ENGINE_TYPE_AUDIO_STREAM, TpStreamEngineAudioStreamPrivate); - - self->priv = priv; - - self->priv->mutex = g_mutex_new (); - - self->priv->output_volume = 1; - self->priv->output_mute = FALSE; -} - - -static GObject * -tp_stream_engine_audio_stream_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *obj; - TpStreamEngineAudioStream *self = NULL; - GstPad *src_pad = NULL; - GstPad *sink_pad = NULL; - GstElement *srcbin = NULL; - - obj = G_OBJECT_CLASS (tp_stream_engine_audio_stream_parent_class)->constructor (type, n_props, props); - - self = (TpStreamEngineAudioStream *) obj; - - srcbin = tp_stream_engine_audio_stream_make_src_bin (self, - &self->priv->construction_error); - if (!srcbin) - goto out; - - if (!gst_bin_add (GST_BIN (self->priv->bin), srcbin)) - { - gst_object_unref (srcbin); - self->priv->construction_error = g_error_new (TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not add src to bin"); - goto out; - } - self->priv->srcbin = srcbin; - - - g_object_get (self->priv->stream, "sink-pad", &sink_pad, NULL); - - if (!sink_pad) - { - self->priv->construction_error = g_error_new (TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not get stream sink pad"); - goto out; - } - - src_pad = gst_element_get_static_pad (self->priv->srcbin, "src"); - - if (!src_pad) - { - self->priv->construction_error = g_error_new (TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, - "Could not get src pad from src"); - gst_object_unref (sink_pad); - goto out; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (src_pad, sink_pad))) - { - self->priv->construction_error = g_error_new (TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not link src to stream"); - gst_object_unref (src_pad); - gst_object_unref (sink_pad); - goto out; - } - - gst_object_unref (src_pad); - gst_object_unref (sink_pad); - - sink_pad = gst_element_get_static_pad (self->priv->srcbin, "sink"); - - if (!sink_pad) - { - self->priv->construction_error = g_error_new (TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, - "Could not get sink pad from srcbin"); - goto out; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (self->priv->pad, sink_pad))) - { - self->priv->construction_error = g_error_new (TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not link src to srcbin"); - gst_object_unref (sink_pad); - goto out; - } - - gst_object_unref (sink_pad); - - gst_element_set_state (self->priv->srcbin, GST_STATE_PLAYING); - - self->priv->src_pad_added_handler_id = g_signal_connect (self->priv->stream, - "src-pad-added", G_CALLBACK (src_pad_added_cb), self); - - out: - return obj; -} - -static void -free_sinkbin (gpointer data, gpointer user_data) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (user_data); - GstElement *bin = data; - GstPad *adderpad = NULL, *adderpeer = NULL; - GstPad *binsink = NULL, *sinkpeer = NULL; - - binsink = gst_element_get_static_pad (bin, "sink"); - - sinkpeer = gst_pad_get_peer (binsink); - if (sinkpeer) - { - gst_pad_unlink (sinkpeer, binsink); - gst_object_unref (sinkpeer); - } - - GST_PAD_STREAM_LOCK(binsink); - GST_PAD_STREAM_UNLOCK(binsink); - gst_object_unref (binsink); - - - adderpeer = gst_element_get_static_pad (bin, "src"); - adderpad = gst_pad_get_peer (adderpeer); - gst_object_unref (adderpeer); - - gst_element_set_locked_state (bin, TRUE); - gst_element_set_state (bin, GST_STATE_NULL); - - gst_bin_remove (GST_BIN (self->priv->bin), bin); - - if (adderpad) - { - g_signal_emit (self, signals[RELEASE_PAD], 0, adderpad); - gst_object_unref (adderpad); - } -} - -static void -tp_stream_engine_audio_stream_dispose (GObject *object) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (object); - - g_mutex_lock (self->priv->mutex); - if (self->priv->error_idle_id) - { - g_source_remove (self->priv->error_idle_id); - self->priv->error_idle_id = 0; - } - g_mutex_unlock (self->priv->mutex); - - if (self->priv->src_pad_added_handler_id) - { - g_signal_handler_disconnect (self->priv->stream, - self->priv->src_pad_added_handler_id); - self->priv->src_pad_added_handler_id = 0; - } - - g_mutex_lock (self->priv->mutex); - g_list_foreach (self->priv->sinkbins, free_sinkbin, self); - g_list_free (self->priv->sinkbins); - self->priv->sinkbins = NULL; - g_mutex_unlock (self->priv->mutex); - - if (self->priv->srcbin) - { - gst_element_set_locked_state (self->priv->srcbin, TRUE); - gst_element_set_state (self->priv->srcbin, GST_STATE_NULL); - gst_bin_remove (GST_BIN (self->priv->bin), self->priv->srcbin); - self->priv->srcbin = NULL; - } - - if (self->priv->bin) - { - gst_object_unref (self->priv->bin); - self->priv->bin = NULL; - } - - if (self->priv->pad) - { - gst_object_unref (self->priv->pad); - self->priv->pad = NULL; - } - - if (self->priv->stream) - { - g_object_unref (self->priv->stream); - self->priv->stream = NULL; - } - - if (G_OBJECT_CLASS (tp_stream_engine_audio_stream_parent_class)->dispose) - G_OBJECT_CLASS (tp_stream_engine_audio_stream_parent_class)->dispose (object); -} - -static void -tp_stream_engine_audio_stream_finalize (GObject *object) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (object); - - g_mutex_free (self->priv->mutex); - - if (G_OBJECT_CLASS (tp_stream_engine_audio_stream_parent_class)->finalize) - G_OBJECT_CLASS (tp_stream_engine_audio_stream_parent_class)->finalize (object); -} - -static gboolean -request_pad_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer data) -{ - if (G_TYPE_CHECK_VALUE_TYPE (handler_return, GST_TYPE_PAD)) - { - g_value_copy (handler_return, return_accu); - return FALSE; - } - - return TRUE; -} - -static void -tp_stream_engine_audio_stream_class_init (TpStreamEngineAudioStreamClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (TpStreamEngineAudioStreamPrivate)); - object_class->dispose = tp_stream_engine_audio_stream_dispose; - object_class->finalize = tp_stream_engine_audio_stream_finalize; - object_class->constructor = tp_stream_engine_audio_stream_constructor; - object_class->set_property = tp_stream_engine_audio_stream_set_property; - object_class->get_property = tp_stream_engine_audio_stream_get_property; - - g_object_class_install_property (object_class, PROP_STREAM, - g_param_spec_object ("stream", - "Tp StreamEngine Stream", - "The Telepathy Stream Engine Stream", - TF_TYPE_STREAM, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_BIN, - g_param_spec_object ("bin", - "The Bin to add stuff to", - "The Bin to add the elements to", - GST_TYPE_BIN, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_PAD, - g_param_spec_object ("pad", - "The pad that the src data comes from", - "The GstPad the src data comes from", - GST_TYPE_PAD, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_OUTPUT_VOLUME, - g_param_spec_double ("output-volume", - "Output volume", - "The output volume for this stream.", - 0, 10, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_OUTPUT_MUTE, - g_param_spec_boolean ("output-mute", - "Output volume", - "Mute stream", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_INPUT_VOLUME, - g_param_spec_double ("input-volume", - "Input volume", - "The input volume for this stream.", - 0, 10, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_INPUT_MUTE, - g_param_spec_boolean ("input-mute", - "Input volume", - "Mute stream", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /* - * BEWARE: - * This signal is emitted from the streaming thread - */ - - signals[REQUEST_PAD] = g_signal_new ("request-pad", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - request_pad_accumulator, NULL, - tp_stream_engine_marshal_OBJECT__VOID, - GST_TYPE_PAD, 0); - - signals[RELEASE_PAD] = g_signal_new ("release-pad", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GST_TYPE_PAD); - -} - -static void -tp_stream_engine_audio_stream_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (object); - - switch (property_id) - { - case PROP_STREAM: - self->priv->stream = g_value_dup_object (value); - break; - case PROP_BIN: - self->priv->bin = g_value_dup_object (value); - break; - case PROP_PAD: - self->priv->pad = g_value_dup_object (value); - break; - case PROP_OUTPUT_VOLUME: - { - GList *item; - g_mutex_lock (self->priv->mutex); - for (item = self->priv->sinkbins; - item; - item = g_list_next (item)) - gst_child_proxy_set_property (GST_OBJECT (item->data), - "volume::volume", value); - self->priv->output_volume = g_value_get_double (value); - g_mutex_unlock (self->priv->mutex); - } - break; - case PROP_OUTPUT_MUTE: - { - GList *item; - g_mutex_lock (self->priv->mutex); - for (item = self->priv->sinkbins; - item; - item = g_list_next (item)) - gst_child_proxy_set_property (GST_OBJECT (item->data), - "volume::mute", value); - self->priv->output_mute = g_value_get_boolean (value); - g_mutex_unlock (self->priv->mutex); - } - break; - case PROP_INPUT_VOLUME: - gst_child_proxy_set_property (GST_OBJECT (self->priv->srcbin), - "volume::volume", value); - break; - case PROP_INPUT_MUTE: - gst_child_proxy_set_property (GST_OBJECT (self->priv->srcbin), - "volume::mute", value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -tp_stream_engine_audio_stream_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (object); - - switch (property_id) - { - case PROP_STREAM: - g_value_set_object (value, self->priv->stream); - break; - case PROP_BIN: - g_value_set_object (value, self->priv->bin); - break; - case PROP_PAD: - g_value_set_object (value, self->priv->pad); - break; - case PROP_OUTPUT_VOLUME: - g_value_set_double (value, self->priv->output_volume); - break; - case PROP_OUTPUT_MUTE: - g_value_set_boolean (value, self->priv->output_mute); - break; - case PROP_INPUT_VOLUME: - gst_child_proxy_get_property (GST_OBJECT (self->priv->srcbin), - "volume::volume", value); - break; - case PROP_INPUT_MUTE: - gst_child_proxy_get_property (GST_OBJECT (self->priv->srcbin), - "volume::mute", value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static GstElement * -tp_stream_engine_audio_stream_make_src_bin (TpStreamEngineAudioStream *self, - GError **error) -{ - GstElement *bin = NULL; - GstElement *queue = NULL; - GstElement *audioconvert = NULL; - GstElement *volume = NULL; - GstPad *pad; - GstPad *ghostpad; - - bin = gst_bin_new (NULL); - - queue = gst_element_factory_make ("queue", NULL); - g_object_set (queue, "leaky", 2, NULL); - - if (!gst_bin_add (GST_BIN (bin), queue)) - { - gst_object_unref (queue); - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not add queue to bin"); - return NULL; - } - - audioconvert = gst_element_factory_make ("audioconvert", NULL); - if (!gst_bin_add (GST_BIN (bin), audioconvert)) - { - gst_object_unref (audioconvert); - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, - "Could not add audioconvert to bin"); - return NULL; - } - - volume = gst_element_factory_make ("volume", "volume"); - if (!gst_bin_add (GST_BIN (bin), volume)) - { - gst_object_unref (volume); - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not add volume to bin"); - return NULL; - } - - if (!gst_element_link_many (queue, audioconvert, volume, NULL)) - { - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, - "Could not link queue, audioconvert and volume elements"); - return NULL; - } - - pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC); - - if (!pad) - { - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, - "Could not find unconnected sink pad in src bin"); - return NULL; - } - - ghostpad = gst_ghost_pad_new ("src", pad); - if (!gst_element_add_pad (bin, ghostpad)) - { - gst_object_unref (ghostpad); - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not add pad to bin"); - return NULL; - } - - gst_object_unref (pad); - - pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK); - - if (!pad) - { - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, - "Could not find unconnected sink pad in sink bin"); - return NULL; - } - - ghostpad = gst_ghost_pad_new ("sink", pad); - if (!gst_element_add_pad (bin, ghostpad)) - { - gst_object_unref (ghostpad); - gst_object_unref (bin); - g_set_error (error, TP_STREAM_ENGINE_ERROR, - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, "Could not add pad to bin"); - return NULL; - } - - gst_object_unref (pad); - - return bin; -} - - -TpStreamEngineAudioStream * -tp_stream_engine_audio_stream_new (TfStream *stream, - GstBin *bin, - GstPad *pad, - GError **error) -{ - TpStreamEngineAudioStream *self = NULL; - - g_return_val_if_fail (TF_IS_STREAM (stream) && - GST_IS_BIN (bin) && - GST_IS_PAD (pad), NULL); - - self = g_object_new (TP_STREAM_ENGINE_TYPE_AUDIO_STREAM, - "stream", stream, - "bin", bin, - "pad", pad, - NULL); - - if (self->priv->construction_error) - { - g_propagate_error (error, self->priv->construction_error); - g_object_unref (self); - return NULL; - } - - return self; -} - -static gboolean -src_pad_added_idle_error (gpointer user_data) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (user_data); - - tf_stream_error (self->priv->stream, 0, - "Error setting up audio reception"); - - - g_mutex_lock (self->priv->mutex); - self->priv->error_idle_id = 0; - g_mutex_unlock (self->priv->mutex); - - return FALSE; -} - -/* This creates the following pipeline - * - * farsight-pad -> { audioconvert -> audioresample -> volume } -> liveadder - */ - -static void -src_pad_added_cb (TfStream *stream, GstPad *pad, FsCodec *codec, - gpointer user_data) -{ - TpStreamEngineAudioStream *self = TP_STREAM_ENGINE_AUDIO_STREAM (user_data); - GstElement *audioconvert = NULL; - GstElement *audioresample = NULL; - GstElement *volume = NULL; - GstPad *adderpad = NULL; - GstPad *mypad = NULL; - GstPad *ghostpad = NULL; - gchar *padname = gst_pad_get_name (pad); - GstElement *bin = NULL; - gint session_id, ssrc, pt; - - DEBUG (self, "New pad added: %s", padname); - - if (sscanf (padname, "src_%d_%d_%d", &session_id, &ssrc, &pt) != 3) - { - WARNING (self, "Pad %s, is not a valid farsight src pad", padname); - g_free (padname); - goto error_finish; - } - - g_free (padname); - - bin = gst_bin_new (NULL); - - audioconvert = gst_element_factory_make ("audioconvert", NULL); - if (!audioconvert) - { - WARNING (self, "Could not create audioconvert"); - goto error_created; - } - - if (!gst_bin_add (GST_BIN (bin), audioconvert)) - { - WARNING (self, "Could add audioconvert to bin"); - gst_object_unref (audioconvert); - goto error_created; - } - - audioresample = gst_element_factory_make ("audioresample", NULL); - if (!audioresample) - { - WARNING (self, "Could not create audioresample"); - goto error_created; - } - - if (!gst_bin_add (GST_BIN (bin), audioresample)) - { - WARNING (self, "Could add audioresample to bin"); - gst_object_unref (audioresample); - goto error_created; - } - - volume = gst_element_factory_make ("volume", "volume"); - if (!volume) - { - WARNING (self, "Could not create volume"); - goto error_created; - } - - g_mutex_lock (self->priv->mutex); - g_object_set (volume, - "volume", self->priv->output_volume, - "mute", self->priv->output_mute, - NULL); - g_mutex_unlock (self->priv->mutex); - - if (!gst_bin_add (GST_BIN (bin), volume)) - { - WARNING (self, "Could add volume to bin"); - gst_object_unref (volume); - goto error_created; - } - - if (!gst_element_link_many (audioconvert, audioresample, volume, NULL)) - { - WARNING (self,"Could not link audioconvert, audioresample and volume"); - goto error_created; - } - - if (!gst_bin_add (GST_BIN (self->priv->bin), bin)) - { - WARNING (self, "could not add sinkbin to the pipeline"); - goto error_created; - } - - if (gst_element_set_state (bin, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) - { - WARNING (self, "Could not start audio sink filter bin"); - goto error_added; - } - - g_signal_emit (self, signals[REQUEST_PAD], 0, &adderpad); - - if (!adderpad) - { - WARNING (self, "Could not get sink pad on from pipeline"); - goto error_added; - } - - mypad = gst_element_get_static_pad (volume, "src"); - if (!mypad) - { - WARNING (self, "Could not get src pad from audioresample"); - goto error_got_pad; - } - - ghostpad = gst_ghost_pad_new ("src", mypad); - gst_object_unref (mypad); - - if (!gst_pad_set_active (ghostpad, TRUE)) - { - WARNING (self, "Could not activate src ghost pad"); - gst_object_unref (ghostpad); - goto error_got_pad; - } - - if (!gst_element_add_pad (bin, ghostpad)) - { - WARNING (self, "Could not add src ghost pad to bin"); - gst_object_unref (ghostpad); - goto error_got_pad; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (ghostpad, adderpad))) - { - WARNING (self, "Could not link src ghost pad to adder"); - goto error_got_pad; - } - - - mypad = gst_element_get_static_pad (audioconvert, "sink"); - if (!mypad) - { - WARNING (self, "Could not get audioconvert pad"); - goto error_got_pad; - } - - if (!mypad) - { - WARNING (self, "Could not get sink pad from audioresample"); - goto error_got_pad; - } - - ghostpad = gst_ghost_pad_new ("sink", mypad); - gst_object_unref (mypad); - - if (!gst_pad_set_active (ghostpad, TRUE)) - { - WARNING (self, "Could not activate sink ghost pad"); - gst_object_unref (ghostpad); - goto error_got_pad; - } - - if (!gst_element_add_pad (bin, ghostpad)) - { - WARNING (self, "Could not add sink ghost pad to bin"); - gst_object_unref (ghostpad); - goto error_got_pad; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (pad, ghostpad))) - { - WARNING (self, "Could not link farsight pad to sink"); - goto error_got_pad; - } - - g_mutex_lock (self->priv->mutex); - self->priv->sinkbins = g_list_append (self->priv->sinkbins, bin); - g_mutex_unlock (self->priv->mutex); - - return; - - error_finish: - g_mutex_lock (self->priv->mutex); - if (!self->priv->error_idle_id) - self->priv->error_idle_id = - g_idle_add (src_pad_added_idle_error, self); - g_mutex_unlock (self->priv->mutex); - return; - - error_created: - gst_object_unref (bin); - goto error_finish; - - error_added: - gst_bin_remove (GST_BIN (self->priv->bin), bin); - goto error_finish; - - error_got_pad: - gst_bin_remove (GST_BIN (self->priv->bin), bin); - g_signal_emit (self, signals[RELEASE_PAD], 0, adderpad); - goto error_finish; - -} diff --git a/src/audiostream.h b/src/audiostream.h deleted file mode 100644 index 6671a6d..0000000 --- a/src/audiostream.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __TP_STREAM_ENGINE_AUDIO_STREAM_H__ -#define __TP_STREAM_ENGINE_AUDIO_STREAM_H__ - -#include <glib-object.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/media-interfaces.h> - -#include <telepathy-farsight/stream.h> - -G_BEGIN_DECLS - -#define TP_STREAM_ENGINE_TYPE_AUDIO_STREAM tp_stream_engine_audio_stream_get_type() - -#define TP_STREAM_ENGINE_AUDIO_STREAM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TP_STREAM_ENGINE_TYPE_AUDIO_STREAM, TpStreamEngineAudioStream)) - -#define TP_STREAM_ENGINE_AUDIO_STREAM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TP_STREAM_ENGINE_TYPE_AUDIO_STREAM, TpStreamEngineAudioStreamClass)) - -#define TP_STREAM_ENGINE_IS_AUDIO_STREAM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - TP_STREAM_ENGINE_TYPE_AUDIO_STREAM)) - -#define TP_STREAM_ENGINE_IS_AUDIO_STREAM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - TP_STREAM_ENGINE_TYPE_AUDIO_STREAM)) - -#define TP_STREAM_ENGINE_AUDIO_STREAM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - TP_STREAM_ENGINE_TYPE_AUDIO_STREAM, TpStreamEngineAudioStreamClass)) - -typedef struct _TpStreamEngineAudioStreamPrivate - TpStreamEngineAudioStreamPrivate; - -typedef struct { - GObject parent; - - TpStreamEngineAudioStreamPrivate *priv; -} TpStreamEngineAudioStream; - -typedef struct { - GObjectClass parent_class; -} TpStreamEngineAudioStreamClass; - -GType tp_stream_engine_audio_stream_get_type (void); - -TpStreamEngineAudioStream * -tp_stream_engine_audio_stream_new (TfStream *stream, - GstBin *bin, - GstPad *pad, - GError **error); - -G_END_DECLS - -#endif /* __TP_STREAM_ENGINE_AUDIO_STREAM_H__ */ diff --git a/src/stream-engine-main.c b/src/stream-engine-main.c deleted file mode 100644 index 43e632c..0000000 --- a/src/stream-engine-main.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * stream-engine-main.c - startup and shutdown of stream-engine - * Copyright (C) 2005 Collabora Ltd. - * Copyright (C) 2005 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#define USE_REALTIME -#ifdef USE_REALTIME -#include <sched.h> -#include <sys/mman.h> -#endif /* USE_REALTIME */ - -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <glib.h> -#include <glib/gstdio.h> - -#include <gtk/gtk.h> - -#include <dbus/dbus-glib.h> -#include <gst/gst.h> - -#include <telepathy-glib/debug.h> -#include <telepathy-glib/errors.h> - -#include "tp-stream-engine.h" - -GSource *timeout = NULL; -GMainLoop *mainloop = NULL; -TpStreamEngine *stream_engine = NULL; -gboolean connections_exist = FALSE; - -/* timeout_id is initialized to 0 to mean no timeout has been added. - * g_timeout_add() returns an event source ID greater than 0. */ -guint timeout_id = 0; - -gboolean forced_exit_in_progress = FALSE; - -#define DIE_TIME 5000 - -/* watchdog barks every 5 seconds, and if we're unresponsive, bites us in 30 */ -#define WATCHDOG_BARK 5 -#define WATCHDOG_BITE 30 - -#ifdef USE_REALTIME -#define DEF_PRIORITY_POLICY SCHED_RR -#define PRIORITY_DELTA 1 - -static void -set_realtime (const char *argv0, int policy) { - int orig_uid, orig_euid; - int prio_policy; - int prio_delta = PRIORITY_DELTA; - struct sched_param schedp; - - /* get original uid */ - orig_uid = getuid(); - orig_euid = geteuid(); - /* set uid to root */ - if (setreuid(orig_uid, 0) == -1) { - perror("setreuid()"); - g_warning("unable to setreuid(,0), maybe you should: \n"); - g_warning("\tchown root %s ; chmod u+s %s\n", argv0, argv0); - } - /* set scheduling parameters, scheduler either SCHED_RR or SCHED_FIFO */ - switch (policy) { - case 1: - prio_policy = SCHED_RR; - break; - case 2: - prio_policy = SCHED_FIFO; - break; - default: - prio_policy = DEF_PRIORITY_POLICY; - } - memset(&schedp, 0x00, sizeof(schedp)); - schedp.sched_priority = sched_get_priority_min(prio_policy) + prio_delta; - /* 0 pid equals to getpid() ie. current process */ - if (sched_setscheduler(0, prio_policy, &schedp) == -1) { - perror("sched_setscheduler()"); - } - /* nail everything to RAM, needed for realtime on systems with swap, - * also avoids extra calls to vm subsystem */ - /*if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) { - perror("mlockall()"); - }*/ - /* restore original uid */ - setreuid(orig_uid, orig_euid); -} -#endif /* USE_REALTIME */ - -static gboolean -kill_stream_engine (gpointer data G_GNUC_UNUSED) -{ - if (!g_getenv ("STREAM_ENGINE_PERSIST") && !connections_exist) - { - g_debug("no channels are being handled, and timed out"); - g_object_unref (stream_engine); - g_main_loop_quit (mainloop); - } - - return FALSE; -} - -static void -handling_channel (TpStreamEngine *stream_engine G_GNUC_UNUSED) -{ - connections_exist = TRUE; - if (timeout_id != 0) - g_source_remove (timeout_id); -} - -static void -no_more_channels (TpStreamEngine *stream_engine G_GNUC_UNUSED) -{ - if (timeout_id != 0) - { - g_source_remove (timeout_id); - } - connections_exist = FALSE; - timeout_id = g_timeout_add(DIE_TIME, kill_stream_engine, NULL); -} - -static void -shutdown (TpStreamEngine *stream_engine) -{ - g_debug ("Unrefing stream_engine and quitting"); - g_object_unref (stream_engine); - g_main_loop_quit (mainloop); -} - -#if 0 -static void -dsp_crashed (gpointer dummy) -{ - if (stream_engine) - { - tp_stream_engine_error (stream_engine, 0, "DSP Crash"); - g_object_unref (stream_engine); - g_main_loop_quit (mainloop); - } -} -#endif - -static gboolean -dump_dot_file(gpointer data) -{ - TpStreamEngine *engine = tp_stream_engine_get (); - GstElement *pipeline = NULL; - - g_object_get (engine, "pipeline", &pipeline, NULL); - - if (pipeline) - { - GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), - GST_DEBUG_GRAPH_SHOW_ALL, "stream-engine-pipeline"); - gst_object_unref (pipeline); - } - - return FALSE; -} - -static void -got_sigusr1 (int i G_GNUC_UNUSED) -{ - g_idle_add (dump_dot_file, NULL); -} - -static void -got_sigbus (int i G_GNUC_UNUSED) -{ - const char *msg = "stream engine: DSP crashed\n"; - - write (STDERR_FILENO, msg, strlen (msg)); - -#if 0 - if (!forced_exit_in_progress) - { - forced_exit_in_progress =TRUE; - g_idle_add ((GSourceFunc) dsp_crashed, NULL); - } -#endif - - _exit (1); -} - -/* every time the watchdog barks, schedule a bite */ -static gboolean -watchdog_bark (gpointer data G_GNUC_UNUSED) -{ - alarm (WATCHDOG_BITE); - return TRUE; -} - -/* if it ever catches us, we're gone */ -static void -watchdog_bite (int sig G_GNUC_UNUSED) -{ - printf ("telepathy-stream-engine: bitten by the watchdog, aborting!\n"); - abort (); -} - -int main(int argc, char **argv) -{ - - gst_init (&argc, &argv); - gtk_init (&argc, &argv); - - tp_debug_divert_messages (g_getenv ("STREAM_ENGINE_LOGFILE")); - tp_debug_set_flags (g_getenv ("STREAM_ENGINE_DEBUG")); - /* FIXME: switch this project to use DEBUG() too */ - - if (g_getenv ("STREAM_ENGINE_TIMING") != NULL) - g_log_set_default_handler (tp_debug_timestamped_log_handler, NULL); - - signal (SIGBUS, got_sigbus); - signal (SIGUSR1, got_sigusr1); - -#ifdef USE_REALTIME - { - int rt_mode; - char *rt_env; - - /* 3.11.2006: This has to be called before gst_init() in order to make - * thread pool inherit the scheduling policy. However, this breaks gthreads, - * so disabled for now... -jl */ - /* Here we don't yet have any media threads running, so the to-be-created - * threads will inherit the scheduling parameters, as glib doesn't know - * anything about that... */ - rt_env = getenv("STREAM_ENGINE_REALTIME"); - if (rt_env != NULL) { - if ((rt_mode = atoi(rt_env))) { - g_debug("realtime scheduling enabled"); - set_realtime(argv[0], rt_mode); - } else { - g_debug("realtime scheduling disabled"); - } - } else { - g_debug("not using realtime scheduling, enable through STREAM_ENGINE_REALTIME env"); - } - } -#endif /* USE_REALTIME */ - - { - GLogLevelFlags fatal_mask; - - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } - - g_set_prgname("telepathy-stream-engine"); - - mainloop = g_main_loop_new (NULL, FALSE); - - dbus_g_error_domain_register (TP_ERRORS, "org.freedesktop.Telepathy.Error", TP_TYPE_ERROR); - - stream_engine = tp_stream_engine_get (); - - g_signal_connect (stream_engine, "handling-channel", - (GCallback) handling_channel, NULL); - - g_signal_connect (stream_engine, "no-more-channels", - (GCallback) no_more_channels, NULL); - - g_signal_connect (stream_engine, "shutdown-requested", - (GCallback) shutdown, NULL); - - tp_stream_engine_register (stream_engine); - - timeout_id = g_timeout_add(DIE_TIME, kill_stream_engine, NULL); - - if (g_getenv ("STREAM_ENGINE_NO_DOG") == NULL) - { - g_timeout_add (WATCHDOG_BARK * 1000, watchdog_bark, NULL); - signal (SIGALRM, watchdog_bite); - } - -#ifdef MAEMO_OSSO_SUPPORT - g_debug ("maemo support enabled"); -#endif - - g_debug("started"); - g_main_loop_run (mainloop); - g_debug("finished"); - - return 0; -} diff --git a/src/tp-stream-engine.c b/src/tp-stream-engine.c deleted file mode 100644 index 8f825b4..0000000 --- a/src/tp-stream-engine.c +++ /dev/null @@ -1,2078 +0,0 @@ -/* - * tp-stream-engine.c - Source for TpStreamEngine - * Copyright (C) 2005-2007 Collabora Ltd. - * Copyright (C) 2005-2007 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <dbus/dbus-glib.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/gtypes.h> - -#include "tp-stream-engine.h" -#include "tp-stream-engine-signals-marshal.h" - -#include <gst/farsight/fs-element-added-notifier.h> - -#include "telepathy-farsight/channel.h" -#include "telepathy-farsight/stream.h" - -#include "api/api.h" -#include "audiostream.h" -#include "videosink.h" -#include "videostream.h" -#include "videopreview.h" -#include "util.h" - -#define BUS_NAME "org.maemo.Telepathy.StreamEngine" -#define OBJECT_PATH "/org/maemo/Telepathy/StreamEngine" - -static void -_create_pipeline (TpStreamEngine *self); - -static void -register_dbus_signal_marshallers() -{ - /*register a marshaller for the NewMediaStreamHandler signal*/ - dbus_g_object_register_marshaller - (tp_stream_engine_marshal_VOID__BOXED_UINT_UINT_UINT, G_TYPE_NONE, - DBUS_TYPE_G_OBJECT_PATH, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, - G_TYPE_INVALID); - - /*register a marshaller for the NewMediaSessionHandler signal*/ - dbus_g_object_register_marshaller - (tp_stream_engine_marshal_VOID__BOXED_STRING, G_TYPE_NONE, - DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_INVALID); - - /*register a marshaller for the AddRemoteCandidate signal*/ - dbus_g_object_register_marshaller - (tp_stream_engine_marshal_VOID__STRING_BOXED, G_TYPE_NONE, - G_TYPE_STRING, TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT_LIST, G_TYPE_INVALID); - - /*register a marshaller for the SetActiveCandidatePair signal*/ - dbus_g_object_register_marshaller - (tp_stream_engine_marshal_VOID__STRING_STRING, G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - - /*register a marshaller for the SetRemoteCandidateList signal*/ - dbus_g_object_register_marshaller - (g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, - TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST, G_TYPE_INVALID); - - /*register a marshaller for the SetRemoteCodecs signal*/ - dbus_g_object_register_marshaller - (g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, - TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST, G_TYPE_INVALID); -} - -GQuark -tp_stream_engine_error_quark (void) -{ - return g_quark_from_static_string ("telepathy-stream-engine-error"); -} - -static void se_iface_init (gpointer, gpointer); - -G_DEFINE_TYPE_WITH_CODE (TpStreamEngine, tp_stream_engine, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (STREAM_ENGINE_TYPE_SVC_STREAM_ENGINE, - se_iface_init)) - -/* properties */ -enum -{ - PROP_0, - PROP_PIPELINE -}; - -/* signal enum */ -enum -{ - HANDLING_CHANNEL, - NO_MORE_CHANNELS, - SHUTDOWN_REQUESTED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -/* private structure */ -struct _TpStreamEnginePrivate -{ - gboolean dispose_has_run; - - TpDBusDaemon *dbus_daemon; - - GstElement *pipeline; - - GstElement *videosrc; - GstElement *videotee; - - GstElement *audiosrc; - GstElement *audiotee; - - GPtrArray *channels; - GHashTable *channels_by_path; - - GMutex *mutex; - - FsElementAddedNotifier *notifier; - - gint video_source_use_count; - gint audio_source_use_count; - - gboolean force_fakesrc; - - /* Everything below this is protected by the mutex */ - GList *output_sinks; - GList *preview_sinks; - - guint bus_async_source_id; - - GstElement *audiosink; - GstElement *audioadder; - - gint audio_sink_use_count; -}; - -static void -set_element_props (FsElementAddedNotifier *notifier, - GstBin *bin, - GstElement *element, - gpointer user_data) -{ - if (g_object_has_property ((GObject *) element, "min-ptime")) - g_object_set (element, "min-ptime", GST_MSECOND * 20, NULL); - - if (g_object_has_property ((GObject *) element, "max-ptime")) - g_object_set (element, "max-ptime", GST_MSECOND * 50, NULL); -} - -static gboolean -load_keyfile (GKeyFile *keyfile, const gchar *path, const gchar *subdir) -{ - gchar *filename; - gboolean loaded = FALSE; - GError *error = NULL; - - - filename = g_build_filename (path, subdir, "gstelements.conf", NULL); - - if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &error)) - { - g_debug ("Could not read element properties config at %s: %s", filename, - error ? error->message : "(no error message set)"); - } - else - { - loaded = TRUE; - } - g_free (filename); - g_clear_error (&error); - - return loaded; -} - -static void -add_gstelements_conf_to_notifier (FsElementAddedNotifier *notifier) -{ - GKeyFile *keyfile = g_key_file_new (); - const gchar *home = NULL; - - home = g_getenv ("HOME"); - if (!home) - home = g_get_home_dir (); - - if (!load_keyfile (keyfile, home, ".stream-engine")) - { - if (!load_keyfile (keyfile, SYSCONFDIR, "stream-engine")) - { - g_key_file_free (keyfile); - return; - } - } - - fs_element_added_notifier_set_properties_from_keyfile (notifier, - keyfile); -} - -static void -tp_stream_engine_init (TpStreamEngine *self) -{ - TpStreamEnginePrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - TP_TYPE_STREAM_ENGINE, TpStreamEnginePrivate); - - self->priv = priv; - - priv->channels = g_ptr_array_new (); - - priv->channels_by_path = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - priv->mutex = g_mutex_new (); - - priv->notifier = fs_element_added_notifier_new (); - g_signal_connect (priv->notifier, "element-added", - G_CALLBACK (set_element_props), self); - add_gstelements_conf_to_notifier (priv->notifier); - - _create_pipeline (self); -} - -static void tp_stream_engine_dispose (GObject *object); -static void tp_stream_engine_finalize (GObject *object); - - - -static void -tp_stream_engine_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (object); - - switch (property_id) - { - case PROP_PIPELINE: - g_value_set_object (value, self->priv->pipeline); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - - -static void -tp_stream_engine_class_init (TpStreamEngineClass *tp_stream_engine_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (tp_stream_engine_class); - - g_type_class_add_private (tp_stream_engine_class, - sizeof (TpStreamEnginePrivate)); - - - object_class->get_property = tp_stream_engine_get_property; - object_class->dispose = tp_stream_engine_dispose; - object_class->finalize = tp_stream_engine_finalize; - - /** - * TpStreamEngine::handling-channel: - * - * Emitted whenever this object starts handling a channel - */ - signals[HANDLING_CHANNEL] = - g_signal_new ("handling-channel", - G_OBJECT_CLASS_TYPE (tp_stream_engine_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * TpStreamEngine::no-more-channels: - * - * Emitted whenever this object is handling no channels - */ - signals[NO_MORE_CHANNELS] = - g_signal_new ("no-more-channels", - G_OBJECT_CLASS_TYPE (tp_stream_engine_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * TpStreamEngine::shutdown: - * - * Emitted whenever stream engine needs to be shutdown - */ - signals[SHUTDOWN_REQUESTED] = - g_signal_new ("shutdown-requested", - G_OBJECT_CLASS_TYPE (tp_stream_engine_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_object_class_install_property (object_class, PROP_PIPELINE, - g_param_spec_object ("pipeline", - "The GstPipeline", - "The GstPipeline that all the objects here live in", - GST_TYPE_PIPELINE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); -} - -static void -tp_stream_engine_dispose (GObject *object) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (object); - TpStreamEnginePrivate *priv = self->priv; - - if (priv->dispose_has_run) - return; - - if (priv->channels) - { - guint i; - - for (i = 0; i < priv->channels->len; i++) - g_object_unref (g_ptr_array_index (priv->channels, i)); - - g_ptr_array_free (priv->channels, TRUE); - priv->channels = NULL; - } - - if (priv->channels_by_path) - { - g_hash_table_destroy (priv->channels_by_path); - priv->channels_by_path = NULL; - } - - g_list_foreach (priv->preview_sinks, (GFunc) g_object_unref, NULL); - g_list_free (priv->preview_sinks); - priv->preview_sinks = NULL; - - if (priv->pipeline) - { - /* - * Lets not check the return values - * if it fails or is async, it will crash on the following - * unref anyways - */ - gst_element_set_state (priv->videosrc, GST_STATE_NULL); - gst_element_set_state (priv->pipeline, GST_STATE_NULL); - g_object_unref (priv->pipeline); - priv->pipeline = NULL; - priv->videosrc = NULL; - } - - if (priv->notifier) - { - g_object_unref (priv->notifier); - priv->notifier = NULL; - } - - priv->dispose_has_run = TRUE; - - if (G_OBJECT_CLASS (tp_stream_engine_parent_class)->dispose) - G_OBJECT_CLASS (tp_stream_engine_parent_class)->dispose (object); -} - -static void -tp_stream_engine_finalize (GObject *object) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (object); - - g_mutex_free (self->priv->mutex); - - G_OBJECT_CLASS (tp_stream_engine_parent_class)->finalize (object); -} - -/** - * tp_stream_engine_error - * - * Used to inform the stream engine than an exceptional situation has ocurred. - * - * @error: The error ID, as per the - * org.freedesktop.Telepathy.Media.StreamHandler::Error signal. - * @message: The human-readable error message. - */ -void -tp_stream_engine_error (TpStreamEngine *self, int error, const char *message) -{ - guint i; - - for (i = 0; i < self->priv->channels->len; i++) - tf_channel_error ( - g_ptr_array_index (self->priv->channels, i), error, message); -} - -static gboolean -tp_stream_engine_start_video_source (TpStreamEngine *self) -{ - GstStateChangeReturn state_ret; - - - if (self->priv->force_fakesrc) - { - g_debug ("Don't have a video source, not starting it"); - return FALSE; - } - - g_debug ("Starting video source"); - - self->priv->video_source_use_count++; - - state_ret = gst_element_set_state (self->priv->videosrc, GST_STATE_PLAYING); - - if (state_ret == GST_STATE_CHANGE_FAILURE) - { - g_warning ("Error starting the video source"); - return FALSE; - } - else - { - return TRUE; - } -} - - -static void -tp_stream_engine_stop_video_source (TpStreamEngine *self) -{ - GstStateChangeReturn state_ret; - - self->priv->video_source_use_count--; - - if (self->priv->video_source_use_count > 0) - return; - - g_debug ("Stopping video source"); - - state_ret = gst_element_set_state (self->priv->videosrc, GST_STATE_NULL); - - if (state_ret == GST_STATE_CHANGE_FAILURE) - g_error ("Error stopping the video source"); - else if (state_ret == GST_STATE_CHANGE_ASYNC) - g_debug ("Stopping video src async??"); -} - - -static void -tp_stream_engine_start_audio_source (TpStreamEngine *self) -{ - GstStateChangeReturn state_ret; - - g_debug ("Starting audio source"); - - self->priv->audio_source_use_count++; - - state_ret = gst_element_set_state (self->priv->audiosrc, GST_STATE_PLAYING); - - if (state_ret == GST_STATE_CHANGE_FAILURE) - g_error ("Error starting the audio source"); -} - - -static void -tp_stream_engine_stop_audio_source (TpStreamEngine *self) -{ - GstStateChangeReturn state_ret; - - self->priv->audio_source_use_count--; - - if (self->priv->audio_source_use_count > 0) - return; - - g_debug ("Stopping audio source"); - - state_ret = gst_element_set_state (self->priv->audiosrc, GST_STATE_NULL); - - if (state_ret == GST_STATE_CHANGE_FAILURE) - g_error ("Error stopping the audio source"); - else if (state_ret == GST_STATE_CHANGE_ASYNC) - g_debug ("Stopping audio src async??"); -} - -static void -stream_free_resource (TfStream *stream, - TpMediaStreamDirection dir, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - TpMediaStreamType media_type; - - if (!(dir & TP_MEDIA_STREAM_DIRECTION_SEND)) - return; - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO) - tp_stream_engine_stop_video_source (self); - else if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO) - tp_stream_engine_stop_audio_source (self); -} - -static gboolean -stream_request_resource (TfStream *stream, - TpMediaStreamDirection dir, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - TpMediaStreamType media_type; - - if (!(dir & TP_MEDIA_STREAM_DIRECTION_SEND)) - return TRUE; - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO) - return tp_stream_engine_start_video_source (self); - else if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO) - tp_stream_engine_start_audio_source (self); - - return TRUE; -} - -static void -channel_session_created (TfChannel *chan G_GNUC_UNUSED, - FsConference *conference, FsParticipant *participant G_GNUC_UNUSED, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - - g_return_if_fail (conference); - - if (g_object_has_property (G_OBJECT (conference), "latency")) - g_object_set (conference, "latency", 100, NULL); - - if (!gst_bin_add (GST_BIN (self->priv->pipeline), GST_ELEMENT (conference))) - g_error ("Could not add conference to pipeline"); - - gst_element_set_state (GST_ELEMENT (conference), GST_STATE_PLAYING); -} - -static void -channel_session_invalidated (TfChannel *channel G_GNUC_UNUSED, - FsConference *conference, FsParticipant *participant G_GNUC_UNUSED, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - - g_return_if_fail (conference); - - gst_element_set_locked_state (GST_ELEMENT (conference), TRUE); - gst_element_set_state (GST_ELEMENT (conference), GST_STATE_NULL); - - gst_bin_remove (GST_BIN (self->priv->pipeline), GST_ELEMENT (conference)); -} - - -static void -stream_closed (TfStream *stream, gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - GObject *sestream = NULL; - - sestream = g_object_get_data (G_OBJECT (stream), "se-stream"); - if (!sestream) - return; - - if (TP_STREAM_ENGINE_IS_VIDEO_STREAM (sestream)) - { - TpStreamEngineVideoStream *videostream = - (TpStreamEngineVideoStream *) sestream; - - g_mutex_lock (self->priv->mutex); - self->priv->output_sinks = g_list_remove (self->priv->output_sinks, - videostream); - g_mutex_unlock (self->priv->mutex); - - } - - if (TP_STREAM_ENGINE_IS_VIDEO_STREAM (sestream) || - TP_STREAM_ENGINE_IS_AUDIO_STREAM (sestream)) - { - GstPad *pad, *peer; - - g_object_get (sestream, "pad", &pad, NULL); - - - /* Take the stream lock to make sure nothing is flowing through the - * pad - * We can only do that because we have no blocking elements before - * a queue in our pipeline after the pads. - */ - peer = gst_pad_get_peer (pad); - GST_PAD_STREAM_LOCK(pad); - if (peer) - { - gst_pad_unlink (pad, peer); - gst_object_unref (peer); - } - /* - * Releasing request pads currently fail cause stuff like - * alloc_buffer() does take any lock and there is no way to prevent it - * ??? or something like that - - if (TP_STREAM_ENGINE_IS_VIDEO_STREAM (sestream)) - gst_element_release_request_pad (self->priv->videotee, pad); - else if (TP_STREAM_ENGINE_IS_AUDIO_STREAM (sestream)) - gst_element_release_request_pad (self->priv->audiotee, pad); - */ - GST_PAD_STREAM_UNLOCK(pad); - - gst_object_unref (pad); - } - g_object_unref (sestream); -} - -static void -stream_receiving (TpStreamEngineVideoStream *videostream, gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - TfStream *stream = NULL; - TfChannel *chan = NULL; - guint stream_id; - gchar *channel_path; - - g_object_get (videostream, "stream", &stream, NULL); - - g_object_get (stream, "channel", &chan, "stream-id", &stream_id, NULL); - - g_object_get (chan, "object-path", &channel_path, NULL); - - stream_engine_svc_stream_engine_emit_receiving (self, - channel_path, stream_id, TRUE); - - g_object_unref (chan); - g_object_unref (stream); - g_free (channel_path); -} - - - -static GstElement * -_make_audio_sink (void) -{ - const gchar *elem; - GstElement *bin = NULL; - GstElement *sink = NULL; - GstElement *audioconvert = NULL; - GstElement *audioresample = NULL; - GstPad *pad; - GstPad *ghostpad; - - if ((elem = getenv ("FS_AUDIO_SINK")) || (elem = getenv("FS_AUDIOSINK"))) - { - g_debug ("making audio sink with pipeline \"%s\"", elem); - sink = gst_parse_bin_from_description (elem, TRUE, NULL); - g_assert (sink); - } - else - { - sink = gst_element_factory_make ("gconfaudiosink", NULL); - - if (sink == NULL) - sink = gst_element_factory_make ("autoaudiosink", NULL); - - if (sink == NULL) - sink = gst_element_factory_make ("pulsesink", NULL); - - if (sink == NULL) - sink = gst_element_factory_make ("alsasink", NULL); - } - - if (sink == NULL) - { - g_warning ("failed to make audio sink element!"); - return NULL; - } - - g_debug ("made audio sink element %s", GST_ELEMENT_NAME (sink)); - - bin = gst_bin_new ("audiosinkbin"); - - if (!gst_bin_add (GST_BIN (bin), sink)) - { - gst_object_unref (bin); - gst_object_unref (sink); - g_warning ("Could not add sink to bin"); - return NULL; - } - - audioresample = gst_element_factory_make ("audioresample", NULL); - if (!gst_bin_add (GST_BIN (bin), audioresample)) - { - gst_object_unref (audioresample); - gst_object_unref (bin); - g_warning ("Could not add audioresample to the bin"); - return NULL; - } - - audioconvert = gst_element_factory_make ("audioconvert", NULL); - if (!gst_bin_add (GST_BIN (bin), audioconvert)) - { - gst_object_unref (audioconvert); - gst_object_unref (bin); - g_warning ("Could not add audioconvert to the bin"); - return NULL; - } - - if (!gst_element_link_many (audioresample, audioconvert, sink, NULL)) - { - gst_object_unref (bin); - g_warning ("Could not link sink elements"); - return NULL; - } - - pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK); - - if (!pad) - { - gst_object_unref (bin); - g_warning ("Could not find unconnected sink pad in src bin"); - return NULL; - } - - ghostpad = gst_ghost_pad_new ("sink", pad); - if (!gst_element_add_pad (bin, ghostpad)) - { - gst_object_unref (ghostpad); - gst_object_unref (bin); - g_warning ("Could not add pad to bin"); - return NULL; - } - - gst_object_unref (pad); - - - return bin; -} - -/* - * BEWARE: This is called with the mutex locked - */ - -static gboolean -tp_stream_engine_add_audio_sink_locked (TpStreamEngine *self) -{ - GstElement *sink = NULL; - GstElement *liveadder = NULL; - - sink = _make_audio_sink (); - - if (!sink) - { - g_warning ("Could not make audio sink"); - goto error; - } - - if (!gst_bin_add (GST_BIN (self->priv->pipeline), sink)) - { - g_warning ("Could not add audio sink to pipeline"); - gst_object_unref (sink); - sink = NULL; - goto error; - } - - liveadder = gst_element_factory_make ("liveadder", NULL); - if (!liveadder) - { - g_warning ("Could not create liveadder"); - goto error; - } - - if (!gst_bin_add (GST_BIN (self->priv->pipeline), liveadder)) - { - gst_object_unref (liveadder); - liveadder = NULL; - g_warning ("Could not add liveadder to the bin"); - goto error; - } - - if (!gst_element_link_pads (liveadder, "src", sink, "sink")) - { - g_warning ("Could not linnk the liveadder to the sink"); - goto error; - } - - if (gst_element_set_state (sink, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE || - gst_element_set_state (liveadder, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start sink or liveadder"); - goto error; - } - - self->priv->audiosink = sink; - self->priv->audioadder = liveadder; - - return TRUE; - - error: - if (sink) - { - gst_element_set_locked_state (sink, TRUE); - gst_element_set_state (sink, GST_STATE_NULL); - gst_bin_remove (GST_BIN (self->priv->pipeline), sink); - } - if (liveadder) - { - gst_element_set_locked_state (liveadder, TRUE); - gst_element_set_state (liveadder, GST_STATE_NULL); - gst_bin_remove (GST_BIN (self->priv->pipeline), liveadder); - } - - return FALSE; -} - -/* - * BEWARE: This is called with the mutex locked - */ - -static void -tp_stream_engine_remove_audio_sink_locked (TpStreamEngine *self) -{ - gst_element_set_locked_state (self->priv->audiosink, TRUE); - gst_element_set_locked_state (self->priv->audioadder, TRUE); - gst_element_set_state (self->priv->audiosink, GST_STATE_NULL); - gst_element_set_state (self->priv->audioadder, GST_STATE_NULL); - - gst_bin_remove (GST_BIN (self->priv->pipeline), self->priv->audioadder); - gst_bin_remove (GST_BIN (self->priv->pipeline), self->priv->audiosink); - - self->priv->audiosink = NULL; - self->priv->audioadder = NULL; -} - -/* - * WARNING: - * This will be called on the streaming thread - * - */ - -static GstPad * -audiostream_request_pad (TpStreamEngineAudioStream *audiostream, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - GstPad *pad = NULL; - - g_mutex_lock (self->priv->mutex); - - if (self->priv->audiosink == NULL) - if (!tp_stream_engine_add_audio_sink_locked (self)) - goto out; - - g_assert (self->priv->audioadder); - - pad = gst_element_get_request_pad (self->priv->audioadder, "sink%d"); - - self->priv->audio_sink_use_count++; - - out: - g_mutex_unlock (self->priv->mutex); - - return pad; -} - -static void -audiostream_release_pad (TpStreamEngineAudioStream *audiostream, GstPad *pad, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - - g_mutex_lock (self->priv->mutex); - - gst_element_release_request_pad (self->priv->audioadder, pad); - - self->priv->audio_sink_use_count--; - - if (self->priv->audio_sink_use_count <= 0) - { - self->priv->audio_sink_use_count = 0; - - tp_stream_engine_remove_audio_sink_locked (self); - } - - g_mutex_unlock (self->priv->mutex); -} - -static void -channel_stream_created (TfChannel *chan G_GNUC_UNUSED, - TfStream *stream, gpointer user_data) -{ - guint media_type; - GError *error = NULL; - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO) - { - TpStreamEngineAudioStream *audiostream; - GstPad *pad; - - pad = gst_element_get_request_pad (self->priv->audiotee, "src%d"); - - audiostream = tp_stream_engine_audio_stream_new (stream, - GST_BIN (self->priv->pipeline), pad, &error); - - if (!audiostream) - { - g_warning ("Could not create audio stream: %s", error->message); - gst_element_release_request_pad (self->priv->audiotee, pad); - return; - } - g_clear_error (&error); - g_object_set_data (G_OBJECT (stream), "se-stream", audiostream); - - g_signal_connect (audiostream, "request-pad", - G_CALLBACK (audiostream_request_pad), self); - g_signal_connect (audiostream, "release-pad", - G_CALLBACK (audiostream_release_pad), self); - - } - else if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO) - { - TpStreamEngineVideoStream *videostream = NULL; - GstPad *pad; - - pad = gst_element_get_request_pad (self->priv->videotee, "src%d"); - - videostream = tp_stream_engine_video_stream_new (stream, - GST_BIN (self->priv->pipeline), pad, &error); - - if (!videostream) - { - g_warning ("Could not create video stream: %s", error->message); - gst_element_release_request_pad (self->priv->videotee, pad); - return; - } - g_clear_error (&error); - g_object_set_data (G_OBJECT (stream), "se-stream", videostream); - - g_mutex_lock (self->priv->mutex); - self->priv->output_sinks = g_list_prepend (self->priv->output_sinks, - videostream); - g_mutex_unlock (self->priv->mutex); - - g_signal_connect (videostream, "receiving", - G_CALLBACK (stream_receiving), self); - } - - g_signal_connect (stream, "closed", G_CALLBACK (stream_closed), self); - - g_signal_connect (stream, "request-resource", - G_CALLBACK (stream_request_resource), self); - g_signal_connect (stream, "free-resource", - G_CALLBACK (stream_free_resource), self); -} - -static GList * -load_codecs_config (const gchar *path, const gchar *subdir) -{ - gchar *filename; - GError *error = NULL; - GList *codec_config = NULL; - - filename = g_build_filename (path, subdir, "gstcodecs.conf", NULL); - - codec_config = fs_codec_list_from_keyfile (filename, &error); - - if (!codec_config) - g_debug ("Could not read local codecs config at %s: %s", filename, - error ? error->message : "(no error message set)"); - - g_clear_error (&error); - g_free (filename); - - return codec_config; -} - -static GList * -stream_get_codec_config (TfChannel *chan, - guint stream_id, - TpMediaStreamType media_type, - TpMediaStreamDirection direction, - TpStreamEngine *self) -{ - GList *codec_config = NULL; - const gchar *home = NULL; - - home = g_getenv ("HOME"); - if (!home) - home = g_get_home_dir (); - - codec_config = load_codecs_config (home, ".stream-engine"); - if (codec_config) - return codec_config; - - codec_config = load_codecs_config (SYSCONFDIR, "stream-engine"); - - return codec_config; -} - -static void -check_if_busy (TpStreamEngine *self) -{ - guint num_previews; - - g_mutex_lock (self->priv->mutex); - num_previews = g_list_length (self->priv->preview_sinks); - g_mutex_unlock (self->priv->mutex); - - if (self->priv->channels->len == 0 && num_previews == 0) - { - g_debug ("no channels or previews remaining; emitting no-more-channels"); - g_signal_emit (self, signals[NO_MORE_CHANNELS], 0); - } - else - { - g_debug ("channels remaining: %d", self->priv->channels->len); - g_debug ("preview windows remaining: %d", num_previews); - } -} - - -static void -channel_closed (TfChannel *chan, gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - gchar *object_path; - - g_object_get (chan, "object-path", &object_path, NULL); - - g_debug ("channel %s (%p) closed", object_path, chan); - - g_ptr_array_remove_fast (self->priv->channels, chan); - g_object_unref (chan); - - g_hash_table_remove (self->priv->channels_by_path, object_path); - g_free (object_path); - - check_if_busy (self); -} - -static void -error_one_stream (TfChannel *chan G_GNUC_UNUSED, - guint stream_id G_GNUC_UNUSED, - TfStream *stream, - gpointer user_data) -{ - const gchar *message = (const gchar *) user_data; - - tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_UNKNOWN, - message); -} - - -static void -error_all_streams (TpStreamEngine *self, const gchar *message) -{ - guint i; - - g_debug ("Closing all streams"); - - for (i = 0; i < self->priv->channels->len; i++) - { - TfChannel *channel = g_ptr_array_index (self->priv->channels, - i); - tf_channel_foreach_stream (channel, - error_one_stream, (gpointer) message); - } -} - -static gboolean -bus_async_handler (GstBus *bus G_GNUC_UNUSED, - GstMessage *message, - gpointer data) -{ - TpStreamEngine *engine = TP_STREAM_ENGINE (data); - TpStreamEnginePrivate *priv = engine->priv; - GError *error = NULL; - gchar *error_string; - guint i; - GstElement *source = GST_ELEMENT (GST_MESSAGE_SRC (message)); - gchar *name = gst_element_get_name (source); - - - for (i = 0; i < priv->channels->len; i++) - if (tf_channel_bus_message ( - g_ptr_array_index (priv->channels, i), message)) - return TRUE; - - switch (GST_MESSAGE_TYPE (message)) - { - case GST_MESSAGE_ERROR: - gst_message_parse_error (message, &error, &error_string); - - g_debug ("%s: got error from %s: %s: %s (%d %d), stopping pipeline", - G_STRFUNC, name, error->message, error_string, - error->domain, error->code); - - error_all_streams (engine, error->message); - - gst_element_set_state (engine->priv->pipeline, GST_STATE_NULL); - gst_element_set_state (engine->priv->videosrc, GST_STATE_NULL); - gst_element_set_state (engine->priv->pipeline, GST_STATE_PLAYING); - - g_free (error_string); - g_error_free (error); - break; - case GST_MESSAGE_WARNING: - { - gchar *debug_msg = NULL; - gst_message_parse_warning (message, &error, &debug_msg); - g_warning ("%s: got warning: %s (%s)", G_STRFUNC, error->message, - debug_msg); - g_free (debug_msg); - g_error_free (error); - break; - } - - default: - break; - } - - g_free (name); - return TRUE; -} - -static GstBusSyncReply -bus_sync_handler (GstBus *bus G_GNUC_UNUSED, GstMessage *message, gpointer data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (data); - GList *item; - gboolean handled = FALSE; - - if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) - return GST_BUS_PASS; - - if (!gst_structure_has_name (message->structure, "prepare-xwindow-id")) - return GST_BUS_PASS; - - - g_mutex_lock (self->priv->mutex); - for (item = g_list_first (self->priv->preview_sinks); - item && !handled; - item = g_list_next (item)) - { - TpStreamEngineVideoSink *preview = item->data; - - handled = tp_stream_engine_video_sink_bus_sync_message (preview, message); - if (handled) - break; - } - - if (!handled) - { - for (item = g_list_first (self->priv->output_sinks); - item && !handled; - item = g_list_next (item)) - { - TpStreamEngineVideoSink *output = item->data; - - handled = tp_stream_engine_video_sink_bus_sync_message (output, - message); - if (handled) - break; - } - } - g_mutex_unlock (self->priv->mutex); - - if (handled) - { - gst_message_unref (message); - return GST_BUS_DROP; - } - else - return GST_BUS_PASS; -} - -static void -_build_base_video_elements (TpStreamEngine *self) -{ - TpStreamEnginePrivate *priv = self->priv; - GstElement *videosrc = NULL; - GstElement *tee; - GstElement *capsfilter; -#ifndef MAEMO_OSSO_SUPPORT - GstElement *tmp; -#endif - const gchar *elem; - const gchar *caps_str; - gboolean ret; - GstElement *fakesink; - GstCaps *filter = NULL; - GstStateChangeReturn state_ret; - - try_again: - - if ((elem = getenv ("FS_VIDEO_SRC")) || (elem = getenv ("FS_VIDEOSRC"))) - { - if (priv->force_fakesrc) - g_error ("Invalid video source passed in FS_VIDEOSRC"); - g_debug ("making video src with pipeline \"%s\"", elem); - videosrc = gst_parse_bin_from_description (elem, TRUE, NULL); - g_assert (videosrc); - gst_element_set_name (videosrc, "videosrc"); - } - else - { - if (priv->force_fakesrc) - { - videosrc = gst_element_factory_make ("fakesrc", NULL); - g_object_set (videosrc, "is-live", TRUE, NULL); - } - - if (videosrc == NULL) - videosrc = gst_element_factory_make ("gconfvideosrc", NULL); - - if (videosrc == NULL) - videosrc = gst_element_factory_make ("v4l2src", NULL); - - if (videosrc == NULL) - videosrc = gst_element_factory_make ("v4lsrc", NULL); - - if (videosrc != NULL) - { - g_debug ("using %s as video source", GST_ELEMENT_NAME (videosrc)); - } - else - { - videosrc = gst_element_factory_make ("videotestsrc", NULL); - if (videosrc == NULL) - g_error ("failed to create any video source"); - g_object_set (videosrc, "is-live", TRUE, NULL); - } - } - - if ((caps_str = getenv ("FS_VIDEO_SRC_CAPS")) != NULL || - (caps_str = getenv ("FS_VIDEOSRC_CAPS")) != NULL) - { - filter = gst_caps_from_string (caps_str); - g_debug ("applying custom caps '%s' on the video source", caps_str); - } - else - { - filter = gst_caps_new_simple ("video/x-raw-yuv", -#ifdef MAEMO_OSSO_SUPPORT - "width", G_TYPE_INT, 176, - "height", G_TYPE_INT, 144, -#else - "width", G_TYPE_INT, 352, - "height", G_TYPE_INT, 288, - "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), -#endif - NULL); - } - - fakesink = gst_element_factory_make ("fakesink", NULL); - - gst_bin_add_many (GST_BIN (priv->pipeline), videosrc, fakesink, NULL); - - if (!gst_element_link (videosrc, fakesink)) - g_error ("Could not link fakesink to videosrc"); - - state_ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); - if (state_ret == GST_STATE_CHANGE_FAILURE) - { - if (priv->force_fakesrc) - { - g_error ("Could not even start fakesrc"); - } - else - { - g_debug ("Video source failed, falling back to fakesrc"); - state_ret = gst_element_set_state (priv->pipeline, GST_STATE_NULL); - g_assert (state_ret == GST_STATE_CHANGE_SUCCESS); - if (!gst_bin_remove (GST_BIN (priv->pipeline), fakesink)) - g_error ("Could not remove fakesink"); - - priv->force_fakesrc = TRUE; - gst_bin_remove (GST_BIN (priv->pipeline), videosrc); - goto try_again; - } - } - else - { - state_ret = gst_element_set_state (priv->pipeline, GST_STATE_NULL); - g_assert (state_ret == GST_STATE_CHANGE_SUCCESS); - gst_bin_remove (GST_BIN (priv->pipeline), fakesink); - } - - gst_element_set_locked_state (videosrc, TRUE); - - tee = gst_element_factory_make ("tee", "videotee"); - g_assert (tee); - if (!gst_bin_add (GST_BIN (priv->pipeline), tee)) - g_error ("Could not add tee to pipeline"); - - priv->videosrc = videosrc; - priv->videotee = tee; - -#ifndef MAEMO_OSSO_SUPPORT -#if 0 - /* <wtay> Tester_, yes, videorate does not play nice with live pipelines */ - tmp = gst_element_factory_make ("videorate", NULL); - if (tmp != NULL) - { - g_debug ("linking videorate"); - gst_bin_add (GST_BIN (priv->pipeline), tmp); - gst_element_link (videosrc, tmp); - videosrc = tmp; - } -#endif - - tmp = gst_element_factory_make ("ffmpegcolorspace", NULL); - if (tmp != NULL) - { - g_debug ("linking ffmpegcolorspace"); - gst_bin_add (GST_BIN (priv->pipeline), tmp); - gst_element_link (videosrc, tmp); - videosrc = tmp; - } - - tmp = gst_element_factory_make ("videoscale", NULL); - if (tmp != NULL) - { - g_debug ("linking videoscale"); - gst_bin_add (GST_BIN (priv->pipeline), tmp); - gst_element_link (videosrc, tmp); - videosrc = tmp; - } -#endif - - capsfilter = gst_element_factory_make ("capsfilter", NULL); - g_assert (capsfilter); - ret = gst_bin_add (GST_BIN (priv->pipeline), capsfilter); - g_assert (ret); - - g_object_set (capsfilter, "caps", filter, NULL); - gst_caps_unref (filter); - - ret = gst_element_link (videosrc, capsfilter); - g_assert (ret); - ret = gst_element_link (capsfilter, tee); - g_assert (ret); -} - - -static GstElement * -_make_audio_src (void) -{ - const gchar *elem; - GstElement *bin = NULL; - GstElement *audioconvert = NULL; - GstElement *src = NULL; - GstPad *pad; - GstPad *ghostpad; - - bin = gst_bin_new ("audiosrcbin"); - - if ((elem = getenv ("FS_AUDIO_SRC")) || (elem = getenv ("FS_AUDIOSRC"))) - { - g_debug ("making audio src with pipeline \"%s\"", elem); - src = gst_parse_bin_from_description (elem, TRUE, NULL); - g_assert (src); - } - else - { - src = gst_element_factory_make ("gconfaudiosrc", NULL); - - if (src == NULL) - src = gst_element_factory_make ("pulsesrc", NULL); - - if (src == NULL) - src = gst_element_factory_make ("alsasrc", NULL); - } - - if (src == NULL) - { - g_debug ("failed to make audio src element!"); - return NULL; - } - - g_debug ("made audio src element %s", GST_ELEMENT_NAME (src)); - - audioconvert = gst_element_factory_make ("audioconvert", NULL); - - - if (!gst_bin_add (GST_BIN (bin), audioconvert) || - !gst_bin_add (GST_BIN (bin), src)) - { - gst_object_unref (bin); - gst_object_unref (src); - gst_object_unref (audioconvert); - - g_warning ("Could not add audioconvert or src to the bin"); - - return NULL; - } - - if (!gst_element_link_pads (src, "src", audioconvert, "sink")) - { - gst_object_unref (bin); - g_warning ("Could not link src and audioconvert elements"); - return NULL; - } - - pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC); - - if (!pad) - { - gst_object_unref (bin); - g_warning ("Could not find unconnected sink pad in src bin"); - return NULL; - } - - ghostpad = gst_ghost_pad_new ("src", pad); - if (!gst_element_add_pad (bin, ghostpad)) - { - gst_object_unref (ghostpad); - gst_object_unref (bin); - g_warning ("Could not add pad to bin"); - return NULL; - } - - gst_object_unref (pad); - - return bin; - -} - - -static void -_build_base_audio_elements (TpStreamEngine *self) -{ - GstElement *src = NULL; - GstElement *tee = NULL; - - src = _make_audio_src (); - - if (!src) - { - g_warning ("Could not make audio src"); - return; - } - - if (!gst_bin_add (GST_BIN (self->priv->pipeline), src)) - { - g_warning ("Could not add audiosrc to pipeline"); - gst_object_unref (src); - return; - } - - gst_element_set_locked_state (src, TRUE); - - tee = gst_element_factory_make ("tee", "audiotee"); - - if (!gst_bin_add (GST_BIN (self->priv->pipeline), tee)) - { - g_warning ("Could not add audiosrc to pipeline"); - gst_object_unref (tee); - return; - } - - if (!gst_element_link_pads (src, "src", tee, "sink")) - { - g_warning ("Could not link audio src and tee"); - return; - } - - - self->priv->audiosrc = src; - self->priv->audiotee = tee; -} - - -static void -_create_pipeline (TpStreamEngine *self) -{ - TpStreamEnginePrivate *priv = self->priv; - GstBus *bus; - GstStateChangeReturn state_ret; - - priv->pipeline = gst_pipeline_new (NULL); - - fs_element_added_notifier_add (priv->notifier, GST_BIN (priv->pipeline)); - - _build_base_video_elements (self); - _build_base_audio_elements (self); - - - /* connect a callback to the stream bus so that we can set X window IDs - * at the right time, and detect when sinks have gone away */ - bus = gst_element_get_bus (priv->pipeline); - gst_bus_set_sync_handler (bus, bus_sync_handler, self); - priv->bus_async_source_id = - gst_bus_add_watch (bus, bus_async_handler, self); - gst_object_unref (bus); - - state_ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); - g_assert (state_ret != GST_STATE_CHANGE_FAILURE); -} - - -static void -_preview_window_plug_deleted (TpStreamEngineVideoPreview *preview, - gpointer user_data) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (user_data); - GstPad *pad = NULL; - - while (g_signal_handlers_disconnect_by_func(preview, - _preview_window_plug_deleted, - user_data)) {} - - g_mutex_lock (self->priv->mutex); - self->priv->preview_sinks = g_list_remove (self->priv->preview_sinks, - preview); - g_mutex_unlock (self->priv->mutex); - - tp_stream_engine_stop_video_source (self); - - g_object_get (preview, "pad", &pad, NULL); - - if (pad) - { - GstPad *peer; - /* Take the stream lock to make sure nothing is flowing through the - * pad - * We can only do that because we have no blocking elements before - * a queue in our pipeline after the pads. - */ - peer = gst_pad_get_peer (pad); - GST_PAD_STREAM_LOCK(pad); - if (peer) - { - gst_pad_unlink (pad, peer); - gst_object_unref (peer); - } - //gst_element_release_request_pad (self->priv->videotee, pad); - GST_PAD_STREAM_UNLOCK(pad); - - gst_object_unref (pad); - } - - gst_object_unref (preview); -} - -/** - * tp_stream_engine_create_preview_window - * - * Implements DBus method CreatePreviewWindow - * on interface org.maemo.Telepathy.StreamEngine - */ -static void -tp_stream_engine_create_preview_window (StreamEngineSvcStreamEngine *iface, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - GError *error = NULL; - GstPad *pad; - TpStreamEngineVideoPreview *preview; - guint window_id; - - if (self->priv->force_fakesrc) - { - GError error = {TP_ERRORS, TP_ERROR_NOT_AVAILABLE, - "Could not get a video source"}; - g_debug ("%s", error.message); - - dbus_g_method_return_error (context, &error); - return; - } - - preview = tp_stream_engine_video_preview_new (GST_BIN (self->priv->pipeline), - &error); - - if (!preview) - { - dbus_g_method_return_error (context, error); - g_clear_error (&error); - return; - } - - g_mutex_lock (self->priv->mutex); - self->priv->preview_sinks = g_list_prepend (self->priv->preview_sinks, - preview); - g_mutex_unlock (self->priv->mutex); - - pad = gst_element_get_request_pad (self->priv->videotee, "src%d"); - - g_object_set (preview, "pad", pad, NULL); - - g_signal_connect (preview, "plug-deleted", - G_CALLBACK (_preview_window_plug_deleted), self); - - g_object_get (preview, "window-id", &window_id, NULL); - - stream_engine_svc_stream_engine_return_from_create_preview_window (context, - window_id); - - tp_stream_engine_start_video_source (self); - - g_signal_emit (self, signals[HANDLING_CHANNEL], 0); -} - - -static void -handler_result (TfChannel *chan G_GNUC_UNUSED, - GError *error, - DBusGMethodInvocation *context) -{ - if (error == NULL) - stream_engine_svc_stream_engine_return_from_attach_to_channel (context); - else - dbus_g_method_return_error (context, error); -} - -/** - * tp_stream_engine_attach_to_channel - * - * Implements DBus method AttachToChannel - * on interface org.maemo.Telepathy.StreamEngine - */ -static void -tp_stream_engine_attach_to_channel (StreamEngineSvcStreamEngine *iface, - const gchar *bus_name, - const gchar *connection, - const gchar *channel_type, - const gchar *channel, - guint handle_type, - guint handle, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - TfChannel *chan = NULL; - GError *error = NULL; - - g_debug("HandleChannel called"); - - if (strcmp (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA) != 0) - { - GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Stream Engine was passed a channel that was not a " - TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA }; - - g_message ("%s", e.message); - dbus_g_method_return_error (context, &e); - return; - } - - chan = tf_channel_new (self->priv->dbus_daemon, bus_name, - connection, channel, handle_type, handle, &error); - - if (chan == NULL) - { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_ptr_array_add (self->priv->channels, chan); - g_hash_table_insert (self->priv->channels_by_path, g_strdup (channel), chan); - - g_signal_connect (chan, "handler-result", G_CALLBACK (handler_result), - context); - g_signal_connect (chan, "closed", G_CALLBACK (channel_closed), self); - g_signal_connect (chan, "session-created", - G_CALLBACK (channel_session_created), self); - g_signal_connect (chan, "session-invalidated", - G_CALLBACK (channel_session_invalidated), self); - g_signal_connect (chan, "stream-created", - G_CALLBACK (channel_stream_created), self); - g_signal_connect (chan, "stream-get-codec-config", - G_CALLBACK (stream_get_codec_config), self); - - g_signal_emit (self, signals[HANDLING_CHANNEL], 0); -} - -void -tp_stream_engine_register (TpStreamEngine *self) -{ - DBusGConnection *bus; - GError *error = NULL; - guint request_name_result; - - g_assert (TP_IS_STREAM_ENGINE (self)); - - bus = tp_get_bus (); - self->priv->dbus_daemon = tp_dbus_daemon_new (bus); - - g_debug("registering StreamEngine at " OBJECT_PATH); - dbus_g_connection_register_g_object (bus, OBJECT_PATH, G_OBJECT (self)); - - register_dbus_signal_marshallers(); - - g_debug("Requesting " BUS_NAME); - - if (!tp_cli_dbus_daemon_run_request_name (self->priv->dbus_daemon, -1, - BUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, &request_name_result, &error, - NULL)) - g_error ("Failed to request bus name: %s", error->message); - - if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS) - g_error ("Failed to acquire bus name, stream engine already running?"); -} - -static TfStream * -_lookup_stream (TpStreamEngine *self, - const gchar *path, - guint stream_id, - GError **error) -{ - TfChannel *channel; - TfStream *stream; - - channel = g_hash_table_lookup (self->priv->channels_by_path, path); - if (channel == NULL) - { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, - "stream-engine is not handling the channel %s", path); - - return NULL; - } - - stream = tf_channel_lookup_stream (channel, stream_id); - if (stream == NULL) - { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, - "the channel %s has no stream with id %d", path, stream_id); - - return NULL; - } - - return stream; -} - - -/** - * tp_stream_engine_mute_input - * - * Implements DBus method MuteInput - * on interface org.maemo.Telepathy.StreamEngine - */ - -static void -tp_stream_engine_mute_input (StreamEngineSvcStreamEngine *iface, - const gchar *channel_path, - guint stream_id, - gboolean mute_state, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - TfStream *stream; - GError *error = NULL; - TpMediaStreamType media_type; - TpStreamEngineAudioStream *audiostream; - - stream = _lookup_stream (self, channel_path, stream_id, &error); - - - if (stream == NULL) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Stream does not exist"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type != TP_MEDIA_STREAM_TYPE_AUDIO) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "MuteInput can only be called on audio streams"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - audiostream = g_object_get_data ((GObject*) stream, "se-stream"); - - g_object_set (audiostream, "input-mute", mute_state, NULL); - - stream_engine_svc_stream_engine_return_from_mute_input (context); -} - -/** - * tp_stream_engine_mute_output - * - * Implements DBus method MuteOutput - * on interface org.maemo.Telepathy.StreamEngine - */ - -static void -tp_stream_engine_mute_output (StreamEngineSvcStreamEngine *iface, - const gchar *channel_path, - guint stream_id, - gboolean mute_state, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - TfStream *stream; - GError *error = NULL; - TpMediaStreamType media_type; - TpStreamEngineAudioStream *audiostream; - - stream = _lookup_stream (self, channel_path, stream_id, &error); - - - if (stream == NULL) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Stream does not exist"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type != TP_MEDIA_STREAM_TYPE_AUDIO) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "MuteOutput can only be called on audio streams"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - audiostream = g_object_get_data ((GObject*) stream, "se-stream"); - - g_object_set (audiostream, "output-mute", mute_state, NULL); - - stream_engine_svc_stream_engine_return_from_mute_output (context); -} - - - -/** - * tp_stream_engine_set_output_volume - * - * Implements DBus method SetOutputVolume - * on interface org.maemo.Telepathy.StreamEngine - */ -static void -tp_stream_engine_set_output_volume (StreamEngineSvcStreamEngine *iface, - const gchar *channel_path, - guint stream_id, - guint volume, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - TfStream *stream; - GError *error = NULL; - TpMediaStreamType media_type; - TpStreamEngineAudioStream *audiostream; - gdouble doublevolume = volume / 100.0; - - stream = _lookup_stream (self, channel_path, stream_id, &error); - - - if (stream == NULL) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Stream does not exist"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type != TP_MEDIA_STREAM_TYPE_AUDIO) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "MuteOutput can only be called on audio streams"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - audiostream = g_object_get_data ((GObject*) stream, "se-stream"); - - g_object_set (audiostream, "output-volume", doublevolume, NULL); - - stream_engine_svc_stream_engine_return_from_mute_output (context); -} - - - -/** - * tp_stream_engine_set_input_volume - * - * Implements DBus method SetInputVolume - * on interface org.maemo.Telepathy.StreamEngine - */ -static void -tp_stream_engine_set_input_volume (StreamEngineSvcStreamEngine *iface, - const gchar *channel_path, - guint stream_id, - guint volume, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - TfStream *stream; - GError *error = NULL; - TpMediaStreamType media_type; - TpStreamEngineAudioStream *audiostream; - gdouble doublevolume = volume / 100.0; - - stream = _lookup_stream (self, channel_path, stream_id, &error); - - - if (stream == NULL) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Stream does not exist"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type != TP_MEDIA_STREAM_TYPE_AUDIO) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "MuteInput can only be called on audio streams"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - audiostream = g_object_get_data ((GObject*) stream, "se-stream"); - - g_object_set (audiostream, "input-volume", doublevolume, NULL); - - stream_engine_svc_stream_engine_return_from_mute_input (context); -} - -/** - * tp_stream_engine_get_output_window - * - * Implements DBus method SetOutputWindow - * on interface org.maemo.Telepathy.StreamEngine - */ -static void -tp_stream_engine_get_output_window (StreamEngineSvcStreamEngine *iface, - const gchar *channel_path, - guint stream_id, - DBusGMethodInvocation *context) -{ - TpStreamEngine *self = TP_STREAM_ENGINE (iface); - TfStream *stream; - TpMediaStreamType media_type; - GError *error = NULL; - - g_debug ("%s: channel_path=%s, stream_id=%u", G_STRFUNC, channel_path, - stream_id); - - stream = _lookup_stream (self, channel_path, stream_id, &error); - - if (stream == NULL) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Stream does not exist"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - g_object_get (stream, "media-type", &media_type, NULL); - - if (media_type != TP_MEDIA_STREAM_TYPE_VIDEO) - { - error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "GetOutputWindow can only be called on video streams"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - if (stream) - { - guint window_id; - TpStreamEngineVideoSink *videosink; - - videosink = TP_STREAM_ENGINE_VIDEO_SINK ( - g_object_get_data ((GObject*) stream, "se-stream")); - - g_object_get (videosink, "window-id", &window_id, NULL); - - g_debug ("Returning window id %u", window_id); - - stream_engine_svc_stream_engine_return_from_get_output_window (context, - window_id); - } -} - -/* - * tp_stream_engine_get - * - * Return the stream engine singleton. Caller does not own a reference to the - * stream engine. - */ - -TpStreamEngine * -tp_stream_engine_get () -{ - static TpStreamEngine *engine = NULL; - - if (NULL == engine) - { - engine = g_object_new (TP_TYPE_STREAM_ENGINE, NULL); - g_object_add_weak_pointer (G_OBJECT (engine), (gpointer) &engine); - } - - return engine; -} - -/** - * tp_stream_engine_shutdown - * - * Implements DBus method Shutdown - * on interface org.maemo.Telepathy.StreamEngine - */ -static void -tp_stream_engine_shutdown (StreamEngineSvcStreamEngine *iface, - DBusGMethodInvocation *context) -{ - g_debug ("%s: Emitting shutdown signal", G_STRFUNC); - g_signal_emit (iface, signals[SHUTDOWN_REQUESTED], 0); - stream_engine_svc_stream_engine_return_from_shutdown (context); -} - -static void -se_iface_init (gpointer iface, gpointer data G_GNUC_UNUSED) -{ - StreamEngineSvcStreamEngineClass *klass = iface; - -#define IMPLEMENT(x) stream_engine_svc_stream_engine_implement_##x (\ - klass, tp_stream_engine_##x) - IMPLEMENT (set_output_volume); - IMPLEMENT (set_input_volume); - IMPLEMENT (mute_input); - IMPLEMENT (mute_output); - IMPLEMENT (get_output_window); - IMPLEMENT (create_preview_window); - IMPLEMENT (shutdown); - IMPLEMENT (attach_to_channel); -#undef IMPLEMENT -} diff --git a/src/tp-stream-engine.h b/src/tp-stream-engine.h deleted file mode 100644 index ced63f5..0000000 --- a/src/tp-stream-engine.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * tp-stream-engine.h - Header for TpStreamEngine - * Copyright (C) 2005-2007 Collabora Ltd. - * Copyright (C) 2005-2007 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __TP_STREAM_ENGINE_H__ -#define __TP_STREAM_ENGINE_H__ - -#include <glib-object.h> -#include <telepathy-glib/enums.h> - -#include "videostream.h" - -G_BEGIN_DECLS - -typedef struct _TpStreamEngine TpStreamEngine; -typedef struct _TpStreamEnginePrivate TpStreamEnginePrivate; -typedef struct _TpStreamEngineClass TpStreamEngineClass; - -struct _TpStreamEngineClass { - GObjectClass parent_class; - -}; - -struct _TpStreamEngine { - GObject parent; - - TpStreamEnginePrivate *priv; -}; - -GType tp_stream_engine_get_type(void); - -/* TYPE MACROS */ -#define TP_TYPE_STREAM_ENGINE \ - (tp_stream_engine_get_type()) -#define TP_STREAM_ENGINE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TYPE_STREAM_ENGINE, TpStreamEngine)) -#define TP_STREAM_ENGINE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), TP_TYPE_STREAM_ENGINE, TpStreamEngineClass)) -#define TP_IS_STREAM_ENGINE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TYPE_STREAM_ENGINE)) -#define TP_IS_STREAM_ENGINE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TYPE_STREAM_ENGINE)) -#define TP_STREAM_ENGINE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_STREAM_ENGINE, TpStreamEngineClass)) - -GQuark tp_stream_engine_error_quark (void); - -#define TP_STREAM_ENGINE_ERROR (tp_stream_engine_error_quark ()) - -typedef enum -{ - TP_STREAM_ENGINE_ERROR_CONSTRUCTION, -} TpStreamEngineError; - -void -tp_stream_engine_register (TpStreamEngine *self); - -void -tp_stream_engine_error (TpStreamEngine *self, - int error, - const char *debug); - -TpStreamEngine * -tp_stream_engine_get (void); - -GstElement * -tp_stream_engine_make_video_sink (gboolean is_preview); - -gboolean -tp_stream_engine_add_output_window (TpStreamEngine *obj, - TpStreamEngineVideoStream *stream, - GstElement *sink, - guint window_id); - -gboolean -tp_stream_engine_remove_output_window (TpStreamEngine *obj, - guint window_id); - -G_END_DECLS - -#endif /* #ifndef __TP_STREAM_ENGINE_H__*/ diff --git a/src/util.c b/src/util.c deleted file mode 100644 index 2786080..0000000 --- a/src/util.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * util.c - Source for utility functions - * Copyright (C) 2006 Collabora Ltd. - * Copyright (C) 2006 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "util.h" - -#include <glib-object.h> - -gboolean -g_object_has_property (GObject *object, const gchar *property) -{ - GObjectClass *klass; - - klass = G_OBJECT_GET_CLASS (object); - return NULL != g_object_class_find_property (klass, property); -} - diff --git a/src/util.h b/src/util.h deleted file mode 100644 index 6c107ae..0000000 --- a/src/util.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __TP_STREAM_ENGINE_UTIL_H__ -#define __TP_STREAM_ENGINE_UTIL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -gboolean g_object_has_property (GObject *object, const gchar *property); - -G_END_DECLS - -#endif /* __TP_STREAM_ENGINE_UTIL_H__ */ diff --git a/src/videopreview.c b/src/videopreview.c deleted file mode 100644 index 63da17f..0000000 --- a/src/videopreview.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * videopreview.c - Source for TpStreamEngineVideoPreview - * Copyright (C) 2006-2008 Collabora Ltd. - * Copyright (C) 2006-2008 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -#include <gst/interfaces/xoverlay.h> -#include <gst/farsight/fs-element-added-notifier.h> - -#include <telepathy-glib/errors.h> - -#include <tp-stream-engine.h> - -#include "videopreview.h" -#include "util.h" - -G_DEFINE_TYPE (TpStreamEngineVideoPreview, tp_stream_engine_video_preview, - TP_STREAM_ENGINE_TYPE_VIDEO_SINK); - -struct _TpStreamEngineVideoPreviewPrivate -{ - GstPad *pad; - GstElement *bin; - - FsElementAddedNotifier *element_added_notifier; - - GMutex *mutex; - - GstElement *sinkbin; - - GError *construction_error; -}; - -/* properties */ -enum -{ - PROP_0, - PROP_BIN, - PROP_PAD -}; - -static void -set_preview_props (FsElementAddedNotifier *notifier, - GstBin *parent G_GNUC_UNUSED, - GstElement *element, - gpointer user_data) -{ - if (g_object_has_property ((GObject *) element, "sync")) - g_object_set (element, "sync", FALSE, NULL); - if (g_object_has_property ((GObject *) element, "async")) - g_object_set (element, "async", FALSE, NULL); -} - - -static void -tp_stream_engine_video_preview_init (TpStreamEngineVideoPreview *self) -{ - TpStreamEngineVideoPreviewPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW, TpStreamEngineVideoPreviewPrivate); - - self->priv = priv; - - self->priv->element_added_notifier = fs_element_added_notifier_new (); - - g_signal_connect (self->priv->element_added_notifier, - "element-added", G_CALLBACK (set_preview_props), NULL); - - self->priv->mutex = g_mutex_new (); -} - -static GstElement * -make_sink (TpStreamEngineVideoPreview *self) -{ - GstElement *bin = gst_bin_new (NULL); - GstElement *queue; - GstElement *sink; - GstPad *pad; - GstPad *ghostpad; - - g_object_get (self, "sink", &sink, NULL); - - if (!sink) - { - g_warning ("Could not make sink"); - goto error; - } - - if (!gst_bin_add (GST_BIN (bin), sink)) - { - gst_object_unref (sink); - g_warning ("Could not add sink to bin"); - goto error; - } - - queue = gst_element_factory_make ("queue", NULL); - if (!queue) - { - g_warning ("Could not make queue"); - goto error; - } - - if (!gst_bin_add (GST_BIN (bin), queue)) - { - gst_object_unref (queue); - g_warning ("Could not add queue to bin"); - goto error; - } - - g_object_set (queue, - "leaky", 2, - NULL); - - if (!gst_element_link (queue, sink)) - { - g_warning ("Could not link queue and sink"); - goto error; - } - - pad = gst_element_get_static_pad (queue, "sink"); - if (!pad) - { - g_warning ("Could not get queue sink pad"); - goto error; - } - - ghostpad = gst_ghost_pad_new ("sink", pad); - if (!gst_element_add_pad (bin, ghostpad)) - { - gst_object_unref (ghostpad); - g_warning ("Could not add ghostpad to bin"); - goto error; - } - - gst_object_unref (pad); - - return bin; - - error: - gst_object_unref (bin); - return NULL; -} - - -static GObject * -tp_stream_engine_video_preview_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *obj; - TpStreamEngineVideoPreview *self = NULL; - - obj = G_OBJECT_CLASS (tp_stream_engine_video_preview_parent_class)->constructor (type, n_props, props); - - self = (TpStreamEngineVideoPreview *) obj; - - if (!self->priv->bin) - { - self->priv->construction_error = g_error_new (TP_ERRORS, - TP_ERROR_INVALID_ARGUMENT, - "You must set the bin property"); - return obj; - } - - self->priv->sinkbin = make_sink (self); - - if (!self->priv->sinkbin) - { - self->priv->construction_error = g_error_new (TP_ERRORS, TP_ERROR_PERMISSION_DENIED, - "Unable to make sink"); - return obj;; - } - - fs_element_added_notifier_add (self->priv->element_added_notifier, - GST_BIN (self->priv->sinkbin)); - - if (!gst_bin_add (GST_BIN (self->priv->bin), self->priv->sinkbin)) - { - self->priv->construction_error = g_error_new (TP_ERRORS, TP_ERROR_PERMISSION_DENIED, - "Unable to add sink to the bin"); - gst_object_unref (self->priv->sinkbin); - self->priv->sinkbin = NULL; - return obj; - } - - if (gst_element_set_state (self->priv->sinkbin, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) - { - self->priv->construction_error = g_error_new (TP_ERRORS, TP_ERROR_PERMISSION_DENIED, - "Could not set sink to playing"); - return obj; - } - - return obj; -} - -static void -tp_stream_engine_video_preview_dispose (GObject *object) -{ - TpStreamEngineVideoPreview *self = TP_STREAM_ENGINE_VIDEO_PREVIEW (object); - - if (self->priv->element_added_notifier) - { - g_object_unref (self->priv->element_added_notifier); - self->priv->element_added_notifier = NULL; - } - - if (self->priv->pad) - { - gst_object_unref (self->priv->pad); - self->priv->pad = NULL; - } - - if (self->priv->sinkbin) - { - gst_element_set_locked_state (self->priv->sinkbin, TRUE); - gst_element_set_state (self->priv->sinkbin, GST_STATE_NULL); - gst_bin_remove (GST_BIN (self->priv->bin), self->priv->sinkbin); - self->priv->sinkbin = NULL; - } - - if (self->priv->bin) - { - gst_object_unref (self->priv->bin); - self->priv->bin = NULL; - } - - if (G_OBJECT_CLASS (tp_stream_engine_video_preview_parent_class)->dispose) - G_OBJECT_CLASS (tp_stream_engine_video_preview_parent_class)->dispose ( - object); -} - - -static void -tp_stream_engine_video_preview_finalize (GObject *object) -{ - TpStreamEngineVideoPreview *self = TP_STREAM_ENGINE_VIDEO_PREVIEW (object); - - g_mutex_free (self->priv->mutex); - - if (G_OBJECT_CLASS (tp_stream_engine_video_preview_parent_class)->finalize) - G_OBJECT_CLASS (tp_stream_engine_video_preview_parent_class)->finalize ( - object); -} - - -static void -tp_stream_engine_video_preview_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineVideoPreview *self = TP_STREAM_ENGINE_VIDEO_PREVIEW (object); - - switch (property_id) - { - case PROP_BIN: - self->priv->bin = g_value_dup_object (value); - break; - case PROP_PAD: - { - GstPad *pad; - - if (self->priv->pad) - { - g_warning ("Trying to set already set pad"); - return; - } - - self->priv->pad = g_value_dup_object (value); - - pad = gst_element_get_static_pad (self->priv->sinkbin, "sink"); - - if (GST_PAD_LINK_FAILED (gst_pad_link (self->priv->pad, pad))) - g_warning ("Could not link pad to preview sink"); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -tp_stream_engine_video_preview_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineVideoPreview *self = TP_STREAM_ENGINE_VIDEO_PREVIEW (object); - - switch (property_id) - { - case PROP_BIN: - g_value_set_object (value, self->priv->bin); - break; - case PROP_PAD: - g_value_set_object (value, self->priv->pad); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -tp_stream_engine_video_preview_class_init (TpStreamEngineVideoPreviewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (TpStreamEngineVideoPreviewPrivate)); - object_class->dispose = tp_stream_engine_video_preview_dispose; - object_class->finalize = tp_stream_engine_video_preview_finalize; - object_class->constructor = tp_stream_engine_video_preview_constructor; - object_class->set_property = tp_stream_engine_video_preview_set_property; - object_class->get_property = tp_stream_engine_video_preview_get_property; - - g_object_class_install_property (object_class, PROP_BIN, - g_param_spec_object ("bin", - "The Bin to add stuff to", - "The Bin to add the elements to", - GST_TYPE_BIN, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_PAD, - g_param_spec_object ("pad", - "The pad to get the data from", - "the GstPad the data comes from", - GST_TYPE_PAD, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); -} - - - -TpStreamEngineVideoPreview * -tp_stream_engine_video_preview_new (GstBin *bin, - GError **error) -{ - TpStreamEngineVideoPreview *self = NULL; - - self = g_object_new (TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW, - "bin", bin, - "is-preview", TRUE, - NULL); - - if (self->priv->construction_error) - { - g_propagate_error (error, self->priv->construction_error); - g_object_unref (self); - return NULL; - } - - return self; -} diff --git a/src/videopreview.h b/src/videopreview.h deleted file mode 100644 index e97aa85..0000000 --- a/src/videopreview.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __TP_STREAM_ENGINE_VIDEO_PREVIEW_H__ -#define __TP_STREAM_ENGINE_VIDEO_PREVIEW_H__ - -#include <glib-object.h> - -#include "videosink.h" - -G_BEGIN_DECLS - -#define TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW tp_stream_engine_video_preview_get_type() - -#define TP_STREAM_ENGINE_VIDEO_PREVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW, TpStreamEngineVideoPreview)) - -#define TP_STREAM_ENGINE_VIDEO_PREVIEW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW, TpStreamEngineVideoPreviewClass)) - -#define TP_STREAM_ENGINE_IS_VIDEO_PREVIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW)) - -#define TP_STREAM_ENGINE_IS_VIDEO_PREVIEW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW)) - -#define TP_STREAM_ENGINE_VIDEO_PREVIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_PREVIEW, TpStreamEngineVideoPreviewClass)) - -typedef struct _TpStreamEngineVideoPreviewPrivate - TpStreamEngineVideoPreviewPrivate; - -typedef struct { - TpStreamEngineVideoSink parent; - - TpStreamEngineVideoPreviewPrivate *priv; -} TpStreamEngineVideoPreview; - -typedef struct { - TpStreamEngineVideoSinkClass parent_class; -} TpStreamEngineVideoPreviewClass; - -GType tp_stream_engine_video_preview_get_type (void); - -TpStreamEngineVideoPreview * -tp_stream_engine_video_preview_new (GstBin *bin, - GError **error); - -G_END_DECLS - -#endif /* __TP_STREAM_ENGINE_VIDEO_PREVIEW_H__ */ diff --git a/src/videosink.c b/src/videosink.c deleted file mode 100644 index a7483ff..0000000 --- a/src/videosink.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * videosink.c - Source for TpStreamEngineVideoSink - * Copyright (C) 2006-2008 Collabora Ltd. - * Copyright (C) 2006-2008 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <stdlib.h> - -#include <gst/interfaces/xoverlay.h> -#include <gst/farsight/fs-element-added-notifier.h> - -#include <tp-stream-engine.h> - -#include <gtk/gtk.h> - -#include "videosink.h" -#include "util.h" - -G_DEFINE_ABSTRACT_TYPE (TpStreamEngineVideoSink, tp_stream_engine_video_sink, - G_TYPE_OBJECT); - -struct _TpStreamEngineVideoSinkPrivate -{ - GstElement *sink; - GtkWidget *plug; - - guint window_id; - - gboolean is_preview; - - gulong delete_event_handler_id; - gulong embedded_handler_id; -}; - -/* properties */ -enum -{ - PROP_0, - PROP_SINK, - PROP_WINDOW_ID, - PROP_IS_PREVIEW -}; - - -/* signals */ - -enum -{ - PLUG_DELETED, - SIGNAL_COUNT -}; - - -static guint signals[SIGNAL_COUNT] = {0}; - -static void -tp_stream_engine_video_sink_init (TpStreamEngineVideoSink *self) -{ - TpStreamEngineVideoSinkPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - TP_STREAM_ENGINE_TYPE_VIDEO_SINK, TpStreamEngineVideoSinkPrivate); - - self->priv = priv; -} - - - -static GstElement * -make_video_sink (gboolean is_preview) -{ - const gchar *videosink_name; - GstElement *sink = NULL; -#ifndef MAEMO_OSSO_SUPPORT - GstElement *bin, *tmp; - GstPad *pad; - GstPad *ghostpad; -#endif - - if ((videosink_name = getenv ("PREVIEW_VIDEO_SINK")) || - (videosink_name = getenv ("FS_VIDEO_SINK")) || - (videosink_name = getenv ("FS_VIDEOSINK"))) - { - g_debug ("making video sink for local preview with pipeline \"%s\"", videosink_name); - sink = gst_parse_bin_from_description (videosink_name, TRUE, NULL); - } - else - { -#ifndef MAEMO_OSSO_SUPPORT - if (is_preview) { - /* hack to leave an xvimage free for the bigger output. - * Most machines only have one xvport, so this helps in the majority of - * cases. More intelligent widgets could do it for us? Maybe know - * how many Xv ports there are and do a more educated guess - * */ - sink = gst_element_factory_make ("ximagesink", NULL); - } - - if (sink == NULL) - sink = gst_element_factory_make ("gconfvideosink", NULL); - - if (sink == NULL) - sink = gst_element_factory_make ("autovideosink", NULL); -#endif - - if (sink == NULL) - sink = gst_element_factory_make ("xvimagesink", NULL); - -#ifndef MAEMO_OSSO_SUPPORT - if (sink == NULL) - sink = gst_element_factory_make ("ximagesink", NULL); -#endif - } - - if (sink == NULL) - { - g_debug ("failed to make a video sink"); - return NULL; - } - - g_debug ("made video sink element %s", GST_ELEMENT_NAME (sink)); - -#ifndef MAEMO_OSSO_SUPPORT - bin = gst_bin_new (NULL); - - if (!gst_bin_add (GST_BIN (bin), sink)) - { - g_warning ("Could not add source bin to the pipeline"); - gst_object_unref (bin); - gst_object_unref (sink); - return NULL; - } - - tmp = gst_element_factory_make ("videoscale", NULL); - if (tmp != NULL) - { - g_object_set (tmp, "qos", FALSE, NULL); - g_debug ("linking videoscale"); - if (!gst_bin_add (GST_BIN (bin), tmp)) - { - g_warning ("Could not add videoscale to the source bin"); - gst_object_unref (tmp); - gst_object_unref (bin); - return NULL; - } - if (!gst_element_link (tmp, sink)) - { - g_warning ("Could not link sink and videoscale elements"); - gst_object_unref (bin); - return NULL; - } - sink = tmp; - } - - tmp = gst_element_factory_make ("ffmpegcolorspace", NULL); - if (tmp != NULL) - { - g_object_set (tmp, "qos", FALSE, NULL); - g_debug ("linking ffmpegcolorspace"); - - if (!gst_bin_add (GST_BIN (bin), tmp)) - { - g_warning ("Could not add ffmpegcolorspace to the source bin"); - gst_object_unref (tmp); - gst_object_unref (bin); - return NULL; - } - if (!gst_element_link (tmp, sink)) - { - g_warning ("Could not link sink and ffmpegcolorspace elements"); - gst_object_unref (bin); - return NULL; - } - sink = tmp; - } - - pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK); - - if (!pad) - { - g_warning ("Could not find unconnected sink pad in the source bin"); - gst_object_unref (bin); - return NULL; - } - - ghostpad = gst_ghost_pad_new ("sink", pad); - if (!gst_element_add_pad (bin, ghostpad)) - { - gst_object_unref (ghostpad); - g_warning ("Could not add sink ghostpad to the source bin"); - gst_object_unref (bin); - return NULL; - } - gst_object_unref (GST_OBJECT (pad)); - - sink = bin; -#endif - - return sink; -} - - -static gboolean -delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - g_signal_emit (user_data, signals[PLUG_DELETED], 0); - - gtk_widget_hide (widget); - return TRUE; -} - -static GObject * -tp_stream_engine_video_sink_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *obj; - TpStreamEngineVideoSink *self = NULL; - - obj = G_OBJECT_CLASS (tp_stream_engine_video_sink_parent_class)->constructor (type, n_props, props); - - self = (TpStreamEngineVideoSink *) obj; - - self->priv->sink = make_video_sink (self->priv->is_preview); - - if (self->priv->sink) - gst_object_ref (self->priv->sink); - - self->priv->plug = gtk_plug_new (0); - self->priv->delete_event_handler_id = g_signal_connect (self->priv->plug, - "delete-event", G_CALLBACK (delete_event), self); - self->priv->embedded_handler_id = g_signal_connect (self->priv->plug, - "embedded", G_CALLBACK (gtk_widget_show), NULL); - - self->priv->window_id = gtk_plug_get_id (GTK_PLUG (self->priv->plug)); - - return obj; -} - -static void -tp_stream_engine_video_sink_dispose (GObject *object) -{ - TpStreamEngineVideoSink *self = TP_STREAM_ENGINE_VIDEO_SINK (object); - - if (self->priv->sink) - { - gst_object_unref (self->priv->sink); - self->priv->sink = NULL; - } - - if (self->priv->delete_event_handler_id) - { - g_signal_handler_disconnect (self->priv->plug, - self->priv->delete_event_handler_id); - self->priv->delete_event_handler_id = 0; - } - - if (self->priv->embedded_handler_id) - { - g_signal_handler_disconnect (self->priv->plug, - self->priv->embedded_handler_id); - self->priv->embedded_handler_id = 0; - } - - if (self->priv->plug) - { - gtk_widget_destroy (self->priv->plug); - self->priv->plug = NULL; - } - - if (G_OBJECT_CLASS (tp_stream_engine_video_sink_parent_class)->dispose) - G_OBJECT_CLASS (tp_stream_engine_video_sink_parent_class)->dispose ( - object); -} - - - -static void -tp_stream_engine_video_sink_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineVideoSink *self = TP_STREAM_ENGINE_VIDEO_SINK (object); - - switch (property_id) - { - case PROP_IS_PREVIEW: - self->priv->is_preview = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -tp_stream_engine_video_sink_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineVideoSink *self = TP_STREAM_ENGINE_VIDEO_SINK (object); - - switch (property_id) - { - case PROP_SINK: - g_value_set_object (value, self->priv->sink); - break; - case PROP_WINDOW_ID: - g_value_set_uint (value, self->priv->window_id); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -static void -tp_stream_engine_video_sink_class_init (TpStreamEngineVideoSinkClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (TpStreamEngineVideoSinkPrivate)); - object_class->dispose = tp_stream_engine_video_sink_dispose; - object_class->constructor = tp_stream_engine_video_sink_constructor; - object_class->set_property = tp_stream_engine_video_sink_set_property; - object_class->get_property = tp_stream_engine_video_sink_get_property; - - g_object_class_install_property (object_class, PROP_SINK, - g_param_spec_object ("sink", - "The video sink element", - "The GstElement that is used as videosink", - GST_TYPE_ELEMENT, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_WINDOW_ID, - g_param_spec_uint ("window-id", - "Window id", - "The window id to Xembed", - 0, G_MAXUINT, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_IS_PREVIEW, - g_param_spec_boolean ("is-preview", - "Window id", - "The window id to Xembed", - FALSE, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - signals[PLUG_DELETED] = - g_signal_new ("plug-deleted", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -set_window_xid (gpointer data, gpointer user_data) -{ - GstXOverlay *xov = GST_X_OVERLAY (data); - gulong xid = GPOINTER_TO_UINT (user_data); - - gst_x_overlay_set_xwindow_id (xov, xid); -} - -gboolean -tp_stream_engine_video_sink_bus_sync_message ( - TpStreamEngineVideoSink *self, - GstMessage *message) -{ - const GstStructure *s; - gboolean found = FALSE; -#ifndef MAEMO_OSSO_SUPPORT - GstIterator *it = NULL; -#endif - - if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) - return FALSE; - - s = gst_message_get_structure (message); - if (!gst_structure_has_name (s, "prepare-xwindow-id")) - return FALSE; - -#ifdef MAEMO_OSSO_SUPPORT - - if (GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (self->priv->sink)) - { - g_debug ("Setting window id on sink"); - gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (self->priv->sink), - self->priv->window_id); - found = TRUE; - } -#else - - it = gst_bin_iterate_all_by_interface (GST_BIN (self->priv->sink), - GST_TYPE_X_OVERLAY); - while (gst_iterator_foreach (it, set_window_xid, - GUINT_TO_POINTER (self->priv->window_id)) == GST_ITERATOR_RESYNC) - gst_iterator_resync (it); - gst_iterator_free (it); - -#endif - - return found; -} diff --git a/src/videosink.h b/src/videosink.h deleted file mode 100644 index 06b763c..0000000 --- a/src/videosink.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __TP_STREAM_ENGINE_VIDEO_SINK_H__ -#define __TP_STREAM_ENGINE_VIDEO_SINK_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define TP_STREAM_ENGINE_TYPE_VIDEO_SINK tp_stream_engine_video_sink_get_type() - -#define TP_STREAM_ENGINE_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_SINK, TpStreamEngineVideoSink)) - -#define TP_STREAM_ENGINE_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TP_STREAM_ENGINE_TYPE_VIDEO_SINK, TpStreamEngineVideoSinkClass)) - -#define TP_STREAM_ENGINE_IS_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_SINK)) - -#define TP_STREAM_ENGINE_IS_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - TP_STREAM_ENGINE_TYPE_VIDEO_SINK)) - -#define TP_STREAM_ENGINE_VIDEO_SINK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_SINK, TpStreamEngineVideoSinkClass)) - -typedef struct _TpStreamEngineVideoSinkPrivate - TpStreamEngineVideoSinkPrivate; - -typedef struct { - GObject parent; - - TpStreamEngineVideoSinkPrivate *priv; -} TpStreamEngineVideoSink; - -typedef struct { - GObjectClass parent_class; -} TpStreamEngineVideoSinkClass; - -GType tp_stream_engine_video_sink_get_type (void); - -gboolean -tp_stream_engine_video_sink_bus_sync_message ( - TpStreamEngineVideoSink *self, - GstMessage *message); - - -G_END_DECLS - -#endif /* __TP_STREAM_ENGINE_VIDEO_SINK_H__ */ diff --git a/src/videostream.c b/src/videostream.c deleted file mode 100644 index 85385f9..0000000 --- a/src/videostream.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * stream.c - Source for TpStreamEngineVideoStream - * Copyright (C) 2006-2008 Collabora Ltd. - * Copyright (C) 2006-2008 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -#include <telepathy-glib/errors.h> - -#include <gst/interfaces/xoverlay.h> - -#include "videostream.h" -#include "tp-stream-engine.h" -#include "tp-stream-engine-signals-marshal.h" -#include "util.h" - -G_DEFINE_TYPE (TpStreamEngineVideoStream, tp_stream_engine_video_stream, - TP_STREAM_ENGINE_TYPE_VIDEO_SINK); - -#define DEBUG(stream, format, ...) \ - g_debug ("stream %d (video) %s: " format, \ - ((TfStream *) stream)->stream_id, \ - G_STRFUNC, \ - ##__VA_ARGS__) - -struct _TpStreamEngineVideoStreamPrivate -{ - TfStream *stream; - - gulong src_pad_added_handler_id; - - GError *construction_error; - - GstPad *pad; - - GstElement *bin; - - GstElement *sink; - - GstElement *queue; - - GMutex *mutex; - - /* Everything below this line is protected by the mutex */ - guint error_idle_id; - - GstPad *sinkpad; - gulong receiving_probe_id; - guint receiving_idle_id; -}; - - -enum -{ - RECEIVING, - SIGNAL_COUNT -}; - -static guint signals[SIGNAL_COUNT] = {0}; - - -/* properties */ -enum -{ - PROP_0, - PROP_STREAM, - PROP_BIN, - PROP_PAD, -}; - - -static GstElement * -tp_stream_engine_video_stream_make_sink (TpStreamEngineVideoStream *stream, - GstPad **pad); - -static void src_pad_added_cb (TfStream *stream, GstPad *pad, - FsCodec *codec, gpointer user_data); - - - -static void tp_stream_engine_video_stream_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); - -static void tp_stream_engine_video_stream_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); - - -static void -tp_stream_engine_video_stream_init (TpStreamEngineVideoStream *self) -{ - TpStreamEngineVideoStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - TP_STREAM_ENGINE_TYPE_VIDEO_STREAM, TpStreamEngineVideoStreamPrivate); - - self->priv = priv; - - self->priv->mutex = g_mutex_new (); -} - - -static GstElement * -tp_stream_engine_video_stream_make_sink (TpStreamEngineVideoStream *self, - GstPad **pad) -{ - GstElement *bin = gst_bin_new (NULL); - GstElement *sink = NULL; - GstElement *funnel = NULL; - - g_object_get (self, "sink", &sink, NULL); - - if (!sink) - { - g_warning ("Could not make sink"); - goto error; - } - - if (!gst_bin_add (GST_BIN (bin), sink)) - { - gst_object_unref (sink); - g_warning ("Could not add sink to bin"); - goto error; - } - - funnel = gst_element_factory_make ("fsfunnel", "funnel"); - if (!funnel) - { - g_warning ("Could not make funnel"); - goto error; - } - - if (!gst_bin_add (GST_BIN (bin), funnel)) - { - gst_object_unref (funnel); - g_warning ("Could not add funnel to bin"); - goto error; - } - - if (!gst_element_link (funnel, sink)) - { - g_warning ("Could not link funnel and sink"); - goto error; - } - - *pad = gst_element_get_static_pad (sink, "sink"); - gst_object_unref (*pad); - - return bin; -error: - gst_object_unref (bin); - return NULL; -} - -static gboolean -receiving_idle (gpointer user_data) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (user_data); - - g_mutex_lock (self->priv->mutex); - self->priv->receiving_idle_id = 0; - g_mutex_unlock (self->priv->mutex); - - g_signal_emit (self, signals[RECEIVING], 0); - - return FALSE; -} - -static gboolean -receiving_data (GstPad *pad, GstMiniObject *obj, gpointer user_data) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (user_data); - - g_mutex_lock (self->priv->mutex); - self->priv->receiving_idle_id = g_idle_add (receiving_idle, self); - gst_pad_remove_buffer_probe (pad, self->priv->receiving_probe_id); - self->priv->receiving_probe_id = 0; - g_mutex_unlock (self->priv->mutex); - - return TRUE; -} - -static GObject * -tp_stream_engine_video_stream_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *obj; - TpStreamEngineVideoStream *self = NULL; - GstElement *sink = NULL; - GstPad *srcpad; - GstPad *sinkpad; - - obj = G_OBJECT_CLASS (tp_stream_engine_video_stream_parent_class)->constructor (type, n_props, props); - - self = (TpStreamEngineVideoStream *) obj; - - sink = tp_stream_engine_video_stream_make_sink (self, &self->priv->sinkpad); - - if (!sink) - return obj; - - if (!gst_bin_add (GST_BIN (self->priv->bin), sink)) - { - g_warning ("Could not add sink to bin"); - return obj; - } - - self->priv->sink = sink; - - self->priv->receiving_probe_id = - gst_pad_add_buffer_probe (self->priv->sinkpad, - G_CALLBACK (receiving_data), self); - - if (gst_element_set_state (sink, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start sink"); - return obj; - } - - self->priv->queue = gst_element_factory_make ("queue", NULL); - - if (!self->priv->queue) - { - g_warning ("Could not make queue element"); - return obj; - } - - g_object_set (self->priv->queue, "leaky", 2, NULL); - - if (!gst_bin_add (GST_BIN (self->priv->bin), self->priv->queue)) - { - g_warning ("Could not add quue to bin"); - return obj; - } - - if (gst_element_set_state (self->priv->queue, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start queue"); - return obj; - } - - sinkpad = gst_element_get_static_pad (self->priv->queue, "sink"); - - if (GST_PAD_LINK_FAILED (gst_pad_link (self->priv->pad, sinkpad))) - { - g_warning ("Could not link sink to queue"); - gst_object_unref (sinkpad); - return obj; - } - - gst_object_unref (sinkpad); - - g_object_get (self->priv->stream, "sink-pad", &sinkpad, NULL); - - if (!sinkpad) - { - g_warning ("Could not get stream's sinkpad"); - return obj; - } - - srcpad = gst_element_get_static_pad (self->priv->queue, "src"); - - if (!sinkpad) - { - g_warning ("Could not get queue's srcpad"); - gst_object_unref (sinkpad); - return obj; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (srcpad, sinkpad))) - { - gst_object_unref (srcpad); - gst_object_unref (sinkpad); - g_warning ("Could not link sink to queue"); - return obj; - } - - gst_object_unref (srcpad); - gst_object_unref (sinkpad); - - - self->priv->src_pad_added_handler_id = g_signal_connect (self->priv->stream, - "src-pad-added", G_CALLBACK (src_pad_added_cb), self); - - return obj; -} - -static void -tp_stream_engine_video_stream_dispose (GObject *object) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (object); - - - if (self->priv->src_pad_added_handler_id) - { - g_signal_handler_disconnect (self->priv->stream, - self->priv->src_pad_added_handler_id); - self->priv->src_pad_added_handler_id = 0; - } - - g_mutex_lock (self->priv->mutex); - if (self->priv->receiving_probe_id) - { - gst_pad_remove_buffer_probe (self->priv->sinkpad, - self->priv->receiving_probe_id); - self->priv->receiving_probe_id = 0; - } - if (self->priv->error_idle_id) - { - g_source_remove (self->priv->error_idle_id); - self->priv->error_idle_id = 0; - } - if (self->priv->receiving_idle_id) - { - g_source_remove (self->priv->receiving_idle_id); - self->priv->error_idle_id = 0; - } - g_mutex_unlock (self->priv->mutex); - - if (self->priv->queue) - { - gst_element_set_locked_state (self->priv->queue, TRUE); - gst_element_set_state (self->priv->queue, GST_STATE_NULL); - gst_bin_remove (GST_BIN (self->priv->bin), self->priv->queue); - self->priv->queue = NULL; - } - - if (self->priv->sink) - { - gst_element_set_locked_state (self->priv->sink, TRUE); - gst_element_set_state (self->priv->sink, GST_STATE_NULL); - - gst_bin_remove (GST_BIN (self->priv->bin), self->priv->sink); - self->priv->sink = NULL; - self->priv->sinkpad = NULL; - } - - if (self->priv->bin) - { - gst_object_unref (self->priv->bin); - self->priv->bin = NULL; - } - - if (self->priv->stream) - { - g_object_unref (self->priv->stream); - self->priv->stream = NULL; - } - - if (G_OBJECT_CLASS (tp_stream_engine_video_stream_parent_class)->dispose) - G_OBJECT_CLASS (tp_stream_engine_video_stream_parent_class)->dispose (object); -} - -static void -tp_stream_engine_video_stream_finalize (GObject *object) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (object); - - g_mutex_free (self->priv->mutex); - - if (G_OBJECT_CLASS (tp_stream_engine_video_stream_parent_class)->finalize) - G_OBJECT_CLASS (tp_stream_engine_video_stream_parent_class)->finalize (object); -} - -static void -tp_stream_engine_video_stream_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (object); - - switch (property_id) - { - case PROP_STREAM: - self->priv->stream = g_value_dup_object (value); - break; - case PROP_BIN: - self->priv->bin = g_value_dup_object (value); - break; - case PROP_PAD: - self->priv->pad = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -tp_stream_engine_video_stream_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (object); - - switch (property_id) - { - case PROP_STREAM: - g_value_set_object (value, self->priv->stream); - break; - case PROP_BIN: - g_value_set_object (value, self->priv->bin); - break; - case PROP_PAD: - g_value_set_object (value, self->priv->pad); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -tp_stream_engine_video_stream_class_init (TpStreamEngineVideoStreamClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (TpStreamEngineVideoStreamPrivate)); - object_class->dispose = tp_stream_engine_video_stream_dispose; - object_class->finalize = tp_stream_engine_video_stream_finalize; - object_class->constructor = tp_stream_engine_video_stream_constructor; - object_class->set_property = tp_stream_engine_video_stream_set_property; - object_class->get_property = tp_stream_engine_video_stream_get_property; - - g_object_class_install_property (object_class, PROP_STREAM, - g_param_spec_object ("stream", - "Tp StreamEngine Stream", - "The Telepathy Stream Engine Stream", - TF_TYPE_STREAM, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_BIN, - g_param_spec_object ("bin", - "The Bin to add stuff to", - "The Bin to add the elements to", - GST_TYPE_BIN, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_PAD, - g_param_spec_object ("pad", - "The pad to get the data from", - "the GstPad the data comes from", - GST_TYPE_PAD, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - signals[RECEIVING] = - g_signal_new ("receiving", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - - -static gboolean -src_pad_added_idle_error (gpointer user_data) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (user_data); - - tf_stream_error (self->priv->stream, 0, - "Error setting up video reception"); - - - g_mutex_lock (self->priv->mutex); - self->priv->error_idle_id = 0; - g_mutex_unlock (self->priv->mutex); - - return FALSE; -} - -static void -src_pad_added_cb (TfStream *stream, GstPad *pad, FsCodec *codec, - gpointer user_data) -{ - TpStreamEngineVideoStream *self = TP_STREAM_ENGINE_VIDEO_STREAM (user_data); - GstPad *sinkpad; - GstPad *ghost; - GstElement *funnel; - - funnel = gst_bin_get_by_name (GST_BIN (self->priv->sink), "funnel"); - - if (!funnel) - { - g_warning ("Could not get funnel"); - goto error; - } - - - sinkpad = gst_element_get_request_pad (funnel, "sink%d"); - if (!sinkpad) - { - gst_object_unref (funnel); - g_warning ("Could not get funnel sink pad"); - goto error; - } - - gst_object_unref (funnel); - - ghost = gst_ghost_pad_new (NULL, sinkpad); - - gst_object_unref (sinkpad); - - gst_pad_set_active (ghost, TRUE); - - if (!gst_element_add_pad (self->priv->sink, ghost)) - { - g_warning ("Could not add ghost pad to sink bin"); - gst_object_unref (ghost); - goto error; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (pad, ghost))) - { - g_warning ("Could not link pad to ghost pad"); - goto error; - } - - return; - - - error: - - g_mutex_lock (self->priv->mutex); - if (!self->priv->error_idle_id) - self->priv->error_idle_id = - g_idle_add (src_pad_added_idle_error, self); - g_mutex_unlock (self->priv->mutex); -} - - - -TpStreamEngineVideoStream * -tp_stream_engine_video_stream_new ( - TfStream *stream, - GstBin *bin, - GstPad *pad, - GError **error) -{ - TpStreamEngineVideoStream *self = NULL; - - - self = g_object_new (TP_STREAM_ENGINE_TYPE_VIDEO_STREAM, - "stream", stream, - "bin", bin, - "pad", pad, - "is-preview", FALSE, - NULL); - - if (self->priv->construction_error) - { - g_propagate_error (error, self->priv->construction_error); - g_object_unref (self); - return NULL; - } - - return self; -} diff --git a/src/videostream.h b/src/videostream.h deleted file mode 100644 index 2d614a6..0000000 --- a/src/videostream.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __TP_STREAM_ENGINE_VIDEO_STREAM_H__ -#define __TP_STREAM_ENGINE_VIDEO_STREAM_H__ - -#include <glib-object.h> - -#include <telepathy-farsight/stream.h> - -#include "videosink.h" - -G_BEGIN_DECLS - -#define TP_STREAM_ENGINE_TYPE_VIDEO_STREAM tp_stream_engine_video_stream_get_type() - -#define TP_STREAM_ENGINE_VIDEO_STREAM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_STREAM, TpStreamEngineVideoStream)) - -#define TP_STREAM_ENGINE_VIDEO_STREAM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TP_STREAM_ENGINE_TYPE_VIDEO_STREAM, TpStreamEngineVideoStreamClass)) - -#define TP_STREAM_ENGINE_IS_VIDEO_STREAM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_STREAM)) - -#define TP_STREAM_ENGINE_IS_VIDEO_STREAM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - TP_STREAM_ENGINE_TYPE_VIDEO_STREAM)) - -#define TP_STREAM_ENGINE_VIDEO_STREAM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - TP_STREAM_ENGINE_TYPE_VIDEO_STREAM, TpStreamEngineVideoStreamClass)) - -typedef struct _TpStreamEngineVideoStreamPrivate - TpStreamEngineVideoStreamPrivate; - -typedef struct { - TpStreamEngineVideoSink parent; - - TpStreamEngineVideoStreamPrivate *priv; -} TpStreamEngineVideoStream; - -typedef struct { - TpStreamEngineVideoSinkClass parent_class; -} TpStreamEngineVideoStreamClass; - -GType tp_stream_engine_video_stream_get_type (void); - - -TpStreamEngineVideoStream * -tp_stream_engine_video_stream_new ( - TfStream *stream, - GstBin *bin, - GstPad *pad, - GError **error); - -G_END_DECLS - -#endif /* __TP_STREAM_ENGINE_VIDEO_STREAM_H__ */ diff --git a/telepathy-farsight/Makefile.am b/telepathy-farsight/Makefile.am index 2676d7a..fc61aff 100644 --- a/telepathy-farsight/Makefile.am +++ b/telepathy-farsight/Makefile.am @@ -29,9 +29,7 @@ AM_CFLAGS = \ $(ERROR_CFLAGS) \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(X11_CFLAGS) \ $(GST_CFLAGS) \ - $(GST_INTERFACES_CFLAGS) \ $(FARSIGHT2_CFLAGS) \ $(TELEPATHY_CFLAGS) \ -I$(top_srcdir) \ @@ -40,8 +38,6 @@ AM_CFLAGS = \ libtelepathy_farsight_la_LIBADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS) \ - $(X11_LIBS) \ - $(GST_INTERFACES_LIB) \ $(GST_LIBS) \ $(FARSIGHT2_LIBS) \ $(TELEPATHY_LIBS) diff --git a/test/Makefile.am b/test/Makefile.am deleted file mode 100644 index 96fcb3e..0000000 --- a/test/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = python diff --git a/test/do_test.sh b/test/do_test.sh deleted file mode 100644 index 473e240..0000000 --- a/test/do_test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sh $PWD/run-with-tmp-session-bus.sh python python/test-stream-engine.py diff --git a/test/python/Makefile.am b/test/python/Makefile.am deleted file mode 100644 index 4a4be6d..0000000 --- a/test/python/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = test-stream-engine.py diff --git a/test/python/test-gabble-voip.py b/test/python/test-gabble-voip.py deleted file mode 100644 index d78d32e..0000000 --- a/test/python/test-gabble-voip.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python - -# test-gabble-voip.py - test the functionality of gabble hooked up to the stream engine -# -# Copyright (C) 2005 Collabora Limited -# Copyright (C) 2005 Nokia Corporation -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - -import dbus -import dbus.glib -import dbus.service - -assert(getattr(dbus, 'version', (0,0,0)) >= (0,51,0)) - -import gobject - -import telepathy.server -from telepathy import * - -TEST_APP_NAME = "org.freedesktop.Telepathy.TestGabbleVoip" - -def connection_handle_new_channel(channel_path, channel_type, handle_type, handle, suppress_handler, **kwargs): - print "connection_handle_new_channel" - print " channel_path = '%s'" % (channel_path,) - print " channel_type = '%s'" % (channel_type,) - print " handle_type = %d" % (handle_type,) - print " handle = %d" % (handle,) - print " suppress_handler = %s" % (suppress_handler,) - print " kwargs:", kwargs - print - - if not channel_type == CHANNEL_TYPE_STREAMED_MEDIA: - return - - print "connection_handle_new_channel: detected a CHANNEL_TYPE_STREAMED_MEDIA channel!" - - chandler.HandleChannel(kwargs["connection_sender"], - kwargs["connection_path"], - channel_type, - channel_path, - handle_type, - handle) - - -if __name__ == '__main__': - global bus - global stream_obj - global chandler - - bus = dbus.Bus() - bus_name = dbus.service.BusName(TEST_APP_NAME, bus=bus) - - stream_obj = bus.get_object("org.freedesktop.Telepathy.VoipEngine", - "/org/freedesktop/Telepathy/VoipEngine") - chandler = dbus.Interface(stream_obj, "org.freedesktop.Telepathy.ChannelHandler") - - bus.add_signal_receiver(connection_handle_new_channel, - "NewChannel", - CONN_INTERFACE, - sender_keyword="connection_sender", - path_keyword="connection_path") - - gobject.MainLoop().run() - diff --git a/test/python/test-stream-engine.py b/test/python/test-stream-engine.py deleted file mode 100644 index c19f24c..0000000 --- a/test/python/test-stream-engine.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python - -# test-stream-engine.py - test the functionaity of the stream engine -# -# Copyright (C) 2005 Collabora Limited -# Copyright (C) 2005 Nokia Corporation -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import dbus -import dbus.glib -import dbus.service - -assert(getattr(dbus, 'version', (0,0,0)) >= (0,51,0)) - -import gobject - -import telepathy.server -from telepathy import * - -TEST_APP_NAME = "org.freedesktop.Telepathy.TestVoipEngine" -TEST_CONNECTION_PATH = "/org/freedesktop/Telepathy/TestConnection" -TEST_CHANNEL_PATH = "/org/freedesktop/Telepathy/TestChannel" -TEST_SESSION_PATH = "/org/freedesktop/Telepathy/TestSession" -TEST_STREAM_PATH = "/org/freedesktop/Telepathy/TestStream" - -SELF_HANDLE = 1 -OTHER_HANDLE = 2 - -class DummyConnection(dbus.service.Object): - def __init__(self, bus_name, object_path): - dbus.service.Object.__init__(self, bus_name, object_path) - self._name = bus_name - - def get_channel_path(self): - return TEST_CHANNEL_PATH - - def remove_channel(self,channel): - pass - - def GetSelfHandle(self): - return SELF_HANDLE - -class TestMediaStreamHandler(telepathy.server.MediaStreamHandler): - def __init__(self, bus_name): - telepathy.server.MediaStreamHandler.__init__(self, bus_name, TEST_STREAM_PATH) - - def Ready(self): - print "TestMediaStreamHandler::Ready called, creating new stream" - -class TestMediaSessionHandler(telepathy.server.MediaSessionHandler): - def __init__(self, bus_name): - telepathy.server.MediaSessionHandler.__init__(self,bus_name, TEST_SESSION_PATH) - self._bus_name = bus_name - - def Ready(self): - print "TestMediaSessionHandler::Ready called, creating new stream" - self.NewMediaStreamHandler(TEST_STREAM_PATH, - MEDIA_STREAM_TYPE_AUDIO, - MEDIA_STREAM_DIRECTION_BIDIRECTIONAL) - print "Emitted %s signal" % MEDIA_SESSION_HANDLER - -class TestStreamedMediaChannel(telepathy.server.ChannelTypeStreamedMedia, telepathy.server.ChannelInterfaceGroup): - def __init__(self, conn, handle): - telepathy.server.ChannelTypeStreamedMedia.__init__(self, conn, handle) - telepathy.server.ChannelInterfaceGroup.__init__(self) - - def GetSessionHandlers(self): - print "GetSessionHandlers called" - return [(OTHER_HANDLE, TEST_SESSION_PATH, "rtp")] - - -if __name__ == '__main__': - bus = dbus.Bus() - bus_name = dbus.service.BusName(TEST_APP_NAME, bus=bus) - manager = DummyConnection(bus_name, TEST_CONNECTION_PATH) - channel = TestStreamedMediaChannel(manager, 0) - session = TestMediaSessionHandler(bus_name) - stream = TestMediaStreamHandler(bus_name) - - proxy_obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') - dbus_iface = dbus.Interface(proxy_obj, 'org.freedesktop.DBus') - - try: - dbus_iface.StartServiceByName("org.freedesktop.Telepathy.VoipEngine",0) - except: - print "failed to activate org.freedesktop.Telepathy.VoipEngine, continuing anyway..." - - stream_engine = bus.get_object("org.freedesktop.Telepathy.VoipEngine", - "/org/freedesktop/Telepathy/VoipEngine") - channel_handler = dbus.Interface(stream_engine, - "org.freedesktop.Telepathy.ChannelHandler") - channel_handler.HandleChannel(TEST_APP_NAME, TEST_CONNECTION_PATH, - CHANNEL_TYPE_STREAMED_MEDIA, TEST_CHANNEL_PATH, 0, 0) - - gobject.MainLoop().run() - - - diff --git a/test/run-with-tmp-session-bus.sh b/test/run-with-tmp-session-bus.sh deleted file mode 100644 index fdc99d8..0000000 --- a/test/run-with-tmp-session-bus.sh +++ /dev/null @@ -1,68 +0,0 @@ -#! /bin/bash - -SCRIPTNAME=$0 -WRAPPED_SCRIPT=$1 -shift - -function die() -{ - if ! test -z "$DBUS_SESSION_BUS_PID" ; then - echo "killing message bus "$DBUS_SESSION_BUS_PID >&2 - kill -9 $DBUS_SESSION_BUS_PID - fi - echo $SCRIPTNAME: $* >&2 - exit 1 -} - - -## convenient to be able to ctrl+C without leaking the message bus process -trap 'die "Received SIGINT"' SIGINT - -CONFIG_FILE=./run-with-tmp-session-bus.conf -SERVICE_DIR="$PWD/services" -EXEC_DIR=`echo $PWD/../ | sed -e 's/\//\\\\\\//g'` -ESCAPED_SERVICE_DIR=`echo $SERVICE_DIR | sed -e 's/\//\\\\\\//g'` -echo "escaped service dir is: $ESCAPED_SERVICE_DIR" >&2 - -## create a configuration file based on the standard session.conf -cat session.conf | \ - sed -e 's/<servicedir>.*$/<servicedir>'$ESCAPED_SERVICE_DIR'<\/servicedir>/g' | \ - sed -e 's/<include.*$//g' \ - > $CONFIG_FILE - -rm -rf services -mkdir -p services -for i in services.in/*; do - echo mangling $i - cat $i | sed -e "s/@EXEC_DIR@/$EXEC_DIR/g" > ${i/services.in\//services\//} -done - -echo "Created configuration file $CONFIG_FILE" >&2 - -export PATH=$PWD:$PATH - -unset DBUS_SESSION_BUS_ADDRESS -unset DBUS_SESSION_BUS_PID - -echo "Running dbus-launch --sh-syntax --config-file=$CONFIG_FILE" >&2 - -eval `dbus-launch --sh-syntax --config-file=$CONFIG_FILE` - -if test -z "$DBUS_SESSION_BUS_PID" ; then - die "Failed to launch message bus for introspection generation to run" -fi - -echo "Started bus pid $DBUS_SESSION_BUS_PID at $DBUS_SESSION_BUS_ADDRESS" >&2 - -# Execute wrapped script -echo "Running $WRAPPED_SCRIPT $@" >&2 -$WRAPPED_SCRIPT "$@" || die "script \"$WRAPPED_SCRIPT\" failed" - -kill -TERM $DBUS_SESSION_BUS_PID || die "Message bus vanished! should not have happened" && echo "Killed daemon $DBUS_SESSION_BUS_PID" >&2 - -sleep 2 - -## be sure it really died -kill -9 $DBUS_SESSION_BUS_PID > /dev/null 2>&1 || true - -exit 0 diff --git a/test/services.in/org.freedesktop.Telepathy.VoipEngine.service b/test/services.in/org.freedesktop.Telepathy.VoipEngine.service deleted file mode 100644 index cf3e322..0000000 --- a/test/services.in/org.freedesktop.Telepathy.VoipEngine.service +++ /dev/null @@ -1,3 +0,0 @@ -[D-BUS Service] -Name=org.freedesktop.Telepathy.VoipEngine -Exec=@EXEC_DIR@/src/telepathy-stream-engine diff --git a/test/session.conf b/test/session.conf deleted file mode 100644 index 4c0313b..0000000 --- a/test/session.conf +++ /dev/null @@ -1,32 +0,0 @@ -<!-- This configuration file controls the per-user-login-session message bus. - Add a session-local.conf and edit that rather than changing this - file directly. --> - -<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> -<busconfig> - <!-- Our well-known bus type, don't change this --> - <type>session</type> - - <listen>unix:tmpdir=/tmp</listen> - - <servicedir>@EXPANDED_DATADIR@/dbus-1/services</servicedir> - - <policy context="default"> - <!-- Allow everything to be sent --> - <allow send_destination="*"/> - <!-- Allow everything to be received --> - <allow eavesdrop="true"/> - <!-- Allow anyone to own anything --> - <allow own="*"/> - <!-- Allow any user to connect --> - <allow user="*"/> - </policy> - - <!-- This is included last so local configuration can override what's - in this standard file --> - <include ignore_missing="yes">session-local.conf</include> - - <include if_selinux_enabled="yes" selinux_root_relative="yes">contexts/dbus_contexts</include> - -</busconfig> diff --git a/tools/Makefile.am b/tools/Makefile.am deleted file mode 100644 index 4b76328..0000000 --- a/tools/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -EXTRA_DIST = \ - c-constants-generator.xsl \ - c-interfaces-generator.xsl \ - doc-generator.xsl \ - glib-client-gen.py \ - glib-client-marshaller-gen.py \ - glib-interfaces-generator.xsl \ - glib-interfaces-body-generator.xsl \ - glib-ginterface-gen.py \ - glib-gtypes-generator.py \ - glib-signals-marshal-gen.py \ - identity.xsl \ - libglibcodegen.py - -CLEANFILES = libglibcodegen.pyc libglibcodegen.pyo $(noinst_SCRIPTS) - -all: $(EXTRA_DIST) - -glib-client-marshaller-gen.py: libglibcodegen.py - touch $@ -glib-ginterface-gen.py: libglibcodegen.py - touch $@ -glib-gtypes-generator.py: libglibcodegen.py - touch $@ -glib-signals-marshal-gen.py: libglibcodegen.py - touch $@ - -TELEPATHY_GLIB_SRCDIR = $(top_srcdir)/../telepathy-glib -maintainer-update-from-telepathy-glib: - set -e && cd $(srcdir) && \ - for x in $(EXTRA_DIST); do \ - if test -f $(TELEPATHY_SPEC_SRCDIR)/tools/$$x; then \ - cp $(TELEPATHY_SPEC_SRCDIR)/tools/$$x $$x; \ - fi; \ - done diff --git a/tools/c-constants-generator.xsl b/tools/c-constants-generator.xsl deleted file mode 100644 index 18b2e49..0000000 --- a/tools/c-constants-generator.xsl +++ /dev/null @@ -1,299 +0,0 @@ -<!-- Stylesheet to extract C enumerations from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:output method="text" indent="no" encoding="ascii"/> - - <xsl:param name="mixed-case-prefix" select="''"/> - - <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> - <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/> - - <xsl:variable name="upper-case-prefix" select="concat(translate($mixed-case-prefix, $lower, $upper), '_')"/> - <xsl:variable name="lower-case-prefix" select="concat(translate($mixed-case-prefix, $upper, $lower), '_')"/> - - - <xsl:template match="tp:flags"> - <xsl:variable name="name"> - <xsl:choose> - <xsl:when test="@plural"> - <xsl:value-of select="@plural"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@singular"> - <xsl:value-of select="@singular"/> - </xsl:when> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:text>/** </xsl:text> - <xsl:text> * </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>: </xsl:text> - <xsl:apply-templates mode="flag-or-enumvalue-gtkdoc"> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text> * </xsl:text> - <xsl:if test="tp:docstring"> - <xsl:text> * <![CDATA[</xsl:text> - <xsl:value-of select="translate(string (tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - <xsl:text> * </xsl:text> - </xsl:if> - <xsl:text> * Bitfield/set of flags generated from the Telepathy specification. </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text>typedef enum { </xsl:text> - <xsl:apply-templates> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text>} </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>; </xsl:text> - <xsl:text> </xsl:text> - </xsl:template> - - <xsl:template match="text()" mode="flag-or-enumvalue-gtkdoc"/> - - <xsl:template match="tp:enumvalue" mode="flag-or-enumvalue-gtkdoc"> - <xsl:param name="value-prefix"/> - <xsl:text> * @</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $value-prefix, '_', @suffix), $lower, $upper)"/> - <xsl:text>: <![CDATA[</xsl:text> - <xsl:value-of select="translate(string(tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - </xsl:template> - - <xsl:template match="tp:flag" mode="flag-or-enumvalue-gtkdoc"> - <xsl:param name="value-prefix"/> - <xsl:text> * @</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $value-prefix, '_', @suffix), $lower, $upper)"/> - <xsl:text>: <![CDATA[</xsl:text> - <xsl:value-of select="translate(string(tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - </xsl:template> - - <xsl:template match="tp:enum"> - <xsl:variable name="name"> - <xsl:choose> - <xsl:when test="@singular"> - <xsl:value-of select="@singular"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@singular"> - <xsl:value-of select="@singular"/> - </xsl:when> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="name-plural"> - <xsl:choose> - <xsl:when test="@plural"> - <xsl:value-of select="@plural"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/><xsl:text>s</xsl:text> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:text>/** </xsl:text> - <xsl:text> * </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>: </xsl:text> - <xsl:apply-templates mode="flag-or-enumvalue-gtkdoc"> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text> * </xsl:text> - <xsl:if test="tp:docstring"> - <xsl:text> * <![CDATA[</xsl:text> - <xsl:value-of select="translate(string (tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - <xsl:text> * </xsl:text> - </xsl:if> - <xsl:text> * Bitfield/set of flags generated from the Telepathy specification. </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text>typedef enum { </xsl:text> - <xsl:apply-templates> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text>} </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>; </xsl:text> - <xsl:text> </xsl:text> - <xsl:text>/** </xsl:text> - <xsl:text> * NUM_</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $name-plural), $lower, $upper)"/> - <xsl:text>: </xsl:text> - <xsl:text> * </xsl:text> - <xsl:text> * 1 higher than the highest valid value of #</xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>. </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text>#define NUM_</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $name-plural), $lower, $upper)"/> - <xsl:text> (</xsl:text> - <xsl:value-of select="tp:enumvalue[position() = last()]/@value"/> - <xsl:text>+1) </xsl:text> - <xsl:text> </xsl:text> - </xsl:template> - - <xsl:template match="tp:flags/tp:flag"> - <xsl:param name="value-prefix"/> - <xsl:variable name="suffix"> - <xsl:choose> - <xsl:when test="@suffix"> - <xsl:value-of select="@suffix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="name" select="translate(concat($upper-case-prefix, $value-prefix, '_', $suffix), $lower, $upper)"/> - - <xsl:if test="@name and @suffix and @name != @suffix"> - <xsl:message terminate="yes"> - <xsl:text>Flag name </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> != suffix </xsl:text> - <xsl:value-of select="@suffix"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> = </xsl:text> - <xsl:value-of select="@value"/> - <xsl:text>, </xsl:text> - </xsl:template> - - <xsl:template match="tp:enum/tp:enumvalue"> - <xsl:param name="value-prefix"/> - <xsl:variable name="suffix"> - <xsl:choose> - <xsl:when test="@suffix"> - <xsl:value-of select="@suffix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="name" select="translate(concat($upper-case-prefix, $value-prefix, '_', $suffix), $lower, $upper)"/> - - <xsl:if test="@name and @suffix and @name != @suffix"> - <xsl:message terminate="yes"> - <xsl:text>Enumvalue name </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> != suffix </xsl:text> - <xsl:value-of select="@suffix"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="preceding-sibling::tp:enumvalue and number(preceding-sibling::tp:enumvalue[1]/@value) > number(@value)"> - <xsl:message terminate="yes"> - <xsl:text>Enum values must be in ascending numeric order, but </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> is less than the previous value</xsl:text> - </xsl:message> - </xsl:if> - - <xsl:text> </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> = </xsl:text> - <xsl:value-of select="@value"/> - <xsl:text>, </xsl:text> - </xsl:template> - - <xsl:template match="tp:flag"> - <xsl:message terminate="yes">tp:flag found outside tp:flags </xsl:message> - </xsl:template> - - <xsl:template match="tp:enumvalue"> - <xsl:message terminate="yes">tp:enumvalue found outside tp:enum </xsl:message> - </xsl:template> - - <xsl:template match="text()"/> - - <xsl:template match="/tp:spec"> - <xsl:if test="$mixed-case-prefix = ''"> - <xsl:message terminate="yes"> - <xsl:text>mixed-case-prefix param must be set </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:text>/* Generated from </xsl:text> - <xsl:value-of select="tp:title"/> - <xsl:if test="tp:version"> - <xsl:text>, version </xsl:text> - <xsl:value-of select="tp:version"/> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:text> </xsl:text> - <xsl:for-each select="tp:copyright"> - <xsl:value-of select="."/> - <xsl:text> </xsl:text> - </xsl:for-each> - <xsl:value-of select="tp:license"/> - <xsl:text> </xsl:text> - <xsl:value-of select="tp:docstring"/> - <xsl:text> </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text> </xsl:text> - <xsl:text>#ifdef __cplusplus </xsl:text> - <xsl:text>extern "C" { </xsl:text> - <xsl:text>#endif </xsl:text> - <xsl:text> </xsl:text> - <xsl:apply-templates/> - <xsl:text> </xsl:text> - <xsl:text>#ifdef __cplusplus </xsl:text> - <xsl:text>} </xsl:text> - <xsl:text>#endif </xsl:text> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/c-interfaces-generator.xsl b/tools/c-interfaces-generator.xsl deleted file mode 100644 index f965a70..0000000 --- a/tools/c-interfaces-generator.xsl +++ /dev/null @@ -1,84 +0,0 @@ -<!-- Stylesheet to extract C enumerations from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:param name="mixed-case-prefix" select="''"/> - - <xsl:variable name="PREFIX" - select="translate($mixed-case-prefix, $lower, $upper)"/> - <xsl:variable name="Prefix" select="$mixed-case-prefix"/> - <xsl:variable name="prefix" - select="translate($mixed-case-prefix, $upper, $lower)"/> - - <xsl:output method="text" indent="no" encoding="ascii"/> - - <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> - <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/> - - <xsl:template match="interface"> - <xsl:text>/** * </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text>: * * The interface name "</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>" */ #define </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text> \ "</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>" </xsl:text> - </xsl:template> - - <xsl:template match="text()"/> - - <xsl:template match="/tp:spec"> - <xsl:if test="$mixed-case-prefix = ''"> - <xsl:message terminate="yes"> - <xsl:text>mixed-case-prefix param must be set </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:text>/* Generated from: </xsl:text> - <xsl:value-of select="tp:title"/> - <xsl:if test="tp:version"> - <xsl:text> version </xsl:text> - <xsl:value-of select="tp:version"/> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:for-each select="tp:copyright"> - <xsl:value-of select="."/> - <xsl:text> </xsl:text> - </xsl:for-each> - <xsl:text> </xsl:text> - <xsl:value-of select="tp:license"/> - <xsl:value-of select="tp:docstring"/> - <xsl:text> */ </xsl:text> - <xsl:apply-templates/> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/doc-generator.xsl b/tools/doc-generator.xsl deleted file mode 100644 index 83b42dc..0000000 --- a/tools/doc-generator.xsl +++ /dev/null @@ -1,689 +0,0 @@ -<!-- Generate HTML documentation from the Telepathy specification. -The master copy of this stylesheet is in the Telepathy spec repository - -please make any changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - <!--Don't move the declaration of the HTML namespace up here - XMLNSs - don't work ideally in the presence of two things that want to use the - absence of a prefix, sadly. --> - - <xsl:template match="*" mode="identity"> - <xsl:copy> - <xsl:apply-templates mode="identity"/> - </xsl:copy> - </xsl:template> - - <xsl:template match="tp:docstring"> - <xsl:apply-templates select="node()" mode="identity"/> - </xsl:template> - - <xsl:template match="tp:errors"> - <h1 xmlns="http://www.w3.org/1999/xhtml">Errors</h1> - <xsl:apply-templates/> - </xsl:template> - - <xsl:template match="tp:generic-types"> - <h1 xmlns="http://www.w3.org/1999/xhtml">Generic types</h1> - <xsl:call-template name="do-types"/> - </xsl:template> - - <xsl:template name="do-types"> - <xsl:if test="tp:simple-type"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Simple types</h2> - <xsl:apply-templates select="tp:simple-type"/> - </xsl:if> - - <xsl:if test="tp:enum"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Enumerated types:</h2> - <xsl:apply-templates select="tp:enum"/> - </xsl:if> - - <xsl:if test="tp:flags"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Sets of flags:</h2> - <xsl:apply-templates select="tp:flags"/> - </xsl:if> - - <xsl:if test="tp:struct"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Structure types</h2> - <xsl:apply-templates select="tp:struct"/> - </xsl:if> - - <xsl:if test="tp:mapping"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Mapping types</h2> - <xsl:apply-templates select="tp:mapping"/> - </xsl:if> - - <xsl:if test="tp:external-type"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Types defined elsewhere</h2> - <dl><xsl:apply-templates select="tp:external-type"/></dl> - </xsl:if> - </xsl:template> - - <xsl:template match="tp:error"> - <h2 xmlns="http://www.w3.org/1999/xhtml"><a name="{concat(../@namespace, '.', translate(@name, ' ', ''))}"></a><xsl:value-of select="concat(../@namespace, '.', translate(@name, ' ', ''))"/></h2> - <xsl:apply-templates select="tp:docstring"/> - </xsl:template> - - <xsl:template match="/tp:spec/tp:copyright"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates/> - </div> - </xsl:template> - <xsl:template match="/tp:spec/tp:license"> - <div xmlns="http://www.w3.org/1999/xhtml" class="license"> - <xsl:apply-templates mode="identity"/> - </div> - </xsl:template> - - <xsl:template match="tp:copyright"/> - <xsl:template match="tp:license"/> - - <xsl:template match="interface"> - <h1 xmlns="http://www.w3.org/1999/xhtml"><a name="{@name}"></a><xsl:value-of select="@name"/></h1> - - <xsl:if test="@tp:causes-havoc"> - <p xmlns="http://www.w3.org/1999/xhtml" class="causes-havoc"> - This interface is <xsl:value-of select="@tp:causes-havoc"/> - and is likely to cause havoc to your API/ABI if bindings are generated. - Don't include it in libraries that care about compatibility. - </p> - </xsl:if> - - <xsl:if test="tp:requires"> - <p>Implementations of this interface must also implement:</p> - <ul xmlns="http://www.w3.org/1999/xhtml"> - <xsl:for-each select="tp:requires"> - <li><code><a href="#{@interface}"><xsl:value-of select="@interface"/></a></code></li> - </xsl:for-each> - </ul> - </xsl:if> - - <xsl:apply-templates select="tp:docstring" /> - - <xsl:choose> - <xsl:when test="method"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Methods:</h2> - <xsl:apply-templates select="method"/> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no methods.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:choose> - <xsl:when test="signal"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Signals:</h2> - <xsl:apply-templates select="signal"/> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no signals.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:choose> - <xsl:when test="tp:property"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Properties:</h2> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:property"/> - </dl> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no properties.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:call-template name="do-types"/> - - </xsl:template> - - <xsl:template match="tp:flags"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - </h3> - <xsl:apply-templates select="tp:docstring" /> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:for-each select="tp:flag"> - <dt xmlns="http://www.w3.org/1999/xhtml"><code><xsl:value-of select="concat($value-prefix, '_', @suffix)"/> = <xsl:value-of select="@value"/></code></dt> - <xsl:choose> - <xsl:when test="tp:docstring"> - <dd xmlns="http://www.w3.org/1999/xhtml"><xsl:apply-templates select="tp:docstring" /></dd> - </xsl:when> - <xsl:otherwise> - <dd xmlns="http://www.w3.org/1999/xhtml">(Undocumented)</dd> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - </dl> - </xsl:template> - - <xsl:template match="tp:enum"> - <h3 xmlns="http://www.w3.org/1999/xhtml"> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - </h3> - <xsl:apply-templates select="tp:docstring" /> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:for-each select="tp:enumvalue"> - <dt xmlns="http://www.w3.org/1999/xhtml"><code><xsl:value-of select="concat($value-prefix, '_', @suffix)"/> = <xsl:value-of select="@value"/></code></dt> - <xsl:choose> - <xsl:when test="tp:docstring"> - <dd xmlns="http://www.w3.org/1999/xhtml"><xsl:apply-templates select="tp:docstring" /></dd> - </xsl:when> - <xsl:otherwise> - <dd xmlns="http://www.w3.org/1999/xhtml">(Undocumented)</dd> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - </dl> - </xsl:template> - - <xsl:template match="tp:property"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <xsl:if test="@name"> - <code><xsl:value-of select="@name"/></code> - - </xsl:if> - <code><xsl:value-of select="@type"/></code> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring"/> - </dd> - </xsl:template> - - <xsl:template match="tp:mapping"> - <div xmlns="http://www.w3.org/1999/xhtml" class="struct"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - a{ - <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:text>: </xsl:text> - <xsl:value-of select="@name"/> - <xsl:if test="position() != last()"> → </xsl:if> - </xsl:for-each> - } - </h3> - <div class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - </div> - <div> - <h4>Members</h4> - <dl> - <xsl:apply-templates select="tp:member" mode="members-in-docstring"/> - </dl> - </div> - </div> - </xsl:template> - - <xsl:template match="tp:docstring" mode="in-index"/> - - <xsl:template match="tp:simple-type | tp:enum | tp:flags | tp:external-type" - mode="in-index"> - - <xsl:value-of select="@type"/> - </xsl:template> - - <xsl:template match="tp:simple-type"> - <div xmlns="http://www.w3.org/1999/xhtml" class="simple-type"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - <xsl:value-of select="@type"/> - </h3> - <div class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - </div> - </div> - </xsl:template> - - <xsl:template match="tp:external-type"> - <div xmlns="http://www.w3.org/1999/xhtml" class="external-type"> - <dt> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - <xsl:value-of select="@type"/> - </dt> - <dd>Defined by: <xsl:value-of select="@from"/></dd> - </div> - </xsl:template> - - <xsl:template match="tp:struct" mode="in-index"> - - ( <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> ) - </xsl:template> - - <xsl:template match="tp:mapping" mode="in-index"> - - a{ <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:if test="position() != last()"> → </xsl:if> - </xsl:for-each> } - </xsl:template> - - <xsl:template match="tp:struct"> - <div xmlns="http://www.w3.org/1999/xhtml" class="struct"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - ( - <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:text>: </xsl:text> - <xsl:value-of select="@name"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - ) - </h3> - <div class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - </div> - <xsl:choose> - <xsl:when test="string(@array-name) != ''"> - <p>In bindings that need a separate name, arrays of - <xsl:value-of select="@name"/> should be called - <xsl:value-of select="@array-name"/>.</p> - </xsl:when> - <xsl:otherwise> - <p>Arrays of <xsl:value-of select="@name"/> don't generally - make sense.</p> - </xsl:otherwise> - </xsl:choose> - <div> - <h4>Members</h4> - <dl> - <xsl:apply-templates select="tp:member" mode="members-in-docstring"/> - </dl> - </div> - </div> - </xsl:template> - - <xsl:template match="method"> - <div xmlns="http://www.w3.org/1999/xhtml" class="method"> - <h3 xmlns="http://www.w3.org/1999/xhtml"> - <a name="{concat(../@name, concat('.', @name))}"> - <xsl:value-of select="@name"/> - </a> ( - <xsl:for-each xmlns="" select="arg[@direction='in']"> - <xsl:value-of select="@type"/>: <xsl:value-of select="@name"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - ) → - <xsl:choose> - <xsl:when test="arg[@direction='out']"> - <xsl:for-each xmlns="" select="arg[@direction='out']"> - <xsl:value-of select="@type"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - </xsl:when> - <xsl:otherwise>nothing</xsl:otherwise> - </xsl:choose> - </h3> - <div xmlns="http://www.w3.org/1999/xhtml" class="docstring"> - <xsl:apply-templates select="tp:docstring" /> - </div> - - <xsl:if test="arg[@direction='in']"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Parameters</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="arg[@direction='in']" - mode="parameters-in-docstring"/> - </dl> - </div> - </xsl:if> - - <xsl:if test="arg[@direction='out']"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Returns</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="arg[@direction='out']" - mode="returns-in-docstring"/> - </dl> - </div> - </xsl:if> - - <xsl:if test="tp:possible-errors"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Possible errors</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:possible-errors/tp:error"/> - </dl> - </div> - </xsl:if> - - </div> - </xsl:template> - - <xsl:template name="parenthesized-tp-type"> - <xsl:if test="@tp:type"> - <xsl:variable name="tp-type" select="@tp:type"/> - <xsl:variable name="single-type"> - <xsl:choose> - <xsl:when test="contains($tp-type, '[]')"> - <xsl:value-of select="substring-before($tp-type, '[]')"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="$tp-type"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:choose> - <xsl:when test="//tp:simple-type[@name=$tp-type]" /> - <xsl:when test="//tp:simple-type[concat(@name, '[]')=$tp-type]" /> - <xsl:when test="//tp:struct[concat(@name, '[]')=$tp-type][string(@array-name) != '']" /> - <xsl:when test="//tp:struct[@name=$tp-type]" /> - <xsl:when test="//tp:enum[@name=$tp-type]" /> - <xsl:when test="//tp:enum[concat(@name, '[]')=$tp-type]" /> - <xsl:when test="//tp:flags[@name=$tp-type]" /> - <xsl:when test="//tp:flags[concat(@name, '[]')=$tp-type]" /> - <xsl:when test="//tp:mapping[@name=$tp-type]" /> - <xsl:when test="//tp:external-type[concat(@name, '[]')=$tp-type]" /> - <xsl:when test="//tp:external-type[@name=$tp-type]" /> - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: Unable to find type '</xsl:text> - <xsl:value-of select="$tp-type"/> - <xsl:text>' </xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - (<a href="#type-{$single-type}"><xsl:value-of select="$tp-type"/></a>) - </xsl:if> - </xsl:template> - - <xsl:template match="tp:member" mode="members-in-docstring"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <code><xsl:value-of select="@name"/></code> - - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:choose> - <xsl:when test="tp:docstring"> - <xsl:apply-templates select="tp:docstring" /> - </xsl:when> - <xsl:otherwise> - <em>(undocumented)</em> - </xsl:otherwise> - </xsl:choose> - </dd> - </xsl:template> - - <xsl:template match="arg" mode="parameters-in-docstring"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <code><xsl:value-of select="@name"/></code> - - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring" /> - </dd> - </xsl:template> - - <xsl:template match="arg" mode="returns-in-docstring"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <xsl:if test="@name"> - <code><xsl:value-of select="@name"/></code> - - </xsl:if> - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring"/> - </dd> - </xsl:template> - - <xsl:template match="tp:possible-errors/tp:error"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <code><xsl:value-of select="@name"/></code> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:variable name="name" select="@name"/> - <xsl:choose> - <xsl:when test="tp:docstring"> - <xsl:apply-templates select="tp:docstring"/> - </xsl:when> - <xsl:when test="//tp:errors/tp:error[concat(../@namespace, '.', translate(@name, ' ', ''))=$name]/tp:docstring"> - <xsl:apply-templates select="//tp:errors/tp:error[concat(../@namespace, '.', translate(@name, ' ', ''))=$name]/tp:docstring"/> <em xmlns="http://www.w3.org/1999/xhtml">(generic description)</em> - </xsl:when> - <xsl:otherwise> - (Undocumented.) - </xsl:otherwise> - </xsl:choose> - </dd> - </xsl:template> - - <xsl:template match="signal"> - <div xmlns="http://www.w3.org/1999/xhtml" class="signal"> - <h3 xmlns="http://www.w3.org/1999/xhtml"> - <a name="{concat(../@name, concat('.', @name))}"> - <xsl:value-of select="@name"/> - </a> ( - <xsl:for-each xmlns="" select="arg"> - <xsl:value-of select="@type"/>: <xsl:value-of select="@name"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - )</h3> - <div xmlns="http://www.w3.org/1999/xhtml" class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - </div> - - <xsl:if test="arg"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Parameters</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="arg" mode="parameters-in-docstring"/> - </dl> - </div> - </xsl:if> - </div> - </xsl:template> - - <xsl:output method="xml" indent="no" encoding="ascii" - omit-xml-declaration="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" /> - - <xsl:template match="/tp:spec"> - <html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title> - <xsl:value-of select="tp:title"/> - <xsl:if test="tp:version"> - <xsl:text> version </xsl:text> - <xsl:value-of select="tp:version"/> - </xsl:if> - </title> - <style type="text/css"> - - body { - font-family: sans-serif; - margin: 2em; - height: 100%; - font-size: 1.2em; - } - h1 { - padding-top: 5px; - padding-bottom: 5px; - font-size: 1.6em; - background: #dadae2; - } - h2 { - font-size: 1.3em; - } - h3 { - font-size: 1.2em; - } - a:link, a:visited, a:link:hover, a:visited:hover { - font-weight: bold; - } - .topbox { - padding-top: 10px; - padding-left: 10px; - border-bottom: black solid 1px; - padding-bottom: 10px; - background: #dadae2; - font-size: 2em; - font-weight: bold; - color: #5c5c5c; - } - .topnavbox { - padding-left: 10px; - padding-top: 5px; - padding-bottom: 5px; - background: #abacba; - border-bottom: black solid 1px; - font-size: 1.2em; - } - .topnavbox a{ - color: black; - font-weight: normal; - } - .sidebar { - float: left; - /* width:9em; - border-right:#abacba solid 1px; - border-left: #abacba solid 1px; - height:100%; */ - border: #abacba solid 1px; - padding-left: 10px; - margin-left: 10px; - padding-right: 10px; - margin-right: 10px; - color: #5d5d5d; - background: #dadae2; - } - .sidebar a { - text-decoration: none; - border-bottom: #e29625 dotted 1px; - color: #e29625; - font-weight: normal; - } - .sidebar h1 { - font-size: 1.2em; - color: black; - } - .sidebar ul { - padding-left: 25px; - padding-bottom: 10px; - border-bottom: #abacba solid 1px; - } - .sidebar li { - padding-top: 2px; - padding-bottom: 2px; - } - .sidebar h2 { - font-style:italic; - font-size: 0.81em; - padding-left: 5px; - padding-right: 5px; - font-weight: normal; - } - .date { - font-size: 0.6em; - float: right; - font-style: italic; - } - .method { - margin-left: 1em; - margin-right: 4em; - } - .signal { - margin-left: 1em; - margin-right: 4em; - } - - </style> - </head> - <body> - <h1 class="topbox"> - <xsl:value-of select="tp:title" /> - </h1> - <xsl:if test="tp:version"> - <h2>Version <xsl:apply-templates select="tp:version"/></h2> - </xsl:if> - <xsl:apply-templates select="tp:copyright"/> - <xsl:apply-templates select="tp:license"/> - <xsl:apply-templates select="tp:docstring"/> - - <h2>Interfaces</h2> - <ul> - <xsl:for-each select="node/interface"> - <li><code><a href="#{@name}"><xsl:value-of select="@name"/></a></code></li> - </xsl:for-each> - </ul> - - <xsl:apply-templates select="node"/> - <xsl:apply-templates select="tp:generic-types"/> - <xsl:apply-templates select="tp:errors"/> - - <h1>Index</h1> - <h2>Index of interfaces</h2> - <ul> - <xsl:for-each select="node/interface"> - <li><code><a href="#{@name}"><xsl:value-of select="@name"/></a></code></li> - </xsl:for-each> - </ul> - <h2>Index of types</h2> - <ul> - <xsl:for-each select="//tp:simple-type | //tp:enum | //tp:flags | //tp:mapping | //tp:struct | //tp:external-type"> - <xsl:sort select="@name"/> - <li> - <code> - <a href="#type-{@name}"> - <xsl:value-of select="@name"/> - </a> - </code> - <xsl:apply-templates mode="in-index" select="."/> - </li> - </xsl:for-each> - </ul> - </body> - </html> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et: --> diff --git a/tools/glib-client-gen.py b/tools/glib-client-gen.py deleted file mode 100644 index 81d3aed..0000000 --- a/tools/glib-client-gen.py +++ /dev/null @@ -1,1131 +0,0 @@ -#!/usr/bin/python - -# glib-client-gen.py: "I Can't Believe It's Not dbus-binding-tool" -# -# Generate GLib client wrappers from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006-2008 Collabora Ltd. <http://www.collabora.co.uk/> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os.path -import xml.dom.minidom -from getopt import gnu_getopt - -from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \ - camelcase_to_lower, get_docstring, xml_escape - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, dom, prefix, basename, opts): - self.dom = dom - self.__header = [] - self.__body = [] - - self.prefix_lc = prefix.lower() - self.prefix_uc = prefix.upper() - self.prefix_mc = prefix.replace('_', '') - self.basename = basename - self.group = opts.get('--group', None) - self.iface_quark_prefix = opts.get('--iface-quark-prefix', None) - self.proxy_cls = opts.get('--subclass', 'TpProxy') + ' *' - self.proxy_arg = opts.get('--subclass', 'void') + ' *' - self.proxy_assert = opts.get('--subclass-assert', 'TP_IS_PROXY') - self.proxy_doc = ('A #%s or subclass' - % opts.get('--subclass', 'TpProxy')) - if self.proxy_arg == 'void *': - self.proxy_arg = 'gpointer ' - - def h(self, s): - self.__header.append(s) - - def b(self, s): - self.__body.append(s) - - def get_iface_quark(self): - assert self.iface_dbus is not None - assert self.iface_uc is not None - if self.iface_quark_prefix is None: - return 'g_quark_from_static_string (\"%s\")' % self.iface_dbus - else: - return '%s_%s' % (self.iface_quark_prefix, self.iface_uc) - - def do_signal(self, iface, signal): - iface_lc = iface.lower() - - member = signal.getAttribute('name') - member_lc = camelcase_to_lower(member) - member_uc = member_lc.upper() - - arg_count = 0 - args = [] - out_args = [] - - for arg in signal.getElementsByTagName('arg'): - name = arg.getAttribute('name') - type = arg.getAttribute('type') - tp_type = arg.getAttribute('tp:type') - - if not name: - name = 'arg%u' % arg_count - arg_count += 1 - else: - name = 'arg_%s' % name - - info = type_to_gtype(type) - args.append((name, info, tp_type, arg)) - - callback_name = ('%s_%s_signal_callback_%s' - % (self.prefix_lc, iface_lc, member_lc)) - collect_name = ('_%s_%s_collect_args_of_%s' - % (self.prefix_lc, iface_lc, member_lc)) - invoke_name = ('_%s_%s_invoke_callback_for_%s' - % (self.prefix_lc, iface_lc, member_lc)) - - # Example: - # - # typedef void (*tp_cli_connection_signal_callback_new_channel) - # (TpConnection *proxy, const gchar *arg_object_path, - # const gchar *arg_channel_type, guint arg_handle_type, - # guint arg_handle, gboolean arg_suppress_handler, - # gpointer user_data, GObject *weak_object); - - self.b('/**') - self.b(' * %s:' % callback_name) - self.b(' * @proxy: The proxy on which %s_%s_connect_to_%s ()' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * was called') - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: %s' % (name, - xml_escape(get_docstring(elt) or '(Undocumented)'))) - - self.b(' * @user_data: User-supplied data') - self.b(' * @weak_object: User-supplied weakly referenced object') - self.b(' *') - self.b(' * Represents the signature of a callback for the signal %s.' - % member) - self.b(' */') - self.h('typedef void (*%s) (%sproxy,' - % (callback_name, self.proxy_cls)) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' gpointer user_data, GObject *weak_object);') - - if args: - self.b('static void') - self.b('%s (DBusGProxy *proxy G_GNUC_UNUSED,' % collect_name) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s%s%s,' % (const, ctype, name)) - - self.b(' TpProxySignalConnection *sc)') - self.b('{') - self.b(' GValueArray *args = g_value_array_new (%d);' % len(args)) - self.b(' GValue blank = { 0 };') - self.b(' guint i;') - self.b('') - self.b(' g_value_init (&blank, G_TYPE_INT);') - self.b('') - self.b(' for (i = 0; i < %d; i++)' % len(args)) - self.b(' g_value_array_append (args, &blank);') - self.b('') - - for i, arg in enumerate(args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' g_value_unset (args->values + %d);' % i) - self.b(' g_value_init (args->values + %d, %s);' % (i, gtype)) - - if gtype == 'G_TYPE_STRING': - self.b(' g_value_set_string (args->values + %d, %s);' - % (i, name)) - elif marshaller == 'BOXED': - self.b(' g_value_set_boxed (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_set_uchar (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_set_boolean (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_set_double (args->values + %d, %s);' - % (i, name)) - else: - assert False, ("Don't know how to put %s in a GValue" - % gtype) - self.b('') - - self.b(' tp_proxy_signal_connection_v0_take_results (sc, args);') - self.b('}') - - self.b('static void') - self.b('%s (TpProxy *tpproxy,' % invoke_name) - self.b(' GError *error G_GNUC_UNUSED,') - self.b(' GValueArray *args,') - self.b(' GCallback generic_callback,') - self.b(' gpointer user_data,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' %s callback =' % callback_name) - self.b(' (%s) generic_callback;' % callback_name) - self.b('') - self.b(' if (callback != NULL)') - self.b(' callback (g_object_ref (tpproxy),') - - # FIXME: factor out into a function - for i, arg in enumerate(args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED': - self.b(' g_value_get_boxed (args->values + %d),' % i) - elif gtype == 'G_TYPE_STRING': - self.b(' g_value_get_string (args->values + %d),' % i) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_get_uchar (args->values + %d),' % i) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_get_boolean (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_get_uint (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_get_int (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_get_uint64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_get_int64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_get_double (args->values + %d),' % i) - else: - assert False, "Don't know how to get %s from a GValue" % gtype - - self.b(' user_data,') - self.b(' weak_object);') - self.b('') - - if len(args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - self.b('') - - self.b(' g_object_unref (tpproxy);') - self.b('}') - - # Example: - # - # TpProxySignalConnection * - # tp_cli_connection_connect_to_new_channel - # (TpConnection *proxy, - # tp_cli_connection_signal_callback_new_channel callback, - # gpointer user_data, - # GDestroyNotify destroy); - # - # destroy is invoked when the signal becomes disconnected. This - # is either because the signal has been disconnected explicitly - # by the user, because the TpProxy has become invalid and - # emitted the 'invalidated' signal, or because the weakly referenced - # object has gone away. - - self.b('/**') - self.b(' * %s_%s_connect_to_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: %s' % self.proxy_doc) - self.b(' * @callback: Callback to be called when the signal is') - self.b(' * received') - self.b(' * @user_data: User-supplied data for the callback') - self.b(' * @destroy: Destructor for the user-supplied data, which') - self.b(' * will be called when this signal is disconnected, or') - self.b(' * before this function returns %NULL') - self.b(' * @weak_object: A #GObject which will be weakly referenced; ') - self.b(' * if it is destroyed, this callback will automatically be') - self.b(' * disconnected') - self.b(' * @error: If not %NULL, used to raise an error if %NULL is') - self.b(' * returned') - self.b(' *') - self.b(' * Connect a handler to the signal %s.' % member) - self.b(' *') - self.b(' * %s' % xml_escape(get_docstring(signal) or '(Undocumented)')) - self.b(' *') - self.b(' * Returns: a #TpProxySignalConnection containing all of the') - self.b(' * above, which can be used to disconnect the signal; or') - self.b(' * %NULL if the proxy does not have the desired interface') - self.b(' * or has become invalid.') - self.b(' */') - self.h('TpProxySignalConnection *%s_%s_connect_to_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object,') - self.h(' GError **error);') - - self.b('TpProxySignalConnection *') - self.b('%s_%s_connect_to_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.b(' %s callback,' % callback_name) - self.b(' gpointer user_data,') - self.b(' GDestroyNotify destroy,') - self.b(' GObject *weak_object,') - self.b(' GError **error)') - self.b('{') - self.b(' GType expected_types[%d] = {' % (len(args) + 1)) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s,' % gtype) - - self.b(' G_TYPE_INVALID };') - self.b('') - self.b(' g_return_val_if_fail (%s (proxy), NULL);' - % self.proxy_assert) - self.b(' g_return_val_if_fail (callback != NULL, NULL);') - self.b('') - self.b(' return tp_proxy_signal_connection_v0_new ((TpProxy *) proxy,') - self.b(' %s, \"%s\",' % (self.get_iface_quark(), member)) - self.b(' expected_types,') - - if args: - self.b(' G_CALLBACK (%s),' % collect_name) - else: - self.b(' NULL, /* no args => no collector function */') - - self.b(' %s,' % invoke_name) - self.b(' G_CALLBACK (callback), user_data, destroy,') - self.b(' weak_object, error);') - self.b('}') - self.b('') - - self.h('') - - def do_method(self, iface, method): - iface_lc = iface.lower() - - member = method.getAttribute('name') - member_lc = camelcase_to_lower(member) - member_uc = member_lc.upper() - - in_count = 0 - ret_count = 0 - in_args = [] - out_args = [] - - for arg in method.getElementsByTagName('arg'): - name = arg.getAttribute('name') - direction = arg.getAttribute('direction') - type = arg.getAttribute('type') - tp_type = arg.getAttribute('tp:type') - - if direction != 'out': - if not name: - name = 'in%u' % in_count - in_count += 1 - else: - name = 'in_%s' % name - else: - if not name: - name = 'out%u' % ret_count - ret_count += 1 - else: - name = 'out_%s' % name - - info = type_to_gtype(type) - if direction != 'out': - in_args.append((name, info, tp_type, arg)) - else: - out_args.append((name, info, tp_type, arg)) - - # Async reply callback type - - # Example: - # void (*tp_cli_properties_interface_callback_for_get_properties) - # (TpProxy *proxy, - # const GPtrArray *out0, - # const GError *error, - # gpointer user_data, - # GObject *weak_object); - - self.b('/**') - self.b(' * %s_%s_callback_for_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: the proxy on which the call was made') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to return an \'out\' argument if @error is ' - '%%NULL: %s' - % (name, xml_escape(get_docstring(elt) or '(Undocumented)'))) - - self.b(' * @error: %NULL on success, or an error on failure') - self.b(' * @user_data: user-supplied data') - self.b(' * @weak_object: user-supplied object') - self.b(' *') - self.b(' * Signature of the callback called when a %s method call' - % member) - self.b(' * succeeds or fails.') - self.b(' */') - - callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc, - member_lc) - - self.h('typedef void (*%s) (%sproxy,' - % (callback_name, self.proxy_cls)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' const GError *error, gpointer user_data,') - self.h(' GObject *weak_object);') - self.h('') - - # Async callback implementation - - invoke_callback = '_%s_%s_invoke_callback_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - collect_callback = '_%s_%s_collect_callback_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - # The callback called by dbus-glib; this ends the call and collects - # the results into a GValueArray. - self.b('static void') - self.b('%s (DBusGProxy *proxy,' % collect_callback) - self.b(' DBusGProxyCall *call,') - self.b(' gpointer user_data)') - self.b('{') - self.b(' GError *error = NULL;') - - if len(out_args) > 0: - self.b(' GValueArray *args;') - self.b(' GValue blank = { 0 };') - self.b(' guint i;') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - # "We handle variants specially; the caller is expected to - # have already allocated storage for them". Thanks, - # dbus-glib... - if gtype == 'G_TYPE_VALUE': - self.b(' GValue *%s = g_new0 (GValue, 1);' % name) - else: - self.b(' %s%s;' % (ctype, name)) - - self.b('') - self.b(' dbus_g_proxy_end_call (proxy, call, &error,') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if gtype == 'G_TYPE_VALUE': - self.b(' %s, %s,' % (gtype, name)) - else: - self.b(' %s, &%s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID);') - - if len(out_args) == 0: - self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,' - 'NULL);') - else: - self.b('') - self.b(' if (error != NULL)') - self.b(' {') - self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,') - self.b(' NULL);') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - if gtype == 'G_TYPE_VALUE': - self.b(' g_free (%s);' % name) - - self.b(' return;') - self.b(' }') - self.b('') - self.b(' args = g_value_array_new (%d);' % len(out_args)) - self.b(' g_value_init (&blank, G_TYPE_INT);') - self.b('') - self.b(' for (i = 0; i < %d; i++)' % len(out_args)) - self.b(' g_value_array_append (args, &blank);') - - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b('') - self.b(' g_value_unset (args->values + %d);' % i) - self.b(' g_value_init (args->values + %d, %s);' % (i, gtype)) - - if gtype == 'G_TYPE_STRING': - self.b(' g_value_take_string (args->values + %d, %s);' - % (i, name)) - elif marshaller == 'BOXED': - self.b(' g_value_take_boxed (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_set_uchar (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_set_boolean (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_set_double (args->values + %d, %s);' - % (i, name)) - else: - assert False, ("Don't know how to put %s in a GValue" - % gtype) - - self.b(' tp_proxy_pending_call_v0_take_results (user_data, ' - 'NULL, args);') - - self.b('}') - - self.b('static void') - self.b('%s (TpProxy *self,' % invoke_callback) - self.b(' GError *error,') - self.b(' GValueArray *args,') - self.b(' GCallback generic_callback,') - self.b(' gpointer user_data,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' %s callback = (%s) generic_callback;' - % (callback_name, callback_name)) - self.b('') - self.b(' if (error != NULL)') - self.b(' {') - self.b(' callback ((%s) self,' % self.proxy_cls) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED' or pointer: - self.b(' NULL,') - elif gtype == 'G_TYPE_DOUBLE': - self.b(' 0.0,') - else: - self.b(' 0,') - - self.b(' error, user_data, weak_object);') - self.b(' g_error_free (error);') - self.b(' return;') - self.b(' }') - - self.b(' callback ((%s) self,' % self.proxy_cls) - - # FIXME: factor out into a function - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED': - self.b(' g_value_get_boxed (args->values + %d),' % i) - elif gtype == 'G_TYPE_STRING': - self.b(' g_value_get_string (args->values + %d),' % i) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_get_uchar (args->values + %d),' % i) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_get_boolean (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_get_uint (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_get_int (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_get_uint64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_get_int64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_get_double (args->values + %d),' % i) - else: - assert False, "Don't know how to get %s from a GValue" % gtype - - self.b(' error, user_data, weak_object);') - self.b('') - - if len(out_args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - - self.b('}') - self.b('') - - # Async stub - - # Example: - # TpProxyPendingCall * - # tp_cli_properties_interface_call_get_properties - # (gpointer proxy, - # gint timeout_ms, - # const GArray *in_properties, - # tp_cli_properties_interface_callback_for_get_properties callback, - # gpointer user_data, - # GDestroyNotify *destructor); - - self.h('TpProxyPendingCall *%s_%s_call_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.h(' gint timeout_ms,') - - self.b('/**') - self.b(' * %s_%s_call_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: the #TpProxy') - self.b(' * @timeout_ms: the timeout in milliseconds, or -1 to use the') - self.b(' * default') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to pass an \'in\' argument: %s' - % (name, xml_escape(get_docstring(elt) or '(Undocumented)'))) - - self.b(' * @callback: called when the method call succeeds or fails') - self.b(' * @user_data: user-supplied data passed to the callback') - self.b(' * @destroy: called with the user_data as argument, after the') - self.b(' * call has succeeded, failed or been cancelled') - self.b(' * @weak_object: A #GObject which will be weakly referenced; ') - self.b(' * if it is destroyed, this callback will automatically be') - self.b(' * disconnected') - self.b(' *') - self.b(' * Start a %s method call.' % member) - self.b(' *') - self.b(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)')) - self.b(' *') - self.b(' * Returns: a #TpProxyPendingCall representing the call in') - self.b(' * progress. It is borrowed from the object, and will become') - self.b(' * invalid when the callback is called, the call is') - self.b(' * cancelled or the #TpProxy becomes invalid.') - self.b(' */') - self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.b(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - self.b(' %s%s%s,' % (const, ctype, name)) - - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object);') - self.h('') - - self.b(' %s callback,' % callback_name) - self.b(' gpointer user_data,') - self.b(' GDestroyNotify destroy,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' GError *error = NULL;') - self.b(' GQuark interface = %s;' % self.get_iface_quark()) - self.b(' DBusGProxy *iface;') - self.b('') - self.b(' g_return_val_if_fail (%s (proxy), NULL);' - % self.proxy_assert) - self.b('') - self.b(' iface = tp_proxy_borrow_interface_by_id (') - self.b(' (TpProxy *) proxy,') - self.b(' interface, &error);') - self.b('') - self.b(' if (iface == NULL)') - self.b(' {') - self.b(' if (callback != NULL)') - self.b(' callback (proxy,') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if pointer: - self.b(' NULL,') - else: - self.b(' 0,') - - self.b(' error, user_data, weak_object);') - self.b(' g_error_free (error);') - self.b(' return NULL;') - self.b(' }') - self.b('') - self.b(' if (callback == NULL)') - self.b(' {') - self.b(' dbus_g_proxy_call_no_reply (iface, "%s",' % member) - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID);') - self.b(' return NULL;') - self.b(' }') - self.b(' else') - self.b(' {') - self.b(' TpProxyPendingCall *data;') - self.b('') - self.b(' data = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,') - self.b(' interface, "%s", iface,' % member) - self.b(' %s,' % invoke_callback) - self.b(' G_CALLBACK (callback), user_data, destroy,') - self.b(' weak_object, FALSE);') - self.b(' tp_proxy_pending_call_v0_take_pending_call (data,') - self.b(' dbus_g_proxy_begin_call_with_timeout (iface,') - self.b(' "%s",' % member) - self.b(' %s,' % collect_callback) - self.b(' data,') - self.b(' tp_proxy_pending_call_v0_completed,') - self.b(' timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID));') - self.b('') - self.b(' return data;') - self.b(' }') - self.b('}') - self.b('') - - # Reentrant blocking calls - # Example: - # gboolean tp_cli_properties_interface_run_get_properties - # (gpointer proxy, - # gint timeout_ms, - # const GArray *in_properties, - # GPtrArray **out0, - # GError **error, - # GMainLoop **loop); - - self.b('typedef struct {') - self.b(' GMainLoop *loop;') - self.b(' GError **error;') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s*%s;' % (ctype, name)) - - self.b(' gboolean success:1;') - self.b(' gboolean completed:1;') - self.b('} _%s_%s_run_state_%s;' - % (self.prefix_lc, iface_lc, member_lc)) - - reentrant_invoke = '_%s_%s_finish_running_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - self.b('static void') - self.b('%s (TpProxy *self G_GNUC_UNUSED,' % reentrant_invoke) - self.b(' GError *error,') - self.b(' GValueArray *args,') - self.b(' GCallback unused G_GNUC_UNUSED,') - self.b(' gpointer user_data G_GNUC_UNUSED,') - self.b(' GObject *unused2 G_GNUC_UNUSED)') - self.b('{') - self.b(' _%s_%s_run_state_%s *state = user_data;' - % (self.prefix_lc, iface_lc, member_lc)) - self.b('') - self.b(' state->success = (error == NULL);') - self.b(' state->completed = TRUE;') - self.b(' g_main_loop_quit (state->loop);') - self.b('') - self.b(' if (error != NULL)') - self.b(' {') - self.b(' if (state->error != NULL)') - self.b(' *state->error = error;') - self.b(' else') - self.b(' g_error_free (error);') - self.b('') - self.b(' return;') - self.b(' }') - self.b('') - - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' if (state->%s != NULL)' % name) - if marshaller == 'BOXED': - self.b(' *state->%s = g_value_dup_boxed (' - 'args->values + %d);' % (name, i)) - elif marshaller == 'STRING': - self.b(' *state->%s = g_value_dup_string ' - '(args->values + %d);' % (name, i)) - elif marshaller in ('UCHAR', 'BOOLEAN', 'INT', 'UINT', - 'INT64', 'UINT64', 'DOUBLE'): - self.b(' *state->%s = g_value_get_%s (args->values + %d);' - % (name, marshaller.lower(), i)) - else: - assert False, "Don't know how to copy %s" % gtype - - self.b('') - - if len(out_args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - - self.b('}') - self.b('') - - self.h('gboolean %s_%s_run_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.h(' gint timeout_ms,') - - self.b('/**') - self.b(' * %s_%s_run_%s:' % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: %s' % self.proxy_doc) - self.b(' * @timeout_ms: Timeout in milliseconds, or -1 for default') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to pass an \'in\' argument: %s' - % (name, xml_escape(get_docstring(elt) or '(Undocumented)'))) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to return an \'out\' argument if %%TRUE is ' - 'returned: %s' - % (name, xml_escape(get_docstring(elt) or '(Undocumented)'))) - - self.b(' * @error: If not %NULL, used to return errors if %FALSE ') - self.b(' * is returned') - self.b(' * @loop: If not %NULL, set before re-entering ') - self.b(' * the main loop, to point to a #GMainLoop ') - self.b(' * which can be used to cancel this call with ') - self.b(' * g_main_loop_quit(), causing a return of ') - self.b(' * %FALSE with @error set to %TP_DBUS_ERROR_CANCELLED') - self.b(' *') - self.b(' * Call the method %s and run the main loop' % member) - self.b(' * until it returns. Before calling this method, you must') - self.b(' * add a reference to any borrowed objects you need to keep,') - self.b(' * and generally ensure that everything is in a consistent') - self.b(' * state.') - self.b(' *') - self.b(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)')) - self.b(' *') - self.b(' * Returns: TRUE on success, FALSE and sets @error on error') - self.b(' */') - self.b('gboolean\n%s_%s_run_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.b(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - self.b(' %s%s%s,' % (const, ctype, name)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.h(' %s*%s,' % (ctype, name)) - self.b(' %s*%s,' % (ctype, name)) - - self.h(' GError **error,') - self.h(' GMainLoop **loop);') - self.h('') - - self.b(' GError **error,') - self.b(' GMainLoop **loop)') - self.b('{') - self.b(' DBusGProxy *iface;') - self.b(' GQuark interface = %s;' % self.get_iface_quark()) - self.b(' TpProxyPendingCall *pc;') - self.b(' _%s_%s_run_state_%s state = {' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' NULL /* loop */, error,') - - for arg in out_args: - name, info, tp_type, elt = arg - - self.b(' %s,' % name) - - self.b(' FALSE /* completed */, FALSE /* success */ };') - self.b('') - self.b(' g_return_val_if_fail (%s (proxy), FALSE);' - % self.proxy_assert) - self.b('') - self.b(' iface = tp_proxy_borrow_interface_by_id') - self.b(' ((TpProxy *) proxy, interface, error);') - self.b('') - self.b(' if (iface == NULL)') - self.b(' return FALSE;') - self.b('') - self.b(' state.loop = g_main_loop_new (NULL, FALSE);') - self.b('') - self.b(' pc = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,') - self.b(' interface, "%s", iface,' % member) - self.b(' %s,' % reentrant_invoke) - self.b(' NULL, &state, NULL, NULL, TRUE);') - self.b('') - self.b(' if (loop != NULL)') - self.b(' *loop = state.loop;') - self.b('') - self.b(' tp_proxy_pending_call_v0_take_pending_call (pc,') - self.b(' dbus_g_proxy_begin_call_with_timeout (iface,') - self.b(' "%s",' % member) - self.b(' %s,' % collect_callback) - self.b(' pc,') - self.b(' tp_proxy_pending_call_v0_completed,') - self.b(' timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID));') - self.b('') - self.b(' if (!state.completed)') - self.b(' g_main_loop_run (state.loop);') - self.b('') - self.b(' if (!state.completed)') - self.b(' tp_proxy_pending_call_cancel (pc);') - self.b('') - self.b(' if (loop != NULL)') - self.b(' *loop = NULL;') - self.b('') - self.b(' g_main_loop_unref (state.loop);') - self.b('') - self.b(' return state.success;') - self.b('}') - self.b('') - - # leave a gap for the end of the method - self.b('') - self.h('') - - def do_signal_add(self, signal): - marshaller_items = [] - gtypes = [] - - for i in signal.getElementsByTagName('arg'): - name = i.getAttribute('name') - type = i.getAttribute('type') - info = type_to_gtype(type) - # type, GType, STRING, is a pointer - gtypes.append(info[1]) - - self.b(' dbus_g_proxy_add_signal (proxy, "%s",' - % signal.getAttribute('name')) - for gtype in gtypes: - self.b(' %s,' % gtype) - self.b(' G_TYPE_INVALID);') - - def do_interface(self, node): - ifaces = node.getElementsByTagName('interface') - assert len(ifaces) == 1 - iface = ifaces[0] - name = node.getAttribute('name').replace('/', '') - - self.iface = name - self.iface_lc = name.lower() - self.iface_uc = name.upper() - self.iface_mc = name.replace('_', '') - self.iface_dbus = iface.getAttribute('name') - - signals = node.getElementsByTagName('signal') - methods = node.getElementsByTagName('method') - - if signals: - self.b('static inline void') - self.b('%s_add_signals_for_%s (DBusGProxy *proxy)' - % (self.prefix_lc, name.lower())) - self.b('{') - - for signal in signals: - self.do_signal_add(signal) - - self.b('}') - self.b('') - self.b('') - - for signal in signals: - self.do_signal(name, signal) - - for method in methods: - self.do_method(name, method) - - self.iface_dbus = None - - def __call__(self): - - self.h('G_BEGIN_DECLS') - self.h('') - - self.b('/* We don\'t want gtkdoc scanning this file, it\'ll get') - self.b(' * confused by seeing function definitions, so mark it as: */') - self.b('/*<private_header>*/') - self.b('') - - nodes = self.dom.getElementsByTagName('node') - nodes.sort(cmp_by_name) - - for node in nodes: - self.do_interface(node) - - if self.group is not None: - - self.b('/*') - self.b(' * %s_%s_add_signals:' % (self.prefix_lc, self.group)) - self.b(' * @self: the #TpProxy') - self.b(' * @quark: a quark whose string value is the interface') - self.b(' * name whose signals should be added') - self.b(' * @proxy: the D-Bus proxy to which to add the signals') - self.b(' * @unused: not used for anything') - self.b(' *') - self.b(' * Tell dbus-glib that @proxy has the signatures of all') - self.b(' * signals on the given interface, if it\'s one we') - self.b(' * support.') - self.b(' *') - self.b(' * This function should be used as a signal handler for') - self.b(' * #TpProxy::interface-added.') - self.b(' */') - self.b('static void') - self.b('%s_%s_add_signals (TpProxy *self G_GNUC_UNUSED,' - % (self.prefix_lc, self.group)) - self.b(' guint quark,') - self.b(' DBusGProxy *proxy,') - self.b(' gpointer unused G_GNUC_UNUSED)') - - self.b('{') - - for node in nodes: - iface = node.getElementsByTagName('interface')[0] - self.iface_dbus = iface.getAttribute('name') - signals = node.getElementsByTagName('signal') - if not signals: - continue - name = node.getAttribute('name').replace('/', '').lower() - self.iface_uc = name.upper() - self.b(' if (quark == %s)' % self.get_iface_quark()) - self.b(' %s_add_signals_for_%s (proxy);' - % (self.prefix_lc, name)) - - self.b('}') - self.b('') - - self.h('G_END_DECLS') - self.h('') - - open(self.basename + '.h', 'w').write('\n'.join(self.__header)) - open(self.basename + '-body.h', 'w').write('\n'.join(self.__body)) - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - - -if __name__ == '__main__': - options, argv = gnu_getopt(sys.argv[1:], '', - ['group=', 'subclass=', 'subclass-assert=', - 'iface-quark-prefix=']) - - opts = {} - - for option, value in options: - opts[option] = value - - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom, argv[1], argv[2], opts)() diff --git a/tools/glib-client-marshaller-gen.py b/tools/glib-client-marshaller-gen.py deleted file mode 100644 index 5444725..0000000 --- a/tools/glib-client-marshaller-gen.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/python - -import sys -import xml.dom.minidom -from string import ascii_letters, digits - - -from libglibcodegen import signal_to_marshal_name - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, dom, prefix): - self.dom = dom - self.marshallers = {} - self.prefix = prefix - - def do_signal(self, signal): - marshaller = signal_to_marshal_name(signal, self.prefix) - - assert '__' in marshaller - rhs = marshaller.split('__', 1)[1].split('_') - - self.marshallers[marshaller] = rhs - - def __call__(self): - signals = self.dom.getElementsByTagName('signal') - - for signal in signals: - self.do_signal(signal) - - print 'void' - print '%s_register_dbus_glib_marshallers (void)' % self.prefix - print '{' - - all = self.marshallers.keys() - all.sort() - for marshaller in all: - rhs = self.marshallers[marshaller] - - print ' dbus_g_object_register_marshaller (%s,' % marshaller - print ' G_TYPE_NONE, /* return */' - for type in rhs: - print ' G_TYPE_%s,' % type.replace('VOID', 'NONE') - print ' G_TYPE_INVALID);' - - print '}' - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - -if __name__ == '__main__': - argv = sys.argv[1:] - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom, argv[1])() diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py deleted file mode 100644 index 36f3242..0000000 --- a/tools/glib-ginterface-gen.py +++ /dev/null @@ -1,711 +0,0 @@ -#!/usr/bin/python - -# glib-ginterface-gen.py: service-side interface generator -# -# Generate dbus-glib 0.x service GInterfaces from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006, 2007 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os.path -import xml.dom.minidom - -from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \ - camelcase_to_lower, NS_TP, dbus_gutils_wincaps_to_uscore, \ - signal_to_marshal_name, method_to_glue_marshal_name - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, dom, prefix, basename, signal_marshal_prefix, - headers, end_headers, not_implemented_func, - allow_havoc): - self.dom = dom - self.__header = [] - self.__body = [] - - assert prefix.endswith('_') - assert not signal_marshal_prefix.endswith('_') - - # The main_prefix, sub_prefix thing is to get: - # FOO_ -> (FOO_, _) - # FOO_SVC_ -> (FOO_, _SVC_) - # but - # FOO_BAR/ -> (FOO_BAR_, _) - # FOO_BAR/SVC_ -> (FOO_BAR_, _SVC_) - - if '/' in prefix: - main_prefix, sub_prefix = prefix.upper().split('/', 1) - prefix = prefix.replace('/', '_') - else: - main_prefix, sub_prefix = prefix.upper().split('_', 1) - - self.MAIN_PREFIX_ = main_prefix + '_' - self._SUB_PREFIX_ = '_' + sub_prefix - - self.Prefix_ = prefix - self.Prefix = prefix.replace('_', '') - self.prefix_ = prefix.lower() - self.PREFIX_ = prefix.upper() - - self.signal_marshal_prefix = signal_marshal_prefix - self.headers = headers - self.end_headers = end_headers - self.not_implemented_func = not_implemented_func - self.allow_havoc = allow_havoc - - def h(self, s): - self.__header.append(s) - - def b(self, s): - self.__body.append(s) - - def do_node(self, node): - node_name = node.getAttribute('name').replace('/', '') - node_name_mixed = self.node_name_mixed = node_name.replace('_', '') - node_name_lc = self.node_name_lc = node_name.lower() - node_name_uc = self.node_name_uc = node_name.upper() - - interfaces = node.getElementsByTagName('interface') - assert len(interfaces) == 1, interfaces - interface = interfaces[0] - self.iface_name = interface.getAttribute('name') - - tmp = interface.getAttribute('tp:implement-service') - if tmp == "no": - return - - tmp = interface.getAttribute('tp:causes-havoc') - if tmp and not self.allow_havoc: - raise AssertionError('%s is %s' % (self.iface_name, tmp)) - - self.b('static const DBusGObjectInfo _%s%s_object_info;' - % (self.prefix_, node_name_lc)) - self.b('') - - methods = interface.getElementsByTagName('method') - signals = interface.getElementsByTagName('signal') - properties = interface.getElementsByTagName('property') - # Don't put properties in dbus-glib glue - glue_properties = [] - - self.b('struct _%s%sClass {' % (self.Prefix, node_name_mixed)) - self.b(' GTypeInterface parent_class;') - for method in methods: - self.b(' %s %s;' % self.get_method_impl_names(method)) - self.b('};') - self.b('') - - if signals: - self.b('enum {') - for signal in signals: - self.b(' %s,' % self.get_signal_const_entry(signal)) - self.b(' N_%s_SIGNALS' % node_name_uc) - self.b('};') - self.b('static guint %s_signals[N_%s_SIGNALS] = {0};' - % (node_name_lc, node_name_uc)) - self.b('') - - self.b('static void %s%s_base_init (gpointer klass);' - % (self.prefix_, node_name_lc)) - self.b('') - - self.b('GType') - self.b('%s%s_get_type (void)' - % (self.prefix_, node_name_lc)) - self.b('{') - self.b(' static GType type = 0;') - self.b('') - self.b(' if (G_UNLIKELY (type == 0))') - self.b(' {') - self.b(' static const GTypeInfo info = {') - self.b(' sizeof (%s%sClass),' % (self.Prefix, node_name_mixed)) - self.b(' %s%s_base_init, /* base_init */' - % (self.prefix_, node_name_lc)) - self.b(' NULL, /* base_finalize */') - self.b(' NULL, /* class_init */') - self.b(' NULL, /* class_finalize */') - self.b(' NULL, /* class_data */') - self.b(' 0,') - self.b(' 0, /* n_preallocs */') - self.b(' NULL /* instance_init */') - self.b(' };') - self.b('') - self.b(' type = g_type_register_static (G_TYPE_INTERFACE,') - self.b(' "%s%s", &info, 0);' % (self.Prefix, node_name_mixed)) - self.b(' }') - self.b('') - self.b(' return type;') - self.b('}') - self.b('') - - self.h('/**') - self.h(' * %s%s:' % (self.Prefix, node_name_mixed)) - self.h(' *') - self.h(' * Dummy typedef representing any implementation of this ' - 'interface.') - self.h(' */') - self.h('typedef struct _%s%s %s%s;' - % (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed)) - self.h('') - self.h('/**') - self.h(' * %s%sClass:' % (self.Prefix, node_name_mixed)) - self.h(' *') - self.h(' * The class of %s%s.' % (self.Prefix, node_name_mixed)) - self.h(' */') - self.h('typedef struct _%s%sClass %s%sClass;' - % (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed)) - self.h('') - self.h('GType %s%s_get_type (void);' - % (self.prefix_, node_name_lc)) - - gtype = self.current_gtype = \ - self.MAIN_PREFIX_ + 'TYPE' + self._SUB_PREFIX_ + node_name_uc - classname = self.Prefix + node_name_mixed - - self.h('#define %s \\\n (%s%s_get_type ())' - % (gtype, self.prefix_, node_name_lc)) - self.h('#define %s%s(obj) \\\n' - ' (G_TYPE_CHECK_INSTANCE_CAST((obj), %s, %s))' - % (self.PREFIX_, node_name_uc, gtype, classname)) - self.h('#define %sIS%s%s(obj) \\\n' - ' (G_TYPE_CHECK_INSTANCE_TYPE((obj), %s))' - % (self.MAIN_PREFIX_, self._SUB_PREFIX_, node_name_uc, gtype)) - self.h('#define %s%s_GET_CLASS(obj) \\\n' - ' (G_TYPE_INSTANCE_GET_INTERFACE((obj), %s, %sClass))' - % (self.PREFIX_, node_name_uc, gtype, classname)) - self.h('') - self.h('') - - base_init_code = [] - - for method in methods: - self.do_method(method) - - for signal in signals: - base_init_code.extend(self.do_signal(signal)) - - self.b('static inline void') - self.b('%s%s_base_init_once (gpointer klass G_GNUC_UNUSED)' - % (self.prefix_, node_name_lc)) - self.b('{') - self.b(' static TpDBusPropertiesMixinPropInfo properties[%d] = {' - % (len(properties) + 1)) - - for m in properties: - access = m.getAttribute('access') - assert access in ('read', 'write', 'readwrite') - - if access == 'read': - flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_READ' - elif access == 'write': - flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE' - else: - flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | ' - 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE') - - self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */' - % (flags, m.getAttribute('type'), m.getAttribute('name'))) - - self.b(' { 0, 0, NULL, 0, NULL, NULL }') - self.b(' };') - self.b(' static TpDBusPropertiesMixinIfaceInfo interface =') - self.b(' { 0, properties, NULL, NULL };') - self.b('') - self.b(' interface.dbus_interface = g_quark_from_static_string ' - '("%s");' % self.iface_name) - - for i, m in enumerate(properties): - self.b(' properties[%d].name = g_quark_from_static_string ("%s");' - % (i, m.getAttribute('name'))) - self.b(' properties[%d].type = %s;' - % (i, type_to_gtype(m.getAttribute('type'))[1])) - - self.b(' tp_svc_interface_set_dbus_properties_info (%s, &interface);' - % self.current_gtype) - - self.b('') - for s in base_init_code: - self.b(s) - self.b(' dbus_g_object_type_install_info (%s%s_get_type (),' - % (self.prefix_, node_name_lc)) - self.b(' &_%s%s_object_info);' - % (self.prefix_, node_name_lc)) - self.b('}') - - self.b('static void') - self.b('%s%s_base_init (gpointer klass)' - % (self.prefix_, node_name_lc)) - self.b('{') - self.b(' static gboolean initialized = FALSE;') - self.b('') - self.b(' if (!initialized)') - self.b(' {') - self.b(' initialized = TRUE;') - self.b(' %s%s_base_init_once (klass);' - % (self.prefix_, node_name_lc)) - self.b(' }') - # insert anything we need to do per implementation here - self.b('}') - - self.h('') - - self.b('static const DBusGMethodInfo _%s%s_methods[] = {' - % (self.prefix_, node_name_lc)) - - method_blob, offsets = self.get_method_glue(methods) - - for method, offset in zip(methods, offsets): - self.do_method_glue(method, offset) - - self.b('};') - self.b('') - - self.b('static const DBusGObjectInfo _%s%s_object_info = {' - % (self.prefix_, node_name_lc)) - self.b(' 0,') # version - self.b(' _%s%s_methods,' % (self.prefix_, node_name_lc)) - self.b(' %d,' % len(methods)) - self.b('"' + method_blob.replace('\0', '\\0') + '",') - self.b('"' + self.get_signal_glue(signals).replace('\0', '\\0') + '",') - self.b('"' + - self.get_property_glue(glue_properties).replace('\0', '\\0') + - '",') - self.b('};') - self.b('') - - self.node_name_mixed = None - self.node_name_lc = None - self.node_name_uc = None - - def get_method_glue(self, methods): - info = [] - offsets = [] - - for method in methods: - offsets.append(len(''.join(info))) - - info.append(self.iface_name + '\0') - info.append(method.getAttribute('name') + '\0') - - info.append('A\0') # async - - counter = 0 - for arg in method.getElementsByTagName('arg'): - out = arg.getAttribute('direction') == 'out' - - name = arg.getAttribute('name') - if not name: - assert out - name = 'arg%u' % counter - counter += 1 - - info.append(name + '\0') - - if out: - info.append('O\0') - else: - info.append('I\0') - - if out: - info.append('F\0') # not const - info.append('N\0') # not error or return - info.append(arg.getAttribute('type') + '\0') - - info.append('\0') - - return ''.join(info) + '\0', offsets - - def do_method_glue(self, method, offset): - lc_name = camelcase_to_lower(method.getAttribute('name')) - - marshaller = method_to_glue_marshal_name(method, - self.signal_marshal_prefix) - wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name - - self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset)) - - def get_signal_glue(self, signals): - info = [] - - for signal in signals: - info.append(self.iface_name) - info.append(signal.getAttribute('name')) - - return '\0'.join(info) + '\0\0' - - # the implementation can be the same - get_property_glue = get_signal_glue - - def get_method_impl_names(self, method): - dbus_method_name = method.getAttribute('name') - class_member_name = camelcase_to_lower(dbus_method_name) - stub_name = (self.prefix_ + self.node_name_lc + '_' + - class_member_name) - return (stub_name + '_impl', class_member_name) - - def do_method(self, method): - assert self.node_name_mixed is not None - - in_class = [] - - # Examples refer to Thing.DoStuff (su) -> ii - - # DoStuff - dbus_method_name = method.getAttribute('name') - # do_stuff - class_member_name = camelcase_to_lower(dbus_method_name) - # void tp_svc_thing_do_stuff (TpSvcThing *, const char *, guint, - # DBusGMethodInvocation *); - stub_name = (self.prefix_ + self.node_name_lc + '_' + - class_member_name) - # typedef void (*tp_svc_thing_do_stuff_impl) (TpSvcThing *, - # const char *, guint, DBusGMethodInvocation); - impl_name = stub_name + '_impl' - # void tp_svc_thing_return_from_do_stuff (DBusGMethodInvocation *, - # gint, gint); - ret_name = (self.prefix_ + self.node_name_lc + '_return_from_' + - class_member_name) - - # Gather arguments - in_args = [] - out_args = [] - for i in method.getElementsByTagName('arg'): - name = i.getAttribute('name') - direction = i.getAttribute('direction') or 'in' - dtype = i.getAttribute('type') - - assert direction in ('in', 'out') - - if name: - name = direction + '_' + name - elif direction == 'in': - name = direction + str(len(in_args)) - else: - name = direction + str(len(out_args)) - - ctype, gtype, marshaller, pointer = type_to_gtype(dtype) - - if pointer: - ctype = 'const ' + ctype - - struct = (ctype, name) - - if direction == 'in': - in_args.append(struct) - else: - out_args.append(struct) - - # Implementation type declaration (in header, docs in body) - self.b('/**') - self.b(' * %s:' % impl_name) - self.b(' * @self: The object implementing this interface') - for (ctype, name) in in_args: - self.b(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.b(' * @context: Used to return values or throw an error') - self.b(' *') - self.b(' * The signature of an implementation of the D-Bus method') - self.b(' * %s on interface %s.' % (dbus_method_name, self.iface_name)) - self.b(' */') - self.h('typedef void (*%s) (%s%s *self,' - % (impl_name, self.Prefix, self.node_name_mixed)) - for (ctype, name) in in_args: - self.h(' %s%s,' % (ctype, name)) - self.h(' DBusGMethodInvocation *context);') - - # Class member (in class definition) - in_class.append(' %s %s;' % (impl_name, class_member_name)) - - # Stub definition (in body only - it's static) - self.b('static void') - self.b('%s (%s%s *self,' - % (stub_name, self.Prefix, self.node_name_mixed)) - for (ctype, name) in in_args: - self.b(' %s%s,' % (ctype, name)) - self.b(' DBusGMethodInvocation *context)') - self.b('{') - self.b(' %s impl = (%s%s_GET_CLASS (self)->%s);' - % (impl_name, self.PREFIX_, self.node_name_uc, class_member_name)) - self.b('') - self.b(' if (impl != NULL)') - tmp = ['self'] + [name for (ctype, name) in in_args] + ['context'] - self.b(' {') - self.b(' (impl) (%s);' % ',\n '.join(tmp)) - self.b(' }') - self.b(' else') - self.b(' {') - if self.not_implemented_func: - self.b(' %s (context);' % self.not_implemented_func) - else: - self.b(' GError e = { DBUS_GERROR, ') - self.b(' DBUS_GERROR_UNKNOWN_METHOD,') - self.b(' "Method not implemented" };') - self.b('') - self.b(' dbus_g_method_return_error (context, &e);') - self.b(' }') - self.b('}') - self.b('') - - # Implementation registration (in both header and body) - self.h('void %s%s_implement_%s (%s%sClass *klass, %s impl);' - % (self.prefix_, self.node_name_lc, class_member_name, - self.Prefix, self.node_name_mixed, impl_name)) - - self.b('/**') - self.b(' * %s%s_implement_%s:' - % (self.prefix_, self.node_name_lc, class_member_name)) - self.b(' * @klass: A class whose instances implement this interface') - self.b(' * @impl: A callback used to implement the %s D-Bus method' - % dbus_method_name) - self.b(' *') - self.b(' * Register an implementation for the %s method in the vtable' - % dbus_method_name) - self.b(' * of an implementation of this interface. To be called from') - self.b(' * the interface init function.') - self.b(' */') - self.b('void') - self.b('%s%s_implement_%s (%s%sClass *klass, %s impl)' - % (self.prefix_, self.node_name_lc, class_member_name, - self.Prefix, self.node_name_mixed, impl_name)) - self.b('{') - self.b(' klass->%s = impl;' % class_member_name) - self.b('}') - self.b('') - - # Return convenience function (static inline, in header) - self.h('/**') - self.h(' * %s:' % ret_name) - self.h(' * @context: The D-Bus method invocation context') - for (ctype, name) in out_args: - self.h(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.h(' *') - self.h(' * Return successfully by calling dbus_g_method_return().') - self.h(' * This inline function exists only to provide type-safety.') - self.h(' */') - tmp = (['DBusGMethodInvocation *context'] + - [ctype + name for (ctype, name) in out_args]) - self.h('static inline') - self.h('/* this comment is to stop gtkdoc realising this is static */') - self.h(('void %s (' % ret_name) + (',\n '.join(tmp)) + ');') - self.h('static inline void') - self.h(('%s (' % ret_name) + (',\n '.join(tmp)) + ')') - self.h('{') - tmp = ['context'] + [name for (ctype, name) in out_args] - self.h(' dbus_g_method_return (' + ',\n '.join(tmp) + ');') - self.h('}') - self.h('') - - return in_class - - def get_signal_const_entry(self, signal): - assert self.node_name_uc is not None - return ('SIGNAL_%s_%s' - % (self.node_name_uc, signal.getAttribute('name'))) - - def do_signal(self, signal): - assert self.node_name_mixed is not None - - in_base_init = [] - - # for signal: Thing::StuffHappened (s, u) - # we want to emit: - # void tp_svc_thing_emit_stuff_happened (gpointer instance, - # const char *arg0, guint arg1); - - dbus_name = signal.getAttribute('name') - stub_name = (self.prefix_ + self.node_name_lc + '_emit_' + - camelcase_to_lower(dbus_name)) - const_name = self.get_signal_const_entry(signal) - - # Gather arguments - args = [] - for i in signal.getElementsByTagName('arg'): - name = i.getAttribute('name') - dtype = i.getAttribute('type') - tp_type = i.getAttribute('tp:type') - - if name: - name = 'arg_' + name - else: - name = 'arg' + str(len(args)) - - ctype, gtype, marshaller, pointer = type_to_gtype(dtype) - - if pointer: - ctype = 'const ' + ctype - - struct = (ctype, name, gtype) - args.append(struct) - - tmp = (['gpointer instance'] + - [ctype + name for (ctype, name, gtype) in args]) - - self.h(('void %s (' % stub_name) + (',\n '.join(tmp)) + ');') - - # FIXME: emit docs - - self.b('/**') - self.b(' * %s:' % stub_name) - self.b(' * @instance: The object implementing this interface') - for (ctype, name, gtype) in args: - self.b(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.b(' *') - self.b(' * Type-safe wrapper around g_signal_emit to emit the') - self.b(' * %s signal on interface %s.' - % (dbus_name, self.iface_name)) - self.b(' */') - - self.b('void') - self.b(('%s (' % stub_name) + (',\n '.join(tmp)) + ')') - self.b('{') - self.b(' g_assert (instance != NULL);') - self.b(' g_assert (G_TYPE_CHECK_INSTANCE_TYPE (instance, %s));' - % (self.current_gtype)) - tmp = (['instance', '%s_signals[%s]' % (self.node_name_lc, const_name), - '0'] + [name for (ctype, name, gtype) in args]) - self.b(' g_signal_emit (' + ',\n '.join(tmp) + ');') - self.b('}') - self.b('') - - in_base_init.append(' %s_signals[%s] =' - % (self.node_name_lc, const_name)) - in_base_init.append(' g_signal_new ("%s",' - % (dbus_gutils_wincaps_to_uscore(dbus_name).replace('_', '-'))) - in_base_init.append(' G_OBJECT_CLASS_TYPE (klass),') - in_base_init.append(' G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,') - in_base_init.append(' 0,') - in_base_init.append(' NULL, NULL,') - in_base_init.append(' %s,' - % signal_to_marshal_name(signal, self.signal_marshal_prefix)) - in_base_init.append(' G_TYPE_NONE,') - tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args] - in_base_init.append(' %s);' % ',\n '.join(tmp)) - in_base_init.append('') - - return in_base_init - - def __call__(self): - self.h('#include <glib-object.h>') - self.h('#include <dbus/dbus-glib.h>') - self.h('#include <telepathy-glib/dbus-properties-mixin.h>') - self.h('') - self.h('G_BEGIN_DECLS') - self.h('') - - self.b('#include "%s.h"' % basename) - self.b('') - for header in self.headers: - self.b('#include %s' % header) - self.b('') - - nodes = self.dom.getElementsByTagName('node') - nodes.sort(cmp_by_name) - - for node in nodes: - self.do_node(node) - - self.h('') - self.h('G_END_DECLS') - - self.b('') - for header in self.end_headers: - self.b('#include %s' % header) - - self.h('') - self.b('') - open(basename + '.h', 'w').write('\n'.join(self.__header)) - open(basename + '.c', 'w').write('\n'.join(self.__body)) - - -def cmdline_error(): - print """\ -usage: - gen-ginterface [OPTIONS] xmlfile Prefix_ -options: - --include='<header.h>' (may be repeated) - --include='"header.h"' (ditto) - --include-end='"header.h"' (ditto) - Include extra headers in the generated .c file - --signal-marshal-prefix='prefix' - Use the given prefix on generated signal marshallers (default is - prefix.lower()). - --filename='BASENAME' - Set the basename for the output files (default is prefix.lower() - + 'ginterfaces') - --not-implemented-func='symbol' - Set action when methods not implemented in the interface vtable are - called. symbol must have signature - void symbol (DBusGMethodInvocation *context) - and return some sort of "not implemented" error via - dbus_g_method_return_error (context, ...) -""" - sys.exit(1) - - -if __name__ == '__main__': - from getopt import gnu_getopt - - options, argv = gnu_getopt(sys.argv[1:], '', - ['filename=', 'signal-marshal-prefix=', - 'include=', 'include-end=', - 'allow-unstable', - 'not-implemented-func=']) - - try: - prefix = argv[1] - except IndexError: - cmdline_error() - - basename = prefix.lower() + 'ginterfaces' - signal_marshal_prefix = prefix.lower().rstrip('_') - headers = [] - end_headers = [] - not_implemented_func = '' - allow_havoc = False - - for option, value in options: - if option == '--filename': - basename = value - elif option == '--signal-marshal-prefix': - signal_marshal_prefix = value - elif option == '--include': - if value[0] not in '<"': - value = '"%s"' % value - headers.append(value) - elif option == '--include-end': - if value[0] not in '<"': - value = '"%s"' % value - end_headers.append(value) - elif option == '--not-implemented-func': - not_implemented_func = value - elif option == '--allow-unstable': - allow_havoc = True - - try: - dom = xml.dom.minidom.parse(argv[0]) - except IndexError: - cmdline_error() - - Generator(dom, prefix, basename, signal_marshal_prefix, headers, - end_headers, not_implemented_func, allow_havoc)() diff --git a/tools/glib-gtypes-generator.py b/tools/glib-gtypes-generator.py deleted file mode 100644 index fcb46e8..0000000 --- a/tools/glib-gtypes-generator.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/python - -# Generate GLib GInterfaces from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006, 2007 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import xml.dom.minidom - -from libglibcodegen import escape_as_identifier, \ - get_docstring, \ - NS_TP, \ - Signature, \ - type_to_gtype, \ - xml_escape - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - - -class GTypesGenerator(object): - def __init__(self, dom, output, mixed_case_prefix): - self.dom = dom - self.Prefix = mixed_case_prefix - self.PREFIX_ = self.Prefix.upper() + '_' - self.prefix_ = self.Prefix.lower() + '_' - - self.header = open(output + '.h', 'w') - self.body = open(output + '-body.h', 'w') - - for f in (self.header, self.body): - f.write('/* Auto-generated, do not edit.\n *\n' - ' * This file may be distributed under the same terms\n' - ' * as the specification from which it was generated.\n' - ' */\n\n') - - self.need_mappings = {} - self.need_structs = {} - self.need_arrays = {} - - def do_mapping_header(self, mapping): - members = mapping.getElementsByTagNameNS(NS_TP, 'member') - assert len(members) == 2 - - impl_sig = ''.join([elt.getAttribute('type') - for elt in members]) - - esc_impl_sig = escape_as_identifier(impl_sig) - - name = (self.PREFIX_ + 'HASH_TYPE_' + - mapping.getAttribute('name').upper()) - impl = self.prefix_ + 'type_dbus_hash_' + esc_impl_sig - - docstring = get_docstring(mapping) or '(Undocumented)' - - self.header.write('/**\n * %s:\n *\n' % name) - self.header.write(' * %s\n' % xml_escape(docstring)) - self.header.write(' *\n') - self.header.write(' * This macro expands to a call to a function\n') - self.header.write(' * that returns the #GType of a #GHashTable\n') - self.header.write(' * appropriate for representing a D-Bus\n') - self.header.write(' * dictionary of signature\n') - self.header.write(' * <literal>a{%s}</literal>.\n' % impl_sig) - self.header.write(' *\n') - - key, value = members - - self.header.write(' * Keys (D-Bus type <literal>%s</literal>,\n' - % key.getAttribute('type')) - tp_type = key.getAttributeNS(NS_TP, 'type') - if tp_type: - self.header.write(' * type <literal>%s</literal>,\n' % tp_type) - self.header.write(' * named <literal>%s</literal>):\n' - % key.getAttribute('name')) - docstring = get_docstring(key) or '(Undocumented)' - self.header.write(' * %s\n' % xml_escape(docstring)) - self.header.write(' *\n') - - self.header.write(' * Values (D-Bus type <literal>%s</literal>,\n' - % value.getAttribute('type')) - tp_type = value.getAttributeNS(NS_TP, 'type') - if tp_type: - self.header.write(' * type <literal>%s</literal>,\n' % tp_type) - self.header.write(' * named <literal>%s</literal>):\n' - % value.getAttribute('name')) - docstring = get_docstring(value) or '(Undocumented)' - self.header.write(' * %s\n' % xml_escape(docstring)) - self.header.write(' *\n') - - self.header.write(' */\n') - - self.header.write('#define %s (%s ())\n\n' % (name, impl)) - self.need_mappings[impl_sig] = esc_impl_sig - - def do_struct_header(self, struct): - members = struct.getElementsByTagNameNS(NS_TP, 'member') - impl_sig = ''.join([elt.getAttribute('type') for elt in members]) - esc_impl_sig = escape_as_identifier(impl_sig) - - name = (self.PREFIX_ + 'STRUCT_TYPE_' + - struct.getAttribute('name').upper()) - impl = self.prefix_ + 'type_dbus_struct_' + esc_impl_sig - docstring = struct.getElementsByTagNameNS(NS_TP, 'docstring') - if docstring: - docstring = docstring[0].toprettyxml() - if docstring.startswith('<tp:docstring>'): - docstring = docstring[14:] - if docstring.endswith('</tp:docstring>\n'): - docstring = docstring[:-16] - if docstring.strip() in ('<tp:docstring/>', ''): - docstring = '(Undocumented)' - else: - docstring = '(Undocumented)' - self.header.write('/**\n * %s:\n\n' % name) - self.header.write(' * %s\n' % xml_escape(docstring)) - self.header.write(' *\n') - self.header.write(' * This macro expands to a call to a function\n') - self.header.write(' * that returns the #GType of a #GValueArray\n') - self.header.write(' * appropriate for representing a D-Bus struct\n') - self.header.write(' * with signature <literal>(%s)</literal>.\n' - % impl_sig) - self.header.write(' *\n') - - for i, member in enumerate(members): - self.header.write(' * Member %d (D-Bus type ' - '<literal>%s</literal>,\n' - % (i, member.getAttribute('type'))) - tp_type = member.getAttributeNS(NS_TP, 'type') - if tp_type: - self.header.write(' * type <literal>%s</literal>,\n' % tp_type) - self.header.write(' * named <literal>%s</literal>):\n' - % member.getAttribute('name')) - docstring = get_docstring(member) or '(Undocumented)' - self.header.write(' * %s\n' % xml_escape(docstring)) - self.header.write(' *\n') - - self.header.write(' */\n') - self.header.write('#define %s (%s ())\n\n' % (name, impl)) - - array_name = struct.getAttribute('array-name') - if array_name != '': - array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper()) - impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig - self.header.write('/**\n * %s:\n\n' % array_name) - self.header.write(' * Expands to a call to a function\n') - self.header.write(' * that returns the #GType of a #GPtrArray\n') - self.header.write(' * of #%s.\n' % name) - self.header.write(' */\n') - self.header.write('#define %s (%s ())\n\n' % (array_name, impl)) - self.need_arrays[impl_sig] = esc_impl_sig - - self.need_structs[impl_sig] = esc_impl_sig - - def __call__(self): - mappings = self.dom.getElementsByTagNameNS(NS_TP, 'mapping') - structs = self.dom.getElementsByTagNameNS(NS_TP, 'struct') - - for mapping in mappings: - self.do_mapping_header(mapping) - - for sig in self.need_mappings: - self.header.write('GType %stype_dbus_hash_%s (void);\n\n' % - (self.prefix_, self.need_mappings[sig])) - self.body.write('GType\n%stype_dbus_hash_%s (void)\n{\n' % - (self.prefix_, self.need_mappings[sig])) - self.body.write(' static GType t = 0;\n\n') - self.body.write(' if (G_UNLIKELY (t == 0))\n') - # FIXME: translate sig into two GTypes - items = tuple(Signature(sig)) - gtypes = types_to_gtypes(items) - self.body.write(' t = dbus_g_type_get_map ("GHashTable", ' - '%s, %s);\n' % (gtypes[0], gtypes[1])) - self.body.write(' return t;\n') - self.body.write('}\n\n') - - for struct in structs: - self.do_struct_header(struct) - - for sig in self.need_structs: - self.header.write('GType %stype_dbus_struct_%s (void);\n\n' % - (self.prefix_, self.need_structs[sig])) - self.body.write('GType\n%stype_dbus_struct_%s (void)\n{\n' % - (self.prefix_, self.need_structs[sig])) - self.body.write(' static GType t = 0;\n\n') - self.body.write(' if (G_UNLIKELY (t == 0))\n') - self.body.write(' t = dbus_g_type_get_struct ("GValueArray",\n') - items = tuple(Signature(sig)) - gtypes = types_to_gtypes(items) - for gtype in gtypes: - self.body.write(' %s,\n' % gtype) - self.body.write(' G_TYPE_INVALID);\n') - self.body.write(' return t;\n') - self.body.write('}\n\n') - - for sig in self.need_arrays: - self.header.write('GType %stype_dbus_array_%s (void);\n\n' % - (self.prefix_, self.need_structs[sig])) - self.body.write('GType\n%stype_dbus_array_%s (void)\n{\n' % - (self.prefix_, self.need_structs[sig])) - self.body.write(' static GType t = 0;\n\n') - self.body.write(' if (G_UNLIKELY (t == 0))\n') - self.body.write(' t = dbus_g_type_get_collection ("GPtrArray", ' - '%stype_dbus_struct_%s ());\n' % - (self.prefix_, self.need_structs[sig])) - self.body.write(' return t;\n') - self.body.write('}\n\n') - -if __name__ == '__main__': - argv = sys.argv[1:] - - dom = xml.dom.minidom.parse(argv[0]) - - GTypesGenerator(dom, argv[1], argv[2])() diff --git a/tools/glib-interfaces-body-generator.xsl b/tools/glib-interfaces-body-generator.xsl deleted file mode 100644 index caff891..0000000 --- a/tools/glib-interfaces-body-generator.xsl +++ /dev/null @@ -1,47 +0,0 @@ -<!-- Stylesheet to extract C interface names from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:import href="c-interfaces-generator.xsl"/> - - <xsl:template match="interface"> - <xsl:text>GQuark </xsl:text> - <xsl:value-of select="$prefix"/> - <xsl:text>_iface_quark_</xsl:text> - <xsl:value-of select="translate(../@name, concat($upper, '/'), $lower)"/> - <xsl:text> (void) { </xsl:text> - <xsl:text> static GQuark quark = 0; </xsl:text> - <xsl:text> if (G_UNLIKELY (quark == 0)) </xsl:text> - <xsl:text> { </xsl:text> - <xsl:text> quark = g_quark_from_static_string ("</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>"); </xsl:text> - <xsl:text> } </xsl:text> - <xsl:text> return quark; </xsl:text> - <xsl:text>} </xsl:text> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/glib-interfaces-generator.xsl b/tools/glib-interfaces-generator.xsl deleted file mode 100644 index e703c40..0000000 --- a/tools/glib-interfaces-generator.xsl +++ /dev/null @@ -1,55 +0,0 @@ -<!-- Stylesheet to extract C interface names from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:import href="c-interfaces-generator.xsl"/> - - <xsl:template match="interface"> - <xsl:apply-imports/> - - <xsl:text>/** * </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_QUARK_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text>: * * Expands to a call to a function that </xsl:text> - <xsl:text>returns a quark for the interface name "</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>" */ #define </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_QUARK_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text> \ (</xsl:text> - <xsl:value-of select="$prefix"/> - <xsl:text>_iface_quark_</xsl:text> - <xsl:value-of select="translate(../@name, concat($upper, '/'), $lower)"/> - <xsl:text> ()) GQuark </xsl:text> - <xsl:value-of select="$prefix"/> - <xsl:text>_iface_quark_</xsl:text> - <xsl:value-of select="translate(../@name, concat($upper, '/'), $lower)"/> - <xsl:text> (void); </xsl:text> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/glib-signals-marshal-gen.py b/tools/glib-signals-marshal-gen.py deleted file mode 100644 index 0d02c13..0000000 --- a/tools/glib-signals-marshal-gen.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/python - -import sys -import xml.dom.minidom -from string import ascii_letters, digits - - -from libglibcodegen import signal_to_marshal_name, method_to_glue_marshal_name - - -class Generator(object): - - def __init__(self, dom): - self.dom = dom - self.marshallers = {} - - def do_method(self, method): - marshaller = method_to_glue_marshal_name(method, 'PREFIX') - - assert '__' in marshaller - rhs = marshaller.split('__', 1)[1].split('_') - - self.marshallers[marshaller] = rhs - - def do_signal(self, signal): - marshaller = signal_to_marshal_name(signal, 'PREFIX') - - assert '__' in marshaller - rhs = marshaller.split('__', 1)[1].split('_') - - self.marshallers[marshaller] = rhs - - def __call__(self): - methods = self.dom.getElementsByTagName('method') - - for method in methods: - self.do_method(method) - - signals = self.dom.getElementsByTagName('signal') - - for signal in signals: - self.do_signal(signal) - - all = self.marshallers.keys() - all.sort() - for marshaller in all: - rhs = self.marshallers[marshaller] - if not marshaller.startswith('g_cclosure'): - print 'VOID:' + ','.join(rhs) - -if __name__ == '__main__': - argv = sys.argv[1:] - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom)() diff --git a/tools/identity.xsl b/tools/identity.xsl deleted file mode 100644 index 6630f84..0000000 --- a/tools/identity.xsl +++ /dev/null @@ -1,7 +0,0 @@ -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - <xsl:template match="@*|node()"> - <xsl:copy> - <xsl:apply-templates select="@*|node()"/> - </xsl:copy> - </xsl:template> -</xsl:stylesheet> diff --git a/tools/libglibcodegen.py b/tools/libglibcodegen.py deleted file mode 100644 index 090e8de..0000000 --- a/tools/libglibcodegen.py +++ /dev/null @@ -1,320 +0,0 @@ -"""Library code for GLib/D-Bus-related code generation. - -The master copy of this library is in the telepathy-glib repository - -please make any changes there. -""" - -# Copyright (C) 2006, 2007 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -from string import ascii_letters, digits - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -_ASCII_ALNUM = ascii_letters + digits - - -def camelcase_to_lower(s): - out =""; - out += s[0].lower() - last_upper=False - if s[0].isupper(): - last_upper=True - for i in range(1,len(s)): - if s[i].isupper(): - if last_upper: - if (i+1) < len(s) and s[i+1].islower(): - out += "_" + s[i].lower() - else: - out += s[i].lower() - else: - out += "_" + s[i].lower() - last_upper=True - else: - out += s[i] - last_upper=False - return out - - -def camelcase_to_upper(s): - return camelcase_to_lower(s).upper() - - -def cmp_by_name(node1, node2): - return cmp(node1.getAttributeNode("name").nodeValue, - node2.getAttributeNode("name").nodeValue) - - -def dbus_gutils_wincaps_to_uscore(s): - """Bug-for-bug compatible Python port of _dbus_gutils_wincaps_to_uscore - which gets sequences of capital letters wrong in the same way. - (e.g. in Telepathy, SendDTMF -> send_dt_mf) - """ - ret = '' - for c in s: - if c >= 'A' and c <= 'Z': - length = len(ret) - if length > 0 and (length < 2 or ret[length-2] != '_'): - ret += '_' - ret += c.lower() - else: - ret += c - return ret - - -def escape_as_identifier(identifier): - """Escape the given string to be a valid D-Bus object path or service - name component, using a reversible encoding to ensure uniqueness. - - The reversible encoding is as follows: - - * The empty string becomes '_' - * Otherwise, each non-alphanumeric character is replaced by '_' plus - two lower-case hex digits; the same replacement is carried out on - the first character, if it's a digit - """ - # '' -> '_' - if not identifier: - return '_' - - # A bit of a fast path for strings which are already OK. - # We deliberately omit '_' because, for reversibility, that must also - # be escaped. - if (identifier.strip(_ASCII_ALNUM) == '' and - identifier[0] in ascii_letters): - return identifier - - # The first character may not be a digit - if identifier[0] not in ascii_letters: - ret = ['_%02x' % ord(identifier[0])] - else: - ret = [identifier[0]] - - # Subsequent characters may be digits or ASCII letters - for c in identifier[1:]: - if c in _ASCII_ALNUM: - ret.append(c) - else: - ret.append('_%02x' % ord(c)) - - return ''.join(ret) - - -def get_docstring(element): - docstring = None - for x in element.childNodes: - if x.namespaceURI == NS_TP and x.localName == 'docstring': - docstring = x - if docstring is not None: - docstring = docstring.toxml().replace('\n', ' ').strip() - if docstring.startswith('<tp:docstring>'): - docstring = docstring[14:].lstrip() - if docstring.endswith('</tp:docstring>'): - docstring = docstring[:-15].rstrip() - if docstring in ('<tp:docstring/>', ''): - docstring = '' - return docstring - - -def signal_to_marshal_type(signal): - """ - return a list of strings indicating the marshalling type for this signal. - """ - - mtype=[] - for i in signal.getElementsByTagName("arg"): - name =i.getAttribute("name") - type = i.getAttribute("type") - mtype.append(type_to_gtype(type)[2]) - - return mtype - - -_glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT', - 'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT', - 'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT', - 'UINT_POINTER'] - - -def signal_to_marshal_name(signal, prefix): - - mtype = signal_to_marshal_type(signal) - if len(mtype): - name = '_'.join(mtype) - else: - name = 'VOID' - - if name in _glib_marshallers: - return 'g_cclosure_marshal_VOID__' + name - else: - return prefix + '_marshal_VOID__' + name - - -def method_to_glue_marshal_name(method, prefix): - - mtype = [] - for i in method.getElementsByTagName("arg"): - if i.getAttribute("direction") != "out": - type = i.getAttribute("type") - mtype.append(type_to_gtype(type)[2]) - - mtype.append('POINTER') - - name = '_'.join(mtype) - - if name in _glib_marshallers: - return 'g_cclosure_marshal_VOID__' + name - else: - return prefix + '_marshal_VOID__' + name - - -class _SignatureIter: - """Iterator over a D-Bus signature. Copied from dbus-python 0.71 so we - can run genginterface in a limited environment with only Python - (like Scratchbox). - """ - def __init__(self, string): - self.remaining = string - - def next(self): - if self.remaining == '': - raise StopIteration - - signature = self.remaining - block_depth = 0 - block_type = None - end = len(signature) - - for marker in range(0, end): - cur_sig = signature[marker] - - if cur_sig == 'a': - pass - elif cur_sig == '{' or cur_sig == '(': - if block_type == None: - block_type = cur_sig - - if block_type == cur_sig: - block_depth = block_depth + 1 - - elif cur_sig == '}': - if block_type == '{': - block_depth = block_depth - 1 - - if block_depth == 0: - end = marker - break - - elif cur_sig == ')': - if block_type == '(': - block_depth = block_depth - 1 - - if block_depth == 0: - end = marker - break - - else: - if block_depth == 0: - end = marker - break - - end = end + 1 - self.remaining = signature[end:] - return Signature(signature[0:end]) - - -class Signature(str): - """A string, iteration over which is by D-Bus single complete types - rather than characters. - """ - def __iter__(self): - return _SignatureIter(self) - - -def type_to_gtype(s): - if s == 'y': #byte - return ("guchar ", "G_TYPE_UCHAR","UCHAR", False) - elif s == 'b': #boolean - return ("gboolean ", "G_TYPE_BOOLEAN","BOOLEAN", False) - elif s == 'n': #int16 - return ("gint ", "G_TYPE_INT","INT", False) - elif s == 'q': #uint16 - return ("guint ", "G_TYPE_UINT","UINT", False) - elif s == 'i': #int32 - return ("gint ", "G_TYPE_INT","INT", False) - elif s == 'u': #uint32 - return ("guint ", "G_TYPE_UINT","UINT", False) - elif s == 'x': #int64 - return ("gint64 ", "G_TYPE_INT64","INT64", False) - elif s == 't': #uint64 - return ("guint64 ", "G_TYPE_UINT64","UINT64", False) - elif s == 'd': #double - return ("gdouble ", "G_TYPE_DOUBLE","DOUBLE", False) - elif s == 's': #string - return ("gchar *", "G_TYPE_STRING", "STRING", True) - elif s == 'g': #signature - FIXME - return ("gchar *", "DBUS_TYPE_G_SIGNATURE", "STRING", True) - elif s == 'o': #object path - return ("gchar *", "DBUS_TYPE_G_OBJECT_PATH", "BOXED", True) - elif s == 'v': #variant - return ("GValue *", "G_TYPE_VALUE", "BOXED", True) - elif s == 'as': #array of strings - return ("gchar **", "G_TYPE_STRV", "BOXED", True) - elif s == 'ay': #byte array - return ("GArray *", - "dbus_g_type_get_collection (\"GArray\", G_TYPE_UCHAR)", "BOXED", - True) - elif s == 'au': #uint array - return ("GArray *", "DBUS_TYPE_G_UINT_ARRAY", "BOXED", True) - elif s == 'ai': #int array - return ("GArray *", "DBUS_TYPE_G_INT_ARRAY", "BOXED", True) - elif s == 'ax': #int64 array - return ("GArray *", "DBUS_TYPE_G_INT64_ARRAY", "BOXED", True) - elif s == 'at': #uint64 array - return ("GArray *", "DBUS_TYPE_G_UINT64_ARRAY", "BOXED", True) - elif s == 'ad': #double array - return ("GArray *", "DBUS_TYPE_G_DOUBLE_ARRAY", "BOXED", True) - elif s == 'ab': #boolean array - return ("GArray *", "DBUS_TYPE_G_BOOLEAN_ARRAY", "BOXED", True) - elif s == 'ao': #object path array - return ("GArray *", "DBUS_TYPE_G_OBJECT_ARRAY", "BOXED", True) - elif s == 'a{ss}': #hash table of string to string - return ("GHashTable *", "DBUS_TYPE_G_STRING_STRING_HASHTABLE", "BOXED", False) - elif s[:2] == 'a{': #some arbitrary hash tables - if s[2] not in ('y', 'b', 'n', 'q', 'i', 'u', 's', 'o', 'g'): - raise Exception, "can't index a hashtable off non-basic type " + s - first = type_to_gtype(s[2]) - second = type_to_gtype(s[3:-1]) - return ("GHashTable *", "(dbus_g_type_get_map (\"GHashTable\", " + first[1] + ", " + second[1] + "))", "BOXED", False) - elif s[:2] in ('a(', 'aa'): # array of structs or arrays, recurse - gtype = type_to_gtype(s[1:])[1] - return ("GPtrArray *", "(dbus_g_type_get_collection (\"GPtrArray\", "+gtype+"))", "BOXED", True) - elif s[:1] == '(': #struct - gtype = "(dbus_g_type_get_struct (\"GValueArray\", " - for subsig in Signature(s[1:-1]): - gtype = gtype + type_to_gtype(subsig)[1] + ", " - gtype = gtype + "G_TYPE_INVALID))" - return ("GValueArray *", gtype, "BOXED", True) - - # we just don't know .. - raise Exception, "don't know the GType for " + s - - -def xml_escape(s): - s = s.replace('&', '&').replace("'", ''').replace('"', '"') - return s.replace('<', '<').replace('>', '>') |