]> sjero.net Git - linphone/commitdiff
implement hotpluging of usb devices for linux, and update ortp
authorSimon Morlat <simon.morlat@linphone.org>
Mon, 12 Mar 2012 15:21:39 +0000 (16:21 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Mon, 12 Mar 2012 15:21:39 +0000 (16:21 +0100)
configure.ac
coreapi/linphonecore.c
coreapi/linphonecore.h
gtk/linphone.h
gtk/main.c
gtk/parameters.ui
gtk/propertybox.c
gtk/utils.c
oRTP

index 023236f8352d00825b2111d9bbc1fecc7fdd99ec..ce360445100e6653a255d51eb880cf4b7e368728 100644 (file)
@@ -442,6 +442,9 @@ if test "$build_wizard" = "true" ; then
    AC_DEFINE( BUILD_WIZARD, 1, [Define if wizard enabled] ) 
 fi
 
+AC_CHECK_HEADERS(libudev.h)
+AC_CHECK_LIB(udev,udev_new)
+
 ##################################################
 # Stricter build options (after external packages)
 ##################################################
index e7d778b604a061511c9a6612b9dced0175fa5a73..938c35bafb8a1ec503cf9fce0f5cb47bb93ae9c6 100644 (file)
@@ -748,17 +748,13 @@ static void codecs_config_read(LinphoneCore *lc)
        linphone_core_update_allocated_audio_bandwidth(lc);
 }
 
-static void video_config_read(LinphoneCore *lc){
-#ifdef VIDEO_ENABLED
-       int capture, display, self_view;
-#endif
-       const char *str;
-       int ndev;
-       const char **devices;
+static void build_video_devices_table(LinphoneCore *lc){
        const MSList *elem;
        int i;
-       LinphoneVideoPolicy vpol;
-
+       int ndev;
+       const char **devices;
+       if (lc->video_conf.cams)
+               ms_free(lc->video_conf.cams);
        /* retrieve all video devices */
        elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get());
        ndev=ms_list_size(elem);
@@ -768,6 +764,16 @@ static void video_config_read(LinphoneCore *lc){
        }
        devices[ndev]=NULL;
        lc->video_conf.cams=devices;
+}
+
+static void video_config_read(LinphoneCore *lc){
+#ifdef VIDEO_ENABLED
+       int capture, display, self_view;
+#endif
+       const char *str;        
+       LinphoneVideoPolicy vpol;
+
+       build_video_devices_table(lc);
 
        str=lp_config_get_string(lc->config,"video","device",NULL);
        if (str && str[0]==0) str=NULL;
@@ -3049,7 +3055,6 @@ const char * linphone_core_get_capture_device(LinphoneCore *lc)
  * @param lc The LinphoneCore object
 **/
 const char**  linphone_core_get_sound_devices(LinphoneCore *lc){
-       build_sound_devices_table(lc);
        return lc->sound_conf.cards;
 }
 
@@ -3063,6 +3068,38 @@ const char**  linphone_core_get_video_devices(const LinphoneCore *lc){
        return lc->video_conf.cams;
 }
 
+/**
+ * Update detection of sound devices.
+ * 
+ * Use this function when the application is notified of USB plug events, so that
+ * list of available hardwares for sound playback and capture is updated.
+ **/
+void linphone_core_reload_sound_devices(LinphoneCore *lc){
+       const char *ringer,*playback,*capture;
+       ringer=linphone_core_get_ringer_device(lc);
+       playback=linphone_core_get_playback_device(lc);
+       capture=linphone_core_get_capture_device(lc);
+       ms_snd_card_manager_reload(ms_snd_card_manager_get());
+       build_sound_devices_table(lc);
+       linphone_core_set_ringer_device(lc,ringer);
+       linphone_core_set_playback_device(lc,playback);
+       linphone_core_set_capture_device(lc,capture);
+}
+
+/**
+ * Update detection of camera devices.
+ * 
+ * Use this function when the application is notified of USB plug events, so that
+ * list of available hardwares for video capture is updated.
+ **/
+void linphone_core_reload_video_devices(LinphoneCore *lc){
+       const char *devid;
+       devid=linphone_core_get_video_device(lc);
+       ms_web_cam_manager_reload(ms_web_cam_manager_get());
+       build_video_devices_table(lc);
+       linphone_core_set_video_device(lc,devid);
+}
+
 char linphone_core_get_sound_source(LinphoneCore *lc)
 {
        return lc->sound_conf.source;
index 2c0aa16653b3bc21482c9c624715879036b7f785..bb4a84b0ba6981490d65bbad5d28955cd85f341b 100644 (file)
@@ -874,6 +874,7 @@ int linphone_core_set_relay_addr(LinphoneCore *lc, const char *addr);
 /* sound functions */
 /* returns a null terminated static array of string describing the sound devices */
 const char**  linphone_core_get_sound_devices(LinphoneCore *lc);
+void linphone_core_reload_sound_devices(LinphoneCore *lc);
 bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *device);
 bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *device);
 int linphone_core_get_ring_level(LinphoneCore *lc);
