diff --git a/src/Makefile.am b/src/Makefile.am index 666d48fa2..e5770e7be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -84,11 +84,12 @@ client/pv-enumtypes.c: $(enumtypesincludes) client/pv-enumtypes.h dbus/org-pulsevideo.c: dbus/org-pulsevideo.h dbus/org-pulsevideo.h: dbus/org.pulsevideo.xml $(AM_V_GEN) $(GDBUS_CODEGEN) \ - --c-generate-object-manager \ --interface-prefix org.pulsevideo. \ --generate-c-code dbus/org-pulsevideo \ --generate-docbook ../doc/org-pulsevideo \ - --c-namespace Pv dbus/org.pulsevideo.xml + --c-namespace Pv dbus/org.pulsevideo.xml \ + --c-generate-object-manager + built_header_make = client/pv-enumtypes.h dbus/org-pulsevideo.h built_source_make = client/pv-enumtypes.c dbus/org-pulsevideo.c @@ -192,6 +193,7 @@ lib_LTLIBRARIES += libpulsevideocore-@PV_MAJORMINOR@.la # Pure core stuff libpulsevideocore_@PV_MAJORMINOR@_la_SOURCES = \ server/pv-client.c server/pv-client.h \ + server/pv-source-provider.c server/pv-source-provider.h \ server/pv-daemon.c server/pv-daemon.h \ modules/v4l2/pv-v4l2-source.c diff --git a/src/client/pv-source.c b/src/client/pv-source.c index 8adb0ea78..7071372dc 100644 --- a/src/client/pv-source.c +++ b/src/client/pv-source.c @@ -92,6 +92,28 @@ pv_source_set_property (GObject *_object, break; } } + +static gboolean +handle_create_source_output (PvSource1 *interface, + GDBusMethodInvocation *invocation, + GVariant *arg_properties, + gpointer user_data) +{ + PvSource *source = user_data; + PvSourcePrivate *priv = source->priv; + PvSourceOutput *output; + const gchar *object_path; + + output = pv_source_create_source_output (source, arg_properties, priv->object_path); + + object_path = pv_source_output_get_object_path (output); + + pv_source1_complete_create_source_output (interface, + invocation, + object_path); + return TRUE; +} + static void source_register_object (PvSource *source) { @@ -103,6 +125,7 @@ source_register_object (PvSource *source) PvSource1 *iface; iface = pv_source1_skeleton_new (); + g_signal_connect (iface, "handle-create-source-output", (GCallback) handle_create_source_output, source); g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface)); g_object_unref (iface); } diff --git a/src/client/pv-stream.c b/src/client/pv-stream.c index f93e4d1ac..bae71c38c 100644 --- a/src/client/pv-stream.c +++ b/src/client/pv-stream.c @@ -327,6 +327,8 @@ on_source_output_created (GObject *source_object, &priv->source_output_sender, &priv->source_output_path, res, &error)) goto create_failed; + g_print ("got source-output %s %s\n", priv->source_output_sender, priv->source_output_path); + pv_source_output1_proxy_new (pv_context_get_connection (context), G_DBUS_PROXY_FLAGS_NONE, priv->source_output_sender, diff --git a/src/client/pv-subscribe.c b/src/client/pv-subscribe.c index 963a07768..c7ae06f6e 100644 --- a/src/client/pv-subscribe.c +++ b/src/client/pv-subscribe.c @@ -68,19 +68,19 @@ notify_subscription (PvSubscribe *subscribe, if ((interface == NULL && pv_object_peek_client1 (PV_OBJECT (object))) || PV_IS_CLIENT1_PROXY (interface)) g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event, - PV_SUBSCRIPTION_FLAGS_CLIENT, g_dbus_object_get_object_path (object)); + PV_SUBSCRIPTION_FLAGS_CLIENT, object); } if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE) { if ((interface == NULL && pv_object_peek_source1 (PV_OBJECT (object))) || PV_IS_SOURCE1_PROXY (interface)) g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event, - PV_SUBSCRIPTION_FLAGS_SOURCE, g_dbus_object_get_object_path (object)); + PV_SUBSCRIPTION_FLAGS_SOURCE, object); } if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT) { if ((interface == NULL && pv_object_peek_source_output1 (PV_OBJECT (object))) || PV_IS_SOURCE_OUTPUT1_PROXY (interface)) g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event, - PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT, g_dbus_object_get_object_path (object)); + PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT, object); } } @@ -359,7 +359,7 @@ pv_subscribe_class_init (PvSubscribeClass * klass) 3, PV_TYPE_SUBSCRIPTION_EVENT, PV_TYPE_SUBSCRIPTION_FLAGS, - G_TYPE_STRING); + G_TYPE_DBUS_OBJECT_PROXY); } static void diff --git a/src/client/pv-subscribe.h b/src/client/pv-subscribe.h index f49e8704d..c74025c0c 100644 --- a/src/client/pv-subscribe.h +++ b/src/client/pv-subscribe.h @@ -41,10 +41,10 @@ typedef enum { PV_SUBSCRIPTION_FLAGS_CLIENT = (1 << 0), PV_SUBSCRIPTION_FLAGS_SOURCE = (1 << 1), PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT = (1 << 2), - - PV_SUBSCRIPTION_FLAGS_ALL = 0xf } PvSubscriptionFlags; +#define PV_SUBSCRIPTION_FLAGS_ALL 0x3 + typedef enum { PV_SUBSCRIPTION_EVENT_NEW = 0, PV_SUBSCRIPTION_EVENT_CHANGE = 1, diff --git a/src/dbus/org.pulsevideo.xml b/src/dbus/org.pulsevideo.xml index 5fe67c8aa..bd17635c5 100644 --- a/src/dbus/org.pulsevideo.xml +++ b/src/dbus/org.pulsevideo.xml @@ -35,14 +35,16 @@ - - - + + + + + @@ -52,7 +54,6 @@ - diff --git a/src/modules/v4l2/pv-v4l2-source.c b/src/modules/v4l2/pv-v4l2-source.c index 8472cab40..0348dfb5f 100644 --- a/src/modules/v4l2/pv-v4l2-source.c +++ b/src/modules/v4l2/pv-v4l2-source.c @@ -40,7 +40,7 @@ setup_pipeline (PvV4l2Source *source) { PvV4l2SourcePrivate *priv = source->priv; - priv->pipeline = gst_parse_launch ("v4l2src ! video/x-raw,width=320,height=240,framerate=30/1 ! " + priv->pipeline = gst_parse_launch ("v4l2src ! video/x-raw,width=640,height=480,framerate=30/1 ! " "pvfdpay ! multisocketsink buffers-max=2 buffers-soft-max=1 " "recover-policy=latest sync-method=latest name=sink sync=true " "enable-last-sample=false", NULL); diff --git a/src/server/pv-client.c b/src/server/pv-client.c index b456401fa..437665ed5 100644 --- a/src/server/pv-client.c +++ b/src/server/pv-client.c @@ -32,7 +32,7 @@ struct _PvClientPrivate PvDaemon *daemon; gchar *object_path; - PvSource *source; + PvClient1 *client1; GHashTable *source_outputs; }; @@ -97,6 +97,46 @@ pv_client_set_property (GObject *_object, } } +typedef struct { + PvClient *client; + GDBusMethodInvocation *invocation; +} CreateData; + +static void +on_source_output_created (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + CreateData *data = user_data; + PvClient *client = data->client; + PvClientPrivate *priv = client->priv; + PvSource1 *source1 = PV_SOURCE1 (source_object); + GDBusMethodInvocation *invocation = data->invocation; + GError *error = NULL; + gchar *object_path, *name; + + if (!pv_source1_call_create_source_output_finish (source1, &object_path, res, &error)) + goto create_failed; + + name = g_object_get_data (G_OBJECT (source1), "org.pulsevideo.name"); + pv_client1_complete_create_source_output (priv->client1, invocation, name, object_path); + g_free (name); + + g_free (data); + + return; + + /* ERRORS */ +create_failed: + { + g_print ("failed to get connect capture: %s", error->message); + g_clear_error (&error); + g_free (data); + return; + } +} + + static gboolean handle_create_source_output (PvClient1 *interface, GDBusMethodInvocation *invocation, @@ -107,18 +147,30 @@ handle_create_source_output (PvClient1 *interface, PvClient *client = user_data; PvClientPrivate *priv = client->priv; PvDaemon *daemon = priv->daemon; - PvSource *source; - PvSourceOutput *output; - const gchar *object_path; + PvSource1 *source1; + GVariantBuilder builder; + CreateData *data; - source = pv_daemon_get_source (daemon, arg_source); + source1 = pv_daemon_get_source (daemon, arg_source); + if (source1 == NULL) { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.pulsevideo.NotFound", + "No source found"); + return TRUE; + } - output = pv_source_create_source_output (source, NULL, priv->object_path); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string ("hello")); - object_path = pv_source_output_get_object_path (output); - g_hash_table_insert (priv->source_outputs, g_strdup (object_path), output); + data = g_new0 (CreateData, 1); + data->client = client; + data->invocation = invocation; - pv_client1_complete_create_source_output (interface, invocation, PV_DBUS_SERVICE, object_path); + pv_source1_call_create_source_output (source1, + g_variant_builder_end (&builder), + NULL, + on_source_output_created, + data); return TRUE; } @@ -135,15 +187,10 @@ client_register_object (PvClient *client, const gchar *prefix) skel = g_dbus_object_skeleton_new (name); g_free (name); - { - PvClient1 *iface; - - iface = pv_client1_skeleton_new (); - pv_client1_set_name (iface, "poppy"); - g_signal_connect (iface, "handle-create-source-output", (GCallback) handle_create_source_output, client); - g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface)); - g_object_unref (iface); - } + priv->client1 = pv_client1_skeleton_new (); + pv_client1_set_name (priv->client1, "poppy"); + g_signal_connect (priv->client1, "handle-create-source-output", (GCallback) handle_create_source_output, client); + g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (priv->client1)); g_free (priv->object_path); priv->object_path = pv_daemon_export_uniquely (daemon, skel); @@ -156,7 +203,7 @@ client_unregister_object (PvClient *client) PvDaemon *daemon = priv->daemon; g_hash_table_unref (priv->source_outputs); - g_clear_object (&priv->source); + g_clear_object (&priv->client1); pv_daemon_unexport (daemon, priv->object_path); g_free (priv->object_path); diff --git a/src/server/pv-daemon.c b/src/server/pv-daemon.c index b63f88914..946059d31 100644 --- a/src/server/pv-daemon.c +++ b/src/server/pv-daemon.c @@ -23,6 +23,7 @@ #include "server/pv-daemon.h" #include "server/pv-client.h" +#include "server/pv-source-provider.h" #include "modules/v4l2/pv-v4l2-source.h" #include "dbus/org-pulsevideo.h" @@ -36,7 +37,7 @@ struct _PvDaemonPrivate GDBusObjectManagerServer *server_manager; GHashTable *senders; - PvSource *source; + GList *sources; }; typedef struct { @@ -46,14 +47,74 @@ typedef struct { GHashTable *clients; PvSubscribe *subscribe; + + GHashTable *sources; } SenderData; +static void +on_subscription_event (PvSubscribe *subscribe, + PvSubscriptionEvent event, + PvSubscriptionFlags flags, + GDBusObjectProxy *object, + gpointer user_data) +{ + SenderData *data = user_data; + PvDaemon *daemon = data->daemon; + PvDaemonPrivate *priv = daemon->priv; + const gchar *object_path; + PvSource1 *source1; + + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); + + g_print ("got event %d %d %s.%s\n", event, flags, data->sender, object_path); + + if (flags != PV_SUBSCRIPTION_FLAGS_SOURCE) + return; + + source1 = pv_object_peek_source1 (PV_OBJECT (object)); + + switch (event) { + case PV_SUBSCRIPTION_EVENT_NEW: + { + g_object_set_data (G_OBJECT (source1), "org.pulsevideo.name", data->sender); + + g_hash_table_insert (data->sources, g_strdup (object_path), source1); + priv->sources = g_list_prepend (priv->sources, source1); + break; + } + + case PV_SUBSCRIPTION_EVENT_CHANGE: + break; + + case PV_SUBSCRIPTION_EVENT_REMOVE: + { + priv->sources = g_list_remove (priv->sources, source1); + g_hash_table_remove (data->sources, object_path); + break; + } + } +} + static void client_name_appeared_handler (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { + SenderData *data = user_data; + + /* subscribe to Source events. We want to be notified when this new + * sender add/change/remove sources */ + data->subscribe = pv_subscribe_new (); + g_object_set (data->subscribe, "service", data->sender, + "subscription-mask", PV_SUBSCRIPTION_FLAGS_SOURCE, + "connection", connection, + NULL); + + g_signal_connect (data->subscribe, + "subscription-event", + (GCallback) on_subscription_event, + data); } static void @@ -66,22 +127,16 @@ client_name_vanished_handler (GDBusConnection *connection, g_print ("vanished client %s\n", name); - g_hash_table_unref (data->clients); g_hash_table_remove (priv->senders, data->sender); + + g_hash_table_unref (data->clients); + g_hash_table_unref (data->sources); + g_object_unref (data->subscribe); g_free (data->sender); g_bus_unwatch_name (data->id); g_free (data); } -static void -on_subscription_event (PvSubscribe *subscribe, - PvSubscriptionEvent event, - PvSubscriptionFlags flags, - const gchar *object_path) -{ - g_print ("got event %d %d %s\n", event, flags, object_path); -} - static SenderData * sender_data_new (PvDaemon *daemon, const gchar *sender) { @@ -92,6 +147,7 @@ sender_data_new (PvDaemon *daemon, const gchar *sender) data->daemon = daemon; data->sender = g_strdup (sender); data->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + data->sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); data->id = g_bus_watch_name_on_connection (priv->connection, sender, @@ -101,16 +157,6 @@ sender_data_new (PvDaemon *daemon, const gchar *sender) data, NULL); - data->subscribe = pv_subscribe_new (); - g_object_set (data->subscribe, "service", sender, - "subscription-mask", PV_SUBSCRIPTION_FLAGS_SOURCE, - "connection", priv->connection, - NULL); - g_signal_connect (data->subscribe, - "subscription-event", - (GCallback) on_subscription_event, - data); - g_hash_table_insert (priv->senders, data->sender, data); return data; @@ -288,19 +334,21 @@ pv_daemon_unexport (PvDaemon *daemon, const gchar *object_path) g_dbus_object_manager_server_unexport (daemon->priv->server_manager, object_path); } -PvSource * +PvSource1 * pv_daemon_get_source (PvDaemon *daemon, const gchar *name) { PvDaemonPrivate *priv; + PvSource1 *source; g_return_val_if_fail (PV_IS_DAEMON (daemon), NULL); priv = daemon->priv; - if (priv->source == NULL) { - priv->source = pv_v4l2_source_new (); - pv_source_set_manager (priv->source, priv->server_manager); - } - return priv->source; + if (priv->sources == NULL) + return NULL; + + source = priv->sources->data; + + return source; } G_DEFINE_TYPE (PvDaemon, pv_daemon, G_TYPE_OBJECT); diff --git a/src/server/pv-daemon.h b/src/server/pv-daemon.h index 34a3e2550..4eddcb28b 100644 --- a/src/server/pv-daemon.h +++ b/src/server/pv-daemon.h @@ -23,6 +23,8 @@ #include #include +#include "dbus/org-pulsevideo.h" + G_BEGIN_DECLS #define PV_TYPE_DAEMON (pv_daemon_get_type ()) @@ -38,7 +40,8 @@ typedef struct _PvDaemon PvDaemon; typedef struct _PvDaemonClass PvDaemonClass; typedef struct _PvDaemonPrivate PvDaemonPrivate; -#include "client/pv-source.h" +#include +#include /** * PvDaemon: @@ -61,17 +64,17 @@ struct _PvDaemonClass { }; /* normal GObject stuff */ -GType pv_daemon_get_type (void); +GType pv_daemon_get_type (void); -PvDaemon * pv_daemon_new (void); +PvDaemon * pv_daemon_new (void); -void pv_daemon_start (PvDaemon *daemon); -void pv_daemon_stop (PvDaemon *daemon); +void pv_daemon_start (PvDaemon *daemon); +void pv_daemon_stop (PvDaemon *daemon); -gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel); -void pv_daemon_unexport (PvDaemon *daemon, const gchar *name); +gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel); +void pv_daemon_unexport (PvDaemon *daemon, const gchar *name); -PvSource * pv_daemon_get_source (PvDaemon *daemon, const gchar *name); +PvSource1 * pv_daemon_get_source (PvDaemon *daemon, const gchar *name); G_END_DECLS diff --git a/src/server/pv-source-provider.c b/src/server/pv-source-provider.c new file mode 100644 index 000000000..0c3fbc0ae --- /dev/null +++ b/src/server/pv-source-provider.c @@ -0,0 +1,261 @@ +/* Pulsevideo + * Copyright (C) 2015 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 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 Library 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 "server/pv-source-provider.h" + +#include "dbus/org-pulsevideo.h" + +struct _PvSourceProviderPrivate +{ + PvDaemon *daemon; + gchar *object_path; + + gchar *name; + gchar *path; +}; + +#define PV_SOURCE_PROVIDER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PV_TYPE_SOURCE_PROVIDER, PvSourceProviderPrivate)) + +G_DEFINE_TYPE (PvSourceProvider, pv_source_provider, G_TYPE_OBJECT); + +enum +{ + PROP_0, + PROP_DAEMON, + PROP_OBJECT_PATH, + PROP_NAME, + PROP_PATH, +}; + +static void +pv_source_provider_get_property (GObject *_object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PvSourceProvider *client = PV_SOURCE_PROVIDER (_object); + PvSourceProviderPrivate *priv = client->priv; + + switch (prop_id) { + case PROP_DAEMON: + g_value_set_object (value, priv->daemon); + break; + + case PROP_OBJECT_PATH: + g_value_set_string (value, priv->object_path); + break; + + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + + case PROP_PATH: + g_value_set_string (value, priv->path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (client, prop_id, pspec); + break; + } +} + +static void +pv_source_provider_set_property (GObject *_object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PvSourceProvider *client = PV_SOURCE_PROVIDER (_object); + PvSourceProviderPrivate *priv = client->priv; + + switch (prop_id) { + case PROP_DAEMON: + priv->daemon = g_value_dup_object (value); + break; + + case PROP_OBJECT_PATH: + priv->object_path = g_value_dup_string (value); + break; + + case PROP_NAME: + priv->name = g_value_dup_string (value); + break; + + case PROP_PATH: + priv->path = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (client, prop_id, pspec); + break; + } +} + +static void +source_provider_register_object (PvSourceProvider *client, const gchar *prefix) +{ + PvSourceProviderPrivate *priv = client->priv; + PvDaemon *daemon = priv->daemon; + GDBusObjectSkeleton *skel; + gchar *name; + + name = g_strdup_printf ("%s/source", prefix); + skel = g_dbus_object_skeleton_new (name); + g_free (name); + + { + PvSourceProvider1 *iface; + + iface = pv_source_provider1_skeleton_new (); + g_object_set (iface, "name", priv->name, NULL); + g_object_set (iface, "path", priv->path, NULL); + g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface)); + g_object_unref (iface); + } + + g_free (priv->object_path); + priv->object_path = pv_daemon_export_uniquely (daemon, skel); +} + +static void +source_provider_unregister_object (PvSourceProvider *client) +{ + PvSourceProviderPrivate *priv = client->priv; + PvDaemon *daemon = priv->daemon; + + pv_daemon_unexport (daemon, priv->object_path); + g_free (priv->object_path); +} + +static void +pv_source_provider_finalize (GObject * object) +{ + PvSourceProvider *client = PV_SOURCE_PROVIDER (object); + PvSourceProviderPrivate *priv = client->priv; + + source_provider_unregister_object (client); + + g_free (priv->name); + g_free (priv->path); + + G_OBJECT_CLASS (pv_source_provider_parent_class)->finalize (object); +} + +static void +pv_source_provider_constructed (GObject * object) +{ + PvSourceProvider *client = PV_SOURCE_PROVIDER (object); + PvSourceProviderPrivate *priv = client->priv; + + source_provider_register_object (client, priv->object_path); + + G_OBJECT_CLASS (pv_source_provider_parent_class)->constructed (object); +} + +static void +pv_source_provider_class_init (PvSourceProviderClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (PvSourceProviderPrivate)); + + gobject_class->finalize = pv_source_provider_finalize; + gobject_class->set_property = pv_source_provider_set_property; + gobject_class->get_property = pv_source_provider_get_property; + gobject_class->constructed = pv_source_provider_constructed; + + g_object_class_install_property (gobject_class, + PROP_DAEMON, + g_param_spec_object ("daemon", + "Daemon", + "The daemon", + PV_TYPE_DAEMON, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_OBJECT_PATH, + g_param_spec_string ("object-path", + "Object Path", + "The object path", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "The name of the owner", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_PATH, + g_param_spec_string ("path", + "Path", + "The path", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +pv_source_provider_init (PvSourceProvider * client) +{ + client->priv = PV_SOURCE_PROVIDER_GET_PRIVATE (client); +} + + +/** + * pv_source_provider_new: + * + * Make a new unconnected #PvSourceProvider + * + * Returns: a new #PvSourceProvider + */ +PvSourceProvider * +pv_source_provider_new (PvDaemon *daemon, + const gchar *prefix, + const gchar *name, + const gchar *path) +{ + g_return_val_if_fail (PV_IS_DAEMON (daemon), NULL); + g_return_val_if_fail (g_variant_is_object_path (prefix), NULL); + + return g_object_new (PV_TYPE_SOURCE_PROVIDER, "daemon", daemon, "object-path", prefix, + "name", name, "path", path, NULL); +} + +const gchar * +pv_source_provider_get_object_path (PvSourceProvider *client) +{ + PvSourceProviderPrivate *priv; + + g_return_val_if_fail (PV_IS_SOURCE_PROVIDER (client), NULL); + priv = client->priv; + + return priv->object_path; +} + diff --git a/src/server/pv-source-provider.h b/src/server/pv-source-provider.h new file mode 100644 index 000000000..17c6e9fe6 --- /dev/null +++ b/src/server/pv-source-provider.h @@ -0,0 +1,74 @@ +/* Pulsevideo + * Copyright (C) 2015 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 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 Library 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 __PV_SOURCE_PROVIDER_H__ +#define __PV_SOURCE_PROVIDER_H__ + +#include + +G_BEGIN_DECLS + +#define PV_TYPE_SOURCE_PROVIDER (pv_source_provider_get_type ()) +#define PV_IS_SOURCE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PV_TYPE_SOURCE_PROVIDER)) +#define PV_IS_SOURCE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PV_TYPE_SOURCE_PROVIDER)) +#define PV_SOURCE_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PV_TYPE_SOURCE_PROVIDER, PvSourceProviderClass)) +#define PV_SOURCE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PV_TYPE_SOURCE_PROVIDER, PvSourceProvider)) +#define PV_SOURCE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PV_TYPE_SOURCE_PROVIDER, PvSourceProviderClass)) +#define PV_SOURCE_PROVIDER_CAST(obj) ((PvSourceProvider*)(obj)) +#define PV_SOURCE_PROVIDER_CLASS_CAST(klass) ((PvSourceProviderClass*)(klass)) + +typedef struct _PvSourceProvider PvSourceProvider; +typedef struct _PvSourceProviderClass PvSourceProviderClass; +typedef struct _PvSourceProviderPrivate PvSourceProviderPrivate; + +#include "pv-daemon.h" + + +/** + * PvSourceProvider: + * + * Pulsevideo source provider object class. + */ +struct _PvSourceProvider { + GObject object; + + PvSourceProviderPrivate *priv; +}; + +/** + * PvSourceProviderClass: + * + * Pulsevideo source provider object class. + */ +struct _PvSourceProviderClass { + GObjectClass parent_class; +}; + +/* normal GObject stuff */ +GType pv_source_provider_get_type (void); + +PvSourceProvider * pv_source_provider_new (PvDaemon *daemon, const gchar *prefix, + const gchar *name, const gchar *path); + +const gchar * pv_source_provider_get_object_path (PvSourceProvider *client); + +G_END_DECLS + +#endif /* __PV_SOURCE_PROVIDER_H__ */ + diff --git a/src/tests/test-client.c b/src/tests/test-client.c index 98da7f0a2..f9d710ac0 100644 --- a/src/tests/test-client.c +++ b/src/tests/test-client.c @@ -22,7 +22,7 @@ #include -#define CAPS "video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1" +#define CAPS "video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1" static GMainLoop *loop; diff --git a/src/tests/test-subscribe.c b/src/tests/test-subscribe.c index ecd1be626..c0c3e328f 100644 --- a/src/tests/test-subscribe.c +++ b/src/tests/test-subscribe.c @@ -25,9 +25,9 @@ static GMainLoop *loop; static void subscription_cb (PvContext *context, PvSubscriptionEvent type, PvSubscriptionFlags flags, - const gchar *object_path, gpointer user_data) + GDBusObject *object, gpointer user_data) { - g_print ("got event %d %d %s\n", type, flags, object_path); + g_print ("got event %d %d %s\n", type, flags, g_dbus_object_get_object_path (object)); } static void