source: mediastreamer2/linphone/gtk-glade/main.c @ 763:919f31020a06

Last change on this file since 763:919f31020a06 was 763:919f31020a06, checked in by smorlat <smorlat@…>, 4 years ago

fix unhandled option --workdir

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@751 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File size: 38.9 KB
Line 
1/*
2linphone, gtk-glade interface.
3Copyright (C) 2008  Simon MORLAT (simon.morlat@linphone.org)
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18*/
19
20#define USE_LIBGLADE 1
21
22#include "linphone.h"
23#include "lpconfig.h"
24
25
26
27#ifdef USE_LIBGLADE
28#include <glade/glade.h>
29#endif
30
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <unistd.h>
34
35#define LINPHONE_ICON "linphone2.png"
36
37const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
38
39static LinphoneCore *the_core=NULL;
40static GtkWidget *the_ui=NULL;
41
42static void linphone_gtk_show(LinphoneCore *lc);
43static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from);
44static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from);
45static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img);
46static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
47static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username);
48static void linphone_gtk_display_status(LinphoneCore *lc, const char *status);
49static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg);
50static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning);
51static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
52static void linphone_gtk_display_question(LinphoneCore *lc, const char *question);
53static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl);
54static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate);
55static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to);
56static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window);
57
58static LinphoneCoreVTable vtable={
59        .show=linphone_gtk_show,
60        .inv_recv=linphone_gtk_inv_recv,
61        .bye_recv=linphone_gtk_bye_recv,
62        .notify_recv=linphone_gtk_notify_recv,
63        .new_unknown_subscriber=linphone_gtk_new_unknown_subscriber,
64        .auth_info_requested=linphone_gtk_auth_info_requested,
65        .display_status=linphone_gtk_display_status,
66        .display_message=linphone_gtk_display_message,
67        .display_warning=linphone_gtk_display_warning,
68        .display_url=linphone_gtk_display_url,
69        .display_question=linphone_gtk_display_question,
70        .call_log_updated=linphone_gtk_call_log_updated,
71        .text_received=linphone_gtk_text_received,
72        .general_state=linphone_gtk_general_state,
73        .refer_received=linphone_gtk_refer_received,
74        .buddy_info_updated=linphone_gtk_buddy_info_updated
75};
76
77static gboolean verbose=0;
78static gboolean auto_answer = 0;
79static gchar * addr_to_call = NULL;
80static gboolean iconified=FALSE;
81#ifdef WIN32
82static gchar *workingdir=NULL;
83#endif
84
85static GOptionEntry linphone_options[]={
86        {
87                .long_name="verbose",
88                .short_name= '\0',
89                .arg=G_OPTION_ARG_NONE,
90                .arg_data= (gpointer)&verbose,
91                .description=N_("log to stdout some debug information while running.")
92        },
93        {
94                .long_name="iconified",
95                .short_name= '\0',
96                .arg=G_OPTION_ARG_NONE,
97                .arg_data= (gpointer)&iconified,
98                .description=N_("Start only in the system tray, do not show the main interface.")
99        },
100        {
101            .long_name = "call",
102            .short_name = 'c',
103            .arg = G_OPTION_ARG_STRING,
104            .arg_data = &addr_to_call,
105            .description = N_("address to call right now")
106        },
107        {
108            .long_name = "auto-answer",
109            .short_name = 'a',
110            .arg = G_OPTION_ARG_NONE,
111            .arg_data = (gpointer) & auto_answer,
112            .description = N_("if set automatically answer incoming calls")
113        },
114#ifdef WIN32
115        {                               /* zsd addition */
116            .long_name = "workdir",
117            .short_name = '\0',
118            .arg = G_OPTION_ARG_STRING,
119            .arg_data = (gpointer) & workingdir,
120            .description = N_("Specifiy a working directory (should be the base of the installation, eg: c:\\Program Files\\Linphone)")
121        },
122#endif
123        {0}
124};
125
126#define INSTALLED_XML_DIR PACKAGE_DATA_DIR "/linphone"
127#define BUILD_TREE_XML_DIR "gtk-glade"
128
129#ifndef WIN32
130#define CONFIG_FILE ".linphonerc"
131#else
132#define CONFIG_FILE "linphonerc"
133#endif
134
135
136
137static char _config_file[1024];
138
139
140const char *linphone_gtk_get_config_file(){
141        /*try accessing a local file first if exists*/
142        if (access(CONFIG_FILE,F_OK)==0){
143                snprintf(_config_file,sizeof(_config_file),"%s",CONFIG_FILE);
144        }else{
145#ifdef WIN32
146                const char *appdata=getenv("APPDATA");
147                if (appdata){
148                        snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
149                        CreateDirectory(_config_file,NULL);
150                        snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR "\\" CONFIG_FILE);
151                }
152#else
153                const char *home=getenv("HOME");
154                if (home==NULL) home=".";
155                snprintf(_config_file,sizeof(_config_file),"%s/%s",home,CONFIG_FILE);
156#endif
157        }
158        return _config_file;
159}
160
161static void linphone_gtk_init_liblinphone(const char *file){
162        linphone_core_set_user_agent("Linphone", LINPHONE_VERSION);
163        the_core=linphone_core_new(&vtable,file,NULL);
164        linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
165}
166
167
168
169LinphoneCore *linphone_gtk_get_core(void){
170        return the_core;
171}
172
173GtkWidget *linphone_gtk_get_main_window(){
174        return the_ui;
175}
176
177static void parse_item(const char *item, const char *window_name, GtkWidget *w,  gboolean show){
178        char tmp[64];
179        char *dot;
180        strcpy(tmp,item);
181        dot=strchr(tmp,'.');
182        if (dot){
183                *dot='\0';
184                dot++;
185                if (strcmp(window_name,tmp)==0){
186                        GtkWidget *wd=linphone_gtk_get_widget(w,dot);
187                        if (wd) {
188                                if (!show) gtk_widget_hide(wd);
189                                else gtk_widget_show(wd);
190                        }
191                }
192        }
193}
194
195static void parse_widgets(const char *hiddens, const char *window_name, GtkWidget *w, gboolean show){
196        char item[64];
197        const char *i;
198        const char *b;
199        int len;
200        for(b=i=hiddens;*i!='\0';++i){
201                if (*i==' '){
202                        len=MIN(i-b,sizeof(item)-1);
203                        strncpy(item,b,len);
204                        item[len]='\0';
205                        b=i+1;
206                        parse_item(item,window_name,w,show);
207                }
208        }
209        len=MIN(i-b,sizeof(item)-1);
210        if (len>0){
211                strncpy(item,b,len);
212                item[len]='\0';
213                parse_item(item,window_name,w,show);
214        }
215}
216
217static void linphone_gtk_configure_window(GtkWidget *w, const char *window_name){
218        static const char *icon_path=NULL;
219        static const char *hiddens=NULL;
220        static const char *shown=NULL;
221        static bool_t config_loaded=FALSE;
222        if (linphone_gtk_get_core()==NULL) return;
223        if (config_loaded==FALSE){
224                hiddens=linphone_gtk_get_ui_config("hidden_widgets",NULL);
225                shown=linphone_gtk_get_ui_config("shown_widgets",NULL);
226                icon_path=linphone_gtk_get_ui_config("icon",NULL);
227                config_loaded=TRUE;
228        }
229        if (hiddens)
230                parse_widgets(hiddens,window_name,w,FALSE);
231        if (shown)
232                parse_widgets(shown,window_name,w,TRUE);
233        if (icon_path) {
234                GdkPixbuf *pbuf=create_pixbuf(icon_path);
235                gtk_window_set_icon(GTK_WINDOW(w),pbuf);
236                g_object_unref(G_OBJECT(pbuf));
237        }
238}
239
240#ifdef USE_LIBGLADE
241
242GtkWidget *linphone_gtk_create_window(const char *window_name){
243        GtkWidget *w;
244        GladeXML *gxml;
245        char path[2048];
246        snprintf(path,sizeof(path),"%s/%s.glade",BUILD_TREE_XML_DIR,window_name);
247        if (access(path,F_OK)!=0){
248                snprintf(path,sizeof(path),"%s/%s.glade",INSTALLED_XML_DIR,window_name);
249                if (access(path,F_OK)!=0){
250                        g_error("Could not locate neither %s/%s.glade and %s/%s.glade .",BUILD_TREE_XML_DIR,window_name,
251                                INSTALLED_XML_DIR,window_name);
252                        return NULL;
253                }
254        }
255        gxml=glade_xml_new(path,NULL,NULL);
256        glade_xml_signal_autoconnect(gxml);
257        w=glade_xml_get_widget(gxml,window_name);
258        if (w==NULL) g_error("Could not retrieve '%s' window from xml file",window_name);
259        linphone_gtk_configure_window(w,window_name);
260        return w;
261}
262
263GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
264        GtkWidget *w;
265        GladeXML *gxml=glade_get_widget_tree(window);
266        if (gxml==NULL) g_error("Could not retrieve XML tree of window %s",name);
267        w=glade_xml_get_widget(gxml,name);
268        if (w==NULL) g_error("Could not retrieve widget %s",name);
269        return GTK_WIDGET(w);
270}
271
272#else
273
274GtkWidget *linphone_gtk_create_window(const char *window_name){
275       
276}
277
278GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
279        GObject *w=gtk_builder_get_object(the_ui,name);
280        if (w==NULL){
281                g_error("No widget named %s found in xml interface.",name);
282        }
283        return GTK_WIDGET(w);
284}
285
286#endif
287
288void linphone_gtk_display_something(GtkMessageType type,const gchar *message){
289        GtkWidget *dialog;
290        GtkWidget *main_window=linphone_gtk_get_main_window();
291       
292        gtk_widget_show(main_window);
293        if (type==GTK_MESSAGE_QUESTION)
294        {
295                /* draw a question box. link to dialog_click callback */
296                dialog = gtk_message_dialog_new (
297                                GTK_WINDOW(main_window),
298                                GTK_DIALOG_DESTROY_WITH_PARENT,
299                                GTK_MESSAGE_QUESTION,
300                                GTK_BUTTONS_YES_NO,
301                                "%s",
302                                (const gchar*)message);
303                /* connect to some callback : REVISIT */
304                /*
305                g_signal_connect_swapped (G_OBJECT (dialog), "response",
306                           G_CALLBACK (dialog_click),
307                           G_OBJECT (dialog));
308                */
309                /* actually show the box */
310                gtk_widget_show(dialog);
311        }
312        else
313        {
314                dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
315                                  GTK_DIALOG_DESTROY_WITH_PARENT,
316                                  type,
317                                  GTK_BUTTONS_CLOSE,
318                                  "%s",
319                                  (const gchar*)message);
320                /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
321                g_signal_connect_swapped (G_OBJECT (dialog), "response",
322                           G_CALLBACK (gtk_widget_destroy),
323                           G_OBJECT (dialog));
324                gtk_widget_show(dialog);
325        }
326}
327
328void linphone_gtk_about_response(GtkDialog *dialog, gint id){
329        if (id==GTK_RESPONSE_CANCEL){
330                gtk_widget_destroy(GTK_WIDGET(dialog));
331        }
332}
333
334static void about_url_clicked(GtkAboutDialog *dialog, const char *url, gpointer data){
335        g_message("About url clicked");
336        linphone_gtk_open_browser(url);
337}
338
339void linphone_gtk_show_about(){
340        struct stat filestat;
341        const char *license_file=PACKAGE_DATA_DIR "/linphone/COPYING";
342        GtkWidget *about;
343       
344        about=linphone_gtk_create_window("about");
345        gtk_about_dialog_set_url_hook(about_url_clicked,NULL,NULL);
346        memset(&filestat,0,sizeof(filestat));
347        if (stat(license_file,&filestat)!=0){
348                license_file="COPYING";
349                stat(license_file,&filestat);
350        }
351        if (filestat.st_size>0){
352                char *license=g_malloc(filestat.st_size+1);
353                FILE *f=fopen(license_file,"r");
354                if (f && fread(license,filestat.st_size,1,f)==1){
355                        license[filestat.st_size]='\0';
356                        gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about),license);
357                }
358                g_free(license);
359        }
360        gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LINPHONE_VERSION);
361        gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("title","Linphone"));
362        gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("home","http://www.linphone.org"));
363        gtk_widget_show(about);
364}
365
366static void set_video_window_decorations(GdkWindow *w){
367        const char *title=linphone_gtk_get_ui_config("title","Linphone");
368        const char *icon_path=linphone_gtk_get_ui_config("icon","linphone2.png");
369        char video_title[256];
370        GdkPixbuf *pbuf=create_pixbuf(icon_path);
371        if (!linphone_core_in_call(linphone_gtk_get_core())){
372                snprintf(video_title,sizeof(video_title),"%s video",title);     
373        }else{
374                const char *uri=linphone_core_get_remote_uri(linphone_gtk_get_core());
375                gchar *display_name=linphone_gtk_get_display_name(uri);
376                snprintf(video_title,sizeof(video_title),"Call with %s",display_name);
377                g_free(display_name);
378        }
379        gdk_window_set_title(w,video_title);
380        /*gdk_window_set_urgency_hint(w,TRUE);*/
381        gdk_window_raise(w);
382        if (pbuf){
383                GList *l=NULL;
384                l=g_list_append(l,pbuf);
385                gdk_window_set_icon_list(w,l);
386                g_list_free(l);
387                g_object_unref(G_OBJECT(pbuf));
388        }
389}
390
391static gboolean video_needs_update=FALSE;
392
393static void update_video_title(){
394        video_needs_update=TRUE;
395}
396
397static gboolean linphone_gtk_iterate(LinphoneCore *lc){
398        static gboolean first_time=TRUE;
399        unsigned long id;
400        static unsigned long previd=0;
401        static gboolean in_iterate=FALSE;
402       
403        /*avoid reentrancy*/
404        if (in_iterate) return TRUE;
405        in_iterate=TRUE;
406        linphone_core_iterate(lc);
407        if (first_time){
408                /*after the first call to iterate, SipSetupContexts should be ready, so take actions:*/
409                linphone_gtk_show_directory_search();
410                first_time=FALSE;
411        }
412
413        id=linphone_core_get_native_video_window_id(lc);
414        if (id!=previd || video_needs_update){
415                GdkWindow *w;
416                previd=id;
417                if (id!=0){
418                        ms_message("Updating window decorations");
419#ifndef WIN32
420                        w=gdk_window_foreign_new(id);
421#else
422                        w=gdk_window_foreign_new((HANDLE)id);
423#endif
424                        if (w) {
425                                set_video_window_decorations(w);
426                                g_object_unref(G_OBJECT(w));
427                        }
428                        else ms_error("gdk_window_foreign_new() failed");
429                        if (video_needs_update) video_needs_update=FALSE;
430                }
431        }
432        if (addr_to_call!=NULL){
433                /*make sure we are not showing the login screen*/
434                GtkWidget *mw=linphone_gtk_get_main_window();
435                GtkWidget *login_frame=linphone_gtk_get_widget(mw,"login_frame");
436                if (!GTK_WIDGET_VISIBLE(login_frame)){
437                        GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar");
438                        gtk_entry_set_text(GTK_ENTRY(uri_bar),addr_to_call);
439                        addr_to_call=NULL;
440                        linphone_gtk_start_call(uri_bar);
441                }
442        }
443        in_iterate=FALSE;
444        return TRUE;
445}
446
447static void load_uri_history(){
448        GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
449        char key[20];
450        int i;
451        GtkEntryCompletion *gep=gtk_entry_completion_new();
452        GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING);
453        for (i=0;;i++){
454                const char *uri;
455                snprintf(key,sizeof(key),"uri%i",i);
456                uri=linphone_gtk_get_ui_config(key,NULL);
457                if (uri!=NULL) {
458                        GtkTreeIter iter;
459                        gtk_list_store_append(model,&iter);
460                        gtk_list_store_set(model,&iter,0,uri,-1);
461                        if (i==0) gtk_entry_set_text(uribar,uri);
462                }
463                else break;
464        }
465        gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model));
466        gtk_entry_completion_set_text_column(gep,0);
467        gtk_entry_set_completion(uribar,gep);
468}
469
470static void save_uri_history(){
471        LinphoneCore *lc=linphone_gtk_get_core();
472        LpConfig *cfg=linphone_core_get_config(lc);
473        GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
474        char key[20];
475        int i=0;
476        char *uri=NULL;
477        GtkTreeIter iter;
478        GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar));
479
480        if (!gtk_tree_model_get_iter_first(model,&iter)) return;
481        do {
482                gtk_tree_model_get(model,&iter,0,&uri,-1);
483                if (uri) {
484                        snprintf(key,sizeof(key),"uri%i",i);
485                        lp_config_set_string(cfg,"GtkUi",key,uri);
486                        g_free(uri);
487                }else break;
488                i++;
489                if (i>5) break;
490        }while(gtk_tree_model_iter_next(model,&iter));
491        lp_config_sync(cfg);
492}
493
494static void completion_add_text(GtkEntry *entry, const char *text){
495        GtkTreeIter iter;
496        GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry));
497       
498        if (gtk_tree_model_get_iter_first(model,&iter)){ 
499                do {
500                        gchar *uri=NULL;
501                        gtk_tree_model_get(model,&iter,0,&uri,-1);
502                        if (uri!=NULL){
503                                if (strcmp(uri,text)==0) {
504                                        /*remove text */
505                                        gtk_list_store_remove(GTK_LIST_STORE(model),&iter);
506                                        g_free(uri);
507                                        break;
508                                }
509                                g_free(uri);
510                        }
511                }while (gtk_tree_model_iter_next(model,&iter));
512        }
513        /* and prepend it on top of the list */
514        gtk_list_store_prepend(GTK_LIST_STORE(model),&iter);
515        gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1);
516        save_uri_history();
517}
518
519void linphone_gtk_call_terminated(const char *error){
520        GtkWidget *mw=linphone_gtk_get_main_window();
521        GtkWidget *icw;
522        gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),FALSE);
523        gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),TRUE);
524        gtk_widget_hide_all(linphone_gtk_get_widget(mw,"go_to_call_view_box"));
525        linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"main_mute")),FALSE);
526        if (linphone_gtk_use_in_call_view())
527                linphone_gtk_in_call_view_terminate(error);
528        update_video_title();
529        icw=GTK_WIDGET(g_object_get_data(G_OBJECT(mw),"incoming_call"));
530        if (icw!=NULL){
531                g_object_set_data(G_OBJECT(mw),"incoming_call",NULL);
532                gtk_widget_destroy(icw);
533        }
534}
535
536static gboolean in_call_timer(){
537        if (linphone_core_in_call(linphone_gtk_get_core())){
538                linphone_gtk_in_call_view_update_duration(
539                        linphone_core_get_current_call_duration(linphone_gtk_get_core()));
540                return TRUE;
541        }
542        return FALSE;
543}
544
545static void linphone_gtk_call_started(GtkWidget *mw){
546        gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),FALSE);
547        gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),TRUE);
548        gtk_widget_show_all(linphone_gtk_get_widget(mw,"go_to_call_view_box"));
549        update_video_title();
550        if (linphone_gtk_use_in_call_view())
551                g_timeout_add(250,(GSourceFunc)in_call_timer,NULL);
552}
553
554static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){
555        const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar));
556        if (linphone_core_invite(linphone_gtk_get_core(),entered)==0) {
557                completion_add_text(GTK_ENTRY(uri_bar),entered);
558        }else{
559        }
560        return FALSE;
561}
562
563static void _linphone_gtk_accept_call(){
564        LinphoneCore *lc=linphone_gtk_get_core();
565        GtkWidget *mw=linphone_gtk_get_main_window();
566        GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(mw),"incoming_call"));
567        if (icw!=NULL){
568                g_object_set_data(G_OBJECT(mw),"incoming_call",NULL);
569                gtk_widget_destroy(icw);
570        }
571
572        linphone_core_accept_call(lc,NULL);
573        linphone_gtk_call_started(linphone_gtk_get_main_window());
574        if (linphone_gtk_use_in_call_view()){
575                linphone_gtk_in_call_view_set_in_call();
576                linphone_gtk_show_in_call_view();
577        }
578        linphone_gtk_enable_mute_button(
579                GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute"))
580                ,TRUE);
581}
582
583void linphone_gtk_start_call(GtkWidget *w){
584        LinphoneCore *lc=linphone_gtk_get_core();
585        if (linphone_core_inc_invite_pending(lc)){
586                /*accept the call*/
587                _linphone_gtk_accept_call();
588        }else if (linphone_core_in_call(lc)) {
589                /*already in call */
590        }else{
591                /*change into in-call mode, then do the work later as it might block a bit */
592                GtkWidget *mw=gtk_widget_get_toplevel(w);
593                GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar");
594                const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar));
595                linphone_gtk_call_started(mw);
596                if (linphone_gtk_use_in_call_view()){
597                        linphone_gtk_in_call_view_set_calling(entered);
598                        linphone_gtk_show_in_call_view();
599                }
600                g_timeout_add(100,(GSourceFunc)linphone_gtk_start_call_do,uri_bar);
601        }
602}
603
604void linphone_gtk_uri_bar_activate(GtkWidget *w){
605        linphone_gtk_start_call(w);
606}
607
608
609void linphone_gtk_terminate_call(GtkWidget *button){
610        linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
611}
612
613void linphone_gtk_decline_call(GtkWidget *button){
614        linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
615        gtk_widget_destroy(gtk_widget_get_toplevel(button));
616}
617
618void linphone_gtk_accept_call(GtkWidget *button){
619        _linphone_gtk_accept_call();
620}
621
622static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window){
623        linphone_gtk_accept_call(linphone_gtk_get_widget(incall_window,"accept_call"));
624        return FALSE;
625}
626
627void linphone_gtk_set_audio_video(){
628        linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE);
629        linphone_core_enable_video_preview(linphone_gtk_get_core(),TRUE);
630}
631
632void linphone_gtk_set_audio_only(){
633        linphone_core_enable_video(linphone_gtk_get_core(),FALSE,FALSE);
634        linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
635}
636
637void linphone_gtk_enable_self_view(GtkWidget *w){
638        linphone_core_enable_self_view(linphone_gtk_get_core(),
639                gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
640}
641
642void linphone_gtk_used_identity_changed(GtkWidget *w){
643        int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
644        char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
645        if (sel && strlen(sel)>0){ //avoid a dummy "changed" at gui startup
646                linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1));
647                linphone_gtk_show_directory_search();
648        }
649        if (sel) g_free(sel);
650}
651
652static void linphone_gtk_show_main_window(){
653        GtkWidget *w=linphone_gtk_get_main_window();
654        LinphoneCore *lc=linphone_gtk_get_core();
655        linphone_core_enable_video_preview(lc,linphone_core_video_enabled(lc));
656        gtk_widget_show(w);
657        gtk_window_present(GTK_WINDOW(w));
658}
659
660static void linphone_gtk_show(LinphoneCore *lc){
661        linphone_gtk_show_main_window();
662}
663
664static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){
665        GtkWidget *w=linphone_gtk_create_window("incoming_call");
666        GtkWidget *label;
667        gchar *msg;
668
669        if (auto_answer){
670                g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer,w);
671        }
672
673        gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window()));
674        gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT);
675
676        label=linphone_gtk_get_widget(w,"message");
677        msg=g_strdup_printf(_("Incoming call from %s"),from);
678        gtk_label_set_text(GTK_LABEL(label),msg);
679        gtk_window_set_title(GTK_WINDOW(w),msg);
680        gtk_widget_show(w);
681        gtk_window_present(GTK_WINDOW(w));
682        /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/
683        g_free(msg);
684        g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w);
685        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),
686                        from);
687}
688
689static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){
690       
691}
692
693static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img){
694}
695
696static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint response_id, LinphoneFriend *lf){
697        switch(response_id){
698                case GTK_RESPONSE_YES:
699                        linphone_gtk_show_contact(lf);
700                break;
701                default:
702                        linphone_core_reject_subscriber(linphone_gtk_get_core(),lf);
703        }
704        gtk_widget_destroy(dialog);
705}
706
707static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
708        GtkWidget *dialog;
709        gchar *message=g_strdup_printf(_("%s would like to add you to his contact list.\nWould you allow him to see your presence status or add him to your contact list ?\nIf you answer no, this person will be temporarily blacklisted."),url);
710        dialog = gtk_message_dialog_new (
711                                GTK_WINDOW(linphone_gtk_get_main_window()),
712                                GTK_DIALOG_DESTROY_WITH_PARENT,
713                                GTK_MESSAGE_QUESTION,
714                                GTK_BUTTONS_YES_NO,
715                                "%s",
716                                message);
717        g_free(message);
718        g_signal_connect(G_OBJECT (dialog), "response",
719                G_CALLBACK (linphone_gtk_new_subscriber_response),lf);
720        /* actually show the box */
721        gtk_widget_show(dialog);
722}
723
724typedef struct _AuthTimeout{
725        GtkWidget *w;
726} AuthTimeout;
727
728
729static void auth_timeout_clean(AuthTimeout *tout){
730        tout->w=NULL;
731}
732
733static gboolean auth_timeout_destroy(AuthTimeout *tout){
734        if (tout->w)  {
735                g_object_weak_unref(G_OBJECT(tout->w),(GWeakNotify)auth_timeout_clean,tout);
736                gtk_widget_destroy(tout->w);
737        }
738        g_free(tout);
739        return FALSE;
740}
741
742static AuthTimeout * auth_timeout_new(GtkWidget *w){
743        AuthTimeout *tout=g_new(AuthTimeout,1);
744        tout->w=w;
745        /*so that the timeout no more references the widget when it is destroyed:*/
746        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)auth_timeout_clean,tout);
747        /*so that the widget is automatically destroyed after some time */
748        g_timeout_add(30000,(GtkFunction)auth_timeout_destroy,tout);
749        return tout;
750}
751
752void linphone_gtk_password_cancel(GtkWidget *w){
753        LinphoneAuthInfo *info;
754        GtkWidget *window=gtk_widget_get_toplevel(w);
755        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
756        linphone_core_abort_authentication(linphone_gtk_get_core(),info);
757        gtk_widget_destroy(window);
758}
759
760void linphone_gtk_password_ok(GtkWidget *w){
761        GtkWidget *entry;
762        GtkWidget *window=gtk_widget_get_toplevel(w);
763        LinphoneAuthInfo *info;
764        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
765        g_object_weak_unref(G_OBJECT(window),(GWeakNotify)linphone_auth_info_destroy,info);
766        entry=linphone_gtk_get_widget(window,"password_entry");
767        linphone_auth_info_set_passwd(info,gtk_entry_get_text(GTK_ENTRY(entry)));
768        linphone_auth_info_set_userid(info,
769                gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(window,"userid_entry"))));
770        linphone_core_add_auth_info(linphone_gtk_get_core(),info);
771        gtk_widget_destroy(window);
772}
773
774static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username){
775        GtkWidget *w=linphone_gtk_create_window("password");
776        GtkWidget *label=linphone_gtk_get_widget(w,"message");
777        LinphoneAuthInfo *info;
778        gchar *msg;
779        msg=g_strdup_printf(_("Please enter your password for username <i>%s</i>\n at domain <i>%s</i>:"),
780                username,realm);
781        gtk_label_set_markup(GTK_LABEL(label),msg);
782        g_free(msg);
783        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"userid_entry")),username);
784        info=linphone_auth_info_new(username, NULL, NULL, NULL,realm);
785        g_object_set_data(G_OBJECT(w),"auth_info",info);
786        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_auth_info_destroy,info);
787        gtk_widget_show(w);
788        auth_timeout_new(w);
789}
790
791static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){
792        GtkWidget *w=linphone_gtk_get_main_window();
793        GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar");
794        gtk_statusbar_push(GTK_STATUSBAR(status_bar),
795                        gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),""),
796                        status);
797}
798
799static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){
800        linphone_gtk_display_something(GTK_MESSAGE_INFO,msg);
801}
802
803static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning){
804        linphone_gtk_display_something(GTK_MESSAGE_WARNING,warning);
805}
806
807static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url){
808        char richtext[4096];
809        snprintf(richtext,sizeof(richtext),"%s %s",msg,url);
810        linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext);
811}
812
813static void linphone_gtk_display_question(LinphoneCore *lc, const char *question){
814        linphone_gtk_display_something(GTK_MESSAGE_QUESTION,question);
815}
816
817static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){
818        GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
819        if (w) linphone_gtk_call_log_update(w);
820}
821
822static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
823        switch(gstate->new_state){
824                case GSTATE_CALL_OUT_CONNECTED:
825                case GSTATE_CALL_IN_CONNECTED:
826                        if (linphone_gtk_use_in_call_view())
827                                linphone_gtk_in_call_view_set_in_call();
828                        linphone_gtk_enable_mute_button(
829                                GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")),
830                        TRUE);
831                break;
832                case GSTATE_CALL_ERROR:
833                        linphone_gtk_call_terminated(gstate->message);
834                break;
835                case GSTATE_CALL_END:
836                        linphone_gtk_call_terminated(NULL);
837                break;
838                default:
839                break;
840        }
841}
842
843static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
844        GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
845        gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
846}
847
848void linphone_gtk_open_browser(const char *url){
849        /*in gtk 2.16, gtk_show_uri does not work...*/
850        /*gtk_show_uri(NULL,url,GDK_CURRENT_TIME,NULL);*/
851#ifdef WIN32
852        ShellExecute(0,"open",url,NULL,NULL,1);
853#else
854        char cl[255];
855        snprintf(cl,sizeof(cl),"/usr/bin/x-www-browser %s",url);
856        g_spawn_command_line_async(cl,NULL);
857#endif
858}
859
860void linphone_gtk_link_to_website(GtkWidget *item){
861        const gchar *home=(const gchar*)g_object_get_data(G_OBJECT(item),"home");
862        linphone_gtk_open_browser(home);
863}
864
865static GtkWidget *create_icon_menu(){
866        GtkWidget *menu=gtk_menu_new();
867        GtkWidget *menu_item;
868        GtkWidget *image;
869        gchar *tmp;
870        const gchar *homesite;
871       
872        homesite=linphone_gtk_get_ui_config("home","http://www.linphone.org");
873        menu_item=gtk_image_menu_item_new_with_label(_("Website link"));
874        tmp=g_strdup(homesite);
875        g_object_set_data(G_OBJECT(menu_item),"home",tmp);
876        g_object_weak_ref(G_OBJECT(menu_item),(GWeakNotify)g_free,tmp);
877       
878        image=gtk_image_new_from_stock(GTK_STOCK_HELP,GTK_ICON_SIZE_MENU);
879        gtk_widget_show(image);
880        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
881        //g_object_unref(G_OBJECT(image));
882        gtk_widget_show(menu_item);
883        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
884        g_signal_connect(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_link_to_website,NULL);
885       
886        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,NULL);
887        gtk_widget_show(menu_item);
888        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
889        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_about,NULL);
890        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,NULL);
891        gtk_widget_show(menu_item);
892        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
893        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)gtk_main_quit,NULL);
894        gtk_widget_show(menu);
895        return menu;
896}
897
898static GtkStatusIcon *icon=NULL;
899
900static void linphone_gtk_init_status_icon(){
901        const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON);
902        GdkPixbuf *pbuf=create_pixbuf(icon_path);
903        GtkWidget *menu=create_icon_menu();
904        const char *title;
905        icon=gtk_status_icon_new_from_pixbuf(pbuf);
906        g_object_unref(G_OBJECT(pbuf));
907        g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)linphone_gtk_show_main_window,linphone_gtk_get_main_window());
908        g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL);
909        title=linphone_gtk_get_ui_config("title",_("Linphone - a video internet phone"));
910        gtk_status_icon_set_tooltip(icon,title);
911        gtk_status_icon_set_visible(icon,TRUE);
912        g_object_set_data(G_OBJECT(icon),"menu",menu);
913        g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu);
914}
915
916void linphone_gtk_load_identities(void){
917        const MSList *elem;
918        GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities"));
919        char *def_identity;
920        LinphoneProxyConfig *def=NULL;
921        int def_index=0,i;
922        GtkListStore *store;
923
924        store=GTK_LIST_STORE(gtk_combo_box_get_model(box));
925        gtk_list_store_clear(store);
926
927        linphone_core_get_default_proxy(linphone_gtk_get_core(),&def);
928        def_identity=g_strdup_printf(_("%s (Default)"),linphone_core_get_primary_contact(linphone_gtk_get_core()));
929        gtk_combo_box_append_text(box,def_identity);
930        g_free(def_identity);
931        for(i=1,elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());
932                        elem!=NULL;
933                        elem=ms_list_next(elem),i++){
934                LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
935                gtk_combo_box_append_text(box,linphone_proxy_config_get_identity(cfg));
936                if (cfg==def) {
937                        def_index=i;
938                }
939        }
940        gtk_combo_box_set_active(box,def_index);
941}
942
943static void linphone_gtk_dtmf_clicked(GtkButton *button){
944        const char *label=gtk_button_get_label(button);
945        if (linphone_core_in_call(linphone_gtk_get_core())){
946                linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]);
947        }else{
948                GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"uribar");
949                int pos=-1;
950                gtk_editable_insert_text(GTK_EDITABLE(uri_bar),label,1,&pos);
951        }
952}
953
954static void linphone_gtk_connect_digits(void){
955        GtkContainer *cont=GTK_CONTAINER(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"dtmf_table"));
956        GList *children=gtk_container_get_children(cont);
957        GList *elem;
958        for(elem=children;elem!=NULL;elem=elem->next){
959                GtkButton *button=GTK_BUTTON(elem->data);
960                g_signal_connect(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_dtmf_clicked,NULL);
961        }
962}
963
964static void linphone_gtk_check_menu_items(void){
965        bool_t audio_only=!linphone_core_video_enabled(linphone_gtk_get_core());
966        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(linphone_gtk_get_widget(
967                                        linphone_gtk_get_main_window(),
968                                        audio_only ? "audio_only_item" : "video_item")), TRUE);
969}
970
971static gboolean linphone_gtk_can_manage_accounts(){
972        LinphoneCore *lc=linphone_gtk_get_core();
973        const MSList *elem;
974        for(elem=linphone_core_get_sip_setups(lc);elem!=NULL;elem=elem->next){
975                SipSetup *ss=(SipSetup*)elem->data;
976                if (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_ACCOUNT_MANAGER){
977                        return TRUE;
978                }
979        }
980        return FALSE;
981}
982
983static void linphone_gtk_configure_main_window(){
984        static gboolean config_loaded=FALSE;
985        static const char *title;
986        static const char *home;
987        static const char *start_call_icon;
988        static const char *stop_call_icon;
989        static gboolean update_check_menu;
990        GtkWidget *w=linphone_gtk_get_main_window();
991        if (!config_loaded){
992                title=linphone_gtk_get_ui_config("title","Linphone");
993                home=linphone_gtk_get_ui_config("home","http://www.linphone.org");
994                start_call_icon=linphone_gtk_get_ui_config("start_call_icon","green.png");
995                stop_call_icon=linphone_gtk_get_ui_config("stop_call_icon","red.png");
996                update_check_menu=linphone_gtk_get_ui_config_int("update_check_menu",0);
997                config_loaded=TRUE;
998        }
999        linphone_gtk_configure_window(w,"main_window");
1000        if (title) {
1001                gtk_window_set_title(GTK_WINDOW(w),title);
1002#if GTK_CHECK_VERSION(2,16,0)
1003                gtk_menu_item_set_label(GTK_MENU_ITEM(linphone_gtk_get_widget(w,"main_menu")),title);
1004#endif
1005        }
1006        if (start_call_icon){
1007                GdkPixbuf *pbuf=create_pixbuf(start_call_icon);
1008                gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"start_call_icon")),pbuf);
1009                g_object_unref(G_OBJECT(pbuf));
1010        }
1011        if (stop_call_icon){
1012                GdkPixbuf *pbuf=create_pixbuf(stop_call_icon);
1013                gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"terminate_call_icon")),pbuf);
1014                gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"in_call_terminate_icon")),pbuf);
1015                g_object_unref(G_OBJECT(pbuf));
1016        }
1017        if (home){
1018                gchar *tmp;
1019                GtkWidget *menu_item=linphone_gtk_get_widget(w,"home_item");
1020                tmp=g_strdup(home);
1021                g_object_set_data(G_OBJECT(menu_item),"home",tmp);
1022        }
1023        if (!linphone_gtk_can_manage_accounts())
1024                gtk_widget_hide(linphone_gtk_get_widget(w,"run_assistant"));
1025        if (update_check_menu){
1026                gtk_widget_show(linphone_gtk_get_widget(w,"versioncheck"));
1027        }
1028}
1029
1030void linphone_gtk_manage_login(void){
1031        LinphoneCore *lc=linphone_gtk_get_core();
1032        LinphoneProxyConfig *cfg=NULL;
1033        linphone_core_get_default_proxy(lc,&cfg);
1034        if (cfg){
1035                SipSetup *ss=linphone_proxy_config_get_sip_setup(cfg);
1036                if (ss && (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_LOGIN)){
1037                        linphone_gtk_show_login_frame(cfg);
1038                }
1039        }
1040}
1041
1042static void linphone_gtk_init_main_window(){
1043        linphone_gtk_configure_main_window();
1044        linphone_gtk_manage_login();
1045        load_uri_history();
1046        linphone_gtk_load_identities();
1047        linphone_gtk_set_my_presence(linphone_core_get_presence_info(linphone_gtk_get_core()));
1048        linphone_gtk_show_friends();
1049        linphone_gtk_connect_digits();
1050        linphone_gtk_check_menu_items();
1051        linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),
1052                                        "main_mute")),FALSE);
1053        linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),
1054                                        "incall_mute")),FALSE);
1055        if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started(
1056                linphone_gtk_get_main_window());/*hide the call button, show terminate button*/
1057}
1058
1059void linphone_gtk_close(){
1060        /* couldn't find a way to prevent closing to destroy the main window*/
1061        LinphoneCore *lc=linphone_gtk_get_core();
1062        the_ui=NULL;
1063        the_ui=linphone_gtk_create_window("main");
1064        linphone_gtk_init_main_window();
1065        /*shutdown call if any*/
1066        if (linphone_core_in_call(lc)){
1067                linphone_core_terminate_call(lc,NULL);
1068                linphone_gtk_call_terminated(NULL);
1069        }
1070        linphone_core_enable_video_preview(lc,FALSE);
1071}
1072
1073void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
1074        if (verbose){
1075                const char *lname="undef";
1076                char *msg;
1077                #ifdef __linux
1078                va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
1079                #endif
1080                switch(lev){
1081                        case ORTP_DEBUG:
1082                                lname="debug";
1083                                break;
1084                        case ORTP_MESSAGE:
1085                                lname="message";
1086                                break;
1087                        case ORTP_WARNING:
1088                                lname="warning";
1089                                break;
1090                        case ORTP_ERROR:
1091                                lname="error";
1092                                break;
1093                        case ORTP_FATAL:
1094                                lname="fatal";
1095                                break;
1096                        default:
1097                                g_error("Bad level !");
1098                }
1099#ifdef __linux
1100                va_copy(cap,args);
1101                msg=g_strdup_vprintf(fmt,cap);
1102                va_end(cap);
1103#else
1104                msg=g_strdup_vprintf(fmt,args);
1105#endif
1106                fprintf(stdout,"linphone-%s : %s\n",lname,msg);
1107                ortp_free(msg);
1108        }
1109        linphone_gtk_log_push(lev,fmt,args);
1110}
1111
1112
1113static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to){
1114    GtkEntry * uri_bar =GTK_ENTRY(linphone_gtk_get_widget(
1115                linphone_gtk_get_main_window(), "uribar"));
1116        linphone_gtk_show_main_window();
1117        gtk_entry_set_text(uri_bar, refer_to);
1118        linphone_gtk_start_call(linphone_gtk_get_main_window());
1119}
1120
1121int main(int argc, char *argv[]){
1122#ifdef ENABLE_NLS
1123        void *p;
1124#endif
1125        const char *config_file;
1126        const char *lang;
1127
1128        g_thread_init(NULL);
1129        gdk_threads_init();
1130       
1131        config_file=linphone_gtk_get_config_file();
1132
1133#ifdef WIN32
1134        /*workaround for windows: sometimes LANG is defined to an integer value, not understood by gtk */
1135        if ((lang=getenv("LANG"))!=NULL){
1136                if (atoi(lang)!=0){
1137                        char tmp[128];
1138                        snprintf(tmp,sizeof(tmp),"LANG=",lang);
1139                        _putenv(tmp);
1140                }
1141        }
1142#endif
1143
1144        if ((lang=linphone_gtk_get_lang(config_file))!=NULL && lang[0]!='\0'){
1145#ifdef WIN32
1146                char tmp[128];
1147                snprintf(tmp,sizeof(tmp),"LANG=%s",lang);
1148                _putenv(tmp);
1149#else
1150                setenv("LANG",lang,1);
1151#endif
1152        }
1153
1154#ifdef ENABLE_NLS
1155        p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
1156        if (p==NULL) perror("bindtextdomain failed");
1157        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1158        textdomain (GETTEXT_PACKAGE);
1159#else
1160        g_message("NLS disabled.\n");
1161#endif
1162#ifdef WIN32
1163        gtk_rc_add_default_file("./gtkrc");
1164#endif
1165        gdk_threads_enter();
1166       
1167        if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"),
1168                                linphone_options,NULL,NULL)){
1169                gdk_threads_leave();
1170                return -1;
1171        }
1172#ifdef WIN32
1173        if (workingdir!=NULL)
1174                _chdir(workingdir);
1175#endif
1176
1177        if (linphone_core_wake_up_possible_already_running_instance(
1178                config_file, addr_to_call) == 0){
1179                g_message("addr_to_call=%s",addr_to_call);
1180                g_warning("Another running instance of linphone has been detected. It has been woken-up.");
1181                g_warning("This instance is going to exit now.");
1182                gdk_threads_leave();
1183                return 0;
1184        }
1185
1186        add_pixmap_directory("pixmaps");
1187        add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone");
1188
1189        the_ui=linphone_gtk_create_window("main");
1190       
1191        linphone_gtk_create_log_window();
1192        linphone_core_enable_logs_with_cb(linphone_gtk_log_handler);
1193
1194        linphone_gtk_init_liblinphone(config_file);
1195        /* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/
1196        gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
1197        gtk_timeout_add(30,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL);
1198        linphone_gtk_init_main_window();
1199        linphone_gtk_init_status_icon();
1200        if (!iconified)
1201                linphone_gtk_show_main_window();
1202        if (linphone_gtk_get_ui_config_int("update_check_menu",0)==0)
1203                linphone_gtk_check_for_new_version();
1204
1205        gtk_main();
1206        gdk_threads_leave();
1207        linphone_gtk_destroy_log_window();
1208        linphone_core_destroy(the_core);
1209        /*workaround a bug on win32 that makes status icon still present in the systray even after program exit.*/
1210        gtk_status_icon_set_visible(icon,FALSE);
1211        return 0;
1212}
Note: See TracBrowser for help on using the repository browser.