]> sjero.net Git - linphone/blob - gtk/propertybox.c
Merge branch 'master' of git.savannah.nongnu.org:/srv/git/linphone
[linphone] / gtk / propertybox.c
1 /*
2 linphone, gtk-glade interface.
3 Copyright (C) 2008-2009  Simon MORLAT (simon.morlat@linphone.org)
4
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.
9
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.
14
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.
18 */
19
20 #include "linphone.h"
21
22 typedef enum {
23         CAP_IGNORE,
24         CAP_PLAYBACK,
25         CAP_CAPTURE
26 }DeviceCap;
27
28 static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){
29         const char **p=devices;
30         int i=0,active=0;
31         /* glade creates a combo box without list model and text renderer,
32         unless we fill it with a dummy text.
33         This dummy text needs to be removed first*/
34         gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
35         for(;*p!=NULL;++p){
36                 if ( cap==CAP_IGNORE
37                         || (cap==CAP_CAPTURE && linphone_core_sound_device_can_capture(linphone_gtk_get_core(),*p))
38                         || (cap==CAP_PLAYBACK && linphone_core_sound_device_can_playback(linphone_gtk_get_core(),*p)) ){
39                         gtk_combo_box_append_text(GTK_COMBO_BOX(combo),*p);
40                         if (strcmp(selected,*p)==0) active=i;
41                         i++;
42                 }
43         }
44         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
45 }
46
47 void linphone_gtk_fill_video_sizes(GtkWidget *combo){
48         const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
49         int i,active=0;
50         char vsize_def[256];
51         MSVideoSize cur=linphone_core_get_preferred_video_size(linphone_gtk_get_core());
52         /* glade creates a combo box without list model and text renderer,
53         unless we fill it with a dummy text.
54         This dummy text needs to be removed first*/
55         gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
56         for(i=0;def->name!=NULL;++def,++i){
57                 snprintf(vsize_def,sizeof(vsize_def),"%s (%ix%i)",def->name,def->vsize.width,def->vsize.height);
58                 gtk_combo_box_append_text(GTK_COMBO_BOX(combo),vsize_def);
59                 if (cur.width==def->vsize.width && cur.height==def->vsize.height) active=i;
60         }
61         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
62 }
63
64 void linphone_gtk_parameters_closed(GtkWidget *button){
65         GtkWidget *pb=gtk_widget_get_toplevel(button);
66         gtk_widget_destroy(pb);
67 }
68
69 void linphone_gtk_update_my_contact(GtkWidget *w){
70         GtkWidget *pb=gtk_widget_get_toplevel(w);
71         const char *username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")));
72         const char *displayname=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname")));
73         int port=linphone_core_get_sip_port(linphone_gtk_get_core());
74         LinphoneAddress *parsed=linphone_core_get_primary_contact_parsed(linphone_gtk_get_core());
75         char *contact;
76         g_return_if_fail(parsed!=NULL);
77         if (username[0]=='\0') return;
78
79         linphone_address_set_display_name(parsed,displayname);
80         linphone_address_set_username(parsed,username);
81         linphone_address_set_port_int(parsed,port);
82         contact=linphone_address_as_string(parsed);
83         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"sip_address")),contact);
84         linphone_core_set_primary_contact(linphone_gtk_get_core(),contact);
85         ms_free(contact);
86         linphone_address_destroy(parsed);
87         linphone_gtk_load_identities();
88 }
89
90 void linphone_gtk_update_my_port(GtkWidget *w){
91     GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(w));
92         LCSipTransports tr;
93         LinphoneCore *lc=linphone_gtk_get_core();
94     GtkComboBox *combo = GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"));
95
96         gint port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
97     if (port == 1) { // We use default port if not specified
98         if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (UDP)") == 0) {
99             gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
100                                 5060);
101         }
102         else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TCP)") == 0) {
103             gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
104                                 5060);
105         }
106         else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TLS)") == 0) {
107             gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
108                                 5061);
109         }
110     }
111
112         linphone_core_get_sip_transports(lc,&tr);
113     gchar *selected = gtk_combo_box_get_active_text(combo);
114         if (strcmp(selected, "SIP (TCP)") == 0) {
115                 tr.tcp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
116                 tr.udp_port = 0;
117                 tr.tls_port = 0;
118         }
119         else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (UDP)") == 0) {
120                 tr.udp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
121                 tr.tcp_port = 0;
122                 tr.tls_port = 0;
123         }
124         else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (TLS)") == 0){
125                 tr.udp_port = 0;
126                 tr.tcp_port = 0;
127                 tr.tls_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
128         }
129
130         linphone_core_set_sip_transports(lc,&tr);
131 }
132
133 void linphone_gtk_stun_server_changed(GtkWidget *w){
134         const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w));
135         linphone_core_set_stun_server(linphone_gtk_get_core(),addr);
136 }
137
138 void linphone_gtk_nat_address_changed(GtkWidget *w){
139         const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w));
140         linphone_core_set_nat_address(linphone_gtk_get_core(),addr);
141 }
142
143 void linphone_gtk_ipv6_toggled(GtkWidget *w){
144         linphone_core_enable_ipv6(linphone_gtk_get_core(),
145                                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
146 }
147
148 /* void linphone_gtk_udp_sip_port_changed(GtkWidget *w){
149         LCSipTransports tr;
150         LinphoneCore *lc=linphone_gtk_get_core();
151
152         linphone_core_get_sip_transports(lc,&tr);
153         tr.udp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
154         linphone_core_set_sip_transports(lc,&tr);
155 }
156
157 void linphone_gtk_tcp_sip_port_changed(GtkWidget *w){
158         LCSipTransports tr;
159         LinphoneCore *lc=linphone_gtk_get_core();
160
161         linphone_core_get_sip_transports(lc,&tr);
162         tr.tcp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
163         linphone_core_set_sip_transports(lc,&tr);
164 } */
165
166 void linphone_gtk_audio_port_changed(GtkWidget *w){
167         linphone_core_set_audio_port(linphone_gtk_get_core(),
168                         (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
169 }
170
171 void linphone_gtk_video_port_changed(GtkWidget *w){
172         linphone_core_set_video_port(linphone_gtk_get_core(),
173                         (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
174 }
175
176 void linphone_gtk_no_firewall_toggled(GtkWidget *w){
177         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
178                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyNoFirewall);
179 }
180
181 void linphone_gtk_use_nat_address_toggled(GtkWidget *w){
182         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
183                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseNatAddress);
184 }
185
186 void linphone_gtk_use_stun_toggled(GtkWidget *w){
187         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
188                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseStun);
189 }
190
191 void linphone_gtk_mtu_changed(GtkWidget *w){
192         if (GTK_WIDGET_SENSITIVE(w))
193                 linphone_core_set_mtu(linphone_gtk_get_core(),gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
194 }
195
196 void linphone_gtk_use_sip_info_dtmf_toggled(GtkWidget *w){
197         linphone_core_set_use_info_for_dtmf(linphone_gtk_get_core(),
198                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
199 }
200
201 void linphone_gtk_mtu_set(GtkWidget *w){
202         GtkWidget *mtu=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"mtu");
203         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
204                 gtk_widget_set_sensitive(mtu,TRUE);
205                 linphone_gtk_mtu_changed(mtu);
206         }else{
207                 gtk_widget_set_sensitive(mtu,FALSE);
208                 linphone_core_set_mtu(linphone_gtk_get_core(),0);
209         }
210 }
211
212 void linphone_gtk_playback_device_changed(GtkWidget *w){
213         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
214         linphone_core_set_playback_device(linphone_gtk_get_core(),sel);
215         g_free(sel);
216 }
217
218 void linphone_gtk_capture_device_changed(GtkWidget *w){
219         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
220         linphone_core_set_capture_device(linphone_gtk_get_core(),sel);
221         g_free(sel);
222 }
223
224 void linphone_gtk_ring_device_changed(GtkWidget *w){
225         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
226         linphone_core_set_ringer_device(linphone_gtk_get_core(),sel);
227         g_free(sel);
228 }
229
230 void linphone_gtk_alsa_special_device_changed(GtkWidget *w){
231         /*
232         const gchar *dev=gtk_entry_get_text(GTK_ENTRY(w));
233         ...*/
234 }
235
236 void linphone_gtk_cam_changed(GtkWidget *w){
237         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
238         linphone_core_set_video_device(linphone_gtk_get_core(),sel);
239         g_free(sel);
240 }
241
242 void linphone_gtk_video_size_changed(GtkWidget *w){
243         int sel=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
244         const MSVideoSizeDef *defs=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());
245         if (sel<0) return;
246         linphone_core_set_preferred_video_size(linphone_gtk_get_core(),
247                                         defs[sel].vsize);
248 }
249
250 void linphone_gtk_ring_file_set(GtkWidget *w){
251         gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w));
252         linphone_core_set_ring(linphone_gtk_get_core(),file);
253         g_free(file);
254 }
255
256 static void linphone_gtk_end_of_ring(LinphoneCore *lc, void *user_data){
257         gtk_widget_set_sensitive((GtkWidget*)user_data,TRUE);
258 }
259
260 void linphone_gtk_play_ring_file(GtkWidget *w){
261         if (linphone_core_preview_ring(linphone_gtk_get_core(),
262                                 linphone_core_get_ring(linphone_gtk_get_core()),
263                                 linphone_gtk_end_of_ring,
264                                 w)==0){
265                 gtk_widget_set_sensitive(w,FALSE);
266         }
267 }
268
269 void linphone_gtk_echo_cancelation_toggled(GtkWidget *w){
270         linphone_core_enable_echo_cancellation(linphone_gtk_get_core(),
271                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
272 }
273
274 enum {
275         CODEC_NAME,
276         CODEC_RATE,
277         CODEC_BITRATE,
278         CODEC_STATUS,
279         CODEC_PARAMS,
280         CODEC_PRIVDATA,
281         CODEC_COLOR,
282         CODEC_INFO,
283         CODEC_NCOLUMNS
284 };
285
286 static void fmtp_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer userdata){
287         GtkListStore *store=(GtkListStore*)userdata;
288         GtkTreeIter iter;
289         if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),&iter,path)){
290                 PayloadType *pt;
291                 gtk_list_store_set(store,&iter,CODEC_PARAMS,new_text,-1);
292                 gtk_tree_model_get(GTK_TREE_MODEL(store),&iter,CODEC_PRIVDATA,&pt,-1);
293                 payload_type_set_recv_fmtp(pt,new_text);
294         }
295 }
296
297 static void linphone_gtk_init_codec_list(GtkTreeView *listview){
298         GtkCellRenderer *renderer;
299         GtkTreeViewColumn *column;
300         GtkTreeSelection *select;
301
302         GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING,G_TYPE_INT,
303                                                         G_TYPE_FLOAT,
304                                                         G_TYPE_STRING,
305                                                         G_TYPE_STRING,
306                                                         G_TYPE_POINTER,
307                                                         G_TYPE_STRING,
308                                                         G_TYPE_STRING);
309
310         gtk_tree_view_set_model(listview,GTK_TREE_MODEL(store));
311         g_object_unref(G_OBJECT(store));
312
313         renderer = gtk_cell_renderer_text_new ();
314         column = gtk_tree_view_column_new_with_attributes (_("Name"),
315                                                    renderer,
316                                                    "text", CODEC_NAME,
317                                                 "foreground",CODEC_COLOR,
318                                                    NULL);
319         gtk_tree_view_append_column (listview, column);
320         column = gtk_tree_view_column_new_with_attributes (_("Rate (Hz)"),
321                                                    renderer,
322                                                    "text", CODEC_RATE,
323                                                 "foreground",CODEC_COLOR,
324                                                    NULL);
325         gtk_tree_view_append_column (listview, column);
326         column = gtk_tree_view_column_new_with_attributes (_("Status"),
327                                                    renderer,
328                                                    "text", CODEC_STATUS,
329                                                 "foreground",CODEC_COLOR,
330                                                    NULL);
331         gtk_tree_view_append_column (listview, column);
332         column = gtk_tree_view_column_new_with_attributes (_("Min bitrate (kbit/s)"),
333                                                    renderer,
334                                                    "text", CODEC_BITRATE,
335                                                 "foreground",CODEC_COLOR,
336                                                    NULL);
337         gtk_tree_view_append_column (listview, column);
338         renderer = gtk_cell_renderer_text_new ();
339         column = gtk_tree_view_column_new_with_attributes (_("Parameters"),
340                                                    renderer,
341                                                    "text", CODEC_PARAMS,
342                                                 "foreground",CODEC_COLOR,
343                                         "editable",TRUE,
344                                                    NULL);
345         g_signal_connect(G_OBJECT(renderer),"edited",G_CALLBACK(fmtp_edited),store);
346         gtk_tree_view_append_column (listview, column);
347         /* Setup the selection handler */
348         select = gtk_tree_view_get_selection (listview);
349         gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
350 }
351
352
353 const char *get_codec_color(LinphoneCore *lc, PayloadType *pt){
354         const gchar *color;
355         if (linphone_core_check_payload_type_usability(lc,pt)) color="blue";
356                 else color="red";
357         if (!linphone_core_payload_type_enabled(lc,pt)) {
358                 color="grey";
359         }
360         return color;
361 }
362
363 static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codeclist)
364 {
365         const MSList *elem;
366         GtkTreeIter iter;
367         GtkListStore *store=GTK_LIST_STORE(gtk_tree_view_get_model(listview));
368         GtkTreeSelection *selection;
369
370         gtk_list_store_clear(store);
371
372         for(elem=codeclist; elem!=NULL; elem=elem->next){
373                 gchar *status;
374                 gint rate;
375                 gfloat bitrate;
376                 const gchar *color;
377                 const char *params="";
378
379                 struct _PayloadType *pt=(struct _PayloadType *)elem->data;
380
381                 color=get_codec_color(linphone_gtk_get_core(),pt);
382                 if (linphone_core_payload_type_enabled(linphone_gtk_get_core(),pt)) status=_("Enabled");
383                 else {
384                         status=_("Disabled");
385                 }
386                 /* get an iterator */
387                 gtk_list_store_append(store,&iter);
388                 bitrate=payload_type_get_bitrate(pt)/1000.0;
389                 rate=payload_type_get_rate(pt);
390                 if (pt->recv_fmtp!=NULL) params=pt->recv_fmtp;
391                 gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt),
392                                         CODEC_RATE,rate,
393                                         CODEC_BITRATE,bitrate,
394                                         CODEC_STATUS,status,
395                                         CODEC_PARAMS,params,
396                                         CODEC_PRIVDATA,(gpointer)pt,
397                                         CODEC_COLOR,(gpointer)color,
398                                         CODEC_INFO,(gpointer)linphone_core_get_payload_type_description(linphone_gtk_get_core(),pt),
399                                         -1);
400         }
401
402
403
404         /* Setup the selection handler */
405         selection = gtk_tree_view_get_selection (listview);
406         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
407         //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces));
408 #if GTK_CHECK_VERSION(2,12,0)
409         gtk_tree_view_set_tooltip_column(listview,CODEC_INFO);
410 #endif
411 }
412
413 static void linphone_gtk_check_codec_bandwidth(GtkTreeView *v){
414         GtkTreeIter iter;
415         GtkTreeModel *model;
416         model=gtk_tree_view_get_model(v);
417         g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter));
418         do{
419                 PayloadType *pt=NULL;
420
421                 gfloat bitrate;
422                 gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1);
423
424                 bitrate=payload_type_get_bitrate(pt)/1000.0;
425                 gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR, (gpointer)get_codec_color(linphone_gtk_get_core(),pt),
426                                         CODEC_BITRATE, bitrate,-1);
427         }while(gtk_tree_model_iter_next(model,&iter));
428 }
429
430 static void linphone_gtk_select_codec(GtkTreeView *v, PayloadType *ref){
431         GtkTreeIter iter;
432         GtkTreeModel *model;
433         GtkTreeSelection *selection;
434         selection=gtk_tree_view_get_selection(v);
435         model=gtk_tree_view_get_model(v);
436         g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter));
437         do{
438                 PayloadType *pt=NULL;
439                 gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1);
440                 if (pt==ref){
441                         gtk_tree_selection_select_iter(selection,&iter);
442                 }
443
444         }while(gtk_tree_model_iter_next(model,&iter));
445 }
446
447 static void linphone_gtk_draw_codec_list(GtkTreeView *v, int type){ /* 0=audio, 1=video*/
448         const MSList *list;
449         if (type==0) list=linphone_core_get_audio_codecs(linphone_gtk_get_core());
450         else list=linphone_core_get_video_codecs(linphone_gtk_get_core());
451         linphone_gtk_show_codecs(v,list);
452 }
453
454 void linphone_gtk_codec_view_changed(GtkWidget *w){
455         GtkWidget *listview=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list");
456         int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
457         linphone_gtk_draw_codec_list(GTK_TREE_VIEW(listview),active);
458 }
459
460 void linphone_gtk_download_bw_changed(GtkWidget *w){
461         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"));
462         linphone_core_set_download_bandwidth(linphone_gtk_get_core(),
463                                 (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
464         linphone_gtk_check_codec_bandwidth(v);
465 }
466
467 void linphone_gtk_upload_bw_changed(GtkWidget *w){
468         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"));
469         linphone_core_set_upload_bandwidth(linphone_gtk_get_core(),
470                                 (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
471         linphone_gtk_check_codec_bandwidth(v);
472 }
473
474 static void linphone_gtk_codec_move(GtkWidget *button, int dir){
475         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list"));
476         GtkTreeSelection *sel=gtk_tree_view_get_selection(v);
477         GtkTreeModel *mod;
478         GtkTreeIter iter;
479         PayloadType *pt=NULL;
480         LinphoneCore *lc=linphone_gtk_get_core();
481         if (gtk_tree_selection_get_selected(sel,&mod,&iter)){
482                 MSList *sel_elem,*before;
483                 MSList *codec_list;
484                 gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1);
485                 if (pt->type==PAYLOAD_VIDEO)
486                         codec_list=ms_list_copy(linphone_core_get_video_codecs(lc));
487                 else codec_list=ms_list_copy(linphone_core_get_audio_codecs(lc));
488                 sel_elem=ms_list_find(codec_list,pt);
489                 if (dir>0) {
490                         if (sel_elem->prev) before=sel_elem->prev;
491                         else before=sel_elem;
492                         codec_list=ms_list_insert(codec_list,before,pt);
493                 }
494                 else{
495                         if (sel_elem->next) before=sel_elem->next->next;
496                         else before=sel_elem;
497                         codec_list=ms_list_insert(codec_list,before,pt);
498                 }
499                 codec_list=ms_list_remove_link(codec_list,sel_elem);
500                 if (pt->type==PAYLOAD_VIDEO)
501                         linphone_core_set_video_codecs(lc,codec_list);
502                 else linphone_core_set_audio_codecs(lc,codec_list);
503                 linphone_gtk_show_codecs(v,codec_list);
504                 linphone_gtk_select_codec(v,pt);
505         }
506 }
507
508 static void linphone_gtk_codec_set_enable(GtkWidget *button, gboolean enabled){
509         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list"));
510         GtkTreeSelection *sel=gtk_tree_view_get_selection(v);
511         GtkTreeModel *mod;
512         GtkListStore *store;
513         GtkTreeIter iter;
514         PayloadType *pt=NULL;
515
516         if (gtk_tree_selection_get_selected(sel,&mod,&iter)){
517                 store=GTK_LIST_STORE(mod);
518                 gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1);
519                 linphone_core_enable_payload_type(linphone_gtk_get_core(),pt,enabled);
520                 gtk_list_store_set(store,&iter,CODEC_STATUS, enabled ? _("Enabled") : _("Disabled"),
521                                    CODEC_COLOR,(gpointer)get_codec_color(linphone_gtk_get_core(),pt), -1);
522         }
523 }
524
525 void linphone_gtk_codec_up(GtkWidget *button){
526         linphone_gtk_codec_move(button,+1);
527 }
528
529 void linphone_gtk_codec_down(GtkWidget *button){
530         linphone_gtk_codec_move(button,-1);
531 }
532
533 void linphone_gtk_codec_enable(GtkWidget *button){
534         linphone_gtk_codec_set_enable(button,TRUE);
535 }
536
537 void linphone_gtk_codec_disable(GtkWidget *button){
538         linphone_gtk_codec_set_enable(button,FALSE);
539 }
540
541 void linphone_gtk_clear_passwords(GtkWidget *button){
542         linphone_core_clear_all_auth_info(linphone_gtk_get_core());
543 }
544
545 enum{
546         PROXY_CONFIG_IDENTITY,
547         PROXY_CONFIG_REF,
548         PROXY_CONFIG_NCOL
549 };
550
551 void linphone_gtk_show_sip_accounts(GtkWidget *w){
552         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(w,"proxy_list"));
553         GtkTreeModel *model=gtk_tree_view_get_model(v);
554         GtkListStore *store;
555         GtkTreeSelection *select;
556         const MSList *elem;
557         if (!model){
558                 GtkCellRenderer *renderer;
559                 GtkTreeViewColumn *column;
560                 /* create the proxy list */
561                 store = gtk_list_store_new (PROXY_CONFIG_NCOL, G_TYPE_STRING, G_TYPE_POINTER);
562
563                 gtk_tree_view_set_model(v,GTK_TREE_MODEL(store));
564                 g_object_unref(G_OBJECT(store));
565                 renderer = gtk_cell_renderer_text_new ();
566                 column = gtk_tree_view_column_new_with_attributes (_("Account"),
567                                                         renderer,
568                                                         "text", PROXY_CONFIG_IDENTITY,
569                                                         NULL);
570                 gtk_tree_view_append_column (v, column);
571
572                 select = gtk_tree_view_get_selection (v);
573                 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
574                 model=GTK_TREE_MODEL(store);
575         }else {
576                 store=GTK_LIST_STORE(model);
577         }
578         gtk_list_store_clear(store);
579         for(elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());elem!=NULL;elem=ms_list_next(elem)){
580                 LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
581                 GtkTreeIter iter;
582                 gtk_list_store_append(store,&iter);
583                 gtk_list_store_set(store,&iter,PROXY_CONFIG_IDENTITY,linphone_proxy_config_get_identity(cfg),
584                                         PROXY_CONFIG_REF,cfg,-1);
585         }
586 }
587
588 static void linphone_gtk_proxy_closed(GtkWidget *w){
589         LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
590         if (cfg){
591                 linphone_proxy_config_done(cfg);
592         }
593 }
594
595 void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){
596         GtkWidget *w=linphone_gtk_create_window("sip_account");
597         const char *tmp;
598         if (cfg){
599                 linphone_proxy_config_edit(cfg);
600                 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")),
601                         linphone_proxy_config_get_identity(cfg));
602                 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")),
603                         linphone_proxy_config_get_addr(cfg));
604                 tmp=linphone_proxy_config_get_route(cfg);
605                 if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")),tmp);
606                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")),
607                         linphone_proxy_config_get_expires(cfg));
608                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")),
609                         linphone_proxy_config_register_enabled(cfg));
610                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")),
611                         linphone_proxy_config_publish_enabled(cfg));
612         }
613         g_object_set_data(G_OBJECT(w),"config",(gpointer)cfg);
614         g_object_set_data(G_OBJECT(w),"parameters",(gpointer)pb);
615         g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_proxy_closed,w);
616         gtk_widget_show(w);
617 }
618
619 void linphone_gtk_proxy_cancel(GtkButton *button){
620         GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
621         gtk_widget_destroy(w);
622 }
623
624 void linphone_gtk_proxy_ok(GtkButton *button){
625         GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
626         LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
627         gboolean was_editing=TRUE;
628         if (!cfg){
629                 was_editing=FALSE;
630                 cfg=linphone_proxy_config_new();
631         }
632         linphone_proxy_config_set_identity(cfg,
633                 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity"))));
634         linphone_proxy_config_set_server_addr(cfg,
635                 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy"))));
636         linphone_proxy_config_set_route(cfg,
637                 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route"))));
638         linphone_proxy_config_expires(cfg,
639                 (int)gtk_spin_button_get_value(
640                         GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod"))));
641         linphone_proxy_config_enable_publish(cfg,
642                 gtk_toggle_button_get_active(
643                         GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish"))));
644         linphone_proxy_config_enable_register(cfg,
645                 gtk_toggle_button_get_active(
646                         GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register"))));
647         if (was_editing){
648                 if (linphone_proxy_config_done(cfg)==-1)
649                         return;
650         }
651         else {
652                 if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) return;
653                 linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg);
654         }
655         g_object_set_data(G_OBJECT(w),"config",NULL);
656         linphone_gtk_show_sip_accounts(GTK_WIDGET(g_object_get_data(G_OBJECT(w),"parameters")));
657         gtk_widget_destroy(w);
658         /* also update the main window's list of identities*/
659         linphone_gtk_load_identities();
660 }
661
662 static LinphoneProxyConfig *linphone_gtk_get_selected_proxy_config(GtkWidget* pb){
663         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(pb,"proxy_list"));
664         GtkTreeSelection *selection=gtk_tree_view_get_selection(v);
665         GtkTreeIter iter;
666         GtkTreeModel *model;
667         if (gtk_tree_selection_get_selected(selection,&model,&iter)){
668                 LinphoneProxyConfig *cfg=NULL;
669                 gtk_tree_model_get(model,&iter,PROXY_CONFIG_REF,&cfg,-1);
670                 return cfg;
671         }
672         return NULL;
673 }
674
675 void linphone_gtk_add_proxy(GtkButton *button){
676         linphone_gtk_show_proxy_config(gtk_widget_get_toplevel(GTK_WIDGET(button)),NULL);
677 }
678
679 void linphone_gtk_remove_proxy(GtkButton *button){
680         LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(
681                         gtk_widget_get_toplevel(GTK_WIDGET(button)));
682         if (cfg){
683                 linphone_core_remove_proxy_config(linphone_gtk_get_core(),cfg);
684                 linphone_gtk_show_sip_accounts(gtk_widget_get_toplevel(GTK_WIDGET(button)));
685                 /* also update the main window's list of identities*/
686                 linphone_gtk_load_identities();
687         }
688 }
689
690 void linphone_gtk_edit_proxy(GtkButton *button){
691         GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(button));
692         LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(pb);
693         if (cfg){
694                 linphone_gtk_show_proxy_config(pb,cfg);
695                 /* also update the main window's list of identities*/
696                 linphone_gtk_load_identities();
697         }
698 }
699
700 typedef struct _LangCodes{
701         const char *code;
702         const char *name;
703 }LangCodes;
704
705 static LangCodes supported_langs[]={
706         {       "C"     ,       N_("English")   },
707         {       "fr"    ,       N_("French")    },
708         {       "sv"    ,       N_("Swedish")   },
709         {       "it"    ,       N_("Italian")   },
710         {       "es"    ,       N_("Spanish")   },
711         {       "pt_BR" ,       N_("Brazilian Portugese")       },
712         {       "pl"    ,       N_("Polish")    },
713         {       "de"    ,       N_("German")    },
714         {       "ru"    ,       N_("Russian")   },
715         {       "ja"    ,       N_("Japanese")  },
716         {       "nl"    ,       N_("Dutch")     },
717         {       "hu"    ,       N_("Hungarian") },
718         {       "cs"    ,       N_("Czech")     },
719         {       "zh_CN" ,       N_("Chinese")   },
720         {       "zh_TW" ,       N_("Traditional Chinese")       },
721         {       "nb_NO" ,       N_("Norwegian") },
722         {       NULL    ,       NULL            }
723 };
724
725 static const char *lang_get_name(const char *code){
726         LangCodes *p=supported_langs;
727         while(p->code!=NULL){
728                 if (strcmp(p->code,code)==0) return p->name;
729                 p++;
730         }
731         return NULL;
732 }
733
734 static gboolean lang_equals(const char *l1, const char *l2){
735         return ((strncmp(l1,l2,5)==0 || strncmp(l1,l2,2)==0));
736 }
737
738 static void linphone_gtk_fill_langs(GtkWidget *pb){
739         GtkWidget *combo=linphone_gtk_get_widget(pb,"lang_combo");
740         char code[10];
741         const char *all_langs="C " LINPHONE_ALL_LANGS;
742         const char *name;
743         int i=0,index=0;
744         const char *cur_lang=getenv("LANG");
745         int cur_lang_index=-1;
746         char text[256]={0};
747         if (cur_lang==NULL) cur_lang="C";
748         /* glade creates a combo box without list model and text renderer,
749         unless we fill it with a dummy text.
750         This dummy text needs to be removed first*/
751         gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
752         while(sscanf(all_langs+i,"%s",code)==1){
753                 i+=strlen(code);
754                 while(all_langs[i]==' ') ++i;
755                 name=lang_get_name(code);
756                 snprintf(text,sizeof(text)-1,"%s : %s",code,name!=NULL ? _(name) : code);
757                 gtk_combo_box_append_text(GTK_COMBO_BOX(combo),text);
758                 if (cur_lang_index==-1 && lang_equals(cur_lang,code))
759                         cur_lang_index=index;
760                 index++;
761         }
762         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),cur_lang_index);
763 }
764
765 void linphone_gtk_lang_changed(GtkComboBox *combo){
766         const char *selected=gtk_combo_box_get_active_text(combo);
767         char code[10];
768         const char *cur_lang=getenv("LANG");
769         if (selected!=NULL){
770                 sscanf(selected,"%s",code);
771                 if (cur_lang==NULL) cur_lang="C";
772                 if (!lang_equals(cur_lang,code)){
773                         GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(combo))),
774                                 GTK_DIALOG_DESTROY_WITH_PARENT,
775                                 GTK_MESSAGE_INFO,
776                                 GTK_BUTTONS_CLOSE,
777                                 "%s",
778                                 (const gchar*)_("You need to restart linphone for the new language selection to take effect."));
779                                 /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
780                         g_signal_connect_swapped (G_OBJECT (dialog), "response",
781                                         G_CALLBACK (gtk_widget_destroy),
782                                         G_OBJECT (dialog));
783                         gtk_widget_show(dialog);
784                         linphone_gtk_set_lang(code);
785                 }
786         }
787 }
788
789 void linphone_gtk_proto_changed(GtkComboBox *combo){
790     GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(combo));
791
792     GtkWidget *proto_port = linphone_gtk_get_widget(pb, "proto_port");
793     // When we change the network protocol, we call update_my_port to move the port number from the old protocol to the new one
794     linphone_gtk_update_my_port(proto_port);
795 }
796
797 static void linphone_gtk_ui_level_adapt(GtkWidget *top) {
798         gboolean ui_advanced;
799         const char *simple_ui = linphone_gtk_get_ui_config("simple_ui", "parameters.codec_tab parameters.transport_frame parameters.ports_frame");
800
801         ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", TRUE);
802         if (ui_advanced) {
803                 linphone_gtk_visibility_set(simple_ui, "parameters", top, TRUE);
804         } else {
805                 linphone_gtk_visibility_set(simple_ui, "parameters", top, FALSE);
806         }
807 }
808
809 void linphone_gtk_ui_level_toggled(GtkWidget *w) {
810         gint ui_advanced;
811         GtkWidget *top;
812
813         top = gtk_widget_get_toplevel(w);
814         ui_advanced = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
815         linphone_gtk_set_ui_config_int("advanced_ui", ui_advanced);
816         linphone_gtk_ui_level_adapt(top);
817 }
818
819 void linphone_gtk_show_parameters(void){
820         GtkWidget *pb=linphone_gtk_create_window("parameters");
821         LinphoneCore *lc=linphone_gtk_get_core();
822         const char **sound_devices=linphone_core_get_sound_devices(lc);
823         const char *tmp;
824         LinphoneAddress *contact;
825         LinphoneFirewallPolicy pol;
826         GtkWidget *codec_list=linphone_gtk_get_widget(pb,"codec_list");
827         int mtu;
828         int ui_advanced;
829         LCSipTransports tr;
830
831         /* NETWORK CONFIG */
832         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")),
833                                 linphone_core_ipv6_enabled(lc));
834         linphone_core_get_sip_transports(lc,&tr);
835
836     if (tr.tcp_port > 0) {
837         gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 1);
838         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
839                                 tr.tcp_port);
840     }
841     else if (tr.tls_port > 0) {
842         gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 2);
843         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
844                                 tr.tls_port);
845     }
846     else {
847         gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 0);
848         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
849                                 tr.udp_port);
850     }
851
852         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"audio_rtp_port")),
853                                 linphone_core_get_audio_port(lc));
854         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"video_rtp_port")),
855                                 linphone_core_get_video_port(lc));
856
857         tmp=linphone_core_get_nat_address(lc);
858         if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"nat_address")),tmp);
859         tmp=linphone_core_get_stun_server(lc);
860         if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"stun_server")),tmp);
861         pol=linphone_core_get_firewall_policy(lc);
862         switch(pol){
863                 case LinphonePolicyNoFirewall:
864                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"no_nat")),TRUE);
865                 break;
866                 case LinphonePolicyUseNatAddress:
867                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_nat_address")),TRUE);
868                 break;
869                 case LinphonePolicyUseStun:
870                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_stun")),TRUE);
871                 break;
872         }
873         mtu=linphone_core_get_mtu(lc);
874         if (mtu<=0){
875                 gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),FALSE);
876                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),1500);
877                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),FALSE);
878         }else{
879                 gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),TRUE);
880                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),mtu);
881                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),TRUE);
882         }
883         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"dtmf_sipinfo")),
884                                         linphone_core_get_use_info_for_dtmf(lc));
885         /* MUTIMEDIA CONFIG */
886         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"playback_device"), sound_devices,
887                                         linphone_core_get_playback_device(lc),CAP_PLAYBACK);
888         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"ring_device"), sound_devices,
889                                         linphone_core_get_ringer_device(lc),CAP_PLAYBACK);
890         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"capture_device"), sound_devices,
891                                         linphone_core_get_capture_device(lc), CAP_CAPTURE);
892         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc),
893                                         linphone_core_get_video_device(lc),CAP_IGNORE);
894         linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size"));
895         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")),
896                                         linphone_core_echo_cancellation_enabled(lc));
897
898         gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(linphone_gtk_get_widget(pb,"ring_chooser")),
899                                         linphone_core_get_ring(lc));
900         /* SIP CONFIG */
901         contact=linphone_core_get_primary_contact_parsed(lc);
902         if (contact){
903                 if (linphone_address_get_display_name(contact)) {
904                         const char *dn=linphone_address_get_display_name(contact);
905                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname")),dn);
906                 }
907                 if (linphone_address_get_username(contact))
908                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")),linphone_address_get_username(contact));
909         }
910         linphone_address_destroy(contact);
911         linphone_gtk_show_sip_accounts(pb);
912         /* CODECS CONFIG */
913         linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list));
914         linphone_gtk_draw_codec_list(GTK_TREE_VIEW(codec_list),0);
915         gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"codec_view")),0);
916         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"download_bw")),
917                                 linphone_core_get_download_bandwidth(lc));
918         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"upload_bw")),
919                                 linphone_core_get_upload_bandwidth(lc));
920
921
922         /* UI CONFIG */
923         linphone_gtk_fill_langs(pb);
924         ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", 1);
925         linphone_gtk_set_ui_config_int("advanced_ui", ui_advanced);
926         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ui_level")),
927                                 ui_advanced);
928         linphone_gtk_ui_level_adapt(pb);
929
930         gtk_widget_show(pb);
931 }