]> sjero.net Git - linphone/blob - gtk/propertybox.c
Fix UI feedbacks :
[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 #include "linphone_tunnel.h"
22
23 typedef enum {
24         CAP_IGNORE,
25         CAP_PLAYBACK,
26         CAP_CAPTURE
27 }DeviceCap;
28
29 static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){
30         const char **p=devices;
31         int i=0,active=0;
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);
36         for(;*p!=NULL;++p){
37                 if ( cap==CAP_IGNORE
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;
42                         i++;
43                 }
44         }
45         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
46 }
47
48 void linphone_gtk_fill_video_sizes(GtkWidget *combo){
49         const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
50         int i,active=0;
51         char vsize_def[256];
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;
61         }
62         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
63 }
64
65 void linphone_gtk_parameters_closed(GtkWidget *button){
66         GtkWidget *pb=gtk_widget_get_toplevel(button);
67         gtk_widget_destroy(pb);
68 }
69
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());
76         char *contact;
77         g_return_if_fail(parsed!=NULL);
78         if (username[0]=='\0') return;
79
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);
86         ms_free(contact);
87         linphone_address_destroy(parsed);
88         linphone_gtk_load_identities();
89 }
90
91 void linphone_gtk_update_my_port(GtkWidget *w){
92     GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(w));
93         LCSipTransports tr;
94         LinphoneCore *lc=linphone_gtk_get_core();
95     GtkComboBox *combo = GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"));
96
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),
101                                 5060);
102         }
103         else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TCP)") == 0) {
104             gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
105                                 5060);
106         }
107         else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TLS)") == 0) {
108             gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
109                                 5061);
110         }
111     }
112
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));
117                 tr.udp_port = 0;
118                 tr.tls_port = 0;
119         }
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));
122         tr.tcp_port = 0;
123                 tr.tls_port = 0;
124         }
125         else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (TLS)") == 0){
126                 tr.udp_port = 0;
127         tr.tcp_port = 0;
128                 tr.tls_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
129         }
130
131         linphone_core_set_sip_transports(lc,&tr);
132 }
133
134 void linphone_gtk_set_propety_entry(GtkWidget *w, gboolean stunServer, gboolean ip){
135         GtkWidget *stun_entry=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"stun_server");
136         GtkWidget *ip_entry=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"nat_address");
137         gtk_widget_set_sensitive(stun_entry,stunServer);
138         gtk_widget_set_sensitive(ip_entry,ip);
139 }
140
141 void linphone_gtk_stun_server_changed(GtkWidget *w){
142         const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w));
143         linphone_core_set_stun_server(linphone_gtk_get_core(),addr);
144 }
145
146 void linphone_gtk_nat_address_changed(GtkWidget *w){
147         const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w));
148         linphone_core_set_nat_address(linphone_gtk_get_core(),addr);
149 }
150
151 void linphone_gtk_ipv6_toggled(GtkWidget *w){
152         linphone_core_enable_ipv6(linphone_gtk_get_core(),
153                                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
154 }
155
156 void linphone_gtk_min_audio_port_changed(GtkWidget *w){
157         GtkWidget *mw = linphone_gtk_get_main_window();
158         GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
159         GtkSpinButton *min_button = GTK_SPIN_BUTTON(w);
160         GtkSpinButton *max_button = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_max_rtp_port"));
161         gboolean fixed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "fixed_audio_port")));
162
163         if (fixed) {
164                 linphone_core_set_audio_port(linphone_gtk_get_core(), (gint) gtk_spin_button_get_value(min_button));
165                 gtk_spin_button_set_value(max_button, gtk_spin_button_get_value(min_button));
166         } else {
167                 gint min_port = gtk_spin_button_get_value(min_button);
168                 gint max_port = gtk_spin_button_get_value(max_button);
169                 if (min_port > max_port) {
170                         gtk_spin_button_set_value(max_button, min_port);
171                         max_port = min_port;
172                 }
173                 linphone_core_set_audio_port_range(linphone_gtk_get_core(), min_port, max_port);
174         }
175 }
176
177 void linphone_gtk_max_audio_port_changed(GtkWidget *w){
178         GtkWidget *mw = linphone_gtk_get_main_window();
179         GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
180         GtkSpinButton *min_button = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_min_rtp_port"));
181         GtkSpinButton *max_button = GTK_SPIN_BUTTON(w);
182         gint min_port = gtk_spin_button_get_value(min_button);
183         gint max_port = gtk_spin_button_get_value(max_button);
184         if (max_port < min_port) {
185                 gtk_spin_button_set_value(min_button, max_port);
186                 min_port = max_port;
187         }
188         linphone_core_set_audio_port_range(linphone_gtk_get_core(), min_port, max_port);
189 }
190
191 void linphone_gtk_min_video_port_changed(GtkWidget *w){
192         GtkWidget *mw = linphone_gtk_get_main_window();
193         GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
194         GtkSpinButton *min_button = GTK_SPIN_BUTTON(w);
195         GtkSpinButton *max_button = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "video_max_rtp_port"));
196         gboolean fixed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "fixed_video_port")));
197
198         if (fixed) {
199                 linphone_core_set_video_port(linphone_gtk_get_core(), (gint) gtk_spin_button_get_value(min_button));
200                 gtk_spin_button_set_value(max_button, gtk_spin_button_get_value(min_button));
201         } else {
202                 gint min_port = gtk_spin_button_get_value(min_button);
203                 gint max_port = gtk_spin_button_get_value(max_button);
204                 if (min_port > max_port) {
205                         gtk_spin_button_set_value(max_button, min_port);
206                         max_port = min_port;
207                 }
208                 linphone_core_set_video_port_range(linphone_gtk_get_core(), min_port, max_port);
209         }
210 }
211
212 void linphone_gtk_max_video_port_changed(GtkWidget *w){
213         GtkWidget *mw = linphone_gtk_get_main_window();
214         GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
215         GtkSpinButton *min_button = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "video_min_rtp_port"));
216         GtkSpinButton *max_button = GTK_SPIN_BUTTON(w);
217         gint min_port = gtk_spin_button_get_value(min_button);
218         gint max_port = gtk_spin_button_get_value(max_button);
219         if (max_port < min_port) {
220                 gtk_spin_button_set_value(min_button, max_port);
221                 min_port = max_port;
222         }
223         linphone_core_set_video_port_range(linphone_gtk_get_core(), min_port, max_port);
224 }
225
226 void linphone_gtk_no_firewall_toggled(GtkWidget *w){
227         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
228                 linphone_gtk_set_propety_entry(w,FALSE,FALSE);
229                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyNoFirewall);
230         }
231 }
232
233 void linphone_gtk_use_nat_address_toggled(GtkWidget *w){
234         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
235                 linphone_gtk_set_propety_entry(w,FALSE,TRUE);
236                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseNatAddress);
237         }
238 }
239
240 void linphone_gtk_use_stun_toggled(GtkWidget *w){
241         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
242                 linphone_gtk_set_propety_entry(w,TRUE,FALSE);
243                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseStun);
244         }
245 }
246
247 void linphone_gtk_use_ice_toggled(GtkWidget *w){
248         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
249                 linphone_gtk_set_propety_entry(w,TRUE,FALSE);
250                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseIce);
251         }
252 }
253
254 void linphone_gtk_use_upnp_toggled(GtkWidget *w){
255         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
256                 linphone_gtk_set_propety_entry(w,FALSE,FALSE);
257                 linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseUpnp);
258         }
259 }
260
261 void linphone_gtk_mtu_changed(GtkWidget *w){
262         if (GTK_WIDGET_SENSITIVE(w))
263                 linphone_core_set_mtu(linphone_gtk_get_core(),gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
264 }
265
266 void linphone_gtk_use_sip_info_dtmf_toggled(GtkWidget *w){
267         linphone_core_set_use_info_for_dtmf(linphone_gtk_get_core(),
268                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
269 }
270
271 void linphone_gtk_mtu_set(GtkWidget *w){
272         GtkWidget *mtu=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"mtu");
273         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
274                 gtk_widget_set_sensitive(mtu,TRUE);
275                 linphone_gtk_mtu_changed(mtu);
276         }else{
277                 gtk_widget_set_sensitive(mtu,FALSE);
278                 linphone_core_set_mtu(linphone_gtk_get_core(),0);
279         }
280 }
281
282 void linphone_gtk_playback_device_changed(GtkWidget *w){
283         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
284         linphone_core_set_playback_device(linphone_gtk_get_core(),sel);
285         g_free(sel);
286 }
287
288 void linphone_gtk_capture_device_changed(GtkWidget *w){
289         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
290         linphone_core_set_capture_device(linphone_gtk_get_core(),sel);
291         g_free(sel);
292 }
293
294 void linphone_gtk_ring_device_changed(GtkWidget *w){
295         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
296         linphone_core_set_ringer_device(linphone_gtk_get_core(),sel);
297         g_free(sel);
298 }
299
300 void linphone_gtk_alsa_special_device_changed(GtkWidget *w){
301         /*
302         const gchar *dev=gtk_entry_get_text(GTK_ENTRY(w));
303         ...*/
304 }
305
306 void linphone_gtk_cam_changed(GtkWidget *w){
307         gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
308         linphone_core_set_video_device(linphone_gtk_get_core(),sel);
309         g_free(sel);
310 }
311
312 void linphone_gtk_video_size_changed(GtkWidget *w){
313         int sel=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
314         const MSVideoSizeDef *defs=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());
315         if (sel<0) return;
316         linphone_core_set_preferred_video_size(linphone_gtk_get_core(),
317                                         defs[sel].vsize);
318 }
319
320 void linphone_gtk_ring_file_set(GtkWidget *w){
321         gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w));
322         linphone_core_set_ring(linphone_gtk_get_core(),file);
323         g_free(file);
324 }
325
326 static void linphone_gtk_end_of_ring(LinphoneCore *lc, void *user_data){
327         gtk_widget_set_sensitive((GtkWidget*)user_data,TRUE);
328 }
329
330 void linphone_gtk_play_ring_file(GtkWidget *w){
331         if (linphone_core_preview_ring(linphone_gtk_get_core(),
332                                 linphone_core_get_ring(linphone_gtk_get_core()),
333                                 linphone_gtk_end_of_ring,
334                                 w)==0){
335                 gtk_widget_set_sensitive(w,FALSE);
336         }
337 }
338
339 void linphone_gtk_echo_cancelation_toggled(GtkWidget *w){
340         linphone_core_enable_echo_cancellation(linphone_gtk_get_core(),
341                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
342 }
343
344 enum {
345         CODEC_NAME,
346         CODEC_RATE,
347         CODEC_BITRATE,
348         CODEC_STATUS,
349         CODEC_PARAMS,
350         CODEC_PRIVDATA,
351         CODEC_COLOR,
352         CODEC_INFO,
353         CODEC_NCOLUMNS
354 };
355
356 static void fmtp_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer userdata){
357         GtkListStore *store=(GtkListStore*)userdata;
358         GtkTreeIter iter;
359         if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),&iter,path)){
360                 PayloadType *pt;
361                 gtk_list_store_set(store,&iter,CODEC_PARAMS,new_text,-1);
362                 gtk_tree_model_get(GTK_TREE_MODEL(store),&iter,CODEC_PRIVDATA,&pt,-1);
363                 payload_type_set_recv_fmtp(pt,new_text);
364         }
365 }
366
367 static void linphone_gtk_init_codec_list(GtkTreeView *listview){
368         GtkCellRenderer *renderer;
369         GtkTreeViewColumn *column;
370         GtkTreeSelection *select;
371
372         GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING,G_TYPE_INT,
373                                                         G_TYPE_FLOAT,
374                                                         G_TYPE_STRING,
375                                                         G_TYPE_STRING,
376                                                         G_TYPE_POINTER,
377                                                         G_TYPE_STRING,
378                                                         G_TYPE_STRING);
379
380         gtk_tree_view_set_model(listview,GTK_TREE_MODEL(store));
381         g_object_unref(G_OBJECT(store));
382
383         renderer = gtk_cell_renderer_text_new ();
384         column = gtk_tree_view_column_new_with_attributes (_("Name"),
385                                                    renderer,
386                                                    "text", CODEC_NAME,
387                                                 "foreground",CODEC_COLOR,
388                                                    NULL);
389         gtk_tree_view_append_column (listview, column);
390         column = gtk_tree_view_column_new_with_attributes (_("Rate (Hz)"),
391                                                    renderer,
392                                                    "text", CODEC_RATE,
393                                                 "foreground",CODEC_COLOR,
394                                                    NULL);
395         gtk_tree_view_append_column (listview, column);
396         column = gtk_tree_view_column_new_with_attributes (_("Status"),
397                                                    renderer,
398                                                    "text", CODEC_STATUS,
399                                                 "foreground",CODEC_COLOR,
400                                                    NULL);
401         gtk_tree_view_append_column (listview, column);
402         column = gtk_tree_view_column_new_with_attributes (_("Min bitrate (kbit/s)"),
403                                                    renderer,
404                                                    "text", CODEC_BITRATE,
405                                                 "foreground",CODEC_COLOR,
406                                                    NULL);
407         gtk_tree_view_append_column (listview, column);
408         renderer = gtk_cell_renderer_text_new ();
409         column = gtk_tree_view_column_new_with_attributes (_("Parameters"),
410                                                    renderer,
411                                                    "text", CODEC_PARAMS,
412                                                 "foreground",CODEC_COLOR,
413                                         "editable",TRUE,
414                                                    NULL);
415         g_signal_connect(G_OBJECT(renderer),"edited",G_CALLBACK(fmtp_edited),store);
416         gtk_tree_view_append_column (listview, column);
417         /* Setup the selection handler */
418         select = gtk_tree_view_get_selection (listview);
419         gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
420 }
421
422
423 const char *get_codec_color(LinphoneCore *lc, PayloadType *pt){
424         const gchar *color;
425         if (linphone_core_check_payload_type_usability(lc,pt)) color="blue";
426                 else color="red";
427         if (!linphone_core_payload_type_enabled(lc,pt)) {
428                 color="grey";
429         }
430         return color;
431 }
432
433 static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codeclist)
434 {
435         const MSList *elem;
436         GtkTreeIter iter;
437         GtkListStore *store=GTK_LIST_STORE(gtk_tree_view_get_model(listview));
438         GtkTreeSelection *selection;
439
440         gtk_list_store_clear(store);
441
442         for(elem=codeclist; elem!=NULL; elem=elem->next){
443                 gchar *status;
444                 gint rate;
445                 gfloat bitrate;
446                 const gchar *color;
447                 const char *params="";
448
449                 struct _PayloadType *pt=(struct _PayloadType *)elem->data;
450
451                 color=get_codec_color(linphone_gtk_get_core(),pt);
452                 if (linphone_core_payload_type_enabled(linphone_gtk_get_core(),pt)) status=_("Enabled");
453                 else {
454                         status=_("Disabled");
455                 }
456                 /* get an iterator */
457                 gtk_list_store_append(store,&iter);
458                 bitrate=payload_type_get_bitrate(pt)/1000.0;
459                 rate=payload_type_get_rate(pt);
460                 if (pt->recv_fmtp!=NULL) params=pt->recv_fmtp;
461                 gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt),
462                                         CODEC_RATE,rate,
463                                         CODEC_BITRATE,bitrate,
464                                         CODEC_STATUS,status,
465                                         CODEC_PARAMS,params,
466                                         CODEC_PRIVDATA,(gpointer)pt,
467                                         CODEC_COLOR,(gpointer)color,
468                                         CODEC_INFO,(gpointer)linphone_core_get_payload_type_description(linphone_gtk_get_core(),pt),
469                                         -1);
470         }
471
472
473
474         /* Setup the selection handler */
475         selection = gtk_tree_view_get_selection (listview);
476         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
477         //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces));
478 #if GTK_CHECK_VERSION(2,12,0)
479         gtk_tree_view_set_tooltip_column(listview,CODEC_INFO);
480 #endif
481 }
482
483 static void linphone_gtk_check_codec_bandwidth(GtkTreeView *v){
484         GtkTreeIter iter;
485         GtkTreeModel *model;
486         model=gtk_tree_view_get_model(v);
487         g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter));
488         do{
489                 PayloadType *pt=NULL;
490
491                 gfloat bitrate;
492                 gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1);
493
494                 bitrate=payload_type_get_bitrate(pt)/1000.0;
495                 gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR, (gpointer)get_codec_color(linphone_gtk_get_core(),pt),
496                                         CODEC_BITRATE, bitrate,-1);
497         }while(gtk_tree_model_iter_next(model,&iter));
498 }
499
500 static void linphone_gtk_select_codec(GtkTreeView *v, PayloadType *ref){
501         GtkTreeIter iter;
502         GtkTreeModel *model;
503         GtkTreeSelection *selection;
504         selection=gtk_tree_view_get_selection(v);
505         model=gtk_tree_view_get_model(v);
506         g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter));
507         do{
508                 PayloadType *pt=NULL;
509                 gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1);
510                 if (pt==ref){
511                         gtk_tree_selection_select_iter(selection,&iter);
512                 }
513
514         }while(gtk_tree_model_iter_next(model,&iter));
515 }
516
517 static void linphone_gtk_draw_codec_list(GtkTreeView *v, int type){ /* 0=audio, 1=video*/
518         const MSList *list;
519         if (type==0) list=linphone_core_get_audio_codecs(linphone_gtk_get_core());
520         else list=linphone_core_get_video_codecs(linphone_gtk_get_core());
521         linphone_gtk_show_codecs(v,list);
522 }
523
524 void linphone_gtk_codec_view_changed(GtkWidget *w){
525         GtkWidget *listview=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list");
526         int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
527         linphone_gtk_draw_codec_list(GTK_TREE_VIEW(listview),active);
528 }
529
530 void linphone_gtk_download_bw_changed(GtkWidget *w){
531         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"));
532         linphone_core_set_download_bandwidth(linphone_gtk_get_core(),
533                                 (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
534         linphone_gtk_check_codec_bandwidth(v);
535 }
536
537 void linphone_gtk_upload_bw_changed(GtkWidget *w){
538         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"));
539         linphone_core_set_upload_bandwidth(linphone_gtk_get_core(),
540                                 (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
541         linphone_gtk_check_codec_bandwidth(v);
542 }
543
544 void linphone_gtk_adaptive_rate_control_toggled(GtkToggleButton *button){
545         gboolean active=gtk_toggle_button_get_active(button);
546         linphone_core_enable_adaptive_rate_control(linphone_gtk_get_core(),active);
547 }
548
549 static void linphone_gtk_codec_move(GtkWidget *button, int dir){
550         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list"));
551         GtkTreeSelection *sel=gtk_tree_view_get_selection(v);
552         GtkTreeModel *mod;
553         GtkTreeIter iter;
554         PayloadType *pt=NULL;
555         LinphoneCore *lc=linphone_gtk_get_core();
556         if (gtk_tree_selection_get_selected(sel,&mod,&iter)){
557                 MSList *sel_elem,*before;
558                 MSList *codec_list;
559                 gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1);
560                 if (pt->type==PAYLOAD_VIDEO)
561                         codec_list=ms_list_copy(linphone_core_get_video_codecs(lc));
562                 else codec_list=ms_list_copy(linphone_core_get_audio_codecs(lc));
563                 sel_elem=ms_list_find(codec_list,pt);
564                 if (dir>0) {
565                         if (sel_elem->prev) before=sel_elem->prev;
566                         else before=sel_elem;
567                         codec_list=ms_list_insert(codec_list,before,pt);
568                 }
569                 else{
570                         if (sel_elem->next) before=sel_elem->next->next;
571                         else before=sel_elem;
572                         codec_list=ms_list_insert(codec_list,before,pt);
573                 }
574                 codec_list=ms_list_remove_link(codec_list,sel_elem);
575                 if (pt->type==PAYLOAD_VIDEO)
576                         linphone_core_set_video_codecs(lc,codec_list);
577                 else linphone_core_set_audio_codecs(lc,codec_list);
578                 linphone_gtk_show_codecs(v,codec_list);
579                 linphone_gtk_select_codec(v,pt);
580         }
581 }
582
583 static void linphone_gtk_codec_set_enable(GtkWidget *button, gboolean enabled){
584         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list"));
585         GtkTreeSelection *sel=gtk_tree_view_get_selection(v);
586         GtkTreeModel *mod;
587         GtkListStore *store;
588         GtkTreeIter iter;
589         PayloadType *pt=NULL;
590
591         if (gtk_tree_selection_get_selected(sel,&mod,&iter)){
592                 store=GTK_LIST_STORE(mod);
593                 gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1);
594                 linphone_core_enable_payload_type(linphone_gtk_get_core(),pt,enabled);
595                 gtk_list_store_set(store,&iter,CODEC_STATUS, enabled ? _("Enabled") : _("Disabled"),
596                                    CODEC_COLOR,(gpointer)get_codec_color(linphone_gtk_get_core(),pt), -1);
597         }
598 }
599
600 void linphone_gtk_codec_up(GtkWidget *button){
601         linphone_gtk_codec_move(button,+1);
602 }
603
604 void linphone_gtk_codec_down(GtkWidget *button){
605         linphone_gtk_codec_move(button,-1);
606 }
607
608 void linphone_gtk_codec_enable(GtkWidget *button){
609         linphone_gtk_codec_set_enable(button,TRUE);
610 }
611
612 void linphone_gtk_codec_disable(GtkWidget *button){
613         linphone_gtk_codec_set_enable(button,FALSE);
614 }
615
616 void linphone_gtk_clear_passwords(GtkWidget *button){
617         linphone_core_clear_all_auth_info(linphone_gtk_get_core());
618 }
619
620 enum{
621         PROXY_CONFIG_IDENTITY,
622         PROXY_CONFIG_REF,
623         PROXY_CONFIG_NCOL
624 };
625
626 void linphone_gtk_show_sip_accounts(GtkWidget *w){
627         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(w,"proxy_list"));
628         GtkTreeModel *model=gtk_tree_view_get_model(v);
629         GtkListStore *store;
630         GtkTreeSelection *select;
631         const MSList *elem;
632         if (!model){
633                 GtkCellRenderer *renderer;
634                 GtkTreeViewColumn *column;
635                 /* create the proxy list */
636                 store = gtk_list_store_new (PROXY_CONFIG_NCOL, G_TYPE_STRING, G_TYPE_POINTER);
637
638                 gtk_tree_view_set_model(v,GTK_TREE_MODEL(store));
639                 g_object_unref(G_OBJECT(store));
640                 renderer = gtk_cell_renderer_text_new ();
641                 column = gtk_tree_view_column_new_with_attributes (_("Account"),
642                                                         renderer,
643                                                         "text", PROXY_CONFIG_IDENTITY,
644                                                         NULL);
645                 gtk_tree_view_append_column (v, column);
646
647                 select = gtk_tree_view_get_selection (v);
648                 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
649                 model=GTK_TREE_MODEL(store);
650         }else {
651                 store=GTK_LIST_STORE(model);
652         }
653         gtk_list_store_clear(store);
654         for(elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());elem!=NULL;elem=ms_list_next(elem)){
655                 LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
656                 GtkTreeIter iter;
657                 gtk_list_store_append(store,&iter);
658                 gtk_list_store_set(store,&iter,PROXY_CONFIG_IDENTITY,linphone_proxy_config_get_identity(cfg),
659                                         PROXY_CONFIG_REF,cfg,-1);
660         }
661 }
662
663 static void linphone_gtk_proxy_closed(GtkWidget *w){
664         LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
665         if (cfg){
666                 linphone_proxy_config_done(cfg);
667         }
668 }
669
670 void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){
671         GtkWidget *w=linphone_gtk_create_window("sip_account");
672         const char *tmp;
673         if (cfg){
674                 linphone_proxy_config_edit(cfg);
675                 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")),
676                         linphone_proxy_config_get_identity(cfg));
677                 gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")),
678                         linphone_proxy_config_get_addr(cfg));
679                 tmp=linphone_proxy_config_get_route(cfg);
680                 if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")),tmp);
681                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")),
682                         linphone_proxy_config_get_expires(cfg));
683                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")),
684                         linphone_proxy_config_register_enabled(cfg));
685                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")),
686                         linphone_proxy_config_publish_enabled(cfg));
687         }
688         g_object_set_data(G_OBJECT(w),"config",(gpointer)cfg);
689         g_object_set_data(G_OBJECT(w),"parameters",(gpointer)pb);
690         g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_proxy_closed,w);
691         gtk_widget_show(w);
692 }
693
694 void linphone_gtk_proxy_cancel(GtkButton *button){
695         GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
696         gtk_widget_destroy(w);
697 }
698
699 void linphone_gtk_proxy_ok(GtkButton *button){
700         GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
701         LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
702         gboolean was_editing=TRUE;
703         if (!cfg){
704                 was_editing=FALSE;
705                 cfg=linphone_proxy_config_new();
706         }
707         linphone_proxy_config_set_identity(cfg,
708                 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity"))));
709         linphone_proxy_config_set_server_addr(cfg,
710                 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy"))));
711         linphone_proxy_config_set_route(cfg,
712                 gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route"))));
713         linphone_proxy_config_expires(cfg,
714                 (int)gtk_spin_button_get_value(
715                         GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod"))));
716         linphone_proxy_config_enable_publish(cfg,
717                 gtk_toggle_button_get_active(
718                         GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish"))));
719         linphone_proxy_config_enable_register(cfg,
720                 gtk_toggle_button_get_active(
721                         GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register"))));
722         if (was_editing){
723                 if (linphone_proxy_config_done(cfg)==-1)
724                         return;
725         }
726         else {
727                 if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) return;
728                 linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg);
729         }
730         g_object_set_data(G_OBJECT(w),"config",NULL);
731         linphone_gtk_show_sip_accounts(GTK_WIDGET(g_object_get_data(G_OBJECT(w),"parameters")));
732         gtk_widget_destroy(w);
733         /* also update the main window's list of identities*/
734         linphone_gtk_load_identities();
735 }
736
737 static LinphoneProxyConfig *linphone_gtk_get_selected_proxy_config(GtkWidget* pb){
738         GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(pb,"proxy_list"));
739         GtkTreeSelection *selection=gtk_tree_view_get_selection(v);
740         GtkTreeIter iter;
741         GtkTreeModel *model;
742         if (gtk_tree_selection_get_selected(selection,&model,&iter)){
743                 LinphoneProxyConfig *cfg=NULL;
744                 gtk_tree_model_get(model,&iter,PROXY_CONFIG_REF,&cfg,-1);
745                 return cfg;
746         }
747         return NULL;
748 }
749
750 void linphone_gtk_add_proxy(GtkButton *button){
751         linphone_gtk_show_proxy_config(gtk_widget_get_toplevel(GTK_WIDGET(button)),NULL);
752 }
753
754 void linphone_gtk_remove_proxy(GtkButton *button){
755         LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(
756                         gtk_widget_get_toplevel(GTK_WIDGET(button)));
757         if (cfg){
758                 linphone_core_remove_proxy_config(linphone_gtk_get_core(),cfg);
759                 linphone_gtk_show_sip_accounts(gtk_widget_get_toplevel(GTK_WIDGET(button)));
760                 /* also update the main window's list of identities*/
761                 linphone_gtk_load_identities();
762         }
763 }
764
765 void linphone_gtk_edit_proxy(GtkButton *button){
766         GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(button));
767         LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(pb);
768         if (cfg){
769                 linphone_gtk_show_proxy_config(pb,cfg);
770                 /* also update the main window's list of identities*/
771                 linphone_gtk_load_identities();
772         }
773 }
774
775 typedef struct _LangCodes{
776         const char *code;
777         const char *name;
778 }LangCodes;
779
780 static LangCodes supported_langs[]={
781         {       "C"     ,       N_("English")   },
782         {       "fr"    ,       N_("French")    },
783         {       "sv"    ,       N_("Swedish")   },
784         {       "it"    ,       N_("Italian")   },
785         {       "es"    ,       N_("Spanish")   },
786         {       "pt_BR" ,       N_("Brazilian Portugese")       },
787         {       "pl"    ,       N_("Polish")    },
788         {       "de"    ,       N_("German")    },
789         {       "ru"    ,       N_("Russian")   },
790         {       "ja"    ,       N_("Japanese")  },
791         {       "nl"    ,       N_("Dutch")     },
792         {       "hu"    ,       N_("Hungarian") },
793         {       "cs"    ,       N_("Czech")     },
794         {       "zh_CN" ,       N_("Chinese")   },
795         {       "zh_TW" ,       N_("Traditional Chinese")       },
796         {       "nb_NO" ,       N_("Norwegian") },
797         {       "he"    ,       N_("Hebrew")    },
798         {       "sr"    ,       N_("Serbian")   },
799         {       NULL    ,       NULL            }
800 };
801
802 static const char *lang_get_name(const char *code){
803         LangCodes *p=supported_langs;
804         while(p->code!=NULL){
805                 if (strcmp(p->code,code)==0) return p->name;
806                 p++;
807         }
808         return NULL;
809 }
810
811 static gboolean lang_equals(const char *l1, const char *l2){
812         return ((strncmp(l1,l2,5)==0 || strncmp(l1,l2,2)==0));
813 }
814
815 static void linphone_gtk_fill_langs(GtkWidget *pb){
816         GtkWidget *combo=linphone_gtk_get_widget(pb,"lang_combo");
817         char code[10];
818         const char *all_langs="C " LINPHONE_ALL_LANGS;
819         const char *name;
820         int i=0,index=0;
821         const char *cur_lang;
822         #if defined(WIN32) || defined(__APPLE__)
823                 cur_lang=getenv("LANG");
824         #else
825                 cur_lang=getenv("LANGUAGE");
826         #endif
827         int cur_lang_index=-1;
828         char text[256]={0};
829         if (cur_lang==NULL) cur_lang="C";
830         /* glade creates a combo box without list model and text renderer,
831         unless we fill it with a dummy text.
832         This dummy text needs to be removed first*/
833         gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
834         while(sscanf(all_langs+i,"%s",code)==1){
835                 i+=strlen(code);
836                 while(all_langs[i]==' ') ++i;
837                 name=lang_get_name(code);
838                 snprintf(text,sizeof(text)-1,"%s : %s",code,name!=NULL ? _(name) : code);
839                 gtk_combo_box_append_text(GTK_COMBO_BOX(combo),text);
840                 if (cur_lang_index==-1 && lang_equals(cur_lang,code))
841                         cur_lang_index=index;
842                 index++;
843         }
844         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),cur_lang_index);
845 }
846
847 void linphone_gtk_lang_changed(GtkComboBox *combo){
848         const char *selected=gtk_combo_box_get_active_text(combo);
849         char code[10];
850         const char *cur_lang;
851         #if defined(WIN32) || defined(__APPLE__)
852                 cur_lang=getenv("LANG");
853         #else
854                 cur_lang=getenv("LANGUAGE");
855         #endif
856         if (selected!=NULL){
857                 sscanf(selected,"%s",code);
858                 if (cur_lang==NULL) cur_lang="C";
859                 if (!lang_equals(cur_lang,code)){
860                         GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(combo))),
861                                 GTK_DIALOG_DESTROY_WITH_PARENT,
862                                 GTK_MESSAGE_INFO,
863                                 GTK_BUTTONS_CLOSE,
864                                 "%s",
865                                 (const gchar*)_("You need to restart linphone for the new language selection to take effect."));
866                                 /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
867                         g_signal_connect_swapped (G_OBJECT (dialog), "response",
868                                         G_CALLBACK (gtk_widget_destroy),
869                                         G_OBJECT (dialog));
870                         gtk_widget_show(dialog);
871                         linphone_gtk_set_lang(code);
872                 }
873         }
874 }
875
876 void linphone_gtk_proto_changed(GtkComboBox *combo){
877     GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(combo));
878
879     GtkWidget *proto_port = linphone_gtk_get_widget(pb, "proto_port");
880     // When we change the network protocol, we call update_my_port to move the port number from the old protocol to the new one
881     linphone_gtk_update_my_port(proto_port);
882 }
883
884 static void linphone_gtk_ui_level_adapt(GtkWidget *top) {
885         gboolean ui_advanced;
886         const char *simple_ui = linphone_gtk_get_ui_config("simple_ui", "parameters.codec_tab parameters.transport_frame parameters.ports_frame");
887
888         ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", TRUE);
889         if (ui_advanced) {
890                 linphone_gtk_visibility_set(simple_ui, "parameters", top, TRUE);
891         } else {
892                 linphone_gtk_visibility_set(simple_ui, "parameters", top, FALSE);
893         }
894 }
895
896 void linphone_gtk_ui_level_toggled(GtkWidget *w) {
897         gint ui_advanced;
898         GtkWidget *top;
899
900         top = gtk_widget_get_toplevel(w);
901         ui_advanced = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
902         linphone_gtk_set_ui_config_int("advanced_ui", ui_advanced);
903         linphone_gtk_ui_level_adapt(top);
904 }
905
906 static void linphone_gtk_set_media_encryption_mandatory_sensitive(GtkWidget *propbox, gboolean val){
907         GtkWidget *w=linphone_gtk_get_widget(propbox,"media_encryption_mandatory");
908         gtk_widget_set_sensitive(w,val);
909 }
910
911 static void linphone_gtk_media_encryption_changed(GtkWidget *combo){
912         char *selected=gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
913         LinphoneCore *lc=linphone_gtk_get_core();
914         GtkWidget *toplevel=gtk_widget_get_toplevel(combo);
915         if (selected!=NULL){
916                 if (strcasecmp(selected,"SRTP")==0){
917                         linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionSRTP);
918                         linphone_gtk_set_media_encryption_mandatory_sensitive(toplevel,TRUE);
919                 }else if (strcasecmp(selected,"ZRTP")==0){
920                         linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionZRTP);
921                         linphone_gtk_set_media_encryption_mandatory_sensitive(toplevel,FALSE);
922                 }
923                 else {
924                         linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionNone);
925                         linphone_gtk_set_media_encryption_mandatory_sensitive(toplevel,FALSE);
926                 }
927                 g_free(selected);
928         }else g_warning("gtk_combo_box_get_active_text() returned NULL");
929 }
930
931 void linphone_gtk_set_media_encryption_mandatory(GtkWidget *button){
932         linphone_core_set_media_encryption_mandatory(linphone_gtk_get_core(),gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));
933 }
934
935 static void linphone_gtk_show_media_encryption(GtkWidget *pb){
936         LinphoneCore *lc=linphone_gtk_get_core();
937         GtkWidget *combo=linphone_gtk_get_widget(pb,"media_encryption_combo");
938         bool_t no_enc=TRUE;
939         int srtp_id=-1,zrtp_id=-1;
940         GtkTreeModel *model;
941         GtkListStore *store;
942         GtkTreeIter iter;
943         GtkCellRenderer *renderer=gtk_cell_renderer_text_new();
944         
945         model=GTK_TREE_MODEL((store=gtk_list_store_new(1,G_TYPE_STRING)));
946         gtk_combo_box_set_model(GTK_COMBO_BOX(combo),model);
947         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo),renderer,TRUE);
948         gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo),renderer,"text",0,NULL);
949         
950         gtk_list_store_append(store,&iter);
951         gtk_list_store_set(store,&iter,0,_("None"),-1);
952         
953         if (linphone_core_media_encryption_supported(lc,LinphoneMediaEncryptionSRTP)){
954                 gtk_list_store_append(store,&iter);
955                 gtk_list_store_set(store,&iter,0,_("SRTP"),-1);
956                 srtp_id=1;
957                 no_enc=FALSE;
958         }
959         if (linphone_core_media_encryption_supported(lc,LinphoneMediaEncryptionZRTP)){
960                 gtk_list_store_append(store,&iter);
961                 gtk_list_store_set(store,&iter,0,_("ZRTP"),-1);
962                 no_enc=FALSE;
963                 if (srtp_id!=-1) zrtp_id=2;
964                 else zrtp_id=1;
965         }
966         if (no_enc){
967                 /*hide this setting*/
968                 gtk_widget_hide(combo);
969                 gtk_widget_hide(linphone_gtk_get_widget(pb,"media_encryption_label"));
970                 gtk_widget_hide(linphone_gtk_get_widget(pb,"media_encryption_mandatory"));
971         }else{
972                 LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc);
973                 switch(menc){
974                         case LinphoneMediaEncryptionNone:
975                                 gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
976                                 linphone_gtk_set_media_encryption_mandatory_sensitive(pb,FALSE);
977                         break;
978                         case LinphoneMediaEncryptionSRTP:
979                                 if (srtp_id!=-1) {
980                                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),srtp_id);
981                                         linphone_gtk_set_media_encryption_mandatory_sensitive(pb,TRUE);
982                                 }
983                         break;
984                         case LinphoneMediaEncryptionZRTP:
985                                 if (zrtp_id!=-1) {
986                                         gtk_combo_box_set_active(GTK_COMBO_BOX(combo),zrtp_id);
987                                         linphone_gtk_set_media_encryption_mandatory_sensitive(pb,FALSE);
988                                 }
989                         break;
990                 }
991                 g_signal_connect(G_OBJECT(combo),"changed",(GCallback)linphone_gtk_media_encryption_changed,NULL);
992         }
993         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"media_encryption_mandatory")),
994                                      linphone_core_is_media_encryption_mandatory(lc));
995         g_object_unref(G_OBJECT(model));
996 }
997
998 void linphone_gtk_parameters_destroyed(GtkWidget *pb){
999         GtkWidget *mw=linphone_gtk_get_main_window();
1000         ms_error("linphone_gtk_paramters_destroyed");
1001         g_object_set_data(G_OBJECT(mw),"parameters",NULL);
1002 }
1003
1004 void linphone_gtk_fill_soundcards(GtkWidget *pb){
1005         LinphoneCore *lc=linphone_gtk_get_core();
1006         const char **sound_devices=linphone_core_get_sound_devices(lc);
1007         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"playback_device"), sound_devices,
1008                                         linphone_core_get_playback_device(lc),CAP_PLAYBACK);
1009         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"ring_device"), sound_devices,
1010                                         linphone_core_get_ringer_device(lc),CAP_PLAYBACK);
1011         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"capture_device"), sound_devices,
1012                                         linphone_core_get_capture_device(lc), CAP_CAPTURE);
1013 }
1014
1015 void linphone_gtk_fill_webcams(GtkWidget *pb){
1016         LinphoneCore *lc=linphone_gtk_get_core();
1017         linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc),
1018                                         linphone_core_get_video_device(lc),CAP_IGNORE);
1019 }
1020
1021 void linphone_gtk_show_parameters(void){
1022         GtkWidget *mw=linphone_gtk_get_main_window();
1023         GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters");
1024         LinphoneCore *lc=linphone_gtk_get_core();
1025         const char *tmp;
1026         LinphoneAddress *contact;
1027         LinphoneFirewallPolicy pol;
1028         GtkWidget *codec_list;
1029         int mtu;
1030         int ui_advanced;
1031         LCSipTransports tr;
1032         int min_port = 0, max_port = 0;
1033
1034         if (pb==NULL) {
1035                 pb=linphone_gtk_create_window("parameters");
1036                 g_object_set_data(G_OBJECT(mw),"parameters",pb);
1037         }else {
1038                 gtk_widget_show(pb);
1039                 return;
1040         }
1041         codec_list=linphone_gtk_get_widget(pb,"codec_list");
1042
1043         /* NETWORK CONFIG */
1044         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")),
1045                                 linphone_core_ipv6_enabled(lc));
1046         linphone_core_get_sip_transports(lc,&tr);
1047
1048         if (tr.tcp_port > 0) {
1049                 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 1);
1050                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
1051                                 tr.tcp_port);
1052         }
1053         else if (tr.tls_port > 0) {
1054                 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 2);
1055                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
1056                                 tr.tls_port);
1057         }
1058         else {
1059                 gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 0);
1060                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")),
1061                                 tr.udp_port);
1062         }
1063
1064         linphone_core_get_audio_port_range(lc, &min_port, &max_port);
1065         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_min_rtp_port")), min_port);
1066         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_max_rtp_port")), max_port);
1067         if (min_port == max_port) {
1068                 gtk_widget_set_sensitive(GTK_WIDGET(linphone_gtk_get_widget(pb, "audio_max_rtp_port")), FALSE);
1069                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "fixed_audio_port")), TRUE);
1070         }
1071         linphone_core_get_video_port_range(lc, &min_port, &max_port);
1072         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "video_min_rtp_port")), min_port);
1073         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "video_max_rtp_port")), max_port);
1074         if (min_port == max_port) {
1075                 gtk_widget_set_sensitive(GTK_WIDGET(linphone_gtk_get_widget(pb, "video_max_rtp_port")), FALSE);
1076                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "fixed_video_port")), TRUE);
1077         }
1078
1079         linphone_gtk_show_media_encryption(pb);
1080         
1081         tmp=linphone_core_get_nat_address(lc);
1082         if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"nat_address")),tmp);
1083         tmp=linphone_core_get_stun_server(lc);
1084         if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"stun_server")),tmp);
1085         pol=linphone_core_get_firewall_policy(lc);
1086         switch(pol){
1087                 case LinphonePolicyNoFirewall:
1088                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"no_nat")),TRUE);
1089                 break;
1090                 case LinphonePolicyUseNatAddress:
1091                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_nat_address")),TRUE);
1092                 break;
1093                 case LinphonePolicyUseStun:
1094                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_stun")),TRUE);
1095                 break;
1096                 case LinphonePolicyUseIce:
1097                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_ice")),TRUE);
1098                 break;
1099                 case LinphonePolicyUseUpnp:
1100                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_upnp")),TRUE);
1101                 break;
1102         }
1103         if(!linphone_core_upnp_available(lc)) {
1104                 gtk_widget_hide(linphone_gtk_get_widget(pb,"use_upnp"));
1105         }
1106
1107         mtu=linphone_core_get_mtu(lc);
1108         if (mtu<=0){
1109                 gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),FALSE);
1110                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),1500);
1111                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),FALSE);
1112         }else{
1113                 gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),TRUE);
1114                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),mtu);
1115                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),TRUE);
1116         }
1117         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"dtmf_sipinfo")),
1118                                         linphone_core_get_use_info_for_dtmf(lc));
1119         /* MUTIMEDIA CONFIG */
1120         linphone_gtk_fill_soundcards(pb);
1121         linphone_gtk_fill_webcams(pb);
1122
1123         linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size"));
1124         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")),
1125                                         linphone_core_echo_cancellation_enabled(lc));
1126
1127         gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(linphone_gtk_get_widget(pb,"ring_chooser")),
1128                                         linphone_core_get_ring(lc));
1129         /* SIP CONFIG */
1130         contact=linphone_core_get_primary_contact_parsed(lc);
1131         if (contact){
1132                 if (linphone_address_get_display_name(contact)) {
1133                         const char *dn=linphone_address_get_display_name(contact);
1134                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname")),dn);
1135                 }
1136                 if (linphone_address_get_username(contact))
1137                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")),linphone_address_get_username(contact));
1138         }
1139         linphone_address_destroy(contact);
1140         linphone_gtk_show_sip_accounts(pb);
1141         /* CODECS CONFIG */
1142         linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list));
1143         linphone_gtk_draw_codec_list(GTK_TREE_VIEW(codec_list),0);
1144         gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"codec_view")),0);
1145         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"download_bw")),
1146                                 linphone_core_get_download_bandwidth(lc));
1147         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"upload_bw")),
1148                                 linphone_core_get_upload_bandwidth(lc));
1149         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"adaptive_rate_control")),
1150                                  linphone_core_adaptive_rate_control_enabled(lc));
1151
1152
1153         /* UI CONFIG */
1154         linphone_gtk_fill_langs(pb);
1155         ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", 1);
1156         linphone_gtk_set_ui_config_int("advanced_ui", ui_advanced);
1157         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ui_level")),
1158                                 ui_advanced);
1159         linphone_gtk_ui_level_adapt(pb);
1160
1161         g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_port")),"value-changed",(GCallback)linphone_gtk_update_my_port,NULL);
1162         g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_combo")),"changed",(GCallback)linphone_gtk_proto_changed,NULL);
1163
1164
1165         if (linphone_core_tunnel_available()){
1166                 gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_edit_button")), TRUE);
1167                 gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_label")), TRUE);
1168         }
1169
1170         gtk_widget_show(pb);
1171 }
1172
1173
1174 void linphone_gtk_fixed_audio_port_toggle(void) {
1175         GtkWidget *mw = linphone_gtk_get_main_window();
1176         GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
1177         gboolean fixed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "fixed_audio_port")));
1178         gint min_port = gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_min_rtp_port")));
1179         gint max_port = gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_max_rtp_port")));
1180         gtk_widget_set_sensitive(GTK_WIDGET(linphone_gtk_get_widget(pb, "audio_max_rtp_port")), !fixed);
1181         if (fixed) {
1182                 linphone_core_set_audio_port(linphone_gtk_get_core(), min_port);
1183         } else {
1184                 linphone_core_set_audio_port_range(linphone_gtk_get_core(), min_port, max_port);
1185         }
1186 }
1187
1188
1189 void linphone_gtk_fixed_video_port_toggle(void) {
1190         GtkWidget *mw = linphone_gtk_get_main_window();
1191         GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
1192         gboolean fixed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "fixed_video_port")));
1193         gint min_port = gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "video_min_rtp_port")));
1194         gint max_port = gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "video_max_rtp_port")));
1195         gtk_widget_set_sensitive(GTK_WIDGET(linphone_gtk_get_widget(pb, "video_max_rtp_port")), !fixed);
1196         if (fixed) {
1197                 linphone_core_set_video_port(linphone_gtk_get_core(), min_port);
1198         } else {
1199                 linphone_core_set_video_port_range(linphone_gtk_get_core(), min_port, max_port);
1200         }
1201 }
1202
1203
1204 void linphone_gtk_edit_tunnel_closed(GtkWidget *button){
1205         GtkWidget *pb=gtk_widget_get_toplevel(button);
1206         gtk_widget_destroy(pb);
1207 }
1208
1209 void linphone_gtk_edit_tunnel(GtkButton *button){
1210         GtkWidget *w=linphone_gtk_create_window("tunnel_config");
1211         LinphoneCore *lc=linphone_gtk_get_core();
1212         LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc);
1213         const MSList *configs;
1214         const char *host = NULL;
1215         int port=0;
1216         
1217         if (!tunnel) return;
1218         
1219         configs = linphone_tunnel_get_servers(tunnel);
1220         if(configs != NULL) {
1221                 LinphoneTunnelConfig *ltc = (LinphoneTunnelConfig *)configs->data;
1222                 host = linphone_tunnel_config_get_host(ltc);
1223                 port = linphone_tunnel_config_get_port(ltc);
1224         }
1225
1226         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"host")),host);
1227         if (port==0) port=443;
1228         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"port")), port);
1229
1230         if (linphone_tunnel_enabled(tunnel)){
1231                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_enable")),1);
1232         } else{
1233                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_disable")),1);
1234         }
1235         {
1236                 const char *proxy=NULL,*username=NULL,*password=NULL;
1237                 port=0;
1238                 linphone_tunnel_get_http_proxy(tunnel,&proxy,&port,&username,&password);
1239                 if (proxy)
1240                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"http_host")),proxy);
1241                 if (port>0)
1242                         gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"http_port")), port);
1243                 if (username)
1244                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"username")),username);
1245                 if (password)
1246                         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"password")),password);
1247         }
1248
1249         g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_edit_tunnel_closed,w);
1250         gtk_widget_show(w);
1251 }
1252
1253 void linphone_gtk_tunnel_ok(GtkButton *button){
1254         GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button));
1255         LinphoneCore *lc=linphone_gtk_get_core();
1256         LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc);
1257         LinphoneTunnelConfig *config=linphone_tunnel_config_new();
1258
1259         gint port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"port")));
1260         gboolean enabled=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_enable")));
1261         const char *host=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"host")));
1262         const char *http_host=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"http_host")));
1263         gint http_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"http_port")));
1264         const char *username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"username")));
1265         const char *password=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"password")));
1266         
1267         if (tunnel==NULL) return;
1268         if (host && *host=='\0') host=NULL;
1269         if (http_port==0) http_port=8080;
1270         linphone_tunnel_clean_servers(tunnel);
1271         linphone_tunnel_config_set_host(config, host);
1272         linphone_tunnel_config_set_port(config, port);
1273         linphone_tunnel_add_server(tunnel, config);
1274         linphone_tunnel_enable(tunnel,enabled);
1275         linphone_tunnel_set_http_proxy(tunnel,http_host,http_port,username,password);
1276         
1277         gtk_widget_destroy(w);
1278 }
1279
1280
1281 void linphone_gtk_tunnel_cancel(GtkButton *button){
1282
1283 }
1284
1285 static void show_dscp(GtkWidget *entry, int val){
1286         char tmp[20];
1287         snprintf(tmp,sizeof(tmp),"0x%x",val);
1288         gtk_entry_set_text(GTK_ENTRY(entry),tmp);
1289         
1290 }
1291
1292 static int read_dscp(GtkWidget *entry){
1293         const char *val=gtk_entry_get_text(GTK_ENTRY(entry));
1294         const char *begin;
1295         int ret=0;
1296         if (val==NULL || val[0]=='\0') return 0;
1297         /*skip potential 0x*/
1298         begin=strstr(val,"0x");
1299         if (begin) begin+=2;
1300         else begin=val;
1301         if (sscanf(begin,"%x",&ret)==1)
1302                 return ret;
1303         return -1;
1304 }
1305
1306 void linphone_gtk_dscp_edit(){
1307         LinphoneCore *lc=linphone_gtk_get_core();
1308         GtkWidget *widget=linphone_gtk_create_window("dscp_settings");
1309         show_dscp(linphone_gtk_get_widget(widget,"sip_dscp"),
1310                   linphone_core_get_sip_dscp(lc));
1311         show_dscp(linphone_gtk_get_widget(widget,"audio_dscp"),
1312                   linphone_core_get_audio_dscp(lc));
1313         show_dscp(linphone_gtk_get_widget(widget,"video_dscp"),
1314                   linphone_core_get_video_dscp(lc));
1315         gtk_widget_show(widget);
1316 }
1317
1318 void linphone_gtk_dscp_edit_response(GtkWidget *dialog, guint response_id){
1319         LinphoneCore *lc=linphone_gtk_get_core();
1320         switch(response_id){
1321                 case GTK_RESPONSE_OK:
1322                         linphone_core_set_sip_dscp(lc,
1323                                 read_dscp(linphone_gtk_get_widget(dialog,"sip_dscp")));
1324                         linphone_core_set_audio_dscp(lc,
1325                                 read_dscp(linphone_gtk_get_widget(dialog,"audio_dscp")));
1326                         linphone_core_set_video_dscp(lc,
1327                                 read_dscp(linphone_gtk_get_widget(dialog,"video_dscp")));
1328                         
1329                 break;
1330                 default:
1331                 break;
1332         }
1333         gtk_widget_destroy(dialog);
1334 }