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