adium/adium
Clone
Summary
Browse
Changes
Graph
1.5.10.3b1
adium-1.5.10.3
2017-03-23, Evan D. Schoenberg, M.D.
6d760b7b1d69
1.5.10.3b1
/*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program 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 program 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 program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <AdiumLibpurple/SLPurpleCocoaAdapter.h>
#import <Adium/AIAccount.h>
#import <Adium/AIListContact.h>
#import <Adium/AIMedia.h>
#import <Adium/AIMediaControllerProtocol.h>
#include
<string.h>
#include
<libpurple/media.h>
#include
<libpurple/mediamanager.h>
#include
<libpurple/media-gst.h>
#include
<gst/interfaces/xoverlay.h>
static
void
level_message_cb
(
PurpleMedia
*
media
,
gchar
*
session_id
,
gchar
*
participant
,
double
level
,
AIMedia
*
adiumMedia
)
{
if
(
participant
==
NULL
)
{
// Send progress
[
adiumMedia
setSendProgress
:
(
CGFloat
)
level
];
}
else
{
// Receive progress
[
adiumMedia
setReceiveProgress
:
(
CGFloat
)
level
];
}
}
static
void
adium_media_emit_message
(
AIMedia
*
adiumMedia
,
const
char
*
message
)
{
#warning emit message
NSLog
(
@"Media emit message: %s"
,
message
);
}
static
void
adium_media_error_cb
(
AIMedia
*
adiumMdia
,
const
char
*
message
)
{
#warning error message
NSLog
(
@"Media error message: %s"
,
message
);
}
static
void
adium_media_ready_cb
(
PurpleMedia
*
media
,
AIMedia
*
adiumMedia
,
const
gchar
*
sid
)
{
PurpleMediaSessionType
type
=
purple_media_get_session_type
(
media
,
sid
);
if
(
type
&
PURPLE_MEDIA_RECV_VIDEO
)
{
// Setup receiving video view
#warning Set up receiving video view
}
if
(
type
&
PURPLE_MEDIA_SEND_VIDEO
)
{
// Set up sending video view
#warning Set up sending video view
}
if
(
type
&
PURPLE_MEDIA_RECV_AUDIO
)
{
// Set up receiving audio
#warning Set up receiving audio
}
if
(
type
&
PURPLE_MEDIA_SEND_AUDIO
)
{
// Set up sending audio
#warning Set up sending audio
}
if
(
purple_media_is_initiator
(
media
,
sid
,
NULL
)
==
FALSE
)
{
#warning Add something to accept or reject this media
}
/* set the window icon according to the type */
if
(
type
&
PURPLE_MEDIA_VIDEO
)
{
adiumMedia
.
mediaType
|=
AIMediaTypeVideo
;
}
else
if
(
type
&
PURPLE_MEDIA_AUDIO
)
{
adiumMedia
.
mediaType
|=
AIMediaTypeAudio
;
}
}
static
void
adium_media_state_changed_cb
(
PurpleMedia
*
media
,
PurpleMediaState
state
,
gchar
*
sid
,
gchar
*
name
,
AIMedia
*
adiumMedia
)
{
NSLog
(
@"state: %d sid: %s name: %s
\n
"
,
state
,
sid
?
sid
:
"(null)"
,
name
?
name
:
"(null)"
);
adiumMedia
.
mediaState
=
state
;
if
(
sid
==
NULL
&&
name
==
NULL
)
{
if
(
state
==
PURPLE_MEDIA_STATE_END
)
{
adium_media_emit_message
(
adiumMedia
,
_
(
"The call has been terminated."
));
}
}
else
if
(
state
==
PURPLE_MEDIA_STATE_NEW
&&
sid
!=
NULL
&&
name
!=
NULL
)
{
adium_media_ready_cb
(
media
,
adiumMedia
,
sid
);
}
}
static
void
adium_media_stream_info_cb
(
PurpleMedia
*
media
,
PurpleMediaInfoType
type
,
gchar
*
sid
,
gchar
*
name
,
gboolean
local
,
AIMedia
*
adiumMedia
)
{
NSLog
(
@"Media stream info cb: %d"
,
type
);
if
(
type
==
PURPLE_MEDIA_INFO_REJECT
)
{
adium_media_emit_message
(
adiumMedia
,
_
(
"You have rejected the call."
));
}
else
if
(
type
==
PURPLE_MEDIA_INFO_ACCEPT
)
{
#warning Check for pending accept/deny
adiumMedia
.
mediaState
=
AIMediaStateAccepted
;
adium_media_emit_message
(
adiumMedia
,
_
(
"Call in progress."
));
}
}
static
gboolean
adium_media_new_cb
(
PurpleMediaManager
*
manager
,
PurpleMedia
*
media
,
PurpleAccount
*
account
,
gchar
*
screenname
,
gpointer
nul
)
{
NSLog
(
@"Media new cb: %s"
,
screenname
);
AIListContact
*
contact
=
contactLookupFromBuddy
(
purple_find_buddy
(
account
,
screenname
));
AIAccount
*
adiumAccount
=
accountLookup
(
account
);
AIMedia
*
adiumMedia
=
[
adium
.
mediaController
mediaWithContact
:
contact
onAccount
:
adiumAccount
];
adiumMedia
.
protocolInfo
=
(
id
)
media
;
if
(
purple_media_is_initiator
(
media
,
NULL
,
NULL
)
==
TRUE
)
{
adiumMedia
.
mediaState
=
AIMediaStateWaiting
;
[[
adium
.
mediaController
windowControllerForMedia
:
adiumMedia
]
showWindow
:
nil
];
}
else
{
adiumMedia
.
mediaState
=
AIMediaStateRequested
;
}
g_signal_connect
(
G_OBJECT
(
media
),
"error"
,
G_CALLBACK
(
adium_media_error_cb
),
adiumMedia
);
g_signal_connect
(
G_OBJECT
(
media
),
"state-changed"
,
G_CALLBACK
(
adium_media_state_changed_cb
),
adiumMedia
);
g_signal_connect
(
G_OBJECT
(
media
),
"stream-info"
,
G_CALLBACK
(
adium_media_stream_info_cb
),
adiumMedia
);
g_signal_connect
(
G_OBJECT
(
media
),
"level"
,
G_CALLBACK
(
level_message_cb
),
adiumMedia
);
return
TRUE
;
}
void
adium_media_remove
(
AIMedia
*
adiumMedia
)
{
PurpleMedia
*
media
=
(
PurpleMedia
*
)
adiumMedia
.
protocolInfo
;
purple_media_remove_output_windows
(
media
);
PurpleMediaManager
*
manager
=
purple_media_get_manager
(
media
);
GstElement
*
element
=
purple_media_manager_get_pipeline
(
manager
);
gulong
handler_id
=
g_signal_handler_find
(
G_OBJECT
(
gst_pipeline_get_bus
(
GST_PIPELINE
(
element
))),
G_SIGNAL_MATCH_FUNC
|
G_SIGNAL_MATCH_DATA
,
0
,
0
,
NULL
,
G_CALLBACK
(
level_message_cb
),
adiumMedia
);
if
(
handler_id
)
{
g_signal_handler_disconnect
(
G_OBJECT
(
gst_pipeline_get_bus
(
GST_PIPELINE
(
element
))),
handler_id
);
}
}
static
GstElement
*
create_default_video_src
(
PurpleMedia
*
media
,
const
gchar
*
session_id
,
const
gchar
*
participant
)
{
GstElement
*
sendbin
,
*
src
,
*
videoscale
,
*
capsfilter
;
GstPad
*
pad
;
GstPad
*
ghost
;
GstCaps
*
caps
;
src
=
gst_element_factory_make
(
"osxvideosrc"
,
NULL
);
if
(
src
==
NULL
)
{
NSLog
(
@"Unable to find suitable element for default video source."
);
return
NULL
;
}
sendbin
=
gst_bin_new
(
"adiumdefaultvideosrc"
);
videoscale
=
gst_element_factory_make
(
"videoscale"
,
NULL
);
capsfilter
=
gst_element_factory_make
(
"capsfilter"
,
NULL
);
/* It was recommended to set the size <= 352x288 and framerate <= 20 */
caps
=
gst_caps_from_string
(
"video/x-raw-yuv , width=[250,352] , height=[200,288] , framerate=[1/1,20/1]"
);
g_object_set
(
G_OBJECT
(
capsfilter
),
"caps"
,
caps
,
NULL
);
gst_bin_add_many
(
GST_BIN
(
sendbin
),
src
,
videoscale
,
capsfilter
,
NULL
);
gst_element_link_many
(
src
,
videoscale
,
capsfilter
,
NULL
);
pad
=
gst_element_get_static_pad
(
capsfilter
,
"src"
);
ghost
=
gst_ghost_pad_new
(
"ghostsrc"
,
pad
);
gst_object_unref
(
pad
);
gst_element_add_pad
(
sendbin
,
ghost
);
return
sendbin
;
}
static
GstElement
*
create_default_video_sink
(
PurpleMedia
*
media
,
const
gchar
*
session_id
,
const
gchar
*
participant
)
{
GstElement
*
sink
=
gst_element_factory_make
(
"osxvideosink"
,
NULL
);
if
(
sink
==
NULL
)
{
NSLog
(
@"Unable to find suitable element for default video sink."
);
}
return
sink
;
}
static
GstElement
*
create_default_audio_src
(
PurpleMedia
*
media
,
const
gchar
*
session_id
,
const
gchar
*
participant
)
{
GstElement
*
src
;
src
=
gst_element_factory_make
(
"osxaudiosrc"
,
NULL
);
if
(
src
==
NULL
)
{
NSLog
(
@"Unable to find suitable element for default audio source."
);
return
NULL
;
}
gst_element_set_name
(
src
,
"adiumdefaultaudiosrc"
);
return
src
;
}
static
GstElement
*
create_default_audio_sink
(
PurpleMedia
*
media
,
const
gchar
*
session_id
,
const
gchar
*
participant
)
{
GstElement
*
sink
;
sink
=
gst_element_factory_make
(
"osxaudiosink"
,
NULL
);
if
(
sink
==
NULL
)
{
NSLog
(
@"Unable to find suitable element for default audio sink."
);
return
NULL
;
}
return
sink
;
}
void
adiumPurpleMedia_init
(
void
)
{
PurpleMediaManager
*
manager
=
purple_media_manager_get
();
PurpleMediaElementInfo
*
default_video_src
=
g_object_new
(
PURPLE_TYPE_MEDIA_ELEMENT_INFO
,
"id"
,
"adiumdefaultvideosrc"
,
"name"
,
"Adium Default Video Source"
,
"type"
,
PURPLE_MEDIA_ELEMENT_VIDEO
|
PURPLE_MEDIA_ELEMENT_SRC
|
PURPLE_MEDIA_ELEMENT_ONE_SRC
|
PURPLE_MEDIA_ELEMENT_UNIQUE
,
"create-cb"
,
create_default_video_src
,
NULL
);
PurpleMediaElementInfo
*
default_video_sink
=
g_object_new
(
PURPLE_TYPE_MEDIA_ELEMENT_INFO
,
"id"
,
"adiumdefaultvideosink"
,
"name"
,
"Adium Default Video Sink"
,
"type"
,
PURPLE_MEDIA_ELEMENT_VIDEO
|
PURPLE_MEDIA_ELEMENT_SINK
|
PURPLE_MEDIA_ELEMENT_ONE_SINK
,
"create-cb"
,
create_default_video_sink
,
NULL
);
PurpleMediaElementInfo
*
default_audio_src
=
g_object_new
(
PURPLE_TYPE_MEDIA_ELEMENT_INFO
,
"id"
,
"adiumdefaultaudiosrc"
,
"name"
,
"Adium Default Audio Source"
,
"type"
,
PURPLE_MEDIA_ELEMENT_AUDIO
|
PURPLE_MEDIA_ELEMENT_SRC
|
PURPLE_MEDIA_ELEMENT_ONE_SRC
|
PURPLE_MEDIA_ELEMENT_UNIQUE
,
"create-cb"
,
create_default_audio_src
,
NULL
);
PurpleMediaElementInfo
*
default_audio_sink
=
g_object_new
(
PURPLE_TYPE_MEDIA_ELEMENT_INFO
,
"id"
,
"adiumdefaultaudiosink"
,
"name"
,
"Adium Default Audio Sink"
,
"type"
,
PURPLE_MEDIA_ELEMENT_AUDIO
|
PURPLE_MEDIA_ELEMENT_SINK
|
PURPLE_MEDIA_ELEMENT_ONE_SINK
,
"create-cb"
,
create_default_audio_sink
,
NULL
);
g_signal_connect
(
G_OBJECT
(
manager
),
"init-media"
,
G_CALLBACK
(
adium_media_new_cb
),
NULL
);
purple_media_manager_set_ui_caps
(
manager
,
PURPLE_MEDIA_CAPS_AUDIO
|
PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION
|
PURPLE_MEDIA_CAPS_VIDEO
|
PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION
|
PURPLE_MEDIA_CAPS_AUDIO_VIDEO
);
AILogWithSignature
(
@"Registering media element types"
);
purple_media_manager_set_active_element
(
manager
,
default_video_src
);
purple_media_manager_set_active_element
(
manager
,
default_video_sink
);
purple_media_manager_set_active_element
(
manager
,
default_audio_src
);
purple_media_manager_set_active_element
(
manager
,
default_audio_sink
);
}