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

implement dynamic video add/remove in gtk ui.

parent aba3dac9
......@@ -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_call_init_common(call, from, to);
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->camera_active=call->params.has_video;
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
......
......@@ -756,6 +756,7 @@ static void video_config_read(LinphoneCore *lc){
const char **devices;
const MSList *elem;
int i;
LinphoneVideoPolicy vpol;
/* retrieve all video devices */
elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get());
......@@ -778,12 +779,15 @@ static void video_config_read(LinphoneCore *lc){
capture=lp_config_get_int(lc->config,"video","capture",1);
display=lp_config_get_int(lc->config,"video","display",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);
if(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_self_view(lc,self_view);
linphone_core_set_video_policy(lc,&vpol);
#endif
}
......@@ -1930,6 +1934,7 @@ const char * linphone_core_get_route(LinphoneCore *lc){
void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call){
if (call->refer_pending){
LinphoneCallParams *cp=linphone_core_create_default_call_parameters(lc);
cp->has_video &= !!lc->video_policy.automatically_initiate;
cp->referer=call;
ms_message("Starting new call to refered address %s",call->refer_to);
call->refer_pending=FALSE;
......@@ -2082,6 +2087,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro
LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url){
LinphoneCall *call;
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);
linphone_call_params_destroy(p);
return call;
......@@ -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 *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);
linphone_call_params_destroy(p);
return call;
......@@ -3421,6 +3428,14 @@ void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t di
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.
* @ingroup media_parameters
......@@ -3429,6 +3444,28 @@ bool_t linphone_core_video_enabled(LinphoneCore *lc){
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.
*
......
......@@ -209,6 +209,17 @@ typedef enum _LinphoneReason LinphoneReason;
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
**/
......@@ -923,8 +934,11 @@ const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
void linphone_core_clear_call_logs(LinphoneCore *lc);
/* 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);
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{
MSVideoSize vsize;
......
......@@ -466,6 +466,7 @@ struct _LinphoneCore
MSList *hooks;
LinphoneConference conf_ctx;
char* zrtp_secrets_cache;
LinphoneVideoPolicy video_policy;
bool_t use_files;
bool_t apply_nat_settings;
bool_t initial_subscribes_sent;
......
......@@ -219,6 +219,36 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
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){
GtkWidget *w=(GtkWidget*)linphone_call_get_user_pointer (call);
GtkWidget *main_window=linphone_gtk_get_main_window ();
......
......@@ -114,6 +114,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call);
void linphone_gtk_unset_from_conference(LinphoneCall *call);
void linphone_gtk_terminate_conference_participant(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);
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,
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
linphone_core_set_zrtp_secrets_file(the_core,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){
linphone_gtk_enable_transfer_button(lc,call_list_size>1);
linphone_gtk_enable_conference_button(lc,call_list_size>1);
update_video_title();
if (call) linphone_gtk_update_video_button(call);
}
static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){
......@@ -766,7 +768,11 @@ void linphone_gtk_answer_clicked(GtkWidget *button){
void linphone_gtk_enable_video(GtkWidget *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");
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);
if (val){
linphone_core_enable_video_preview(linphone_gtk_get_core(),
......@@ -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){
switch(cs){
case LinphoneCallOutgoingInit:
......@@ -1033,6 +1085,9 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
case LinphoneCallStreamsRunning:
linphone_gtk_in_call_view_set_in_call(call);
break;
case LinphoneCallUpdatedByRemote:
linphone_gtk_call_updated_by_remote(call);
break;
case LinphoneCallError:
linphone_gtk_in_call_view_terminate (call,msg);
break;
......@@ -1345,7 +1400,8 @@ static void linphone_gtk_connect_digits(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);
GtkWidget *selfview_item=linphone_gtk_get_widget(
linphone_gtk_get_main_window(),"selfview_item");
......@@ -1491,13 +1547,13 @@ gboolean linphone_gtk_close(GtkWidget *mw){
#ifdef HAVE_GTK_OSX
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) ){
linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
}else{
linphone_core_enable_video_preview(linphone_gtk_get_core(),
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);
}else{
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()));
}
return FALSE;
}
return FALSE;
}
#endif
......
......@@ -293,7 +293,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
<property name="layout_style">center</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkButton" id="hold_call">
<property name="label" translatable="yes">Pause</property>
......@@ -308,6 +308,20 @@
<property name="position">0</property>
</packing>
</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>
<packing>
<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