@@ -958,6 +959,7 @@ bool_t linphone_core_self_view_enabled(const LinphoneCore *lc);
 
 
 /* returns a null terminated static array of string describing the webcams */
+void linphone_core_reload_video_devices(LinphoneCore *lc);
 const char**  linphone_core_get_video_devices(const LinphoneCore *lc);
 int linphone_core_set_video_device(LinphoneCore *lc, const char *id);
 const char *linphone_core_get_video_device(const LinphoneCore *lc);
index 03410b1a5612560496acce473bdf8b5788c6b45a..7074bc87d551cde92d81edb6da1c142adbef0879 100644 (file)
@@ -67,6 +67,8 @@ void linphone_gtk_show_friends(void);
 void linphone_gtk_show_contact(LinphoneFriend *lf);
 void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss);
 void linphone_gtk_show_parameters(void);
+void linphone_gtk_fill_soundcards(GtkWidget *pb);
+void linphone_gtk_fill_webcams(GtkWidget *pb);
 void linphone_gtk_load_identities(void);
 void linphone_gtk_create_chatroom(const char *with);
 void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
@@ -126,3 +128,6 @@ void linphone_gtk_log_uninit();
 
 bool_t linphone_gtk_init_instance(const char *app_name, const char *addr_to_call);
 void linphone_gtk_uninit_instance(void);
+void linphone_gtk_monitor_usb(void);
+void linphone_gtk_unmonitor_usb(void);
+
index b986b4eba5485898852c6d5b8ccacce92967828e..60c4556d7eff165493495371de577c1a613524f3 100644 (file)
@@ -1666,6 +1666,7 @@ static void linphone_gtk_quit(void){
        static gboolean quit_done=FALSE;
        if (!quit_done){
                quit_done=TRUE;
+               linphone_gtk_unmonitor_usb();
                g_source_remove_by_user_data(linphone_gtk_get_core());
                linphone_gtk_uninit_instance();
                linphone_gtk_destroy_log_window();
@@ -1824,6 +1825,7 @@ int main(int argc, char *argv[]){
        }
        if (linphone_gtk_get_ui_config_int("update_check_menu",0)==0)
                linphone_gtk_check_for_new_version();
+       linphone_gtk_monitor_usb();
 
        gtk_main();
        linphone_gtk_quit();
index b5b0b8c6fd3ecc067ba1ee01fc6c8c3fe45f802a..b8f4adbdc4e2066f06ba77a57ff7e806e5701f39 100644 (file)
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
     <property name="title" translatable="yes">Settings</property>
     <property name="icon">linphone2.png</property>
+    <signal name="destroy" handler="linphone_gtk_parameters_destroyed" swapped="no"/>
     <child>
       <object class="GtkVBox" id="vbox1">
         <property name="visible">True</property>
index f8187860d289191f100c8f3d6a55d0cfba916f33..5af25a5c4b2e06ec253b0d4173588678262dc201 100644 (file)
@@ -870,18 +870,49 @@ static void linphone_gtk_show_media_encryption(GtkWidget *pb){
        g_object_unref(G_OBJECT(model));
 }
 
-void linphone_gtk_show_parameters(void){
-       GtkWidget *pb=linphone_gtk_create_window("parameters");
+void linphone_gtk_parameters_destroyed(GtkWidget *pb){
+       GtkWidget *mw=linphone_gtk_get_main_window();
+       g_object_set_data(G_OBJECT(mw),"parameters",NULL);
+}
+
+void linphone_gtk_fill_soundcards(GtkWidget *pb){
        LinphoneCore *lc=linphone_gtk_get_core();
        const char **sound_devices=linphone_core_get_sound_devices(lc);
+       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"playback_device"), sound_devices,
+                                       linphone_core_get_playback_device(lc),CAP_PLAYBACK);
+       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"ring_device"), sound_devices,
+                                       linphone_core_get_ringer_device(lc),CAP_PLAYBACK);
+       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"capture_device"), sound_devices,
+                                       linphone_core_get_capture_device(lc), CAP_CAPTURE);
+}
+
+void linphone_gtk_fill_webcams(GtkWidget *pb){
+       LinphoneCore *lc=linphone_gtk_get_core();
+       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc),
+                                       linphone_core_get_video_device(lc),CAP_IGNORE);
+}
+
+void linphone_gtk_show_parameters(void){
+       GtkWidget *mw=linphone_gtk_get_main_window();
+       GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters");
+       LinphoneCore *lc=linphone_gtk_get_core();
        const char *tmp;
        LinphoneAddress *contact;
        LinphoneFirewallPolicy pol;
-       GtkWidget *codec_list=linphone_gtk_get_widget(pb,"codec_list");
+       GtkWidget *codec_list;
        int mtu;
        int ui_advanced;
        LCSipTransports tr;
 
+       if (pb==NULL) {
+               pb=linphone_gtk_create_window("parameters");
+               g_object_set_data(G_OBJECT(mw),"parameters",pb);
+       }else {
+               gtk_widget_show(pb);
+               return;
+       }
+       codec_list=linphone_gtk_get_widget(pb,"codec_list");
+
        /* NETWORK CONFIG */
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")),
                                linphone_core_ipv6_enabled(lc));
