diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 4fd1d700d..d2ac2c524 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2093,11 +2093,8 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneProxyConfig *dest_proxy=NULL; LinphoneCall *call; - if (linphone_core_in_call(lc)){ - if (lc->vtable.display_warning) - lc->vtable.display_warning(lc,_("Sorry, you have to pause or stop the current call or conference first !")); - return NULL; - } + linphone_core_preempt_sound_resources(lc); + if(!linphone_core_can_we_add_call(lc)){ if (lc->vtable.display_warning) lc->vtable.display_warning(lc,_("Sorry, we have reached the maximum number of simultaneous calls")); @@ -2287,25 +2284,12 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) if (rc){ ms_message("Call %p replaces call %p. This last one is going to be terminated automatically.", call,rc); - linphone_core_terminate_call (lc,rc); + linphone_core_terminate_call(lc,rc); } } - if (lc->current_call!=NULL && lc->current_call!=call){ - ms_warning("Cannot accept this call, there is already one running."); - return -1; - } - - /*can accept a new call only if others are on hold */ - { - MSList *elem; - for(elem=lc->calls;elem!=NULL;elem=elem->next){ - LinphoneCall *c=(LinphoneCall*)elem->data; - if (c!=call && (c->state!=LinphoneCallPaused && c->state!=LinphoneCallPausing)){ - ms_warning("Cannot accept this call as another one is running, pause it before."); - return -1; - } - } + if (lc->current_call!=call){ + linphone_core_preempt_sound_resources(lc); } /*stop ringing */ @@ -2527,6 +2511,19 @@ int linphone_core_pause_all_calls(LinphoneCore *lc){ return 0; } +void linphone_core_preempt_sound_resources(LinphoneCore *lc){ + LinphoneCall *current_call; + if (linphone_core_is_in_conference(lc)){ + linphone_core_leave_conference(lc); + return; + } + current_call=linphone_core_get_current_call(lc); + if(current_call != NULL){ + ms_message("Pausing automatically the current call."); + linphone_core_pause_call(lc,current_call); + } +} + /** * Resumes the call. * @@ -2543,12 +2540,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call) return -1; } if (call->params.in_conference==FALSE){ - if(linphone_core_get_current_call(lc) != NULL){ - ms_warning("There is already a call in process, pause or stop it first."); - if (lc->vtable.display_warning) - lc->vtable.display_warning(lc,_("There is already a call in process, pause or stop it first.")); - return -1; - } + linphone_core_preempt_sound_resources(lc); ms_message("Resuming call %p",call); } sal_media_description_set_dir(call->localdesc,SalStreamSendRecv); diff --git a/coreapi/private.h b/coreapi/private.h index 2424d68be..b8aba9d1f 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -507,7 +507,7 @@ LinphoneEcCalibratorStatus ec_calibrator_get_status(EcCalibrator *ecc); void ec_calibrator_destroy(EcCalibrator *ecc); void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed); - +void linphone_core_preempt_sound_resources(LinphoneCore *lc); /*conferencing subsystem*/ void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted); void linphone_call_add_to_conf(LinphoneCall *call); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 659f4b30d..6a2dc0cda 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -126,6 +126,8 @@ static void transfer_button_clicked(GtkWidget *button, gpointer call_ref){ 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){ @@ -147,6 +149,31 @@ void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value){ } } +static void conference_button_clicked(GtkWidget *button, gpointer call_ref){ + +} + +void linphone_gtk_enable_conference_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),"conference"); + if (button && value==FALSE){ + gtk_widget_destroy(button); + button=NULL; + }else if (!button && value==TRUE){ + button=gtk_button_new_with_label (_("Conference")); + gtk_button_set_image(GTK_BUTTON(button),gtk_image_new_from_stock (GTK_STOCK_ADD,GTK_ICON_SIZE_BUTTON)); + g_signal_connect(G_OBJECT(button),"clicked",(GCallback)conference_button_clicked,call); + gtk_widget_show_all(button); + gtk_container_add(GTK_CONTAINER(box),button); + } + g_object_set_data(G_OBJECT(box),"conference",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 (); @@ -216,7 +243,7 @@ void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){ linphone_gtk_in_call_set_animation_spinner(callview); } -void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_pause){ +void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call){ 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"); @@ -230,10 +257,7 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus answer_button=linphone_gtk_get_widget(callview,"accept_call"); image=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_label(GTK_BUTTON(answer_button),_("Answer")); gtk_button_set_image(GTK_BUTTON(answer_button),image); gtk_widget_show(image); diff --git a/gtk/linphone.h b/gtk/linphone.h index 01bf71265..db25bbdd2 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -102,11 +102,12 @@ 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, bool_t with_pause); +void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call); 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_enable_conference_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 dccc09cfb..6675af430 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -655,18 +655,6 @@ void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){ update_video_title(); } -static bool_t all_other_calls_paused(LinphoneCall *refcall, const MSList *calls){ - for(;calls!=NULL;calls=calls->next){ - LinphoneCall *call=(LinphoneCall*)calls->data; - LinphoneCallState cs=linphone_call_get_state(call); - if (refcall!=call){ - if (cs!=LinphoneCallPaused && cs!=LinphoneCallPausing) - return FALSE; - } - } - return TRUE; -} - static void linphone_gtk_update_call_buttons(LinphoneCall *call){ LinphoneCore *lc=linphone_gtk_get_core(); GtkWidget *mw=linphone_gtk_get_main_window(); @@ -681,21 +669,9 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ start_active=TRUE; stop_active=FALSE; }else{ - stop_active=TRUE; - if (all_other_calls_paused(NULL,calls)){ - start_active=TRUE; - add_call=TRUE; - }else if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived && all_other_calls_paused(call,calls)){ - if (call_list_size>1){ - start_active=TRUE; - add_call=TRUE; - }else{ - start_active=TRUE; - add_call=FALSE; - } - }else{ - start_active=FALSE; - } + stop_active=TRUE; + start_active=TRUE; + add_call=TRUE; } button=linphone_gtk_get_widget(mw,"start_call"); gtk_widget_set_sensitive(button,start_active); @@ -708,6 +684,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),stop_active); linphone_gtk_enable_transfer_button(lc,call_list_size>1); + linphone_gtk_enable_conference_button(lc,call_list_size>1); update_video_title(); } @@ -737,7 +714,7 @@ void linphone_gtk_start_call(GtkWidget *w){ GtkWidget *mw=gtk_widget_get_toplevel(w); GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar"); - call=linphone_gtk_get_currently_displayed_call (); + call=linphone_gtk_get_currently_displayed_call(); if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived){ linphone_core_accept_call(lc,call); }else{ @@ -1015,7 +992,7 @@ 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,!all_other_calls_paused (call,linphone_core_get_calls(lc))); + linphone_gtk_in_call_view_set_incoming(call); linphone_gtk_status_icon_set_blinking(TRUE); if (auto_answer) { linphone_call_ref(call); diff --git a/gtk/main.ui b/gtk/main.ui index c86d12fc4..6bd4cf9da 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -148,7 +148,7 @@ - + True False @@ -166,20 +166,19 @@ 0 - - - Merge to conference - True - True - False - - - - True - True - 1 - - + + + False + False + 3 + + + + + True + False + True + center Pause @@ -192,14 +191,14 @@ False False - 2 + 0 False False - 3 + 4 diff --git a/gtk/singleinstance.c b/gtk/singleinstance.c new file mode 100644 index 000000000..d92749e95 --- /dev/null +++ b/gtk/singleinstance.c @@ -0,0 +1,99 @@ +/* +linphone, gtk interface. +Copyright (C) 2011 Belledonne Communications SARL +Author: Simon MORLAT (simon.morlat@linphone.org) + +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. +*/ + +#include "linphone.h" + +static ms_thread_t pipe_thread; +static ortp_pipe_t server_pipe=-1; +static gboolean server_pipe_running=TRUE; +static char *pipe_name; + +static gboolean execute_wakeup(char *uri){ + linphone_gtk_show_main_window(); + if (strlen(uri)>0) + linphone_gtk_refer_received(linphone_gtk_get_core(),uri); + g_free(uri); + return FALSE; +} + +static void * server_pipe_thread(void *pointer){ + ortp_pipe_t child; + + do{ + child=ortp_server_pipe_accept_client(server_pipe); + if (server_pipe_running && child!=-1){ + char buf[256]={0}; + if (ortp_pipe_read(child,(uint8_t*)buf,sizeof(buf))>0){ + g_message("Received wakeup command with arg %s",buf); + gdk_threads_enter(); + g_timeout_add(20,(GSourceFunc)execute_wakeup,g_strdup(buf)); + gdk_threads_leave(); + } + ortp_server_pipe_close_client(child); + } + }while(server_pipe_running); + ortp_server_pipe_close(server_pipe); + return NULL; +} + +static void linphone_gtk_init_pipe(const char *name){ + pipe_name=g_strdup(name); + server_pipe=ortp_server_pipe_create(name); + if (server_pipe==-1){ + g_warning("Fail to create server pipe for name %s: %s",name,strerror(errno)); + } + ms_thread_create(&pipe_thread,NULL,server_pipe_thread,NULL); +} + +bool_t linphone_gtk_init_instance(const char *app_name, const char *addr_to_call){ + ortp_pipe_t p=ortp_client_pipe_connect(app_name); + if (p!=-1){ + uint8_t buf[256]={0}; + g_message("There is already a running instance."); + if (addr_to_call!=NULL){ + strncpy((char*)buf,addr_to_call,sizeof(buf)-1); + } + if (ortp_pipe_write(p,buf,sizeof(buf))==-1){ + g_error("Fail to send wakeup command to running instance: %s",strerror(errno)); + }else{ + g_message("Message to running instance sent."); + } + ortp_client_pipe_close(p); + return FALSE; + }else{ + linphone_gtk_init_pipe(app_name); + } + return TRUE; +} + +void linphone_gtk_uninit_instance(void){ + if (server_pipe!=-1){ + ortp_pipe_t client; + server_pipe_running=FALSE; + /*this is to unblock the accept() of the server pipe*/ + client=ortp_client_pipe_connect(pipe_name); + ortp_pipe_write(client,(uint8_t*)" ",1); + ortp_client_pipe_close(client); + ms_thread_join(pipe_thread,NULL); + server_pipe=-1; + g_free(pipe_name); + pipe_name=NULL; + } +}