Commit 26df0c6d authored by Simon Morlat's avatar Simon Morlat
Browse files

merge patch for notification bubbles + 2nd call incoming tone notification

parent fb0dfb52
......@@ -145,6 +145,28 @@ else
echo "GTK interface compilation is disabled."
fi
AC_ARG_ENABLE(notify,
[ --enable-notify=[yes/no] Enable libnotify support [default=yes]],
[case "${enableval}" in
yes) notify=true ;;
no) notify=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-notify) ;;
esac],[notify=true])
dnl conditionnal build of the notify library
if test "$gtk_ui" = "true" ; then
if test "$notify" = "true"; then
PKG_CHECK_MODULES([NOTIFY], [libnotify >= 0.7.0 ], [found_notify=yes], foo=bar)
case "$found_notify" in
yes)
AC_SUBST(NOTIFY_CFLAGS)
AC_SUBST(NOTIFY_LIBS)
AC_DEFINE([HAVE_NOTIFY],[1],[NOTIFY support])
esac
else
echo "Libnotify support is disabled."
fi
fi
dnl os-specific problems not handled by existing macros.
case "$host_os" in
......
......@@ -195,7 +195,8 @@ static void call_received(SalOp *h){
ms_message("the local ring is already started");
}
}else{
/*TODO : play a tone within the context of the current call */
/* play a tone within the context of the current call */
linphone_core_play_tone(lc);
}
......
......@@ -2313,7 +2313,6 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call)
ms_message("ring stopped");
lc->ringstream=NULL;
}
linphone_core_get_default_proxy(lc,&cfg);
dest_proxy=cfg;
dest_proxy=linphone_core_lookup_known_proxy(lc,call->log->to);
......@@ -2369,6 +2368,11 @@ static void terminate_call(LinphoneCore *lc, LinphoneCall *call){
ring_stop(lc->ringstream);
lc->ringstream=NULL;
}
/*stop any dtmf tone still playing */
ms_message("test");
linphone_core_stop_dtmf(lc);
linphone_call_stop_media_streams(call);
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Call ended") );
......@@ -3684,6 +3688,25 @@ void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms){
else ms_filter_call_method(f, MS_DTMF_GEN_START, &dtmf);
}
/**
* @ingroup media_parameters
* Plays a repeated tone to the local user until next further call to #linphone_core_stop_dtmf()
* @param lc #LinphoneCore
**/
void linphone_core_play_tone(LinphoneCore *lc){
MSFilter *f=get_dtmf_gen(lc);
MSDtmfGenCustomTone def;
if (f==NULL){
ms_error("No dtmf generator at this time !");
return;
}
def.duration=300;
def.frequency=500;
def.amplitude=1;
def.interval=800;
ms_filter_call_method(f, MS_DTMF_GEN_PLAY_CUSTOM,&def);
}
/**
* @ingroup media_parameters
*
......
......@@ -210,6 +210,8 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char
void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg);
void linphone_core_play_tone(LinphoneCore *lc);
void linphone_call_init_media_streams(LinphoneCall *call);
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone);
void linphone_call_stop_media_streams(LinphoneCall *call);
......
......@@ -49,7 +49,7 @@ linphone_SOURCES= \
linphone_LDADD=$(ORTP_LIBS) \
$(MEDIASTREAMER_LIBS) \
$(top_builddir)/coreapi/liblinphone.la \
$(LIBGTK_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS)
$(LIBGTK_LIBS) $(NOTIFY_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS)
if BUILD_WIN32
......
......@@ -36,6 +36,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define chdir _chdir
#endif
#ifdef HAVE_NOTIFY
#include <libnotify/notify.h>
#endif
#define LINPHONE_ICON "linphone.png"
const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
......@@ -56,6 +60,7 @@ static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl)
static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to);
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg);
static gboolean linphone_gtk_auto_answer(LinphoneCall *call);
static void linphone_gtk_status_icon_set_blinking(gboolean val);
static gboolean verbose=0;
......@@ -622,6 +627,24 @@ static void completion_add_text(GtkEntry *entry, const char *text){
save_uri_history();
}
static void linphone_gtk_show_main_window(){
GtkWidget *w=linphone_gtk_get_main_window();
LinphoneCore *lc=linphone_gtk_get_core();
if (linphone_core_video_enabled(lc)){
linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview",
VIDEOSELFVIEW_DEFAULT));
}
gtk_widget_show(w);
gtk_window_present(GTK_WINDOW(w));
}
static void linphone_gtk_show(LinphoneCore *lc){
#ifndef HAVE_NOTIFY
linphone_gtk_show_main_window();
#endif
}
void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){
GtkWidget *mw=linphone_gtk_get_main_window();
if (linphone_core_get_calls(linphone_gtk_get_core())==NULL){
......@@ -749,6 +772,7 @@ void linphone_gtk_answer_clicked(GtkWidget *button){
if (call){
linphone_core_pause_all_calls(linphone_gtk_get_core());
linphone_core_accept_call(linphone_gtk_get_core(),call);
linphone_gtk_show_main_window(); /* useful when the button is clicked on a notification */
}
}
......@@ -759,7 +783,7 @@ void linphone_gtk_enable_video(GtkWidget *w){
gtk_widget_set_sensitive(selfview_item,val);
if (val){
linphone_core_enable_video_preview(linphone_gtk_get_core(),
linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT));
linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT));
}else{
linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
}
......@@ -783,21 +807,6 @@ void linphone_gtk_used_identity_changed(GtkWidget *w){
if (sel) g_free(sel);
}
static void linphone_gtk_show_main_window(){
GtkWidget *w=linphone_gtk_get_main_window();
LinphoneCore *lc=linphone_gtk_get_core();
if (linphone_core_video_enabled(lc)){
linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview",
VIDEOSELFVIEW_DEFAULT));
}
gtk_widget_show(w);
gtk_window_present(GTK_WINDOW(w));
}
static void linphone_gtk_show(LinphoneCore *lc){
linphone_gtk_show_main_window();
}
static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid){
linphone_gtk_show_friends();
}
......@@ -938,6 +947,54 @@ static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl)
if (w) linphone_gtk_call_log_update(w);
}
#ifdef HAVE_NOTIFY
static void make_notification(const char *title, const char *body){
NotifyNotification *n;
n = notify_notification_new(title,body,linphone_gtk_get_ui_config("icon",LINPHONE_ICON));
if (n && !notify_notification_show(n,NULL))
ms_error("Failed to send notification.");
}
#endif
static void linphone_gtk_notify(LinphoneCall *call, const char *msg){
#ifdef HAVE_NOTIFY
if (!notify_is_initted())
if (!notify_init ("Linphone")) ms_error("Libnotify failed to init.");
#endif
if (!call) {
#ifdef HAVE_NOTIFY
if (!notify_notification_show(notify_notification_new("Linphone",msg,NULL),NULL))
ms_error("Failed to send notification.");
#else
linphone_gtk_show_main_window();
#endif
} else if (!gtk_window_is_active((GtkWindow*)linphone_gtk_get_main_window())) {
#ifdef HAVE_NOTIFY
char *body=NULL;
char *remote=call!=NULL ? linphone_call_get_remote_address_as_string(call) : NULL;
switch(linphone_call_get_state(call)){
case LinphoneCallError:
make_notification(_("Call error"),body=g_markup_printf_escaped("<span size=\"large\">%s</span>\n%s",msg,remote));
break;
case LinphoneCallEnd:
make_notification(_("Call ended"),body=g_markup_printf_escaped("<span size=\"large\">%s</span>",remote));
break;
case LinphoneCallIncomingReceived:
make_notification(_("Incoming call"),body=g_markup_printf_escaped("<span size=\"large\">%s</span>",remote));
break;
case LinphoneCallPausedByRemote:
make_notification(_("Call paused"),body=g_markup_printf_escaped("<span size=\"large\">by %s</span>",remote));
break;
default:
break;
}
if (body) g_free(body);
if (remote) g_free(remote);
#endif
}
}
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg){
switch(cs){
case LinphoneCallOutgoingInit:
......@@ -954,10 +1011,12 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
break;
case LinphoneCallEnd:
linphone_gtk_in_call_view_terminate(call,NULL);
linphone_gtk_status_icon_set_blinking(FALSE);
break;
case LinphoneCallIncomingReceived:
linphone_gtk_create_in_call_view (call);
linphone_gtk_in_call_view_set_incoming(call,!all_other_calls_paused (call,linphone_core_get_calls(lc)));
linphone_gtk_status_icon_set_blinking(TRUE);
if (auto_answer) {
linphone_call_ref(call);
g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer ,call);
......@@ -974,10 +1033,12 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
break;
case LinphoneCallConnected:
linphone_gtk_enable_hold_button (call,TRUE,TRUE);
linphone_gtk_status_icon_set_blinking(FALSE);
break;
default:
break;
}
linphone_gtk_notify(call, msg);
linphone_gtk_update_call_buttons (call);
}
......@@ -1060,18 +1121,49 @@ static GtkStatusIcon *icon=NULL;
static void linphone_gtk_init_status_icon(){
const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON);
const char *call_icon_path=linphone_gtk_get_ui_config("start_call_icon","startcall-green.png");
GdkPixbuf *pbuf=create_pixbuf(icon_path);
GtkWidget *menu=create_icon_menu();
const char *title;
title=linphone_gtk_get_ui_config("title",_("Linphone - a video internet phone"));
icon=gtk_status_icon_new_from_pixbuf(pbuf);
g_object_unref(G_OBJECT(pbuf));
gtk_status_icon_set_name(icon,title);
g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)linphone_gtk_show_main_window,linphone_gtk_get_main_window());
g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL);
title=linphone_gtk_get_ui_config("title",_("Linphone - a video internet phone"));
gtk_status_icon_set_tooltip(icon,title);
gtk_status_icon_set_visible(icon,TRUE);
g_object_set_data(G_OBJECT(icon),"menu",menu);
g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu);
g_object_set_data(G_OBJECT(icon),"icon",pbuf);
g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)g_object_unref,pbuf);
pbuf=create_pixbuf(call_icon_path);
g_object_set_data(G_OBJECT(icon),"call_icon",pbuf);
}
static gboolean do_icon_blink(GtkStatusIcon *gi){
GdkPixbuf *call_icon=g_object_get_data(G_OBJECT(gi),"call_icon");
GdkPixbuf *normal_icon=g_object_get_data(G_OBJECT(gi),"icon");
GdkPixbuf *cur_icon=gtk_status_icon_get_pixbuf(gi);
if (cur_icon==call_icon){
gtk_status_icon_set_from_pixbuf(gi,normal_icon);
}else{
gtk_status_icon_set_from_pixbuf(gi,call_icon);
}
return TRUE;
}
static void linphone_gtk_status_icon_set_blinking(gboolean val){
guint tout;
tout=(unsigned)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon),"timeout"));
if (val && tout==0){
tout=g_timeout_add(1000,(GSourceFunc)do_icon_blink,icon);
g_object_set_data(G_OBJECT(icon),"timeout",GINT_TO_POINTER(tout));
}else if (!val && tout!=0){
GdkPixbuf *normal_icon=g_object_get_data(G_OBJECT(icon),"icon");
g_source_remove(tout);
g_object_set_data(G_OBJECT(icon),"timeout",NULL);
gtk_status_icon_set_from_pixbuf(icon,normal_icon);
}
}
void linphone_gtk_load_identities(void){
......@@ -1348,9 +1440,11 @@ void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to){
GtkEntry * uri_bar =GTK_ENTRY(linphone_gtk_get_widget(
GtkEntry * uri_bar =GTK_ENTRY(linphone_gtk_get_widget(
linphone_gtk_get_main_window(), "uribar"));
linphone_gtk_show_main_window();
char *text;
linphone_gtk_notify(NULL,(text=ms_strdup_printf(_("We are transferred to %s"),refer_to)));
g_free(text);
gtk_entry_set_text(uri_bar, refer_to);
linphone_gtk_start_call(linphone_gtk_get_main_window());
}
......@@ -1359,16 +1453,19 @@ static void linphone_gtk_check_soundcards(){
const char **devices=linphone_core_get_sound_devices(linphone_gtk_get_core());
if (devices==NULL || devices[0]==NULL){
linphone_gtk_display_something(GTK_MESSAGE_WARNING,
_("No sound cards have been detected on this computer.\n"
"You won't be able to send or receive audio calls."));
_("No sound cards have been detected on this computer.\n"
"You won't be able to send or receive audio calls."));
}
}
static void linphone_gtk_quit(void){
gdk_threads_leave();
linphone_gtk_destroy_log_window();
linphone_core_destroy(the_core);
linphone_gtk_log_uninit();
linphone_gtk_destroy_log_window();
linphone_core_destroy(the_core);
linphone_gtk_log_uninit();
#ifdef HAVE_NOTIFY
notify_uninit();
#endif
}
#ifdef HAVE_GTK_OSX
......
......@@ -2,6 +2,66 @@
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="dummy_conf_window">
<property name="can_focus">False</property>
<child>
<object class="GtkFrame" id="callee_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="conf_alignment1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkHBox" id="conf_hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkProgressBar" id="sound_indicator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="hangup_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_conf_hangup_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="callee_name_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Callee name&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="dummy_in_call_window">
<property name="can_focus">False</property>
<child>
......@@ -90,7 +150,6 @@
<object class="GtkHButtonBox" id="mute_pause_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkButton" id="incall_mute">
<property name="label" translatable="yes">Mute</property>
......@@ -106,6 +165,20 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="incall_merge">
<property name="label" translatable="yes">Merge to conference</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_merge_to_conference" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="hold_call">
<property name="label" translatable="yes">Pause</property>
......@@ -118,7 +191,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
</object>
......
mediastreamer2 @ a73e5529
Subproject commit 90be72f669f3c5067c571b0f29f22eda21166006
Subproject commit a73e55293ed2b551cf12bfc85d812fa659fb25da
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment