From 43f371594fcb9667163a911108f9724372d66c02 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 10 Sep 2010 12:06:01 +0200 Subject: [PATCH] multicall in gtk and bugfixes --- console/commands.c | 3 +++ console/linphonec.c | 3 +++ coreapi/callbacks.c | 4 ++-- coreapi/linphonecall.c | 8 ++++---- coreapi/linphonecore.c | 22 ++++++++++++++++------ coreapi/linphonecore.h | 3 +++ coreapi/offeranswer.c | 17 ++++++++++++++++- gtk/incall_view.c | 23 ++++++++++++++++++++--- gtk/linphone.h | 3 ++- gtk/main.c | 18 ++++++++++++------ 10 files changed, 81 insertions(+), 23 deletions(-) diff --git a/console/commands.c b/console/commands.c index 3abe0fb68..816135687 100644 --- a/console/commands.c +++ b/console/commands.c @@ -413,6 +413,9 @@ static const char *get_call_status(LinphoneCall *call){ return "Paused"; } break; + case LinphoneCallPausedByRemote: + return "Paused by remote"; + break; case LinphoneCallIncomingReceived: return "Pending"; break; diff --git a/console/linphonec.c b/console/linphonec.c index df86abb8f..75121db61 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -325,6 +325,9 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L case LinphoneCallPaused: linphonec_out("Call %i with %s is now paused.\n", id, from); break; + case LinphoneCallPausedByRemote: + linphonec_out("Call %i has been paused by %s.\n",id,from); + break; case LinphoneCallIncomingReceived: linphonec_call_identify(call); id=(long)linphone_call_get_user_pointer (call); diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 8cbccc7c3..c96207251 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -277,7 +277,7 @@ static void call_updating(SalOp *op){ if (call->resultdesc && !sal_media_description_empty(call->resultdesc)) { - if (call->state==LinphoneCallPaused && + if (call->state==LinphoneCallPausedByRemote && sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv) && strcmp(call->resultdesc->addr,"0.0.0.0")!=0){ /*make sure we can be resumed */ if (lc->current_call!=NULL && lc->current_call!=call){ @@ -294,7 +294,7 @@ static void call_updating(SalOp *op){ sal_media_description_has_dir(call->resultdesc,SalStreamRecvOnly) && !strcmp(call->resultdesc->addr,"0.0.0.0")){ if(lc->vtable.display_status) lc->vtable.display_status(lc,_("We are being paused...")); - linphone_call_set_state (call,LinphoneCallPaused,"Call paused"); + linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote"); if (lc->current_call!=call){ ms_error("Inconsitency detected: current call is %p but call %p is being paused !",lc->current_call,call); } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 3244aac7e..00739ae95 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -293,8 +293,9 @@ void linphone_call_ref(LinphoneCall *obj){ **/ void linphone_call_unref(LinphoneCall *obj){ obj->refcnt--; - if (obj->refcnt==0) + if (obj->refcnt==0){ linphone_call_destroy(obj); + } } /** @@ -576,7 +577,6 @@ static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md, number=payload_type_get_number(pt); if (rtp_profile_get_payload(prof,number)!=NULL){ ms_warning("A payload type with number %i already exists in profile !",number); - payload_type_destroy(pt); }else rtp_profile_set_payload(prof,number,pt); } @@ -603,7 +603,7 @@ void linphone_call_start_media_streams(LinphoneCall *call){ { const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc, SalProtoRtpAvp,SalAudio); - if (stream){ + if (stream && stream->dir!=SalStreamInactive){ MSSndCard *playcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard; MSSndCard *captcard=lc->sound_conf.capt_sndcard; @@ -661,7 +661,7 @@ void linphone_call_start_media_streams(LinphoneCall *call){ video_preview_stop(lc->previewstream); lc->previewstream=NULL; } - if (stream) { + if (stream && stream->dir!=SalStreamInactive) { const char *addr=stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr; call->video_profile=make_profile(lc,call->resultdesc,stream,&used_pt); if (used_pt!=-1){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0bbfe8af1..89ad4382a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2283,11 +2283,6 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call) { LinphoneCall *call = the_call; - if(linphone_core_get_current_call(lc) != call) - { - ms_error("The call asked to be paused was not the current on"); - return -1; - } if (sal_call_hold(call->op,TRUE) != 0) { if (lc->vtable.display_warning) @@ -2301,6 +2296,21 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call) return 0; } +/** + * Pause all currently running calls. +**/ +int linphone_core_pause_all_calls(LinphoneCore *lc){ + const MSList *elem; + for(elem=lc->calls;elem!=NULL;elem=elem->next){ + LinphoneCall *call=(LinphoneCall *)elem->data; + LinphoneCallState cs=linphone_call_get_state(call); + if (cs==LinphoneCallStreamsRunning && cs==LinphoneCallPausedByRemote){ + linphone_core_pause_call(lc,call); + } + } + return 0; +} + /** * Resumes the call. * @@ -2312,7 +2322,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call) LinphoneCall *call = the_call; if(call->state!=LinphoneCallPaused ){ - ms_warning("we cannot resume a call when the communication is not established"); + ms_warning("we cannot resume a call that has not been established and paused before"); return -1; } if(linphone_core_get_current_call(lc) != NULL){ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index c845e4596..707e4b40c 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -176,6 +176,7 @@ typedef enum _LinphoneCallState{ LinphoneCallRefered, LinphoneCallError, LinphoneCallEnd, + LinphoneCallPausedByRemote } LinphoneCallState; @@ -527,6 +528,8 @@ int linphone_core_terminate_all_calls(LinphoneCore *lc); int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call); +int linphone_core_pause_all_calls(LinphoneCore *lc); + int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call); LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address); diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 172255716..ac5ea1d7a 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -98,6 +98,21 @@ static bool_t only_telephone_event(const MSList *l){ return TRUE; } +static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){ + SalStreamDir res=local; + if (local==SalStreamSendRecv){ + if (answered==SalStreamRecvOnly){ + res=SalStreamSendOnly; + }else if (answered==SalStreamSendOnly){ + res=SalStreamRecvOnly; + } + } + if (answered==SalStreamInactive){ + res=SalStreamInactive; + } + return res; +} + static void initiate_outgoing(const SalStreamDescription *local_offer, const SalStreamDescription *remote_answer, SalStreamDescription *result){ @@ -105,7 +120,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE); result->proto=local_offer->proto; result->type=local_offer->type; - result->dir=local_offer->dir; + result->dir=compute_dir(local_offer->dir,remote_answer->dir); if (result->payloads && !only_telephone_event(result->payloads)){ strcpy(result->addr,remote_answer->addr); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index fca97adda..ffa6329d3 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -72,7 +72,11 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){ GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); static int call_index=1; int idx; - + + if (ms_list_size(linphone_core_get_calls(linphone_gtk_get_core()))==1){ + /*this is the only call at this time */ + call_index=1; + } g_object_set_data(G_OBJECT(call_view),"call",call); linphone_call_set_user_pointer (call,call_view); linphone_call_ref(call); @@ -131,20 +135,26 @@ void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){ }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_FIND,GTK_ICON_SIZE_DIALOG); } -void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call){ +void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_pause){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri"); GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration"); GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif"); + GtkWidget *answer_button; gtk_label_set_markup(GTK_LABEL(status),_("Incoming call")); gtk_widget_show_all(linphone_gtk_get_widget(callview,"answer_decline_panel")); display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); - gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"accept_call")), + answer_button=linphone_gtk_get_widget(callview,"accept_call"); + gtk_button_set_image(GTK_BUTTON(answer_button), create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"))); + if (with_pause){ + gtk_button_set_label(GTK_BUTTON(answer_button), + _("Pause all calls\nand answer")); + }else gtk_button_set_label(GTK_BUTTON(answer_button),_("Answer")); gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")), create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"))); @@ -181,6 +191,13 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ g_object_set_data(G_OBJECT(holdbutton),"call",call); } +void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); + gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); + gtk_label_set_markup(GTK_LABEL(status),_("Paused call with")); +} + void linphone_gtk_in_call_view_update_duration(LinphoneCall *call){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *duration_label=linphone_gtk_get_widget(callview,"in_call_duration"); diff --git a/gtk/linphone.h b/gtk/linphone.h index c50dde591..0b77f6430 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -93,7 +93,8 @@ void linphone_gtk_in_call_view_set_calling(LinphoneCall *call); void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call); void linphone_gtk_in_call_view_update_duration(LinphoneCall *call); void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg); -void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call); +void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_pause); +void linphone_gtk_in_call_view_set_paused(LinphoneCall *call); void linphone_gtk_enable_mute_button(GtkToggleButton *button, gboolean sensitive); void linphone_gtk_enable_hold_button(GtkToggleButton *button, gboolean sensitive); diff --git a/gtk/main.c b/gtk/main.c index f435ff31a..6ad7c65fe 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -636,7 +636,8 @@ static gboolean in_call_timer(){ static bool_t all_calls_paused(const MSList *calls){ for(;calls!=NULL;calls=calls->next){ LinphoneCall *call=(LinphoneCall*)calls->data; - if (linphone_call_get_state(call)!=LinphoneCallPaused) + LinphoneCallState cs=linphone_call_get_state(call); + if (cs!=LinphoneCallPaused && cs!=LinphoneCallIncomingReceived) return FALSE; } return TRUE; @@ -741,8 +742,10 @@ void linphone_gtk_decline_clicked(GtkWidget *button){ void linphone_gtk_answer_clicked(GtkWidget *button){ LinphoneCall *call=linphone_gtk_get_currently_displayed_call (); - if (call) + if (call){ + linphone_core_pause_all_calls(linphone_gtk_get_core()); linphone_core_accept_call(linphone_gtk_get_core(),call); + } } void linphone_gtk_set_audio_video(){ @@ -937,7 +940,7 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call case LinphoneCallOutgoingProgress: linphone_gtk_in_call_view_set_calling (call); break; - case LinphoneCallConnected: + case LinphoneCallStreamsRunning: linphone_gtk_in_call_view_set_in_call(call); linphone_gtk_enable_mute_button( GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")), @@ -952,12 +955,15 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call break; case LinphoneCallIncomingReceived: linphone_gtk_create_in_call_view (call); - linphone_gtk_in_call_view_set_incoming(call); + linphone_gtk_in_call_view_set_incoming(call,!all_calls_paused (linphone_core_get_calls(lc))); if (auto_answer) { linphone_call_ref(call); g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer ,call); - } - + } + break; + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: + linphone_gtk_in_call_view_set_paused(call); break; default: break;