diff --git a/NEWS b/NEWS index 903df2fb20cda7f64cefcd040ce73bb1cb39621c..2f74239aa4cf1759f90457dc7348e849725629b8 100644 --- a/NEWS +++ b/NEWS @@ -5,8 +5,9 @@ linphone-3.4.0 -- XXXXX - acceptance of 2nd call while putting the others on hold - creation of another outgoing call while already in call - blind call transfer - - attend call transfer + - attended call transfer * improve bandwidth management (one b=AS line is used for audio+video) + * improvements in the echo limiter * stun support bugfixes * possibility to use two video windows, one for local preview, one for remote video (linphonec only) * optimize by not re-creating streams when SDP is unchanged during a reinvite diff --git a/coreapi/sal.c b/coreapi/sal.c index 4e09846f696cb5c857e7b73bad1e1ab7dd1dcf00..6f80436c624787096261898bc183cb6959da4637 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -267,9 +267,11 @@ void __sal_op_free(SalOp *op){ sal_media_description_unref(b->remote_media); ms_free(op); } + SalAuthInfo* sal_auth_info_new() { return ms_new0(SalAuthInfo,1); } + SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info) { SalAuthInfo* new_auth_info=sal_auth_info_new(); new_auth_info->username=auth_info->username?ms_strdup(auth_info->username):NULL; @@ -278,6 +280,7 @@ SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info) { new_auth_info->password=auth_info->password?ms_strdup(auth_info->password):NULL; return new_auth_info; } + void sal_auth_info_delete(const SalAuthInfo* auth_info) { if (auth_info->username) ms_free(auth_info->username); if (auth_info->userid) ms_free(auth_info->userid); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 28f05da378af1212efb6a168b516adffb33dd50e..733f8df27eab63b2255678a38107b6d9411bc78d 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -747,7 +747,7 @@ static void push_auth_to_exosip(const SalAuthInfo *info){ eXosip_add_authentication_info (info->username,userid, info->password, NULL,info->realm); } -/** +/* * Just for symmetry ;-) */ static void pop_auth_from_exosip() { @@ -1729,7 +1729,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){ call_message_new(sal,ev); break; case EXOSIP_CALL_MESSAGE_REQUESTFAILURE: - if (ev->did<0 && ev->response && + if (ev->response && (ev->response->status_code==407 || ev->response->status_code==401)){ return process_authentication(sal,ev); } diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 83df3a44754075406dc1fae01f37c2db19b25a82..3941bfe727055bd9ec5ec2327ceacde24cfba582 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -58,7 +58,7 @@ static GtkWidget *make_tab_header(int number){ GtkWidget *w=gtk_hbox_new (FALSE,0); GtkWidget *i=create_pixmap ("status-green.png"); GtkWidget *l; - gchar *text=g_strdup_printf("Call %i",number); + gchar *text=g_strdup_printf("Call #%i",number); l=gtk_label_new (text); gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); gtk_box_pack_end(GTK_BOX(w),l,TRUE,TRUE,0); @@ -66,6 +66,60 @@ static GtkWidget *make_tab_header(int number){ return w; } +static void linphone_gtk_transfer_call(LinphoneCall *dest_call){ + LinphoneCall *call=linphone_gtk_get_currently_displayed_call(); + linphone_core_transfer_call_to_another (linphone_gtk_get_core(),call,dest_call); +} + +static void transfer_button_clicked(GtkWidget *button, gpointer call_ref){ + GtkWidget *menu_item; + GtkWidget *menu=gtk_menu_new(); + LinphoneCall *call=(LinphoneCall*)call_ref; + LinphoneCore *lc=linphone_gtk_get_core(); + const MSList *elem=linphone_core_get_calls(lc); + + for(;elem!=NULL;elem=elem->next){ + LinphoneCall *other_call=(LinphoneCall*)elem->data; + GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(other_call); + if (other_call!=call){ + int call_index=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(call_view),"call_index")); + char *remote_uri=linphone_call_get_remote_address_as_string (other_call); + char *text=g_strdup_printf("Transfer to call #%i with %s",call_index,remote_uri); + menu_item=gtk_image_menu_item_new_with_label(text); + ms_free(remote_uri); + g_free(text); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),create_pixmap("status-green.png")); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_transfer_call,other_call); + } + } + gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0, + gtk_get_current_event_time()); + gtk_widget_show(menu); +} + +void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value){ + const MSList *elem=linphone_core_get_calls(lc); + for(;elem!=NULL;elem=elem->next){ + LinphoneCall *call=(LinphoneCall*)elem->data; + GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *box=linphone_gtk_get_widget (call_view,"mute_pause_buttons"); + GtkWidget *button=(GtkWidget*)g_object_get_data(G_OBJECT(box),"transfer"); + if (button && value==FALSE){ + gtk_widget_destroy(button); + button=NULL; + }else if (!button && value==TRUE){ + button=gtk_button_new_with_label (_("Transfer")); + gtk_button_set_image(GTK_BUTTON(button),gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,GTK_ICON_SIZE_BUTTON)); + g_signal_connect(G_OBJECT(button),"clicked",(GCallback)transfer_button_clicked,call); + gtk_widget_show_all(button); + gtk_container_add(GTK_CONTAINER(box),button); + } + g_object_set_data(G_OBJECT(box),"transfer",button); + } +} + void linphone_gtk_create_in_call_view(LinphoneCall *call){ GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame"); GtkWidget *main_window=linphone_gtk_get_main_window (); @@ -78,6 +132,8 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){ call_index=1; } g_object_set_data(G_OBJECT(call_view),"call",call); + g_object_set_data(G_OBJECT(call_view),"call_index",GINT_TO_POINTER(call_index)); + linphone_call_set_user_pointer (call,call_view); linphone_call_ref(call); gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index)); diff --git a/gtk/linphone.h b/gtk/linphone.h index 70e1d5dc4545a93dcc632d4c99cba1dca0016e12..faa2cb5ed3a10eff8417d8f8a1a76ff0802af7d3 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -97,6 +97,7 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus void linphone_gtk_in_call_view_set_paused(LinphoneCall *call); void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive); void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon); +void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value); void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg); void linphone_gtk_exit_login_frame(void); diff --git a/gtk/main.c b/gtk/main.c index f88f9cfcda2807d6040733b7804255956b0d181b..643f948d9adb2e11e2e0a52067c96181e3e3e5f3 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -689,6 +689,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ bool_t start_active=TRUE; bool_t stop_active=FALSE; bool_t add_call=FALSE; + int call_list_size=ms_list_size(calls); if (calls==NULL){ start_active=TRUE; @@ -699,7 +700,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ start_active=TRUE; add_call=TRUE; }else if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived && all_other_calls_paused(call,calls)){ - if (ms_list_size(calls)>1){ + if (call_list_size>1){ start_active=TRUE; add_call=TRUE; }else{ @@ -724,6 +725,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ GTK_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")), FALSE); } + linphone_gtk_enable_transfer_button(lc,call_list_size>1); update_video_title(); } diff --git a/gtk/main.ui b/gtk/main.ui index a2c717df58e86ad65c275902c278959a0c0672ba..4f3e6797ad1d8edbfe9f709354ed7aaab61f65e2 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -1401,6 +1401,8 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">2</property> </packing> </child>