]> sjero.net Git - linphone/commitdiff
implement dynamic video add/remove in gtk ui.
authorSimon Morlat <simon.morlat@linphone.org>
Wed, 22 Feb 2012 17:28:21 +0000 (18:28 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Wed, 22 Feb 2012 17:29:55 +0000 (18:29 +0100)
coreapi/linphonecall.c
coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/private.h
gtk/incall_view.c
gtk/linphone.h
gtk/main.c
gtk/main.ui

index 888c76593928dbbaa79e27b0a9897f64278656e3..a384a9299afaca25e58d0df300663983d40ec26b 100644 (file)
@@ -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)
index 68cea9b33a77244de94b8829dc8936774f30674a..dd41305b4094866c90cc9aca65b36d2de4b7549c 100644 (file)
@@ -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.
  *
index 4a6fed8b3576243acc0461e7fd624292e188f8e5..e2c46bf7bf28b57279f1ae42a1b12624b3290b51 100644 (file)
@@ -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;
index ccb1b1b76ad04737242cd8d382eb37725471ee51..10876734beb25db2418874bada0a7e3e8fddd02f 100644 (file)
@@ -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;
index 5674d5544b12f0ca247aaa170ad993de2bca1f2b..6ac443e984c3821c12fdf8a97285be38f009414e 100644 (file)
@@ -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 ();
index 45c8b54aacfa4b42c3adc1a18d69a7ffe1561a35..03410b1a5612560496acce473bdf8b5788c6b45a 100644 (file)
@@ -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);
 
index 7079bc89fea5d0dfe0682110d40125f1947b8768..f7ea40ec1bd89a4c4bbeddc2e2db7bea366af044 100644 (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_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
 
index d4c061a452d49ea63600877487c0a6cb83e139b0..96647fe4d5e83f15335991284786894ad689624c 100644 (file)
                     <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>
                         <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>