2 linphone, gtk-glade interface.
3 Copyright (C) 2008-2009 Simon MORLAT (simon.morlat@linphone.org)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "linphone_tunnel_manager.h"
29 static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){
30 const char **p=devices;
32 /* glade creates a combo box without list model and text renderer,
33 unless we fill it with a dummy text.
34 This dummy text needs to be removed first*/
35 gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
38 || (cap==CAP_CAPTURE && linphone_core_sound_device_can_capture(linphone_gtk_get_core(),*p))
39 || (cap==CAP_PLAYBACK && linphone_core_sound_device_can_playback(linphone_gtk_get_core(),*p)) ){
40 gtk_combo_box_append_text(GTK_COMBO_BOX(combo),*p);
41 if (strcmp(selected,*p)==0) active=i;
45 gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
48 void linphone_gtk_fill_video_sizes(GtkWidget *combo){
49 const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
52 MSVideoSize cur=linphone_core_get_preferred_video_size(linphone_gtk_get_core());
53 /* glade creates a combo box without list model and text renderer,
54 unless we fill it with a dummy text.
55 This dummy text needs to be removed first*/
56 gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
57 for(i=0;def->name!=NULL;++def,++i){
58 snprintf(vsize_def,sizeof(vsize_def),"%s (%ix%i)",def->name,def->vsize.width,def->vsize.height);
59 gtk_combo_box_append_text(GTK_COMBO_BOX(combo),vsize_def);
60 if (cur.width==def->vsize.width && cur.height==def->vsize.height) active=i;
62 gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
65 void linphone_gtk_parameters_closed(GtkWidget *button){
66 GtkWidget *pb=gtk_widget_get_toplevel(button);
67 gtk_widget_destroy(pb);
70 void linphone_gtk_update_my_contact(GtkWidget *w){
71 GtkWidget *pb=gtk_widget_get_toplevel(w);
72 const char *username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")));
73 const char *displayname=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname")));
74 int port=linphone_core_get_sip_port(linphone_gtk_get_core());
75 LinphoneAddress *parsed=linphone_core_get_primary_contact_parsed(linphone_gtk_get_core());
77 g_return_if_fail(parsed!=NULL);
78 if (username[0]=='\0') return;
80 linphone_address_set_display_name(parsed,displayname);
81 linphone_address_set_username(parsed,username);
82 linphone_address_set_port_int(parsed,port);
83 contact=linphone_address_as_string(parsed);
84 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"sip_address")),contact);
85 linphone_core_set_primary_contact(linphone_gtk_get_core(),contact);
87 linphone_address_destroy(parsed);
88 linphone_gtk_load_identities();
91 void linphone_gtk_update_my_port(GtkWidget *w){
92 GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(w));
94 LinphoneCore *lc=linphone_gtk_get_core();
95 GtkComboBox *combo = GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"));
97 gint port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
98 if (port == 1) { // We use default port if not specified
99 if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (UDP)") == 0) {
100 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
103 else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TCP)") == 0) {
104 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
107 else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TLS)") == 0) {
108 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
113 linphone_core_get_sip_transports(lc,&tr);
114 gchar *selected = gtk_combo_box_get_active_text(combo);
115 if (strcmp(selected, "SIP (TCP)") == 0) {
116 tr.tcp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
120 else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (UDP)") == 0) {
121 tr.udp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
125 else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (TLS)") == 0){
128 tr.tls_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
131 linphone_core_set_sip_transports(lc,&tr);
134 void linphone_gtk_stun_server_changed(GtkWidget *w){
135 const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w));
136 linphone_core_set_stun_server(linphone_gtk_get_core(),addr);
139 void linphone_gtk_nat_address_changed(GtkWidget *w){
140 const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w));
141 linphone_core_set_nat_address(linphone_gtk_get_core(),addr);
144 void linphone_gtk_ipv6_toggled(GtkWidget *w){
145 linphone_core_enable_ipv6(linphone_gtk_get_core(),
146 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
149 void linphone_gtk_audio_port_changed(GtkWidget *w){
150 linphone_core_set_audio_port(linphone_gtk_get_core(),
151 (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
154 void linphone_gtk_video_port_changed(GtkWidget *w){
155 linphone_core_set_video_port(linphone_gtk_get_core(),
156 (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
159 void linphone_gtk_no_firewall_toggled(GtkWidget *w){
160 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
161 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyNoFirewall);
164 void linphone_gtk_use_nat_address_toggled(GtkWidget *w){
165 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
166 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseNatAddress);
169 void linphone_gtk_use_stun_toggled(GtkWidget *w){
170 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
171 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseStun);
174 void linphone_gtk_mtu_changed(GtkWidget *w){
175 if (GTK_WIDGET_SENSITIVE(w))
176 linphone_core_set_mtu(linphone_gtk_get_core(),gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
179 void linphone_gtk_use_sip_info_dtmf_toggled(GtkWidget *w){
180 linphone_core_set_use_info_for_dtmf(linphone_gtk_get_core(),
181 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
184 void linphone_gtk_mtu_set(GtkWidget *w){
185 GtkWidget *mtu=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"mtu");
186 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
187 gtk_widget_set_sensitive(mtu,TRUE);
188 linphone_gtk_mtu_changed(mtu);
190 gtk_widget_set_sensitive(mtu,FALSE);
191 linphone_core_set_mtu(linphone_gtk_get_core(),0);
195 void linphone_gtk_playback_device_changed(GtkWidget *w){
196 gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
197 linphone_core_set_playback_device(linphone_gtk_get_core(),sel);
201 void linphone_gtk_capture_device_changed(GtkWidget *w){
202 gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
203 linphone_core_set_capture_device(linphone_gtk_get_core(),sel);
207 void linphone_gtk_ring_device_changed(GtkWidget *w){
208 gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
209 linphone_core_set_ringer_device(linphone_gtk_get_core(),sel);
213 void linphone_gtk_alsa_special_device_changed(GtkWidget *w){
215 const gchar *dev=gtk_entry_get_text(GTK_ENTRY(w));
219 void linphone_gtk_cam_changed(GtkWidget *w){
220 gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
221 linphone_core_set_video_device(linphone_gtk_get_core(),sel);
225 void linphone_gtk_video_size_changed(GtkWidget *w){
226 int sel=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
227 const MSVideoSizeDef *defs=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());
229 linphone_core_set_preferred_video_size(linphone_gtk_get_core(),
233 void linphone_gtk_ring_file_set(GtkWidget *w){
234 gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w));
235 linphone_core_set_ring(linphone_gtk_get_core(),file);
239 static void linphone_gtk_end_of_ring(LinphoneCore *lc, void *user_data){
240 gtk_widget_set_sensitive((GtkWidget*)user_data,TRUE);
243 void linphone_gtk_play_ring_file(GtkWidget *w){
244 if (linphone_core_preview_ring(linphone_gtk_get_core(),
245 linphone_core_get_ring(linphone_gtk_get_core()),
246 linphone_gtk_end_of_ring,
248 gtk_widget_set_sensitive(w,FALSE);
252 void linphone_gtk_echo_cancelation_toggled(GtkWidget *w){
253 linphone_core_enable_echo_cancellation(linphone_gtk_get_core(),
254 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
269 static void fmtp_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer userdata){
270 GtkListStore *store=(GtkListStore*)userdata;
272 if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),&iter,path)){
274 gtk_list_store_set(store,&iter,CODEC_PARAMS,new_text,-1);
275 gtk_tree_model_get(GTK_TREE_MODEL(store),&iter,CODEC_PRIVDATA,&pt,-1);
276 payload_type_set_recv_fmtp(pt,new_text);
280 static void linphone_gtk_init_codec_list(GtkTreeView *listview){
281 GtkCellRenderer *renderer;
282 GtkTreeViewColumn *column;
283 GtkTreeSelection *select;
285 GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING,G_TYPE_INT,
293 gtk_tree_view_set_model(listview,GTK_TREE_MODEL(store));
294 g_object_unref(G_OBJECT(store));
296 renderer = gtk_cell_renderer_text_new ();
297 column = gtk_tree_view_column_new_with_attributes (_("Name"),
300 "foreground",CODEC_COLOR,
302 gtk_tree_view_append_column (listview, column);
303 column = gtk_tree_view_column_new_with_attributes (_("Rate (Hz)"),
306 "foreground",CODEC_COLOR,
308 gtk_tree_view_append_column (listview, column);
309 column = gtk_tree_view_column_new_with_attributes (_("Status"),
311 "text", CODEC_STATUS,
312 "foreground",CODEC_COLOR,
314 gtk_tree_view_append_column (listview, column);
315 column = gtk_tree_view_column_new_with_attributes (_("Min bitrate (kbit/s)"),
317 "text", CODEC_BITRATE,
318 "foreground",CODEC_COLOR,
320 gtk_tree_view_append_column (listview, column);
321 renderer = gtk_cell_renderer_text_new ();
322 column = gtk_tree_view_column_new_with_attributes (_("Parameters"),
324 "text", CODEC_PARAMS,
325 "foreground",CODEC_COLOR,
328 g_signal_connect(G_OBJECT(renderer),"edited",G_CALLBACK(fmtp_edited),store);
329 gtk_tree_view_append_column (listview, column);
330 /* Setup the selection handler */
331 select = gtk_tree_view_get_selection (listview);
332 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
336 const char *get_codec_color(LinphoneCore *lc, PayloadType *pt){
338 if (linphone_core_check_payload_type_usability(lc,pt)) color="blue";
340 if (!linphone_core_payload_type_enabled(lc,pt)) {
346 static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codeclist)
350 GtkListStore *store=GTK_LIST_STORE(gtk_tree_view_get_model(listview));
351 GtkTreeSelection *selection;
353 gtk_list_store_clear(store);
355 for(elem=codeclist; elem!=NULL; elem=elem->next){
360 const char *params="";
362 struct _PayloadType *pt=(struct _PayloadType *)elem->data;
364 color=get_codec_color(linphone_gtk_get_core(),pt);
365 if (linphone_core_payload_type_enabled(linphone_gtk_get_core(),pt)) status=_("Enabled");
367 status=_("Disabled");
369 /* get an iterator */
370 gtk_list_store_append(store,&iter);
371 bitrate=payload_type_get_bitrate(pt)/1000.0;
372 rate=payload_type_get_rate(pt);
373 if (pt->recv_fmtp!=NULL) params=pt->recv_fmtp;
374 gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt),
376 CODEC_BITRATE,bitrate,
379 CODEC_PRIVDATA,(gpointer)pt,
380 CODEC_COLOR,(gpointer)color,
381 CODEC_INFO,(gpointer)linphone_core_get_payload_type_description(linphone_gtk_get_core(),pt),
387 /* Setup the selection handler */
388 selection = gtk_tree_view_get_selection (listview);
389 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
390 //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces));
391 #if GTK_CHECK_VERSION(2,12,0)
392 gtk_tree_view_set_tooltip_column(listview,CODEC_INFO);
396 static void linphone_gtk_check_codec_bandwidth(GtkTreeView *v){
399 model=gtk_tree_view_get_model(v);
400 g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter));
402 PayloadType *pt=NULL;
405 gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1);
407 bitrate=payload_type_get_bitrate(pt)/1000.0;
408 gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR, (gpointer)get_codec_color(linphone_gtk_get_core(),pt),
409 CODEC_BITRATE, bitrate,-1);
410 }while(gtk_tree_model_iter_next(model,&iter));
413 static void linphone_gtk_select_codec(GtkTreeView *v, PayloadType *ref){
416 GtkTreeSelection *selection;
417 selection=gtk_tree_view_get_selection(v);
418 model=gtk_tree_view_get_model(v);
419 g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter));
421 PayloadType *pt=NULL;
422 gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1);
424 gtk_tree_selection_select_iter(selection,&iter);
427 }while(gtk_tree_model_iter_next(model,&iter));
430 static void linphone_gtk_draw_codec_list(GtkTreeView *v, int type){ /* 0=audio, 1=video*/
432 if (type==0) list=linphone_core_get_audio_codecs(linphone_gtk_get_core());
433 else list=linphone_core_get_video_codecs(linphone_gtk_get_core());
434 linphone_gtk_show_codecs(v,list);
437 void linphone_gtk_codec_view_changed(GtkWidget *w){
438 GtkWidget *listview=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list");
439 int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
440 linphone_gtk_draw_codec_list(GTK_TREE_VIEW(listview),active);
443 void linphone_gtk_download_bw_changed(GtkWidget *w){
444 GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"));
445 linphone_core_set_download_bandwidth(linphone_gtk_get_core(),
446 (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
447 linphone_gtk_check_codec_bandwidth(v);
450 void linphone_gtk_upload_bw_changed(GtkWidget *w){
451 GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"));
452 linphone_core_set_upload_bandwidth(linphone_gtk_get_core(),
453 (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
454 linphone_gtk_check_codec_bandwidth(v);
457 void linphone_gtk_adaptive_rate_control_toggled(GtkToggleButton *button){
458 gboolean active=gtk_toggle_button_get_active(button);
459 linphone_core_enable_adaptive_rate_control(linphone_gtk_get_core(),active);
462 static void linphone_gtk_codec_move(GtkWidget *button, int dir){
463 GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list"));
464 GtkTreeSelection *sel=gtk_tree_view_get_selection(v);
467 PayloadType *pt=NULL;
468 LinphoneCore *lc=linphone_gtk_get_core();
469 if (gtk_tree_selection_get_selected(sel,&mod,&iter)){
470 MSList *sel_elem,*before;
472 gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1);
473 if (pt->type==PAYLOAD_VIDEO)
474 codec_list=ms_list_copy(linphone_core_get_video_codecs(lc));
475 else codec_list=ms_list_copy(linphone_core_get_audio_codecs(lc));
476 sel_elem=ms_list_find(codec_list,pt);
478 if (sel_elem->prev) before=sel_elem->prev;
479 else before=sel_elem;
480 codec_list=ms_list_insert(codec_list,before,pt);
483 if (sel_elem->next) before=sel_elem->next->next;
484 else before=sel_elem;
485 codec_list=ms_list_insert(codec_list,before,pt);
487 codec_list=ms_list_remove_link(codec_list,sel_elem);
488 if (pt->type==PAYLOAD_VIDEO)
489 linphone_core_set_video_codecs(lc,codec_list);
490 else linphone_core_set_audio_codecs(lc,codec_list);
491 linphone_gtk_show_codecs(v,codec_list);
492 linphone_gtk_select_codec(v,pt);
496 static void linphone_gtk_codec_set_enable(GtkWidget *button, gboolean enabled){
497 GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list"));
498 GtkTreeSelection *sel=gtk_tree_view_get_selection(v);
502 PayloadType *pt=NULL;
504 if (gtk_tree_selection_get_selected(sel,&mod,&iter)){
505 store=GTK_LIST_STORE(mod);
506 gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1);
507 linphone_core_enable_payload_type(linphone_gtk_get_core(),pt,enabled);
508 gtk_list_store_set(store,&iter,CODEC_STATUS, enabled ? _("Enabled") : _("Disabled"),
509 CODEC_COLOR,(gpointer)get_codec_color(linphone_gtk_get_core(),pt), -1);
513 void linphone_gtk_codec_up(GtkWidget *button){
514 linphone_gtk_codec_move(button,+1);
517 void linphone_gtk_codec_down(GtkWidget *button){
518 linphone_gtk_codec_move(button,-1);
521 void linphone_gtk_codec_enable(GtkWidget *button){
522 linphone_gtk_codec_set_enable(button,TRUE);
525 void linphone_gtk_codec_disable(GtkWidget *button){
526 linphone_gtk_codec_set_enable(button,FALSE);
529 void linphone_gtk_clear_passwords(GtkWidget *button){
530 linphone_core_clear_all_auth_info(linphone_gtk_get_core());
534 PROXY_CONFIG_IDENTITY,
539 void linphone_gtk_show_sip_accounts(GtkWidget *w){
540 GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(w,"proxy_list"));
541 GtkTreeModel *model=gtk_tree_view_get_model(v);
543 GtkTreeSelection *select;
546 GtkCellRenderer *renderer;
547 GtkTreeViewColumn *column;
548 /* create the proxy list */
549 store = gtk_list_store_new (PROXY_CONFIG_NCOL, G_TYPE_STRING, G_TYPE_POINTER);
551 gtk_tree_view_set_model(v,GTK_TREE_MODEL(store));
552 g_object_unref(G_OBJECT(store));
553 renderer = gtk_cell_renderer_text_new ();
554 column = gtk_tree_view_column_new_with_attributes (_("Account"),
556 "text", PROXY_CONFIG_IDENTITY,
558 gtk_tree_view_append_column (v, column);
560 select = gtk_tree_view_get_selection (v);
561 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
562 model=GTK_TREE_MODEL(store);
564 store=GTK_LIST_STORE(model);
566 gtk_list_store_clear(store);
567 for(elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());elem!=NULL;elem=ms_list_next(elem)){
568 LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
570 gtk_list_store_append(store,&iter);
571 gtk_list_store_set(store,&iter,PROXY_CONFIG_IDENTITY,linphone_proxy_config_get_identity(cfg),
572 PROXY_CONFIG_REF,cfg,-1);
576 static void linphone_gtk_proxy_closed(GtkWidget *w){
577 LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
579 linphone_proxy_config_done(cfg);
583 void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){
584 GtkWidget *w=linphone_gtk_create_window("sip_account");
587 linphone_proxy_config_edit(cfg);
588 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")),
589 linphone_proxy_config_get_identity(cfg));
590 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")),
591 linphone_proxy_config_get_addr(cfg));
592 tmp=linphone_proxy_config_get_route(cfg);
593 if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")),tmp);
594 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")),
595 linphone_proxy_config_get_expires(cfg));
596 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")),
597 linphone_proxy_config_register_enabled(cfg));
598 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")),
599 linphone_proxy_config_publish_enabled(cfg));
601 g_object_set_data(G_OBJECT(w),"config",(gpointer)cfg);
602 g_object_set_data(G_OBJECT(w),"parameters",(gpointer)pb);
603 g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_proxy_closed,w);
607 void linphone_gtk_proxy_cancel(GtkButton *button){
608 GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
609 gtk_widget_destroy(w);
612 void linphone_gtk_proxy_ok(GtkButton *button){
613 GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
614 LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
615 gboolean was_editing=TRUE;
618 cfg=linphone_proxy_config_new();
620 linphone_proxy_config_set_identity(cfg,
621 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity"))));
622 linphone_proxy_config_set_server_addr(cfg,
623 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy"))));
624 linphone_proxy_config_set_route(cfg,
625 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route"))));
626 linphone_proxy_config_expires(cfg,
627 (int)gtk_spin_button_get_value(
628 GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod"))));
629 linphone_proxy_config_enable_publish(cfg,
630 gtk_toggle_button_get_active(
631 GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish"))));
632 linphone_proxy_config_enable_register(cfg,
633 gtk_toggle_button_get_active(
634 GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register"))));
636 if (linphone_proxy_config_done(cfg)==-1)
640 if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) return;
641 linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg);
643 g_object_set_data(G_OBJECT(w),"config",NULL);
644 linphone_gtk_show_sip_accounts(GTK_WIDGET(g_object_get_data(G_OBJECT(w),"parameters")));
645 gtk_widget_destroy(w);
646 /* also update the main window's list of identities*/
647 linphone_gtk_load_identities();
650 static LinphoneProxyConfig *linphone_gtk_get_selected_proxy_config(GtkWidget* pb){
651 GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(pb,"proxy_list"));
652 GtkTreeSelection *selection=gtk_tree_view_get_selection(v);
655 if (gtk_tree_selection_get_selected(selection,&model,&iter)){
656 LinphoneProxyConfig *cfg=NULL;
657 gtk_tree_model_get(model,&iter,PROXY_CONFIG_REF,&cfg,-1);
663 void linphone_gtk_add_proxy(GtkButton *button){
664 linphone_gtk_show_proxy_config(gtk_widget_get_toplevel(GTK_WIDGET(button)),NULL);
667 void linphone_gtk_remove_proxy(GtkButton *button){
668 LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(
669 gtk_widget_get_toplevel(GTK_WIDGET(button)));
671 linphone_core_remove_proxy_config(linphone_gtk_get_core(),cfg);
672 linphone_gtk_show_sip_accounts(gtk_widget_get_toplevel(GTK_WIDGET(button)));
673 /* also update the main window's list of identities*/
674 linphone_gtk_load_identities();
678 void linphone_gtk_edit_proxy(GtkButton *button){
679 GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(button));
680 LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(pb);
682 linphone_gtk_show_proxy_config(pb,cfg);
683 /* also update the main window's list of identities*/
684 linphone_gtk_load_identities();
688 typedef struct _LangCodes{
693 static LangCodes supported_langs[]={
694 { "C" , N_("English") },
695 { "fr" , N_("French") },
696 { "sv" , N_("Swedish") },
697 { "it" , N_("Italian") },
698 { "es" , N_("Spanish") },
699 { "pt_BR" , N_("Brazilian Portugese") },
700 { "pl" , N_("Polish") },
701 { "de" , N_("German") },
702 { "ru" , N_("Russian") },
703 { "ja" , N_("Japanese") },
704 { "nl" , N_("Dutch") },
705 { "hu" , N_("Hungarian") },
706 { "cs" , N_("Czech") },
707 { "zh_CN" , N_("Chinese") },
708 { "zh_TW" , N_("Traditional Chinese") },
709 { "nb_NO" , N_("Norwegian") },
713 static const char *lang_get_name(const char *code){
714 LangCodes *p=supported_langs;
715 while(p->code!=NULL){
716 if (strcmp(p->code,code)==0) return p->name;
722 static gboolean lang_equals(const char *l1, const char *l2){
723 return ((strncmp(l1,l2,5)==0 || strncmp(l1,l2,2)==0));
726 static void linphone_gtk_fill_langs(GtkWidget *pb){
727 GtkWidget *combo=linphone_gtk_get_widget(pb,"lang_combo");
729 const char *all_langs="C " LINPHONE_ALL_LANGS;
732 const char *cur_lang=getenv("LANG");
733 int cur_lang_index=-1;
735 if (cur_lang==NULL) cur_lang="C";
736 /* glade creates a combo box without list model and text renderer,
737 unless we fill it with a dummy text.
738 This dummy text needs to be removed first*/
739 gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
740 while(sscanf(all_langs+i,"%s",code)==1){
742 while(all_langs[i]==' ') ++i;
743 name=lang_get_name(code);
744 snprintf(text,sizeof(text)-1,"%s : %s",code,name!=NULL ? _(name) : code);
745 gtk_combo_box_append_text(GTK_COMBO_BOX(combo),text);
746 if (cur_lang_index==-1 && lang_equals(cur_lang,code))
747 cur_lang_index=index;
750 gtk_combo_box_set_active(GTK_COMBO_BOX(combo),cur_lang_index);
753 void linphone_gtk_lang_changed(GtkComboBox *combo){
754 const char *selected=gtk_combo_box_get_active_text(combo);
756 const char *cur_lang=getenv("LANG");
758 sscanf(selected,"%s",code);
759 if (cur_lang==NULL) cur_lang="C";
760 if (!lang_equals(cur_lang,code)){
761 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(combo))),
762 GTK_DIALOG_DESTROY_WITH_PARENT,
766 (const gchar*)_("You need to restart linphone for the new language selection to take effect."));
767 /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
768 g_signal_connect_swapped (G_OBJECT (dialog), "response",
769 G_CALLBACK (gtk_widget_destroy),
771 gtk_widget_show(dialog);
772 linphone_gtk_set_lang(code);
777 void linphone_gtk_proto_changed(GtkComboBox *combo){
778 GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(combo));
780 GtkWidget *proto_port = linphone_gtk_get_widget(pb, "proto_port");
781 // When we change the network protocol, we call update_my_port to move the port number from the old protocol to the new one
782 linphone_gtk_update_my_port(proto_port);
785 static void linphone_gtk_ui_level_adapt(GtkWidget *top) {
786 gboolean ui_advanced;
787 const char *simple_ui = linphone_gtk_get_ui_config("simple_ui", "parameters.codec_tab parameters.transport_frame parameters.ports_frame");
789 ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", TRUE);
791 linphone_gtk_visibility_set(simple_ui, "parameters", top, TRUE);
793 linphone_gtk_visibility_set(simple_ui, "parameters", top, FALSE);
797 void linphone_gtk_ui_level_toggled(GtkWidget *w) {
801 top = gtk_widget_get_toplevel(w);
802 ui_advanced = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
803 linphone_gtk_set_ui_config_int("advanced_ui", ui_advanced);
804 linphone_gtk_ui_level_adapt(top);
807 static void linphone_gtk_media_encryption_changed(GtkWidget *combo){
808 char *selected=gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
809 LinphoneCore *lc=linphone_gtk_get_core();
811 if (strcasecmp(selected,"SRTP")==0)
812 linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionSRTP);
813 else if (strcasecmp(selected,"ZRTP")==0)
814 linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionZRTP);
815 else linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionNone);
817 }else g_warning("gtk_combo_box_get_active_text() returned NULL");
820 static void linphone_gtk_show_media_encryption(GtkWidget *pb){
821 LinphoneCore *lc=linphone_gtk_get_core();
822 GtkWidget *combo=linphone_gtk_get_widget(pb,"media_encryption_combo");
824 int srtp_id=-1,zrtp_id=-1;
828 GtkCellRenderer *renderer=gtk_cell_renderer_text_new();
830 model=GTK_TREE_MODEL((store=gtk_list_store_new(1,G_TYPE_STRING)));
831 gtk_combo_box_set_model(GTK_COMBO_BOX(combo),model);
832 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo),renderer,TRUE);
833 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo),renderer,"text",0,NULL);
835 gtk_list_store_append(store,&iter);
836 gtk_list_store_set(store,&iter,0,_("None"),-1);
838 if (linphone_core_media_encryption_supported(lc,LinphoneMediaEncryptionSRTP)){
839 gtk_list_store_append(store,&iter);
840 gtk_list_store_set(store,&iter,0,_("SRTP"),-1);
844 if (linphone_core_media_encryption_supported(lc,LinphoneMediaEncryptionZRTP)){
845 gtk_list_store_append(store,&iter);
846 gtk_list_store_set(store,&iter,0,_("ZRTP"),-1);
848 if (srtp_id!=-1) zrtp_id=2;
852 /*hide this setting*/
853 gtk_widget_hide(combo);
854 gtk_widget_hide(linphone_gtk_get_widget(pb,"media_encryption_label"));
856 LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc);
858 case LinphoneMediaEncryptionNone:
859 gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
861 case LinphoneMediaEncryptionSRTP:
862 if (srtp_id!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),srtp_id);
864 case LinphoneMediaEncryptionZRTP:
865 if (zrtp_id!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),zrtp_id);
868 g_signal_connect(G_OBJECT(combo),"changed",(GCallback)linphone_gtk_media_encryption_changed,NULL);
870 g_object_unref(G_OBJECT(model));
873 void linphone_gtk_show_parameters(void){
874 GtkWidget *pb=linphone_gtk_create_window("parameters");
875 LinphoneCore *lc=linphone_gtk_get_core();
876 const char **sound_devices=linphone_core_get_sound_devices(lc);
878 LinphoneAddress *contact;
879 LinphoneFirewallPolicy pol;
880 GtkWidget *codec_list=linphone_gtk_get_widget(pb,"codec_list");
886 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")),
887 linphone_core_ipv6_enabled(lc));
888 linphone_core_get_sip_transports(lc,&tr);
890 if (tr.tcp_port > 0) {
891 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 1);
892 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
895 else if (tr.tls_port > 0) {
896 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 2);
897 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
901 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 0);
902 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
906 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"audio_rtp_port")),
907 linphone_core_get_audio_port(lc));
908 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"video_rtp_port")),
909 linphone_core_get_video_port(lc));
911 linphone_gtk_show_media_encryption(pb);
913 tmp=linphone_core_get_nat_address(lc);
914 if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"nat_address")),tmp);
915 tmp=linphone_core_get_stun_server(lc);
916 if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"stun_server")),tmp);
917 pol=linphone_core_get_firewall_policy(lc);
919 case LinphonePolicyNoFirewall:
920 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"no_nat")),TRUE);
922 case LinphonePolicyUseNatAddress:
923 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_nat_address")),TRUE);
925 case LinphonePolicyUseStun:
926 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_stun")),TRUE);
929 mtu=linphone_core_get_mtu(lc);
931 gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),FALSE);
932 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),1500);
933 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),FALSE);
935 gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),TRUE);
936 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),mtu);
937 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),TRUE);
939 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"dtmf_sipinfo")),
940 linphone_core_get_use_info_for_dtmf(lc));
941 /* MUTIMEDIA CONFIG */
942 linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"playback_device"), sound_devices,
943 linphone_core_get_playback_device(lc),CAP_PLAYBACK);
944 linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"ring_device"), sound_devices,
945 linphone_core_get_ringer_device(lc),CAP_PLAYBACK);
946 linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"capture_device"), sound_devices,
947 linphone_core_get_capture_device(lc), CAP_CAPTURE);
948 linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc),
949 linphone_core_get_video_device(lc),CAP_IGNORE);
950 linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size"));
951 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")),
952 linphone_core_echo_cancellation_enabled(lc));
954 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(linphone_gtk_get_widget(pb,"ring_chooser")),
955 linphone_core_get_ring(lc));
957 contact=linphone_core_get_primary_contact_parsed(lc);
959 if (linphone_address_get_display_name(contact)) {
960 const char *dn=linphone_address_get_display_name(contact);
961 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname")),dn);
963 if (linphone_address_get_username(contact))
964 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")),linphone_address_get_username(contact));
966 linphone_address_destroy(contact);
967 linphone_gtk_show_sip_accounts(pb);
969 linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list));
970 linphone_gtk_draw_codec_list(GTK_TREE_VIEW(codec_list),0);
971 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"codec_view")),0);
972 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"download_bw")),
973 linphone_core_get_download_bandwidth(lc));
974 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"upload_bw")),
975 linphone_core_get_upload_bandwidth(lc));
976 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"adaptive_rate_control")),
977 linphone_core_adaptive_rate_control_enabled(lc));
981 linphone_gtk_fill_langs(pb);
982 ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", 1);
983 linphone_gtk_set_ui_config_int("advanced_ui", ui_advanced);
984 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ui_level")),
986 linphone_gtk_ui_level_adapt(pb);
988 g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_port")),"value-changed",(GCallback)linphone_gtk_update_my_port,NULL);
989 g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_combo")),"changed",(GCallback)linphone_gtk_proto_changed,NULL);
992 if (linphone_core_tunnel_available(lc)){
993 gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_edit_button")), TRUE);
994 gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_label")), TRUE);
1001 void linphone_gtk_edit_tunnel_closed(GtkWidget *button){
1002 GtkWidget *pb=gtk_widget_get_toplevel(button);
1003 gtk_widget_destroy(pb);
1006 #ifdef TUNNEL_ENABLED
1007 static void tunnel_get_server_host_and_port(LinphoneTunnelManager *tunnel, char *host, int size, int *port){
1009 char *addresses=(char*)ms_strdup(linphone_tunnel_get_server_addresses(tunnel));
1010 char *str1=addresses;
1011 char *address=strtok(str1," "); // Not thread safe
1012 if (!address) return;
1013 colon=strchr(address, ':');
1017 memcpy(host,address,size);
1022 void linphone_gtk_edit_tunnel(GtkButton *button){
1023 #ifdef TUNNEL_ENABLED
1024 LinphoneCore *lc=linphone_gtk_get_core();
1025 GtkWidget *w=linphone_gtk_create_window("tunnel_config");
1026 LinphoneTunnelManager *tunnel=linphone_tunnel_get(lc);
1027 char host[50]={'\0'};
1029 tunnel_get_server_host_and_port(tunnel, host, sizeof(host), &port);
1030 LinphoneTunnelState state=linphone_tunnel_get_state(tunnel);
1032 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"host")),host);
1033 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"port")), port);
1035 if (state == LinphoneTunnelEnabled){
1036 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_enable")),1);
1038 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_disable")),1);
1041 g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_edit_tunnel_closed,w);
1047 void linphone_gtk_tunnel_ok(GtkButton *button){
1048 #ifdef TUNNEL_ENABLED
1049 // Save information to config file
1050 LinphoneCore *lc=linphone_gtk_get_core();
1051 GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
1052 char address[50]={'\0'};
1053 LinphoneTunnelManager *tunnel=linphone_tunnel_get(lc);
1055 gint port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"port")));
1056 gboolean enabled=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_enable")));
1057 const char *host=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"host")));
1059 snprintf(address, sizeof address, "%s:%i", host, port);
1060 linphone_tunnel_set_server_addresses(tunnel, address);
1062 linphone_tunnel_set_state(tunnel, LinphoneTunnelEnabled);
1064 linphone_tunnel_set_state(tunnel,LinphoneTunnelDisabled);
1066 linphone_core_update_tunnel(lc);
1067 gtk_widget_destroy(w);
1072 void linphone_gtk_tunnel_cancel(GtkButton *button){