1
/***************************************************************************
2
linphone.c - Main code for linphone's gnome
5
begin : Mon Dec 17 2001
6
copyright : (C) 2001 by Simon Morlat
7
email : simon.morlat@linphone.org
8
***************************************************************************/
10
/***************************************************************************
12
* This program is free software; you can redistribute it and/or modify *
13
* it under the terms of the GNU General Public License as published by *
14
* the Free Software Foundation; either version 2 of the License, or *
15
* (at your option) any later version. *
17
***************************************************************************/
27
#include "interface.h"
28
#include "callbacks.h"
29
#include "gui_utils.h"
35
LinphoneGnomeUI *uiobj=NULL;
36
#define get_uiobj() (uiobj)
37
#define get_core() (uiobj->core)
38
#define get_friend_list() (&uiobj->main_window.friendlist)
40
void linphone_gnome_ui_init(LinphoneGnomeUI *ui,LinphoneCore *core)
42
memset(ui,0,sizeof(LinphoneGnomeUI));
45
ui->main_window.shown_once=FALSE;
48
static void restore_uri_history(GtkEntry *uribar, LpConfig *cfg){
51
GtkEntryCompletion *gep=gtk_entry_completion_new();
52
GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING);
55
snprintf(key,sizeof(key),"uri%i",i);
56
uri=lp_config_get_string(cfg,"GtkUi",key,NULL);
59
gtk_list_store_append(model,&iter);
60
gtk_list_store_set(model,&iter,0,uri,-1);
61
if (i==0) gtk_entry_set_text(uribar,uri);
65
gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model));
66
gtk_entry_completion_set_text_column(gep,0);
67
gtk_entry_set_completion(uribar,gep);
70
void linphone_gnome_save_uri_history(LinphoneGnomeUI *ui){
75
GtkEntry *uribar=GTK_ENTRY(ui->main_window.addressentry);
76
GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar));
77
LpConfig *cfg=linphone_core_get_config(ui->core);
78
if (!gtk_tree_model_get_iter_first(model,&iter)) return;
80
gtk_tree_model_get(model,&iter,0,&uri,-1);
82
snprintf(key,sizeof(key),"uri%i",i);
83
lp_config_set_string(cfg,"GtkUi",key,uri);
88
}while(gtk_tree_model_iter_next(model,&iter));
91
void main_window_create(LinphoneGnomeUI *obj)
95
window=create_app1 ();
97
gnome_window_icon_set_from_default(GTK_WINDOW(window));
99
obj->main_window.status_bar=lookup_widget(window,"appbar1");
100
obj->main_window.addressentry=lookup_widget(window,"addressentry");
101
obj->main_window.optioncontrols=lookup_widget(window,"optioncontrols");
102
obj->main_window.dtmfentry=lookup_widget(window,"dtmf_entry");
103
obj->main_window.callbutton=lookup_widget(window,"callbutton");
104
child=lookup_widget(window,"showmore");
105
/* hide the optionnal controls at startup */
106
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(child),0);
107
#ifndef VIDEO_ENABLED
108
gtk_widget_hide(lookup_widget(child,"video_enabled"));
110
gtk_toggle_button_set_active(
111
GTK_TOGGLE_BUTTON(lookup_widget(child,"video_enabled")),
112
linphone_core_video_enabled(obj->core));
114
presence_box_init(&obj->main_window.presencebox,window,obj->core);
115
friend_list_init(&obj->main_window.friendlist,obj->core,window);
116
g_object_set_data(G_OBJECT(window),"ui",(gpointer)obj);
117
obj->main_window.window=window;
120
void linphone_gnome_ui_show(LinphoneGnomeUI *ui)
122
if (ui->main_window.window==NULL){
123
main_window_create(ui);
126
gtk_widget_show(ui->main_window.window);
127
ui->main_window.shown_once=TRUE;
130
void linphone_gnome_ui_hide(LinphoneGnomeUI *ui)
132
if (ui->main_window.window==NULL) return;
133
gtk_widget_hide(ui->main_window.window);
137
void linphone_gnome_ui_uninit(LinphoneGnomeUI *ui)
139
ui->main_window.window=NULL;
142
void linphone_gnome_ui_display_something(LinphoneGnomeUI *ui,GtkMessageType type,const gchar *message)
146
linphone_gnome_ui_show(ui);
147
if (type==GTK_MESSAGE_QUESTION)
149
#ifdef VINCENT_MAURY_RSVP
150
/* draw a question box. link to dialog_click callback */
151
dialog = gtk_message_dialog_new (
152
GTK_WINDOW(ui->main_window.window),
153
GTK_DIALOG_DESTROY_WITH_PARENT,
154
GTK_MESSAGE_QUESTION,
156
(const gchar*)message);
157
/* connect the click event to the callback */
158
g_signal_connect_swapped (G_OBJECT (dialog), "response",
159
G_CALLBACK (dialog_click),
161
/* actually show the box */
162
gtk_widget_show(dialog);
167
dialog = gtk_message_dialog_new (GTK_WINDOW(ui->main_window.window),
168
GTK_DIALOG_DESTROY_WITH_PARENT,
171
(const gchar*)message);
172
/* Destroy the dialog when the user responds to it (e.g. clicks a button) */
173
g_signal_connect_swapped (G_OBJECT (dialog), "response",
174
G_CALLBACK (gtk_widget_destroy),
176
gtk_widget_show(dialog);
180
/* these are the LinphoneCore virtual functions */
181
void linphone_gnome_display_message(LinphoneCore *lc, const char *message)
183
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
184
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_INFO,message);
187
#ifdef VINCENT_MAURY_RSVP
188
/* Question box with yes/no answer. */
189
void linphone_gnome_display_yes_no(LinphoneCore *lc,const char *message)
191
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
192
if (strcmp(message,"With QoS")==0)
193
/* the caller asks for QoS, this function is called because, by default,
194
* you don't use QoS ! */
195
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION,
196
_("The caller asks for resource reservation. Do you agree ?"));
198
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION,
199
_("The caller doesn't use resource reservation. \
200
Do you wish to continue anyway ?"));
204
void linphone_gnome_display_warning(LinphoneCore *lc, const char *warning)
206
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
207
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_WARNING,warning);
210
void linphone_gnome_display_status(LinphoneCore *lc, const char *status)
212
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
213
if (ui->main_window.window==NULL) return;
214
if (!ui->main_window.shown_once) return; /* avoid a gnome bug*/
215
gtk_statusbar_push(GTK_STATUSBAR(ui->main_window.status_bar),
216
gtk_statusbar_get_context_id(GTK_STATUSBAR(ui->main_window.status_bar),"")
220
void linphone_gnome_inv_recv(LinphoneCore *lc,const char *from)
222
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
224
if (ui->main_window.window==NULL) return;
225
gtk_entry_set_text(GTK_ENTRY(ui->main_window.addressentry),from);
226
title=g_strdup_printf(_("linphone - receiving call from %s"),from);
227
gtk_window_set_title(GTK_WINDOW(ui->main_window.window),title);
228
gdk_window_set_keep_above (ui->main_window.window->window, 1);
232
void linphone_gnome_show(LinphoneCore *lc)
234
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
235
linphone_gnome_ui_show(ui);
238
void linphone_gnome_display_url(LinphoneCore *lc, const char *message, const char *url)
240
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
241
alt_ressource_display(ui,url);
246
void linphone_gnome_notify_received(LinphoneCore *lc,LinphoneFriend *fid, const char *from, const char *status, const char *img){
247
FriendList *fl=get_friend_list();
248
friend_list_set_friend_status(fl,fid,from,status, img);
251
void linphone_gnome_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
252
GtkWidget *d=create_inc_subscr_dialog();
253
gchar *text=g_strdup_printf(_("You have received a subscription from %s."
254
"This means that this person wishes to be notified of your presence information (online, busy, away...).\n"
255
"Do you agree ?"),url);
256
gtk_label_set_text(GTK_LABEL(lookup_widget(d,"subscr_label")),text);
257
g_object_set_data(G_OBJECT(d),"friend_ref",(gpointer)lf);
261
static gboolean destroy_auth(GtkWidget *w){
262
gtk_widget_destroy(w);
266
void linphone_gnome_prompt_authentication(LinphoneCore *lc, const gchar *realm, const gchar *username){
267
GtkWidget *w=create_authentication_dialog();
268
gchar *question=g_strdup_printf(_("Authentication required for realm %s"),realm);
269
gtk_label_set_text(GTK_LABEL(lookup_widget(w,"question")),question);
271
gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"realm")),realm);
272
gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"username")),username);
274
//automatically destroys the window after 30 seconds to avoid multiple windows to be popped up after some hours.
275
g_timeout_add(30000,(GtkFunction)destroy_auth,w);
278
void linphone_gnome_bye_recv(LinphoneCore *lc, const char *from){
279
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
280
gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone");
286
void linphone_gnome_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){
287
LinphoneGnomeUI *ui=(LinphoneGnomeUI *)linphone_core_get_user_data(lc);
288
linphone_gnome_update_call_logs(ui);
291
void linphone_gnome_text_received(LinphoneCore *lc,LinphoneChatRoom *cr, const char *from, const char *msg){
292
GtkWidget *gcr=(GtkWidget*)linphone_chat_room_get_user_data(cr);
294
gcr=chatroom_new(from,cr);
296
gtk_widget_show(gcr);
297
chatroom_append(gcr,from,msg);
300
LinphoneCoreVTable linphone_gnome_vtable=
302
show: linphone_gnome_show,
303
inv_recv: linphone_gnome_inv_recv,
304
bye_recv : linphone_gnome_bye_recv,
305
notify_recv: linphone_gnome_notify_received,
306
new_unknown_subscriber: linphone_gnome_new_unknown_subscriber,
307
auth_info_requested: linphone_gnome_prompt_authentication,
308
display_status : linphone_gnome_display_status,
309
display_message : linphone_gnome_display_message,
310
display_warning : linphone_gnome_display_warning,
311
#ifdef VINCENT_MAURY_RSVP
312
display_yes_no : linphone_gnome_display_yes_no,
314
display_url : linphone_gnome_display_url,
315
display_question : stub,
316
call_log_updated : linphone_gnome_call_log_updated,
317
text_received: linphone_gnome_text_received
320
gboolean linphone_gnome_iterate(LinphoneCore *lc)
322
linphone_core_iterate(lc);
326
void proxy_changed(GtkWidget *combo){
327
LinphoneProxyConfig *pcfg=proxy_combo_box_get_selected(combo);
328
linphone_core_set_default_proxy(get_core(),pcfg);
331
void linphone_refresh_proxy_combo_box(GtkWidget *window){
332
LinphoneCore *lc=get_core();
334
const MSList *elem=linphone_core_get_proxy_config_list(lc);
335
LinphoneProxyConfig *cfg=NULL;
336
GtkWidget *hbox=lookup_widget(window,"proxy_hbox");
338
linphone_core_get_default_proxy(lc,&cfg);
341
gtk_widget_hide(hbox);
344
combo=(GtkWidget*)g_object_get_data(G_OBJECT(hbox),"proxy");
346
gtk_widget_destroy(combo);
348
combo=proxy_combo_box_new(cfg);
349
g_object_set_data(G_OBJECT(hbox),"proxy",(gpointer)combo);
350
g_signal_connect(G_OBJECT(combo),"changed",G_CALLBACK(proxy_changed),NULL);
351
gtk_box_pack_start_defaults(GTK_BOX(hbox),combo);
352
gtk_widget_show(combo);
353
gtk_widget_show(hbox);
357
void linphone_gnome_init(LinphoneGnomeUI *ui,LinphoneCore *lc)
359
gchar *configfile_name =
360
g_strdup_printf ("%s/.gnome2/linphone", getenv ("HOME"));
361
linphone_gnome_ui_init(ui,lc);
362
linphone_gnome_ui_show(ui);
363
linphone_core_init(lc,&linphone_gnome_vtable,configfile_name,(gpointer)ui);
364
g_free(configfile_name);
365
set_levels(ui,linphone_core_get_rec_level(lc),linphone_core_get_play_level(lc),linphone_core_get_ring_level(lc));
366
/* get history of uri bar */
367
restore_uri_history(GTK_ENTRY(ui->main_window.addressentry), linphone_core_get_config(lc));
368
linphone_refresh_proxy_combo_box(ui->main_window.window);
369
ui->timeout_id=gtk_timeout_add(20,(GtkFunction)linphone_gnome_iterate,(gpointer)lc);
372
void linphone_gnome_uninit(LinphoneGnomeUI *ui)
374
LinphoneCore *lc=ui->core;
375
linphone_gnome_ui_uninit(ui);
376
linphone_core_uninit(lc);
377
gtk_timeout_remove (ui->timeout_id);
380
GtkWidget *proxy_combo_box_new(LinphoneProxyConfig *selected){
383
GtkListStore *store=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_POINTER);
386
GtkCellRenderer *renderer;
387
gboolean proxy_found=FALSE;
389
elem=linphone_core_get_proxy_config_list(get_core());
390
gtk_list_store_append(store,&iter);
391
gtk_list_store_set(store,&iter,0,_("None"),1,(gpointer)NULL,-1);
392
for(;elem!=NULL;elem=ms_list_next(elem)){
393
LinphoneProxyConfig *proxy=(LinphoneProxyConfig*)elem->data;
394
gtk_list_store_append(store,&iter);
395
gtk_list_store_set(store,&iter,0,proxy->reg_proxy,1,(gpointer)proxy,-1);
396
if (selected==proxy) {
401
combo=gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
402
g_object_unref(G_OBJECT(store));
403
renderer = gtk_cell_renderer_text_new ();
404
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
405
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
409
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),&prxiter);
411
/*else select "None" */
412
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
417
LinphoneProxyConfig *proxy_combo_box_get_selected(GtkWidget *combo){
418
LinphoneProxyConfig *pcfg=NULL;
420
if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo),&iter)){
421
GtkTreeModel *model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
422
gtk_tree_model_get(model,&iter,1,(gpointer)&pcfg,-1);
427
void linphone_gnome_update_call_logs(LinphoneGnomeUI *ui){
428
LinphoneCore *lc=ui->core;
431
GtkTextIter begin,end;
434
if (ui->logs==NULL) return;
435
tv=GTK_TEXT_VIEW(lookup_widget(ui->logs,"logview"));
436
tb=gtk_text_view_get_buffer(tv);
438
gtk_text_buffer_get_bounds(tb,&begin,&end);
439
gtk_text_buffer_delete(tb,&begin,&end);
440
gtk_text_buffer_get_end_iter(tb,&end);
441
for (elem=linphone_core_get_call_logs(lc);elem!=NULL;elem=ms_list_next(elem)){
442
LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
443
gchar *str=linphone_call_log_to_str(cl);
445
if (cl->status==LinphoneCallMissed){
446
tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(tb),"redforeground");
447
if (tag==NULL) tag = gtk_text_buffer_create_tag (tb, "redforeground",
448
"foreground", "red", NULL);
450
gtk_text_buffer_insert_with_tags(tb,&end,str,-1,tag,NULL);
451
gtk_text_buffer_insert(tb,&end,"\n",-1);
457
void linphone_gnome_show_call_logs_window(LinphoneGnomeUI *ui){
458
if (ui->logs==NULL) {
459
ui->logs=create_call_logs();
461
linphone_gnome_update_call_logs(ui);
462
gtk_widget_show(ui->logs);