Commit 4b178dc8 authored by Simon Morlat's avatar Simon Morlat
Browse files

implement dynamic video add/remove in gtk ui.

parent aba3dac9
...@@ -359,6 +359,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro ...@@ -359,6 +359,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip); linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
linphone_call_init_common(call, from, to); linphone_call_init_common(call, from, to);
linphone_core_init_default_params(lc, &call->params); linphone_core_init_default_params(lc, &call->params);
call->params.has_video &= !!lc->video_policy.automatically_accept;
call->localdesc=create_local_media_description (lc,call); call->localdesc=create_local_media_description (lc,call);
call->camera_active=call->params.has_video; call->camera_active=call->params.has_video;
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun) if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
......
...@@ -756,6 +756,7 @@ static void video_config_read(LinphoneCore *lc){ ...@@ -756,6 +756,7 @@ static void video_config_read(LinphoneCore *lc){
const char **devices; const char **devices;
const MSList *elem; const MSList *elem;
int i; int i;
LinphoneVideoPolicy vpol;
/* retrieve all video devices */ /* retrieve all video devices */
elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get()); elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get());
...@@ -778,12 +779,15 @@ static void video_config_read(LinphoneCore *lc){ ...@@ -778,12 +779,15 @@ static void video_config_read(LinphoneCore *lc){
capture=lp_config_get_int(lc->config,"video","capture",1); capture=lp_config_get_int(lc->config,"video","capture",1);
display=lp_config_get_int(lc->config,"video","display",1); display=lp_config_get_int(lc->config,"video","display",1);
self_view=lp_config_get_int(lc->config,"video","self_view",1); self_view=lp_config_get_int(lc->config,"video","self_view",1);
vpol.automatically_initiate=lp_config_get_int(lc->config,"video","automatically_initiate",1);
vpol.automatically_accept=lp_config_get_int(lc->config,"video","automatically_accept",1);
lc->video_conf.displaytype=lp_config_get_string(lc->config,"video","displaytype",NULL); lc->video_conf.displaytype=lp_config_get_string(lc->config,"video","displaytype",NULL);
if(lc->video_conf.displaytype) if(lc->video_conf.displaytype)
ms_message("we are using a specific display:%s\n",lc->video_conf.displaytype); ms_message("we are using a specific display:%s\n",lc->video_conf.displaytype);
linphone_core_enable_video(lc,capture,display); linphone_core_enable_video(lc,capture,display);
linphone_core_enable_self_view(lc,self_view); linphone_core_enable_self_view(lc,self_view);
linphone_core_set_video_policy(lc,&vpol);
#endif #endif
} }
...@@ -1930,6 +1934,7 @@ const char * linphone_core_get_route(LinphoneCore *lc){ ...@@ -1930,6 +1934,7 @@ const char * linphone_core_get_route(LinphoneCore *lc){
void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call){ void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call){
if (call->refer_pending){ if (call->refer_pending){
LinphoneCallParams *cp=linphone_core_create_default_call_parameters(lc); LinphoneCallParams *cp=linphone_core_create_default_call_parameters(lc);
cp->has_video &= !!lc->video_policy.automatically_initiate;
cp->referer=call; cp->referer=call;
ms_message("Starting new call to refered address %s",call->refer_to); ms_message("Starting new call to refered address %s",call->refer_to);
call->refer_pending=FALSE; call->refer_pending=FALSE;
...@@ -2082,6 +2087,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro ...@@ -2082,6 +2087,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro
LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url){ LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url){
LinphoneCall *call; LinphoneCall *call;
LinphoneCallParams *p=linphone_core_create_default_call_parameters (lc); LinphoneCallParams *p=linphone_core_create_default_call_parameters (lc);
p->has_video &= !!lc->video_policy.automatically_initiate;
call=linphone_core_invite_with_params(lc,url,p); call=linphone_core_invite_with_params(lc,url,p);
linphone_call_params_destroy(p); linphone_call_params_destroy(p);
return call; return call;
...@@ -2128,7 +2134,8 @@ LinphoneCall * linphone_core_invite_with_params(LinphoneCore *lc, const char *ur ...@@ -2128,7 +2134,8 @@ LinphoneCall * linphone_core_invite_with_params(LinphoneCore *lc, const char *ur
**/ **/
LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr){ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr){
LinphoneCall *call; LinphoneCall *call;
LinphoneCallParams *p=linphone_core_create_default_call_parameters (lc); LinphoneCallParams *p=linphone_core_create_default_call_parameters(lc);
p->has_video &= !!lc->video_policy.automatically_initiate;
call=linphone_core_invite_address_with_params (lc,addr,p); call=linphone_core_invite_address_with_params (lc,addr,p);
linphone_call_params_destroy(p); linphone_call_params_destroy(p);
return call; return call;
...@@ -3421,6 +3428,14 @@ void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t di ...@@ -3421,6 +3428,14 @@ void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t di
linphone_core_get_upload_bandwidth(lc)); linphone_core_get_upload_bandwidth(lc));
} }
bool_t linphone_core_video_supported(LinphoneCore *lc){
#ifdef VIDEO_ENABLED
return TRUE;
#else
return FALSE;
#endif
}
/** /**
* Returns TRUE if video is enabled, FALSE otherwise. * Returns TRUE if video is enabled, FALSE otherwise.
* @ingroup media_parameters * @ingroup media_parameters
...@@ -3429,6 +3444,28 @@ bool_t linphone_core_video_enabled(LinphoneCore *lc){ ...@@ -3429,6 +3444,28 @@ bool_t linphone_core_video_enabled(LinphoneCore *lc){
return (lc->video_conf.display || lc->video_conf.capture); return (lc->video_conf.display || lc->video_conf.capture);
} }
/**
* Sets the default policy for video.
* This policy defines whether:
* - video shall be initiated by default for outgoing calls
* - video shall be accepter by default for incoming calls
**/
void linphone_core_set_video_policy(LinphoneCore *lc, const LinphoneVideoPolicy *policy){
lc->video_policy=*policy;
if (linphone_core_ready(lc)){
lp_config_set_int(lc->config,"video","automatically_initiate",policy->automatically_initiate);
lp_config_set_int(lc->config,"video","automatically_accept",policy->automatically_accept);
}
}
/**
* Get the default policy for video.
* See linphone_core_set_video_policy() for more details.
**/
const LinphoneVideoPolicy *linphone_core_get_video_policy(LinphoneCore *lc){
return &lc->video_policy;
}
/** /**
* Controls video preview enablement. * Controls video preview enablement.
* *
......
...@@ -209,6 +209,17 @@ typedef enum _LinphoneReason LinphoneReason; ...@@ -209,6 +209,17 @@ typedef enum _LinphoneReason LinphoneReason;
const char *linphone_reason_to_string(LinphoneReason err); const char *linphone_reason_to_string(LinphoneReason err);
/**
* Structure describing policy regarding video streams establishments.
**/
struct _LinphoneVideoPolicy{
bool_t automatically_initiate; /**<Whether video shall be automatically proposed for outgoing calls.*/
bool_t automatically_accept; /**<Whether video shall be automatically accepted for incoming calls*/
bool_t unused[2];
};
typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy;
/** /**
* The LinphoneCall object represents a call issued or received by the LinphoneCore * The LinphoneCall object represents a call issued or received by the LinphoneCore
**/ **/
...@@ -923,8 +934,11 @@ const MSList * linphone_core_get_call_logs(LinphoneCore *lc); ...@@ -923,8 +934,11 @@ const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
void linphone_core_clear_call_logs(LinphoneCore *lc); void linphone_core_clear_call_logs(LinphoneCore *lc);
/* video support */ /* video support */
bool_t linphone_core_video_supported(LinphoneCore *lc);
void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled); void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled);
bool_t linphone_core_video_enabled(LinphoneCore *lc); bool_t linphone_core_video_enabled(LinphoneCore *lc);
void linphone_core_set_video_policy(LinphoneCore *lc, const LinphoneVideoPolicy *policy);
const LinphoneVideoPolicy *linphone_core_get_video_policy(LinphoneCore *lc);
typedef struct MSVideoSizeDef{ typedef struct MSVideoSizeDef{
MSVideoSize vsize; MSVideoSize vsize;
......
...@@ -466,6 +466,7 @@ struct _LinphoneCore ...@@ -466,6 +466,7 @@ struct _LinphoneCore
MSList *hooks; MSList *hooks;
LinphoneConference conf_ctx; LinphoneConference conf_ctx;
char* zrtp_secrets_cache; char* zrtp_secrets_cache;
LinphoneVideoPolicy video_policy;
bool_t use_files; bool_t use_files;
bool_t apply_nat_settings; bool_t apply_nat_settings;
bool_t initial_subscribes_sent; bool_t initial_subscribes_sent;
......
...@@ -219,6 +219,36 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){ ...@@ -219,6 +219,36 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE); GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE);
} }
static void video_button_clicked(GtkWidget *button, LinphoneCall *call){
gboolean adding=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"adding_video"));
LinphoneCore *lc=linphone_call_get_core(call);
LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call));
gtk_widget_set_sensitive(button,FALSE);
linphone_call_params_enable_video(params,adding);
linphone_core_update_call(lc,call,params);
linphone_call_params_destroy(params);
}
void linphone_gtk_update_video_button(LinphoneCall *call){
GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *button=linphone_gtk_get_widget(call_view,"video_button");
const LinphoneCallParams *params=linphone_call_get_current_params(call);
gboolean has_video=linphone_call_params_video_enabled(params);
gtk_button_set_image(GTK_BUTTON(button),
gtk_image_new_from_stock(has_video ? GTK_STOCK_REMOVE : GTK_STOCK_ADD,GTK_ICON_SIZE_BUTTON));
g_object_set_data(G_OBJECT(button),"adding_video",GINT_TO_POINTER(!has_video));
if (!linphone_core_video_supported(linphone_call_get_core(call))){
gtk_widget_set_sensitive(button,FALSE);
return;
}
if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"signal_connected"))==0){
g_signal_connect(G_OBJECT(button),"clicked",(GCallback)video_button_clicked,call);
g_object_set_data(G_OBJECT(button),"signal_connected",GINT_TO_POINTER(1));
}
gtk_widget_set_sensitive(button,linphone_call_get_state(call)==LinphoneCallStreamsRunning);
}
void linphone_gtk_remove_in_call_view(LinphoneCall *call){ void linphone_gtk_remove_in_call_view(LinphoneCall *call){
GtkWidget *w=(GtkWidget*)linphone_call_get_user_pointer (call); GtkWidget *w=(GtkWidget*)linphone_call_get_user_pointer (call);
GtkWidget *main_window=linphone_gtk_get_main_window (); GtkWidget *main_window=linphone_gtk_get_main_window ();
......
...@@ -114,6 +114,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call); ...@@ -114,6 +114,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call);
void linphone_gtk_unset_from_conference(LinphoneCall *call); void linphone_gtk_unset_from_conference(LinphoneCall *call);
void linphone_gtk_terminate_conference_participant(LinphoneCall *call); void linphone_gtk_terminate_conference_participant(LinphoneCall *call);
void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call); void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call);
void linphone_gtk_update_video_button(LinphoneCall *call);
typedef float (*get_volume_t)(void *data); typedef float (*get_volume_t)(void *data);
void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data); void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data);
......
...@@ -231,6 +231,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, ...@@ -231,6 +231,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL); linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
linphone_core_set_zrtp_secrets_file(the_core,secrets_file); linphone_core_set_zrtp_secrets_file(the_core,secrets_file);
g_free(secrets_file); g_free(secrets_file);
linphone_core_enable_video(the_core,TRUE,TRUE);
} }
...@@ -694,6 +695,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ ...@@ -694,6 +695,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
linphone_gtk_enable_transfer_button(lc,call_list_size>1); linphone_gtk_enable_transfer_button(lc,call_list_size>1);
linphone_gtk_enable_conference_button(lc,call_list_size>1); linphone_gtk_enable_conference_button(lc,call_list_size>1);
update_video_title(); update_video_title();
if (call) linphone_gtk_update_video_button(call);
} }
static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){
...@@ -766,7 +768,11 @@ void linphone_gtk_answer_clicked(GtkWidget *button){ ...@@ -766,7 +768,11 @@ void linphone_gtk_answer_clicked(GtkWidget *button){
void linphone_gtk_enable_video(GtkWidget *w){ void linphone_gtk_enable_video(GtkWidget *w){
gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w));
GtkWidget *selfview_item=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"selfview_item"); GtkWidget *selfview_item=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"selfview_item");
linphone_core_enable_video(linphone_gtk_get_core(),val,val); LinphoneVideoPolicy policy={0};
policy.automatically_initiate=policy.automatically_accept=val;
linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE);
linphone_core_set_video_policy(linphone_gtk_get_core(),&policy);
gtk_widget_set_sensitive(selfview_item,val); gtk_widget_set_sensitive(selfview_item,val);
if (val){ if (val){
linphone_core_enable_video_preview(linphone_gtk_get_core(), linphone_core_enable_video_preview(linphone_gtk_get_core(),
...@@ -1022,6 +1028,52 @@ static void linphone_gtk_notify(LinphoneCall *call, const char *msg){ ...@@ -1022,6 +1028,52 @@ static void linphone_gtk_notify(LinphoneCall *call, const char *msg){
} }
} }
static void on_call_updated_response(GtkWidget *dialog, gint responseid, LinphoneCall *call){
if (linphone_call_get_state(call)==LinphoneCallUpdatedByRemote){
LinphoneCore *lc=linphone_call_get_core(call);
LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call));
linphone_call_params_enable_video(params,responseid==GTK_RESPONSE_YES);
linphone_core_accept_call_update(lc,call,params);
linphone_call_params_destroy(params);
}
linphone_call_unref(call);
g_source_remove_by_user_data(dialog);
gtk_widget_destroy(dialog);
}
static void on_call_updated_timeout(GtkWidget *dialog){
gtk_widget_destroy(dialog);
}
static void linphone_gtk_call_updated_by_remote(LinphoneCall *call){
LinphoneCore *lc=linphone_call_get_core(call);
const LinphoneVideoPolicy *pol=linphone_core_get_video_policy(lc);
const LinphoneCallParams *rparams=linphone_call_get_remote_params(call);
const LinphoneCallParams *current_params=linphone_call_get_current_params(call);
gboolean video_requested=linphone_call_params_video_enabled(rparams);
gboolean video_used=linphone_call_params_video_enabled(current_params);
g_message("Video used=%i, video requested=%i, automatically_accept=%i",
video_used,video_requested,pol->automatically_accept);
if (video_used==FALSE && video_requested && !pol->automatically_accept){
linphone_core_defer_call_update(lc,call);
{
const LinphoneAddress *addr=linphone_call_get_remote_address(call);
GtkWidget *dialog;
const char *dname=linphone_address_get_display_name(addr);
if (dname==NULL) dname=linphone_address_get_username(addr);
if (dname==NULL) dname=linphone_address_get_domain(addr);
dialog=gtk_message_dialog_new(GTK_WINDOW(linphone_gtk_get_main_window()),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_YES_NO,
_("%s proposed to start video. Do you accept ?"),dname);
g_signal_connect(G_OBJECT(dialog),"response",(GCallback)on_call_updated_response,linphone_call_ref(call));
g_timeout_add(20000,(GSourceFunc)on_call_updated_timeout,dialog);
gtk_widget_show(dialog);
}
}
}
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg){ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg){
switch(cs){ switch(cs){
case LinphoneCallOutgoingInit: case LinphoneCallOutgoingInit:
...@@ -1033,6 +1085,9 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call ...@@ -1033,6 +1085,9 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
case LinphoneCallStreamsRunning: case LinphoneCallStreamsRunning:
linphone_gtk_in_call_view_set_in_call(call); linphone_gtk_in_call_view_set_in_call(call);
break; break;
case LinphoneCallUpdatedByRemote:
linphone_gtk_call_updated_by_remote(call);
break;
case LinphoneCallError: case LinphoneCallError:
linphone_gtk_in_call_view_terminate (call,msg); linphone_gtk_in_call_view_terminate (call,msg);
break; break;
...@@ -1345,7 +1400,8 @@ static void linphone_gtk_connect_digits(void){ ...@@ -1345,7 +1400,8 @@ static void linphone_gtk_connect_digits(void){
} }
static void linphone_gtk_check_menu_items(void){ static void linphone_gtk_check_menu_items(void){
bool_t video_enabled=linphone_core_video_enabled(linphone_gtk_get_core()); const LinphoneVideoPolicy *pol=linphone_core_get_video_policy(linphone_gtk_get_core());
bool_t video_enabled=pol->automatically_accept && pol->automatically_initiate;
bool_t selfview=linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT); bool_t selfview=linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT);
GtkWidget *selfview_item=linphone_gtk_get_widget( GtkWidget *selfview_item=linphone_gtk_get_widget(
linphone_gtk_get_main_window(),"selfview_item"); linphone_gtk_get_main_window(),"selfview_item");
...@@ -1491,13 +1547,13 @@ gboolean linphone_gtk_close(GtkWidget *mw){ ...@@ -1491,13 +1547,13 @@ gboolean linphone_gtk_close(GtkWidget *mw){
#ifdef HAVE_GTK_OSX #ifdef HAVE_GTK_OSX
static gboolean on_window_state_event(GtkWidget *w, GdkEventWindowState *event){ static gboolean on_window_state_event(GtkWidget *w, GdkEventWindowState *event){
if ((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ||(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ){ if ((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ||(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ){
linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE); linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
}else{ }else{
linphone_core_enable_video_preview(linphone_gtk_get_core(), linphone_core_enable_video_preview(linphone_gtk_get_core(),
linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT) && linphone_core_video_enabled(linphone_gtk_get_core())); linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT) && linphone_core_video_enabled(linphone_gtk_get_core()));
} }
return FALSE; return FALSE;
} }
#endif #endif
......
...@@ -293,7 +293,7 @@ ...@@ -293,7 +293,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="homogeneous">True</property> <property name="homogeneous">True</property>
<property name="layout_style">center</property> <property name="layout_style">spread</property>
<child> <child>
<object class="GtkButton" id="hold_call"> <object class="GtkButton" id="hold_call">
<property name="label" translatable="yes">Pause</property> <property name="label" translatable="yes">Pause</property>
...@@ -308,6 +308,20 @@ ...@@ -308,6 +308,20 @@
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton" id="video_button">
<property name="label" translatable="yes">Video</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
......
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