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