diff --git a/README.mingw b/README.mingw index 57c0851c4..5e859680b 100644 --- a/README.mingw +++ b/README.mingw @@ -60,6 +60,8 @@ General rules for compilation - all other commands (configure, autogen.sh, make) must be done within the mingw shell (msys). In both msys and msys-git windows, change into the directory you created for sources: cd /c/sources +- make sure pkg-config works by adding this env variable to your terminal: + export PKG_CONFIG_PATH=/usr/lib/pkgconfig Building belle-sip ****************** diff --git a/configure.ac b/configure.ac index f584f5b9a..e7caf35b9 100644 --- a/configure.ac +++ b/configure.ac @@ -898,8 +898,8 @@ dnl ################################################## dnl # Check for doxygen dnl ################################################## -AC_PATH_PROG(DOXYGEN,doxygen,false) -AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false) +AC_CHECK_PROG(DOXYGEN,doxygen,doxygen,false) +AM_CONDITIONAL(HAVE_DOXYGEN, test "$DOXYGEN" != "false") AC_CONFIG_FILES([ diff --git a/console/linphonec.c b/console/linphonec.c index efa8ceab4..439702b85 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -500,7 +500,6 @@ static void *pipe_thread(void*p){ } static void start_pipe_reader(void){ - ms_mutex_init(&prompt_mutex,NULL); pipe_reader_run=TRUE; ortp_thread_create(&pipe_reader_th,NULL,pipe_thread,NULL); } diff --git a/gtk/incall_view.c b/gtk/incall_view.c index a9ef8e272..c21503d35 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -29,6 +29,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" +#ifdef __linux +#include +#elif defined(WIN32) +#include +#elif defined(__APPLE__) +extern void *gdk_quartz_window_get_nswindow(GdkWindow *window); +extern void *gdk_quartz_window_get_nsview(GdkWindow *window); +#endif + +#include + +static void set_video_controls_position(GtkWidget *video_window); gboolean linphone_gtk_use_in_call_view(){ static int val=-1; @@ -403,7 +415,7 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){ gtk_widget_hide(conf); button=linphone_gtk_get_widget(call_view,"terminate_call"); - image=create_pixmap("stopcall-small.png"); + image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png")); gtk_button_set_label(GTK_BUTTON(button),_("Hang up")); gtk_button_set_image(GTK_BUTTON(button),image); gtk_widget_show(image); @@ -687,6 +699,215 @@ void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){ } } +char *linphone_gtk_address(const LinphoneAddress *addr){ + const char *displayname=linphone_address_get_display_name(addr); + if (!displayname) return linphone_address_as_string_uri_only(addr); + return ms_strdup(displayname); +} + +unsigned long get_native_handle(GdkWindow *gdkw){ +#ifdef __linux + return (unsigned long)GDK_WINDOW_XID(gdkw); +#elif defined(WIN32) + return (unsigned long)GDK_WINDOW_HWND(gdkw); +#elif defined(__APPLE__) + return (unsigned long)gdk_quartz_window_get_nsview(gdkw); +#endif + g_warning("No way to get the native handle from gdk window"); + return 0; +} + +static gint resize_video_window(LinphoneCall *call){ + const LinphoneCallParams *params=linphone_call_get_current_params(call); + if (params){ + MSVideoSize vsize=linphone_call_params_get_received_video_size(params); + if (vsize.width>0 && vsize.height>0){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window"); + gint curw,curh; + if (video_window){ + gtk_window_get_size(GTK_WINDOW(video_window),&curw,&curh); + if (vsize.width*vsize.height>curw*curh){ + gtk_window_resize(GTK_WINDOW(video_window),vsize.width,vsize.height); + } + } + } + } + return TRUE; +} + +static void on_video_window_destroy(GtkWidget *w, guint timeout){ + g_source_remove(timeout); + linphone_core_set_native_video_window_id(linphone_gtk_get_core(),(unsigned long)-1); +} + +static void video_window_set_fullscreen(GtkWidget *w, gboolean val){ + if (val){ + g_object_set_data(G_OBJECT(w),"fullscreen",GINT_TO_POINTER(1)); + gtk_window_fullscreen(GTK_WINDOW(w)); + }else{ + g_object_set_data(G_OBJECT(w),"fullscreen",GINT_TO_POINTER(0)); + gtk_window_unfullscreen(GTK_WINDOW(w)); + } +} + +static void on_video_window_key_press(GtkWidget *w, GdkEvent *ev, gpointer up){ + g_message("Key press event"); + switch(ev->key.keyval){ + case GDK_KEY_f: + case GDK_KEY_F: + video_window_set_fullscreen(w,TRUE); + break; + case GDK_KEY_Escape: + video_window_set_fullscreen(w,FALSE); + break; + } +} + +static void on_controls_response(GtkWidget *dialog, int response_id, GtkWidget *video_window){ + + gtk_widget_destroy(dialog); + switch(response_id){ + case GTK_RESPONSE_YES: + video_window_set_fullscreen(video_window,TRUE); + break; + case GTK_RESPONSE_NO: + video_window_set_fullscreen(video_window,FALSE); + break; + case GTK_RESPONSE_REJECT: + { + LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(video_window),"call"); + linphone_core_terminate_call(linphone_gtk_get_core(),call); + } + break; + } + +} + +static void on_controls_destroy(GtkWidget *w){ + GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(w),"video_window"); + gint timeout=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"timeout")); + if (timeout!=0){ + g_source_remove(timeout); + g_object_set_data(G_OBJECT(w),"timeout",GINT_TO_POINTER(0)); + } + g_object_set_data(G_OBJECT(video_window),"controls",NULL); +} + +static gboolean _set_video_controls_position(GtkWidget *video_window){ + GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(video_window),"controls"); + if (w){ + gint vw,vh; + gint cw,ch; + gint x,y; + gtk_window_get_size(GTK_WINDOW(video_window),&vw,&vh); + gtk_window_get_position(GTK_WINDOW(video_window),&x,&y); + gtk_window_get_size(GTK_WINDOW(w),&cw,&ch); + gtk_window_move(GTK_WINDOW(w),x+vw/2 - cw/2, y + vh - ch); + } + return FALSE; +} + +static void set_video_controls_position(GtkWidget *video_window){ + /*do it a first time*/ + _set_video_controls_position(video_window); + /*and schedule to do it a second time in order to workaround a bug in fullscreen mode, where poistion is not taken into account the first time*/ + g_timeout_add(0,(GSourceFunc)_set_video_controls_position,video_window); +} + +static gboolean video_window_moved(GtkWidget *widget, GdkEvent *event, gpointer user_data){ + set_video_controls_position(widget); + return TRUE; +} + +static GtkWidget *show_video_controls(GtkWidget *video_window){ + GtkWidget *w; + w=(GtkWidget*)g_object_get_data(G_OBJECT(video_window),"controls"); + if (!w){ + gboolean isfullscreen=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(video_window),"fullscreen")); + const char *stock_button=isfullscreen ? GTK_STOCK_LEAVE_FULLSCREEN : GTK_STOCK_FULLSCREEN; + gint response_id=isfullscreen ? GTK_RESPONSE_NO : GTK_RESPONSE_YES ; + gint timeout; + GtkWidget *button; + w=gtk_dialog_new_with_buttons("",GTK_WINDOW(video_window),GTK_DIALOG_DESTROY_WITH_PARENT,stock_button,response_id,NULL); + gtk_window_set_opacity(GTK_WINDOW(w),0.5); + gtk_window_set_decorated(GTK_WINDOW(w),FALSE); + button=gtk_button_new_with_label(_("Hang up")); + gtk_button_set_image(GTK_BUTTON(button),create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png"))); + gtk_widget_show(button); + gtk_dialog_add_action_widget(GTK_DIALOG(w),button,GTK_RESPONSE_REJECT); + g_signal_connect(w,"response",(GCallback)on_controls_response,video_window); + timeout=g_timeout_add(3000,(GSourceFunc)gtk_widget_destroy,w); + g_object_set_data(G_OBJECT(w),"timeout",GINT_TO_POINTER(timeout)); + g_signal_connect(w,"destroy",(GCallback)on_controls_destroy,NULL); + g_object_set_data(G_OBJECT(w),"video_window",video_window); + g_object_set_data(G_OBJECT(video_window),"controls",w); + set_video_controls_position(video_window); + gtk_widget_show(w); + }else{ + gint timeout=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"timeout")); + g_source_remove(timeout); + timeout=g_timeout_add(3000,(GSourceFunc)gtk_widget_destroy,w); + g_object_set_data(G_OBJECT(w),"timeout",GINT_TO_POINTER(timeout)); + } + return w; +} + +GtkWidget *create_video_window(LinphoneCall *call){ + char *remote,*title; + GtkWidget *video_window; + const LinphoneAddress *addr; + const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON); + GdkPixbuf *pbuf=create_pixbuf(icon_path); + guint timeout; + MSVideoSize vsize=MS_VIDEO_SIZE_CIF; + GdkColor color; + + addr=linphone_call_get_remote_address(call); + remote=linphone_gtk_address(addr); + video_window=gtk_window_new(GTK_WINDOW_TOPLEVEL); + title=g_strdup_printf("%s - Video call with %s",linphone_gtk_get_ui_config("title","Linphone"),remote); + ms_free(remote); + gtk_window_set_title(GTK_WINDOW(video_window),title); + g_free(title); + if (pbuf){ + gtk_window_set_icon(GTK_WINDOW(video_window),pbuf); + } + gtk_window_resize(GTK_WINDOW(video_window),vsize.width,vsize.height); + gdk_color_parse("black",&color); + gtk_widget_modify_bg(video_window,GTK_STATE_NORMAL,&color); + gtk_widget_show(video_window); + gdk_window_set_events(gtk_widget_get_window(video_window), + gdk_window_get_events(gtk_widget_get_window(video_window)) | GDK_POINTER_MOTION_MASK); + timeout=g_timeout_add(500,(GSourceFunc)resize_video_window,call); + g_signal_connect(video_window,"destroy",(GCallback)on_video_window_destroy,GINT_TO_POINTER(timeout)); + g_signal_connect(video_window,"key-press-event",(GCallback)on_video_window_key_press,NULL); + g_signal_connect_swapped(video_window,"motion-notify-event",(GCallback)show_video_controls,video_window); + g_signal_connect(video_window,"configure-event",(GCallback)video_window_moved,NULL); + g_object_set_data(G_OBJECT(video_window),"call",call); + return video_window; +} + +void linphone_gtk_in_call_show_video(LinphoneCall *call){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window"); + const LinphoneCallParams *params=linphone_call_get_current_params(call); + LinphoneCore *lc=linphone_gtk_get_core(); + + if (linphone_call_get_state(call)!=LinphoneCallPaused && params && linphone_call_params_video_enabled(params)){ + if (video_window==NULL){ + video_window=create_video_window(call); + g_object_set_data(G_OBJECT(callview),"video_window",video_window); + } + linphone_core_set_native_video_window_id(lc,get_native_handle(gtk_widget_get_window(video_window))); + }else{ + if (video_window){ + gtk_widget_destroy(video_window); + g_object_set_data(G_OBJECT(callview),"video_window",NULL); + } + } +} + void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); @@ -696,6 +917,8 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ gboolean in_conf=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call)); GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"call_stats"); + linphone_gtk_in_call_show_video(call); + display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); @@ -736,7 +959,7 @@ void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){ GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); gtk_label_set_markup(GTK_LABEL(status),_("Paused call")); - + linphone_gtk_in_call_show_video(call); linphone_gtk_in_call_set_animation_image(callview,GTK_STOCK_MEDIA_PAUSE,TRUE); } @@ -760,13 +983,15 @@ static gboolean in_call_view_terminated(LinphoneCall *call){ void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *status; + GtkWidget *video_window; gboolean in_conf; guint taskid; if(callview==NULL) return; + video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window"); status=linphone_gtk_get_widget(callview,"in_call_status"); taskid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(callview),"taskid")); in_conf=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call)); - + gtk_widget_destroy(video_window); if (status==NULL) return; if (error_msg==NULL) gtk_label_set_markup(GTK_LABEL(status),_("Call ended.")); diff --git a/gtk/linphone.h b/gtk/linphone.h index 2a256cab5..22e2cb336 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -48,6 +48,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define LINPHONE_VERSION LINPHONE_VERSION_DATE #endif +#define LINPHONE_ICON "linphone.png" + enum { COMPLETION_HISTORY, COMPLETION_LDAP diff --git a/gtk/main.c b/gtk/main.c index 66cb27035..60c27e43b 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -48,7 +48,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef ENABLE_NLS #include #endif -#define LINPHONE_ICON "linphone.png" + const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION; @@ -318,6 +318,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, g_free(secrets_file); linphone_core_enable_video_capture(the_core, TRUE); linphone_core_enable_video_display(the_core, TRUE); + linphone_core_set_native_video_window_id(the_core,-1);/*don't create the window*/ if (no_video) { _linphone_gtk_enable_video(FALSE); linphone_gtk_set_ui_config_int("videoselfview",0); @@ -566,102 +567,6 @@ void linphone_gtk_show_about(){ gtk_widget_show(about); } -static void set_video_window_decorations(GdkWindow *w){ - const char *title=linphone_gtk_get_ui_config("title","Linphone"); - const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON); - char video_title[256]; - GdkPixbuf *pbuf=create_pixbuf(icon_path); - - if (!linphone_core_in_call(linphone_gtk_get_core())){ - snprintf(video_title,sizeof(video_title),"%s video",title); - /* When not in call, treat the video as a normal window */ - gdk_window_set_keep_above(w, FALSE); - }else{ - LinphoneAddress *uri = - linphone_address_clone(linphone_core_get_current_call_remote_address(linphone_gtk_get_core())); - char *display_name; - - linphone_address_clean(uri); - if (linphone_address_get_display_name(uri)!=NULL){ - display_name=ms_strdup(linphone_address_get_display_name(uri)); - }else{ - display_name=linphone_address_as_string(uri); - } - snprintf(video_title,sizeof(video_title),_("Call with %s"),display_name); - linphone_address_destroy(uri); - ms_free(display_name); - - /* During calls, bring up the video window, arrange so that - it is above all the other windows */ - gdk_window_deiconify(w); - gdk_window_set_keep_above(w,TRUE); - /* Maybe we should have the following, but then we want to - have a timer that turns it off after a little while. */ - /* gdk_window_set_urgency_hint(w,TRUE); */ - } - gdk_window_set_title(w,video_title); - /* Refrain the video window to be closed at all times. */ - gdk_window_set_functions(w, - GDK_FUNC_RESIZE|GDK_FUNC_MOVE| - GDK_FUNC_MINIMIZE|GDK_FUNC_MAXIMIZE); - if (pbuf){ - GList *l=NULL; - l=g_list_append(l,pbuf); - gdk_window_set_icon_list(w,l); - g_list_free(l); - g_object_unref(G_OBJECT(pbuf)); - } -} - -static gboolean video_needs_update=FALSE; - -static void update_video_title(){ - video_needs_update=TRUE; -} - -static void update_video_titles(LinphoneCore *lc){ - unsigned long id; - static unsigned long previd=0; - static unsigned long preview_previd=0; - id=linphone_core_get_native_video_window_id(lc); - if (id!=previd || video_needs_update){ - GdkWindow *w; - previd=id; - if (id!=0){ - ms_message("Updating window decorations"); -#ifndef WIN32 - w=gdk_window_foreign_new((GdkNativeWindow)id); -#else - w=gdk_window_foreign_new((HANDLE)id); -#endif - if (w) { - set_video_window_decorations(w); - g_object_unref(G_OBJECT(w)); - } - else ms_error("gdk_window_foreign_new() failed"); - if (video_needs_update) video_needs_update=FALSE; - } - } - id=linphone_core_get_native_preview_window_id (lc); - if (id!=preview_previd ){ - GdkWindow *w; - preview_previd=id; - if (id!=0){ - ms_message("Updating window decorations for preview"); -#ifndef WIN32 - w=gdk_window_foreign_new((GdkNativeWindow)id); -#else - w=gdk_window_foreign_new((HANDLE)id); -#endif - if (w) { - set_video_window_decorations(w); - g_object_unref(G_OBJECT(w)); - } - else ms_error("gdk_window_foreign_new() failed"); - if (video_needs_update) video_needs_update=FALSE; - } - } -} static gboolean linphone_gtk_iterate(LinphoneCore *lc){ static gboolean first_time=TRUE; @@ -677,7 +582,6 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){ first_time=FALSE; } - update_video_titles(lc); if (addr_to_call!=NULL){ /*make sure we are not showing the login screen*/ GtkWidget *mw=linphone_gtk_get_main_window(); @@ -928,7 +832,6 @@ void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){ } if (linphone_gtk_use_in_call_view() && call) linphone_gtk_in_call_view_terminate(call,error); - update_video_title(); } static void linphone_gtk_update_call_buttons(LinphoneCall *call){ @@ -971,7 +874,6 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ linphone_gtk_enable_transfer_button(lc,FALSE); linphone_gtk_enable_conference_button(lc,FALSE); } - update_video_title(); if (call) { linphone_gtk_update_video_button(call); } diff --git a/mediastreamer2 b/mediastreamer2 index 4464c0944..dbded55e1 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 4464c094410dd4396b3563798031ed50ae90d8c8 +Subproject commit dbded55e10f03f77edfff660f38cc0b41348cc79 diff --git a/oRTP b/oRTP index d2c898513..540ee49bd 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit d2c898513d486b6c25af040ce54eb75ee86d6e19 +Subproject commit 540ee49bd3f65139f7e5938cc6bc1f8a4353c3f7