source: mediastreamer2/linphone/gtk-glade/main.c @ 194:dd674a337c93

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

fix some little bugs concerning selfview.

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

File size: 25.7 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        linphone_core_enable_video_preview(linphone_gtk_get_core(),TRUE);
377}
378
379void linphone_gtk_set_audio_only(){
380        linphone_core_enable_video(linphone_gtk_get_core(),FALSE,FALSE);
381        linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
382}
383
384void linphone_gtk_enable_self_view(GtkWidget *w){
385        linphone_core_enable_self_view(linphone_gtk_get_core(),
386                gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
387}
388
389void linphone_gtk_used_identity_changed(GtkWidget *w){
390        int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
391        char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
392        if (sel && strlen(sel)>0) //avoid a dummy "changed" at gui startup
393                linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1));
394}
395
396static void linphone_gtk_show_main_window(){
397        GtkWidget *w=linphone_gtk_get_main_window();
398        LinphoneCore *lc=linphone_gtk_get_core();
399        linphone_core_enable_video_preview(lc,linphone_core_video_enabled(lc));
400        gtk_widget_show(w);
401        gtk_window_present(GTK_WINDOW(w));
402}
403
404static void linphone_gtk_show(LinphoneCore *lc){
405        linphone_gtk_show_main_window();
406}
407
408static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){
409        GtkWidget *w=linphone_gtk_create_window("incoming_call");
410        GtkWidget *label;
411        gchar *msg;
412        gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window()));
413        gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT);
414
415        label=linphone_gtk_get_widget(w,"message");
416        msg=g_strdup_printf(_("Incoming call from %s"),from);
417        gtk_label_set_text(GTK_LABEL(label),msg);
418        gtk_window_set_title(GTK_WINDOW(w),msg);
419        gtk_widget_show(w);
420        gtk_window_present(GTK_WINDOW(w));
421        /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/
422        g_free(msg);
423        g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w);
424        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),
425                        from);
426}
427
428static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){
429        GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call"));
430        if (icw!=NULL){
431                gtk_widget_destroy(icw);
432        }
433        linphone_gtk_call_terminated(linphone_gtk_get_main_window());
434}
435
436static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img){
437}
438
439static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint response_id, LinphoneFriend *lf){
440        switch(response_id){
441                case GTK_RESPONSE_YES:
442                        linphone_gtk_show_contact(lf);
443                break;
444                default:
445                        linphone_core_reject_subscriber(linphone_gtk_get_core(),lf);
446        }
447        gtk_widget_destroy(dialog);
448}
449
450static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
451        GtkWidget *dialog;
452        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);
453        dialog = gtk_message_dialog_new (
454                                GTK_WINDOW(linphone_gtk_get_main_window()),
455                                GTK_DIALOG_DESTROY_WITH_PARENT,
456                                GTK_MESSAGE_QUESTION,
457                                GTK_BUTTONS_YES_NO,
458                                "%s",
459                                message);
460        g_free(message);
461        g_signal_connect(G_OBJECT (dialog), "response",
462                G_CALLBACK (linphone_gtk_new_subscriber_response),lf);
463        /* actually show the box */
464        gtk_widget_show(dialog);
465}
466
467typedef struct _AuthTimeout{
468        GtkWidget *w;
469} AuthTimeout;
470
471
472static void auth_timeout_clean(AuthTimeout *tout){
473        tout->w=NULL;
474}
475
476static gboolean auth_timeout_destroy(AuthTimeout *tout){
477        if (tout->w)  {
478                g_object_weak_unref(G_OBJECT(tout->w),(GWeakNotify)auth_timeout_clean,tout);
479                gtk_widget_destroy(tout->w);
480        }
481        g_free(tout);
482        return FALSE;
483}
484
485static AuthTimeout * auth_timeout_new(GtkWidget *w){
486        AuthTimeout *tout=g_new(AuthTimeout,1);
487        tout->w=w;
488        /*so that the timeout no more references the widget when it is destroyed:*/
489        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)auth_timeout_clean,tout);
490        /*so that the widget is automatically destroyed after some time */
491        g_timeout_add(30000,(GtkFunction)auth_timeout_destroy,tout);
492        return tout;
493}
494
495void linphone_gtk_password_cancel(GtkWidget *w){
496        LinphoneAuthInfo *info;
497        GtkWidget *window=gtk_widget_get_toplevel(w);
498        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
499        linphone_core_abort_authentication(linphone_gtk_get_core(),info);
500        gtk_widget_destroy(window);
501}
502
503void linphone_gtk_password_ok(GtkWidget *w){
504        GtkWidget *entry;
505        GtkWidget *window=gtk_widget_get_toplevel(w);
506        LinphoneAuthInfo *info;
507        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
508        g_object_weak_unref(G_OBJECT(window),(GWeakNotify)linphone_auth_info_destroy,info);
509        entry=linphone_gtk_get_widget(window,"password_entry");
510        linphone_auth_info_set_passwd(info,gtk_entry_get_text(GTK_ENTRY(entry)));
511        linphone_auth_info_set_username(info,
512                gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(window,"username_entry"))));
513        linphone_core_add_auth_info(linphone_gtk_get_core(),info);
514        gtk_widget_destroy(window);
515}
516
517static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username){
518        GtkWidget *w=linphone_gtk_create_window("password");
519        GtkWidget *label=linphone_gtk_get_widget(w,"message");
520        LinphoneAuthInfo *info;
521        gchar *msg;
522        msg=g_strdup_printf(_("Please enter your password for domain %s:"),realm);
523        gtk_label_set_text(GTK_LABEL(label),msg);
524        g_free(msg);
525        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"username_entry")),username);
526        info=linphone_auth_info_new(username, NULL, NULL, NULL,realm);
527        g_object_set_data(G_OBJECT(w),"auth_info",info);
528        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_auth_info_destroy,info);
529        gtk_widget_show(w);
530        auth_timeout_new(w);
531}
532
533static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){
534        GtkWidget *w=linphone_gtk_get_main_window();
535        GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar");
536        gtk_statusbar_push(GTK_STATUSBAR(status_bar),
537                        gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),""),
538                        status);
539}
540
541static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){
542        linphone_gtk_display_something(GTK_MESSAGE_INFO,msg);
543}
544
545static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning){
546        linphone_gtk_display_something(GTK_MESSAGE_WARNING,warning);
547}
548
549static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url){
550        char richtext[4096];
551        snprintf(richtext,sizeof(richtext),"%s %s",msg,url);
552        linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext);
553}
554
555static void linphone_gtk_display_question(LinphoneCore *lc, const char *question){
556        linphone_gtk_display_something(GTK_MESSAGE_QUESTION,question);
557}
558
559static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){
560        GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
561        if (w) linphone_gtk_call_log_update(w);
562}
563
564static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
565}
566
567
568static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
569        GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
570        gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
571}
572
573static GtkWidget *create_icon_menu(){
574        GtkWidget *menu=gtk_menu_new();
575        GtkWidget *menu_item;
576        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,NULL);
577        gtk_widget_show(menu_item);
578        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
579        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_about,NULL);
580        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,NULL);
581        gtk_widget_show(menu_item);
582        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
583        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)gtk_main_quit,NULL);
584        gtk_widget_show(menu);
585        return menu;
586}
587
588static GtkStatusIcon *icon=NULL;
589
590static void linphone_gtk_init_status_icon(){
591        GdkPixbuf *pbuf=create_pixbuf("linphone2.png");
592        GtkWidget *menu=create_icon_menu();
593        icon=gtk_status_icon_new_from_pixbuf(pbuf);
594        g_object_unref(G_OBJECT(pbuf));
595        g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)linphone_gtk_show_main_window,linphone_gtk_get_main_window());
596        g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL);
597        gtk_status_icon_set_tooltip(icon,_("Linphone - a video internet phone"));
598        g_object_set_data(G_OBJECT(icon),"menu",menu);
599        g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu);
600}
601
602void linphone_gtk_load_identities(void){
603        const MSList *elem;
604        GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities"));
605        char *def_identity;
606        LinphoneProxyConfig *def=NULL;
607        int def_index=0,i;
608        GtkListStore *store;
609
610        store=GTK_LIST_STORE(gtk_combo_box_get_model(box));
611        gtk_list_store_clear(store);
612
613        linphone_core_get_default_proxy(linphone_gtk_get_core(),&def);
614        def_identity=g_strdup_printf(_("%s (Default)"),linphone_core_get_primary_contact(linphone_gtk_get_core()));
615        gtk_combo_box_append_text(box,def_identity);
616        g_free(def_identity);
617        for(i=1,elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());
618                        elem!=NULL;
619                        elem=ms_list_next(elem),i++){
620                LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
621                gtk_combo_box_append_text(box,linphone_proxy_config_get_identity(cfg));
622                if (cfg==def) {
623                        def_index=i;
624                }
625        }
626        gtk_combo_box_set_active(box,def_index);
627}
628
629static void linphone_gtk_dtmf_clicked(GtkButton *button){
630        const char *label=gtk_button_get_label(button);
631        linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]);
632}
633
634static void linphone_gtk_connect_digits(void){
635        GtkContainer *cont=GTK_CONTAINER(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"dtmf_table"));
636        GList *children=gtk_container_get_children(cont);
637        GList *elem;
638        for(elem=children;elem!=NULL;elem=elem->next){
639                GtkButton *button=GTK_BUTTON(elem->data);
640                g_signal_connect(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_dtmf_clicked,NULL);
641        }
642}
643
644static void linphone_gtk_check_menu_items(void){
645        bool_t audio_only=!linphone_core_video_enabled(linphone_gtk_get_core());
646        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(linphone_gtk_get_widget(
647                                        linphone_gtk_get_main_window(),
648                                        audio_only ? "audio_only_item" : "video_item")), TRUE);
649}
650
651static void linphone_gtk_configure_main_window(){
652        static LpConfig *conf=NULL;
653        static int show_digits=1;
654        GtkWidget *w=linphone_gtk_get_main_window();
655        if (conf==NULL){
656                conf=linphone_core_get_config(linphone_gtk_get_core());
657                show_digits=lp_config_get_int(conf,"GtkUi","show_digits",show_digits);
658        }
659        if (show_digits==0) gtk_widget_hide(linphone_gtk_get_widget(w,"dialpad"));
660}
661
662static void linphone_gtk_init_main_window(){
663        linphone_gtk_configure_main_window();
664        load_uri_history();
665        linphone_gtk_load_identities();
666        linphone_gtk_set_my_presence(linphone_core_get_presence_info(linphone_gtk_get_core()));
667        linphone_gtk_show_friends();
668        linphone_gtk_connect_digits();
669        linphone_gtk_check_menu_items();
670        if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started(
671                linphone_gtk_get_main_window());/*hide the call button, show terminate button*/
672}
673
674void linphone_gtk_close(){
675        /* couldn't find a way to prevent closing to destroy the main window*/
676        LinphoneCore *lc=linphone_gtk_get_core();
677        /*shutdown call if any*/
678        if (linphone_core_in_call(lc))
679                linphone_core_terminate_call(lc,NULL);
680        linphone_core_enable_video_preview(lc,FALSE);
681        the_ui=NULL;
682        the_ui=linphone_gtk_create_window("main");
683        linphone_gtk_init_main_window();
684}
685
686void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
687        if (verbose){
688                const char *lname="undef";
689                char *msg;
690                #ifdef __linux
691                va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
692                #endif
693                switch(lev){
694                        case ORTP_DEBUG:
695                                lname="debug";
696                                break;
697                        case ORTP_MESSAGE:
698                                lname="message";
699                                break;
700                        case ORTP_WARNING:
701                                lname="warning";
702                                break;
703                        case ORTP_ERROR:
704                                lname="error";
705                                break;
706                        case ORTP_FATAL:
707                                lname="fatal";
708                                break;
709                        default:
710                                g_error("Bad level !");
711                }
712#ifdef __linux
713                va_copy(cap,args);
714                msg=g_strdup_vprintf(fmt,cap);
715                va_end(cap);
716#else
717                msg=g_strdup_vprintf(fmt,args);
718#endif
719                fprintf(stdout,"linphone-%s : %s\n",lname,msg);
720                ortp_free(msg);
721        }
722        linphone_gtk_log_push(lev,fmt,args);
723}
724
725int main(int argc, char *argv[]){
726        void *p;
727        const char *config_file;
728        g_thread_init(NULL);
729        gdk_threads_init();
730#ifdef ENABLE_NLS
731        p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
732        if (p==NULL) perror("bindtextdomain failed");
733        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
734        textdomain (GETTEXT_PACKAGE);
735#else
736        g_message("NLS disabled.\n");
737#endif
738        config_file=linphone_gtk_get_config_file();
739        if (linphone_core_wake_up_possible_already_running_instance(config_file)==0){
740                g_warning("Another running instance of linphone has been detected. It has been woken-up.");
741                g_warning("This instance is going to exit now.");
742                return 0;
743        }
744        gdk_threads_enter();
745        if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"),
746                                linphone_options,NULL,NULL)){
747                gdk_threads_leave();
748                return -1;
749        }
750       
751        add_pixmap_directory("pixmaps");
752        add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone");
753#ifdef WIN32
754        add_pixmap_directory("linphone");
755#endif
756
757        the_ui=linphone_gtk_create_window("main");
758       
759        linphone_gtk_create_log_window();
760        linphone_core_enable_logs_with_cb(linphone_gtk_log_handler);
761
762        linphone_gtk_init_liblinphone(config_file);
763        gtk_timeout_add(20,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
764        gtk_timeout_add(20,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL);
765        linphone_gtk_init_main_window();
766        linphone_gtk_init_status_icon();
767        linphone_gtk_show_main_window();
768        gtk_main();
769        gdk_threads_leave();
770        linphone_gtk_destroy_log_window();
771        linphone_core_destroy(the_core);
772        /*workaround a bug on win32 that makes status icon still present in the systray even after program exit.*/
773        gtk_status_icon_set_visible(icon,FALSE);
774        return 0;
775}
776
777
Note: See TracBrowser for help on using the repository browser.