source: mediastreamer2/linphone/gtk-glade/main.c @ 174:34fbf3171bf6

Last change on this file since 174:34fbf3171bf6 was 174:34fbf3171bf6, checked in by smorlat <smorlat@…>, 5 years ago

-fix warnings (contributed patches)
-pressing enter in uri bar calls.

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

File size: 25.3 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 "lpconfig.h"
23
24#include "linphone.h"
25
26#ifdef USE_LIBGLADE
27#include <glade/glade.h>
28#endif
29
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <unistd.h>
33
34#ifndef GETTEXT_PACKAGE
35#define GETTEXT_PACKAGE "linphone"
36#endif
37
38#ifndef PACKAGE_LOCALE_DIR
39#define PACKAGE_LOCALE_DIR "po"
40#endif
41
42
43static LinphoneCore *the_core=NULL;
44static GtkWidget *the_ui=NULL;
45
46static void linphone_gtk_show(LinphoneCore *lc);
47static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from);
48static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from);
49static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img);
50static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
51static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username);
52static void linphone_gtk_display_status(LinphoneCore *lc, const char *status);
53static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg);
54static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning);
55static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
56static void linphone_gtk_display_question(LinphoneCore *lc, const char *question);
57static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl);
58static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate);
59
60static LinphoneCoreVTable vtable={
61        .show=linphone_gtk_show,
62        .inv_recv=linphone_gtk_inv_recv,
63        .bye_recv=linphone_gtk_bye_recv,
64        .notify_recv=linphone_gtk_notify_recv,
65        .new_unknown_subscriber=linphone_gtk_new_unknown_subscriber,
66        .auth_info_requested=linphone_gtk_auth_info_requested,
67        .display_status=linphone_gtk_display_status,
68        .display_message=linphone_gtk_display_message,
69        .display_warning=linphone_gtk_display_warning,
70        .display_url=linphone_gtk_display_url,
71        .display_question=linphone_gtk_display_question,
72        .call_log_updated=linphone_gtk_call_log_updated,
73        .text_received=linphone_gtk_text_received,
74        .general_state=linphone_gtk_general_state
75};
76
77static gboolean verbose=0;
78static GOptionEntry linphone_options[2]={
79        {
80                .long_name="verbose",
81                .short_name= '\0',
82                .arg=G_OPTION_ARG_NONE,
83                .arg_data= (gpointer)&verbose,
84                .description="log to stdout some debug information while running."
85        }
86};
87
88#define INSTALLED_XML_DIR PACKAGE_DATA_DIR "/linphone"
89#define BUILD_TREE_XML_DIR "gtk-glade"
90#define CONFIG_FILE ".linphonerc"
91
92static char _config_file[1024];
93
94const char *linphone_gtk_get_config_file(){
95        const char *home;
96        /*try accessing a local file first if exists*/
97        if (access(CONFIG_FILE,F_OK)==0){
98                snprintf(_config_file,sizeof(_config_file),"%s",CONFIG_FILE);
99        }else{
100#ifdef WIN32
101                const char *appdata=getenv("APPDATA");
102                if (appdata){
103                        snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,"Linphone\\");
104                        CreateDirectory(_config_file,NULL);
105                        snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,"Linphone\\linphonerc");
106                }
107#else
108                home=getenv("HOME");
109                if (home==NULL) home="";
110                snprintf(_config_file,sizeof(_config_file),"%s/%s",home,CONFIG_FILE);
111#endif
112        }
113        return _config_file;
114}
115
116static void linphone_gtk_init_liblinphone(const char *file){
117        the_core=linphone_core_new(&vtable,file,NULL);
118}
119
120
121
122LinphoneCore *linphone_gtk_get_core(void){
123        return the_core;
124}
125
126GtkWidget *linphone_gtk_get_main_window(){
127        return the_ui;
128}
129
130#ifdef USE_LIBGLADE
131
132GtkWidget *linphone_gtk_create_window(const char *window_name){
133        GtkWidget *w;
134        GladeXML *gxml;
135        char path[2048];
136        snprintf(path,sizeof(path),"%s/%s.glade",BUILD_TREE_XML_DIR,window_name);
137        if (access(path,F_OK)!=0){
138                snprintf(path,sizeof(path),"%s/%s.glade",INSTALLED_XML_DIR,window_name);
139                if (access(path,F_OK)!=0){
140                        g_error("Could not locate neither %s/%s.glade and %s/%s.glade .",BUILD_TREE_XML_DIR,window_name,
141                                INSTALLED_XML_DIR,window_name);
142                        return NULL;
143                }
144        }
145        gxml=glade_xml_new(path,NULL,NULL);
146        glade_xml_signal_autoconnect(gxml);
147        w=glade_xml_get_widget(gxml,window_name);
148        if (w==NULL) g_error("Could not retrieve '%s' window from xml file",window_name);
149        return w;
150}
151
152GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
153        GtkWidget *w;
154        GladeXML *gxml=glade_get_widget_tree(window);
155        if (gxml==NULL) g_error("Could not retrieve XML tree of window %s",name);
156        w=glade_xml_get_widget(gxml,name);
157        if (w==NULL) g_error("Could not retrieve widget %s",name);
158        return GTK_WIDGET(w);
159}
160
161#else
162
163GtkWidget *linphone_gtk_create_window(const char *window_name){
164       
165}
166
167GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
168        GObject *w=gtk_builder_get_object(the_ui,name);
169        if (w==NULL){
170                g_error("No widget named %s found in xml interface.",name);
171        }
172        return GTK_WIDGET(w);
173}
174
175#endif
176
177void linphone_gtk_display_something(GtkMessageType type,const gchar *message){
178        GtkWidget *dialog;
179        GtkWidget *main_window=linphone_gtk_get_main_window();
180       
181        gtk_widget_show(main_window);
182        if (type==GTK_MESSAGE_QUESTION)
183        {
184                /* draw a question box. link to dialog_click callback */
185                dialog = gtk_message_dialog_new (
186                                GTK_WINDOW(main_window),
187                                GTK_DIALOG_DESTROY_WITH_PARENT,
188                                GTK_MESSAGE_QUESTION,
189                                GTK_BUTTONS_YES_NO,
190                                "%s",
191                                (const gchar*)message);
192                /* connect to some callback : REVISIT */
193                /*
194                g_signal_connect_swapped (G_OBJECT (dialog), "response",
195                           G_CALLBACK (dialog_click),
196                           G_OBJECT (dialog));
197                */
198                /* actually show the box */
199                gtk_widget_show(dialog);
200        }
201        else
202        {
203                dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
204                                  GTK_DIALOG_DESTROY_WITH_PARENT,
205                                  type,
206                                  GTK_BUTTONS_CLOSE,
207                                  "%s",
208                                  (const gchar*)message);
209                /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
210                g_signal_connect_swapped (G_OBJECT (dialog), "response",
211                           G_CALLBACK (gtk_widget_destroy),
212                           G_OBJECT (dialog));
213                gtk_widget_show(dialog);
214        }
215}
216
217void linphone_gtk_about_response(GtkDialog *dialog, gint id){
218        if (id==GTK_RESPONSE_CANCEL){
219                gtk_widget_destroy(GTK_WIDGET(dialog));
220        }
221}
222
223void linphone_gtk_show_about(){
224        struct stat filestat;
225        const char *license_file=PACKAGE_DATA_DIR "/doc/COPYING";
226        GtkWidget *about;
227
228        about=linphone_gtk_create_window("about");
229        memset(&filestat,0,sizeof(filestat));
230        if (stat(license_file,&filestat)!=0){
231                license_file="COPYING";
232                stat(license_file,&filestat);
233        }
234        if (filestat.st_size>0){
235                char *license=g_malloc(filestat.st_size+1);
236                FILE *f=fopen(license_file,"r");
237                if (f && fread(license,filestat.st_size,1,f)==1){
238                        license[filestat.st_size]='\0';
239                        gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about),license);
240                }
241                g_free(license);
242        }
243        gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LINPHONE_VERSION);
244
245        gtk_widget_show(about);
246}
247
248static gboolean linphone_gtk_iterate(LinphoneCore *lc){
249        linphone_core_iterate(lc);
250        return TRUE;
251}
252
253static void load_uri_history(){
254        GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
255        LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core());
256        char key[20];
257        int i;
258        GtkEntryCompletion *gep=gtk_entry_completion_new();
259        GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING);
260        for (i=0;;i++){
261                const char *uri;
262                snprintf(key,sizeof(key),"uri%i",i);
263                uri=lp_config_get_string(cfg,"GtkUi",key,NULL);
264                if (uri!=NULL) {
265                        GtkTreeIter iter;
266                        gtk_list_store_append(model,&iter);
267                        gtk_list_store_set(model,&iter,0,uri,-1);
268                        if (i==0) gtk_entry_set_text(uribar,uri);
269                }
270                else break;
271        }
272        gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model));
273        gtk_entry_completion_set_text_column(gep,0);
274        gtk_entry_set_completion(uribar,gep);
275}
276
277static void save_uri_history(){
278        LinphoneCore *lc=linphone_gtk_get_core();
279        LpConfig *cfg=linphone_core_get_config(lc);
280        GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
281        char key[20];
282        int i=0;
283        char *uri=NULL;
284        GtkTreeIter iter;
285        GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar));
286
287        if (!gtk_tree_model_get_iter_first(model,&iter)) return;
288        do {
289                gtk_tree_model_get(model,&iter,0,&uri,-1);
290                if (uri) {
291                        snprintf(key,sizeof(key),"uri%i",i);
292                        lp_config_set_string(cfg,"GtkUi",key,uri);
293                        g_free(uri);
294                }else break;
295                i++;
296                if (i>5) break;
297        }while(gtk_tree_model_iter_next(model,&iter));
298        lp_config_sync(cfg);
299}
300
301static void completion_add_text(GtkEntry *entry, const char *text){
302        GtkTreeIter iter;
303        GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry));
304       
305        if (gtk_tree_model_get_iter_first(model,&iter)){ 
306                do {
307                        gchar *uri=NULL;
308                        gtk_tree_model_get(model,&iter,0,&uri,-1);
309                        if (uri!=NULL){
310                                if (strcmp(uri,text)==0) {
311                                        /*remove text */
312                                        gtk_list_store_remove(GTK_LIST_STORE(model),&iter);
313                                        g_free(uri);
314                                        break;
315                                }
316                                g_free(uri);
317                        }
318                }while (gtk_tree_model_iter_next(model,&iter));
319        }
320        /* and prepend it on top of the list */
321        gtk_list_store_prepend(GTK_LIST_STORE(model),&iter);
322        gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1);
323        save_uri_history();
324}
325
326static void linphone_gtk_call_started(GtkWidget *mw){
327        gtk_widget_hide(linphone_gtk_get_widget(mw,"start_call"));
328        gtk_widget_show(linphone_gtk_get_widget(mw,"terminate_call"));
329}
330
331void linphone_gtk_start_call(GtkWidget *w){
332        LinphoneCore *lc=linphone_gtk_get_core();
333        if (linphone_core_inc_invite_pending(lc)){
334                /*already in call */
335        }else{
336                GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"uribar");
337                const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar));
338                if (linphone_core_invite(lc,entered)==0) {
339                        linphone_gtk_call_started(linphone_gtk_get_main_window());
340                        completion_add_text(GTK_ENTRY(uri_bar),entered);
341                }
342        }
343}
344
345void linphone_gtk_uri_bar_activate(GtkWidget *w){
346        linphone_gtk_start_call(w);
347}
348
349
350static void linphone_gtk_call_terminated(GtkWidget *mw){
351        gtk_widget_hide(linphone_gtk_get_widget(mw,"terminate_call"));
352        gtk_widget_show(linphone_gtk_get_widget(mw,"start_call"));
353        g_object_set_data(G_OBJECT(mw),"incoming_call",NULL);
354}
355
356void linphone_gtk_terminate_call(GtkWidget *button){
357        linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
358        linphone_gtk_call_terminated(gtk_widget_get_toplevel(button));
359}
360
361void linphone_gtk_decline_call(GtkWidget *button){
362        linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
363        linphone_gtk_call_terminated(linphone_gtk_get_main_window());
364        gtk_widget_destroy(gtk_widget_get_toplevel(button));
365}
366
367void linphone_gtk_accept_call(GtkWidget *button){
368        linphone_core_accept_call(linphone_gtk_get_core(),NULL);
369        g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",NULL);
370        gtk_widget_destroy(gtk_widget_get_toplevel(button));
371        linphone_gtk_call_started(linphone_gtk_get_main_window());
372}
373
374void linphone_gtk_set_audio_video(){
375        linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE);
376}
377
378void linphone_gtk_set_audio_only(){
379        linphone_core_enable_video(linphone_gtk_get_core(),FALSE,FALSE);
380}
381
382void linphone_gtk_used_identity_changed(GtkWidget *w){
383        int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
384        char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
385        if (sel && strlen(sel)>0) //avoid a dummy "changed" at gui startup
386                linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1));
387}
388
389static void linphone_gtk_show_main_window(){
390        GtkWidget *w=linphone_gtk_get_main_window();
391        LinphoneCore *lc=linphone_gtk_get_core();
392        linphone_core_enable_video_preview(lc,linphone_core_video_enabled(lc));
393        gtk_widget_show(w);
394        gtk_window_present(GTK_WINDOW(w));
395}
396
397static void linphone_gtk_show(LinphoneCore *lc){
398        linphone_gtk_show_main_window();
399}
400
401static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){
402        GtkWidget *w=linphone_gtk_create_window("incoming_call");
403        GtkWidget *label;
404        gchar *msg;
405        gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window()));
406        gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT);
407
408        label=linphone_gtk_get_widget(w,"message");
409        msg=g_strdup_printf(_("Incoming call from %s"),from);
410        gtk_label_set_text(GTK_LABEL(label),msg);
411        gtk_window_set_title(GTK_WINDOW(w),msg);
412        gtk_widget_show(w);
413        gtk_window_present(GTK_WINDOW(w));
414        /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/
415        g_free(msg);
416        g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w);
417        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),
418                        from);
419}
420
421static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){
422        GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call"));
423        if (icw!=NULL){
424                gtk_widget_destroy(icw);
425        }
426        linphone_gtk_call_terminated(linphone_gtk_get_main_window());
427}
428
429static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img){
430}
431
432static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint response_id, LinphoneFriend *lf){
433        switch(response_id){
434                case GTK_RESPONSE_YES:
435                        linphone_gtk_show_contact(lf);
436                break;
437                default:
438                        linphone_core_reject_subscriber(linphone_gtk_get_core(),lf);
439        }
440        gtk_widget_destroy(dialog);
441}
442
443static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
444        GtkWidget *dialog;
445        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);
446        dialog = gtk_message_dialog_new (
447                                GTK_WINDOW(linphone_gtk_get_main_window()),
448                                GTK_DIALOG_DESTROY_WITH_PARENT,
449                                GTK_MESSAGE_QUESTION,
450                                GTK_BUTTONS_YES_NO,
451                                "%s",
452                                message);
453        g_free(message);
454        g_signal_connect(G_OBJECT (dialog), "response",
455                G_CALLBACK (linphone_gtk_new_subscriber_response),lf);
456        /* actually show the box */
457        gtk_widget_show(dialog);
458}
459
460typedef struct _AuthTimeout{
461        GtkWidget *w;
462} AuthTimeout;
463
464
465static void auth_timeout_clean(AuthTimeout *tout){
466        tout->w=NULL;
467}
468
469static gboolean auth_timeout_destroy(AuthTimeout *tout){
470        if (tout->w)  {
471                g_object_weak_unref(G_OBJECT(tout->w),(GWeakNotify)auth_timeout_clean,tout);
472                gtk_widget_destroy(tout->w);
473        }
474        g_free(tout);
475        return FALSE;
476}
477
478static AuthTimeout * auth_timeout_new(GtkWidget *w){
479        AuthTimeout *tout=g_new(AuthTimeout,1);
480        tout->w=w;
481        /*so that the timeout no more references the widget when it is destroyed:*/
482        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)auth_timeout_clean,tout);
483        /*so that the widget is automatically destroyed after some time */
484        g_timeout_add(30000,(GtkFunction)auth_timeout_destroy,tout);
485        return tout;
486}
487
488void linphone_gtk_password_cancel(GtkWidget *w){
489        LinphoneAuthInfo *info;
490        GtkWidget *window=gtk_widget_get_toplevel(w);
491        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
492        linphone_core_abort_authentication(linphone_gtk_get_core(),info);
493        gtk_widget_destroy(window);
494}
495
496void linphone_gtk_password_ok(GtkWidget *w){
497        GtkWidget *entry;
498        GtkWidget *window=gtk_widget_get_toplevel(w);
499        LinphoneAuthInfo *info;
500        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
501        g_object_weak_unref(G_OBJECT(window),(GWeakNotify)linphone_auth_info_destroy,info);
502        entry=linphone_gtk_get_widget(window,"password_entry");
503        linphone_auth_info_set_passwd(info,gtk_entry_get_text(GTK_ENTRY(entry)));
504        linphone_auth_info_set_username(info,
505                gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(window,"username_entry"))));
506        linphone_core_add_auth_info(linphone_gtk_get_core(),info);
507        gtk_widget_destroy(window);
508}
509
510static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username){
511        GtkWidget *w=linphone_gtk_create_window("password");
512        GtkWidget *label=linphone_gtk_get_widget(w,"message");
513        LinphoneAuthInfo *info;
514        gchar *msg;
515        msg=g_strdup_printf(_("Please enter your password for domain %s:"),realm);
516        gtk_label_set_text(GTK_LABEL(label),msg);
517        g_free(msg);
518        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"username_entry")),username);
519        info=linphone_auth_info_new(username, NULL, NULL, NULL,realm);
520        g_object_set_data(G_OBJECT(w),"auth_info",info);
521        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_auth_info_destroy,info);
522        gtk_widget_show(w);
523        auth_timeout_new(w);
524}
525
526static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){
527        GtkWidget *w=linphone_gtk_get_main_window();
528        GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar");
529        gtk_statusbar_push(GTK_STATUSBAR(status_bar),
530                        gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),""),
531                        status);
532}
533
534static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){
535        linphone_gtk_display_something(GTK_MESSAGE_INFO,msg);
536}
537
538static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning){
539        linphone_gtk_display_something(GTK_MESSAGE_WARNING,warning);
540}
541
542static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url){
543        char richtext[4096];
544        snprintf(richtext,sizeof(richtext),"%s %s",msg,url);
545        linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext);
546}
547
548static void linphone_gtk_display_question(LinphoneCore *lc, const char *question){
549        linphone_gtk_display_something(GTK_MESSAGE_QUESTION,question);
550}
551
552static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){
553        GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
554        if (w) linphone_gtk_call_log_update(w);
555}
556
557static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
558}
559
560
561static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
562        GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
563        gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
564}
565
566static GtkWidget *create_icon_menu(){
567        GtkWidget *menu=gtk_menu_new();
568        GtkWidget *menu_item;
569        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,NULL);
570        gtk_widget_show(menu_item);
571        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
572        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_about,NULL);
573        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,NULL);
574        gtk_widget_show(menu_item);
575        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
576        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)gtk_main_quit,NULL);
577        gtk_widget_show(menu);
578        return menu;
579}
580
581static GtkStatusIcon *icon=NULL;
582
583static void linphone_gtk_init_status_icon(){
584        GdkPixbuf *pbuf=create_pixbuf("linphone2.png");
585        GtkWidget *menu=create_icon_menu();
586        icon=gtk_status_icon_new_from_pixbuf(pbuf);
587        g_object_unref(G_OBJECT(pbuf));
588        g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)linphone_gtk_show_main_window,linphone_gtk_get_main_window());
589        g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL);
590        gtk_status_icon_set_tooltip(icon,_("Linphone - a video internet phone"));
591        g_object_set_data(G_OBJECT(icon),"menu",menu);
592        g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu);
593}
594
595void linphone_gtk_load_identities(void){
596        const MSList *elem;
597        GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities"));
598        char *def_identity;
599        LinphoneProxyConfig *def=NULL;
600        int def_index=0,i;
601        GtkListStore *store;
602
603        store=GTK_LIST_STORE(gtk_combo_box_get_model(box));
604        gtk_list_store_clear(store);
605
606        linphone_core_get_default_proxy(linphone_gtk_get_core(),&def);
607        def_identity=g_strdup_printf(_("%s (Default)"),linphone_core_get_primary_contact(linphone_gtk_get_core()));
608        gtk_combo_box_append_text(box,def_identity);
609        g_free(def_identity);
610        for(i=1,elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());
611                        elem!=NULL;
612                        elem=ms_list_next(elem),i++){
613                LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
614                gtk_combo_box_append_text(box,linphone_proxy_config_get_identity(cfg));
615                if (cfg==def) {
616                        def_index=i;
617                }
618        }
619        gtk_combo_box_set_active(box,def_index);
620}
621
622static void linphone_gtk_dtmf_clicked(GtkButton *button){
623        const char *label=gtk_button_get_label(button);
624        linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]);
625}
626
627static void linphone_gtk_connect_digits(void){
628        GtkContainer *cont=GTK_CONTAINER(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"dtmf_table"));
629        GList *children=gtk_container_get_children(cont);
630        GList *elem;
631        for(elem=children;elem!=NULL;elem=elem->next){
632                GtkButton *button=GTK_BUTTON(elem->data);
633                g_signal_connect(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_dtmf_clicked,NULL);
634        }
635}
636
637static void linphone_gtk_check_menu_items(void){
638        bool_t audio_only=!linphone_core_video_enabled(linphone_gtk_get_core());
639        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(linphone_gtk_get_widget(
640                                        linphone_gtk_get_main_window(),
641                                        audio_only ? "audio_only_item" : "video_item")), TRUE);
642}
643
644static void linphone_gtk_configure_main_window(){
645        static LpConfig *conf=NULL;
646        static int show_digits=1;
647        GtkWidget *w=linphone_gtk_get_main_window();
648        if (conf==NULL){
649                conf=linphone_core_get_config(linphone_gtk_get_core());
650                show_digits=lp_config_get_int(conf,"GtkUi","show_digits",show_digits);
651        }
652        if (show_digits==0) gtk_widget_hide(linphone_gtk_get_widget(w,"dialpad"));
653}
654
655static void linphone_gtk_init_main_window(){
656        linphone_gtk_configure_main_window();
657        load_uri_history();
658        linphone_gtk_load_identities();
659        linphone_gtk_set_my_presence(linphone_core_get_presence_info(linphone_gtk_get_core()));
660        linphone_gtk_show_friends();
661        linphone_gtk_connect_digits();
662        linphone_gtk_check_menu_items();
663        if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started(
664                linphone_gtk_get_main_window());/*hide the call button, show terminate button*/
665}
666
667void linphone_gtk_close(){
668        /* couldn't find a way to prevent closing to destroy the main window*/
669        linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
670        the_ui=NULL;
671        the_ui=linphone_gtk_create_window("main");
672        linphone_gtk_init_main_window();
673}
674
675void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
676        if (verbose){
677                const char *lname="undef";
678                char *msg;
679                #ifdef __linux
680                va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
681                #endif
682                switch(lev){
683                        case ORTP_DEBUG:
684                                lname="debug";
685                                break;
686                        case ORTP_MESSAGE:
687                                lname="message";
688                                break;
689                        case ORTP_WARNING:
690                                lname="warning";
691                                break;
692                        case ORTP_ERROR:
693                                lname="error";
694                                break;
695                        case ORTP_FATAL:
696                                lname="fatal";
697                                break;
698                        default:
699                                g_error("Bad level !");
700                }
701#ifdef __linux
702                va_copy(cap,args);
703                msg=g_strdup_vprintf(fmt,cap);
704                va_end(cap);
705#else
706                msg=g_strdup_vprintf(fmt,args);
707#endif
708                fprintf(stdout,"linphone-%s : %s\n",lname,msg);
709                ortp_free(msg);
710        }
711        linphone_gtk_log_push(lev,fmt,args);
712}
713
714int main(int argc, char *argv[]){
715        void *p;
716        const char *config_file;
717        g_thread_init(NULL);
718        gdk_threads_init();
719#ifdef ENABLE_NLS
720        p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
721        if (p==NULL) perror("bindtextdomain failed");
722        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
723        textdomain (GETTEXT_PACKAGE);
724#else
725        g_message("NLS disabled.\n");
726#endif
727        config_file=linphone_gtk_get_config_file();
728        if (linphone_core_wake_up_possible_already_running_instance(config_file)==0){
729                g_warning("Another running instance of linphone has been detected. It has been woken-up.");
730                g_warning("This instance is going to exit now.");
731                return 0;
732        }
733        gdk_threads_enter();
734        if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"),
735                                linphone_options,NULL,NULL)){
736                gdk_threads_leave();
737                return -1;
738        }
739       
740        add_pixmap_directory("pixmaps");
741        add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone");
742#ifdef WIN32
743        add_pixmap_directory("linphone");
744#endif
745
746        the_ui=linphone_gtk_create_window("main");
747       
748        linphone_gtk_create_log_window();
749        linphone_core_enable_logs_with_cb(linphone_gtk_log_handler);
750
751        linphone_gtk_init_liblinphone(config_file);
752        gtk_timeout_add(20,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
753        gtk_timeout_add(20,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL);
754        linphone_gtk_init_main_window();
755        linphone_gtk_init_status_icon();
756        gtk_widget_show(the_ui);
757        gtk_main();
758        gdk_threads_leave();
759        linphone_gtk_destroy_log_window();
760        linphone_core_destroy(the_core);
761        /*workaround a bug on win32 that makes status icon still present in the systray even after program exit.*/
762        gtk_status_icon_set_visible(icon,FALSE);
763        return 0;
764}
765
766
Note: See TracBrowser for help on using the repository browser.