pidgin/pidgin

Remove the media API

5 weeks ago, Gary Kramlich
a97f73db61d0
Parents effcb245f840
Children d823c3372e97
Remove the media API

This needs to be redesigned and rewritten and keeping it around is only slowing
things down so removing it is the best course of action until the new API is
implemented.

Testing Done:
Called in the turtles.

Reviewed at https://reviews.imfreedom.org/r/3175/
--- a/libpurple/core.c Thu May 09 21:21:24 2024 -0500
+++ b/libpurple/core.c Thu May 09 21:27:08 2024 -0500
@@ -234,7 +234,6 @@
purple_plugins_uninit();
/* after plugins */
- purple_media_manager_shutdown();
purple_contact_manager_shutdown();
purple_account_manager_shutdown();
purple_credential_manager_shutdown();
--- a/libpurple/media-gst.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_GST_H
-#define PURPLE_MEDIA_GST_H
-
-#include "media.h"
-#include "mediamanager.h"
-#include "purpleversion.h"
-
-#include <gst/gst.h>
-
-#define PURPLE_TYPE_MEDIA_ELEMENT_TYPE purple_media_element_type_get_type()
-
-#define PURPLE_TYPE_MEDIA_ELEMENT_INFO purple_media_element_info_get_type()
-
-/**
- * PurpleMediaElementInfo:
- *
- * An opaque structure representing an audio/video source/sink.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef struct _PurpleMediaElementInfo PurpleMediaElementInfo;
-
-/**
- * PurpleMediaElementCreateCallback:
- * @info: The element.
- * @media: The media.
- * @session_id: The session id.
- * @participant: The participant.
- *
- * A callback that creates a GstElement for the given parameters.
- *
- * Returns: (transfer full): The new element.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef GstElement *(*PurpleMediaElementCreateCallback)(
- PurpleMediaElementInfo *info, PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-/**
- * PurpleMediaElementType:
- * @PURPLE_MEDIA_ELEMENT_NONE: empty element
- * @PURPLE_MEDIA_ELEMENT_AUDIO: supports audio
- * @PURPLE_MEDIA_ELEMENT_VIDEO: supports video
- * @PURPLE_MEDIA_ELEMENT_AUDIO_VIDEO: supports audio and video
- * @PURPLE_MEDIA_ELEMENT_NO_SRCS: has no src pads
- * @PURPLE_MEDIA_ELEMENT_ONE_SRC: has one src pad
- * @PURPLE_MEDIA_ELEMENT_MULTI_SRC: has multiple src pads
- * @PURPLE_MEDIA_ELEMENT_REQUEST_SRC: src pads must be requested
- * @PURPLE_MEDIA_ELEMENT_NO_SINKS: has no sink pads
- * @PURPLE_MEDIA_ELEMENT_ONE_SINK: has one sink pad
- * @PURPLE_MEDIA_ELEMENT_MULTI_SINK: has multiple sink pads
- * @PURPLE_MEDIA_ELEMENT_REQUEST_SINK: sink pads must be requested
- * @PURPLE_MEDIA_ELEMENT_UNIQUE: This element is unique and only one
- * instance of it should be created at a
- * time
- * @PURPLE_MEDIA_ELEMENT_SRC: can be set as an active src
- * @PURPLE_MEDIA_ELEMENT_SINK: can be set as an active sink
- * @PURPLE_MEDIA_ELEMENT_APPLICATION: supports application data
- *
- * The possible types of media elements.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_ELEMENT_NONE = 0,
- PURPLE_MEDIA_ELEMENT_AUDIO = 1,
- PURPLE_MEDIA_ELEMENT_VIDEO = 1 << 1,
- PURPLE_MEDIA_ELEMENT_AUDIO_VIDEO = PURPLE_MEDIA_ELEMENT_AUDIO
- | PURPLE_MEDIA_ELEMENT_VIDEO,
- PURPLE_MEDIA_ELEMENT_NO_SRCS = 0,
- PURPLE_MEDIA_ELEMENT_ONE_SRC = 1 << 2,
- PURPLE_MEDIA_ELEMENT_MULTI_SRC = 1 << 3,
- PURPLE_MEDIA_ELEMENT_REQUEST_SRC = 1 << 4,
- PURPLE_MEDIA_ELEMENT_NO_SINKS = 0,
- PURPLE_MEDIA_ELEMENT_ONE_SINK = 1 << 5,
- PURPLE_MEDIA_ELEMENT_MULTI_SINK = 1 << 6,
- PURPLE_MEDIA_ELEMENT_REQUEST_SINK = 1 << 7,
- PURPLE_MEDIA_ELEMENT_UNIQUE = 1 << 8,
- PURPLE_MEDIA_ELEMENT_SRC = 1 << 9,
- PURPLE_MEDIA_ELEMENT_SINK = 1 << 10,
- PURPLE_MEDIA_ELEMENT_APPLICATION = 1 << 11,
-} PurpleMediaElementType;
-
-G_BEGIN_DECLS
-
-PURPLE_AVAILABLE_IN_2_6
-GType purple_media_element_type_get_type(void);
-
-PURPLE_AVAILABLE_IN_2_6
-G_DECLARE_FINAL_TYPE(PurpleMediaElementInfo, purple_media_element_info, PURPLE,
- MEDIA_ELEMENT_INFO, GObject)
-
-/**
- * purple_media_get_src:
- * @media: The media object the session is in.
- * @sess_id: The session id of the session to get the source from.
- *
- * Gets the source from a session
- *
- * Returns: (transfer none): The source retrieved.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GstElement *purple_media_get_src(PurpleMedia *media, const gchar *sess_id);
-
-/**
- * purple_media_get_tee:
- * @media: The instance to get the tee from.
- * @session_id: The id of the session to get the tee from.
- * @participant: Optionally, the participant of the stream to get the tee from.
- *
- * Gets the tee from a given session/stream.
- *
- * Returns: (transfer none): The GstTee element from the chosen session/stream.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GstElement *purple_media_get_tee(PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-
-/**
- * purple_media_manager_get_pipeline:
- * @manager: The media manager to get the pipeline from.
- *
- * Gets the pipeline from the media manager.
- *
- * Returns: (transfer none): The pipeline.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GstElement *purple_media_manager_get_pipeline(PurpleMediaManager *manager);
-
-/**
- * purple_media_manager_get_element:
- * @manager: The media manager to use to obtain the source/sink.
- * @type: The type of source/sink to get.
- * @media: The media call this element is requested for.
- * @session_id: The id of the session this element is requested for or NULL.
- * @participant: The remote user this element is requested for or NULL.
- *
- * Gets the media element for the given session.
- *
- * Returns: (transfer full): A GStreamer source or sink for audio or video.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GstElement *purple_media_manager_get_element(PurpleMediaManager *manager,
- PurpleMediaSessionType type, PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-/**
- * purple_media_manager_enumerate_elements:
- * @manager: The media manager to use to obtain the element infos.
- * @type: The type of element infos to get.
- *
- * Enumerates the elements in @manager filtered by @type.
- *
- * Returns: (transfer container) (element-type PurpleMediaElementInfo): A #GList of registered #PurpleMediaElementInfo instances that match
- * @type.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-GList *purple_media_manager_enumerate_elements(PurpleMediaManager *manager, PurpleMediaElementType type);
-
-/**
- * purple_media_manager_get_element_info:
- * @manager: The #PurpleMediaManager instance
- * @name: The name of the element to get.
- *
- * Gets the element info for the element named @name in @manager.
- *
- * Returns: (transfer full): The #PurpleMediaElementInfo for @name or NULL.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaElementInfo *purple_media_manager_get_element_info(
- PurpleMediaManager *manager, const gchar *name);
-
-/**
- * purple_media_manager_register_element:
- * @manager: The instance.
- * @info: THe new element to register.
- *
- * Registers @info with @manager.
- *
- * Returns: %TRUE if successful, otherwise %FALSE.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_manager_register_element(PurpleMediaManager *manager,
- PurpleMediaElementInfo *info);
-
-/**
- * purple_media_manager_unregister_element:
- * @manager: The instance.
- * @name: The name of the element to unregister.
- *
- * Unregisters the elemented named @name from @manager.
- *
- * Returns: %TRUE if the element was found and removed, otherwise %FALSE.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_manager_unregister_element(PurpleMediaManager *manager,
- const gchar *name);
-
-/**
- * purple_media_manager_set_active_element:
- * @manager: The instance.
- * @info: The new element to activate.
- *
- * Attempts to activate @info as the active element.
- *
- * Returns: %TRUE if successful, otherwise %FALSE.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_manager_set_active_element(PurpleMediaManager *manager,
- PurpleMediaElementInfo *info);
-
-/**
- * purple_media_manager_get_active_element:
- * @manager: The #PurpleMediaManager instance
- * @type: The #PurpleMediaElementType who's info to get
- *
- * Gets the element that is currently active.
- *
- * Returns: (transfer none): The #PurpleMediaElementInfo for @type.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaElementInfo *purple_media_manager_get_active_element(
- PurpleMediaManager *manager, PurpleMediaElementType type);
-
-/**
- * purple_media_manager_set_video_caps:
- * @manager: The media manager to set the media formats.
- * @caps: Set of allowed media formats.
- *
- * Reduces media formats supported by the video source to given set.
- *
- * Useful to force negotiation of smaller picture resolution more suitable for
- * use with particular codec and communication protocol without rescaling.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-void purple_media_manager_set_video_caps(PurpleMediaManager *manager,
- GstCaps *caps);
-
-/**
- * purple_media_manager_get_video_caps:
- * @manager: The media manager to get the media formats from.
- *
- * Returns current set of media formats limiting the output from video source.
- *
- * Returns: GstCaps limiting the video source's formats.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-GstCaps *purple_media_manager_get_video_caps(PurpleMediaManager *manager);
-
-/**
- * purple_media_element_info_get_id:
- * @info: The instance.
- *
- * Gets the identifier from @info.
- *
- * Returns: The identifier.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_element_info_get_id(PurpleMediaElementInfo *info);
-
-/**
- * purple_media_element_info_get_name:
- * @info: The instance.
- *
- * Gets the name of @info.
- *
- * Returns: The name of @info.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_element_info_get_name(PurpleMediaElementInfo *info);
-
-/**
- * purple_media_element_info_get_element_type:
- * @info: The instance.
- *
- * Gets the element type of @info.
- *
- * Returns: The element type.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaElementType purple_media_element_info_get_element_type(
- PurpleMediaElementInfo *info);
-
-/**
- * purple_media_element_info_call_create:
- * @info: The #PurpleMediaElementInfo to create the element from
- * @media: The media instance.
- * @session_id: The session id.
- * @participant: The participant.
- *
- * Creates a new call.
- *
- * Returns: (transfer full): The new GstElement.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GstElement *purple_media_element_info_call_create(
- PurpleMediaElementInfo *info, PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_GST_H */
--- a/libpurple/media.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1408 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "media.h"
-#include "media/backend-iface.h"
-#include "mediamanager.h"
-#include "purpleaccount.h"
-
-#include "debug.h"
-
-#include "media-gst.h"
-
-typedef struct _PurpleMediaSession PurpleMediaSession;
-typedef struct _PurpleMediaStream PurpleMediaStream;
-
-struct _PurpleMediaSession
-{
- gchar *id;
- PurpleMedia *media;
- PurpleMediaSessionType type;
- gboolean initiator;
-};
-
-struct _PurpleMediaStream
-{
- PurpleMediaSession *session;
- gchar *participant;
-
- GList *local_candidates;
- GList *remote_candidates;
-
- gboolean initiator;
- gboolean accepted;
- gboolean candidates_prepared;
-
- GList *active_local_candidates;
- GList *active_remote_candidates;
-};
-
-struct _PurpleMediaPrivate
-{
- PurpleMediaManager *manager;
- PurpleAccount *account;
- PurpleMediaBackend *backend;
- gchar *conference_type;
- gboolean initiator;
- gpointer protocol_data;
-
- GHashTable *sessions; /* PurpleMediaSession table */
- GList *participants;
- GList *streams; /* PurpleMediaStream table */
-};
-
-static void purple_media_class_init (PurpleMediaClass *klass);
-static void purple_media_init (PurpleMedia *media);
-static void purple_media_dispose (GObject *object);
-static void purple_media_finalize (GObject *object);
-static void purple_media_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-static void purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-
-static void purple_media_new_local_candidate_cb(PurpleMediaBackend *backend,
- const gchar *sess_id, const gchar *participant,
- PurpleMediaCandidate *candidate, PurpleMedia *media);
-static void purple_media_candidates_prepared_cb(PurpleMediaBackend *backend,
- const gchar *sess_id, const gchar *name, PurpleMedia *media);
-static void purple_media_candidate_pair_established_cb(
- PurpleMediaBackend *backend,
- const gchar *sess_id, const gchar *name,
- PurpleMediaCandidate *local_candidate,
- PurpleMediaCandidate *remote_candidate,
- PurpleMedia *media);
-static void purple_media_codecs_changed_cb(PurpleMediaBackend *backend,
- const gchar *sess_id, PurpleMedia *media);
-
-
-enum {
- SIG_ERROR,
- SIG_CANDIDATES_PREPARED,
- SIG_CODECS_CHANGED,
- SIG_LEVEL,
- SIG_NEW_CANDIDATE,
- SIG_STATE_CHANGED,
- SIG_STREAM_INFO,
- SIG_CANDIDATE_PAIR_ESTABLISHED,
- N_SIGNALS,
-};
-static guint signals[N_SIGNALS] = {0, };
-
-enum {
- PROP_0,
- PROP_MANAGER,
- PROP_BACKEND,
- PROP_ACCOUNT,
- PROP_CONFERENCE_TYPE,
- PROP_INITIATOR,
- PROP_PROTOCOL_DATA,
- N_PROPERTIES,
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE(PurpleMedia, purple_media, G_TYPE_OBJECT);
-
-static void
-purple_media_class_init (PurpleMediaClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
-
- gobject_class->dispose = purple_media_dispose;
- gobject_class->finalize = purple_media_finalize;
- gobject_class->set_property = purple_media_set_property;
- gobject_class->get_property = purple_media_get_property;
-
- /**
- * PurpleMedia:manager:
- *
- * The manager that this media is tied to.
- */
- g_object_class_install_property(gobject_class, PROP_MANAGER,
- g_param_spec_object("manager",
- "Purple Media Manager",
- "The media manager that contains this media session.",
- PURPLE_TYPE_MEDIA_MANAGER,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMedia:backend:
- *
- * The backend for this media.
- */
- /*
- * This one should be PURPLE_TYPE_MEDIA_BACKEND, but it doesn't
- * like interfaces because they "aren't GObjects"
- */
- g_object_class_install_property(gobject_class, PROP_BACKEND,
- g_param_spec_object("backend",
- "Purple Media Backend",
- "The backend object this media object uses.",
- G_TYPE_OBJECT,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMedia:account:
- *
- * The [class@Account] that this media belongs to.
- */
- g_object_class_install_property(gobject_class, PROP_ACCOUNT,
- g_param_spec_object("account", "PurpleAccount",
- "The account this media session is on.",
- PURPLE_TYPE_ACCOUNT,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMedia:conference-type:
- *
- * The conference type of this media.
- */
- g_object_class_install_property(gobject_class, PROP_CONFERENCE_TYPE,
- g_param_spec_string("conference-type",
- "Conference Type",
- "The type of conference that this media object "
- "has been created to provide.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMedia:initiator:
- *
- * Whether or not the local user initiated the conference.
- */
- g_object_class_install_property(gobject_class, PROP_INITIATOR,
- g_param_spec_boolean("initiator",
- "initiator",
- "If the local user initiated the conference.",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMedia:protocol-data:
- *
- * Protocol specific data for the media.
- */
- g_object_class_install_property(gobject_class, PROP_PROTOCOL_DATA,
- g_param_spec_pointer("protocol-data",
- "gpointer",
- "Data the protocol set on the media session.",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMedia::error:
- * @media: The instance.
- * @message: The error message.
- *
- * Emitted by [method@Media.error].
- */
- signals[SIG_ERROR] = g_signal_new("error", G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 1, G_TYPE_STRING);
-
- /**
- * PurpleMedia::candidates-prepared:
- * @media: The instance.
- * @session_id: The session id.
- * @name: The candidate element name.
- *
- * Emitted when a candidate element has been determined.
- */
- signals[SIG_CANDIDATES_PREPARED] = g_signal_new("candidates-prepared",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 2, G_TYPE_STRING,
- G_TYPE_STRING);
-
- /**
- * PurpleMedia::codecs-changed:
- * @media: The instance.
- * @session_id: The session id.
- *
- * Emitted when the codecs have changed.
- */
- signals[SIG_CODECS_CHANGED] = g_signal_new("codecs-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 1, G_TYPE_STRING);
-
- /**
- * PurpleMedia::level:
- * @media: The instance.
- * @session_id: The session.
- * @participant: The participant.
- * @level: The new level.
- *
- * Emitted when the volume of a participant has changed. I think?
- */
- signals[SIG_LEVEL] = g_signal_new("level",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 3, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_DOUBLE);
-
-
- /**
- * PurpleMedia::new-candidate:
- * @media: The instance.
- * @session_id: The session id.
- * @participant: The participant.
- * @candidate: The new candidate.
- *
- * Emitted when a new media candidate is available.
- */
- signals[SIG_NEW_CANDIDATE] = g_signal_new("new-candidate",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 3, G_TYPE_POINTER,
- G_TYPE_POINTER, PURPLE_MEDIA_TYPE_CANDIDATE);
-
- /**
- * PurpleMedia::state-changed:
- * @media: The instance.
- * @newstate: The new state.
- * @session_id: The session id.
- * @participant: The participant.
- *
- * Emitted when the media's state has changed.
- */
- signals[SIG_STATE_CHANGED] = g_signal_new("state-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 3, PURPLE_MEDIA_TYPE_STATE,
- G_TYPE_STRING, G_TYPE_STRING);
-
- /**
- * PurpleMedia::stream-info:
- * @media: The instance.
- * @type: The type of the media.
- * @session_id: The session id.
- * @participant: The participant.
- * @local: Whether this request originated from the libpurple user.
- *
- * Emitted when information about the stream is available.
- */
- signals[SIG_STREAM_INFO] = g_signal_new("stream-info",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 4, PURPLE_MEDIA_TYPE_INFO_TYPE,
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
- /**
- * PurpleMedia::candidate-pair-established:
- * @media: The instance.
- * @session_id: The session id.
- * @name: The element name.
- * @local_candidate: The local candidate.
- * @remote_candidate: The remote candidate.
- *
- * Emitted when candidates have been established for a session.
- */
- signals[SIG_CANDIDATE_PAIR_ESTABLISHED] = g_signal_new("candidate-pair-established",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 4, G_TYPE_POINTER, G_TYPE_POINTER,
- PURPLE_MEDIA_TYPE_CANDIDATE, PURPLE_MEDIA_TYPE_CANDIDATE);
-}
-
-
-static void
-purple_media_init (PurpleMedia *media)
-{
- media->priv = purple_media_get_instance_private(media);
- memset(media->priv, 0, sizeof(*media->priv));
-}
-
-static void
-purple_media_stream_free(PurpleMediaStream *stream)
-{
- if (stream == NULL) {
- return;
- }
-
- g_free(stream->participant);
-
- g_clear_pointer(&stream->local_candidates,
- purple_media_candidate_list_free);
- g_clear_pointer(&stream->remote_candidates,
- purple_media_candidate_list_free);
- g_clear_pointer(&stream->active_local_candidates,
- purple_media_candidate_list_free);
- g_clear_pointer(&stream->active_remote_candidates,
- purple_media_candidate_list_free);
-
- g_free(stream);
-}
-
-static void
-purple_media_session_free(PurpleMediaSession *session)
-{
- if (session == NULL) {
- return;
- }
-
- g_free(session->id);
- g_free(session);
-}
-
-static void
-purple_media_dispose(GObject *media)
-{
- PurpleMediaPrivate *priv =
- purple_media_get_instance_private(PURPLE_MEDIA(media));
-
- purple_debug_info("media","purple_media_dispose\n");
-
- purple_media_manager_remove_media(priv->manager, PURPLE_MEDIA(media));
-
- g_clear_object(&priv->backend);
- g_clear_object(&priv->manager);
- g_clear_pointer(&priv->conference_type, g_free);
-
- G_OBJECT_CLASS(purple_media_parent_class)->dispose(media);
-}
-
-static void
-purple_media_finalize(GObject *media)
-{
- PurpleMediaPrivate *priv =
- purple_media_get_instance_private(PURPLE_MEDIA(media));
- purple_debug_info("media","purple_media_finalize\n");
-
- g_list_free_full(priv->streams, (GDestroyNotify)purple_media_stream_free);
- g_list_free_full(priv->participants, g_free);
-
- if (priv->sessions) {
- GList *sessions = g_hash_table_get_values(priv->sessions);
- g_list_free_full(sessions, (GDestroyNotify)purple_media_session_free);
- g_hash_table_destroy(priv->sessions);
- }
-
- G_OBJECT_CLASS(purple_media_parent_class)->finalize(media);
-}
-
-static void
-purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- PurpleMedia *media;
- g_return_if_fail(PURPLE_IS_MEDIA(object));
-
- media = PURPLE_MEDIA(object);
-
- switch (prop_id) {
- case PROP_MANAGER:
- media->priv->manager = g_value_dup_object(value);
- break;
- case PROP_ACCOUNT:
- media->priv->account = g_value_get_object(value);
- break;
- case PROP_CONFERENCE_TYPE:
- media->priv->conference_type = g_value_dup_string(value);
- media->priv->backend = g_object_new(
- purple_media_manager_get_backend_type(purple_media_manager_get()),
- "conference-type", media->priv->conference_type,
- "media", media,
- NULL);
- g_signal_connect(media->priv->backend,
- "active-candidate-pair",
- G_CALLBACK(purple_media_candidate_pair_established_cb),
- media);
- g_signal_connect(media->priv->backend,
- "candidates-prepared",
- G_CALLBACK(purple_media_candidates_prepared_cb),
- media);
- g_signal_connect(media->priv->backend,
- "codecs-changed",
- G_CALLBACK(purple_media_codecs_changed_cb),
- media);
- g_signal_connect(media->priv->backend,
- "new-candidate",
- G_CALLBACK(purple_media_new_local_candidate_cb),
- media);
- break;
- case PROP_INITIATOR:
- media->priv->initiator = g_value_get_boolean(value);
- break;
- case PROP_PROTOCOL_DATA:
- media->priv->protocol_data = g_value_get_pointer(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- PurpleMedia *media;
- g_return_if_fail(PURPLE_IS_MEDIA(object));
-
- media = PURPLE_MEDIA(object);
-
- switch (prop_id) {
- case PROP_MANAGER:
- g_value_set_object(value, media->priv->manager);
- break;
- case PROP_BACKEND:
- g_value_set_object(value, media->priv->backend);
- break;
- case PROP_ACCOUNT:
- g_value_set_object(value, media->priv->account);
- break;
- case PROP_CONFERENCE_TYPE:
- g_value_set_string(value, media->priv->conference_type);
- break;
- case PROP_INITIATOR:
- g_value_set_boolean(value, media->priv->initiator);
- break;
- case PROP_PROTOCOL_DATA:
- g_value_set_pointer(value, media->priv->protocol_data);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
-}
-
-static PurpleMediaSession*
-purple_media_get_session(PurpleMedia *media, const gchar *sess_id)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- return (PurpleMediaSession*) (media->priv->sessions) ?
- g_hash_table_lookup(media->priv->sessions, sess_id) : NULL;
-}
-
-static PurpleMediaStream*
-purple_media_get_stream(PurpleMedia *media, const gchar *session, const gchar *participant)
-{
- GList *streams;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
-
- streams = media->priv->streams;
-
- for (; streams; streams = g_list_next(streams)) {
- PurpleMediaStream *stream = streams->data;
- if (purple_strequal(stream->session->id, session) &&
- purple_strequal(stream->participant, participant))
- {
- return stream;
- }
- }
-
- return NULL;
-}
-
-static GList *
-purple_media_get_streams(PurpleMedia *media, const gchar *session,
- const gchar *participant)
-{
- GList *streams;
- GList *ret = NULL;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
-
- streams = media->priv->streams;
-
- for (; streams; streams = g_list_next(streams)) {
- PurpleMediaStream *stream = streams->data;
- if ((session == NULL ||
- purple_strequal(stream->session->id, session)) &&
- (participant == NULL ||
- purple_strequal(stream->participant, participant)))
- {
- ret = g_list_append(ret, stream);
- }
- }
-
- return ret;
-}
-
-static void
-purple_media_add_session(PurpleMedia *media, PurpleMediaSession *session)
-{
- g_return_if_fail(PURPLE_IS_MEDIA(media));
- g_return_if_fail(session != NULL);
-
- if (!media->priv->sessions) {
- purple_debug_info("media", "Creating hash table for sessions\n");
- media->priv->sessions = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
- }
- g_hash_table_insert(media->priv->sessions, g_strdup(session->id), session);
-}
-
-static PurpleMediaStream *
-purple_media_insert_stream(PurpleMediaSession *session,
- const gchar *name, gboolean initiator)
-{
- PurpleMediaStream *media_stream;
-
- g_return_val_if_fail(session != NULL, NULL);
-
- media_stream = g_new0(PurpleMediaStream, 1);
- media_stream->participant = g_strdup(name);
- media_stream->session = session;
- media_stream->initiator = initiator;
-
- session->media->priv->streams =
- g_list_append(session->media->priv->streams, media_stream);
-
- return media_stream;
-}
-
-static void
-purple_media_insert_local_candidate(PurpleMediaSession *session, const gchar *name,
- PurpleMediaCandidate *candidate)
-{
- PurpleMediaStream *stream;
-
- g_return_if_fail(session != NULL);
-
- stream = purple_media_get_stream(session->media, session->id, name);
- stream->local_candidates = g_list_append(stream->local_candidates, candidate);
-}
-
-GList *
-purple_media_get_session_ids(PurpleMedia *media)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- return media->priv->sessions != NULL ?
- g_hash_table_get_keys(media->priv->sessions) : NULL;
-}
-
-GstElement *
-purple_media_get_src(PurpleMedia *media, G_GNUC_UNUSED const char *sess_id)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
-
- return NULL;
-}
-
-PurpleAccount *
-purple_media_get_account(PurpleMedia *media)
-{
- PurpleAccount *account;
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- g_object_get(media, "account", &account, NULL);
- return account;
-}
-
-gpointer
-purple_media_get_protocol_data(PurpleMedia *media)
-{
- gpointer protocol_data;
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- g_object_get(media, "protocol-data", &protocol_data, NULL);
- return protocol_data;
-}
-
-void
-purple_media_set_protocol_data(PurpleMedia *media, gpointer protocol_data)
-{
- g_return_if_fail(PURPLE_IS_MEDIA(media));
- g_object_set(media, "protocol-data", protocol_data, NULL);
-}
-
-void
-purple_media_error(PurpleMedia *media, const gchar *error, ...)
-{
- va_list args;
- gchar *message;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- va_start(args, error);
- message = g_strdup_vprintf(error, args);
- va_end(args);
-
- purple_debug_error("media", "%s\n", message);
- g_signal_emit(media, signals[SIG_ERROR], 0, message);
-
- g_free(message);
-}
-
-void
-purple_media_end(PurpleMedia *media,
- const gchar *session_id, const gchar *participant)
-{
- GList *iter, *sessions = NULL, *participants = NULL;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- iter = purple_media_get_streams(media, session_id, participant);
-
- /* Free matching streams */
- for (; iter; iter = g_list_delete_link(iter, iter)) {
- PurpleMediaStream *stream = iter->data;
-
- g_signal_emit(media, signals[SIG_STATE_CHANGED],
- 0, PURPLE_MEDIA_STATE_END,
- stream->session->id, stream->participant);
-
- media->priv->streams =
- g_list_remove(media->priv->streams, stream);
-
- if (g_list_find(sessions, stream->session) == NULL) {
- sessions = g_list_prepend(sessions, stream->session);
- }
-
- if (g_list_find_custom(participants, stream->participant,
- (GCompareFunc)strcmp) == NULL)
- {
- participants = g_list_prepend(participants,
- g_strdup(stream->participant));
- }
-
- purple_media_stream_free(stream);
- }
-
- iter = media->priv->streams;
-
- /* Reduce to list of sessions to remove */
- for (; iter; iter = g_list_next(iter)) {
- PurpleMediaStream *stream = iter->data;
-
- sessions = g_list_remove(sessions, stream->session);
- }
-
- /* Free sessions with no streams left */
- for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
- PurpleMediaSession *session = sessions->data;
-
- g_signal_emit(media, signals[SIG_STATE_CHANGED],
- 0, PURPLE_MEDIA_STATE_END,
- session->id, NULL);
-
- g_hash_table_remove(media->priv->sessions, session->id);
- purple_media_session_free(session);
- }
-
- iter = media->priv->streams;
-
- /* Reduce to list of participants to remove */
- for (; iter; iter = g_list_next(iter)) {
- PurpleMediaStream *stream = iter->data;
- GList *tmp;
-
- tmp = g_list_find_custom(participants,
- stream->participant, (GCompareFunc)strcmp);
-
- if (tmp != NULL) {
- g_free(tmp->data);
- participants = g_list_delete_link(participants, tmp);
- }
- }
-
- /* Remove participants with no streams left (just emit the signal) */
- for (; participants; participants =
- g_list_delete_link(participants, participants)) {
- gchar *participant = participants->data;
- GList *link = g_list_find_custom(media->priv->participants,
- participant, (GCompareFunc)strcmp);
-
- g_signal_emit(media, signals[SIG_STATE_CHANGED],
- 0, PURPLE_MEDIA_STATE_END,
- NULL, participant);
-
- if (link != NULL) {
- g_free(link->data);
- media->priv->participants = g_list_delete_link(
- media->priv->participants, link);
- }
-
- g_free(participant);
- }
-
- /* Free the conference if no sessions left */
- if (media->priv->sessions != NULL &&
- g_hash_table_size(media->priv->sessions) == 0) {
- g_signal_emit(media, signals[SIG_STATE_CHANGED],
- 0, PURPLE_MEDIA_STATE_END,
- NULL, NULL);
- g_object_unref(media);
- return;
- }
-}
-
-void
-purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type,
- const gchar *session_id, const gchar *participant,
- gboolean local)
-{
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- if (type == PURPLE_MEDIA_INFO_ACCEPT) {
- GList *streams, *sessions = NULL, *participants = NULL;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- streams = purple_media_get_streams(media, session_id, participant);
-
- /* Emit stream acceptance */
- for (; streams; streams = g_list_delete_link(streams, streams)) {
- PurpleMediaStream *stream = streams->data;
-
- stream->accepted = TRUE;
-
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type, stream->session->id,
- stream->participant, local);
-
- if (g_list_find(sessions, stream->session) == NULL) {
- sessions = g_list_prepend(sessions, stream->session);
- }
-
- if (g_list_find_custom(participants,
- stream->participant,
- (GCompareFunc)strcmp) == NULL) {
- participants = g_list_prepend(participants,
- g_strdup(stream->participant));
- }
- }
-
- /* Emit session acceptance */
- for (; sessions; sessions =
- g_list_delete_link(sessions, sessions)) {
- PurpleMediaSession *session = sessions->data;
-
- if (purple_media_accepted(media, session->id, NULL)) {
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, PURPLE_MEDIA_INFO_ACCEPT,
- session->id, NULL, local);
- }
- }
-
- /* Emit participant acceptance */
- for (; participants; participants = g_list_delete_link(
- participants, participants)) {
- gchar *participant = participants->data;
-
- if (purple_media_accepted(media, NULL, participant)) {
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, PURPLE_MEDIA_INFO_ACCEPT,
- NULL, participant, local);
- }
-
- g_free(participant);
- }
-
- /* Emit conference acceptance */
- if (purple_media_accepted(media, NULL, NULL)) {
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, PURPLE_MEDIA_INFO_ACCEPT,
- NULL, NULL, local);
- }
-
- return;
- } else if (type == PURPLE_MEDIA_INFO_HANGUP ||
- type == PURPLE_MEDIA_INFO_REJECT) {
- GList *streams;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- streams = purple_media_get_streams(media, session_id, participant);
-
- /* Emit for stream */
- for (; streams; streams = g_list_delete_link(streams, streams)) {
- PurpleMediaStream *stream = streams->data;
-
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type, stream->session->id,
- stream->participant, local);
- }
-
- if (session_id != NULL && participant != NULL) {
- /* Everything that needs to be emitted has been */
- } else if (session_id == NULL && participant == NULL) {
- /* Emit for everything in the conference */
- GList *sessions = NULL;
- GList *participants = media->priv->participants;
-
- if (media->priv->sessions != NULL) {
- sessions = g_hash_table_get_values(
- media->priv->sessions);
- }
-
- /* Emit for sessions */
- for (; sessions; sessions = g_list_delete_link(
- sessions, sessions)) {
- PurpleMediaSession *session = sessions->data;
-
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type,
- session->id, NULL, local);
- }
-
- /* Emit for participants */
- for (; participants; participants =
- g_list_next(participants)) {
- gchar *participant = participants->data;
-
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type,
- NULL, participant, local);
- }
-
- /* Emit for conference */
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type, NULL, NULL, local);
- } else if (session_id != NULL) {
- /* Emit just the specific session */
- PurpleMediaSession *session =
- purple_media_get_session(
- media, session_id);
-
- if (session == NULL) {
- purple_debug_warning("media",
- "Couldn't find session"
- " to hangup/reject.\n");
- } else {
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type,
- session->id, NULL, local);
- }
- } else if (participant != NULL) {
- /* Emit just the specific participant */
- if (!g_list_find_custom(media->priv->participants,
- participant, (GCompareFunc)strcmp)) {
- purple_debug_warning("media",
- "Couldn't find participant"
- " to hangup/reject.\n");
- } else {
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type, NULL,
- participant, local);
- }
- }
-
- purple_media_end(media, session_id, participant);
- return;
- }
-
- g_signal_emit(media, signals[SIG_STREAM_INFO],
- 0, type, session_id, participant, local);
-}
-
-void
-purple_media_set_params(PurpleMedia *media, GHashTable *params)
-{
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- purple_media_backend_set_params(media->priv->backend, params);
-}
-
-const gchar **
-purple_media_get_available_params(PurpleMedia *media)
-{
- static const gchar *NULL_ARRAY[] = { NULL };
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL_ARRAY);
-
- return purple_media_backend_get_available_params(media->priv->backend);
-}
-
-gboolean
-purple_media_param_is_supported(PurpleMedia *media, const gchar *param)
-{
- const gchar **params;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
- g_return_val_if_fail(param != NULL, FALSE);
-
- params = purple_media_backend_get_available_params(media->priv->backend);
- for (; *params != NULL; ++params) {
- if (purple_strequal(*params, param)) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-purple_media_new_local_candidate_cb(G_GNUC_UNUSED PurpleMediaBackend *backend,
- const gchar *sess_id, const gchar *participant,
- PurpleMediaCandidate *candidate, PurpleMedia *media)
-{
- PurpleMediaSession *session =
- purple_media_get_session(media, sess_id);
-
- purple_media_insert_local_candidate(session, participant,
- purple_media_candidate_copy(candidate));
-
- g_signal_emit(session->media, signals[SIG_NEW_CANDIDATE],
- 0, session->id, participant, candidate);
-}
-
-static void
-purple_media_candidates_prepared_cb(G_GNUC_UNUSED PurpleMediaBackend *backend,
- const gchar *sess_id, const gchar *name, PurpleMedia *media)
-{
- PurpleMediaStream *stream_data;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- stream_data = purple_media_get_stream(media, sess_id, name);
- stream_data->candidates_prepared = TRUE;
-
- g_signal_emit(media, signals[SIG_CANDIDATES_PREPARED],
- 0, sess_id, name);
-}
-
-/* callback called when a pair of transport candidates (local and remote)
- * has been established */
-static void
-purple_media_candidate_pair_established_cb(G_GNUC_UNUSED PurpleMediaBackend *backend,
- const gchar *sess_id, const gchar *name,
- PurpleMediaCandidate *local_candidate,
- PurpleMediaCandidate *remote_candidate,
- PurpleMedia *media)
-{
- PurpleMediaStream *stream;
- GList *iter;
- guint id;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- stream = purple_media_get_stream(media, sess_id, name);
- id = purple_media_candidate_get_component_id(local_candidate);
-
- iter = stream->active_local_candidates;
- for(; iter; iter = g_list_next(iter)) {
- PurpleMediaCandidate *c = iter->data;
- if (id == purple_media_candidate_get_component_id(c)) {
- g_object_unref(c);
- stream->active_local_candidates = g_list_delete_link(
- stream->active_local_candidates,
- iter);
- break;
- }
- }
- stream->active_local_candidates = g_list_prepend(
- stream->active_local_candidates,
- purple_media_candidate_copy(
- local_candidate));
-
- id = purple_media_candidate_get_component_id(local_candidate);
-
- iter = stream->active_remote_candidates;
- for(; iter; iter = g_list_next(iter)) {
- PurpleMediaCandidate *c = iter->data;
- if (id == purple_media_candidate_get_component_id(c)) {
- g_object_unref(c);
- stream->active_remote_candidates = g_list_delete_link(
- stream->active_remote_candidates,
- iter);
- break;
- }
- }
- stream->active_remote_candidates = g_list_prepend(
- stream->active_remote_candidates,
- purple_media_candidate_copy(
- remote_candidate));
-
- g_signal_emit(media, signals[SIG_CANDIDATE_PAIR_ESTABLISHED],
- 0, sess_id, name, local_candidate, remote_candidate);
- purple_debug_info("media", "candidate pair established\n");
-}
-
-static void
-purple_media_codecs_changed_cb(G_GNUC_UNUSED PurpleMediaBackend *backend,
- const gchar *sess_id, PurpleMedia *media)
-{
- g_signal_emit(media, signals[SIG_CODECS_CHANGED], 0, sess_id);
-}
-
-gboolean
-purple_media_add_stream(PurpleMedia *media, const gchar *sess_id,
- const gchar *who, PurpleMediaSessionType type, gboolean initiator,
- const gchar *transmitter, GHashTable *params)
-{
- PurpleMediaSession *session;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- if (!purple_media_backend_add_stream(media->priv->backend,
- sess_id, who, type, initiator, transmitter, params))
- {
- purple_debug_error("media", "Error adding stream.\n");
- return FALSE;
- }
-
- session = purple_media_get_session(media, sess_id);
-
- if (!session) {
- session = g_new0(PurpleMediaSession, 1);
- session->id = g_strdup(sess_id);
- session->media = media;
- session->type = type;
- session->initiator = initiator;
-
- purple_media_add_session(media, session);
- g_signal_emit(media, signals[SIG_STATE_CHANGED],
- 0, PURPLE_MEDIA_STATE_NEW,
- session->id, NULL);
- }
-
- if (!g_list_find_custom(media->priv->participants,
- who, (GCompareFunc)strcmp)) {
- media->priv->participants = g_list_prepend(
- media->priv->participants, g_strdup(who));
-
- g_signal_emit(media, signals[SIG_STATE_CHANGED], 0,
- PURPLE_MEDIA_STATE_NEW, NULL, who);
- }
-
- if (purple_media_get_stream(media, sess_id, who) == NULL) {
- purple_media_insert_stream(session, who, initiator);
-
- g_signal_emit(media, signals[SIG_STATE_CHANGED],
- 0, PURPLE_MEDIA_STATE_NEW,
- session->id, who);
- }
-
- return TRUE;
-}
-
-PurpleMediaManager *
-purple_media_get_manager(PurpleMedia *media)
-{
- PurpleMediaManager *ret;
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- g_object_get(media, "manager", &ret, NULL);
- return ret;
-}
-
-PurpleMediaSessionType
-purple_media_get_session_type(PurpleMedia *media, const gchar *sess_id)
-{
- PurpleMediaSession *session;
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), PURPLE_MEDIA_NONE);
- session = purple_media_get_session(media, sess_id);
- return session->type;
-}
-
-/* XXX: Should wait until codecs-ready is TRUE before using this function */
-GList *
-purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
-
- return purple_media_backend_get_codecs(media->priv->backend, sess_id);
-}
-
-GList *
-purple_media_get_local_candidates(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
-
- return purple_media_backend_get_local_candidates(media->priv->backend,
- sess_id, participant);
-}
-
-void
-purple_media_add_remote_candidates(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant,
- GList *remote_candidates)
-{
- PurpleMediaStream *stream;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
- stream = purple_media_get_stream(media, sess_id, participant);
-
- if (stream == NULL) {
- purple_debug_error("media",
- "purple_media_add_remote_candidates: "
- "couldn't find stream %s %s.\n",
- sess_id ? sess_id : "(null)",
- participant ? participant : "(null)");
- return;
- }
-
- stream->remote_candidates = g_list_concat(stream->remote_candidates,
- purple_media_candidate_list_copy(remote_candidates));
-
- purple_media_backend_add_remote_candidates(media->priv->backend,
- sess_id, participant, remote_candidates);
-}
-
-GList *
-purple_media_get_active_local_candidates(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant)
-{
- PurpleMediaStream *stream;
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- stream = purple_media_get_stream(media, sess_id, participant);
- return purple_media_candidate_list_copy(
- stream->active_local_candidates);
-}
-
-GList *
-purple_media_get_active_remote_candidates(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant)
-{
- PurpleMediaStream *stream;
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
- stream = purple_media_get_stream(media, sess_id, participant);
- return purple_media_candidate_list_copy(
- stream->active_remote_candidates);
-}
-
-gboolean
-purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant, GList *codecs)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- return purple_media_backend_set_remote_codecs(media->priv->backend,
- sess_id, participant, codecs);
-}
-
-gboolean
-purple_media_candidates_prepared(PurpleMedia *media,
- const gchar *session_id, const gchar *participant)
-{
- GList *streams;
- gboolean prepared = TRUE;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- streams = purple_media_get_streams(media, session_id, participant);
-
- for (; streams; streams = g_list_delete_link(streams, streams)) {
- PurpleMediaStream *stream = streams->data;
- if (stream->candidates_prepared == FALSE) {
- g_list_free(streams);
- prepared = FALSE;
- break;
- }
- }
-
- return prepared;
-}
-
-gboolean
-purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- return purple_media_backend_set_send_codec(
- media->priv->backend, sess_id, codec);
-}
-
-gboolean
-purple_media_set_encryption_parameters(PurpleMedia *media, const gchar *sess_id,
- const gchar *cipher, const gchar *auth,
- const gchar *key, gsize key_len)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
- return purple_media_backend_set_encryption_parameters(media->priv->backend,
- sess_id, cipher, auth, key, key_len);
-}
-
-gboolean
-purple_media_set_decryption_parameters(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant, const gchar *cipher,
- const gchar *auth, const gchar *key, gsize key_len)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
- return purple_media_backend_set_decryption_parameters(media->priv->backend,
- sess_id, participant, cipher, auth, key, key_len);
-}
-
-gboolean
-purple_media_set_require_encryption(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant, gboolean require_encryption)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
- return purple_media_backend_set_require_encryption(media->priv->backend,
- sess_id, participant, require_encryption);
-}
-
-gboolean
-purple_media_codecs_ready(PurpleMedia *media, const gchar *sess_id)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- return purple_media_backend_codecs_ready(
- media->priv->backend, sess_id);
-}
-
-gboolean
-purple_media_set_send_rtcp_mux(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant, gboolean send_rtcp_mux)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- return purple_media_backend_set_send_rtcp_mux(media->priv->backend,
- sess_id, participant, send_rtcp_mux);
-}
-
-gboolean
-purple_media_is_initiator(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- if (sess_id == NULL && participant == NULL)
- return media->priv->initiator;
- else if (sess_id != NULL && participant == NULL) {
- PurpleMediaSession *session =
- purple_media_get_session(media, sess_id);
- return session != NULL ? session->initiator : FALSE;
- } else if (sess_id != NULL && participant != NULL) {
- PurpleMediaStream *stream = purple_media_get_stream(
- media, sess_id, participant);
- return stream != NULL ? stream->initiator : FALSE;
- }
-
- return FALSE;
-}
-
-gboolean
-purple_media_accepted(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant)
-{
- gboolean accepted = TRUE;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- if (sess_id == NULL && participant == NULL) {
- GList *streams = media->priv->streams;
-
- for (; streams; streams = g_list_next(streams)) {
- PurpleMediaStream *stream = streams->data;
- if (stream->accepted == FALSE) {
- accepted = FALSE;
- break;
- }
- }
- } else if (sess_id != NULL && participant == NULL) {
- GList *streams = purple_media_get_streams(media, sess_id, NULL);
- for (; streams; streams = g_list_delete_link(streams, streams)) {
- PurpleMediaStream *stream = streams->data;
- if (stream->accepted == FALSE) {
- g_list_free(streams);
- accepted = FALSE;
- break;
- }
- }
- } else if (sess_id != NULL && participant != NULL) {
- PurpleMediaStream *stream = purple_media_get_stream(
- media, sess_id, participant);
- if (stream == NULL || stream->accepted == FALSE) {
- accepted = FALSE;
- }
- }
-
- return accepted;
-}
-
-void
-purple_media_set_input_volume(PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED double level)
-{
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-}
-
-void
-purple_media_set_output_volume(PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant,
- G_GNUC_UNUSED double level)
-{
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-}
-
-gulong
-purple_media_set_output_window(PurpleMedia *media, const gchar *session_id,
- const gchar *participant)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- return purple_media_manager_set_output_window(media->priv->manager,
- media, session_id, participant);
-}
-
-void
-purple_media_remove_output_windows(PurpleMedia *media)
-{
- GList *iter = media->priv->streams;
- for (; iter; iter = g_list_next(iter)) {
- PurpleMediaStream *stream = iter->data;
- purple_media_manager_remove_output_windows(
- media->priv->manager, media,
- stream->session->id, stream->participant);
- }
-
- iter = purple_media_get_session_ids(media);
- for (; iter; iter = g_list_delete_link(iter, iter)) {
- gchar *session_name = iter->data;
- purple_media_manager_remove_output_windows(
- media->priv->manager, media,
- session_name, NULL);
- }
-}
-
-GstElement *
-purple_media_get_tee(PurpleMedia *media, G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
-
- return NULL;
-}
-
-gboolean
-purple_media_send_dtmf(PurpleMedia *media, const gchar *session_id,
- gchar dtmf, guint8 volume, guint16 duration)
-{
- PurpleMediaBackendInterface *backend_iface = NULL;
-
- if (media) {
- backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(media->priv->backend);
- }
-
- if (dtmf == 'a') {
- dtmf = 'A';
- } else if (dtmf == 'b') {
- dtmf = 'B';
- } else if (dtmf == 'c') {
- dtmf = 'C';
- } else if (dtmf == 'd') {
- dtmf = 'D';
- }
-
- g_return_val_if_fail(strchr("0123456789ABCD#*", dtmf), FALSE);
-
- if (backend_iface && backend_iface->send_dtmf
- && backend_iface->send_dtmf(media->priv->backend,
- session_id, dtmf, volume, duration))
- {
- return TRUE;
- }
-
- return FALSE;
-}
--- a/libpurple/media.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,633 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_H
-#define PURPLE_MEDIA_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-typedef struct _PurpleMedia PurpleMedia;
-
-#include "media/candidate.h"
-#include "media/codec.h"
-#include "media/enum-types.h"
-
-#define PURPLE_TYPE_MEDIA (purple_media_get_type())
-#define PURPLE_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA, PurpleMedia))
-#define PURPLE_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MEDIA, PurpleMediaClass))
-#define PURPLE_IS_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MEDIA))
-#define PURPLE_IS_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_MEDIA))
-#define PURPLE_MEDIA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MEDIA, PurpleMediaClass))
-
-#include "purpleaccount.h"
-#include "purpleversion.h"
-#include "signals.h"
-#include "util.h"
-
-typedef struct _PurpleMediaClass PurpleMediaClass;
-typedef struct _PurpleMediaPrivate PurpleMediaPrivate;
-
-/**
- * PurpleMedia:
- *
- * The media instance
- */
-struct _PurpleMedia
-{
- GObject parent;
-
- /*< private >*/
- PurpleMediaPrivate *priv;
-};
-
-/**
- * PurpleMediaClass:
- *
- * The media class
- */
-struct _PurpleMediaClass
-{
- GObjectClass parent_class;
-
- /*< private >*/
- void (*purple_reserved1)(void);
- void (*purple_reserved2)(void);
- void (*purple_reserved3)(void);
- void (*purple_reserved4)(void);
-};
-
-G_BEGIN_DECLS
-
-/**
- * purple_media_get_type:
- *
- * Gets the media class's GType
- *
- * Returns: The media class's GType.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GType purple_media_get_type(void);
-
-/**
- * purple_media_get_session_ids:
- * @media: The media session from which to retrieve session IDs.
- *
- * Gets a list of session IDs.
- *
- * Returns: (element-type utf8) (transfer container): List of session IDs.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_get_session_ids(PurpleMedia *media);
-
-/**
- * purple_media_get_account:
- * @media: The media session to retrieve the account from.
- *
- * Gets the PurpleAccount this media session is on.
- *
- * Returns: (transfer full): The account retrieved.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleAccount *purple_media_get_account(PurpleMedia *media);
-
-/**
- * purple_media_get_protocol_data:
- * @media: The media session to retrieve the protocol data from.
- *
- * Gets the protocol data from the media session.
- *
- * Returns: The protocol data retrieved.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-gpointer purple_media_get_protocol_data(PurpleMedia *media);
-
-/**
- * purple_media_set_protocol_data:
- * @media: The media session to set the protocol data on.
- * @protocol_data: The data to set on the media session.
- *
- * Sets the protocol data on the media session.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-void purple_media_set_protocol_data(PurpleMedia *media, gpointer protocol_data);
-
-/**
- * purple_media_error:
- * @media: The media object to set the state on.
- * @error: The format of the error message to send in the signal.
- * @...: The arguments to plug into the format.
- *
- * Signals an error in the media session.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_error(PurpleMedia *media, const gchar *error, ...) G_GNUC_PRINTF(2, 3);
-
-/**
- * purple_media_end:
- * @media: The media object with which to end streams.
- * @session_id: The session to end streams on.
- * @participant: The participant to end streams with.
- *
- * Ends all streams that match the given parameters
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_end(PurpleMedia *media, const gchar *session_id,
- const gchar *participant);
-
-/**
- * purple_media_stream_info:
- * @media: The media instance to containing the stream to signal.
- * @type: The type of info being signaled.
- * @session_id: The id of the session of the stream being signaled.
- * @participant: The participant of the stream being signaled.
- * @local: TRUE if the info originated locally, FALSE if on the remote end.
- *
- * Signals different information about the given stream.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type,
- const gchar *session_id, const gchar *participant,
- gboolean local);
-
-/**
- * purple_media_set_params:
- * @media: The media object to set the parameters on.
- * @params: (element-type utf8 GObject.Value) (transfer none): Hash table of
- * parameters to pass.
- *
- * Sets various optional parameters of the media call.
- *
- * Currently supported are:
- * - "sdes-cname" : The CNAME for the RTP sessions
- * - "sdes-name" : Real name used to describe the source in SDES messages
- * - "sdes-tool" : The TOOL to put in SDES messages
- * - "sdes-email" : Email address to put in SDES messages
- * - "sdes-location" : The LOCATION to put in SDES messages
- * - "sdes-note" : The NOTE to put in SDES messages
- * - "sdes-phone" : The PHONE to put in SDES messages
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-void purple_media_set_params(PurpleMedia *media, GHashTable *params);
-
-/**
- * purple_media_get_available_params:
- * @media: The media object
- *
- * Gets the list of optional parameters supported by the media backend.
- *
- * The list is owned by the #PurpleMedia internals and should NOT be freed.
- *
- * Returns: (array zero-terminated=1) (transfer none): Names of supported
- * parameters.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-const gchar **purple_media_get_available_params(PurpleMedia *media);
-
-/**
- * purple_media_param_is_supported:
- * @media: The media object
- * @param: name of parameter
- *
- * Checks if given optional parameter is supported by the media backend.
- *
- * Returns: %TRUE if backend recognizes the parameter, %FALSE otherwise.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-gboolean purple_media_param_is_supported(PurpleMedia *media, const gchar *param);
-
-/**
- * purple_media_add_stream:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to add the stream to.
- * @who: The name of the remote user to add the stream for.
- * @type: The type of stream to create.
- * @initiator: Whether or not the local user initiated the stream.
- * @transmitter: The transmitter to use for the stream.
- * @params: (element-type utf8 GObject.Value) (transfer none): The stream
- * parameters to pass to Farstream.
- *
- * Adds a stream to a session.
- *
- * It only adds a stream to one audio session or video session as
- * the @sess_id must be unique between sessions.
- *
- * Returns: %TRUE The stream was added successfully, %FALSE otherwise.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_add_stream(PurpleMedia *media, const gchar *sess_id,
- const gchar *who, PurpleMediaSessionType type, gboolean initiator,
- const gchar *transmitter, GHashTable *params);
-
-/**
- * purple_media_get_session_type:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to get the type from.
- *
- * Gets the session type from a session
- *
- * Returns: The retrieved session type.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaSessionType purple_media_get_session_type(PurpleMedia *media, const gchar *sess_id);
-
-/**
- * purple_media_get_manager:
- * @media: The media object to get the manager instance from.
- *
- * Gets the PurpleMediaManager this media session is a part of.
- *
- * Returns: The PurpleMediaManager instance retrieved.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-struct _PurpleMediaManager *purple_media_get_manager(PurpleMedia *media);
-
-/**
- * purple_media_get_codecs:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to get the codecs from.
- *
- * Gets the codecs from a session.
- *
- * Returns: (element-type PurpleMediaCodec) (transfer full): The retrieved
- * codecs.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id);
-
-/**
- * purple_media_add_remote_candidates:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session find the stream in.
- * @participant: The name of the remote user to add the candidates for.
- * @remote_candidates: (element-type PurpleMediaCandidate) (transfer none): The
- * remote candidates to add.
- *
- * Adds remote candidates to the stream.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_add_remote_candidates(PurpleMedia *media,
- const gchar *sess_id,
- const gchar *participant,
- GList *remote_candidates);
-
-/**
- * purple_media_get_local_candidates:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to find the stream in.
- * @participant: The name of the remote user to get the candidates from.
- *
- * Gets the local candidates from a stream.
- *
- * Returns: (element-type PurpleMediaCandidate) (transfer full): The local
- * candidates.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_get_local_candidates(PurpleMedia *media,
- const gchar *sess_id,
- const gchar *participant);
-
-/**
- * purple_media_get_active_local_candidates:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to find the stream in.
- * @participant: The name of the remote user to get the active candidate
- * from.
- *
- * Gets the active local candidates for the stream.
- *
- * Returns: (element-type PurpleMediaCandidate) (transfer full): The active
- * candidates retrieved.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-GList *purple_media_get_active_local_candidates(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant);
-
-/**
- * purple_media_get_active_remote_candidates:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to find the stream in.
- * @participant: The name of the remote user to get the remote candidate
- * from.
- *
- * Gets the active remote candidates for the stream.
- *
- * Returns: (element-type PurpleMediaCandidate) (transfer full): The remote
- * candidates retrieved.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-GList *purple_media_get_active_remote_candidates(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant);
-
-/**
- * purple_media_set_remote_codecs:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session find the stream in.
- * @participant: The name of the remote user to set the codecs for.
- * @codecs: (element-type PurpleMediaCodec) (transfer none): The list of remote
- * codecs to set.
- *
- * Sets remote codecs from the stream.
- *
- * Returns: %TRUE The codecs were set successfully, or %FALSE otherwise.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant, GList *codecs);
-
-/**
- * purple_media_candidates_prepared:
- * @media: The media object to find the remote user in.
- * @session_id: The session id of the session to check.
- * @participant: The remote user to check for.
- *
- * Returns whether or not the candidates for set of streams are prepared
- *
- * Returns: %TRUE All streams for the given session_id/participant combination have candidates prepared, %FALSE otherwise.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_candidates_prepared(PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-/**
- * purple_media_set_send_codec:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to set the codec for.
- * @codec: The codec to set the session to stream.
- *
- * Sets the send codec for the a session.
- *
- * Returns: %TRUE The codec was successfully changed, or %FALSE otherwise.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec);
-
-/**
- * purple_media_set_encryption_parameters:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to set parameters of.
- * @cipher: The cipher to use to encrypt our media in the session.
- * @auth: The algorithm to use to compute authentication codes for our media
- * frames.
- * @key: The encryption key.
- * @key_len: Byte length of the encryption key.
- *
- * Sets the encryption parameters of our media in the session.
- *
- * Returns: %TRUE if the encryption parameters were set successfully.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_set_encryption_parameters(PurpleMedia *media,
- const gchar *sess_id, const gchar *cipher,
- const gchar *auth, const gchar *key, gsize key_len);
-
-/**
- * purple_media_set_decryption_parameters:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to set parameters of.
- * @participant: The participant of the session to set parameters of.
- * @cipher: The cipher to use to decrypt media coming from this session's
- * participant.
- * @auth: The algorithm to use for authentication of the media coming from
- * the session's participant.
- * @key: The decryption key.
- * @key_len: Byte length of the decryption key.
- *
- * Sets the decryption parameters for a session participant's media.
- *
- * Returns: %TRUE if the decryption parameters were set successfully.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_set_decryption_parameters(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant,
- const gchar *cipher, const gchar *auth,
- const gchar *key, gsize key_len);
-
-/**
- * purple_media_set_require_encryption:
- * @media: The media object to find the session in.
- * @sess_id: The id of the session to set parameters of.
- * @participant: The participant of the session to set parameters of.
- * @require_encryption: TRUE if the media requires encryption.
- *
- * Sets whether a session participant's media requires encryption.
- *
- * Returns: %TRUE if the encryption requirement was set successfully.
- *
- * Since: 2.14
- */
-PURPLE_AVAILABLE_IN_2_14
-gboolean purple_media_set_require_encryption(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant,
- gboolean require_encryption);
-
-/**
- * purple_media_codecs_ready:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to check.
- *
- * Gets whether a session's codecs are ready to be used.
- *
- * Returns: %TRUE The codecs are ready, or %FALSE otherwise.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_codecs_ready(PurpleMedia *media, const gchar *sess_id);
-
-/**
- * purple_media_set_send_rtcp_mux:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session find the stream in.
- * @participant: The name of the remote user to set the rtcp-mux for.
- * @send_rtcp_mux: Whether to enable the rtcp-mux option
- *
- * Sets the rtcp-mux option for the stream.
- *
- * Returns: %TRUE RTCP-Mux was set successfully, or %FALSE otherwise.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_set_send_rtcp_mux(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant, gboolean send_rtcp_mux);
-/**
- * purple_media_is_initiator:
- * @media: The media instance to find the session in.
- * @sess_id: The session id of the session to check.
- * @participant: The participant of the stream to check.
- *
- * Gets whether the local user is the conference/session/stream's initiator.
- *
- * Returns: TRUE if the local user is the stream's initiator, else FALSE.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_is_initiator(PurpleMedia *media,
- const gchar *sess_id, const gchar *participant);
-
-/**
- * purple_media_accepted:
- * @media: The media object to find the session in.
- * @sess_id: The session id of the session to check.
- * @participant: The participant to check.
- *
- * Gets whether a streams selected have been accepted.
- *
- * Returns: %TRUE The selected streams have been accepted, or %FALSE otherwise.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_accepted(PurpleMedia *media, const gchar *sess_id,
- const gchar *participant);
-
-/**
- * purple_media_set_input_volume:
- * @media: The media object the sessions are in.
- * @session_id: The session to select (if any).
- * @level: The level to set the volume to.
- *
- * Sets the input volume of all the selected sessions.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_set_input_volume(PurpleMedia *media, const gchar *session_id, double level);
-
-/**
- * purple_media_set_output_volume:
- * @media: The media object the streams are in.
- * @session_id: The session to limit the streams to (if any).
- * @participant: The participant to limit the streams to (if any).
- * @level: The level to set the volume to.
- *
- * Sets the output volume of all the selected streams.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_set_output_volume(PurpleMedia *media, const gchar *session_id,
- const gchar *participant, double level);
-
-/**
- * purple_media_set_output_window:
- * @media: The media instance to set the output window on.
- * @session_id: The session to set the output window on.
- * @participant: Optionally, the participant to set the output window on.
- *
- * Sets a video output window for the given session/stream.
- *
- * Returns: An id to reference the output window.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gulong purple_media_set_output_window(PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-/**
- * purple_media_remove_output_windows:
- * @media: The instance to remove all output windows from.
- *
- * Removes all output windows from a given media session.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_remove_output_windows(PurpleMedia *media);
-
-/**
- * purple_media_send_dtmf:
- * @media: The media instance to send a DTMF signal to.
- * @session_id: The session id of the session to send the DTMF signal on.
- * @dtmf: The character representing the DTMF in the range [0-9#*A-D].
- * @volume: The power level expressed in dBm0 after dropping the sign in the
- * range of 0 to 63. A larger value represents a lower volume.
- * @duration: The duration of the tone in milliseconds.
- *
- * Sends a DTMF signal out-of-band.
- *
- * Returns: %TRUE DTMF sent successfully, or %FALSE otherwise.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_send_dtmf(PurpleMedia *media, const gchar *session_id,
- gchar dtmf, guint8 volume, guint16 duration);
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_H */
--- a/libpurple/media/backend-iface.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,311 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "backend-iface.h"
-
-enum {
- SIG_ERROR,
- SIG_CANDIDATES_PREPARED,
- SIG_CODECS_CHANGED,
- SIG_NEW_CANDIDATE,
- SIG_ACTIVE_CANDIDATE_PAIR,
- N_SIGNALS,
-};
-
-static guint signals[N_SIGNALS] = {0, };
-
-static void
-purple_media_backend_base_init(gpointer iface)
-{
- static gboolean is_initialized = FALSE;
-
- if (is_initialized) {
- return;
- }
-
- /**
- * PurpleMediaBackend:conference-type:
- *
- * The type of the conference.
- */
- g_object_interface_install_property(iface,
- g_param_spec_string("conference-type",
- "Conference Type",
- "The type of conference that this backend "
- "has been created to provide.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaBackend:media:
- *
- * The media object that this back end is bound to.
- */
- g_object_interface_install_property(iface,
- g_param_spec_object(
- "media", "Purple Media",
- "The media object that this backend is bound to.",
- PURPLE_TYPE_MEDIA,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaBackend::error:
- * @backend: The backend instance.
- * @message: The error message.
- *
- * Emitted when the backend has encountered an error.
- */
- signals[SIG_ERROR] = g_signal_new("error",
- G_TYPE_FROM_CLASS(iface),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 1, G_TYPE_STRING);
-
- /**
- * PurpleMediaBackend::candidates-prepared:
- * @backend: The backend instance.
- * @session_id: The session id.
- * @name: The name.
- *
- * Emitted when the candidates have been prepared.
- */
- signals[SIG_CANDIDATES_PREPARED] = g_signal_new("candidates-prepared",
- G_TYPE_FROM_CLASS(iface),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 2, G_TYPE_STRING,
- G_TYPE_STRING);
-
- /**
- * PurpleMediaBackend::codecs-changed:
- * @backend: The backend instance.
- * @session_id: The session id.
- *
- * Emitted when the codecs have changed.
- */
- signals[SIG_CODECS_CHANGED] = g_signal_new("codecs-changed",
- G_TYPE_FROM_CLASS(iface),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 1, G_TYPE_STRING);
-
- /**
- * PurpleMediaBackend::new-candidate:
- * @backend: The backend instance.
- * @session_id: The session id.
- * @participant: The participant.
- * @candidate: The new candidate.
- *
- * Emitted when a new media candidate is available.
- */
- signals[SIG_NEW_CANDIDATE] = g_signal_new("new-candidate",
- G_TYPE_FROM_CLASS(iface),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 3, G_TYPE_POINTER,
- G_TYPE_POINTER, PURPLE_MEDIA_TYPE_CANDIDATE);
-
- /**
- * PurpleMediaBackend::active-candidate-pair:
- * @backend: The backend instance.
- * @session_id: The session id.
- * @participant: The participant.
- * @candidate1: The first candidate.
- * @candidate2: The second candidate.
- *
- * This is currently not emitted any, so I'd be guessing...
- */
- signals[SIG_ACTIVE_CANDIDATE_PAIR] = g_signal_new("active-candidate-pair",
- G_TYPE_FROM_CLASS(iface),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING,
- PURPLE_MEDIA_TYPE_CANDIDATE,
- PURPLE_MEDIA_TYPE_CANDIDATE);
-
- is_initialized = TRUE;
-}
-
-GType
-purple_media_backend_get_type(void)
-{
- static GType iface_type = 0;
- if (iface_type == 0) {
- static const GTypeInfo info = {
- sizeof(PurpleMediaBackendInterface),
- purple_media_backend_base_init,
- NULL,
- NULL,
- NULL,
- NULL,
- 0,
- 0,
- NULL,
- NULL
- };
-
- iface_type = g_type_register_static (G_TYPE_INTERFACE,
- "PurpleMediaBackend", &info, 0);
- }
-
- return iface_type;
-}
-
-gboolean
-purple_media_backend_add_stream(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *who, PurpleMediaSessionType type,
- gboolean initiator, const gchar *transmitter, GHashTable *params)
-{
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->add_stream(self,
- sess_id, who, type, initiator, transmitter, params);
-}
-
-void
-purple_media_backend_add_remote_candidates(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- GList *remote_candidates)
-{
- g_return_if_fail(PURPLE_MEDIA_IS_BACKEND(self));
- PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->add_remote_candidates(self,
- sess_id, participant, remote_candidates);
-}
-
-gboolean
-purple_media_backend_codecs_ready(PurpleMediaBackend *self,
- const gchar *sess_id)
-{
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->codecs_ready(self,
- sess_id);
-}
-
-GList *
-purple_media_backend_get_codecs(PurpleMediaBackend *self,
- const gchar *sess_id)
-{
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), NULL);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->get_codecs(self,
- sess_id);
-}
-
-GList *
-purple_media_backend_get_local_candidates(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant)
-{
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), NULL);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->
- get_local_candidates(self,
- sess_id, participant);
-}
-
-gboolean
-purple_media_backend_set_remote_codecs(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- GList *codecs)
-{
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_remote_codecs(
- self, sess_id, participant, codecs);
-}
-
-gboolean
-purple_media_backend_set_send_codec(PurpleMediaBackend *self,
- const gchar *sess_id, PurpleMediaCodec *codec)
-{
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_send_codec(self,
- sess_id, codec);
-}
-
-gboolean
-purple_media_backend_set_encryption_parameters(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *cipher,
- const gchar *auth, const gchar *key, gsize key_len)
-{
- PurpleMediaBackendInterface *backend_iface;
-
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self);
- g_return_val_if_fail(backend_iface->set_encryption_parameters, FALSE);
- return backend_iface->set_encryption_parameters(self,
- sess_id, cipher, auth, key, key_len);
-}
-
-gboolean
-purple_media_backend_set_decryption_parameters(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- const gchar *cipher, const gchar *auth,
- const gchar *key, gsize key_len)
-{
- PurpleMediaBackendInterface *backend_iface;
-
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self);
- g_return_val_if_fail(backend_iface->set_decryption_parameters, FALSE);
- return backend_iface->set_decryption_parameters(self,
- sess_id, participant, cipher, auth, key, key_len);
-}
-
-gboolean
-purple_media_backend_set_require_encryption(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- gboolean require_encryption)
-{
- PurpleMediaBackendInterface *backend_iface;
-
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self);
-
- if (!backend_iface->set_require_encryption) {
- return FALSE;
- }
-
- return backend_iface->set_require_encryption(self,
- sess_id, participant, require_encryption);
-}
-
-void
-purple_media_backend_set_params(PurpleMediaBackend *self, GHashTable *params)
-{
- g_return_if_fail(PURPLE_MEDIA_IS_BACKEND(self));
- PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_params(self, params);
-}
-
-const gchar **
-purple_media_backend_get_available_params(PurpleMediaBackend *self)
-{
- static const gchar *NULL_ARRAY[] = { NULL };
-
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), NULL_ARRAY);
- return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->get_available_params();
-}
-
-gboolean
-purple_media_backend_set_send_rtcp_mux(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant, gboolean send_rtcp_mux)
-{
- PurpleMediaBackendInterface *backend_iface;
-
- g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
- backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self);
- g_return_val_if_fail(backend_iface->set_send_rtcp_mux, FALSE);
- return backend_iface->set_send_rtcp_mux(self,
- sess_id, participant, send_rtcp_mux);
-}
--- a/libpurple/media/backend-iface.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,349 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_BACKEND_IFACE_H
-#define PURPLE_MEDIA_BACKEND_IFACE_H
-
-#include "codec.h"
-#include "enum-types.h"
-#include "media.h"
-#include "purpleversion.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define PURPLE_MEDIA_TYPE_BACKEND (purple_media_backend_get_type())
-#define PURPLE_MEDIA_IS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_MEDIA_TYPE_BACKEND))
-#define PURPLE_MEDIA_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_MEDIA_TYPE_BACKEND, PurpleMediaBackend))
-#define PURPLE_MEDIA_BACKEND_GET_INTERFACE(inst)(G_TYPE_INSTANCE_GET_INTERFACE((inst), PURPLE_MEDIA_TYPE_BACKEND, PurpleMediaBackendInterface))
-
-/**
- * PurpleMediaBackend:
- *
- * A placeholder to represent any media backend
- *
- * Since: 2.6
- */
-typedef struct _PurpleMediaBackend PurpleMediaBackend;
-
-typedef struct _PurpleMediaBackendInterface PurpleMediaBackendInterface;
-
-struct _PurpleMediaBackendInterface
-{
- /*< private >*/
- GTypeInterface parent_iface; /* The parent iface class */
-
- /*< public >*/
- /* Implementable functions called with purple_media_backend_* */
- gboolean (*add_stream) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *who,
- PurpleMediaSessionType type, gboolean initiator,
- const gchar *transmitter, GHashTable *params);
-
- void (*add_remote_candidates) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- GList *remote_candidates);
- gboolean (*codecs_ready) (PurpleMediaBackend *self,
- const gchar *sess_id);
- GList *(*get_codecs) (PurpleMediaBackend *self,
- const gchar *sess_id);
- GList *(*get_local_candidates) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant);
- gboolean (*set_remote_codecs) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- GList *codecs);
- gboolean (*set_send_codec) (PurpleMediaBackend *self,
- const gchar *sess_id, PurpleMediaCodec *codec);
- gboolean (*set_encryption_parameters) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *cipher,
- const gchar *auth, const gchar *key, gsize key_len);
- gboolean (*set_decryption_parameters) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- const gchar *cipher, const gchar *auth,
- const gchar *key, gsize key_len);
- gboolean (*set_require_encryption) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- gboolean require_encryption);
- void (*set_params) (PurpleMediaBackend *self, GHashTable *params);
- const gchar **(*get_available_params) (void);
- gboolean (*send_dtmf) (PurpleMediaBackend *self,
- const gchar *sess_id, gchar dtmf, guint8 volume,
- guint16 duration);
- gboolean (*set_send_rtcp_mux) (PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant, gboolean send_rtcp_mux);
-};
-
-/**
- * purple_media_backend_get_type:
- *
- * Gets the media backend's GType.
- *
- * Returns: The media backend's GType.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-GType purple_media_backend_get_type(void);
-
-/**
- * purple_media_backend_add_stream:
- * @self: The backend to add the stream to.
- * @sess_id: The session id of the stream to add.
- * @who: The remote participant of the stream to add.
- * @type: The media type and direction of the stream to add.
- * @initiator: True if the local user initiated the stream.
- * @transmitter: The string id of the tranmsitter to use.
- * @params: (element-type utf8 GValue) (transfer none): The additional
- * parameters to pass when creating the stream.
- *
- * Creates and adds a stream to the media backend.
- *
- * Returns: True if the stream was successfully created, otherwise False.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-gboolean purple_media_backend_add_stream(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *who, PurpleMediaSessionType type,
- gboolean initiator, const gchar *transmitter, GHashTable *params);
-
-/**
- * purple_media_backend_add_remote_candidates:
- * @self: The backend the stream is in.
- * @sess_id: The session id associated with the stream.
- * @participant: The participant associated with the stream.
- * @remote_candidates: (element-type PurpleMediaCandidate): The list of remote candidates to add.
- *
- * Add remote candidates to a stream.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-void purple_media_backend_add_remote_candidates(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- GList *remote_candidates);
-
-/**
- * purple_media_backend_codecs_ready:
- * @self: The media backend the session is in.
- * @sess_id: The session id of the session to check.
- *
- * Get whether or not a session's codecs are ready.
- *
- * A codec is ready if all of the attributes and additional
- * parameters have been collected.
- *
- * Returns: True if the codecs are ready, otherwise False.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-gboolean purple_media_backend_codecs_ready(PurpleMediaBackend *self,
- const gchar *sess_id);
-
-/**
- * purple_media_backend_get_codecs:
- * @self: The media backend the session is in.
- * @sess_id: The session id of the session to use.
- *
- * Gets the codec intersection list for a session.
- *
- * The intersection list consists of all codecs that are compatible
- * between the local and remote software.
- *
- * Returns: (transfer full) (element-type PurpleMediaCodec): The codec intersection list.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-GList *purple_media_backend_get_codecs(PurpleMediaBackend *self,
- const gchar *sess_id);
-
-/**
- * purple_media_backend_get_local_candidates:
- * @self: The media backend the stream is in.
- * @sess_id: The session id associated with the stream.
- * @participant: The participant associated with the stream.
- *
- * Gets the list of local candidates for a stream.
- *
- * Returns: (transfer full) (element-type PurpleMediaCandidate): The list of
- * local candidates.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-GList *purple_media_backend_get_local_candidates(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant);
-
-/**
- * purple_media_backend_set_remote_codecs:
- * @self: The media backend the stream is in.
- * @sess_id: The session id the stream is associated with.
- * @participant: The participant the stream is associated with.
- * @codecs: (element-type PurpleMediaCodec): The list of remote codecs to set.
- *
- * Sets the remote codecs on a stream.
- *
- * Returns: True if the remote codecs were set successfully, otherwise False.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-gboolean purple_media_backend_set_remote_codecs(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- GList *codecs);
-
-/**
- * purple_media_backend_set_send_codec:
- * @self: The media backend the session is in.
- * @sess_id: The session id of the session to set the codec for.
- * @codec: The codec to set.
- *
- * Sets which codec format to send media content in for a session.
- *
- * Returns: True if set successfully, otherwise False.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-gboolean purple_media_backend_set_send_codec(PurpleMediaBackend *self,
- const gchar *sess_id, PurpleMediaCodec *codec);
-
-/**
- * purple_media_backend_set_encryption_parameters:
- * @self: The media backend the session is in.
- * @sess_id: The session id of the session to set parameters of.
- * @cipher: The cipher to use to encrypt our media in the session.
- * @auth: The algorithm to use to compute authentication codes for our media
- * frames.
- * @key: The encryption key.
- * @key_len: Byte length of the encryption key.
- *
- * Sets the encryption parameters of our media in the session.
- *
- * Returns: %TRUE if the settings were successfully applied, otherwise %FALSE.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_backend_set_encryption_parameters(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *cipher,
- const gchar *auth, const gchar *key, gsize key_len);
-
-/**
- * purple_media_backend_set_decryption_parameters:
- * @self: The media backend the session is in.
- * @sess_id: The session id of the session to set parameters of.
- * @participant: The participant of the session to set parameters of.
- * @cipher: The cipher to use to decrypt media coming from this session's
- * participant.
- * @auth: The algorithm to use for authentication of the media coming from
- * the session's participant.
- * @key: The decryption key.
- * @key_len: Byte length of the decryption key.
- *
- * Sets the decryption parameters for a session participant's media.
- *
- * Returns: %TRUE if the change was successful.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_backend_set_decryption_parameters(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- const gchar *cipher, const gchar *auth,
- const gchar *key, gsize key_len);
-
-/**
- * purple_media_backend_set_require_encryption:
- * @self: The media object to find the session in.
- * @sess_id: The id of the session to set parameters of.
- * @participant: The participant of the session to set parameters of.
- * @require_encryption: TRUE if the media requires encryption.
- *
- * Sets whether a session participant's media requires encryption.
- *
- * Returns: %TRUE if the change was successful.
- *
- * Since: 2.14
- */
-PURPLE_AVAILABLE_IN_2_14
-gboolean purple_media_backend_set_require_encryption(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant,
- gboolean require_encryption);
-
-/**
- * purple_media_backend_set_params:
- * @self: The media backend to set the parameters on.
- * @params: (element-type utf8 GObject.Value) (transfer none): Hash table of
- * parameters to pass to the backend.
- *
- * Sets various optional parameters of the media backend.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-void purple_media_backend_set_params(PurpleMediaBackend *self,
- GHashTable *params);
-
-/**
- * purple_media_backend_get_available_params:
- * @self: The media backend
- *
- * Gets the list of optional parameters supported by the media backend.
- * The list should NOT be freed.
- *
- * Returns: (transfer none): NULL-terminated array of names of supported
- * parameters.
- *
- * Since: 2.8
- */
-PURPLE_AVAILABLE_IN_2_8
-const gchar **purple_media_backend_get_available_params(PurpleMediaBackend *self);
-
-/**
- * purple_media_backend_set_send_rtcp_mux:
- * @self: The media backend the session is in.
- * @sess_id: The session id of the session to set the rtcp-mux option to
- * @participant: The participant the stream is associated with.
- * @send_rtcp_mux: Whether or not to enable rtcp-mux
- *
- * Controls whether or not the RTCP should be muxed with the RTP
- *
- * Returns: True if set successfully, otherwise False.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-gboolean purple_media_backend_set_send_rtcp_mux(PurpleMediaBackend *self,
- const gchar *sess_id, const gchar *participant, gboolean send_rtcp_mux);
-
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_BACKEND_IFACE_H */
--- a/libpurple/media/candidate.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,536 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "candidate.h"
-
-/**
- * PurpleMediaCandidate:
- *
- * An opaque structure representing a network candidate (IP Address and port
- * pair).
- */
-struct _PurpleMediaCandidate
-{
- GObject parent;
-};
-
-typedef struct
-{
- gchar *foundation;
- guint component_id;
- gchar *ip;
- guint16 port;
- gchar *base_ip;
- guint16 base_port;
- PurpleMediaNetworkProtocol proto;
- guint32 priority;
- PurpleMediaCandidateType type;
- gchar *username;
- gchar *password;
- guint ttl;
-} PurpleMediaCandidatePrivate;
-
-enum {
- PROP_0,
- PROP_FOUNDATION,
- PROP_COMPONENT_ID,
- PROP_IP,
- PROP_PORT,
- PROP_BASE_IP,
- PROP_BASE_PORT,
- PROP_PROTOCOL,
- PROP_PRIORITY,
- PROP_TYPE,
- PROP_USERNAME,
- PROP_PASSWORD,
- PROP_TTL,
- N_PROPERTIES,
-};
-
-G_DEFINE_FINAL_TYPE_WITH_PRIVATE(PurpleMediaCandidate, purple_media_candidate,
- G_TYPE_OBJECT)
-
-static void
-purple_media_candidate_init(PurpleMediaCandidate *info)
-{
- PurpleMediaCandidatePrivate *priv =
- purple_media_candidate_get_instance_private(info);
- priv->foundation = NULL;
- priv->component_id = 0;
- priv->ip = NULL;
- priv->port = 0;
- priv->base_ip = NULL;
- priv->proto = PURPLE_MEDIA_NETWORK_PROTOCOL_UDP;
- priv->priority = 0;
- priv->type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
- priv->username = NULL;
- priv->password = NULL;
- priv->ttl = 0;
-}
-
-static void
-purple_media_candidate_finalize(GObject *info)
-{
- PurpleMediaCandidatePrivate *priv =
- purple_media_candidate_get_instance_private(
- PURPLE_MEDIA_CANDIDATE(info));
-
- g_free(priv->foundation);
- g_free(priv->ip);
- g_free(priv->base_ip);
- g_free(priv->username);
- g_free(priv->password);
-
- G_OBJECT_CLASS(purple_media_candidate_parent_class)->finalize(info);
-}
-
-static void
-purple_media_candidate_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- PurpleMediaCandidatePrivate *priv;
-
- priv = purple_media_candidate_get_instance_private(
- PURPLE_MEDIA_CANDIDATE(object));
-
- switch (prop_id) {
- case PROP_FOUNDATION:
- g_free(priv->foundation);
- priv->foundation = g_value_dup_string(value);
- break;
- case PROP_COMPONENT_ID:
- priv->component_id = g_value_get_uint(value);
- break;
- case PROP_IP:
- g_free(priv->ip);
- priv->ip = g_value_dup_string(value);
- break;
- case PROP_PORT:
- priv->port = g_value_get_uint(value);
- break;
- case PROP_BASE_IP:
- g_free(priv->base_ip);
- priv->base_ip = g_value_dup_string(value);
- break;
- case PROP_BASE_PORT:
- priv->base_port = g_value_get_uint(value);
- break;
- case PROP_PROTOCOL:
- priv->proto = g_value_get_enum(value);
- break;
- case PROP_PRIORITY:
- priv->priority = g_value_get_uint(value);
- break;
- case PROP_TYPE:
- priv->type = g_value_get_enum(value);
- break;
- case PROP_USERNAME:
- g_free(priv->username);
- priv->username = g_value_dup_string(value);
- break;
- case PROP_PASSWORD:
- g_free(priv->password);
- priv->password = g_value_dup_string(value);
- break;
- case PROP_TTL:
- priv->ttl = g_value_get_uint(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(
- object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_candidate_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- PurpleMediaCandidatePrivate *priv;
-
- priv = purple_media_candidate_get_instance_private(
- PURPLE_MEDIA_CANDIDATE(object));
-
- switch (prop_id) {
- case PROP_FOUNDATION:
- g_value_set_string(value, priv->foundation);
- break;
- case PROP_COMPONENT_ID:
- g_value_set_uint(value, priv->component_id);
- break;
- case PROP_IP:
- g_value_set_string(value, priv->ip);
- break;
- case PROP_PORT:
- g_value_set_uint(value, priv->port);
- break;
- case PROP_BASE_IP:
- g_value_set_string(value, priv->base_ip);
- break;
- case PROP_BASE_PORT:
- g_value_set_uint(value, priv->base_port);
- break;
- case PROP_PROTOCOL:
- g_value_set_enum(value, priv->proto);
- break;
- case PROP_PRIORITY:
- g_value_set_uint(value, priv->priority);
- break;
- case PROP_TYPE:
- g_value_set_enum(value, priv->type);
- break;
- case PROP_USERNAME:
- g_value_set_string(value, priv->username);
- break;
- case PROP_PASSWORD:
- g_value_set_string(value, priv->password);
- break;
- case PROP_TTL:
- g_value_set_uint(value, priv->ttl);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(
- object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_candidate_class_init(PurpleMediaCandidateClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
-
- gobject_class->finalize = purple_media_candidate_finalize;
- gobject_class->set_property = purple_media_candidate_set_property;
- gobject_class->get_property = purple_media_candidate_get_property;
-
- /**
- * PurpleMediaCandidate:foundation:
- *
- * The foundation of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_FOUNDATION,
- g_param_spec_string("foundation",
- "Foundation",
- "The foundation of the candidate.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:component-id:
- *
- * The component id of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_COMPONENT_ID,
- g_param_spec_uint("component-id",
- "Component ID",
- "The component id of the candidate.",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:ip:
- *
- * The IP address of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_IP,
- g_param_spec_string("ip",
- "IP Address",
- "The IP address of the candidate.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:port:
- *
- * The port of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_PORT,
- g_param_spec_uint("port",
- "Port",
- "The port of the candidate.",
- 0, G_MAXUINT16, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:base-ip:
- *
- * The internal IP address of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_BASE_IP,
- g_param_spec_string("base-ip",
- "Base IP",
- "The internal IP address of the candidate.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:base-port:
- *
- * The internal port of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_BASE_PORT,
- g_param_spec_uint("base-port",
- "Base Port",
- "The internal port of the candidate.",
- 0, G_MAXUINT16, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:protocol:
- *
- * The protocol of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_PROTOCOL,
- g_param_spec_enum("protocol",
- "Protocol",
- "The protocol of the candidate.",
- PURPLE_MEDIA_TYPE_NETWORK_PROTOCOL,
- PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:priority:
- *
- * The priority of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_PRIORITY,
- g_param_spec_uint("priority",
- "Priority",
- "The priority of the candidate.",
- 0, G_MAXUINT32, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:type:
- *
- * The type of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_TYPE,
- g_param_spec_enum("type",
- "Type",
- "The type of the candidate.",
- PURPLE_MEDIA_TYPE_CANDIDATE_TYPE,
- PURPLE_MEDIA_CANDIDATE_TYPE_HOST,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:username:
- *
- * The username used to connect to the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_USERNAME,
- g_param_spec_string("username",
- "Username",
- "The username used to connect to the candidate.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:password:
- *
- * The password used to connect to the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_PASSWORD,
- g_param_spec_string("password",
- "Password",
- "The password use to connect to the candidate.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaCandidate:ttl:
- *
- * The TTL of the candidate.
- */
- g_object_class_install_property(gobject_class, PROP_TTL,
- g_param_spec_uint("ttl",
- "TTL",
- "The TTL of the candidate.",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-}
-
-PurpleMediaCandidate *
-purple_media_candidate_new(const gchar *foundation, guint component_id,
- PurpleMediaCandidateType type,
- PurpleMediaNetworkProtocol proto,
- const gchar *ip, guint port)
-{
- return g_object_new(PURPLE_MEDIA_TYPE_CANDIDATE,
- "foundation", foundation,
- "component-id", component_id,
- "type", type,
- "protocol", proto,
- "ip", ip,
- "port", port, NULL);
-}
-
-PurpleMediaCandidate *
-purple_media_candidate_copy(PurpleMediaCandidate *candidate)
-{
- PurpleMediaCandidatePrivate *priv;
- PurpleMediaCandidate *new_candidate;
-
- if (candidate == NULL) {
- return NULL;
- }
-
- priv = purple_media_candidate_get_instance_private(candidate);
-
- new_candidate = purple_media_candidate_new(priv->foundation,
- priv->component_id, priv->type, priv->proto,
- priv->ip, priv->port);
- g_object_set(new_candidate,
- "base-ip", priv->base_ip,
- "base-port", priv->base_port,
- "priority", priv->priority,
- "username", priv->username,
- "password", priv->password,
- "ttl", priv->ttl, NULL);
- return new_candidate;
-}
-
-GList *
-purple_media_candidate_list_copy(GList *candidates)
-{
- return g_list_copy_deep(candidates,
- (GCopyFunc)(GCallback)purple_media_candidate_copy,
- NULL);
-}
-
-void
-purple_media_candidate_list_free(GList *candidates)
-{
- g_list_free_full(candidates, g_object_unref);
-}
-
-gchar *
-purple_media_candidate_get_foundation(PurpleMediaCandidate *candidate)
-{
- gchar *foundation;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), NULL);
- g_object_get(candidate, "foundation", &foundation, NULL);
- return foundation;
-}
-
-guint
-purple_media_candidate_get_component_id(PurpleMediaCandidate *candidate)
-{
- guint component_id;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), 0);
- g_object_get(candidate, "component-id", &component_id, NULL);
- return component_id;
-}
-
-gchar *
-purple_media_candidate_get_ip(PurpleMediaCandidate *candidate)
-{
- gchar *ip;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), NULL);
- g_object_get(candidate, "ip", &ip, NULL);
- return ip;
-}
-
-guint16
-purple_media_candidate_get_port(PurpleMediaCandidate *candidate)
-{
- guint port;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), 0);
- g_object_get(candidate, "port", &port, NULL);
- return port;
-}
-
-gchar *
-purple_media_candidate_get_base_ip(PurpleMediaCandidate *candidate)
-{
- gchar *base_ip;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), NULL);
- g_object_get(candidate, "base-ip", &base_ip, NULL);
- return base_ip;
-}
-
-guint16
-purple_media_candidate_get_base_port(PurpleMediaCandidate *candidate)
-{
- guint base_port;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), 0);
- g_object_get(candidate, "base_port", &base_port, NULL);
- return base_port;
-}
-
-PurpleMediaNetworkProtocol
-purple_media_candidate_get_protocol(PurpleMediaCandidate *candidate)
-{
- PurpleMediaNetworkProtocol protocol;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate),
- PURPLE_MEDIA_NETWORK_PROTOCOL_UDP);
- g_object_get(candidate, "protocol", &protocol, NULL);
- return protocol;
-}
-
-guint32
-purple_media_candidate_get_priority(PurpleMediaCandidate *candidate)
-{
- guint priority;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), 0);
- g_object_get(candidate, "priority", &priority, NULL);
- return priority;
-}
-
-PurpleMediaCandidateType
-purple_media_candidate_get_candidate_type(PurpleMediaCandidate *candidate)
-{
- PurpleMediaCandidateType type;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate),
- PURPLE_MEDIA_CANDIDATE_TYPE_HOST);
- g_object_get(candidate, "type", &type, NULL);
- return type;
-}
-
-gchar *
-purple_media_candidate_get_username(PurpleMediaCandidate *candidate)
-{
- gchar *username;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), NULL);
- g_object_get(candidate, "username", &username, NULL);
- return username;
-}
-
-gchar *
-purple_media_candidate_get_password(PurpleMediaCandidate *candidate)
-{
- gchar *password;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), NULL);
- g_object_get(candidate, "password", &password, NULL);
- return password;
-}
-
-guint
-purple_media_candidate_get_ttl(PurpleMediaCandidate *candidate)
-{
- guint ttl;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CANDIDATE(candidate), 0);
- g_object_get(candidate, "ttl", &ttl, NULL);
- return ttl;
-}
-
--- a/libpurple/media/candidate.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_CANDIDATE_H
-#define PURPLE_MEDIA_CANDIDATE_H
-
-#include "enum-types.h"
-
-#include <glib-object.h>
-
-#include "purpleversion.h"
-
-G_BEGIN_DECLS
-
-/**
- * PURPLE_MEDIA_TYPE_CANDIDATE:
- *
- * The standard _get_type macro for #PurpleMediaCandidate.
- *
- * Since: 3.0
- */
-#define PURPLE_MEDIA_TYPE_CANDIDATE purple_media_candidate_get_type()
-
-/**
- * purple_media_candidate_get_type:
- *
- * Gets the type of the media candidate structure.
- *
- * Returns: The media canditate's GType
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-G_DECLARE_FINAL_TYPE(PurpleMediaCandidate, purple_media_candidate,
- PURPLE_MEDIA, CANDIDATE, GObject)
-
-/**
- * purple_media_candidate_new:
- * @foundation: The foundation of the candidate.
- * @component_id: The component this candidate is for.
- * @type: The type of candidate.
- * @proto: The protocol this component is for.
- * @ip: The IP address of this component.
- * @port: The network port.
- *
- * Creates a PurpleMediaCandidate instance.
- *
- * Returns: The newly created PurpleMediaCandidate instance.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaCandidate *purple_media_candidate_new(
- const gchar *foundation, guint component_id,
- PurpleMediaCandidateType type,
- PurpleMediaNetworkProtocol proto,
- const gchar *ip, guint port);
-
-/**
- * purple_media_candidate_copy:
- * @candidate: The candidate to copy.
- *
- * Copies a PurpleMediaCandidate.
- *
- * Returns: (transfer full): The copy of the PurpleMediaCandidate.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-PurpleMediaCandidate *purple_media_candidate_copy(
- PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_list_copy:
- * @candidates: (element-type PurpleMediaCandidate) (transfer none): The list
- * of candidates to be copied.
- *
- * Copies a GList of PurpleMediaCandidate and its contents.
- *
- * Returns: (element-type PurpleMediaCandidate) (transfer full): The copy of
- * the candidate list.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_candidate_list_copy(GList *candidates);
-
-/**
- * purple_media_candidate_list_free:
- * @candidates: (element-type PurpleMediaCandidate) (transfer full): The list
- * of candidates to be freed.
- *
- * Frees a GList of PurpleMediaCandidate and its contents.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_candidate_list_free(GList *candidates);
-
-/**
- * purple_media_candidate_get_foundation:
- * @candidate: The candidate to get the foundation from.
- *
- * Gets the foundation (identifier) from the candidate.
- *
- * Returns: The foundation.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_candidate_get_foundation(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_component_id:
- * @candidate: The candidate to get the component id from.
- *
- * Gets the component id (rtp or rtcp)
- *
- * Returns: The component id.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint purple_media_candidate_get_component_id(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_ip:
- * @candidate: The candidate to get the IP address from.
- *
- * Gets the IP address.
- *
- * Returns: The IP address.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_candidate_get_ip(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_port:
- * @candidate: The candidate to get the port from.
- *
- * Gets the port.
- *
- * Returns: The port.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint16 purple_media_candidate_get_port(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_base_ip:
- * @candidate: The candidate to get the base IP address from.
- *
- * Gets the base (internal) IP address.
- * This can be NULL.
- *
- * Returns: The base IP address.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_candidate_get_base_ip(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_base_port:
- * @candidate: The candidate to get the base port.
- *
- * Gets the base (internal) port.
- * Invalid if the base IP is NULL.
- *
- * Returns: The base port.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint16 purple_media_candidate_get_base_port(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_protocol:
- * @candidate: The candidate to get the protocol from.
- *
- * Gets the protocol (TCP or UDP).
- *
- * Returns: The protocol.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaNetworkProtocol purple_media_candidate_get_protocol(
- PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_priority:
- * @candidate: The candidate to get the priority from.
- *
- * Gets the priority.
- *
- * Returns: The priority.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint32 purple_media_candidate_get_priority(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_candidate_type:
- * @candidate: The candidate to get the candidate type from.
- *
- * Gets the candidate type.
- *
- * Returns: The candidate type.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaCandidateType purple_media_candidate_get_candidate_type(
- PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_username:
- * @candidate: The candidate to get the username from.
- *
- * Gets the username.
- * This can be NULL. It depends on the transmission type.
- *
- * Returns: The username.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_candidate_get_username(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_password:
- * @candidate: The candidate to get the password from.
- *
- * Gets the password.
- *
- * This can be NULL. It depends on the transmission type.
- *
- * Returns: The password.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_candidate_get_password(PurpleMediaCandidate *candidate);
-
-/**
- * purple_media_candidate_get_ttl:
- * @candidate: The candidate to get the TTL from.
- *
- * Gets the TTL.
- *
- * Returns: The TTL.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint purple_media_candidate_get_ttl(PurpleMediaCandidate *candidate);
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_CANDIDATE_H */
--- a/libpurple/media/codec.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,427 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "codec.h"
-
-struct _PurpleMediaCodec
-{
- GObject parent;
-};
-
-typedef struct
-{
- gint id;
- char *encoding_name;
- PurpleMediaSessionType media_type;
- guint clock_rate;
- guint channels;
- GList *optional_params;
-} PurpleMediaCodecPrivate;
-
-enum {
- PROP_0,
- PROP_ID,
- PROP_ENCODING_NAME,
- PROP_MEDIA_TYPE,
- PROP_CLOCK_RATE,
- PROP_CHANNELS,
- PROP_OPTIONAL_PARAMS,
- N_PROPERTIES,
-};
-
-static GParamSpec *properties[N_PROPERTIES] = {NULL, };
-
-G_DEFINE_FINAL_TYPE_WITH_PRIVATE(PurpleMediaCodec, purple_media_codec,
- G_TYPE_OBJECT)
-
-static void
-purple_media_codec_init(PurpleMediaCodec *info)
-{
- PurpleMediaCodecPrivate *priv =
- purple_media_codec_get_instance_private(info);
- priv->encoding_name = NULL;
- priv->optional_params = NULL;
-}
-
-static void
-purple_media_codec_finalize(GObject *info)
-{
- PurpleMediaCodecPrivate *priv =
- purple_media_codec_get_instance_private(
- PURPLE_MEDIA_CODEC(info));
- g_free(priv->encoding_name);
- g_list_free_full(priv->optional_params, (GDestroyNotify)purple_key_value_pair_free);
-
- G_OBJECT_CLASS(purple_media_codec_parent_class)->finalize(info);
-}
-
-static void
-purple_media_codec_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- PurpleMediaCodecPrivate *priv;
- g_return_if_fail(PURPLE_MEDIA_IS_CODEC(object));
-
- priv = purple_media_codec_get_instance_private(
- PURPLE_MEDIA_CODEC(object));
-
- switch (prop_id) {
- case PROP_ID:
- priv->id = g_value_get_uint(value);
- break;
- case PROP_ENCODING_NAME:
- g_free(priv->encoding_name);
- priv->encoding_name = g_value_dup_string(value);
- break;
- case PROP_MEDIA_TYPE:
- priv->media_type = g_value_get_flags(value);
- break;
- case PROP_CLOCK_RATE:
- priv->clock_rate = g_value_get_uint(value);
- break;
- case PROP_CHANNELS:
- priv->channels = g_value_get_uint(value);
- break;
- case PROP_OPTIONAL_PARAMS:
- priv->optional_params = g_value_get_pointer(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(
- object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_codec_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- PurpleMediaCodecPrivate *priv;
- g_return_if_fail(PURPLE_MEDIA_IS_CODEC(object));
-
- priv = purple_media_codec_get_instance_private(
- PURPLE_MEDIA_CODEC(object));
-
- switch (prop_id) {
- case PROP_ID:
- g_value_set_uint(value, priv->id);
- break;
- case PROP_ENCODING_NAME:
- g_value_set_string(value, priv->encoding_name);
- break;
- case PROP_MEDIA_TYPE:
- g_value_set_flags(value, priv->media_type);
- break;
- case PROP_CLOCK_RATE:
- g_value_set_uint(value, priv->clock_rate);
- break;
- case PROP_CHANNELS:
- g_value_set_uint(value, priv->channels);
- break;
- case PROP_OPTIONAL_PARAMS:
- g_value_set_pointer(value, priv->optional_params);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(
- object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_codec_class_init(PurpleMediaCodecClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
-
- gobject_class->finalize = purple_media_codec_finalize;
- gobject_class->set_property = purple_media_codec_set_property;
- gobject_class->get_property = purple_media_codec_get_property;
-
- /**
- * PurpleMediaCodec:id:
- *
- * The numeric identifier of the codec.
- */
- properties[PROP_ID] = g_param_spec_uint("id",
- "ID",
- "The numeric identifier of the codec.",
- 0, G_MAXUINT, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleMediaCodec:encoding-name:
- *
- * The name of the codec.
- */
- properties[PROP_ENCODING_NAME] = g_param_spec_string("encoding-name",
- "Encoding Name",
- "The name of the codec.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleMediaCodec:media-type:
- *
- * Whether this is an audio, video, or application codec.
- */
- properties[PROP_MEDIA_TYPE] = g_param_spec_flags("media-type",
- "Media Type",
- "Whether this is an audio, video or application codec.",
- PURPLE_MEDIA_TYPE_SESSION_TYPE,
- PURPLE_MEDIA_NONE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleMediaCodec:clock-rate:
- *
- * The clock rate for the codec.
- */
- properties[PROP_CLOCK_RATE] = g_param_spec_uint("clock-rate",
- "Create Callback",
- "The function called to create this element.",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleMediaCodec:channels:
- *
- * The number of channels in the codec.
- */
- properties[PROP_CHANNELS] = g_param_spec_uint("channels",
- "Channels",
- "The number of channels in this codec.",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleMediaCodec:optional-params:
- *
- * A list of optional parameters for the codec.
- */
- properties[PROP_OPTIONAL_PARAMS] = g_param_spec_pointer("optional-params",
- "Optional Params",
- "A list of optional parameters for the codec.",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties(gobject_class, N_PROPERTIES, properties);
-}
-
-PurpleMediaCodec *
-purple_media_codec_new(int id, const char *encoding_name,
- PurpleMediaSessionType media_type, guint clock_rate)
-{
- PurpleMediaCodec *codec =
- g_object_new(PURPLE_MEDIA_TYPE_CODEC,
- "id", id,
- "encoding_name", encoding_name,
- "media_type", media_type,
- "clock-rate", clock_rate, NULL);
- return codec;
-}
-
-guint
-purple_media_codec_get_id(PurpleMediaCodec *codec)
-{
- guint id;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CODEC(codec), 0);
- g_object_get(codec, "id", &id, NULL);
- return id;
-}
-
-gchar *
-purple_media_codec_get_encoding_name(PurpleMediaCodec *codec)
-{
- gchar *name;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CODEC(codec), NULL);
- g_object_get(codec, "encoding-name", &name, NULL);
- return name;
-}
-
-guint
-purple_media_codec_get_clock_rate(PurpleMediaCodec *codec)
-{
- guint clock_rate;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CODEC(codec), 0);
- g_object_get(codec, "clock-rate", &clock_rate, NULL);
- return clock_rate;
-}
-
-guint
-purple_media_codec_get_channels(PurpleMediaCodec *codec)
-{
- guint channels;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CODEC(codec), 0);
- g_object_get(codec, "channels", &channels, NULL);
- return channels;
-}
-
-GList *
-purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec)
-{
- GList *optional_params;
- g_return_val_if_fail(PURPLE_MEDIA_IS_CODEC(codec), NULL);
- g_object_get(codec, "optional-params", &optional_params, NULL);
- return optional_params;
-}
-
-void
-purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
- const gchar *name, const gchar *value)
-{
- PurpleMediaCodecPrivate *priv;
- PurpleKeyValuePair *new_param;
-
- g_return_if_fail(codec != NULL);
- g_return_if_fail(name != NULL && value != NULL);
-
- priv = purple_media_codec_get_instance_private(codec);
-
- new_param = purple_key_value_pair_new_full(name, g_strdup(value), g_free);
- priv->optional_params = g_list_append(
- priv->optional_params, new_param);
-
- g_object_notify_by_pspec(G_OBJECT(codec), properties[PROP_OPTIONAL_PARAMS]);
-}
-
-void
-purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
- PurpleKeyValuePair *param)
-{
- PurpleMediaCodecPrivate *priv;
-
- g_return_if_fail(codec != NULL && param != NULL);
-
- priv = purple_media_codec_get_instance_private(codec);
-
- priv->optional_params =
- g_list_remove(priv->optional_params, param);
- purple_key_value_pair_free(param);
-
- g_object_notify_by_pspec(G_OBJECT(codec), properties[PROP_OPTIONAL_PARAMS]);
-}
-
-PurpleKeyValuePair *
-purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec,
- const gchar *name, const gchar *value)
-{
- PurpleMediaCodecPrivate *priv;
- GList *iter;
-
- g_return_val_if_fail(codec != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- priv = purple_media_codec_get_instance_private(codec);
-
- for (iter = priv->optional_params; iter; iter = g_list_next(iter)) {
- PurpleKeyValuePair *param = iter->data;
- if (!g_ascii_strcasecmp(param->key, name) &&
- (value == NULL ||
- !g_ascii_strcasecmp(param->value, value)))
- {
- return param;
- }
- }
-
- return NULL;
-}
-
-PurpleMediaCodec *
-purple_media_codec_copy(PurpleMediaCodec *codec)
-{
- PurpleMediaCodecPrivate *priv;
- PurpleMediaCodec *new_codec;
- GList *iter;
-
- if (codec == NULL) {
- return NULL;
- }
-
- priv = purple_media_codec_get_instance_private(codec);
-
- new_codec = purple_media_codec_new(priv->id, priv->encoding_name,
- priv->media_type, priv->clock_rate);
- g_object_set(codec, "channels", priv->channels, NULL);
-
- for (iter = priv->optional_params; iter; iter = g_list_next(iter)) {
- PurpleKeyValuePair *param =
- (PurpleKeyValuePair*)iter->data;
- purple_media_codec_add_optional_parameter(new_codec,
- param->key, param->value);
- }
-
- return new_codec;
-}
-
-GList *
-purple_media_codec_list_copy(GList *codecs)
-{
- return g_list_copy_deep(codecs,
- (GCopyFunc)(GCallback)purple_media_codec_copy,
- NULL);
-}
-
-void
-purple_media_codec_list_free(GList *codecs)
-{
- g_list_free_full(codecs, g_object_unref);
-}
-
-gchar *
-purple_media_codec_to_string(PurpleMediaCodec *codec)
-{
- PurpleMediaCodecPrivate *priv;
- GString *string = NULL;
- GList *item;
- const gchar *media_type_str = NULL;
-
- if (codec == NULL) {
- return g_strdup("(NULL)");
- }
-
- priv = purple_media_codec_get_instance_private(codec);
-
- string = g_string_new("");
-
- if (priv->media_type & PURPLE_MEDIA_AUDIO) {
- media_type_str = "audio";
- } else if (priv->media_type & PURPLE_MEDIA_VIDEO) {
- media_type_str = "video";
- } else if (priv->media_type & PURPLE_MEDIA_APPLICATION) {
- media_type_str = "application";
- }
-
- g_string_printf(string, "%d: %s %s clock:%d channels:%d", priv->id,
- media_type_str, priv->encoding_name,
- priv->clock_rate, priv->channels);
-
- for (item = priv->optional_params; item; item = g_list_next (item)) {
- PurpleKeyValuePair *param = item->data;
- g_string_append_printf (string, " %s=%s",
- param->key, (gchar *)param->value);
- }
-
- return g_string_free(string, FALSE);
-}
-
--- a/libpurple/media/codec.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,250 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_CODEC_H
-#define PURPLE_MEDIA_CODEC_H
-
-#include "enum-types.h"
-
-/**
- * PurpleMediaCodec:
- *
- * An opaque structure representing an audio or video codec.
- */
-typedef struct _PurpleMediaCodec PurpleMediaCodec;
-
-#include "purplekeyvaluepair.h"
-#include "purpleversion.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/**
- * PURPLE_MEDIA_TYPE_CODEC:
- *
- * The standard _get_type macro for #PurpleMediaCodec.
- *
- * Since: 3.0
- */
-#define PURPLE_MEDIA_TYPE_CODEC purple_media_codec_get_type()
-
-/**
- * purple_media_codec_get_type:
- *
- * Gets the type of the media codec structure.
- *
- * Returns: The media codec's GType
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-G_DECLARE_FINAL_TYPE(PurpleMediaCodec, purple_media_codec, PURPLE_MEDIA,
- CODEC, GObject)
-
-/**
- * purple_media_codec_new:
- * @id: Codec identifier.
- * @encoding_name: Name of the media type this encodes.
- * @media_type: PurpleMediaSessionType of this codec.
- * @clock_rate: The clock rate this codec encodes at, if applicable.
- *
- * Creates a new PurpleMediaCodec instance.
- *
- * Returns: The newly created PurpleMediaCodec.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaCodec *purple_media_codec_new(int id, const char *encoding_name,
- PurpleMediaSessionType media_type, guint clock_rate);
-
-/**
- * purple_media_codec_get_id:
- * @codec: The codec to get the id from.
- *
- * Gets the codec id.
- *
- * Returns: The codec id.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint purple_media_codec_get_id(PurpleMediaCodec *codec);
-
-/**
- * purple_media_codec_get_encoding_name:
- * @codec: The codec to get the encoding name from.
- *
- * Gets the encoding name.
- *
- * Returns: The encoding name.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_codec_get_encoding_name(PurpleMediaCodec *codec);
-
-/**
- * purple_media_codec_get_clock_rate:
- * @codec: The codec to get the clock rate from.
- *
- * Gets the clock rate.
- *
- * Returns: The clock rate.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint purple_media_codec_get_clock_rate(PurpleMediaCodec *codec);
-
-/**
- * purple_media_codec_get_channels:
- * @codec: The codec to get the number of channels from.
- *
- * Gets the number of channels.
- *
- * Returns: The number of channels.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-guint purple_media_codec_get_channels(PurpleMediaCodec *codec);
-
-/**
- * purple_media_codec_get_optional_parameters:
- * @codec: The codec to get the optional parameters from.
- *
- * Gets a list of the optional parameters.
- *
- * Returns: (element-type PurpleKeyValuePair) (transfer none): The list of
- * optional parameters.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec);
-
-/**
- * purple_media_codec_add_optional_parameter:
- * @codec: The codec to add the parameter to.
- * @name: The name of the parameter to add.
- * @value: The value of the parameter to add.
- *
- * Adds an optional parameter to the codec.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
- const gchar *name, const gchar *value);
-
-/**
- * purple_media_codec_remove_optional_parameter:
- * @codec: The codec to remove the parameter from.
- * @param: A pointer to the parameter to remove.
- *
- * Removes an optional parameter from the codec.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
- PurpleKeyValuePair *param);
-
-/**
- * purple_media_codec_get_optional_parameter:
- * @codec: The codec to find the parameter in.
- * @name: The name of the parameter to search for.
- * @value: The value to search for or NULL.
- *
- * Gets an optional parameter based on the values given.
- *
- * Returns: (transfer none): The value found or NULL.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleKeyValuePair *purple_media_codec_get_optional_parameter(
- PurpleMediaCodec *codec, const gchar *name,
- const gchar *value);
-
-/**
- * purple_media_codec_copy:
- * @codec: The codec to copy.
- *
- * Copies a PurpleMediaCodec object.
- *
- * Returns: (transfer full): The copy of the codec.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-PurpleMediaCodec *purple_media_codec_copy(PurpleMediaCodec *codec);
-
-/**
- * purple_media_codec_list_copy:
- * @codecs: (element-type PurpleMediaCodec) (transfer none): The list of codecs
- * to be copied.
- *
- * Copies a GList of PurpleMediaCodec and its contents.
- *
- * Returns: (element-type PurpleMediaCodec) (transfer full): The copy of the
- * codec list.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_codec_list_copy(GList *codecs);
-
-/**
- * purple_media_codec_list_free:
- * @codecs: (element-type PurpleMediaCodec) (transfer full): The list of codecs
- * to be freed.
- *
- * Frees a GList of PurpleMediaCodec and its contents.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_codec_list_free(GList *codecs);
-
-/**
- * purple_media_codec_to_string:
- * @codec: The codec to create the string of.
- *
- * Creates a string representation of the codec.
- *
- * Returns: The new string representation.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gchar *purple_media_codec_to_string(PurpleMediaCodec *codec);
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_CODEC_H */
--- a/libpurple/media/enum-types.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "enum-types.h"
-
-/*
- * PurpleMediaCandidateType
- */
-
-GType
-purple_media_candidate_type_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GEnumValue values[] = {
- { PURPLE_MEDIA_CANDIDATE_TYPE_HOST,
- "PURPLE_MEDIA_CANDIDATE_TYPE_HOST",
- "host" },
- { PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX,
- "PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX",
- "srflx" },
- { PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX,
- "PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX",
- "prflx" },
- { PURPLE_MEDIA_CANDIDATE_TYPE_RELAY,
- "PURPLE_MEDIA_CANDIDATE_TYPE_RELAY",
- "relay" },
- { PURPLE_MEDIA_CANDIDATE_TYPE_MULTICAST,
- "PURPLE_MEDIA_CANDIDATE_TYPE_MULTICAST",
- "multicast" },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static("PurpleMediaCandidateType",
- values);
- }
- return type;
-}
-
-/*
- * PurpleMediaCaps
- */
-
-GType
-purple_media_caps_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GEnumValue values[] = {
- { PURPLE_MEDIA_CAPS_NONE,
- "PURPLE_MEDIA_CAPS_NONE", "none" },
- { PURPLE_MEDIA_CAPS_AUDIO,
- "PURPLE_MEDIA_CAPS_AUDIO", "audio" },
- { PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION,
- "PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION",
- "audio-single-direction" },
- { PURPLE_MEDIA_CAPS_VIDEO,
- "PURPLE_MEDIA_CAPS_VIDEO", "video" },
- { PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION,
- "PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION",
- "video-single-direction" },
- { PURPLE_MEDIA_CAPS_AUDIO_VIDEO,
- "PURPLE_MEDIA_CAPS_AUDIO_VIDEO",
- "audio-video" },
- { PURPLE_MEDIA_CAPS_MODIFY_SESSION,
- "PURPLE_MEDIA_CAPS_MODIFY_SESSION",
- "modify-session" },
- { PURPLE_MEDIA_CAPS_CHANGE_DIRECTION,
- "PURPLE_MEDIA_CAPS_CHANGE_DIRECTION",
- "change-direction" },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static("PurpleMediaCaps", values);
- }
- return type;
-}
-
-/*
- * PurpleMediaInfoType
- */
-
-GType
-purple_media_info_type_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GEnumValue values[] = {
- { PURPLE_MEDIA_INFO_HANGUP,
- "PURPLE_MEDIA_INFO_HANGUP", "hangup" },
- { PURPLE_MEDIA_INFO_ACCEPT,
- "PURPLE_MEDIA_INFO_ACCEPT", "accept" },
- { PURPLE_MEDIA_INFO_REJECT,
- "PURPLE_MEDIA_INFO_REJECT", "reject" },
- { PURPLE_MEDIA_INFO_MUTE,
- "PURPLE_MEDIA_INFO_MUTE", "mute" },
- { PURPLE_MEDIA_INFO_UNMUTE,
- "PURPLE_MEDIA_INFO_UNMUTE", "unmute" },
- { PURPLE_MEDIA_INFO_PAUSE,
- "PURPLE_MEDIA_INFO_PAUSE", "pause" },
- { PURPLE_MEDIA_INFO_UNPAUSE,
- "PURPLE_MEDIA_INFO_UNPAUSE", "unpause" },
- { PURPLE_MEDIA_INFO_HOLD,
- "PURPLE_MEDIA_INFO_HOLD", "hold" },
- { PURPLE_MEDIA_INFO_UNHOLD,
- "PURPLE_MEDIA_INFO_HOLD", "unhold" },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static("PurpleMediaInfoType", values);
- }
- return type;
-}
-
-/*
- * PurpleMediaNetworkProtocol
- */
-
-GType
-purple_media_network_protocol_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GEnumValue values[] = {
- { PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
- "PURPLE_MEDIA_NETWORK_PROTOCOL_UDP",
- "udp" },
- { PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE,
- "PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE",
- "tcp-passive" },
- { PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE,
- "PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE",
- "tcp-active" },
- { PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO,
- "PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO",
- "tcp-so" },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static("PurpleMediaNetworkProtocol",
- values);
- }
- return type;
-}
-
-/*
- * PurpleMediaSessionType
- */
-
-GType
-purple_media_session_type_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GFlagsValue values[] = {
- { PURPLE_MEDIA_NONE,
- "PURPLE_MEDIA_NONE", "none" },
- { PURPLE_MEDIA_RECV_AUDIO,
- "PURPLE_MEDIA_RECV_AUDIO", "recv-audio" },
- { PURPLE_MEDIA_SEND_AUDIO,
- "PURPLE_MEDIA_SEND_AUDIO", "send-audio" },
- { PURPLE_MEDIA_RECV_VIDEO,
- "PURPLE_MEDIA_RECV_VIDEO", "recv-video" },
- { PURPLE_MEDIA_SEND_VIDEO,
- "PURPLE_MEDIA_SEND_VIDEO", "send-video" },
- { PURPLE_MEDIA_RECV_APPLICATION,
- "PURPLE_MEDIA_RECV_APPLICATION", "recv-application" },
- { PURPLE_MEDIA_SEND_APPLICATION,
- "PURPLE_MEDIA_SEND_APPLICATION", "send-application" },
- { PURPLE_MEDIA_AUDIO,
- "PURPLE_MEDIA_AUDIO", "audio" },
- { PURPLE_MEDIA_VIDEO,
- "PURPLE_MEDIA_VIDEO", "video" },
- { PURPLE_MEDIA_APPLICATION,
- "PURPLE_MEDIA_APPLICATION", "application" },
- { 0, NULL, NULL }
- };
- type = g_flags_register_static(
- "PurpleMediaSessionType", values);
- }
- return type;
-}
-
-/*
- * PurpleMediaState
- */
-
-GType
-purple_media_state_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GEnumValue values[] = {
- { PURPLE_MEDIA_STATE_NEW,
- "PURPLE_MEDIA_STATE_NEW", "new" },
- { PURPLE_MEDIA_STATE_CONNECTED,
- "PURPLE_MEDIA_STATE_CONNECTED", "connected" },
- { PURPLE_MEDIA_STATE_END,
- "PURPLE_MEDIA_STATE_END", "end" },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static("PurpleMediaState", values);
- }
- return type;
-}
-
--- a/libpurple/media/enum-types.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_ENUM_TYPES_H
-#define PURPLE_MEDIA_ENUM_TYPES_H
-
-#include <glib-object.h>
-
-#include "purpleversion.h"
-
-G_BEGIN_DECLS
-
-/**
- * PURPLE_MEDIA_TYPE_CANDIDATE_TYPE:
- *
- * The standard _get_type macro for #PurpleMediaCandidateType.
- *
- * Since: 3.0
- */
-#define PURPLE_MEDIA_TYPE_CANDIDATE_TYPE (purple_media_candidate_type_get_type())
-
-/**
- * PURPLE_MEDIA_TYPE_CAPS:
- *
- * The standard _get_type macro for #PurpleMediaCaps.
- *
- * Since: 2.7
- */
-#define PURPLE_MEDIA_TYPE_CAPS (purple_media_caps_get_type())
-
-/**
- * PURPLE_MEDIA_TYPE_INFO_TYPE:
- *
- * The standard _get_type macro for #PurpleMediaInfoType.
- *
- * Since: 2.6
- */
-#define PURPLE_MEDIA_TYPE_INFO_TYPE (purple_media_info_type_get_type())
-
-/**
- * PURPLE_MEDIA_TYPE_NETWORK_PROTOCOL:
- *
- * The standard _get_type macro for #PurpleMediaNetworkProtocol.
- *
- * Since: 3.0
- */
-#define PURPLE_MEDIA_TYPE_NETWORK_PROTOCOL (purple_media_network_protocol_get_type())
-
-/**
- * PURPLE_MEDIA_TYPE_SESSION_TYPE:
- *
- * The standard _get_type macro for #PurpleMediaSessionType.
- *
- * Since: 3.0
- */
-#define PURPLE_MEDIA_TYPE_SESSION_TYPE (purple_media_session_type_get_type())
-
-/**
- * PURPLE_MEDIA_TYPE_STATE:
- *
- * The standard _get_type macro for #PurpleMediaState.
- *
- * Since: 3.0
- */
-#define PURPLE_MEDIA_TYPE_STATE (purple_media_state_get_type())
-
-/**
- * PurpleMediaCandidateType:
- * @PURPLE_MEDIA_CANDIDATE_TYPE_HOST: A host candidate (local).
- * @PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX: A server reflexive candidate.
- * @PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX: A peer reflexive candidate.
- * @PURPLE_MEDIA_CANDIDATE_TYPE_RELAY: A relay candidate.
- * @PURPLE_MEDIA_CANDIDATE_TYPE_MULTICAST: A multicast address.
- *
- * Media candidate types
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_CANDIDATE_TYPE_HOST,
- PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX,
- PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX,
- PURPLE_MEDIA_CANDIDATE_TYPE_RELAY,
- PURPLE_MEDIA_CANDIDATE_TYPE_MULTICAST
-} PurpleMediaCandidateType;
-
-/**
- * PurpleMediaCaps:
- * @PURPLE_MEDIA_CAPS_NONE: No capabilities.
- * @PURPLE_MEDIA_CAPS_AUDIO: Bi-directional audio.
- * @PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION: Single direction audio.
- * @PURPLE_MEDIA_CAPS_VIDEO: Bi-directional video.
- * @PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION: Single direction video.
- * @PURPLE_MEDIA_CAPS_AUDIO_VIDEO: Bi-directional audio and video.
- * @PURPLE_MEDIA_CAPS_MODIFY_SESSION: Modifiable session.
- * @PURPLE_MEDIA_CAPS_CHANGE_DIRECTION: Initiator and destination can be
- * switched.
- *
- * Media caps
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_CAPS_NONE = 0,
- PURPLE_MEDIA_CAPS_AUDIO = 1,
- PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION = 1 << 1,
- PURPLE_MEDIA_CAPS_VIDEO = 1 << 2,
- PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION = 1 << 3,
- PURPLE_MEDIA_CAPS_AUDIO_VIDEO = 1 << 4,
- PURPLE_MEDIA_CAPS_MODIFY_SESSION = 1 << 5,
- PURPLE_MEDIA_CAPS_CHANGE_DIRECTION = 1 << 6
-} PurpleMediaCaps;
-
-/**
- * PurpleMediaComponentType:
- * @PURPLE_MEDIA_COMPONENT_NONE: Use this when specifying a component is
- * innapropriate.
- * @PURPLE_MEDIA_COMPONENT_RTP: This component is for RTP data.
- * @PURPLE_MEDIA_COMPONENT_RTCP: This component is for RTCP control.
- *
- * Media component types
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_COMPONENT_NONE = 0,
- PURPLE_MEDIA_COMPONENT_RTP = 1,
- PURPLE_MEDIA_COMPONENT_RTCP = 2
-} PurpleMediaComponentType;
-
-/**
- * PurpleMediaInfoType:
- * @PURPLE_MEDIA_INFO_HANGUP: Terminate the media.
- * @PURPLE_MEDIA_INFO_ACCEPT: Create/join the media.
- * @PURPLE_MEDIA_INFO_REJECT: Terminate the media, possibly noting that it was
- * rejected.
- * @PURPLE_MEDIA_INFO_MUTE: Mute the media.
- * @PURPLE_MEDIA_INFO_UNMUTE: Unmute the media.
- * @PURPLE_MEDIA_INFO_PAUSE: Pause the media.
- * @PURPLE_MEDIA_INFO_UNPAUSE: Unpause the media.
- * @PURPLE_MEDIA_INFO_HOLD: Put the media on hold.
- * @PURPLE_MEDIA_INFO_UNHOLD: Remove the media from hold.
- *
- * Media info types
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_INFO_HANGUP = 0,
- PURPLE_MEDIA_INFO_ACCEPT,
- PURPLE_MEDIA_INFO_REJECT,
- PURPLE_MEDIA_INFO_MUTE,
- PURPLE_MEDIA_INFO_UNMUTE,
- PURPLE_MEDIA_INFO_PAUSE,
- PURPLE_MEDIA_INFO_UNPAUSE,
- PURPLE_MEDIA_INFO_HOLD,
- PURPLE_MEDIA_INFO_UNHOLD
-} PurpleMediaInfoType;
-
-/**
- * PurpleMediaNetworkProtocol:
- * @PURPLE_MEDIA_NETWORK_PROTOCOL_UDP: A UDP based protocol.
- * @PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE: A TCP based protocol, will
- * listen for incoming connections.
- * @PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE: A TCP based protocol, will
- * attempt to open an outbound
- * connection.
- * @PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO: A TCP based protocol, will listen for
- * incoming connections and attempt an
- * outbound connection at the same time
- * as the peer (Simultanuous-Open).
- *
- * Media network protocols
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
- PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE,
- PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE,
- PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO,
-} PurpleMediaNetworkProtocol;
-
-/**
- * PurpleMediaSessionType:
- * @PURPLE_MEDIA_NONE: Used for errors.
- * @PURPLE_MEDIA_RECV_AUDIO: The session has incoming audio.
- * @PURPLE_MEDIA_SEND_AUDIO: The session has outgoing audio.
- * @PURPLE_MEDIA_RECV_VIDEO: The session has incoming video.
- * @PURPLE_MEDIA_SEND_VIDEO: The session has outgoing video.
- * @PURPLE_MEDIA_RECV_APPLICATION: The session has incoming application
- * specific data.
- * @PURPLE_MEDIA_SEND_APPLICATION: The session has outgoing application
- * specific data.
- * @PURPLE_MEDIA_AUDIO: An alias for #PURPLE_MEDIA_RECV_AUDIO and
- * #PURPLE_MEDIA_SEND_AUDIO.
- * @PURPLE_MEDIA_VIDEO: An alias for #PURPLE_MEDIA_RECV_VIDEO and
- * #PURPLE_MEDIA_SEND_VIDEO.
- * @PURPLE_MEDIA_APPLICATION: An alias for #PURPLE_MEDIA_RECV_APPLICATION
- * and #PURPLE_MEDIA_SEND_APPLICATION.
- *
- * Media session types
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_NONE = 0,
- PURPLE_MEDIA_RECV_AUDIO = 1 << 0,
- PURPLE_MEDIA_SEND_AUDIO = 1 << 1,
- PURPLE_MEDIA_RECV_VIDEO = 1 << 2,
- PURPLE_MEDIA_SEND_VIDEO = 1 << 3,
- PURPLE_MEDIA_RECV_APPLICATION = 1 << 4,
- PURPLE_MEDIA_SEND_APPLICATION = 1 << 5,
- PURPLE_MEDIA_AUDIO = PURPLE_MEDIA_RECV_AUDIO | PURPLE_MEDIA_SEND_AUDIO,
- PURPLE_MEDIA_VIDEO = PURPLE_MEDIA_RECV_VIDEO | PURPLE_MEDIA_SEND_VIDEO,
- PURPLE_MEDIA_APPLICATION = PURPLE_MEDIA_RECV_APPLICATION |
- PURPLE_MEDIA_SEND_APPLICATION
-} PurpleMediaSessionType;
-
-/**
- * PurpleMediaState:
- * @PURPLE_MEDIA_STATE_NEW: The media has not yet connected.
- * @PURPLE_MEDIA_STATE_CONNECTED: The media is connected.
- * @PURPLE_MEDIA_STATE_END: The media has previously connected but has since
- * disconnected.
- *
- * Media state-changed types
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef enum {
- PURPLE_MEDIA_STATE_NEW = 0,
- PURPLE_MEDIA_STATE_CONNECTED,
- PURPLE_MEDIA_STATE_END
-} PurpleMediaState;
-
-/**
- * purple_media_candidate_type_get_type:
- *
- * Gets the media candidate type's GType
- *
- * Returns: The media candidate type's GType.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GType purple_media_candidate_type_get_type(void);
-
-/**
- * purple_media_caps_get_type:
- *
- * Gets the type of the media caps flags
- *
- * Returns: The media caps flags' GType
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-GType purple_media_caps_get_type(void);
-
-/**
- * purple_media_info_type_get_type:
- *
- * Gets the type of the info type enum
- *
- * Returns: The info type enum's GType
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GType purple_media_info_type_get_type(void);
-
-/**
- * purple_media_network_protocol_get_type:
- *
- * Gets the media network protocol's GType
- *
- * Returns: The media network protocol's GType.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GType purple_media_network_protocol_get_type(void);
-
-/**
- * purple_media_session_type_get_type:
- *
- * Gets the media session type's GType
- *
- * Returns: The media session type's GType.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GType purple_media_session_type_get_type(void);
-
-/**
- * purple_media_state_get_type:
- *
- * Gets the type of the state enum
- *
- * Returns: The state enum's GType
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-GType purple_media_state_get_type(void);
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_ENUM_TYPES */
--- a/libpurple/mediamanager.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2472 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include <glib/gi18n-lib.h>
-
-#include "debug.h"
-#include "glibcompat.h"
-#include "media.h"
-#include "mediamanager.h"
-#include "prefs.h"
-#include "purpleaccount.h"
-#include "purplepath.h"
-#include "purpleprivate.h"
-
-#include "media-gst.h"
-
-#include <gst/app/app.h>
-
-typedef struct _PurpleMediaOutputWindow PurpleMediaOutputWindow;
-typedef struct _PurpleMediaElementInfoPrivate PurpleMediaElementInfoPrivate;
-
-struct _PurpleMediaOutputWindow
-{
- gulong id;
- PurpleMedia *media;
- gchar *session_id;
- gchar *participant;
- GstElement *sink;
-};
-
-typedef struct
-{
- GstElement *pipeline;
- PurpleMediaCaps ui_caps;
- GList *medias;
- GList *private_medias;
- GList *elements;
- GList *output_windows;
- gulong next_output_window_id;
- GType backend_type;
- GstCaps *video_caps;
-
- PurpleMediaElementInfo *video_src;
- PurpleMediaElementInfo *video_sink;
- PurpleMediaElementInfo *audio_src;
- PurpleMediaElementInfo *audio_sink;
-
- GstDeviceMonitor *device_monitor;
-
- /* Application data streams */
- GList *appdata_info; /* holds PurpleMediaAppDataInfo */
- GMutex appdata_mutex;
- guint appdata_cb_token; /* last used read/write callback token */
-} PurpleMediaManagerPrivate;
-
-/**
- * PurpleMediaManager:
- *
- * The media manager's data.
- */
-struct _PurpleMediaManager
-{
- GObject parent;
-
- /*< private >*/
- PurpleMediaManagerPrivate *priv;
-};
-
-typedef struct {
- PurpleMedia *media;
- GWeakRef media_ref;
- gchar *session_id;
- gchar *participant;
- PurpleMediaAppDataCallbacks callbacks;
- gpointer user_data;
- GDestroyNotify notify;
- GstAppSrc *appsrc;
- GstAppSink *appsink;
- gint num_samples;
- GstSample *current_sample;
- guint sample_offset;
- gboolean writable;
- gboolean connected;
- guint writable_cb_token;
- guint readable_cb_token;
- guint writable_timer_id;
- guint readable_timer_id;
- GCond readable_cond;
-} PurpleMediaAppDataInfo;
-
-static void purple_media_manager_finalize (GObject *object);
-static void free_appdata_info_locked (PurpleMediaAppDataInfo *info);
-static void purple_media_manager_init_device_monitor(PurpleMediaManager *manager);
-static void purple_media_manager_register_static_elements(PurpleMediaManager *manager);
-
-
-enum {
- SIG_INIT_MEDIA,
- SIG_INIT_PRIVATE_MEDIA,
- SIG_UI_CAPS_CHANGED,
- SIG_ELEMENTS_CHANGED,
- N_SIGNALS,
-};
-static guint signals[N_SIGNALS] = {0, };
-
-static PurpleMediaManager *default_manager = NULL;
-
-G_DEFINE_FINAL_TYPE_WITH_PRIVATE(PurpleMediaManager, purple_media_manager,
- G_TYPE_OBJECT);
-
-static void
-purple_media_manager_class_init (PurpleMediaManagerClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
-
- gobject_class->finalize = purple_media_manager_finalize;
-
- /**
- * PurpleMediaManager::init-media:
- * @manager: The instance.
- * @media: The media.
- * @account: The account.
- * @remote_user: The remote user.
- *
- * Emitted to initialize @media.
- *
- * Returns: %TRUE if @media was initialized.
- */
- signals[SIG_INIT_MEDIA] = g_signal_new("init-media",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_BOOLEAN, 3, PURPLE_TYPE_MEDIA,
- G_TYPE_POINTER, G_TYPE_STRING);
-
- /**
- * PurpleMediaManager::init-private-media:
- * @manager: The instance.
- * @media: The media.
- * @account: The account.
- * @remote_user: The remote user.
- *
- * Emitted to initialize @media but not tell the user interface about it.
- *
- * Returns: %TRUE if @media was initialized.
- */
- signals[SIG_INIT_PRIVATE_MEDIA] = g_signal_new("init-private-media",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_BOOLEAN, 3, PURPLE_TYPE_MEDIA,
- G_TYPE_POINTER, G_TYPE_STRING);
-
- /**
- * PurpleMediaManager::ui-caps-changed:
- * @manager: The instance.
- * @new_caps: The new capabilities.
- * @old_caps: The old capabilities.
- *
- * Emitted when the user interface capabilities have changed.
- */
- signals[SIG_UI_CAPS_CHANGED] = g_signal_new("ui-caps-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 2, PURPLE_MEDIA_TYPE_CAPS,
- PURPLE_MEDIA_TYPE_CAPS);
-
- /**
- * PurpleMediaManager::elements-changed:
- * @manager: The instance.
- *
- * Emitted when the elements have changed in @manager.
- */
- signals[SIG_ELEMENTS_CHANGED] = g_signal_new("elements-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-static void
-purple_media_manager_init (PurpleMediaManager *media)
-{
- GError *error = NULL;
-
- media->priv = purple_media_manager_get_instance_private(media);
- media->priv->medias = NULL;
- media->priv->private_medias = NULL;
- media->priv->next_output_window_id = 1;
- media->priv->appdata_info = NULL;
- g_mutex_init (&media->priv->appdata_mutex);
- if (gst_init_check(NULL, NULL, &error)) {
- purple_media_manager_register_static_elements(media);
- purple_media_manager_init_device_monitor(media);
- } else {
- purple_debug_error("mediamanager",
- "GStreamer failed to initialize: %s.",
- error ? error->message : "");
- g_clear_error(&error);
- }
-
- purple_prefs_add_none("/purple/media");
- purple_prefs_add_none("/purple/media/audio");
- purple_prefs_add_int("/purple/media/audio/silence_threshold", 5);
- purple_prefs_add_none("/purple/media/audio/volume");
- purple_prefs_add_int("/purple/media/audio/volume/input", 10);
- purple_prefs_add_int("/purple/media/audio/volume/output", 10);
-}
-
-static void
-purple_media_manager_finalize(GObject *obj)
-{
- PurpleMediaManager *manager = PURPLE_MEDIA_MANAGER(obj);
- PurpleMediaManagerPrivate *priv = NULL;
-
- priv = purple_media_manager_get_instance_private(manager);
-
- if (priv->device_monitor) {
- gst_device_monitor_stop(priv->device_monitor);
- g_object_unref(priv->device_monitor);
- }
-
- g_clear_list(&priv->medias, g_object_unref);
- g_clear_list(&priv->private_medias, g_object_unref);
- g_clear_list(&priv->elements, g_object_unref);
- g_clear_pointer(&priv->video_caps, gst_caps_unref);
- g_clear_list(&priv->appdata_info,
- (GDestroyNotify)free_appdata_info_locked);
- g_mutex_clear (&priv->appdata_mutex);
-
- G_OBJECT_CLASS(purple_media_manager_parent_class)->finalize(obj);
-}
-
-PurpleMediaManager *
-purple_media_manager_get(void)
-{
- if(!PURPLE_IS_MEDIA_MANAGER(default_manager)) {
- default_manager = g_object_new(PURPLE_TYPE_MEDIA_MANAGER, NULL);
- g_object_add_weak_pointer(G_OBJECT(default_manager),
- (gpointer *)&default_manager);
- }
-
- return default_manager;
-}
-
-void
-purple_media_manager_shutdown(void) {
- g_clear_object(&default_manager);
-}
-
-static gboolean
-pipeline_bus_call(G_GNUC_UNUSED GstBus *bus, GstMessage *msg,
- G_GNUC_UNUSED PurpleMediaManager *manager)
-{
- switch(GST_MESSAGE_TYPE(msg)) {
- case GST_MESSAGE_EOS:
- purple_debug_info("mediamanager", "End of Stream");
- break;
- case GST_MESSAGE_ERROR: {
- gchar *debug = NULL;
- GError *err = NULL;
-
- gst_message_parse_error(msg, &err, &debug);
-
- purple_debug_error("mediamanager", "gst pipeline error: %s",
- err->message);
- g_error_free(err);
-
- if (debug) {
- purple_debug_error("mediamanager", "Debug details: %s", debug);
- g_free(debug);
- }
- break;
- }
- default:
- break;
- }
- return TRUE;
-}
-
-GstElement *
-purple_media_manager_get_pipeline(PurpleMediaManager *manager)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), NULL);
-
- if (manager->priv->pipeline == NULL) {
- GstBus *bus;
- manager->priv->pipeline = gst_pipeline_new(NULL);
-
- bus = gst_pipeline_get_bus(
- GST_PIPELINE(manager->priv->pipeline));
- gst_bus_add_signal_watch(GST_BUS(bus));
- g_signal_connect(G_OBJECT(bus), "message",
- G_CALLBACK(pipeline_bus_call), manager);
- gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL, NULL);
- gst_object_unref(bus);
-
- gst_element_set_state(manager->priv->pipeline,
- GST_STATE_PLAYING);
- }
-
- return manager->priv->pipeline;
-}
-
-static PurpleMedia *
-create_media(PurpleMediaManager *manager,
- PurpleAccount *account,
- const char *conference_type,
- const char *remote_user,
- gboolean initiator,
- gboolean private)
-{
- PurpleMedia *media;
- guint signal_id;
-
- media = g_object_new(
- PURPLE_TYPE_MEDIA,
- "manager", manager,
- "account", account,
- "conference-type", conference_type,
- "initiator", initiator,
- NULL);
-
- signal_id = private ?
- signals[SIG_INIT_PRIVATE_MEDIA] :
- signals[SIG_INIT_MEDIA];
-
- if (g_signal_has_handler_pending(manager, signal_id, 0, FALSE)) {
- gboolean signal_ret;
-
- g_signal_emit(manager, signal_id, 0, media, account, remote_user,
- &signal_ret);
- if (signal_ret == FALSE) {
- g_object_unref(media);
- return NULL;
- }
- }
-
- if (private) {
- manager->priv->private_medias = g_list_append(
- manager->priv->private_medias, media);
- } else {
- manager->priv->medias = g_list_append(manager->priv->medias, media);
- }
-
- return media;
-}
-
-static GList *
-get_media(PurpleMediaManager *manager, gboolean private)
-{
- if (private) {
- return manager->priv->private_medias;
- } else {
- return manager->priv->medias;
- }
-}
-
-static GList *
-get_media_by_account(PurpleMediaManager *manager,
- PurpleAccount *account, gboolean private)
-{
- GList *media = NULL;
- GList *iter;
- PurpleAccount *media_account;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), NULL);
-
- if (private) {
- iter = manager->priv->private_medias;
- } else {
- iter = manager->priv->medias;
- }
- for (; iter; iter = g_list_next(iter)) {
- media_account = purple_media_get_account(iter->data);
- if (media_account == account) {
- media = g_list_prepend(media, iter->data);
- }
- g_object_unref (media_account);
- }
-
- return media;
-}
-
-void
-purple_media_manager_remove_media(PurpleMediaManager *manager, PurpleMedia *media)
-{
- GList *list;
- GList **medias = NULL;
-
- g_return_if_fail(manager != NULL);
-
- if ((list = g_list_find(manager->priv->medias, media))) {
- medias = &manager->priv->medias;
- } else if ((list = g_list_find(manager->priv->private_medias, media))) {
- medias = &manager->priv->private_medias;
- }
-
- if (list) {
- *medias = g_list_delete_link(*medias, list);
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- list = manager->priv->appdata_info;
- while (list) {
- PurpleMediaAppDataInfo *info = list->data;
- GList *next = list->next;
-
- if (info->media == media) {
- manager->priv->appdata_info = g_list_delete_link (
- manager->priv->appdata_info, list);
- free_appdata_info_locked (info);
- }
-
- list = next;
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
- }
-}
-
-PurpleMedia *
-purple_media_manager_create_media(PurpleMediaManager *manager,
- PurpleAccount *account,
- const char *conference_type,
- const char *remote_user,
- gboolean initiator)
-{
- return create_media (manager, account, conference_type,
- remote_user, initiator, FALSE);
-}
-
-GList *
-purple_media_manager_get_media(PurpleMediaManager *manager)
-{
- return get_media (manager, FALSE);
-}
-
-GList *
-purple_media_manager_get_media_by_account(PurpleMediaManager *manager,
- PurpleAccount *account)
-{
- return get_media_by_account (manager, account, FALSE);
-}
-
-PurpleMedia *
-purple_media_manager_create_private_media(PurpleMediaManager *manager,
- PurpleAccount *account,
- const char *conference_type,
- const char *remote_user,
- gboolean initiator)
-{
- return create_media (manager, account, conference_type,
- remote_user, initiator, TRUE);
-}
-
-GList *
-purple_media_manager_get_private_media(PurpleMediaManager *manager)
-{
- return get_media (manager, TRUE);
-}
-
-GList *
-purple_media_manager_get_private_media_by_account(PurpleMediaManager *manager,
- PurpleAccount *account)
-{
- return get_media_by_account (manager, account, TRUE);
-}
-
-static void
-free_appdata_info_locked (PurpleMediaAppDataInfo *info)
-{
- GstAppSrcCallbacks null_src_cb = {
- .need_data = NULL,
- .enough_data = NULL,
- .seek_data = NULL,
- };
- GstAppSinkCallbacks null_sink_cb = {
- .eos = NULL,
- .new_preroll = NULL,
- .new_sample = NULL,
- };
-
- if (info->notify) {
- info->notify(info->user_data);
- }
-
- info->media = NULL;
- if (info->appsrc) {
- /* Will call appsrc_destroyed. */
- gst_app_src_set_callbacks (info->appsrc, &null_src_cb,
- NULL, NULL);
- }
- if (info->appsink) {
- /* Will call appsink_destroyed. */
- gst_app_sink_set_callbacks (info->appsink, &null_sink_cb,
- NULL, NULL);
- }
-
- /* Make sure no other thread is using the structure */
- g_free (info->session_id);
- g_free (info->participant);
-
- /* This lets the potential read or write callbacks waiting for appdata_mutex
- * know the info structure has been destroyed. */
- info->readable_cb_token = 0;
- info->writable_cb_token = 0;
-
- g_clear_handle_id(&info->readable_timer_id, g_source_remove);
- g_clear_handle_id(&info->writable_timer_id, g_source_remove);
-
- g_clear_pointer(&info->current_sample, gst_sample_unref);
-
- /* Unblock any reading thread before destroying the GCond */
- g_cond_broadcast (&info->readable_cond);
-
- g_cond_clear (&info->readable_cond);
-
- g_slice_free (PurpleMediaAppDataInfo, info);
-}
-
-/*
- * Get an app data info struct associated with a session and lock the mutex
- * We don't want to return an info struct and unlock then it gets destroyed
- * so we need to return it with the lock still taken
- */
-static PurpleMediaAppDataInfo *
-get_app_data_info_and_lock (PurpleMediaManager *manager,
- PurpleMedia *media, const gchar *session_id, const gchar *participant)
-{
- GList *i;
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- for (i = manager->priv->appdata_info; i; i = i->next) {
- PurpleMediaAppDataInfo *info = i->data;
-
- if (info->media == media &&
- purple_strequal (info->session_id, session_id) &&
- (participant == NULL ||
- purple_strequal (info->participant, participant))) {
- return info;
- }
- }
-
- return NULL;
-}
-
-/*
- * Get an app data info struct associated with a session and lock the mutex
- * if it doesn't exist, we create it.
- */
-static PurpleMediaAppDataInfo *
-ensure_app_data_info_and_lock (PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant)
-{
- PurpleMediaAppDataInfo * info = get_app_data_info_and_lock (manager, media,
- session_id, participant);
-
- if (info == NULL) {
- info = g_slice_new0 (PurpleMediaAppDataInfo);
- info->media = media;
- g_weak_ref_init (&info->media_ref, media);
- info->session_id = g_strdup (session_id);
- info->participant = g_strdup (participant);
- g_cond_init (&info->readable_cond);
- manager->priv->appdata_info = g_list_prepend (
- manager->priv->appdata_info, info);
- }
-
- return info;
-}
-
-
-static void
-request_pad_unlinked_cb(GstPad *pad, G_GNUC_UNUSED GstPad *peer,
- G_GNUC_UNUSED gpointer user_data)
-{
- GstElement *parent = GST_ELEMENT_PARENT(pad);
- GstIterator *iter;
- GValue tmp = G_VALUE_INIT;
- GstIteratorResult result;
-
- gst_element_release_request_pad(parent, pad);
-
- iter = gst_element_iterate_src_pads(parent);
-
- result = gst_iterator_next(iter, &tmp);
-
- if (result == GST_ITERATOR_DONE) {
- gst_element_set_locked_state(parent, TRUE);
- gst_element_set_state(parent, GST_STATE_NULL);
- gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(parent)), parent);
- } else if (result == GST_ITERATOR_OK) {
- g_value_reset(&tmp);
- }
-
- gst_iterator_free(iter);
-}
-
-static void
-nonunique_src_unlinked_cb(GstPad *pad, G_GNUC_UNUSED GstPad *peer,
- G_GNUC_UNUSED gpointer user_data)
-{
- GstElement *element = GST_ELEMENT_PARENT(pad);
- gst_element_set_locked_state(element, TRUE);
- gst_element_set_state(element, GST_STATE_NULL);
- gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(element)), element);
-}
-
-void
-purple_media_manager_set_video_caps(PurpleMediaManager *manager, GstCaps *caps)
-{
- g_clear_pointer(&manager->priv->video_caps, gst_caps_unref);
-
- manager->priv->video_caps = caps;
-
- if (manager->priv->pipeline && manager->priv->video_src) {
- gchar *id = purple_media_element_info_get_id(manager->priv->video_src);
- GstElement *src = gst_bin_get_by_name(GST_BIN(manager->priv->pipeline), id);
-
- if (src) {
- GstElement *capsfilter = gst_bin_get_by_name(GST_BIN(src), "protocol_video_caps");
- if (capsfilter) {
- g_object_set(capsfilter, "caps", caps, NULL);
- gst_object_unref (capsfilter);
- }
- gst_object_unref (src);
- }
-
- g_free(id);
- }
-}
-
-GstCaps *
-purple_media_manager_get_video_caps(PurpleMediaManager *manager)
-{
- if (manager->priv->video_caps == NULL) {
- manager->priv->video_caps = gst_caps_from_string("video/x-raw,"
- "width=[250,352], height=[200,288], framerate=[1/1,20/1]");
- }
-
- return manager->priv->video_caps;
-}
-
-/*
- * Calls the appdata writable callback from the main thread.
- * This needs to grab the appdata lock and make sure it didn't get destroyed
- * before calling the callback.
- */
-static gboolean
-appsrc_writable (gpointer user_data)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
- PurpleMediaAppDataInfo *info = user_data;
- void (*writable_cb) (PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant, gboolean writable,
- gpointer user_data);
- PurpleMedia *media;
- gchar *session_id;
- gchar *participant;
- gboolean writable;
- gpointer cb_data;
- guint *cb_token_ptr = &info->writable_cb_token;
- guint cb_token = *cb_token_ptr;
-
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- if (cb_token == 0 || cb_token != *cb_token_ptr) {
- /* In case info was freed while we were waiting for the mutex to unlock
- * we still have a pointer to the cb_token which should still be
- * accessible since it's in the Glib slice allocator. It gets set to 0
- * just after the timeout is canceled which happens also before the
- * AppDataInfo is freed, so even if that memory slice gets reused, the
- * cb_token would be different from its previous value (unless
- * extremely unlucky). So checking if the value for the cb_token changed
- * should be enough to prevent any kind of race condition in which the
- * media/AppDataInfo gets destroyed in one thread while the timeout was
- * triggered and is waiting on the mutex to get unlocked in this thread
- */
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return FALSE;
- }
- writable_cb = info->callbacks.writable;
- media = g_weak_ref_get (&info->media_ref);
- session_id = g_strdup (info->session_id);
- participant = g_strdup (info->participant);
- writable = info->writable && info->connected;
- cb_data = info->user_data;
-
- info->writable_cb_token = 0;
- g_mutex_unlock (&manager->priv->appdata_mutex);
-
-
- if (writable_cb && media) {
- writable_cb (manager, media, session_id, participant, writable,
- cb_data);
- }
-
- g_object_unref (media);
- g_free (session_id);
- g_free (participant);
-
- return FALSE;
-}
-
-/*
- * Schedule a writable callback to be called from the main thread.
- * We need to do this because need-data/enough-data signals from appsrc
- * will come from the streaming thread and we need to create
- * a source that we attach to the main context but we can't use
- * g_main_context_invoke since we need to be able to cancel the source if the
- * media gets destroyed.
- * We use a timeout source instead of idle source, so the callback gets a higher
- * priority
- */
-static void
-call_appsrc_writable_locked (PurpleMediaAppDataInfo *info)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
-
- /* We already have a writable callback scheduled, don't create another one */
- if (info->writable_cb_token || info->callbacks.writable == NULL) {
- return;
- }
-
- /* We can't use writable_timer_id as a token, because the timeout is added
- * into libpurple's main event loop, which runs in a different thread than
- * from where call_appsrc_writable_locked() was called. Consequently, the
- * callback may run even before g_timeout_add() returns the timer ID
- * to us. */
- info->writable_cb_token = ++manager->priv->appdata_cb_token;
- info->writable_timer_id = g_timeout_add (0, appsrc_writable, info);
-}
-
-static void
-appsrc_need_data(G_GNUC_UNUSED GstAppSrc *appsrc, G_GNUC_UNUSED guint length,
- gpointer user_data)
-{
- PurpleMediaAppDataInfo *info = user_data;
- PurpleMediaManager *manager = purple_media_manager_get ();
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- if (!info->writable) {
- info->writable = TRUE;
- /* Only signal writable if we also established a connection */
- if (info->connected) {
- call_appsrc_writable_locked (info);
- }
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
-}
-
-static void
-appsrc_enough_data(G_GNUC_UNUSED GstAppSrc *appsrc, gpointer user_data)
-{
- PurpleMediaAppDataInfo *info = user_data;
- PurpleMediaManager *manager = purple_media_manager_get ();
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- if (info->writable) {
- info->writable = FALSE;
- call_appsrc_writable_locked (info);
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
-}
-
-static gboolean
-appsrc_seek_data(G_GNUC_UNUSED GstAppSrc *appsrc, G_GNUC_UNUSED guint64 offset,
- G_GNUC_UNUSED gpointer user_data)
-{
- return FALSE;
-}
-
-static void
-appsrc_destroyed (PurpleMediaAppDataInfo *info)
-{
- PurpleMediaManager *manager;
-
- if (!info->media) {
- /* PurpleMediaAppDataInfo is being freed. Return at once. */
- return;
- }
-
- manager = purple_media_manager_get ();
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- info->appsrc = NULL;
- if (info->writable) {
- info->writable = FALSE;
- call_appsrc_writable_locked (info);
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
-}
-
-static void
-media_established_cb(G_GNUC_UNUSED PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant,
- G_GNUC_UNUSED PurpleMediaCandidate *local_candidate,
- G_GNUC_UNUSED PurpleMediaCandidate *remote_candidate,
- PurpleMediaAppDataInfo *info)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- info->connected = TRUE;
- /* We established the connection, if we were writable, then we need to
- * signal it now */
- if (info->writable) {
- call_appsrc_writable_locked (info);
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
-}
-
-static GstElement *
-create_send_appsrc(G_GNUC_UNUSED PurpleMediaElementInfo *element_info,
- PurpleMedia *media, const char *session_id,
- const char *participant)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
- PurpleMediaAppDataInfo * info = ensure_app_data_info_and_lock (manager,
- media, session_id, participant);
- GstElement *appsrc = (GstElement *)info->appsrc;
-
- if (appsrc == NULL) {
- GstAppSrcCallbacks callbacks = {
- .need_data = appsrc_need_data,
- .enough_data = appsrc_enough_data,
- .seek_data = appsrc_seek_data,
- };
- GstCaps *caps = gst_caps_new_empty_simple ("application/octet-stream");
-
- appsrc = gst_element_factory_make("appsrc", NULL);
-
- info->appsrc = (GstAppSrc *)appsrc;
-
- gst_app_src_set_caps (info->appsrc, caps);
- gst_app_src_set_callbacks (info->appsrc,
- &callbacks, info, (GDestroyNotify) appsrc_destroyed);
- g_signal_connect (media, "candidate-pair-established",
- (GCallback) media_established_cb, info);
- gst_caps_unref (caps);
- }
-
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return appsrc;
-}
-
-static void
-appsink_eos(G_GNUC_UNUSED GstAppSink *appsink,
- G_GNUC_UNUSED gpointer user_data)
-{
-}
-
-static GstFlowReturn
-appsink_new_preroll(G_GNUC_UNUSED GstAppSink *appsink,
- G_GNUC_UNUSED gpointer user_data)
-{
- return GST_FLOW_OK;
-}
-
-static gboolean
-appsink_readable (gpointer user_data)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
- PurpleMediaAppDataInfo *info = user_data;
- void (*readable_cb) (PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant, gpointer user_data);
- PurpleMedia *media;
- gchar *session_id;
- gchar *participant;
- gpointer cb_data;
- guint *cb_token_ptr = &info->readable_cb_token;
- guint cb_token = *cb_token_ptr;
- gboolean run_again = FALSE;
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- if (cb_token == 0 || cb_token != *cb_token_ptr) {
- /* Avoided a race condition (see writable callback) */
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return FALSE;
- }
-
- if (info->callbacks.readable &&
- (info->num_samples > 0 || info->current_sample != NULL)) {
- readable_cb = info->callbacks.readable;
- media = g_weak_ref_get (&info->media_ref);
- session_id = g_strdup (info->session_id);
- participant = g_strdup (info->participant);
- cb_data = info->user_data;
- g_mutex_unlock (&manager->priv->appdata_mutex);
-
- readable_cb(manager, media, session_id, participant, cb_data);
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- g_object_unref (media);
- g_free (session_id);
- g_free (participant);
- if (cb_token != *cb_token_ptr) {
- /* We got cancelled */
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return FALSE;
- }
- }
-
- /* Do we still have samples? Schedule appsink_readable again. We break here
- * so that other events get a chance to be processed too. */
- if (info->num_samples > 0 || info->current_sample != NULL) {
- run_again = TRUE;
- } else {
- info->readable_cb_token = 0;
- }
-
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return run_again;
-}
-
-static void
-call_appsink_readable_locked (PurpleMediaAppDataInfo *info)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
-
- /* We must signal that a new sample has arrived to release blocking reads */
- g_cond_broadcast (&info->readable_cond);
-
- /* We already have a writable callback scheduled, don't create another one */
- if (info->readable_cb_token || info->callbacks.readable == NULL) {
- return;
- }
-
- info->readable_cb_token = ++manager->priv->appdata_cb_token;
- info->readable_timer_id = g_timeout_add (0, appsink_readable, info);
-}
-
-static GstFlowReturn
-appsink_new_sample(G_GNUC_UNUSED GstAppSink *appsink, gpointer user_data)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
- PurpleMediaAppDataInfo *info = user_data;
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- info->num_samples++;
- call_appsink_readable_locked (info);
- g_mutex_unlock (&manager->priv->appdata_mutex);
-
- return GST_FLOW_OK;
-}
-
-static void
-appsink_destroyed (PurpleMediaAppDataInfo *info)
-{
- PurpleMediaManager *manager;
-
- if (!info->media) {
- /* PurpleMediaAppDataInfo is being freed. Return at once. */
- return;
- }
-
- manager = purple_media_manager_get ();
-
- g_mutex_lock (&manager->priv->appdata_mutex);
- info->appsink = NULL;
- info->num_samples = 0;
- g_mutex_unlock (&manager->priv->appdata_mutex);
-}
-
-static GstElement *
-create_recv_appsink(G_GNUC_UNUSED PurpleMediaElementInfo *element_info,
- PurpleMedia *media, const char *session_id,
- const char *participant)
-{
- PurpleMediaManager *manager = purple_media_manager_get ();
- PurpleMediaAppDataInfo * info = ensure_app_data_info_and_lock (manager,
- media, session_id, participant);
- GstElement *appsink = (GstElement *)info->appsink;
-
- if (appsink == NULL) {
- GstAppSinkCallbacks callbacks = {
- .eos = appsink_eos,
- .new_preroll = appsink_new_preroll,
- .new_sample = appsink_new_sample,
- };
- GstCaps *caps = gst_caps_new_empty_simple ("application/octet-stream");
-
- appsink = gst_element_factory_make("appsink", NULL);
-
- info->appsink = (GstAppSink *)appsink;
-
- gst_app_sink_set_caps (info->appsink, caps);
- gst_app_sink_set_callbacks (info->appsink,
- &callbacks, info, (GDestroyNotify) appsink_destroyed);
- gst_caps_unref (caps);
-
- }
-
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return appsink;
-}
-
-static PurpleMediaElementInfo *
-get_send_application_element_info(void)
-{
- static PurpleMediaElementInfo *info = NULL;
-
- if (info == NULL) {
- info = g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "pidginappsrc",
- "name", "Pidgin Application Source",
- "type", PURPLE_MEDIA_ELEMENT_APPLICATION
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC,
- "create-cb", create_send_appsrc, NULL);
- }
-
- return info;
-}
-
-static PurpleMediaElementInfo *
-get_recv_application_element_info(void)
-{
- static PurpleMediaElementInfo *info = NULL;
-
- if (info == NULL) {
- info = g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "pidginappsink",
- "name", "Pidgin Application Sink",
- "type", PURPLE_MEDIA_ELEMENT_APPLICATION
- | PURPLE_MEDIA_ELEMENT_SINK
- | PURPLE_MEDIA_ELEMENT_ONE_SINK,
- "create-cb", create_recv_appsink, NULL);
- }
-
- return info;
-}
-
-GstElement *
-purple_media_manager_get_element(PurpleMediaManager *manager,
- PurpleMediaSessionType type, PurpleMedia *media,
- const gchar *session_id, const gchar *participant)
-{
- GstElement *ret = NULL;
- PurpleMediaElementInfo *info = NULL;
- PurpleMediaElementType element_type;
-
- if (type & PURPLE_MEDIA_SEND_AUDIO) {
- info = manager->priv->audio_src;
- } else if (type & PURPLE_MEDIA_RECV_AUDIO) {
- info = manager->priv->audio_sink;
- } else if (type & PURPLE_MEDIA_SEND_VIDEO) {
- info = manager->priv->video_src;
- } else if (type & PURPLE_MEDIA_RECV_VIDEO) {
- info = manager->priv->video_sink;
- } else if (type & PURPLE_MEDIA_SEND_APPLICATION) {
- info = get_send_application_element_info ();
- } else if (type & PURPLE_MEDIA_RECV_APPLICATION) {
- info = get_recv_application_element_info ();
- }
-
- if (info == NULL) {
- return NULL;
- }
-
- element_type = purple_media_element_info_get_element_type(info);
-
- if (element_type & PURPLE_MEDIA_ELEMENT_UNIQUE &&
- element_type & PURPLE_MEDIA_ELEMENT_SRC) {
- GstElement *tee;
- GstPad *pad;
- GstPad *ghost;
- gchar *id = purple_media_element_info_get_id(info);
-
- ret = gst_bin_get_by_name(GST_BIN(
- purple_media_manager_get_pipeline(
- manager)), id);
-
- if (ret == NULL) {
- GstElement *bin, *fakesink;
- ret = purple_media_element_info_call_create(info,
- media, session_id, participant);
- bin = gst_bin_new(id);
- tee = gst_element_factory_make("tee", "tee");
- gst_bin_add_many(GST_BIN(bin), ret, tee, NULL);
-
- if (type & PURPLE_MEDIA_SEND_VIDEO) {
- GstElement *videoscale;
- GstElement *capsfilter;
-
- videoscale = gst_element_factory_make("videoscale", NULL);
- capsfilter = gst_element_factory_make("capsfilter", "protocol_video_caps");
-
- g_object_set(capsfilter,
- "caps", purple_media_manager_get_video_caps(manager), NULL);
-
- gst_bin_add_many(GST_BIN(bin), videoscale, capsfilter, NULL);
- gst_element_link_many(ret, videoscale, capsfilter, tee, NULL);
- } else {
- gst_element_link(ret, tee);
- }
-
- /*
- * This shouldn't be necessary, but it stops it from
- * giving a not-linked error upon destruction
- */
- fakesink = gst_element_factory_make("fakesink", NULL);
- g_object_set(fakesink,
- "async", FALSE,
- "sync", FALSE,
- "enable-last-sample", FALSE,
- NULL);
- gst_bin_add(GST_BIN(bin), fakesink);
- gst_element_link(tee, fakesink);
-
- ret = bin;
- gst_object_ref(ret);
- gst_bin_add(GST_BIN(purple_media_manager_get_pipeline(
- manager)), ret);
- }
- g_free(id);
-
- tee = gst_bin_get_by_name(GST_BIN(ret), "tee");
-#if GST_CHECK_VERSION(1, 19, 1)
- pad = gst_element_request_pad_simple(tee, "src_%u");
-#else
- pad = gst_element_get_request_pad(tee, "src_%u");
-#endif
- gst_object_unref(tee);
- ghost = gst_ghost_pad_new(NULL, pad);
- gst_object_unref(pad);
- g_signal_connect(GST_PAD(ghost), "unlinked",
- G_CALLBACK(request_pad_unlinked_cb), NULL);
- gst_pad_set_active(ghost, TRUE);
- gst_element_add_pad(ret, ghost);
- } else {
- ret = purple_media_element_info_call_create(info,
- media, session_id, participant);
- if (element_type & PURPLE_MEDIA_ELEMENT_SRC) {
- GstPad *pad = gst_element_get_static_pad(ret, "src");
- g_signal_connect(pad, "unlinked",
- G_CALLBACK(nonunique_src_unlinked_cb), NULL);
- gst_object_unref(pad);
- gst_object_ref(ret);
- gst_bin_add(GST_BIN(purple_media_manager_get_pipeline(manager)),
- ret);
- }
- }
-
- if (ret == NULL) {
- purple_debug_error("media", "Error creating source or sink\n");
- }
-
- return ret;
-}
-
-PurpleMediaElementInfo *
-purple_media_manager_get_element_info(PurpleMediaManager *manager,
- const gchar *id)
-{
- GList *iter;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), NULL);
- g_return_val_if_fail(id != NULL, NULL);
-
- iter = manager->priv->elements;
-
- for (; iter; iter = g_list_next(iter)) {
- gchar *element_id = purple_media_element_info_get_id(iter->data);
- if (purple_strequal(element_id, id)) {
- g_free(element_id);
- g_object_ref(iter->data);
- return iter->data;
- }
- g_free(element_id);
- }
-
- return NULL;
-}
-
-static GQuark
-element_info_to_detail(PurpleMediaElementInfo *info)
-{
- PurpleMediaElementType type;
-
- type = purple_media_element_info_get_element_type(info);
-
- if (type & PURPLE_MEDIA_ELEMENT_AUDIO) {
- if (type & PURPLE_MEDIA_ELEMENT_SRC) {
- return g_quark_from_string("audiosrc");
- } else if (type & PURPLE_MEDIA_ELEMENT_SINK) {
- return g_quark_from_string("audiosink");
- }
- } else if (type & PURPLE_MEDIA_ELEMENT_VIDEO) {
- if (type & PURPLE_MEDIA_ELEMENT_SRC) {
- return g_quark_from_string("videosrc");
- } else if (type & PURPLE_MEDIA_ELEMENT_SINK) {
- return g_quark_from_string("videosink");
- }
- }
-
- return 0;
-}
-
-gboolean
-purple_media_manager_register_element(PurpleMediaManager *manager,
- PurpleMediaElementInfo *info)
-{
- PurpleMediaElementInfo *info2;
- gchar *id;
- GQuark detail;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE);
- g_return_val_if_fail(info != NULL, FALSE);
-
- id = purple_media_element_info_get_id(info);
- info2 = purple_media_manager_get_element_info(manager, id);
- g_free(id);
-
- if (info2 != NULL) {
- g_object_unref(info2);
- g_object_unref(info);
- return FALSE;
- }
-
- manager->priv->elements = g_list_prepend(manager->priv->elements, info);
-
- detail = element_info_to_detail(info);
- if (detail != 0) {
- g_signal_emit(manager, signals[SIG_ELEMENTS_CHANGED], detail);
- }
-
- return TRUE;
-}
-
-gboolean
-purple_media_manager_unregister_element(PurpleMediaManager *manager,
- const gchar *id)
-{
- PurpleMediaElementInfo *info;
- GQuark detail;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE);
-
- info = purple_media_manager_get_element_info(manager, id);
-
- if (info == NULL) {
- return FALSE;
- }
-
- if (manager->priv->audio_src == info) {
- manager->priv->audio_src = NULL;
- }
- if (manager->priv->audio_sink == info) {
- manager->priv->audio_sink = NULL;
- }
- if (manager->priv->video_src == info) {
- manager->priv->video_src = NULL;
- }
- if (manager->priv->video_sink == info) {
- manager->priv->video_sink = NULL;
- }
-
- detail = element_info_to_detail(info);
-
- manager->priv->elements = g_list_remove(
- manager->priv->elements, info);
- g_object_unref(info);
-
- if (detail != 0) {
- g_signal_emit(manager, signals[SIG_ELEMENTS_CHANGED], detail);
- }
-
- return TRUE;
-}
-
-gboolean
-purple_media_manager_set_active_element(PurpleMediaManager *manager,
- PurpleMediaElementInfo *info)
-{
- PurpleMediaElementInfo *info2;
- PurpleMediaElementType type;
- gboolean ret = FALSE;
- gchar *id;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE);
- g_return_val_if_fail(info != NULL, FALSE);
-
- id = purple_media_element_info_get_id(info);
- info2 = purple_media_manager_get_element_info(manager, id);
- g_free(id);
-
- if (info2 == NULL) {
- purple_media_manager_register_element(manager, g_object_ref(info));
- } else {
- g_object_unref(info2);
- }
-
- type = purple_media_element_info_get_element_type(info);
-
- if (type & PURPLE_MEDIA_ELEMENT_SRC) {
- if (type & PURPLE_MEDIA_ELEMENT_AUDIO) {
- manager->priv->audio_src = info;
- ret = TRUE;
- }
- if (type & PURPLE_MEDIA_ELEMENT_VIDEO) {
- manager->priv->video_src = info;
- ret = TRUE;
- }
- }
- if (type & PURPLE_MEDIA_ELEMENT_SINK) {
- if (type & PURPLE_MEDIA_ELEMENT_AUDIO) {
- manager->priv->audio_sink = info;
- ret = TRUE;
- }
- if (type & PURPLE_MEDIA_ELEMENT_VIDEO) {
- manager->priv->video_sink = info;
- ret = TRUE;
- }
- }
-
- return ret;
-}
-
-PurpleMediaElementInfo *
-purple_media_manager_get_active_element(PurpleMediaManager *manager,
- PurpleMediaElementType type)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), NULL);
-
- if (type & PURPLE_MEDIA_ELEMENT_SRC) {
- if (type & PURPLE_MEDIA_ELEMENT_AUDIO) {
- return manager->priv->audio_src;
- } else if (type & PURPLE_MEDIA_ELEMENT_VIDEO) {
- return manager->priv->video_src;
- } else if (type & PURPLE_MEDIA_ELEMENT_APPLICATION) {
- return get_send_application_element_info ();
- }
- } else if (type & PURPLE_MEDIA_ELEMENT_SINK) {
- if (type & PURPLE_MEDIA_ELEMENT_AUDIO) {
- return manager->priv->audio_sink;
- } else if (type & PURPLE_MEDIA_ELEMENT_VIDEO) {
- return manager->priv->video_sink;
- } else if (type & PURPLE_MEDIA_ELEMENT_APPLICATION) {
- return get_recv_application_element_info ();
- }
- }
-
- return NULL;
-}
-
-gboolean
-purple_media_manager_create_output_window(PurpleMediaManager *manager,
- PurpleMedia *media, const gchar *session_id,
- const gchar *participant)
-{
- GList *iter;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- iter = manager->priv->output_windows;
- for(; iter; iter = g_list_next(iter)) {
- PurpleMediaOutputWindow *ow = iter->data;
-
- if (ow->sink == NULL && ow->media == media &&
- purple_strequal(participant, ow->participant) &&
- purple_strequal(session_id, ow->session_id)) {
- GstElement *queue, *convert, *scale;
- GstElement *tee = purple_media_get_tee(media,
- session_id, participant);
-
- if (tee == NULL) {
- continue;
- }
-
- queue = gst_element_factory_make("queue", NULL);
- convert = gst_element_factory_make("videoconvert", NULL);
- scale = gst_element_factory_make("videoscale", NULL);
- ow->sink = purple_media_manager_get_element(
- manager, PURPLE_MEDIA_RECV_VIDEO,
- ow->media, ow->session_id,
- ow->participant);
-
- if (participant == NULL) {
- /* aka this is a preview sink */
- GObjectClass *klass =
- G_OBJECT_GET_CLASS(ow->sink);
- if (g_object_class_find_property(klass, "sync")) {
- g_object_set(ow->sink, "sync", FALSE, NULL);
- }
- if (g_object_class_find_property(klass, "async")) {
- g_object_set(ow->sink, "async", FALSE, NULL);
- }
- }
-
- gst_bin_add_many(GST_BIN(GST_ELEMENT_PARENT(tee)),
- queue, convert, scale, ow->sink, NULL);
-
- gst_element_set_state(ow->sink, GST_STATE_PLAYING);
- gst_element_set_state(scale, GST_STATE_PLAYING);
- gst_element_set_state(convert, GST_STATE_PLAYING);
- gst_element_set_state(queue, GST_STATE_PLAYING);
- gst_element_link(scale, ow->sink);
- gst_element_link(convert, scale);
- gst_element_link(queue, convert);
- gst_element_link(tee, queue);
- }
- }
- return TRUE;
-}
-
-gulong
-purple_media_manager_set_output_window(PurpleMediaManager *manager,
- PurpleMedia *media, const gchar *session_id,
- const gchar *participant)
-{
- PurpleMediaOutputWindow *output_window;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE);
- g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
-
- output_window = g_new0(PurpleMediaOutputWindow, 1);
- output_window->id = manager->priv->next_output_window_id++;
- output_window->media = media;
- output_window->session_id = g_strdup(session_id);
- output_window->participant = g_strdup(participant);
-
- manager->priv->output_windows = g_list_prepend(
- manager->priv->output_windows, output_window);
-
- if (purple_media_get_tee(media, session_id, participant) != NULL) {
- purple_media_manager_create_output_window(manager,
- media, session_id, participant);
- }
-
- return output_window->id;
-}
-
-gboolean
-purple_media_manager_remove_output_window(PurpleMediaManager *manager,
- gulong output_window_id)
-{
- PurpleMediaOutputWindow *output_window = NULL;
- GList *iter;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE);
-
- iter = manager->priv->output_windows;
- for (; iter; iter = g_list_next(iter)) {
- PurpleMediaOutputWindow *ow = iter->data;
- if (ow->id == output_window_id) {
- manager->priv->output_windows = g_list_delete_link(
- manager->priv->output_windows, iter);
- output_window = ow;
- break;
- }
- }
-
- if (output_window == NULL) {
- return FALSE;
- }
-
- if (output_window->sink != NULL) {
- GstElement *element = output_window->sink;
- GstPad *teepad = NULL;
- GSList *to_remove = NULL;
-
- /* Find the tee element this output is connected to. */
- while (!teepad) {
- GstPad *pad;
- GstPad *peer;
- GstElementFactory *factory;
- const gchar *factory_name;
-
- to_remove = g_slist_append(to_remove, element);
-
- pad = gst_element_get_static_pad(element, "sink");
- peer = gst_pad_get_peer(pad);
- if (!peer) {
- /* Output is disconnected from the pipeline. */
- gst_object_unref(pad);
- break;
- }
-
- factory = gst_element_get_factory(GST_PAD_PARENT(peer));
- factory_name = gst_plugin_feature_get_name(factory);
- if (purple_strequal(factory_name, "tee")) {
- teepad = peer;
- }
-
- element = GST_PAD_PARENT(peer);
-
- gst_object_unref(pad);
- gst_object_unref(peer);
- }
-
- if (teepad) {
- gst_element_release_request_pad(GST_PAD_PARENT(teepad),
- teepad);
- }
-
- while (to_remove) {
- GstElement *element = to_remove->data;
-
- gst_element_set_locked_state(element, TRUE);
- gst_element_set_state(element, GST_STATE_NULL);
- gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(element)),
- element);
- to_remove = g_slist_delete_link(to_remove, to_remove);
- }
- }
-
- g_free(output_window->session_id);
- g_free(output_window->participant);
- g_free(output_window);
-
- return TRUE;
-}
-
-void
-purple_media_manager_remove_output_windows(PurpleMediaManager *manager,
- PurpleMedia *media, const gchar *session_id,
- const gchar *participant)
-{
- GList *iter;
-
- g_return_if_fail(PURPLE_IS_MEDIA(media));
-
- iter = manager->priv->output_windows;
-
- for (; iter;) {
- PurpleMediaOutputWindow *ow = iter->data;
- iter = g_list_next(iter);
-
- if (media == ow->media &&
- purple_strequal(session_id, ow->session_id) &&
- purple_strequal(participant, ow->participant))
- {
- purple_media_manager_remove_output_window(
- manager, ow->id);
- }
- }
-}
-
-void
-purple_media_manager_set_ui_caps(PurpleMediaManager *manager,
- PurpleMediaCaps caps)
-{
- PurpleMediaCaps oldcaps;
-
- g_return_if_fail(PURPLE_IS_MEDIA_MANAGER(manager));
-
- oldcaps = manager->priv->ui_caps;
- manager->priv->ui_caps = caps;
-
- if (caps != oldcaps) {
- g_signal_emit(manager, signals[SIG_UI_CAPS_CHANGED], 0, caps, oldcaps);
- }
-}
-
-PurpleMediaCaps
-purple_media_manager_get_ui_caps(PurpleMediaManager *manager)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager),
- PURPLE_MEDIA_CAPS_NONE);
- return manager->priv->ui_caps;
-}
-
-void
-purple_media_manager_set_backend_type(PurpleMediaManager *manager,
- GType backend_type)
-{
- g_return_if_fail(PURPLE_IS_MEDIA_MANAGER(manager));
-
- manager->priv->backend_type = backend_type;
-}
-
-GType
-purple_media_manager_get_backend_type(PurpleMediaManager *manager)
-{
- g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager),
- PURPLE_MEDIA_CAPS_NONE);
-
- return manager->priv->backend_type;
-}
-
-void
-purple_media_manager_set_application_data_callbacks(PurpleMediaManager *manager,
- PurpleMedia *media, const gchar *session_id,
- const gchar *participant, PurpleMediaAppDataCallbacks *callbacks,
- gpointer user_data, GDestroyNotify notify)
-{
- PurpleMediaAppDataInfo * info = ensure_app_data_info_and_lock (manager,
- media, session_id, participant);
-
- if (info->notify) {
- info->notify (info->user_data);
- }
-
- g_clear_handle_id(&info->readable_cb_token, g_source_remove);
- g_clear_handle_id(&info->writable_cb_token, g_source_remove);
-
- if (callbacks) {
- info->callbacks = *callbacks;
- } else {
- info->callbacks.writable = NULL;
- info->callbacks.readable = NULL;
- }
- info->user_data = user_data;
- info->notify = notify;
-
- call_appsrc_writable_locked (info);
- if (info->num_samples > 0 || info->current_sample != NULL) {
- call_appsink_readable_locked (info);
- }
-
- g_mutex_unlock (&manager->priv->appdata_mutex);
-}
-
-gint
-purple_media_manager_send_application_data (
- PurpleMediaManager *manager, PurpleMedia *media, const gchar *session_id,
- const gchar *participant, gpointer buffer, guint size, gboolean blocking)
-{
- PurpleMediaAppDataInfo * info = get_app_data_info_and_lock (manager,
- media, session_id, participant);
-
- if (info && info->appsrc && info->connected) {
- GstBuffer *gstbuffer = gst_buffer_new_wrapped (g_memdup2(buffer, size),
- size);
- GstAppSrc *appsrc = gst_object_ref (info->appsrc);
-
- g_mutex_unlock (&manager->priv->appdata_mutex);
- if (gst_app_src_push_buffer (appsrc, gstbuffer) == GST_FLOW_OK) {
- if (blocking) {
- GstPad *srcpad;
-
- srcpad = gst_element_get_static_pad (GST_ELEMENT (appsrc),
- "src");
- if (srcpad) {
- gst_pad_peer_query (srcpad, gst_query_new_drain ());
- gst_object_unref (srcpad);
- }
- }
- gst_object_unref (appsrc);
- return size;
- } else {
- gst_object_unref (appsrc);
- return -1;
- }
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return -1;
-}
-
-gint
-purple_media_manager_receive_application_data (
- PurpleMediaManager *manager, PurpleMedia *media, const gchar *session_id,
- const gchar *participant, gpointer buffer, guint max_size,
- gboolean blocking)
-{
- PurpleMediaAppDataInfo * info = get_app_data_info_and_lock (manager,
- media, session_id, participant);
- guint bytes_read = 0;
-
- if (info) {
- /* If we are in a blocking read, we need to loop until max_size data
- * is read into the buffer, if we're not, then we need to read as much
- * data as possible
- */
- do {
- if (!info->current_sample && info->appsink && info->num_samples > 0) {
- info->current_sample = gst_app_sink_pull_sample (info->appsink);
- info->sample_offset = 0;
- if (info->current_sample) {
- info->num_samples--;
- }
- }
-
- if (info->current_sample) {
- GstBuffer *gstbuffer = gst_sample_get_buffer (
- info->current_sample);
-
- if (gstbuffer) {
- GstMapInfo mapinfo;
- guint bytes_to_copy;
-
- gst_buffer_map (gstbuffer, &mapinfo, GST_MAP_READ);
- /* We must copy only the data remaining in the buffer without
- * overflowing the buffer */
- bytes_to_copy = MIN(max_size - bytes_read,
- mapinfo.size - info->sample_offset);
- memcpy ((guint8 *)buffer + bytes_read,
- mapinfo.data + info->sample_offset, bytes_to_copy);
-
- gst_buffer_unmap (gstbuffer, &mapinfo);
- info->sample_offset += bytes_to_copy;
- bytes_read += bytes_to_copy;
- if (info->sample_offset == mapinfo.size) {
- gst_sample_unref (info->current_sample);
- info->current_sample = NULL;
- info->sample_offset = 0;
- }
- } else {
- /* In case there's no buffer in the sample (should never
- * happen), we need to at least unref it */
- gst_sample_unref (info->current_sample);
- info->current_sample = NULL;
- info->sample_offset = 0;
- }
- }
-
- /* If blocking, wait until there's an available sample */
- while (bytes_read < max_size && blocking &&
- info->current_sample == NULL && info->num_samples == 0) {
- g_cond_wait (&info->readable_cond, &manager->priv->appdata_mutex);
-
- /* We've been signaled, we need to unlock and regrab the info
- * struct to make sure nothing changed */
- g_mutex_unlock (&manager->priv->appdata_mutex);
- info = get_app_data_info_and_lock (manager,
- media, session_id, participant);
- if (info == NULL || info->appsink == NULL) {
- /* The session was destroyed while we were waiting, we
- * should return here */
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return bytes_read;
- }
- }
- } while (bytes_read < max_size && (blocking || info->num_samples > 0));
-
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return bytes_read;
- }
- g_mutex_unlock (&manager->priv->appdata_mutex);
- return -1;
-}
-
-static void
-videosink_disable_last_sample(GstElement *sink)
-{
- GObjectClass *klass = G_OBJECT_GET_CLASS(sink);
-
- if (g_object_class_find_property(klass, "enable-last-sample")) {
- g_object_set(sink, "enable-last-sample", FALSE, NULL);
- }
-}
-
-static PurpleMediaElementType
-gst_class_to_purple_element_type(const gchar *device_class)
-{
- if (purple_strequal(device_class, "Audio/Source")) {
- return PURPLE_MEDIA_ELEMENT_AUDIO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC
- | PURPLE_MEDIA_ELEMENT_UNIQUE;
- } else if (purple_strequal(device_class, "Audio/Sink")) {
- return PURPLE_MEDIA_ELEMENT_AUDIO
- | PURPLE_MEDIA_ELEMENT_SINK
- | PURPLE_MEDIA_ELEMENT_ONE_SINK;
- } else if (purple_strequal(device_class, "Video/Source")) {
- return PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC
- | PURPLE_MEDIA_ELEMENT_UNIQUE;
- } else if (purple_strequal(device_class, "Video/Sink")) {
- return PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SINK
- | PURPLE_MEDIA_ELEMENT_ONE_SINK;
- }
-
- return PURPLE_MEDIA_ELEMENT_NONE;
-}
-
-static GstElement *
-gst_device_create_cb(PurpleMediaElementInfo *info,
- G_GNUC_UNUSED PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant)
-{
- GstDevice *device;
- GstElement *result;
- PurpleMediaElementType type;
-
- device = g_object_get_data(G_OBJECT(info), "gst-device");
- if (!device) {
- return NULL;
- }
-
- result = gst_device_create_element(device, NULL);
- if (!result) {
- return NULL;
- }
-
- type = purple_media_element_info_get_element_type(info);
-
- if ((type & PURPLE_MEDIA_ELEMENT_VIDEO) &&
- (type & PURPLE_MEDIA_ELEMENT_SINK)) {
- videosink_disable_last_sample(result);
- }
-
- return result;
-}
-
-static gboolean
-device_is_ignored(GstDevice *device)
-{
- gboolean result = FALSE;
-
- gchar *device_class;
-
- g_return_val_if_fail(device, TRUE);
-
- device_class = gst_device_get_device_class(device);
-
- /* Ignore PulseAudio monitor audio sources since they have little use
- * in the context of telephony.*/
- if (purple_strequal(device_class, "Audio/Source")) {
- GstStructure *properties;
- const gchar *pa_class;
-
- properties = gst_device_get_properties(device);
-
- pa_class = gst_structure_get_string(properties, "device.class");
- if (purple_strequal(pa_class, "monitor")) {
- result = TRUE;
- }
-
- gst_structure_free(properties);
- }
-
- g_free(device_class);
-
- return result;
-}
-
-static void
-purple_media_manager_register_gst_device(PurpleMediaManager *manager,
- GstDevice *device)
-{
- PurpleMediaElementInfo *info;
- PurpleMediaElementType type;
- gchar *name;
- gchar *device_class;
- gchar *id;
-
- if (device_is_ignored(device)) {
- return;
- }
-
- name = gst_device_get_display_name(device);
- device_class = gst_device_get_device_class(device);
-
- id = g_strdup_printf("%s %s", device_class, name);
-
- type = gst_class_to_purple_element_type(device_class);
-
- info = g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", id,
- "name", name,
- "type", type,
- "create-cb", gst_device_create_cb,
- NULL);
-
- g_object_set_data(G_OBJECT(info), "gst-device", device);
-
- purple_media_manager_register_element(manager, info);
-
- purple_debug_info("mediamanager", "Registered %s device %s",
- device_class, name);
-
- g_free(name);
- g_free(device_class);
- g_free(id);
-}
-
-static void
-purple_media_manager_unregister_gst_device(PurpleMediaManager *manager,
- GstDevice *device)
-{
- GList *i;
- gchar *name;
- gchar *device_class;
- gboolean done = FALSE;
-
- name = gst_device_get_display_name(device);
- device_class = gst_device_get_device_class(device);
-
- for (i = manager->priv->elements; i && !done; i = i->next) {
- PurpleMediaElementInfo *info = i->data;
- GstDevice *device2;
-
- device2 = g_object_get_data(G_OBJECT(info), "gst-device");
- if (device2) {
- gchar *name2;
- gchar *device_class2;
-
- name2 = gst_device_get_display_name(device2);
- device_class2 = gst_device_get_device_class(device2);
-
- if (purple_strequal(name, name2) &&
- purple_strequal(device_class, device_class2)) {
- gchar *id;
-
- id = purple_media_element_info_get_id(info);
- purple_media_manager_unregister_element(manager,
- id);
-
- purple_debug_info("mediamanager",
- "Unregistered %s device %s",
- device_class, name);
-
- g_free(id);
-
- done = TRUE;
- }
-
- g_free(name2);
- g_free(device_class2);
- }
- }
-
- g_free(name);
- g_free(device_class);
-}
-
-static gboolean
-device_monitor_bus_cb(G_GNUC_UNUSED GstBus *bus, GstMessage *message,
- gpointer user_data)
-{
- PurpleMediaManager *manager = user_data;
- GstMessageType message_type;
- GstDevice *device;
-
- message_type = GST_MESSAGE_TYPE(message);
-
- if (message_type == GST_MESSAGE_DEVICE_ADDED) {
- gst_message_parse_device_added(message, &device);
- purple_media_manager_register_gst_device(manager, device);
- } else if (message_type == GST_MESSAGE_DEVICE_REMOVED) {
- gst_message_parse_device_removed (message, &device);
- purple_media_manager_unregister_gst_device(manager, device);
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-purple_media_manager_init_device_monitor(PurpleMediaManager *manager)
-{
- GstBus *bus;
- GList *i;
-
- manager->priv->device_monitor = gst_device_monitor_new();
-
- bus = gst_device_monitor_get_bus(manager->priv->device_monitor);
- gst_bus_add_watch (bus, device_monitor_bus_cb, manager);
- gst_object_unref (bus);
-
- /* This avoids warning in GStreamer logs about no filters set */
- gst_device_monitor_add_filter(manager->priv->device_monitor, NULL, NULL);
-
- gst_device_monitor_start(manager->priv->device_monitor);
-
- i = gst_device_monitor_get_devices(manager->priv->device_monitor);
- for (; i; i = g_list_delete_link(i, i)) {
- GstDevice *device = i->data;
-
- purple_media_manager_register_gst_device(manager, device);
- gst_object_unref(device);
- }
-}
-
-GList *
-purple_media_manager_enumerate_elements(PurpleMediaManager *manager,
- PurpleMediaElementType type)
-{
- GList *result = NULL;
- GList *i;
-
- for (i = manager->priv->elements; i; i = i->next) {
- PurpleMediaElementInfo *info = i->data;
- PurpleMediaElementType type2;
-
- type2 = purple_media_element_info_get_element_type(info);
-
- if ((type2 & type) == type) {
- g_object_ref(info);
- result = g_list_prepend(result, info);
- }
- }
-
- return result;
-}
-
-static GstElement *
-gst_factory_make_cb(PurpleMediaElementInfo *info,
- G_GNUC_UNUSED PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant)
-{
- gchar *id;
- GstElement *element;
-
- id = purple_media_element_info_get_id(info);
-
- element = gst_element_factory_make(id, NULL);
-
- g_free(id);
-
- return element;
-}
-
-static void
-autovideosink_child_added_cb(G_GNUC_UNUSED GstChildProxy *child_proxy,
- GObject *object, G_GNUC_UNUSED gchar *name,
- G_GNUC_UNUSED gpointer user_data)
-{
- videosink_disable_last_sample(GST_ELEMENT(object));
-}
-
-static GstElement *
-default_video_sink_create_cb(G_GNUC_UNUSED PurpleMediaElementInfo *info,
- G_GNUC_UNUSED PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant)
-{
- GstElement *videosink = gst_element_factory_make("autovideosink", NULL);
-
- g_signal_connect(videosink, "child-added",
- G_CALLBACK(autovideosink_child_added_cb), NULL);
-
- return videosink;
-}
-
-static GstElement *
-disabled_video_create_cb(G_GNUC_UNUSED PurpleMediaElementInfo *info,
- G_GNUC_UNUSED PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant)
-{
- GstElement *src = gst_element_factory_make("videotestsrc", NULL);
-
- /* GST_VIDEO_TEST_SRC_BLACK */
- g_object_set(src, "pattern", 2, NULL);
-
- return src;
-}
-
-static GstElement *
-test_video_create_cb(G_GNUC_UNUSED PurpleMediaElementInfo *info,
- G_GNUC_UNUSED PurpleMedia *media,
- G_GNUC_UNUSED const char *session_id,
- G_GNUC_UNUSED const char *participant)
-{
- GstElement *src = gst_element_factory_make("videotestsrc", NULL);
-
- g_object_set(src, "is-live", TRUE, NULL);
-
- return src;
-}
-
-static void
-purple_media_manager_register_static_elements(PurpleMediaManager *manager)
-{
- static const gchar *VIDEO_SINK_PLUGINS[] = {
- "gtksink", "GTK",
- "gtkglsink", "GTK OpenGL",
- /* "aasink", "AALib", Didn't work for me */
- NULL
- };
- const gchar **sinks = NULL;
-
- /* Default auto* elements. */
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "autoaudiosrc",
- "name", N_("Default"),
- "type", PURPLE_MEDIA_ELEMENT_AUDIO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC
- | PURPLE_MEDIA_ELEMENT_UNIQUE,
- "create-cb", gst_factory_make_cb,
- NULL));
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "autoaudiosink",
- "name", N_("Default"),
- "type", PURPLE_MEDIA_ELEMENT_AUDIO
- | PURPLE_MEDIA_ELEMENT_SINK
- | PURPLE_MEDIA_ELEMENT_ONE_SINK,
- "create-cb", gst_factory_make_cb,
- NULL));
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "autovideosrc",
- "name", N_("Default"),
- "type", PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC
- | PURPLE_MEDIA_ELEMENT_UNIQUE,
- "create-cb", gst_factory_make_cb,
- NULL));
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "autovideosink",
- "name", N_("Default"),
- "type", PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SINK
- | PURPLE_MEDIA_ELEMENT_ONE_SINK,
- "create-cb", default_video_sink_create_cb,
- NULL));
-
- /* Special elements */
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "audiotestsrc",
- /* Translators: This is a noun that refers to one
- * possible audio input device. The device can help the
- * user to check if her speakers or headphones have been
- * set up correctly for voice calling. */
- "name", N_("Test Sound"),
- "type", PURPLE_MEDIA_ELEMENT_AUDIO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC,
- "create-cb", gst_factory_make_cb,
- NULL));
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "disabledvideosrc",
- "name", N_("Disabled"),
- "type", PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SINK,
- "create-cb", disabled_video_create_cb,
- NULL));
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", "videotestsrc",
- /* Translators: This is a noun that refers to one
- * possible video input device. The device produces
- * a test "monoscope" image that can help the user check
- * the video output has been set up correctly without
- * needing a webcam connected to the computer. */
- "name", N_("Test Pattern"),
- "type", PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SRC
- | PURPLE_MEDIA_ELEMENT_ONE_SRC,
- "create-cb", test_video_create_cb,
- NULL));
-
- for (sinks = VIDEO_SINK_PLUGINS; sinks[0]; sinks += 2) {
- GstElementFactory *factory;
-
- factory = gst_element_factory_find(sinks[0]);
- if (!factory) {
- continue;
- }
-
- purple_media_manager_register_element(manager,
- g_object_new(PURPLE_TYPE_MEDIA_ELEMENT_INFO,
- "id", sinks[0],
- "name", sinks[1],
- "type", PURPLE_MEDIA_ELEMENT_VIDEO
- | PURPLE_MEDIA_ELEMENT_SINK
- | PURPLE_MEDIA_ELEMENT_ONE_SINK,
- "create-cb", gst_factory_make_cb,
- NULL));
-
- gst_object_unref(factory);
- }
-}
-
-/*
- * PurpleMediaElementType
- */
-
-GType
-purple_media_element_type_get_type(void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GFlagsValue values[] = {
- { PURPLE_MEDIA_ELEMENT_NONE,
- "PURPLE_MEDIA_ELEMENT_NONE", "none" },
- { PURPLE_MEDIA_ELEMENT_AUDIO,
- "PURPLE_MEDIA_ELEMENT_AUDIO", "audio" },
- { PURPLE_MEDIA_ELEMENT_VIDEO,
- "PURPLE_MEDIA_ELEMENT_VIDEO", "video" },
- { PURPLE_MEDIA_ELEMENT_AUDIO_VIDEO,
- "PURPLE_MEDIA_ELEMENT_AUDIO_VIDEO",
- "audio-video" },
- { PURPLE_MEDIA_ELEMENT_NO_SRCS,
- "PURPLE_MEDIA_ELEMENT_NO_SRCS", "no-srcs" },
- { PURPLE_MEDIA_ELEMENT_ONE_SRC,
- "PURPLE_MEDIA_ELEMENT_ONE_SRC", "one-src" },
- { PURPLE_MEDIA_ELEMENT_MULTI_SRC,
- "PURPLE_MEDIA_ELEMENT_MULTI_SRC",
- "multi-src" },
- { PURPLE_MEDIA_ELEMENT_REQUEST_SRC,
- "PURPLE_MEDIA_ELEMENT_REQUEST_SRC",
- "request-src" },
- { PURPLE_MEDIA_ELEMENT_NO_SINKS,
- "PURPLE_MEDIA_ELEMENT_NO_SINKS", "no-sinks" },
- { PURPLE_MEDIA_ELEMENT_ONE_SINK,
- "PURPLE_MEDIA_ELEMENT_ONE_SINK", "one-sink" },
- { PURPLE_MEDIA_ELEMENT_MULTI_SINK,
- "PURPLE_MEDIA_ELEMENT_MULTI_SINK",
- "multi-sink" },
- { PURPLE_MEDIA_ELEMENT_REQUEST_SINK,
- "PURPLE_MEDIA_ELEMENT_REQUEST_SINK",
- "request-sink" },
- { PURPLE_MEDIA_ELEMENT_UNIQUE,
- "PURPLE_MEDIA_ELEMENT_UNIQUE", "unique" },
- { PURPLE_MEDIA_ELEMENT_SRC,
- "PURPLE_MEDIA_ELEMENT_SRC", "src" },
- { PURPLE_MEDIA_ELEMENT_SINK,
- "PURPLE_MEDIA_ELEMENT_SINK", "sink" },
- { PURPLE_MEDIA_ELEMENT_APPLICATION,
- "PURPLE_MEDIA_ELEMENT_APPLICATION", "application" },
- { 0, NULL, NULL }
- };
- type = g_flags_register_static(
- "PurpleMediaElementType", values);
- }
- return type;
-}
-
-/*
- * PurpleMediaElementInfo
- */
-
-struct _PurpleMediaElementInfoClass
-{
- GObjectClass parent_class;
-};
-
-struct _PurpleMediaElementInfo
-{
- GObject parent;
-};
-
-struct _PurpleMediaElementInfoPrivate
-{
- gchar *id;
- gchar *name;
- PurpleMediaElementType type;
- PurpleMediaElementCreateCallback create;
-};
-
-enum {
- PROP_0,
- PROP_ID,
- PROP_NAME,
- PROP_TYPE,
- PROP_CREATE_CB,
- N_PROPERTIES,
-};
-
-G_DEFINE_FINAL_TYPE_WITH_PRIVATE(PurpleMediaElementInfo,
- purple_media_element_info, G_TYPE_OBJECT);
-
-static void
-purple_media_element_info_init(PurpleMediaElementInfo *info)
-{
- PurpleMediaElementInfoPrivate *priv =
- purple_media_element_info_get_instance_private(info);
- priv->id = NULL;
- priv->name = NULL;
- priv->type = PURPLE_MEDIA_ELEMENT_NONE;
- priv->create = NULL;
-}
-
-static void
-purple_media_element_info_finalize(GObject *info)
-{
- PurpleMediaElementInfoPrivate *priv =
- purple_media_element_info_get_instance_private(
- PURPLE_MEDIA_ELEMENT_INFO(info));
- g_free(priv->id);
- g_free(priv->name);
-
- G_OBJECT_CLASS(purple_media_element_info_parent_class)->finalize(info);
-}
-
-static void
-purple_media_element_info_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- PurpleMediaElementInfoPrivate *priv;
- g_return_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(object));
-
- priv = purple_media_element_info_get_instance_private(
- PURPLE_MEDIA_ELEMENT_INFO(object));
-
- switch (prop_id) {
- case PROP_ID:
- g_free(priv->id);
- priv->id = g_value_dup_string(value);
- break;
- case PROP_NAME:
- g_free(priv->name);
- priv->name = g_value_dup_string(value);
- break;
- case PROP_TYPE: {
- priv->type = g_value_get_flags(value);
- break;
- }
- case PROP_CREATE_CB:
- priv->create = g_value_get_pointer(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_element_info_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- PurpleMediaElementInfoPrivate *priv;
- g_return_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(object));
-
- priv = purple_media_element_info_get_instance_private(
- PURPLE_MEDIA_ELEMENT_INFO(object));
-
- switch (prop_id) {
- case PROP_ID:
- g_value_set_string(value, priv->id);
- break;
- case PROP_NAME:
- g_value_set_string(value, priv->name);
- break;
- case PROP_TYPE:
- g_value_set_flags(value, priv->type);
- break;
- case PROP_CREATE_CB:
- g_value_set_pointer(value, priv->create);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-purple_media_element_info_class_init(PurpleMediaElementInfoClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
-
- gobject_class->finalize = purple_media_element_info_finalize;
- gobject_class->set_property = purple_media_element_info_set_property;
- gobject_class->get_property = purple_media_element_info_get_property;
-
- /**
- * PurpleMediaElementInfo:id:
- *
- * The identifier for the element info.
- */
- g_object_class_install_property(gobject_class, PROP_ID,
- g_param_spec_string("id",
- "ID",
- "The unique identifier of the element.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaElementInfo:name:
- *
- * The name of the element info.
- */
- g_object_class_install_property(gobject_class, PROP_NAME,
- g_param_spec_string("name",
- "Name",
- "The friendly/display name of this element.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaElementInfo:type:
- *
- * The type of the element.
- */
- g_object_class_install_property(gobject_class, PROP_TYPE,
- g_param_spec_flags("type",
- "Element Type",
- "The type of element this is.",
- PURPLE_TYPE_MEDIA_ELEMENT_TYPE,
- PURPLE_MEDIA_ELEMENT_NONE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * PurpleMediaElementInfo:create-cb:
- *
- * A call back that is called when the element is created.
- */
- g_object_class_install_property(gobject_class, PROP_CREATE_CB,
- g_param_spec_pointer("create-cb",
- "Create Callback",
- "The function called to create this element.",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-}
-
-gchar *
-purple_media_element_info_get_id(PurpleMediaElementInfo *info)
-{
- gchar *id;
-
- g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), NULL);
- g_object_get(info, "id", &id, NULL);
- return id;
-}
-
-gchar *
-purple_media_element_info_get_name(PurpleMediaElementInfo *info)
-{
- gchar *name;
- g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), NULL);
- g_object_get(info, "name", &name, NULL);
- return name;
-}
-
-PurpleMediaElementType
-purple_media_element_info_get_element_type(PurpleMediaElementInfo *info)
-{
- PurpleMediaElementType type;
- g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info),
- PURPLE_MEDIA_ELEMENT_NONE);
- g_object_get(info, "type", &type, NULL);
- return type;
-}
-
-GstElement *
-purple_media_element_info_call_create(PurpleMediaElementInfo *info,
- PurpleMedia *media, const gchar *session_id,
- const gchar *participant)
-{
- PurpleMediaElementCreateCallback create;
- g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), NULL);
- g_object_get(info, "create-cb", &create, NULL);
- if (create) {
- return create(info, media, session_id, participant);
- }
- return NULL;
-}
--- a/libpurple/mediamanager.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,413 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_MEDIA_MANAGER_H
-#define PURPLE_MEDIA_MANAGER_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-typedef struct _PurpleMediaManager PurpleMediaManager;
-
-#include "media.h"
-#include "purpleaccount.h"
-#include "purpleversion.h"
-
-#define PURPLE_TYPE_MEDIA_MANAGER purple_media_manager_get_type()
-
-/**
- * PurpleMediaManagerClass:
- *
- * The media manager class.
- *
- * Since: 2.6
- */
-
-/**
- * PurpleMediaAppDataCallbacks:
- * @readable: Called when the stream has received data and is readable.
- * @writable: Called when the stream has become writable or has stopped being
- * writable.
- *
- * A set of callbacks that can be installed on an Application data session with
- * purple_media_manager_set_application_data_callbacks()
- *
- * Once installed the @readable callback will get called as long as data is
- * available to read, so the data must be read completely.
- * The @writable callback will only be called when the writable state of the
- * stream changes. The @writable argument defines whether the stream has
- * become writable or stopped being writable.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_TYPE_IN_2_6
-typedef struct {
- void (*readable) (PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant, gpointer user_data);
- void (*writable) (PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant, gboolean writable,
- gpointer user_data);
-} PurpleMediaAppDataCallbacks;
-
-G_BEGIN_DECLS
-
-/**************************************************************************/
-/* Media Manager API */
-/**************************************************************************/
-
-PURPLE_AVAILABLE_IN_2_6
-G_DECLARE_FINAL_TYPE(PurpleMediaManager, purple_media_manager, PURPLE,
- MEDIA_MANAGER, GObject)
-
-/**
- * purple_media_manager_get:
- *
- * Gets the "global" media manager object. It's created if it doesn't already exist.
- *
- * Returns: (transfer none): The "global" instance of the media manager object.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaManager *purple_media_manager_get(void);
-
-/**
- * purple_media_manager_create_media:
- * @manager: The media manager to create the session under.
- * @account: The account to create the session on.
- * @conference_type: The conference type to feed into Farstream.
- * @remote_user: The remote user to initiate the session with.
- * @initiator: TRUE if the local user is the initiator of this media call, FALSE otherwise.
- *
- * Creates a media session.
- *
- * Returns: (transfer full): A newly created media session.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMedia *purple_media_manager_create_media(PurpleMediaManager *manager,
- PurpleAccount *account,
- const char *conference_type,
- const char *remote_user,
- gboolean initiator);
-
-/**
- * purple_media_manager_get_media:
- * @manager: The media manager to get all of the sessions from.
- *
- * Gets all of the media sessions.
- *
- * Returns: (transfer none) (element-type PurpleMedia): A list of all the media sessions.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_manager_get_media(PurpleMediaManager *manager);
-
-/**
- * purple_media_manager_get_media_by_account:
- * @manager: The media manager to get the sessions from.
- * @account: The account the sessions are on.
- *
- * Gets all of the media sessions for a given account.
- *
- * Returns: (transfer container) (element-type PurpleMedia): A list of the media sessions on the given account.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-GList *purple_media_manager_get_media_by_account(
- PurpleMediaManager *manager, PurpleAccount *account);
-
-/**
- * purple_media_manager_remove_media:
- * @manager: The media manager to remove the media session from.
- * @media: The media session to remove.
- *
- * Removes a media session from the media manager.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void
-purple_media_manager_remove_media(PurpleMediaManager *manager,
- PurpleMedia *media);
-
-/**
- * purple_media_manager_create_private_media:
- * @manager: The media manager to create the session under.
- * @account: The account to create the session on.
- * @conference_type: The conference type to feed into Farstream.
- * @remote_user: The remote user to initiate the session with.
- * @initiator: TRUE if the local user is the initiator of this media call, FALSE otherwise.
- *
- * Creates a private media session.
- * A private media session is a media session which is private to the caller. It is
- * meant to be used by plugins to create a media session that the front-end does not
- * get notified about. It is useful especially for sessions with a type of
- * PURPLE_MEDIA_APPLICATION which the front-end wouldn't know how to handle.
- *
- * Returns: (transfer full): A newly created media session.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMedia *purple_media_manager_create_private_media(
- PurpleMediaManager *manager,
- PurpleAccount *account,
- const char *conference_type,
- const char *remote_user,
- gboolean initiator);
-
-/**
- * purple_media_manager_get_private_media:
- * @manager: The media manager to get all of the sessions from.
- *
- * Gets all of the private media sessions.
- *
- * Returns: (transfer none) (element-type PurpleMedia): A list of all the private media sessions.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-GList *purple_media_manager_get_private_media(PurpleMediaManager *manager);
-
-/**
- * purple_media_manager_get_private_media_by_account:
- * @manager: The media manager to get the sessions from.
- * @account: The account the sessions are on.
- *
- * Gets all of the private media sessions for a given account.
- *
- * Returns: (transfer container) (element-type PurpleMedia): A list of the private media sessions on the given account.
- *
- * Since: 2.11
- */
-PURPLE_AVAILABLE_IN_2_11
-GList *purple_media_manager_get_private_media_by_account(
- PurpleMediaManager *manager, PurpleAccount *account);
-
-/**
- * purple_media_manager_create_output_window:
- * @manager: Manager the output windows are registered with.
- * @media: Media session the output windows are registered for.
- * @session_id: The session the output windows are registered with.
- * @participant: The participant the output windows are registered with.
- *
- * Signals that output windows should be created for the chosen stream.
- *
- * This shouldn't be called outside of mediamanager.c and media.c
- *
- * Returns: TRUE if it succeeded, FALSE if it failed.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_manager_create_output_window(
- PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-/**
- * purple_media_manager_set_output_window:
- * @manager: The manager to register the output window with.
- * @media: The media instance to find the stream in.
- * @session_id: The session the stream is associated with.
- * @participant: The participant the stream is associated with.
- *
- * Registers a video output window to be created for a given stream.
- *
- * Returns: A unique ID to the registered output window, 0 if it failed.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gulong purple_media_manager_set_output_window(PurpleMediaManager *manager,
- PurpleMedia *media, const gchar *session_id,
- const gchar *participant);
-
-/**
- * purple_media_manager_remove_output_window:
- * @manager: The manager the output window was registered with.
- * @output_window_id: The ID of the output window.
- *
- * Remove a previously registered output window.
- *
- * Returns: TRUE if it found the output window and was successful, else FALSE.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gboolean purple_media_manager_remove_output_window(
- PurpleMediaManager *manager, gulong output_window_id);
-
-/**
- * purple_media_manager_remove_output_windows:
- * @manager: The manager the output windows were registered with.
- * @media: The media instance the output windows were registered for.
- * @session_id: The session the output windows were registered for.
- * @participant: The participant the output windows were registered for.
- *
- * Remove all output windows for a given conference/session/participant/stream.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_manager_remove_output_windows(
- PurpleMediaManager *manager, PurpleMedia *media,
- const gchar *session_id, const gchar *participant);
-
-/**
- * purple_media_manager_set_ui_caps:
- * @manager: The manager to set the caps on.
- * @caps: The caps to set.
- *
- * Sets which media caps the UI supports.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_manager_set_ui_caps(PurpleMediaManager *manager,
- PurpleMediaCaps caps);
-
-/**
- * purple_media_manager_get_ui_caps:
- * @manager: The manager to get caps from.
- *
- * Gets which media caps the UI supports.
- *
- * Returns: caps The caps retrieved.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-PurpleMediaCaps purple_media_manager_get_ui_caps(PurpleMediaManager *manager);
-
-/**
- * purple_media_manager_set_backend_type:
- * @manager: The manager to set the caps on.
- * @backend_type: The media backend type to use.
- *
- * Sets which media backend type media objects will use.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-void purple_media_manager_set_backend_type(PurpleMediaManager *manager,
- GType backend_type);
-
-/**
- * purple_media_manager_get_backend_type:
- * @manager: The manager to get the media backend type from.
- *
- * Gets which media backend type media objects will use.
- *
- * Returns: The type of media backend type media objects will use.
- *
- * Since: 2.7
- */
-PURPLE_AVAILABLE_IN_2_7
-GType purple_media_manager_get_backend_type(PurpleMediaManager *manager);
-
-/**
- * purple_media_manager_set_application_data_callbacks:
- * @manager: The manager to register the callbacks with.
- * @media: The media instance to register the callbacks with.
- * @session_id: The session to register the callbacks with.
- * @participant: The participant to register the callbacks with.
- * @callbacks: The callbacks to be set on the session.
- * @user_data: a user_data argument for the callbacks.
- * @notify: a destroy notify function.
- *
- * Set callbacks on a session to be called when the stream becomes writable
- * or readable for media sessions of type #PURPLE_MEDIA_APPLICATION
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-void purple_media_manager_set_application_data_callbacks(
- PurpleMediaManager *manager, PurpleMedia *media, const gchar *session_id,
- const gchar *participant, PurpleMediaAppDataCallbacks *callbacks,
- gpointer user_data, GDestroyNotify notify);
-
-/**
- * purple_media_manager_send_application_data:
- * @manager: The manager to send data with.
- * @media: The media instance to which the session belongs.
- * @session_id: The session to send data to.
- * @participant: The participant to send data to.
- * @buffer: The buffer of data to send.
- * @size: The size of @buffer
- * @blocking: Whether to block until the data was send or not.
- *
- * Sends a buffer of data to a #PURPLE_MEDIA_APPLICATION session.
- * If @blocking is set, unless an error occurred, the function will not return
- * until the data has been flushed into the network.
- * If the stream is not writable, the data will be queued. It is the
- * responsibility of the user to stop sending data when the stream isn't
- * writable anymore. It is also the responsibility of the user to only start
- * sending data after the stream has been configured correctly (encryption
- * parameters for example).
- *
- * Returns: Number of bytes sent or -1 in case of error.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gint purple_media_manager_send_application_data (
- PurpleMediaManager *manager, PurpleMedia *media, const gchar *session_id,
- const gchar *participant, gpointer buffer, guint size, gboolean blocking);
-
-/**
- * purple_media_manager_receive_application_data:
- * @manager: The manager to receive data with.
- * @media: The media instance to which the session belongs.
- * @session_id: The session to receive data from.
- * @participant: The participant to receive data from.
- * @buffer: The buffer to receive data into.
- * @max_size: The max_size of @buffer
- * @blocking: Whether to block until the buffer is entirely filled or return
- * with currently available data.
- *
- * Receive a buffer of data from a #PURPLE_MEDIA_APPLICATION session.
- * If @blocking is set, unless an error occurred, the function will not return
- * until @max_size bytes are read.
- *
- * Returns: Number of bytes received or -1 in case of error.
- *
- * Since: 2.6
- */
-PURPLE_AVAILABLE_IN_2_6
-gint purple_media_manager_receive_application_data (
- PurpleMediaManager *manager, PurpleMedia *media, const gchar *session_id,
- const gchar *participant, gpointer buffer, guint max_size,
- gboolean blocking);
-
-/*}@*/
-
-G_END_DECLS
-
-#endif /* PURPLE_MEDIA_MANAGER_H */
--- a/libpurple/meson.build Thu May 09 21:21:24 2024 -0500
+++ b/libpurple/meson.build Thu May 09 21:27:08 2024 -0500
@@ -5,12 +5,6 @@
'core.c',
'debug.c',
'image.c',
- 'media/backend-iface.c',
- 'media/candidate.c',
- 'media/codec.c',
- 'media/enum-types.c',
- 'media.c',
- 'mediamanager.c',
'network.c',
'notify.c',
'plugins.c',
@@ -64,7 +58,6 @@
'purpleprotocolconversation.c',
'purpleprotocolfiletransfer.c',
'purpleprotocolmanager.c',
- 'purpleprotocolmedia.c',
'purpleprotocolroster.c',
'purpleprotocolserver.c',
'purpleprotocolwhiteboard.c',
@@ -102,9 +95,6 @@
'core.h',
'debug.h',
'image.h',
- 'media.h',
- 'media-gst.h',
- 'mediamanager.h',
'network.h',
'notify.h',
'plugins.h',
@@ -157,7 +147,6 @@
'purpleprotocolcontacts.h',
'purpleprotocolconversation.h',
'purpleprotocolfiletransfer.h',
- 'purpleprotocolmedia.h',
'purpleprotocolmanager.h',
'purpleprotocolroster.h',
'purpleprotocolserver.h',
@@ -234,13 +223,6 @@
purple_coresources += windows.compile_resources(libpurplerc)
endif
-purple_mediaheaders = [
- 'media/backend-iface.h',
- 'media/candidate.h',
- 'media/codec.h',
- 'media/enum-types.h'
-]
-
purple_enumheaders = [
'connection.h',
'debug.h',
@@ -271,7 +253,7 @@
enums_h = enums[1]
PURPLE_H_INCLUDES = []
-foreach header : purple_coreheaders + purple_mediaheaders + purple_request_headers + ['purpleversionconsts.h', 'purpleenums.h']
+foreach header : purple_coreheaders + purple_request_headers + ['purpleversionconsts.h', 'purpleenums.h']
PURPLE_H_INCLUDES += f'#include <libpurple/@header@>'
endforeach
purple_h_conf = configuration_data()
@@ -316,9 +298,6 @@
install_headers(purple_coreheaders,
subdir : purple_include_base)
-install_headers(purple_mediaheaders,
- subdir : purple_include_base / 'media')
-
install_headers(purple_request_headers,
subdir : purple_include_base / 'request')
@@ -337,7 +316,7 @@
if enable_introspection
introspection_sources = (purple_coresources + purple_coreheaders +
- purple_builtheaders + purple_mediaheaders + purple_request_headers)
+ purple_builtheaders + purple_request_headers)
libpurple_gir = gnome.generate_gir(libpurple,
sources : introspection_sources,
@@ -375,5 +354,5 @@
meson.current_source_dir(),
'check_license_header_template.h',
] + ['glibcompat.h'] + purple_coresources + purple_coreheaders +
- purple_mediaheaders + purple_private_headers + purple_request_headers)
+ purple_private_headers + purple_request_headers)
--- a/libpurple/purpleprotocolmedia.c Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "purpleprotocolmedia.h"
-
-/******************************************************************************
- * GObject Implementation
- *****************************************************************************/
-G_DEFINE_INTERFACE(PurpleProtocolMedia, purple_protocol_media,
- PURPLE_TYPE_PROTOCOL)
-
-static void
-purple_protocol_media_default_init(G_GNUC_UNUSED PurpleProtocolMediaInterface *iface)
-{
-}
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-gboolean
-purple_protocol_media_initiate_session(PurpleProtocolMedia *media,
- PurpleAccount *account,
- const gchar *who,
- PurpleMediaSessionType type)
-{
- PurpleProtocolMediaInterface *iface = NULL;
-
- g_return_val_if_fail(PURPLE_IS_PROTOCOL_MEDIA(media), FALSE);
-
- iface = PURPLE_PROTOCOL_MEDIA_GET_IFACE(media);
- if(iface && iface->initiate_session) {
- return iface->initiate_session(media, account, who, type);
- }
-
- return FALSE;
-}
-
-PurpleMediaCaps
-purple_protocol_media_get_caps(PurpleProtocolMedia *media,
- PurpleAccount *account, const gchar *who)
-{
- PurpleProtocolMediaInterface *iface = NULL;
-
- g_return_val_if_fail(PURPLE_IS_PROTOCOL_MEDIA(media),
- PURPLE_MEDIA_CAPS_NONE);
-
- iface = PURPLE_PROTOCOL_MEDIA_GET_IFACE(media);
- if(iface && iface->get_caps) {
- return iface->get_caps(media, account, who);
- }
-
- return PURPLE_MEDIA_CAPS_NONE;
-}
-
-gboolean
-purple_protocol_media_send_dtmf(PurpleProtocolMedia *protocol_media,
- PurpleMedia *media, gchar dtmf, guint8 volume,
- guint8 duration)
-{
- PurpleProtocolMediaInterface *iface = NULL;
-
- g_return_val_if_fail(PURPLE_IS_PROTOCOL_MEDIA(protocol_media), FALSE);
-
- iface = PURPLE_PROTOCOL_MEDIA_GET_IFACE(protocol_media);
- if(iface && iface->send_dtmf) {
- return iface->send_dtmf(protocol_media, media, dtmf, volume, duration);
- }
-
- return FALSE;
-}
--- a/libpurple/purpleprotocolmedia.h Thu May 09 21:21:24 2024 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_PROTOCOL_MEDIA_H
-#define PURPLE_PROTOCOL_MEDIA_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include "media.h"
-#include "purpleaccount.h"
-#include "purpleprotocol.h"
-#include "purpleversion.h"
-
-#define PURPLE_TYPE_PROTOCOL_MEDIA (purple_protocol_media_get_type())
-
-PURPLE_AVAILABLE_IN_3_0
-G_DECLARE_INTERFACE(PurpleProtocolMedia, purple_protocol_media, PURPLE,
- PROTOCOL_MEDIA, PurpleProtocol)
-
-G_BEGIN_DECLS
-
-/**
- * PurpleProtocolMedia:
- *
- * #PurpleProtocolMedia describes the multimedia api that is available for
- * protocols.
- *
- * Since: 3.0
- */
-
-struct _PurpleProtocolMediaInterface {
- /*< private >*/
- GTypeInterface parent;
-
- /*< public >*/
- gboolean (*initiate_session)(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who, PurpleMediaSessionType type);
-
- PurpleMediaCaps (*get_caps)(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who);
-
- gboolean (*send_dtmf)(PurpleProtocolMedia *protocol_media, PurpleMedia *media, gchar dtmf, guint8 volume, guint8 duration);
-
- /*< private >*/
- gpointer reserved[4];
-};
-
-/**
- * purple_protocol_media_initiate_session:
- * @media: The #PurpleProtocolMedia instance.
- * @account: The #PurpleAccount instance.
- * @who: The user to initiate a media session with.
- * @type: The type of media session to create.
- *
- * Initiates a media connection of @type to @who.
- *
- * Returns: %TRUE if successful, %FALSE otherwise.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-gboolean purple_protocol_media_initiate_session(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who, PurpleMediaSessionType type);
-
-/**
- * purple_protocol_media_get_caps:
- * @media: The #PurpleProtocolMedia instance.
- * @account: The #PurpleAccount instance.
- * @who: The user to get the media capabilities for.
- *
- * Gets the #PurpleMediaCaps for @who which determine what types of media are
- * available.
- *
- * Returns: the media capabilities of @who.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-PurpleMediaCaps purple_protocol_media_get_caps(PurpleProtocolMedia *media, PurpleAccount *account, const gchar *who);
-
-/**
- * purple_protocol_media_send_dtmf:
- * @protocol_media: The #PurpleProtocolMedia instance.
- * @media: The #PurpleMedia instance.
- * @dtmf: A DTMF to send.
- * @volume: The volume to send @dtmf at.
- * @duration: The duration to send @dtmf (in ms?)
- *
- * Sends a DTMF (dual-tone multi-frequency) signal via the established @media
- * for the given @duration at the given @volume.
- *
- * It is up to the specific implementation if DTMF is send in or out of band.
- *
- * Returns: %TRUE if successful, %FALSE otherwise.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-gboolean purple_protocol_media_send_dtmf(PurpleProtocolMedia *protocol_media, PurpleMedia *media, gchar dtmf, guint8 volume, guint8 duration);
-
-G_END_DECLS
-
-#endif /* PURPLE_PROTOCOL_MEDIA_H */
--- a/po/POTFILES.in Thu May 09 21:21:24 2024 -0500
+++ b/po/POTFILES.in Thu May 09 21:27:08 2024 -0500
@@ -4,12 +4,6 @@
libpurple/core.c
libpurple/debug.c
libpurple/image.c
-libpurple/media/backend-iface.c
-libpurple/media.c
-libpurple/media/candidate.c
-libpurple/media/codec.c
-libpurple/media/enum-types.c
-libpurple/mediamanager.c
libpurple/network.c
libpurple/notify.c
libpurple/plugins/autoaccept/autoaccept.c
@@ -55,7 +49,6 @@
libpurple/purpleprotocol.c
libpurple/purpleprotocolclient.c
libpurple/purpleprotocolmanager.c
-libpurple/purpleprotocolmedia.c
libpurple/purpleprotocolserver.c
libpurple/purpleprotocolwhiteboard.c
libpurple/purplesqlitehistoryadapter.c