diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index aad80a60d10c18c0532dd1b8518c17d236282885..8cbccc7c3779f0e9a35bc433adfc2b80b9d00cd6 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -221,6 +221,9 @@ static void call_accepted(SalOp *op){ } linphone_call_set_state(call,LinphoneCallPaused,"Call paused"); }else{ + if (lc->vtable.display_status){ + lc->vtable.display_status(lc,_("Call answered - connected.")); + } linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)"); } linphone_connect_incoming (lc,call); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index b5c3e8e9405bfeafbb53948d2f827112353f45f4..3244aac7edfb801cf3f8814200f0baa27ade3c88 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -229,17 +229,23 @@ static void linphone_call_set_terminated(LinphoneCall *call){ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){ LinphoneCore *lc=call->core; + bool_t finalize_call=FALSE; if (call->state!=cstate){ if (cstate!=LinphoneCallRefered){ /*LinphoneCallRefered is rather an event, not a state. Indeed it does not change the state of the call (still paused or running)*/ call->state=cstate; } + if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){ + finalize_call=TRUE; + linphone_call_ref(call); + linphone_call_set_terminated (call); + } if (lc->vtable.call_state_changed) lc->vtable.call_state_changed(lc,call,cstate,message); + if (finalize_call) + linphone_call_unref(call); } - if (call->state==LinphoneCallEnd || call->state==LinphoneCallError) - linphone_call_set_terminated (call); } static void linphone_call_destroy(LinphoneCall *obj) @@ -369,6 +375,14 @@ bool_t linphone_call_has_transfer_pending(const LinphoneCall *call){ return call->refer_pending; } +/** + * Returns call's duration in seconds. +**/ +int linphone_call_get_duration(const LinphoneCall *call){ + if (call->media_start_time==0) return 0; + return time(NULL)-call->media_start_time; +} + /** * @} **/ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 145f670121015280076ebaa68207788b316147ee..5f07f2749465c0e18158d9eca22d4719210fc2fd 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -300,15 +300,10 @@ bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call){ return FALSE; } -int linphone_core_get_call_duration(LinphoneCall *call){ - if (call==NULL) return 0; - if (call->media_start_time==0) return 0; - return time(NULL)-call->media_start_time; -} - int linphone_core_get_current_call_duration(const LinphoneCore *lc){ LinphoneCall *call=linphone_core_get_current_call((LinphoneCore *)lc); - return linphone_core_get_call_duration(call); + if (call) return linphone_call_get_duration(call); + return -1; } const LinphoneAddress *linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc){ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 47a6ae47f9f03a80dd9c2126c6b04552623cba54..e8bbd41ba8dd4a6466befeda39be0d8abf2e31b1 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -174,6 +174,7 @@ void linphone_call_unref(LinphoneCall *call); LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call); const char *linphone_call_get_refer_to(const LinphoneCall *call); bool_t linphone_call_has_transfer_pending(const LinphoneCall *call); +int linphone_call_get_duration(const LinphoneCall *call); void *linphone_call_get_user_pointer(LinphoneCall *call); void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer); diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 7bcba956fdd9e24fd4153b07b86c0c038ad36bd8..546e9f4943a582bff046a442b50d1bda48a0d7ea 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -2,7 +2,6 @@ UI_FILES= about.ui \ main.ui \ password.ui \ contact.ui \ - incoming_call.ui \ parameters.ui \ sip_account.ui \ chatroom.ui \ diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 4d60d6309c75eda071792890c251190bf43328d5..fca97adda3bbbfe596da6682e4998ea86d3913c2 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -36,115 +36,155 @@ gboolean linphone_gtk_use_in_call_view(){ return val; } -void linphone_gtk_show_in_call_view(void){ - GtkWidget *main_window=linphone_gtk_get_main_window(); +LinphoneCall *linphone_gtk_get_currently_displayed_call(){ + LinphoneCore *lc=linphone_gtk_get_core(); + GtkWidget *main_window=linphone_gtk_get_main_window (); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); - GtkWidget *in_call_frame=linphone_gtk_get_widget(main_window,"in_call_frame"); - gint idx; - - /* Make the in call frame visible and arrange for the notebook to - show that page */ - gtk_widget_show(in_call_frame); - idx = gtk_notebook_page_num(notebook, in_call_frame); - if (idx >= 0) { - gtk_notebook_set_current_page(notebook, idx); + const MSList *calls=linphone_core_get_calls(lc); + if (!linphone_gtk_use_in_call_view() || ms_list_size(calls)==1){ + if (calls) return (LinphoneCall*)calls->data; + }else{ + int idx=gtk_notebook_get_current_page (notebook); + GtkWidget *page=gtk_notebook_get_nth_page(notebook,idx); + if (page!=NULL){ + LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(page),"call"); + return call; + } } + return NULL; } -void linphone_gtk_show_idle_view(void){ - GtkWidget *main_window=linphone_gtk_get_main_window(); +static GtkWidget *make_tab_header(int number){ + GtkWidget *w=gtk_hbox_new (FALSE,0); + GtkWidget *i=create_pixmap ("status-green.png"); + GtkWidget *l; + gchar *text=g_strdup_printf("Call %i",number); + l=gtk_label_new (text); + gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); + gtk_box_pack_end(GTK_BOX(w),l,TRUE,TRUE,0); + gtk_widget_show_all(w); + return w; +} + +void linphone_gtk_create_in_call_view(LinphoneCall *call){ + GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame"); + GtkWidget *main_window=linphone_gtk_get_main_window (); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); - GtkWidget *idle_frame=linphone_gtk_get_widget(main_window,"idle_frame"); - GtkWidget *in_call_frame=linphone_gtk_get_widget(main_window,"in_call_frame"); - gint idx; + static int call_index=1; + int idx; + + g_object_set_data(G_OBJECT(call_view),"call",call); + linphone_call_set_user_pointer (call,call_view); + linphone_call_ref(call); + gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index)); + gtk_widget_show(call_view); + idx = gtk_notebook_page_num(notebook, call_view); + gtk_notebook_set_current_page(notebook, idx); + call_index++; +} - /* Switch back to the idle frame page, maybe we should have - remembered where we were in gtk_show_in_call_view() to switch - back to that page of the notebook, but this should do in most - cases. */ - gtk_widget_show(idle_frame); /* Make sure it is visible... */ - idx = gtk_notebook_page_num(notebook, idle_frame); - if (idx >= 0) { - gtk_notebook_set_current_page(notebook, idx); - gtk_widget_hide(in_call_frame); - } +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 (); + GtkWidget *nb=linphone_gtk_get_widget(main_window,"viewswitch"); + int idx; + g_return_if_fail(w!=NULL); + idx=gtk_notebook_page_num(GTK_NOTEBOOK(nb),w); + gtk_notebook_remove_page (GTK_NOTEBOOK(nb),idx); + gtk_widget_destroy(w); + linphone_call_set_user_pointer (call,NULL); + linphone_call_unref(call); + gtk_notebook_set_current_page(GTK_NOTEBOOK(nb), 0); } -void display_peer_name_in_label(GtkWidget *label, const char *uri){ - LinphoneAddress *from; +static void display_peer_name_in_label(GtkWidget *label, const LinphoneAddress *from){ const char *displayname=NULL; - char *id=NULL; + const char *id; char *uri_label; - - if (uri==NULL) { - ms_error("Strange: in call with nobody ?"); - return; - } - - from=linphone_address_new(uri); - if (from!=NULL){ - displayname=linphone_address_get_display_name(from); - id=linphone_address_as_string_uri_only(from); - }else id=ms_strdup(uri); - + displayname=linphone_address_get_display_name(from); + id=linphone_address_as_string_uri_only(from); + if (displayname!=NULL){ uri_label=g_markup_printf_escaped("<span size=\"large\">%s</span>\n<i>%s</i>", displayname,id); }else uri_label=g_markup_printf_escaped("<span size=\"large\"><i>%s</i></span>\n",id); gtk_label_set_markup(GTK_LABEL(label),uri_label); - ms_free(id); g_free(uri_label); - if (from!=NULL) linphone_address_destroy(from); } -void linphone_gtk_in_call_view_set_calling(const char *uri){ - GtkWidget *main_window=linphone_gtk_get_main_window(); - GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status"); - GtkWidget *callee=linphone_gtk_get_widget(main_window,"in_call_uri"); - GtkWidget *duration=linphone_gtk_get_widget(main_window,"in_call_duration"); - GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation"); +void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); + GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri"); + GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration"); + GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif"); - + gtk_label_set_markup(GTK_LABEL(status),_("<b>Calling...</b>")); - display_peer_name_in_label(callee,uri); + display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); if (pbuf!=NULL){ gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf); g_object_unref(G_OBJECT(pbuf)); - }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_INFO,GTK_ICON_SIZE_DIALOG); + }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_FIND,GTK_ICON_SIZE_DIALOG); } -void linphone_gtk_in_call_view_set_in_call(){ - LinphoneCore *lc=linphone_gtk_get_core(); - GtkWidget *main_window=linphone_gtk_get_main_window(); - GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status"); - GtkWidget *callee=linphone_gtk_get_widget(main_window,"in_call_uri"); - GtkWidget *duration=linphone_gtk_get_widget(main_window,"in_call_duration"); - GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation"); +void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); + GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri"); + GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration"); + GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); + GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif"); + + gtk_label_set_markup(GTK_LABEL(status),_("<b>Incoming call</b>")); + gtk_widget_show_all(linphone_gtk_get_widget(callview,"answer_decline_panel")); + display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); + + gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"accept_call")), + create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"))); + gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")), + create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"))); + + gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); + if (pbuf!=NULL){ + gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf); + g_object_unref(G_OBJECT(pbuf)); + }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_EXECUTE,GTK_ICON_SIZE_DIALOG); +} + +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"); + GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri"); + GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration"); + GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); GdkPixbufAnimation *pbuf=create_pixbuf_animation("incall_anim.gif"); - const LinphoneAddress *uri=linphone_core_get_current_call_remote_address(lc); - char *tmp=linphone_address_as_string(uri); - display_peer_name_in_label(callee,tmp); - ms_free(tmp); + GtkWidget *holdbutton; + + display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); + gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); gtk_label_set_markup(GTK_LABEL(status),_("<b>In call with</b>")); gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); if (pbuf!=NULL){ gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf); g_object_unref(G_OBJECT(pbuf)); - }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_INFO,GTK_ICON_SIZE_DIALOG); + }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_EXECUTE,GTK_ICON_SIZE_DIALOG); linphone_gtk_enable_mute_button( - GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,"incall_mute")),TRUE); - linphone_gtk_enable_hold_button( - GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,"hold_call")),TRUE); + GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),TRUE); + holdbutton=linphone_gtk_get_widget(callview,"hold_call"); + linphone_gtk_enable_hold_button(GTK_TOGGLE_BUTTON(holdbutton),TRUE); + g_object_set_data(G_OBJECT(holdbutton),"call",call); } -void linphone_gtk_in_call_view_update_duration(int duration){ - GtkWidget *main_window=linphone_gtk_get_main_window(); - GtkWidget *duration_label=linphone_gtk_get_widget(main_window,"in_call_duration"); +void linphone_gtk_in_call_view_update_duration(LinphoneCall *call){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *duration_label=linphone_gtk_get_widget(callview,"in_call_duration"); + int duration=linphone_call_get_duration(call); char tmp[256]={0}; int seconds=duration%60; int minutes=(duration/60)%60; @@ -153,15 +193,15 @@ void linphone_gtk_in_call_view_update_duration(int duration){ gtk_label_set_text(GTK_LABEL(duration_label),tmp); } -static gboolean in_call_view_terminated(){ - linphone_gtk_show_idle_view(); +static gboolean in_call_view_terminated(LinphoneCall *call){ + linphone_gtk_remove_in_call_view(call); return FALSE; } -void linphone_gtk_in_call_view_terminate(const char *error_msg){ - GtkWidget *main_window=linphone_gtk_get_main_window(); - GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status"); - GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation"); +void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); + GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); GdkPixbuf *pbuf=create_pixbuf(linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png")); if (error_msg==NULL) @@ -175,11 +215,12 @@ void linphone_gtk_in_call_view_terminate(const char *error_msg){ gtk_image_set_from_pixbuf(GTK_IMAGE(animation),pbuf); g_object_unref(G_OBJECT(pbuf)); } + gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); linphone_gtk_enable_mute_button( - GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,"incall_mute")),FALSE); + GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),FALSE); linphone_gtk_enable_hold_button( - GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,"hold_call")),FALSE); - g_timeout_add_seconds(2,(GSourceFunc)in_call_view_terminated,NULL); + GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(callview,"hold_call")),FALSE); + g_timeout_add_seconds(2,(GSourceFunc)in_call_view_terminated,call); } void linphone_gtk_draw_mute_button(GtkToggleButton *button, gboolean active){ @@ -215,14 +256,14 @@ void linphone_gtk_enable_mute_button(GtkToggleButton *button, gboolean sensitive void linphone_gtk_draw_hold_button(GtkToggleButton *button, gboolean active){ if (active){ GtkWidget *image=create_pixmap("hold_off.png"); - gtk_button_set_label(GTK_BUTTON(button),_("HoldOff")); + gtk_button_set_label(GTK_BUTTON(button),_("Resume")); if (image!=NULL) { gtk_button_set_image(GTK_BUTTON(button),image); gtk_widget_show(image); } }else{ GtkWidget *image=create_pixmap("hold_on.png"); - gtk_button_set_label(GTK_BUTTON(button),_("HoldOn")); + gtk_button_set_label(GTK_BUTTON(button),_("Pause")); if (image!=NULL) { gtk_button_set_image(GTK_BUTTON(button),image); gtk_widget_show(image); @@ -232,23 +273,14 @@ void linphone_gtk_draw_hold_button(GtkToggleButton *button, gboolean active){ void linphone_gtk_hold_toggled(GtkToggleButton *button){ gboolean active=gtk_toggle_button_get_active(button); - + LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(button),"call"); if(active) { - LinphoneCall *call=linphone_core_get_current_call (linphone_gtk_get_core()); - if (call==NULL) return; linphone_core_pause_call(linphone_gtk_get_core(),call); } else { - const MSList *calls=linphone_core_get_calls(linphone_gtk_get_core()); - if (calls==NULL) return; - if (ms_list_size(calls)>1){ - g_warning("Simultaneously calls not yet implemented in gtk ui."); - return; - } - /*we are supposed to have only one */ - linphone_core_resume_call(linphone_gtk_get_core(),(LinphoneCall*)calls->data); + linphone_core_resume_call(linphone_gtk_get_core(),call); } linphone_gtk_draw_hold_button(button,active); } diff --git a/gtk/linphone.h b/gtk/linphone.h index 85027715570c3572ece370ebb6bf27185f5e3f68..c50dde591027176f7ee04a9a79b5c54fd9170397 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -48,6 +48,8 @@ GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint GtkWidget *linphone_gtk_create_window(const char *window_name); GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); +GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name); + LinphoneCore *linphone_gtk_get_core(void); GtkWidget *linphone_gtk_get_main_window(); void linphone_gtk_display_something(GtkMessageType type,const gchar *message); @@ -85,12 +87,13 @@ void linphone_gtk_show_directory_search(void); /*functions controlling the different views*/ gboolean linphone_gtk_use_in_call_view(); -void linphone_gtk_show_in_call_view(void); -void linphone_gtk_show_idle_view(void); -void linphone_gtk_in_call_view_set_calling(const char *uri); -void linphone_gtk_in_call_view_set_in_call(void); -void linphone_gtk_in_call_view_update_duration(int duration); -void linphone_gtk_in_call_view_terminate(const char *error_msg); +LinphoneCall *linphone_gtk_get_currently_displayed_call(); +void linphone_gtk_create_in_call_view(LinphoneCall *call); +void linphone_gtk_in_call_view_set_calling(LinphoneCall *call); +void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call); +void linphone_gtk_in_call_view_update_duration(LinphoneCall *call); +void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg); +void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call); void linphone_gtk_enable_mute_button(GtkToggleButton *button, gboolean sensitive); void linphone_gtk_enable_hold_button(GtkToggleButton *button, gboolean sensitive); diff --git a/gtk/logging.c b/gtk/logging.c index 9bdf1dc0ea5da35e983c36b5e836949eddd78349..4b3af6638303b733840f19ec747a08c8cc04b3fd 100644 --- a/gtk/logging.c +++ b/gtk/logging.c @@ -213,14 +213,6 @@ static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg) } } - - -static gboolean delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - gtk_widget_hide (widget); - return TRUE; -} - void linphone_gtk_log_hide(){ if (log_window) gtk_widget_hide(log_window); @@ -234,7 +226,7 @@ void linphone_gtk_create_log_window(void){ gtk_text_buffer_create_tag(b,"orange","foreground","orange",NULL); /*prevent the log window from being destroyed*/ g_signal_connect (G_OBJECT (log_window), "delete-event", - G_CALLBACK (delete_event_cb), NULL); + G_CALLBACK (gtk_widget_hide_on_delete), log_window); } diff --git a/gtk/main.c b/gtk/main.c index ea176e666cf365cf0cb809e99bdc18b8569d57c4..f435ff31a0c7f274326b8d68c4e52013eb805ad4 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -42,7 +42,6 @@ static LinphoneCore *the_core=NULL; static GtkWidget *the_ui=NULL; static void linphone_gtk_show(LinphoneCore *lc); -static void linphone_gtk_inv_recv(LinphoneCore *lc, LinphoneCall *call); static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid); static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url); static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username); @@ -53,7 +52,7 @@ static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const ch static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl); static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to); static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg); -static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window); +static gboolean linphone_gtk_auto_answer(LinphoneCall *call); static gboolean verbose=0; @@ -107,7 +106,7 @@ static GOptionEntry linphone_options[]={ }; #define INSTALLED_XML_DIR PACKAGE_DATA_DIR "/linphone" -#define BUILD_TREE_XML_DIR "gtk-glade" +#define BUILD_TREE_XML_DIR "gtk" #ifndef WIN32 #define CONFIG_FILE ".linphonerc" @@ -279,23 +278,31 @@ GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){ #else -GtkWidget *linphone_gtk_create_window(const char *window_name){ - GError* error = NULL; - GtkBuilder* builder = gtk_builder_new (); - char path[2048]; - GtkWidget *w; - snprintf(path,sizeof(path),"%s/%s.ui",BUILD_TREE_XML_DIR,window_name); +static int get_ui_file(const char *name, char *path, int pathsize){ + snprintf(path,pathsize,"%s/%s.ui",BUILD_TREE_XML_DIR,name); if (access(path,F_OK)!=0){ - snprintf(path,sizeof(path),"%s/%s.ui",INSTALLED_XML_DIR,window_name); + snprintf(path,pathsize,"%s/%s.ui",INSTALLED_XML_DIR,name); if (access(path,F_OK)!=0){ - g_error("Could not locate neither %s/%s.ui and %s/%s.ui .",BUILD_TREE_XML_DIR,window_name, - INSTALLED_XML_DIR,window_name); - return NULL; + g_error("Could not locate neither %s/%s.ui and %s/%s.ui .",BUILD_TREE_XML_DIR,name, + INSTALLED_XML_DIR,name); + return -1; } } + return 0; +} + +GtkWidget *linphone_gtk_create_window(const char *window_name){ + GError* error = NULL; + GtkBuilder* builder = gtk_builder_new (); + char path[512]; + GtkWidget *w; + + if (get_ui_file(window_name,path,sizeof(path))==-1) return NULL; + if (!gtk_builder_add_from_file (builder, path, &error)){ g_error("Couldn't load builder file: %s", error->message); g_error_free (error); + return NULL; } w=GTK_WIDGET(gtk_builder_get_object (builder,window_name)); if (w==NULL){ @@ -308,6 +315,33 @@ GtkWidget *linphone_gtk_create_window(const char *window_name){ return w; } +GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name){ + char path[2048]; + GtkWidget *w; + GtkBuilder* builder = gtk_builder_new (); + GError *error=NULL; + gchar *object_ids[2]; + object_ids[0]=g_strdup(widget_name); + object_ids[1]=NULL; + + if (get_ui_file(filename,path,sizeof(path))==-1) return NULL; + if (!gtk_builder_add_objects_from_file(builder,path,object_ids,&error)){ + g_error("Couldn't load %s from builder file %s: %s", widget_name,path,error->message); + g_error_free (error); + g_free(object_ids[0]); + return NULL; + } + g_free(object_ids[0]); + w=GTK_WIDGET(gtk_builder_get_object (builder,widget_name)); + if (w==NULL){ + g_error("Could not retrieve '%s' window from xml file",widget_name); + return NULL; + } + g_object_set_data(G_OBJECT(w),"builder",builder); + gtk_builder_connect_signals(builder,w); + return w; +} + GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){ GtkBuilder *builder=(GtkBuilder*)g_object_get_data(G_OBJECT(window),"builder"); GObject *w; @@ -580,37 +614,74 @@ static void completion_add_text(GtkEntry *entry, const char *text){ save_uri_history(); } -void linphone_gtk_call_terminated(const char *error){ +void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){ GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *icw; gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),FALSE); gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),TRUE); - linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"main_mute")),FALSE); - if (linphone_gtk_use_in_call_view()) - linphone_gtk_in_call_view_terminate(error); + + if (linphone_gtk_use_in_call_view() && call) + linphone_gtk_in_call_view_terminate(call,error); update_video_title(); - icw=GTK_WIDGET(g_object_get_data(G_OBJECT(mw),"incoming_call")); - if (icw!=NULL){ - g_object_set_data(G_OBJECT(mw),"incoming_call",NULL); - gtk_widget_destroy(icw); - } } static gboolean in_call_timer(){ - if (linphone_core_in_call(linphone_gtk_get_core())){ - linphone_gtk_in_call_view_update_duration( - linphone_core_get_current_call_duration(linphone_gtk_get_core())); + LinphoneCall *call=linphone_core_get_current_call(linphone_gtk_get_core()); + if (call){ + linphone_gtk_in_call_view_update_duration(call); return TRUE; } return FALSE; } -static void linphone_gtk_call_started(GtkWidget *mw){ - gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),FALSE); - gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),TRUE); +static bool_t all_calls_paused(const MSList *calls){ + for(;calls!=NULL;calls=calls->next){ + LinphoneCall *call=(LinphoneCall*)calls->data; + if (linphone_call_get_state(call)!=LinphoneCallPaused) + return FALSE; + } + return TRUE; +} + +static void linphone_gtk_update_call_buttons(LinphoneCall *call){ + LinphoneCore *lc=linphone_gtk_get_core(); + GtkWidget *mw=linphone_gtk_get_main_window(); + const MSList *calls=linphone_core_get_calls(lc); + GtkWidget *button; + bool_t start_active=TRUE; + bool_t stop_active=FALSE; + bool_t add_call=FALSE; + + if (calls==NULL){ + start_active=TRUE; + stop_active=FALSE; + }else if (linphone_core_get_current_call(lc)!=NULL){ + start_active=FALSE; + stop_active=TRUE; + }else if (all_calls_paused(calls)){ + start_active=TRUE; + stop_active=TRUE; + add_call=TRUE; + }else if (call!=NULL){ + if (linphone_call_get_state(call)==LinphoneCallIncomingReceived){ + start_active=TRUE; + stop_active=TRUE; + } + } + button=linphone_gtk_get_widget(mw,"start_call"); + gtk_widget_set_sensitive(button,start_active); + gtk_widget_set_visible(button,!add_call); + + button=linphone_gtk_get_widget(mw,"add_call"); + gtk_widget_set_sensitive(button,start_active); + gtk_widget_set_visible(button,add_call); + + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),stop_active); + if (linphone_core_get_calls(lc)==NULL){ + linphone_gtk_enable_mute_button( + GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")), + FALSE); + } update_video_title(); - if (linphone_gtk_use_in_call_view()) - g_timeout_add(250,(GSourceFunc)in_call_timer,NULL); } static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ @@ -618,50 +689,37 @@ static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ if (linphone_core_invite(linphone_gtk_get_core(),entered)!=NULL) { completion_add_text(GTK_ENTRY(uri_bar),entered); }else{ - linphone_gtk_call_terminated(NULL); + linphone_gtk_call_terminated(NULL,NULL); } return FALSE; } -static void _linphone_gtk_accept_call(){ - LinphoneCore *lc=linphone_gtk_get_core(); - GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(mw),"incoming_call")); - if (icw!=NULL){ - g_object_set_data(G_OBJECT(mw),"incoming_call",NULL); - gtk_widget_destroy(icw); +static gboolean linphone_gtk_auto_answer(LinphoneCall *call){ + if (linphone_call_get_state(call)==LinphoneCallIncomingReceived){ + linphone_core_accept_call (linphone_gtk_get_core(),call); + linphone_call_unref(call); } - - linphone_core_accept_call(lc,NULL); - linphone_gtk_call_started(linphone_gtk_get_main_window()); - if (linphone_gtk_use_in_call_view()){ - linphone_gtk_in_call_view_set_in_call(); - linphone_gtk_show_in_call_view(); - } - linphone_gtk_enable_mute_button( - GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")) - ,TRUE); + return FALSE; } + void linphone_gtk_start_call(GtkWidget *w){ LinphoneCore *lc=linphone_gtk_get_core(); - if (linphone_core_inc_invite_pending(lc)){ - /*accept the call*/ - _linphone_gtk_accept_call(); - }else if (linphone_core_in_call(lc)) { - /*already in call */ + LinphoneCall *call; + /*change into in-call mode, then do the work later as it might block a bit */ + GtkWidget *mw=gtk_widget_get_toplevel(w); + GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar"); + + call=linphone_gtk_get_currently_displayed_call (); + if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived){ + linphone_core_accept_call(lc,call); }else{ - /*change into in-call mode, then do the work later as it might block a bit */ - GtkWidget *mw=gtk_widget_get_toplevel(w); - GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar"); - const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar)); - linphone_gtk_call_started(mw); - if (linphone_gtk_use_in_call_view()){ - linphone_gtk_in_call_view_set_calling(entered); - linphone_gtk_show_in_call_view(); - } + /*immediately disable the button and delay a bit the execution the linphone_core_invite() + so that we don't freeze the button. linphone_core_invite() might block for some hundreds of milliseconds*/ + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),FALSE); g_timeout_add(100,(GSourceFunc)linphone_gtk_start_call_do,uri_bar); } + } void linphone_gtk_uri_bar_activate(GtkWidget *w){ @@ -670,23 +728,21 @@ void linphone_gtk_uri_bar_activate(GtkWidget *w){ void linphone_gtk_terminate_call(GtkWidget *button){ - const MSList *elem=linphone_core_get_calls(linphone_gtk_get_core()); - if (elem==NULL) return; - linphone_core_terminate_call(linphone_gtk_get_core(),(LinphoneCall*)elem->data); + LinphoneCall *call=linphone_gtk_get_currently_displayed_call (); + if (call) + linphone_core_terminate_call(linphone_gtk_get_core(),call); } -void linphone_gtk_decline_call(GtkWidget *button){ - linphone_core_terminate_call(linphone_gtk_get_core(),NULL); - gtk_widget_destroy(gtk_widget_get_toplevel(button)); +void linphone_gtk_decline_clicked(GtkWidget *button){ + LinphoneCall *call=linphone_gtk_get_currently_displayed_call (); + if (call) + linphone_core_terminate_call(linphone_gtk_get_core(),call); } -void linphone_gtk_accept_call(GtkWidget *button){ - _linphone_gtk_accept_call(); -} - -static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window){ - linphone_gtk_accept_call(linphone_gtk_get_widget(incall_window,"accept_call")); - return FALSE; +void linphone_gtk_answer_clicked(GtkWidget *button){ + LinphoneCall *call=linphone_gtk_get_currently_displayed_call (); + if (call) + linphone_core_accept_call(linphone_gtk_get_core(),call); } void linphone_gtk_set_audio_video(){ @@ -733,33 +789,6 @@ static void linphone_gtk_show(LinphoneCore *lc){ linphone_gtk_show_main_window(); } -static void linphone_gtk_inv_recv(LinphoneCore *lc, LinphoneCall *call){ - GtkWidget *w=linphone_gtk_create_window("incoming_call"); - GtkWidget *label; - gchar *msg; - char *from=linphone_call_get_remote_address_as_string(call); - - if (auto_answer){ - g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer,w); - } - - gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window())); - gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT); - - label=linphone_gtk_get_widget(w,"message"); - msg=g_strdup_printf(_("Incoming call from %s"),from); - gtk_label_set_text(GTK_LABEL(label),msg); - gtk_window_set_title(GTK_WINDOW(w),msg); - gtk_widget_show(w); - gtk_window_present(GTK_WINDOW(w)); - /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/ - g_free(msg); - g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w); - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")), - from); - ms_free(from); -} - static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid){ linphone_gtk_show_friends(); } @@ -902,25 +931,38 @@ static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl) static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg){ switch(cs){ + case LinphoneCallOutgoingInit: + linphone_gtk_create_in_call_view (call); + break; + case LinphoneCallOutgoingProgress: + linphone_gtk_in_call_view_set_calling (call); + break; case LinphoneCallConnected: - if (linphone_gtk_use_in_call_view()) - linphone_gtk_in_call_view_set_in_call(); + linphone_gtk_in_call_view_set_in_call(call); linphone_gtk_enable_mute_button( GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")), TRUE); + g_timeout_add(250,(GSourceFunc)in_call_timer,NULL); break; case LinphoneCallError: - linphone_gtk_call_terminated(msg); + linphone_gtk_in_call_view_terminate (call,msg); break; case LinphoneCallEnd: - linphone_gtk_call_terminated(NULL); + linphone_gtk_in_call_view_terminate(call,NULL); break; case LinphoneCallIncomingReceived: - linphone_gtk_inv_recv (lc,call); + linphone_gtk_create_in_call_view (call); + linphone_gtk_in_call_view_set_incoming(call); + if (auto_answer) { + linphone_call_ref(call); + g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer ,call); + } + break; default: break; } + linphone_gtk_update_call_buttons (call); } static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){ @@ -1074,6 +1116,7 @@ static void linphone_gtk_configure_main_window(){ static const char *title; static const char *home; static const char *start_call_icon; + static const char *add_call_icon; static const char *stop_call_icon; static const char *search_icon; static gboolean update_check_menu; @@ -1083,6 +1126,7 @@ static void linphone_gtk_configure_main_window(){ title=linphone_gtk_get_ui_config("title","Linphone"); home=linphone_gtk_get_ui_config("home","http://www.linphone.org"); start_call_icon=linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"); + add_call_icon=linphone_gtk_get_ui_config("add_call_icon","addcall-green.png"); stop_call_icon=linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"); search_icon=linphone_gtk_get_ui_config("directory_search_icon",NULL); update_check_menu=linphone_gtk_get_ui_config_int("update_check_menu",0); @@ -1097,18 +1141,22 @@ static void linphone_gtk_configure_main_window(){ #endif } if (start_call_icon){ - GdkPixbuf *pbuf=create_pixbuf(start_call_icon); - gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"start_call_icon")),pbuf); - if (buttons_have_borders) - gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")),GTK_RELIEF_NORMAL); - g_object_unref(G_OBJECT(pbuf)); + gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")), + create_pixmap (start_call_icon)); + if (!buttons_have_borders) + gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")),GTK_RELIEF_NONE); + } + if (add_call_icon){ + gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"add_call")), + create_pixmap (add_call_icon)); + if (!buttons_have_borders) + gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"add_call")),GTK_RELIEF_NONE); } if (stop_call_icon){ - GdkPixbuf *pbuf=create_pixbuf(stop_call_icon); - gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"terminate_call_icon")),pbuf); - if (buttons_have_borders) - gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"terminate_call")),GTK_RELIEF_NORMAL); - g_object_unref(G_OBJECT(pbuf)); + gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"terminate_call")), + create_pixmap (stop_call_icon)); + if (!buttons_have_borders) + gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"terminate_call")),GTK_RELIEF_NONE); } if (search_icon){ GdkPixbuf *pbuf=create_pixbuf(search_icon); @@ -1154,6 +1202,17 @@ void linphone_gtk_manage_login(void){ } } + +void linphone_gtk_close(GtkWidget *mw){ + /*shutdown calls if any*/ + LinphoneCore *lc=linphone_gtk_get_core(); + if (linphone_core_in_call(lc)){ + linphone_core_terminate_all_calls(lc); + } + linphone_core_enable_video_preview(lc,FALSE); + gtk_widget_hide(mw); +} + static void linphone_gtk_init_main_window(){ GtkWidget *main_window; @@ -1175,23 +1234,12 @@ static void linphone_gtk_init_main_window(){ if (!linphone_gtk_use_in_call_view()) { gtk_widget_show(linphone_gtk_get_widget(main_window, "main_mute")); } - if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started( - linphone_gtk_get_main_window());/*hide the call button, show terminate button*/ + linphone_gtk_update_call_buttons (NULL); + /*prevent the main window from being destroyed by a user click on WM controls, instead we hide it*/ + g_signal_connect (G_OBJECT (main_window), "delete-event", + G_CALLBACK (linphone_gtk_close), main_window); } -void linphone_gtk_close(){ - /* couldn't find a way to prevent closing to destroy the main window*/ - LinphoneCore *lc=linphone_gtk_get_core(); - the_ui=NULL; - the_ui=linphone_gtk_create_window("main"); - linphone_gtk_init_main_window(); - /*shutdown call if any*/ - if (linphone_core_in_call(lc)){ - linphone_core_terminate_call(lc,NULL); - linphone_gtk_call_terminated(NULL); - } - linphone_core_enable_video_preview(lc,FALSE); -} void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){ if (verbose){ diff --git a/gtk/main.ui b/gtk/main.ui index 616c8e9f1aa24c91633d120b42c312d6549e2cc9..2f9433a3fb17da7169a2250380bfd7af5b259f1c 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -58,7 +58,6 @@ <object class="GtkUIManager" id="uimanager1"/> <object class="GtkWindow" id="main"> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <signal name="destroy" handler="linphone_gtk_close"/> <child> <object class="GtkVBox" id="vbox2"> <property name="visible">True</property> @@ -244,41 +243,27 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="has_tooltip">True</property> - <property name="tooltip_text" translatable="yes">Start call</property> - <property name="relief">none</property> <signal name="clicked" handler="linphone_gtk_start_call"/> - <child> - <object class="GtkHBox" id="hbox4"> - <property name="visible">True</property> - <child> - <object class="GtkImage" id="start_call_icon"> - <property name="visible">True</property> - <property name="stock">gtk-apply</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="start_call_label"> - <property name="label" translatable="yes">Start call</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - </child> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="padding">10</property> <property name="position">0</property> </packing> </child> + <child> + <object class="GtkButton" id="add_call"> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="tooltip_text" translatable="yes">Initiate a new call</property> + <signal name="clicked" handler="linphone_gtk_start_call"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> <child> <object class="GtkFrame" id="frame4"> <property name="visible">True</property> @@ -321,51 +306,20 @@ </child> </object> <packing> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> <child> <object class="GtkButton" id="terminate_call"> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="has_tooltip">True</property> - <property name="tooltip_text" translatable="yes">Terminate call</property> - <property name="relief">none</property> <signal name="clicked" handler="linphone_gtk_terminate_call"/> - <child> - <object class="GtkHBox" id="hbox21"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <object class="GtkImage" id="terminate_call_icon"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="stock">gtk-close</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="terminate_call_label"> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="label" translatable="yes">Terminate call</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - </child> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="padding">10</property> - <property name="position">2</property> + <property name="position">3</property> </packing> </child> </object> @@ -1116,167 +1070,10 @@ </packing> </child> <child> - <object class="GtkFrame" id="in_call_frame"> - <property name="label_xalign">0.5</property> - <property name="shadow_type">none</property> - <child> - <object class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <property name="right_padding">12</property> - <child> - <object class="GtkVBox" id="vbox3"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkImage" id="in_call_animation"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="icon-size">5</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame2"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkLabel" id="in_call_uri"> - <property name="visible">True</property> - <property name="label" translatable="yes">label</property> - <property name="justify">center</property> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="use_markup">True</property> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="frame1"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <child> - <object class="GtkVBox" id="vbox4"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkLabel" id="in_call_duration"> - <property name="visible">True</property> - <property name="label" translatable="yes">Duration</property> - <property name="justify">center</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="call_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Duration:</property> - <property name="use_markup">True</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkHButtonBox" id="hbuttonbox4"> - <property name="visible">True</property> - <property name="layout_style">spread</property> - <child> - <object class="GtkToggleButton" id="incall_mute"> - <property name="label" translatable="yes">Mute</property> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <signal name="toggled" handler="linphone_gtk_mute_toggled"/> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkToggleButton" id="hold_call"> - <property name="label" translatable="yes">HoldOn</property> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <signal name="toggled" handler="linphone_gtk_hold_toggled"/> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - </object> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="in_call_status"> - <property name="visible">True</property> - <property name="label" translatable="yes">In call</property> - <property name="use_markup">True</property> - <property name="justify">center</property> - </object> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> + <placeholder/> </child> <child type="tab"> - <object class="GtkHBox" id="hbox10"> - <property name="visible">True</property> - <child> - <object class="GtkImage" id="incall_icon"> - <property name="visible">True</property> - <property name="stock">gtk-missing-image</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label18"> - <property name="visible">True</property> - <property name="label" translatable="yes">Call Details</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> - </packing> + <placeholder/> </child> </object> <packing> @@ -1497,4 +1294,175 @@ <property name="visible">True</property> <property name="stock">gtk-execute</property> </object> + <object class="GtkWindow" id="dummy_in_call_window"> + <child> + <object class="GtkFrame" id="in_call_frame"> + <property name="label_xalign">0.5</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <property name="right_padding">12</property> + <child> + <object class="GtkVBox" id="vbox3"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkImage" id="in_call_animation"> + <property name="visible">True</property> + <property name="stock">gtk-info</property> + <property name="icon-size">5</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame2"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <child> + <object class="GtkLabel" id="in_call_uri"> + <property name="visible">True</property> + <property name="label" translatable="yes">label</property> + <property name="justify">center</property> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkHButtonBox" id="answer_decline_panel"> + <property name="layout_style">spread</property> + <child> + <object class="GtkButton" id="accept_call"> + <property name="label" translatable="yes">Answer</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="linphone_gtk_answer_clicked"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="decline_call"> + <property name="label" translatable="yes">Decline</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="linphone_gtk_decline_clicked"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame1"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <child> + <object class="GtkVBox" id="vbox4"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="in_call_duration"> + <property name="visible">True</property> + <property name="label" translatable="yes">Duration</property> + <property name="justify">center</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="call_label"> + <property name="visible">True</property> + <property name="label" translatable="yes">Duration:</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkHButtonBox" id="hbuttonbox4"> + <property name="visible">True</property> + <property name="layout_style">spread</property> + <child> + <object class="GtkToggleButton" id="incall_mute"> + <property name="label" translatable="yes">Mute</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="toggled" handler="linphone_gtk_mute_toggled"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkToggleButton" id="hold_call"> + <property name="label" translatable="yes">HoldOn</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="toggled" handler="linphone_gtk_hold_toggled"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="in_call_status"> + <property name="visible">True</property> + <property name="label" translatable="yes">In call</property> + <property name="use_markup">True</property> + <property name="justify">center</property> + </object> + </child> + </object> + </child> + </object> </interface> diff --git a/pixmaps/addcall-green.png b/pixmaps/addcall-green.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6ae3b7a8b30334482123a99c963bdbc787f559 Binary files /dev/null and b/pixmaps/addcall-green.png differ