source: mediastreamer2/linphone/gtk-glade/main.c @ 72:9b0fd4f1aeac

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

build cleanup, version updated.

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

File size: 24.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                                (const gchar*)message);
191                /* connect to some callback : REVISIT */
192                /*
193                g_signal_connect_swapped (G_OBJECT (dialog), "response",
194                           G_CALLBACK (dialog_click),
195                           G_OBJECT (dialog));
196                */
197                /* actually show the box */
198                gtk_widget_show(dialog);
199        }
200        else
201        {
202                dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
203                                  GTK_DIALOG_DESTROY_WITH_PARENT,
204                                  type,
205                                  GTK_BUTTONS_CLOSE,
206                                  (const gchar*)message);
207                /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
208                g_signal_connect_swapped (G_OBJECT (dialog), "response",
209                           G_CALLBACK (gtk_widget_destroy),
210                           G_OBJECT (dialog));
211                gtk_widget_show(dialog);
212        }
213}
214
215void linphone_gtk_about_response(GtkDialog *dialog, gint id){
216        if (id==GTK_RESPONSE_CANCEL){
217                gtk_widget_destroy(GTK_WIDGET(dialog));
218        }
219}
220
221void linphone_gtk_show_about(){
222        struct stat filestat;
223        const char *license_file=PACKAGE_DATA_DIR "/doc/COPYING";
224        GtkWidget *about;
225
226        about=linphone_gtk_create_window("about");
227        memset(&filestat,0,sizeof(filestat));
228        if (stat(license_file,&filestat)!=0){
229                license_file="COPYING";
230                stat(license_file,&filestat);
231        }
232        if (filestat.st_size>0){
233                char *license=g_malloc(filestat.st_size+1);
234                FILE *f=fopen(license_file,"r");
235                if (f && fread(license,filestat.st_size,1,f)==1){
236                        license[filestat.st_size]='\0';
237                        gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about),license);
238                }
239                g_free(license);
240        }
241        gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LINPHONE_VERSION);
242
243        gtk_widget_show(about);
244}
245
246static gboolean linphone_gtk_iterate(LinphoneCore *lc){
247        linphone_core_iterate(lc);
248        return TRUE;
249}
250
251static void load_uri_history(){
252        GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
253        LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core());
254        char key[20];
255        int i;
256        GtkEntryCompletion *gep=gtk_entry_completion_new();
257        GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING);
258        for (i=0;;i++){
259                const char *uri;
260                snprintf(key,sizeof(key),"uri%i",i);
261                uri=lp_config_get_string(cfg,"GtkUi",key,NULL);
262                if (uri!=NULL) {
263                        GtkTreeIter iter;
264                        gtk_list_store_append(model,&iter);
265                        gtk_list_store_set(model,&iter,0,uri,-1);
266                        if (i==0) gtk_entry_set_text(uribar,uri);
267                }
268                else break;
269        }
270        gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model));
271        gtk_entry_completion_set_text_column(gep,0);
272        gtk_entry_set_completion(uribar,gep);
273}
274
275static void save_uri_history(){
276        LinphoneCore *lc=linphone_gtk_get_core();
277        LpConfig *cfg=linphone_core_get_config(lc);
278        GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
279        char key[20];
280        int i=0;
281        char *uri=NULL;
282        GtkTreeIter iter;
283        GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar));
284
285        if (!gtk_tree_model_get_iter_first(model,&iter)) return;
286        do {
287                gtk_tree_model_get(model,&iter,0,&uri,-1);
288                if (uri) {
289                        snprintf(key,sizeof(key),"uri%i",i);
290                        lp_config_set_string(cfg,"GtkUi",key,uri);
291                        g_free(uri);
292                }else break;
293                i++;
294                if (i>5) break;
295        }while(gtk_tree_model_iter_next(model,&iter));
296        lp_config_sync(cfg);
297}
298
299static void completion_add_text(GtkEntry *entry, const char *text){
300        GtkTreeIter iter;
301        GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry));
302       
303        if (gtk_tree_model_get_iter_first(model,&iter)){ 
304                do {
305                        gchar *uri=NULL;
306                        gtk_tree_model_get(model,&iter,0,&uri,-1);
307                        if (uri!=NULL){
308                                if (strcmp(uri,text)==0) {
309                                        /*remove text */
310                                        gtk_list_store_remove(GTK_LIST_STORE(model),&iter);
311                                        g_free(uri);
312                                        break;
313                                }
314                                g_free(uri);
315                        }
316                }while (gtk_tree_model_iter_next(model,&iter));
317        }
318        /* and prepend it on top of the list */
319        gtk_list_store_prepend(GTK_LIST_STORE(model),&iter);
320        gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1);
321        save_uri_history();
322}
323
324static void linphone_gtk_call_started(GtkWidget *mw){
325        gtk_widget_hide(linphone_gtk_get_widget(mw,"start_call"));
326        gtk_widget_show(linphone_gtk_get_widget(mw,"terminate_call"));
327}
328
329void linphone_gtk_start_call(GtkWidget *button){
330        LinphoneCore *lc=linphone_gtk_get_core();
331        if (linphone_core_inc_invite_pending(lc)){
332                /*already in call */
333        }else{
334                GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"uribar");
335                const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar));
336                if (linphone_core_invite(lc,entered)==0) {
337                        linphone_gtk_call_started(linphone_gtk_get_main_window());
338                        completion_add_text(GTK_ENTRY(uri_bar),entered);
339                }
340        }
341}
342
343static void linphone_gtk_call_terminated(GtkWidget *mw){
344        gtk_widget_hide(linphone_gtk_get_widget(mw,"terminate_call"));
345        gtk_widget_show(linphone_gtk_get_widget(mw,"start_call"));
346        g_object_set_data(G_OBJECT(mw),"incoming_call",NULL);
347}
348
349void linphone_gtk_terminate_call(GtkWidget *button){
350        linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
351        linphone_gtk_call_terminated(gtk_widget_get_toplevel(button));
352}
353
354void linphone_gtk_decline_call(GtkWidget *button){
355        linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
356        linphone_gtk_call_terminated(gtk_widget_get_toplevel(button));
357        gtk_widget_destroy(gtk_widget_get_toplevel(button));
358}
359
360void linphone_gtk_accept_call(GtkWidget *button){
361        linphone_core_accept_call(linphone_gtk_get_core(),NULL);
362        g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",NULL);
363        gtk_widget_destroy(gtk_widget_get_toplevel(button));
364        linphone_gtk_call_started(linphone_gtk_get_main_window());
365}
366
367void linphone_gtk_set_audio_video(){
368        linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE);
369}
370
371void linphone_gtk_set_audio_only(){
372        linphone_core_enable_video(linphone_gtk_get_core(),FALSE,FALSE);
373}
374
375void linphone_gtk_used_identity_changed(GtkWidget *w){
376        int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
377        char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
378        if (sel && strlen(sel)>0) //avoid a dummy "changed" at gui startup
379                linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1));
380}
381
382static void linphone_gtk_show_main_window(){
383        GtkWidget *w=linphone_gtk_get_main_window();
384        LinphoneCore *lc=linphone_gtk_get_core();
385        linphone_core_enable_video_preview(lc,linphone_core_video_enabled(lc));
386        gtk_widget_show(w);
387        gtk_window_present(GTK_WINDOW(w));
388}
389
390static void linphone_gtk_show(LinphoneCore *lc){
391        linphone_gtk_show_main_window();
392}
393
394static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){
395        GtkWidget *w=linphone_gtk_create_window("incoming_call");
396        GtkWidget *label;
397        gchar *msg;
398        gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window()));
399        gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT);
400
401        label=linphone_gtk_get_widget(w,"message");
402        msg=g_strdup_printf(_("Incoming call from %s"),from);
403        gtk_label_set_text(GTK_LABEL(label),msg);
404        gtk_window_set_title(GTK_WINDOW(w),msg);
405        gtk_widget_show(w);
406        gtk_window_present(GTK_WINDOW(w));
407        /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/
408        g_free(msg);
409        g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w);
410        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),
411                        from);
412}
413
414static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){
415        GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call"));
416        if (icw!=NULL){
417                gtk_widget_destroy(icw);
418        }
419        linphone_gtk_call_terminated(linphone_gtk_get_main_window());
420}
421
422static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img){
423}
424
425static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint response_id, LinphoneFriend *lf){
426        switch(response_id){
427                case GTK_RESPONSE_YES:
428                        linphone_gtk_show_contact(lf);
429                break;
430                default:
431                        linphone_core_reject_subscriber(linphone_gtk_get_core(),lf);
432        }
433        gtk_widget_destroy(dialog);
434}
435
436static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
437        GtkWidget *dialog;
438        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);
439        dialog = gtk_message_dialog_new (
440                                GTK_WINDOW(linphone_gtk_get_main_window()),
441                                GTK_DIALOG_DESTROY_WITH_PARENT,
442                                GTK_MESSAGE_QUESTION,
443                                GTK_BUTTONS_YES_NO,
444                                message);
445        g_free(message);
446        g_signal_connect(G_OBJECT (dialog), "response",
447                G_CALLBACK (linphone_gtk_new_subscriber_response),lf);
448        /* actually show the box */
449        gtk_widget_show(dialog);
450}
451
452typedef struct _AuthTimeout{
453        GtkWidget *w;
454} AuthTimeout;
455
456
457static void auth_timeout_clean(AuthTimeout *tout){
458        tout->w=NULL;
459}
460
461static gboolean auth_timeout_destroy(AuthTimeout *tout){
462        if (tout->w)  {
463                g_object_weak_unref(G_OBJECT(tout->w),(GWeakNotify)auth_timeout_clean,tout);
464                gtk_widget_destroy(tout->w);
465        }
466        g_free(tout);
467        return FALSE;
468}
469
470static AuthTimeout * auth_timeout_new(GtkWidget *w){
471        AuthTimeout *tout=g_new(AuthTimeout,1);
472        tout->w=w;
473        /*so that the timeout no more references the widget when it is destroyed:*/
474        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)auth_timeout_clean,tout);
475        /*so that the widget is automatically destroyed after some time */
476        g_timeout_add(30000,(GtkFunction)auth_timeout_destroy,tout);
477        return tout;
478}
479
480void linphone_gtk_password_cancel(GtkWidget *w){
481        LinphoneAuthInfo *info;
482        GtkWidget *window=gtk_widget_get_toplevel(w);
483        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
484        linphone_core_abort_authentication(linphone_gtk_get_core(),info);
485        gtk_widget_destroy(window);
486}
487
488void linphone_gtk_password_ok(GtkWidget *w){
489        GtkWidget *entry;
490        GtkWidget *window=gtk_widget_get_toplevel(w);
491        LinphoneAuthInfo *info;
492        info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info");
493        g_object_weak_unref(G_OBJECT(window),(GWeakNotify)linphone_auth_info_destroy,info);
494        entry=linphone_gtk_get_widget(window,"password_entry");
495        linphone_auth_info_set_passwd(info,gtk_entry_get_text(GTK_ENTRY(entry)));
496        linphone_auth_info_set_username(info,
497                gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(window,"username_entry"))));
498        linphone_core_add_auth_info(linphone_gtk_get_core(),info);
499        gtk_widget_destroy(window);
500}
501
502static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username){
503        GtkWidget *w=linphone_gtk_create_window("password");
504        GtkWidget *label=linphone_gtk_get_widget(w,"message");
505        LinphoneAuthInfo *info;
506        gchar *msg;
507        msg=g_strdup_printf(_("Please enter your password for domain %s:"),realm);
508        gtk_label_set_text(GTK_LABEL(label),msg);
509        g_free(msg);
510        gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"username_entry")),username);
511        info=linphone_auth_info_new(username, NULL, NULL, NULL,realm);
512        g_object_set_data(G_OBJECT(w),"auth_info",info);
513        g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_auth_info_destroy,info);
514        gtk_widget_show(w);
515        auth_timeout_new(w);
516}
517
518static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){
519        GtkWidget *w=linphone_gtk_get_main_window();
520        GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar");
521        gtk_statusbar_push(GTK_STATUSBAR(status_bar),
522                        gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),""),
523                        status);
524}
525
526static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){
527        linphone_gtk_display_something(GTK_MESSAGE_INFO,msg);
528}
529
530static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning){
531        linphone_gtk_display_something(GTK_MESSAGE_WARNING,warning);
532}
533
534static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url){
535        char richtext[4096];
536        snprintf(richtext,sizeof(richtext),"%s %s",msg,url);
537        linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext);
538}
539
540static void linphone_gtk_display_question(LinphoneCore *lc, const char *question){
541        linphone_gtk_display_something(GTK_MESSAGE_QUESTION,question);
542}
543
544static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){
545        GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
546        if (w) linphone_gtk_call_log_update(w);
547}
548
549static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
550}
551
552
553static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
554        GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
555        gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
556}
557
558static GtkWidget *create_icon_menu(){
559        GtkWidget *menu=gtk_menu_new();
560        GtkWidget *menu_item;
561        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,NULL);
562        gtk_widget_show(menu_item);
563        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
564        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_about,NULL);
565        menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,NULL);
566        gtk_widget_show(menu_item);
567        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
568        g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)gtk_main_quit,NULL);
569        gtk_widget_show(menu);
570        return menu;
571}
572
573static GtkStatusIcon *icon=NULL;
574
575static void linphone_gtk_init_status_icon(){
576        GdkPixbuf *pbuf=create_pixbuf("linphone2.png");
577        GtkWidget *menu=create_icon_menu();
578        icon=gtk_status_icon_new_from_pixbuf(pbuf);
579        g_object_unref(G_OBJECT(pbuf));
580        g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)linphone_gtk_show_main_window,linphone_gtk_get_main_window());
581        g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL);
582        gtk_status_icon_set_tooltip(icon,_("Linphone - a video internet phone"));
583        g_object_set_data(G_OBJECT(icon),"menu",menu);
584        g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu);
585}
586
587void linphone_gtk_load_identities(void){
588        const MSList *elem;
589        GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities"));
590        char *def_identity;
591        LinphoneProxyConfig *def=NULL;
592        int def_index=0,i;
593        GtkListStore *store;
594
595        store=GTK_LIST_STORE(gtk_combo_box_get_model(box));
596        gtk_list_store_clear(store);
597
598        linphone_core_get_default_proxy(linphone_gtk_get_core(),&def);
599        def_identity=g_strdup_printf(_("%s (Default)"),linphone_core_get_primary_contact(linphone_gtk_get_core()));
600        gtk_combo_box_append_text(box,def_identity);
601        g_free(def_identity);
602        for(i=1,elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());
603                        elem!=NULL;
604                        elem=ms_list_next(elem),i++){
605                LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
606                gtk_combo_box_append_text(box,linphone_proxy_config_get_identity(cfg));
607                if (cfg==def) {
608                        def_index=i;
609                }
610        }
611        gtk_combo_box_set_active(box,def_index);
612}
613
614static void linphone_gtk_dtmf_clicked(GtkButton *button){
615        const char *label=gtk_button_get_label(button);
616        linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]);
617}
618
619static void linphone_gtk_connect_digits(void){
620        GtkContainer *cont=GTK_CONTAINER(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"dtmf_table"));
621        GList *children=gtk_container_get_children(cont);
622        GList *elem;
623        for(elem=children;elem!=NULL;elem=elem->next){
624                GtkButton *button=GTK_BUTTON(elem->data);
625                g_signal_connect(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_dtmf_clicked,NULL);
626        }
627}
628
629static void linphone_gtk_check_menu_items(void){
630        bool_t audio_only=!linphone_core_video_enabled(linphone_gtk_get_core());
631        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(linphone_gtk_get_widget(
632                                        linphone_gtk_get_main_window(),
633                                        audio_only ? "audio_only_item" : "video_item")), TRUE);
634}
635
636static void linphone_gtk_init_main_window(){
637        load_uri_history();
638        linphone_gtk_load_identities();
639        linphone_gtk_set_my_presence(linphone_core_get_presence_info(linphone_gtk_get_core()));
640        linphone_gtk_show_friends();
641        linphone_gtk_connect_digits();
642        linphone_gtk_check_menu_items();
643        if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started(
644                linphone_gtk_get_main_window());/*hide the call button, show terminate button*/
645}
646
647void linphone_gtk_close(){
648        /* couldn't find a way to prevent closing to destroy the main window*/
649        linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
650        the_ui=NULL;
651        the_ui=linphone_gtk_create_window("main");
652        linphone_gtk_init_main_window();
653}
654
655void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
656        if (verbose){
657                const char *lname="undef";
658                char *msg;
659                #ifdef __linux
660                va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
661                #endif
662                switch(lev){
663                        case ORTP_DEBUG:
664                                lname="debug";
665                                break;
666                        case ORTP_MESSAGE:
667                                lname="message";
668                                break;
669                        case ORTP_WARNING:
670                                lname="warning";
671                                break;
672                        case ORTP_ERROR:
673                                lname="error";
674                                break;
675                        case ORTP_FATAL:
676                                lname="fatal";
677                                break;
678                        default:
679                                g_error("Bad level !");
680                }
681#ifdef __linux
682                va_copy(cap,args);
683                msg=g_strdup_vprintf(fmt,cap);
684                va_end(cap);
685#else
686                msg=g_strdup_vprintf(fmt,args);
687#endif
688                fprintf(stdout,"linphone-%s : %s\n",lname,msg);
689                ortp_free(msg);
690        }
691        linphone_gtk_log_push(lev,fmt,args);
692}
693
694int main(int argc, char *argv[]){
695        void *p;
696        const char *config_file;
697        g_thread_init(NULL);
698        gdk_threads_init();
699#ifdef ENABLE_NLS
700        p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
701        if (p==NULL) perror("bindtextdomain failed");
702        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
703        textdomain (GETTEXT_PACKAGE);
704#else
705        g_message("NLS disabled.\n");
706#endif
707        config_file=linphone_gtk_get_config_file();
708        if (linphone_core_wake_up_possible_already_running_instance(config_file)==0){
709                g_warning("Another running instance of linphone has been detected. It has been woken-up.");
710                g_warning("This instance is going to exit now.");
711                return 0;
712        }
713        gdk_threads_enter();
714        if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"),
715                                linphone_options,NULL,NULL)){
716                gdk_threads_leave();
717                return -1;
718        }
719       
720        add_pixmap_directory("pixmaps");
721        add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone");
722#ifdef WIN32
723        add_pixmap_directory("linphone");
724#endif
725
726        the_ui=linphone_gtk_create_window("main");
727       
728        linphone_gtk_create_log_window();
729        linphone_core_enable_logs_with_cb(linphone_gtk_log_handler);
730
731        linphone_gtk_init_liblinphone(config_file);
732        gtk_timeout_add(20,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
733        gtk_timeout_add(20,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL);
734        linphone_gtk_init_main_window();
735        linphone_gtk_init_status_icon();
736        gtk_widget_show(the_ui);
737        gtk_main();
738        gdk_threads_leave();
739        linphone_gtk_destroy_log_window();
740        linphone_core_destroy(the_core);
741        /*workaround a bug on win32 that makes status icon still present in the systray even after program exit.*/
742        gtk_status_icon_set_visible(icon,FALSE);
743        return 0;
744}
745
746
Note: See TracBrowser for help on using the repository browser.