@@ -939,14 +970,9 @@ void linphone_gtk_show_parameters(void){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"dtmf_sipinfo")),
                                        linphone_core_get_use_info_for_dtmf(lc));
        /* MUTIMEDIA CONFIG */
-       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"playback_device"), sound_devices,
-                                       linphone_core_get_playback_device(lc),CAP_PLAYBACK);
-       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"ring_device"), sound_devices,
-                                       linphone_core_get_ringer_device(lc),CAP_PLAYBACK);
-       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"capture_device"), sound_devices,
-                                       linphone_core_get_capture_device(lc), CAP_CAPTURE);
-       linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc),
-                                       linphone_core_get_video_device(lc),CAP_IGNORE);
+       linphone_gtk_fill_soundcards(pb);
+       linphone_gtk_fill_webcams(pb);
+
        linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size"));
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")),
                                        linphone_core_echo_cancellation_enabled(lc));
index 69ae435a12e21e3d73cb68bd4e79e915e7d387d3..b8db633d842c79b5ecd3aa27dd67859359259d84 100644 (file)
@@ -97,3 +97,70 @@ GtkWidget * _gtk_image_new_from_memory_at_scale(const void *data, gint len, gint
        g_object_unref(G_OBJECT(pbuf));
        return image;
 }
+
+void linphone_gtk_reload_sound_devices(void){
+       GtkWidget *mw=linphone_gtk_get_main_window();
+       GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters");
+       linphone_core_reload_sound_devices(linphone_gtk_get_core());
+       linphone_gtk_fill_soundcards(pb);
+}
+
+void linphone_gtk_reload_video_devices(void){
+       GtkWidget *mw=linphone_gtk_get_main_window();
+       GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters");
+       linphone_core_reload_video_devices(linphone_gtk_get_core());
+       linphone_gtk_fill_webcams(pb);
+}
+
+#ifdef HAVE_LIBUDEV_H
+
+static struct udev *udevroot=NULL;
+static struct udev_monitor *monitor=NULL;
+static GIOChannel *monitor_channel=NULL;
+static guint monitor_src_id;
+
+#include <libudev.h>
+
+static gboolean on_monitor_data(GIOChannel *chan, GIOCondition cond, void *userdata){
+       struct udev_device *dev=udev_monitor_receive_device(monitor);
+       const char *subsys=udev_device_get_subsystem(dev);
+       const char *type=udev_device_get_action(dev);
+       g_message("USB event arrived for class %s of action type %s",subsys,type);
+       if (strcmp(subsys,"sound")==0) linphone_gtk_reload_sound_devices();
+       if (strcmp(subsys,"video4linux")==0) linphone_gtk_reload_video_devices();
+       udev_device_unref(dev);
+       return TRUE;
+}
+
+void linphone_gtk_monitor_usb(void){
+       int fd;
+       udevroot=udev_new();
+       if (!udevroot) return;
+       monitor=udev_monitor_new_from_netlink(udevroot,"udev");
+       udev_monitor_filter_add_match_subsystem_devtype(monitor,"sound",NULL);
+       udev_monitor_filter_add_match_subsystem_devtype(monitor,"video4linux",NULL);
+       fd=udev_monitor_get_fd(monitor);
+       monitor_channel=g_io_channel_unix_new(fd);
+       monitor_src_id=g_io_add_watch(monitor_channel,G_IO_IN,on_monitor_data,NULL);
+       udev_monitor_enable_receiving(monitor);
+}
+
+void linphone_gtk_unmonitor_usb(void){
+       if (monitor) udev_monitor_unref(monitor);
+       if (udevroot) udev_unref(udevroot);
+       if (monitor_channel) {
+               g_source_remove(monitor_src_id);
+               g_io_channel_unref(monitor_channel);
+       }
+}
+
+#else
+
+void linphone_gtk_monitor_usb(void){
+}
+void linphone_gtk_unmonitor_usb(void){
+}
+
+#endif
+
+
diff --git a/oRTP b/oRTP
index 97acf505e76962fe8efa586335fd5c042c2b44fe..3fb614e2ed15803f2c96c223cceb5545a60f2431 160000 (submodule)
--- a/oRTP
+++ b/oRTP
@@ -1 +1 @@
-Subproject commit 97acf505e76962fe8efa586335fd5c042c2b44fe
+Subproject commit 3fb614e2ed15803f2c96c223cceb5545a60f2431