mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-04-21 23:08:32 +00:00
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@1 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
482 lines
16 KiB
C
482 lines
16 KiB
C
/***************************************************************************
|
|
linphone.c - Main code for linphone's gnome
|
|
interface
|
|
-------------------
|
|
begin : Mon Dec 17 2001
|
|
copyright : (C) 2001 by Simon Morlat
|
|
email : simon.morlat@linphone.org
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
/*
|
|
linphone, gtk-glade interface.
|
|
Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org)
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
|
|
#include "linphone.h"
|
|
#include "support.h"
|
|
#include "interface.h"
|
|
#include "callbacks.h"
|
|
#include "gui_utils.h"
|
|
#include "lpconfig.h"
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
LinphoneGnomeUI *uiobj=NULL;
|
|
#define get_uiobj() (uiobj)
|
|
#define get_core() (uiobj->core)
|
|
#define get_friend_list() (&uiobj->main_window.friendlist)
|
|
|
|
void linphone_gnome_ui_init(LinphoneGnomeUI *ui,LinphoneCore *core)
|
|
{
|
|
memset(ui,0,sizeof(LinphoneGnomeUI));
|
|
ui->core=core;
|
|
uiobj=ui;
|
|
ui->main_window.shown_once=FALSE;
|
|
}
|
|
|
|
static void restore_uri_history(GtkEntry *uribar, LpConfig *cfg){
|
|
char key[20];
|
|
int i;
|
|
GtkEntryCompletion *gep=gtk_entry_completion_new();
|
|
GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING);
|
|
for (i=0;;i++){
|
|
const char *uri;
|
|
snprintf(key,sizeof(key),"uri%i",i);
|
|
uri=lp_config_get_string(cfg,"GtkUi",key,NULL);
|
|
if (uri!=NULL) {
|
|
GtkTreeIter iter;
|
|
gtk_list_store_append(model,&iter);
|
|
gtk_list_store_set(model,&iter,0,uri,-1);
|
|
if (i==0) gtk_entry_set_text(uribar,uri);
|
|
}
|
|
else break;
|
|
}
|
|
gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model));
|
|
gtk_entry_completion_set_text_column(gep,0);
|
|
gtk_entry_set_completion(uribar,gep);
|
|
}
|
|
|
|
void linphone_gnome_save_uri_history(LinphoneGnomeUI *ui){
|
|
char key[20];
|
|
int i=0;
|
|
char *uri=NULL;
|
|
GtkTreeIter iter;
|
|
GtkEntry *uribar=GTK_ENTRY(ui->main_window.addressentry);
|
|
GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar));
|
|
LpConfig *cfg=linphone_core_get_config(ui->core);
|
|
if (!gtk_tree_model_get_iter_first(model,&iter)) return;
|
|
do {
|
|
gtk_tree_model_get(model,&iter,0,&uri,-1);
|
|
if (uri) {
|
|
snprintf(key,sizeof(key),"uri%i",i);
|
|
lp_config_set_string(cfg,"GtkUi",key,uri);
|
|
g_free(uri);
|
|
}else break;
|
|
i++;
|
|
if (i>5) break;
|
|
}while(gtk_tree_model_iter_next(model,&iter));
|
|
}
|
|
|
|
void main_window_create(LinphoneGnomeUI *obj)
|
|
{
|
|
GtkWidget *child;
|
|
GtkWidget *window;
|
|
window=create_app1 ();
|
|
#ifdef NOTYET
|
|
gnome_window_icon_set_from_default(GTK_WINDOW(window));
|
|
#endif
|
|
obj->main_window.status_bar=lookup_widget(window,"appbar1");
|
|
obj->main_window.addressentry=lookup_widget(window,"addressentry");
|
|
obj->main_window.optioncontrols=lookup_widget(window,"optioncontrols");
|
|
obj->main_window.dtmfentry=lookup_widget(window,"dtmf_entry");
|
|
obj->main_window.callbutton=lookup_widget(window,"callbutton");
|
|
child=lookup_widget(window,"showmore");
|
|
/* hide the optionnal controls at startup */
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(child),0);
|
|
#ifndef VIDEO_ENABLED
|
|
gtk_widget_hide(lookup_widget(child,"video_enabled"));
|
|
#else
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON(lookup_widget(child,"video_enabled")),
|
|
linphone_core_video_enabled(obj->core));
|
|
#endif
|
|
presence_box_init(&obj->main_window.presencebox,window,obj->core);
|
|
friend_list_init(&obj->main_window.friendlist,obj->core,window);
|
|
g_object_set_data(G_OBJECT(window),"ui",(gpointer)obj);
|
|
obj->main_window.window=window;
|
|
}
|
|
|
|
void linphone_gnome_ui_show(LinphoneGnomeUI *ui)
|
|
{
|
|
if (ui->main_window.window==NULL){
|
|
main_window_create(ui);
|
|
|
|
}
|
|
gtk_widget_show(ui->main_window.window);
|
|
ui->main_window.shown_once=TRUE;
|
|
}
|
|
|
|
void linphone_gnome_ui_hide(LinphoneGnomeUI *ui)
|
|
{
|
|
if (ui->main_window.window==NULL) return;
|
|
gtk_widget_hide(ui->main_window.window);
|
|
}
|
|
|
|
|
|
void linphone_gnome_ui_uninit(LinphoneGnomeUI *ui)
|
|
{
|
|
ui->main_window.window=NULL;
|
|
}
|
|
|
|
void linphone_gnome_ui_display_something(LinphoneGnomeUI *ui,GtkMessageType type,const gchar *message)
|
|
{
|
|
GtkWidget *dialog;
|
|
|
|
linphone_gnome_ui_show(ui);
|
|
if (type==GTK_MESSAGE_QUESTION)
|
|
{
|
|
#ifdef VINCENT_MAURY_RSVP
|
|
/* draw a question box. link to dialog_click callback */
|
|
dialog = gtk_message_dialog_new (
|
|
GTK_WINDOW(ui->main_window.window),
|
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
GTK_MESSAGE_QUESTION,
|
|
GTK_BUTTONS_YES_NO,
|
|
(const gchar*)message);
|
|
/* connect the click event to the callback */
|
|
g_signal_connect_swapped (G_OBJECT (dialog), "response",
|
|
G_CALLBACK (dialog_click),
|
|
G_OBJECT (dialog));
|
|
/* actually show the box */
|
|
gtk_widget_show(dialog);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
dialog = gtk_message_dialog_new (GTK_WINDOW(ui->main_window.window),
|
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
type,
|
|
GTK_BUTTONS_CLOSE,
|
|
(const gchar*)message);
|
|
/* Destroy the dialog when the user responds to it (e.g. clicks a button) */
|
|
g_signal_connect_swapped (G_OBJECT (dialog), "response",
|
|
G_CALLBACK (gtk_widget_destroy),
|
|
G_OBJECT (dialog));
|
|
gtk_widget_show(dialog);
|
|
}
|
|
}
|
|
|
|
/* these are the LinphoneCore virtual functions */
|
|
void linphone_gnome_display_message(LinphoneCore *lc, const char *message)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_INFO,message);
|
|
}
|
|
|
|
#ifdef VINCENT_MAURY_RSVP
|
|
/* Question box with yes/no answer. */
|
|
void linphone_gnome_display_yes_no(LinphoneCore *lc,const char *message)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
if (strcmp(message,"With QoS")==0)
|
|
/* the caller asks for QoS, this function is called because, by default,
|
|
* you don't use QoS ! */
|
|
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION,
|
|
_("The caller asks for resource reservation. Do you agree ?"));
|
|
else
|
|
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION,
|
|
_("The caller doesn't use resource reservation. \
|
|
Do you wish to continue anyway ?"));
|
|
}
|
|
#endif
|
|
|
|
void linphone_gnome_display_warning(LinphoneCore *lc, const char *warning)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
linphone_gnome_ui_display_something(ui,GTK_MESSAGE_WARNING,warning);
|
|
}
|
|
|
|
void linphone_gnome_display_status(LinphoneCore *lc, const char *status)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
if (ui->main_window.window==NULL) return;
|
|
if (!ui->main_window.shown_once) return; /* avoid a gnome bug*/
|
|
gtk_statusbar_push(GTK_STATUSBAR(ui->main_window.status_bar),
|
|
gtk_statusbar_get_context_id(GTK_STATUSBAR(ui->main_window.status_bar),"")
|
|
,status);
|
|
}
|
|
|
|
void linphone_gnome_inv_recv(LinphoneCore *lc,const char *from)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
gchar *title;
|
|
if (ui->main_window.window==NULL) return;
|
|
gtk_entry_set_text(GTK_ENTRY(ui->main_window.addressentry),from);
|
|
title=g_strdup_printf(_("linphone - receiving call from %s"),from);
|
|
gtk_window_set_title(GTK_WINDOW(ui->main_window.window),title);
|
|
gdk_window_set_keep_above (ui->main_window.window->window, 1);
|
|
g_free(title);
|
|
}
|
|
|
|
void linphone_gnome_show(LinphoneCore *lc)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
linphone_gnome_ui_show(ui);
|
|
}
|
|
|
|
void linphone_gnome_display_url(LinphoneCore *lc, const char *message, const char *url)
|
|
{
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
alt_ressource_display(ui,url);
|
|
}
|
|
|
|
|
|
|
|
void linphone_gnome_notify_received(LinphoneCore *lc,LinphoneFriend *fid, const char *from, const char *status, const char *img){
|
|
FriendList *fl=get_friend_list();
|
|
friend_list_set_friend_status(fl,fid,from,status, img);
|
|
}
|
|
|
|
void linphone_gnome_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
|
|
GtkWidget *d=create_inc_subscr_dialog();
|
|
gchar *text=g_strdup_printf(_("You have received a subscription from %s."
|
|
"This means that this person wishes to be notified of your presence information (online, busy, away...).\n"
|
|
"Do you agree ?"),url);
|
|
gtk_label_set_text(GTK_LABEL(lookup_widget(d,"subscr_label")),text);
|
|
g_object_set_data(G_OBJECT(d),"friend_ref",(gpointer)lf);
|
|
gtk_widget_show(d);
|
|
}
|
|
|
|
static gboolean destroy_auth(GtkWidget *w){
|
|
gtk_widget_destroy(w);
|
|
return FALSE;
|
|
}
|
|
|
|
void linphone_gnome_prompt_authentication(LinphoneCore *lc, const gchar *realm, const gchar *username){
|
|
GtkWidget *w=create_authentication_dialog();
|
|
gchar *question=g_strdup_printf(_("Authentication required for realm %s"),realm);
|
|
gtk_label_set_text(GTK_LABEL(lookup_widget(w,"question")),question);
|
|
g_free(question);
|
|
gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"realm")),realm);
|
|
gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"username")),username);
|
|
gtk_widget_show(w);
|
|
//automatically destroys the window after 30 seconds to avoid multiple windows to be popped up after some hours.
|
|
g_timeout_add(30000,(GtkFunction)destroy_auth,w);
|
|
}
|
|
|
|
void linphone_gnome_bye_recv(LinphoneCore *lc, const char *from){
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data;
|
|
gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone");
|
|
}
|
|
|
|
void stub(){
|
|
}
|
|
|
|
void linphone_gnome_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){
|
|
LinphoneGnomeUI *ui=(LinphoneGnomeUI *)linphone_core_get_user_data(lc);
|
|
linphone_gnome_update_call_logs(ui);
|
|
}
|
|
|
|
void linphone_gnome_text_received(LinphoneCore *lc,LinphoneChatRoom *cr, const char *from, const char *msg){
|
|
GtkWidget *gcr=(GtkWidget*)linphone_chat_room_get_user_data(cr);
|
|
if (gcr==NULL){
|
|
gcr=chatroom_new(from,cr);
|
|
}
|
|
gtk_widget_show(gcr);
|
|
chatroom_append(gcr,from,msg);
|
|
}
|
|
|
|
LinphoneCoreVTable linphone_gnome_vtable=
|
|
{
|
|
show: linphone_gnome_show,
|
|
inv_recv: linphone_gnome_inv_recv,
|
|
bye_recv : linphone_gnome_bye_recv,
|
|
notify_recv: linphone_gnome_notify_received,
|
|
new_unknown_subscriber: linphone_gnome_new_unknown_subscriber,
|
|
auth_info_requested: linphone_gnome_prompt_authentication,
|
|
display_status : linphone_gnome_display_status,
|
|
display_message : linphone_gnome_display_message,
|
|
display_warning : linphone_gnome_display_warning,
|
|
#ifdef VINCENT_MAURY_RSVP
|
|
display_yes_no : linphone_gnome_display_yes_no,
|
|
#endif
|
|
display_url : linphone_gnome_display_url,
|
|
display_question : stub,
|
|
call_log_updated : linphone_gnome_call_log_updated,
|
|
text_received: linphone_gnome_text_received
|
|
};
|
|
|
|
gboolean linphone_gnome_iterate(LinphoneCore *lc)
|
|
{
|
|
linphone_core_iterate(lc);
|
|
return TRUE;
|
|
}
|
|
|
|
void proxy_changed(GtkWidget *combo){
|
|
LinphoneProxyConfig *pcfg=proxy_combo_box_get_selected(combo);
|
|
linphone_core_set_default_proxy(get_core(),pcfg);
|
|
}
|
|
|
|
void linphone_refresh_proxy_combo_box(GtkWidget *window){
|
|
LinphoneCore *lc=get_core();
|
|
GtkWidget *combo;
|
|
const MSList *elem=linphone_core_get_proxy_config_list(lc);
|
|
LinphoneProxyConfig *cfg=NULL;
|
|
GtkWidget *hbox=lookup_widget(window,"proxy_hbox");
|
|
|
|
linphone_core_get_default_proxy(lc,&cfg);
|
|
|
|
if (elem==NULL){
|
|
gtk_widget_hide(hbox);
|
|
return;
|
|
}
|
|
combo=(GtkWidget*)g_object_get_data(G_OBJECT(hbox),"proxy");
|
|
if (combo!=NULL){
|
|
gtk_widget_destroy(combo);
|
|
}
|
|
combo=proxy_combo_box_new(cfg);
|
|
g_object_set_data(G_OBJECT(hbox),"proxy",(gpointer)combo);
|
|
g_signal_connect(G_OBJECT(combo),"changed",G_CALLBACK(proxy_changed),NULL);
|
|
gtk_box_pack_start_defaults(GTK_BOX(hbox),combo);
|
|
gtk_widget_show(combo);
|
|
gtk_widget_show(hbox);
|
|
|
|
}
|
|
|
|
void linphone_gnome_init(LinphoneGnomeUI *ui,LinphoneCore *lc)
|
|
{
|
|
gchar *configfile_name =
|
|
g_strdup_printf ("%s/.gnome2/linphone", getenv ("HOME"));
|
|
linphone_gnome_ui_init(ui,lc);
|
|
linphone_gnome_ui_show(ui);
|
|
linphone_core_init(lc,&linphone_gnome_vtable,configfile_name,(gpointer)ui);
|
|
g_free(configfile_name);
|
|
set_levels(ui,linphone_core_get_rec_level(lc),linphone_core_get_play_level(lc),linphone_core_get_ring_level(lc));
|
|
/* get history of uri bar */
|
|
restore_uri_history(GTK_ENTRY(ui->main_window.addressentry), linphone_core_get_config(lc));
|
|
linphone_refresh_proxy_combo_box(ui->main_window.window);
|
|
ui->timeout_id=gtk_timeout_add(20,(GtkFunction)linphone_gnome_iterate,(gpointer)lc);
|
|
}
|
|
|
|
void linphone_gnome_uninit(LinphoneGnomeUI *ui)
|
|
{
|
|
LinphoneCore *lc=ui->core;
|
|
linphone_gnome_ui_uninit(ui);
|
|
linphone_core_uninit(lc);
|
|
gtk_timeout_remove (ui->timeout_id);
|
|
}
|
|
|
|
GtkWidget *proxy_combo_box_new(LinphoneProxyConfig *selected){
|
|
GtkWidget *combo;
|
|
const MSList *elem;
|
|
GtkListStore *store=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_POINTER);
|
|
GtkTreeIter iter;
|
|
GtkTreeIter prxiter;
|
|
GtkCellRenderer *renderer;
|
|
gboolean proxy_found=FALSE;
|
|
/* fill the store */
|
|
elem=linphone_core_get_proxy_config_list(get_core());
|
|
gtk_list_store_append(store,&iter);
|
|
gtk_list_store_set(store,&iter,0,_("None"),1,(gpointer)NULL,-1);
|
|
for(;elem!=NULL;elem=ms_list_next(elem)){
|
|
LinphoneProxyConfig *proxy=(LinphoneProxyConfig*)elem->data;
|
|
gtk_list_store_append(store,&iter);
|
|
gtk_list_store_set(store,&iter,0,proxy->reg_proxy,1,(gpointer)proxy,-1);
|
|
if (selected==proxy) {
|
|
prxiter=iter;
|
|
proxy_found=TRUE;
|
|
}
|
|
}
|
|
combo=gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
|
|
g_object_unref(G_OBJECT(store));
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
|
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
|
|
"text", 0,
|
|
NULL);
|
|
if (proxy_found){
|
|
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),&prxiter);
|
|
}else{
|
|
/*else select "None" */
|
|
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
|
|
}
|
|
return combo;
|
|
}
|
|
|
|
LinphoneProxyConfig *proxy_combo_box_get_selected(GtkWidget *combo){
|
|
LinphoneProxyConfig *pcfg=NULL;
|
|
GtkTreeIter iter;
|
|
if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo),&iter)){
|
|
GtkTreeModel *model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
|
|
gtk_tree_model_get(model,&iter,1,(gpointer)&pcfg,-1);
|
|
}
|
|
return pcfg;
|
|
}
|
|
|
|
void linphone_gnome_update_call_logs(LinphoneGnomeUI *ui){
|
|
LinphoneCore *lc=ui->core;
|
|
GtkTextView *tv;
|
|
GtkTextBuffer *tb;
|
|
GtkTextIter begin,end;
|
|
GtkTextTag *tag;
|
|
MSList *elem;
|
|
if (ui->logs==NULL) return;
|
|
tv=GTK_TEXT_VIEW(lookup_widget(ui->logs,"logview"));
|
|
tb=gtk_text_view_get_buffer(tv);
|
|
|
|
gtk_text_buffer_get_bounds(tb,&begin,&end);
|
|
gtk_text_buffer_delete(tb,&begin,&end);
|
|
gtk_text_buffer_get_end_iter(tb,&end);
|
|
for (elem=linphone_core_get_call_logs(lc);elem!=NULL;elem=ms_list_next(elem)){
|
|
LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
|
|
gchar *str=linphone_call_log_to_str(cl);
|
|
tag=NULL;
|
|
if (cl->status==LinphoneCallMissed){
|
|
tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(tb),"redforeground");
|
|
if (tag==NULL) tag = gtk_text_buffer_create_tag (tb, "redforeground",
|
|
"foreground", "red", NULL);
|
|
}
|
|
gtk_text_buffer_insert_with_tags(tb,&end,str,-1,tag,NULL);
|
|
gtk_text_buffer_insert(tb,&end,"\n",-1);
|
|
|
|
ms_free(str);
|
|
}
|
|
}
|
|
|
|
void linphone_gnome_show_call_logs_window(LinphoneGnomeUI *ui){
|
|
if (ui->logs==NULL) {
|
|
ui->logs=create_call_logs();
|
|
}
|
|
linphone_gnome_update_call_logs(ui);
|
|
gtk_widget_show(ui->logs);
|
|
}
|