Commit 0e7b8dff authored by W. Michael Petullo's avatar W. Michael Petullo
Browse files

Implement DAAPConnection and DPAPConnection, add test program written in Vala


Signed-off-by: W. Michael Petullo's avatarW. Michael Petullo <mike@flyn.org>
parent fbb71fd2
......@@ -53,5 +53,7 @@ tests/.libs/
tests/Makefile
tests/Makefile.in
tests/*.o
tests/dpapview
tests/test-dmap-client
tests/test-dmap-server
tests/vala.stamp
......@@ -17,6 +17,7 @@ pkgconfig_DATA = $(pcfiles)
EXTRA_DIST = \
autogen.sh \
libdmapsharing-2.2.vapi \
libdmapsharing.pc.in \
README-Memory
......
......@@ -326,6 +326,28 @@ else
AC_WARN(GStreamer app element not present, transcoding will not be supported.)
fi
AM_MAINTAINER_MODE
if test "x$USE_MAINTAINER_MODE" = "xyes" ; then
AM_PROG_VALAC([0.10.0])
if test "x$VALAC" = "x" ; then
AC_MSG_ERROR([Cannot find the "valac" compiler in your PATH])
fi
fi
PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes, HAVE_GTK=no)
if test "x$HAVE_GTK" = "xno"; then
AC_MSG_ERROR(you need gtk+-2.0 installed)
fi
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
PKG_CHECK_MODULES(GEE, gee-1.0, HAVE_GEE=yes, HAVE_GEE=no)
if test "x$HAVE_GEE" = "xno"; then
AC_MSG_ERROR(you need gee-1.0 installed)
fi
AC_SUBST(GEE_CFLAGS)
AC_SUBST(GEE_LIBS)
AM_CONDITIONAL(USE_GSTREAMERAPP, test x"$HAVE_GSTREAMERAPP" = "xyes")
AC_SUBST(GSTREAMERAPP_CFLAGS)
......
/* libdmapsharing-2.2.vapi generated by vapigen, do not modify. */
[CCode (cprefix = "DMAP", lower_case_cprefix = "dmap_")]
namespace DMAP {
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class Connection : GLib.Object {
[CCode (has_construct_function = false)]
public Connection (string name, string host, int port, bool password_protected, DMAP.Db db, DMAP.RecordFactory factory);
public virtual unowned Soup.Message build_message (string path, bool need_hash, double version, int req_id, bool send_close);
public void connect (DMAP.ConnectionCallback callback);
public void disconnect (DMAP.ConnectionCallback callback);
public bool @get (string path, bool need_hash, DMAP.ResponseHandler handler);
public unowned Soup.MessageHeaders get_headers (string uri);
public unowned GLib.SList get_playlists ();
public bool is_connected ();
public void setup ();
[NoAccessorMethod]
public void* base_uri { get; set; }
[NoAccessorMethod]
public int database_id { get; set; }
[NoAccessorMethod]
public void* db { get; construct; }
[NoAccessorMethod]
public double dmap_version { get; set; }
[NoAccessorMethod]
public void* factory { get; construct; }
[NoAccessorMethod]
public string host { owned get; construct; }
[NoAccessorMethod]
public string name { owned get; construct; }
[NoAccessorMethod]
public bool password_protected { get; construct; }
[NoAccessorMethod]
public uint port { get; construct; }
[NoAccessorMethod]
public int revision_number { get; set; }
[NoAccessorMethod]
public int session_id { get; set; }
public virtual signal unowned string authenticate (string name);
public virtual signal void connected ();
public virtual signal void connecting (ulong state, float progress);
public virtual signal void disconnected ();
public virtual signal void operation_done ();
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class DACPShare : DAAP.Share {
[CCode (cname = "dacp_share_new", type = "DACPShare*", has_construct_function = false)]
public DACPShare (string library_name, DMAP.DACPPlayer player, DMAP.Db db, DMAP.ContainerDb container_db);
[CCode (cname = "dacp_share_pair")]
public static void pair (DMAP.DACPShare share, string service_name, char[] passcode);
[CCode (cname = "dacp_share_player_updated")]
public static void player_updated (DMAP.DACPShare share);
[CCode (cname = "dacp_share_start_lookup")]
public static void start_lookup (DMAP.DACPShare share);
[CCode (cname = "dacp_share_stop_lookup")]
public static void stop_lookup (DMAP.DACPShare share);
[NoAccessorMethod]
public string library_name { owned get; set; }
[NoAccessorMethod]
public GLib.Object player { owned get; construct; }
public virtual signal void add_guid (string guid);
public virtual signal bool lookup_guid (string guid);
public virtual signal void remote_found (string service_name, string remote_name);
public virtual signal void remote_lost (string service_name);
public virtual signal void remote_paired (string service_name, bool connected);
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class DmapMdnsPublisher : GLib.Object {
[CCode (cname = "dmap_mdns_publisher_new", type = "DmapMdnsPublisher*", has_construct_function = false)]
public DmapMdnsPublisher ();
[CCode (cname = "dmap_mdns_publisher_error_quark")]
public static GLib.Quark error_quark ();
[CCode (cname = "dmap_mdns_publisher_publish")]
public static bool publish (DMAP.DmapMdnsPublisher publisher, string name, uint port, string type_of_service, bool password_required, string txt_records) throws GLib.Error;
[CCode (cname = "dmap_mdns_publisher_rename_at_port")]
public static bool rename_at_port (DMAP.DmapMdnsPublisher publisher, uint port, string name) throws GLib.Error;
[CCode (cname = "dmap_mdns_publisher_withdraw")]
public static bool withdraw (DMAP.DmapMdnsPublisher publisher, uint port) throws GLib.Error;
public virtual signal void name_collision (string name);
public virtual signal void published (string name);
}
[Compact]
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class FilterDefinition {
public weak string key;
public bool negate;
public weak string value;
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class MdnsBrowser : GLib.Object {
[CCode (has_construct_function = false)]
public MdnsBrowser (DMAP.MdnsBrowserServiceType type);
public static GLib.Quark error_quark ();
public DMAP.MdnsBrowserServiceType get_service_type ();
public unowned GLib.SList get_services ();
public bool start () throws GLib.Error;
public bool stop () throws GLib.Error;
public virtual signal void service_added (void* service);
public virtual signal void service_removed (string service);
}
[Compact]
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class MdnsBrowserService {
public weak string host;
public weak string name;
public weak string pair;
public bool password_protected;
public uint port;
public weak string service_name;
}
[Compact]
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class MetaDataMap {
}
[Compact]
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class Playlist {
public int id;
public weak string name;
public weak GLib.List uris;
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class Share : GLib.Object {
[CCode (has_construct_function = false)]
protected Share ();
[NoWrapper]
public virtual void add_entry_to_mlcl (void* id, DMAP.Record record, void* mb);
[NoWrapper]
public virtual void content_codes (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
[NoWrapper]
public virtual void ctrl_int (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
[NoWrapper]
public virtual void databases (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext context);
[NoWrapper]
public virtual void databases_browse_xxx (Soup.Server server, Soup.Message msg, string path, GLib.HashTable query, Soup.ClientContext context);
[NoWrapper]
public virtual void databases_items_xxx (Soup.Server server, Soup.Message msg, string path, GLib.HashTable query, Soup.ClientContext context);
public static void free_filter (GLib.SList filter);
[NoWrapper]
public virtual uint get_desired_port ();
[NoWrapper]
public virtual void* get_meta_data_map ();
[NoWrapper]
public virtual unowned string get_type_of_service ();
[NoWrapper]
public virtual void login (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
[NoWrapper]
public virtual void logout (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
[NoWrapper]
public virtual void message_add_standard_headers (Soup.Message msg);
[NoWrapper]
public virtual void name_collision (DMAP.DmapMdnsPublisher publisher, string name);
[NoWrapper]
public virtual void published (DMAP.DmapMdnsPublisher publisher, string name);
[NoWrapper]
public virtual void server_info (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
[NoWrapper]
public virtual void update (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
[NoAccessorMethod]
public uint auth_method { get; set; }
[NoAccessorMethod]
public void* container_db { get; construct; }
[NoAccessorMethod]
public void* db { get; construct; }
[NoAccessorMethod]
public string name { owned get; set; }
[NoAccessorMethod]
public string password { owned get; set; }
[NoAccessorMethod]
public uint revision_number { get; set; }
[NoAccessorMethod]
public Soup.Server server { owned get; }
[NoAccessorMethod]
public string transcode_mimetype { owned get; construct; }
[NoAccessorMethod]
[CCode (array_length = false, array_null_terminated = true)]
public string[] txt_records { owned get; set; }
}
[Compact]
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class bitwise {
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface ContainerDb {
public abstract int64 count ();
public abstract void @foreach (GLib.HFunc func, void* data);
public abstract unowned DMAP.ContainerRecord lookup_by_id (uint id);
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface ContainerRecord {
public abstract void add_entry (DMAP.Record record, int id);
public abstract unowned DMAP.Db get_entries ();
public abstract uint64 get_entry_count ();
public abstract uint get_id ();
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface DACPPlayer {
[CCode (cname = "dacp_player_cue_clear")]
public abstract void cue_clear (DMAP.DACPPlayer player);
[CCode (cname = "dacp_player_cue_play")]
public abstract void cue_play (DMAP.DACPPlayer player, GLib.List records, uint index);
[CCode (cname = "dacp_player_next_item")]
public abstract void next_item (DMAP.DACPPlayer player);
[CCode (cname = "dacp_player_now_playing_artwork")]
public abstract unowned string now_playing_artwork (DMAP.DACPPlayer player, uint width, uint height);
[CCode (cname = "dacp_player_now_playing_record")]
public abstract unowned DAAP.Record now_playing_record (DMAP.DACPPlayer player);
[CCode (cname = "dacp_player_pause")]
public abstract void pause (DMAP.DACPPlayer player);
[CCode (cname = "dacp_player_play_pause")]
public abstract void play_pause (DMAP.DACPPlayer player);
[CCode (cname = "dacp_player_prev_item")]
public abstract void prev_item (DMAP.DACPPlayer player);
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface Db {
public abstract uint add (DMAP.Record record);
public abstract uint add_path (string path);
public abstract uint add_with_id (DMAP.Record record, uint id);
public unowned GLib.HashTable apply_filter (GLib.SList filter_def);
public abstract int64 count ();
public abstract void @foreach (GLib.HFunc func);
public abstract unowned DMAP.Record lookup_by_id (uint id);
public abstract uint lookup_id_by_location (string location);
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface Record {
public abstract unowned DMAP.Record set_from_blob (GLib.ByteArray blob);
public abstract unowned GLib.ByteArray to_blob ();
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface RecordFactory {
public abstract DMAP.Record create (void* user_data);
}
[CCode (cprefix = "DMAP_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum ConnectionState {
GET_INFO,
GET_PASSWORD,
LOGIN,
GET_REVISION_NUMBER,
GET_DB_INFO,
GET_SONGS,
GET_PLAYLISTS,
GET_PLAYLIST_ENTRIES,
LOGOUT,
DONE
}
[CCode (cprefix = "PLAY_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum DACPPlayState {
STOPPED,
PAUSED,
PLAYING
}
[CCode (cprefix = "REPEAT_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum DACPRepeatState {
NONE,
SINGLE,
ALL
}
[CCode (cprefix = "DMAP_MDNS_PUBLISHER_ERROR_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum DmapMdnsPublisherError {
NOT_RUNNING,
FAILED
}
[CCode (cprefix = "DMAP_MDNS_BROWSER_ERROR_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum MdnsBrowserError {
NOT_RUNNING,
FAILED
}
[CCode (cprefix = "DMAP_MDNS_BROWSER_SERVICE_TYPE_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum MdnsBrowserServiceType {
INVALID,
DAAP,
DPAP,
DACP,
LAST
}
[CCode (cprefix = "DMAP_MEDIA_KIND_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
public enum MediaKind {
MUSIC,
MOVIE
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public delegate bool ConnectionCallback (DMAP.Connection connection, bool result, string reason);
[CCode (cheader_filename = "libdmapsharing/dmap.h", has_target = false)]
public delegate unowned string RecordGetValueFunc (DMAP.Record record);
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public delegate void ResponseHandler (DMAP.Connection connection, uint status, GLib.Node structure);
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public const int SHARE_CHUNK_SIZE;
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public const int STATUS_OK;
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public static void hash_generate (short version_major, uchar[] url, uchar hash_select, uchar[] @out, int request_id);
}
namespace DPAP {
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class Share : DMAP.Share {
[CCode (cname = "dpap_share_new", type = "DPAPShare*", has_construct_function = false)]
public Share (string name, string password, void* db, void* container_db, string transcode_mimetype);
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface Record {
[CCode (cname = "dpap_record_read")]
public abstract unowned GLib.InputStream read (DPAP.Record record) throws GLib.Error;
}
public class Connection : DMAP.Connection {
[CCode (has_construct_function = false)]
public Connection (string name, string host, int port, bool password_protected, DMAP.Db db, DMAP.RecordFactory factory);
}
}
namespace DAAP {
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public class Share : DMAP.Share {
[CCode (cname = "dpap_share_new", type = "DAAP.Share*", has_construct_function = false)]
public Share (string name, string password, void* db, void* container_db, string transcode_mimetype);
}
[CCode (cheader_filename = "libdmapsharing/dmap.h")]
public interface Record {
[CCode (cname = "daap_record_cmp_by_album")]
public static int cmp_by_album (void* a, void* b, DMAP.Db db);
[CCode (cname = "daap_record_itunes_compat")]
public abstract bool itunes_compat (DAAP.Record record);
[CCode (cname = "daap_record_read")]
public abstract unowned GLib.InputStream read (DAAP.Record record) throws GLib.Error;
}
public class Connection : DMAP.Connection {
[CCode (has_construct_function = false)]
public Connection (string name, string host, int port, bool password_protected, DMAP.Db db, DMAP.RecordFactory factory);
}
}
......@@ -4,6 +4,7 @@ BUILT_SOURCES = dmap-marshal.c dmap-marshal.h dmap-enums.c dmap-enums.h
libdmapsharing_la_SOURCES = \
$(BUILT_SOURCES) \
daap-connection.c \
daap-record.c \
daap-share.c \
dacp-share.c \
......@@ -17,6 +18,7 @@ libdmapsharing_la_SOURCES = \
dmap-record-factory.c \
dmap-share.c \
dmap-structure.c \
dpap-connection.c \
dpap-record.c \
dpap-share.c
......@@ -66,6 +68,7 @@ libdmapsharingincludedir = \
$(includedir)/libdmapsharing-@API_VERSION@/libdmapsharing
libdmapsharinginclude_HEADERS = \
daap-connection.h \
daap-record.h \
daap-share.h \
dacp-share.h \
......@@ -81,6 +84,7 @@ libdmapsharinginclude_HEADERS = \
dmap-record.h \
dmap-record-factory.h \
dmap-share.h \
dpap-connection.h \
dpap-record.h \
dpap-share.h
......
/*
* Copyright (C) 2004,2005 Charles Schmidt <cschmidt2@emich.edu>
* Copyright (C) 2006 INDT
* Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
*
* 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"
#include <libdmapsharing/daap-connection.h>
#include <libdmapsharing/dmap-structure.h>
#define DAAP_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DAAP_CONNECTION, DAAPConnectionPrivate))
/* FIXME:
struct DAAPConnectionPrivate {
};
*/
static DMAPContentCode
get_protocol_version_cc (DMAPConnection *connection)
{
return DMAP_CC_APRO;
}
static gchar *
get_query_metadata (void)
{
return g_strdup ("dmap.itemid,dmap.itemname,daap.songalbum,"
"daap.songartist,daap.songgenre,daap.songsize,"
"daap.songtime,daap.songtrackcount,daap.songtracknumber,"
"daap.songyear,daap.songformat,"
"daap.songbitrate,daap.songdiscnumber,daap.songdataurl,"
"daap.sortartist,daap.sortalbum");
}
static DMAPRecord *
handle_mlcl (DMAPConnection *connection, DMAPRecordFactory *factory, GNode *n, int *item_id)
{
GNode *n2;
DMAPRecord *record = NULL;
const gchar *title = NULL;
const gchar *album = NULL;
const gchar *artist = NULL;
const gchar *format = NULL;
const gchar *genre = NULL;
const gchar *streamURI = NULL;
const gchar *sort_artist = NULL;
const gchar *sort_album = NULL;
gint length = 0;
gint track_number = 0;
gint disc_number = 0;
gint year = 0;
gint size = 0;
gint bitrate = 0;
for (n2 = n->children; n2; n2 = n2->next) {
DMAPStructureItem *meta_item;
meta_item = n2->data;
switch (meta_item->content_code) {
case DMAP_CC_MIID:
*item_id = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_MINM:
title = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASAL:
album = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASAR:
artist = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASFM:
format = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASGN:
genre = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASTM:
length = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_ASTN:
track_number = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_ASDN:
disc_number = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_ASYR:
year = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_ASSZ:
size = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_ASBR:
bitrate = g_value_get_int (&(meta_item->content));
break;
case DMAP_CC_ASUL:
streamURI = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASSA:
sort_artist = g_value_get_string (&(meta_item->content));
break;
case DMAP_CC_ASSU:
sort_album = g_value_get_string (&(meta_item->content));
break;
default:
break;
}
}
record = dmap_record_factory_create (factory, NULL);
if (record == NULL) {
goto _return;
}
g_object_set (record,
"year", year,
"track", track_number,
"disc", disc_number,
"bitrate", bitrate,
"duration", length / 1000,
"filesize", (guint64) size,
"format", format,
"title", title,
"songalbum", album,
"songartist", artist,
"songgenre", genre,
"sort-artist", sort_artist,
"sort-album", sort_album,
NULL);
_return:
return record;
}
static void
daap_connection_class_init (DAAPConnectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
DMAPConnectionClass *parent_class = DMAP_CONNECTION_CLASS (object_class);
parent_class->get_protocol_version_cc = get_protocol_version_cc;
parent_class->get_query_metadata = get_query_metadata;
parent_class->handle_mlcl = handle_mlcl;
/* FIXME:
g_type_class_add_private (klass, sizeof (DAAPConnectionPrivate));
*/
}
DAAPConnection *
daap_connection_new (const char *name,
const char *host,
int port,
gboolean password_protected,
DMAPDb *db,
DMAPRecordFactory *factory)
{
DAAPConnection *connection;
connection = g_object_new (TYPE_DAAP_CONNECTION,
"name", name,
"password-protected", password_protected,
"db", db,
"host", host,
"port", port,
"factory", factory,
NULL);
return connection;
}
static void
daap_connection_init (DAAPConnection *connection)
{
/* FIXME:
connection->priv = DAAP_CONNECTION_GET_PRIVATE (connection);
*/
}
G_DEFINE_TYPE (DAAPConnection, daap_connection, TYPE_DMAP_CONNECTION)
/*
* 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 __DAAP_CONNECTION_H
#define __DAAP_CONNECTION_H
#include <glib-object.h>
#include <libdmapsharing/dmap-connection.h>
#include <libdmapsharing/dmap-db.h>
G_BEGIN_DECLS
/**
* TYPE_DAAP_CONNECTION:
*
* The type for #DAAPConnection.