Merge remote-tracking branch 'public/master' into belle-sip

Conflicts:
	configure.ac
	coreapi/linphonecore.h
This commit is contained in:
Jehan Monnier 2013-03-07 21:56:18 +01:00
commit dafc0c1f0c
44 changed files with 9680 additions and 6390 deletions

View file

@ -220,7 +220,7 @@ bundle: $(LIBICONV_HACK)
printf "[Pango]\nModuleFiles=./etc/pango/pango.modules\n" \
> $(BUNDLEDIR)/Contents/Resources/etc/pango/pangorc
cp -f $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig
sed -e 's:@executable_path/../Resources:../..:g' $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig > $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules
sed -e 's:@executable_path.*/::g' $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig > $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules
cp -f $(LIBICONV_HACK) $(BUNDLEDIR)/Contents/Resources/lib/.
cd $(BUNDLEDIR)/.. && rm -f $(MACAPPZIP) && zip -r $(MACAPPZIP) $(MACAPPNAME) && cd -

View file

@ -8,56 +8,70 @@ You need:
Download and install macports using its user friendly installer.
- Install build time dependencies
$ port install automake autoconf libtool intltool
$ sudo port install automake autoconf libtool intltool
- Install some linphone dependencies with macports
$ port install speex
$ port install libosip2 # WARNING: currently outdated in macport
$ port install libeXosip2 #WARNING: currently outdated in macport
$ port install ffmpeg-devel
$ port install libvpx
$ port install readline
$ sudo port install speex
$ sudo port install libosip2 # WARNING: currently outdated in macport
$ sudo port install libeXosip2 #WARNING: currently outdated in macport
$ sudo port install ffmpeg-devel -gpl2
$ sudo port install libvpx
$ sudo port install readline
- Install srtp (optional) for call encryption
$ port install srtp
$ sudo port install srtp
If that fails, get from source:
$ git clone git://git.linphone.org/srtp.git
$ cd srtp && autoconf && ./configure --prefix=/opt/local && make libsrtp.a
$ sudo make install
- Install zrtpcpp (optional), for unbreakable call encryption
$ port install cmake
$ sudo port install cmake
$ git clone git://git.linphone.org/zrtpcpp.git
$ cd zrtpcpp && cmake -Denable-ccrtp=false . && make
$ sudo make install
- Install gtk. It is recommended to use the quartz backend for better integration.
$ port install gtk2 +quartz +no_x11
$ port install ige-mac-integration
$ port install hicolor-icon-theme
$ sudo port install gtk2 +quartz +no_x11
$ sudo port install gtk-osx-application -python27
$ sudo port install hicolor-icon-theme
- Install additional librairies required for wizard (linphone.org account creation assistant)
$ sudo port install libsoup
- Install sqlite3 for message storage
$ sudo port install sqlite3
** WARNING 2013-03-06 glib-networking is currently broken in macports - generates crashes or hangs when used in a bundle **
As a temporary workaround, build a newer version by yourself:
$ wget http://ftp.gnome.org/pub/gnome/sources/glib-networking/2.34/glib-networking-2.34.2.tar.xz
$ tar -xvzf glib-networking-2.34.2.tar.xz
$ cd glib-networking-2.34.2
$ ./configure --prefix=/opt/local --without-ca-certificates && make
$ sudo make install
- Compile and install the tunnel
- Compile and install the tunnel library (optional, proprietary extension only)
If you got the source code from git, run ./autogen.sh first
If you got the source code from git, run ./autogen.sh first
Then or otherwise, do:
Then or otherwise, do:
$ ./configure --prefix=/opt/local && make && sudo make install
- Compile linphone
If you got the source code from git, run ./autogen.sh first.
If you got the source code from git, run ./autogen.sh first.
Then or otherwise, do:
Then or otherwise, do:
$ ./configure --prefix=/opt/local --with-readline=/opt/local --disable-x11 --with-srtp=/opt/local --with-gsm=/opt/local --enable-zrtp && make
Install to /opt/local
Install to /opt/local
$ sudo make install
Done.
Done.
If you want to generate a portable bundle, then install gtk-mac-bundler.
Use git:

View file

@ -1,4 +1,5 @@
export EXTRA_ARGS="--workdir $bundle_res"
export GIO_EXTRA_MODULES="$bundle_res/lib/gio/modules"
export GIO_EXTRA_MODULES="$bundle_lib/gio/modules"
export PANGO_LIBDIR="$bundle_lib"
export PANGO_SYSCONFDIR="$bundle_etc"

View file

@ -113,7 +113,7 @@ AC_CONFIG_COMMANDS([libtool-hacking],
dnl Add the languages which your application supports here.
PKG_PROG_PKG_CONFIG
ALL_LINGUAS="fr it de ja es pl cs nl sv pt_BR hu ru zh_CN nb_NO zh_TW he"
ALL_LINGUAS="fr it de ja es pl cs nl sv pt_BR hu ru zh_CN nb_NO zh_TW he sr"
AC_SUBST(ALL_LINGUAS)
AC_DEFINE_UNQUOTED(LINPHONE_ALL_LANGS, "$ALL_LINGUAS", [All supported languages])
@ -229,7 +229,7 @@ AC_ARG_ENABLE(gtk_ui,
if test "$gtk_ui" = "true" ; then
PKG_CHECK_MODULES(LIBGTK, gtk+-2.0 >= 2.18.0 gthread-2.0)
if test "$enable_x11" = "false" ; then
PKG_CHECK_MODULES(LIBGTKMAC,[ige-mac-integration >= 0.9.7 ])
PKG_CHECK_MODULES(LIBGTKMAC,[gtk-mac-integration >= 2.0.1])
AC_DEFINE([HAVE_GTK_OSX],[1],[Defined when gtk osx is used])
fi
else
@ -665,6 +665,23 @@ if test x$enable_tunnel = xtrue; then
AC_SUBST(TUNNEL_LIBS)
fi
AC_ARG_ENABLE(msg-storage,
[AS_HELP_STRING([--enable-msg-storage=[yes/no]], [Turn on compilation of message storage (default=yes)])],
[case "${enableval}" in
yes) enable_msg_storage=true ;;
no) enable_msg_storage=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-msg-storage) ;;
esac],
[enable_msg_storage=true]
)
AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue)
if test x$enable_msg_storage = xtrue; then
PKG_CHECK_MODULES(SQLITE3,[ sqlite3 >= 3.7.0],[],[
AC_MSG_ERROR([sqlite3 required for message storage not found.])] )
SQLITE3_CFLAGS+="-DMSG_STORAGE_ENABLED"
AC_SUBST(SQLITE3_CFLAGS)
AC_SUBST(SQLITE3_LIBS)
fi
SIPSTACK_CFLAGS=
SIPSTACK_LIBS=
@ -834,6 +851,7 @@ printf "* %-30s %s\n" "GTK interface" $gtk_ui
printf "* %-30s %s\n" "Account assistant" $build_wizard
printf "* %-30s %s\n" "Console interface" $console_ui
printf "* %-30s %s\n" "Tools" $build_tools
printf "* %-30s %s\n" "Message storage" $enable_msg_storage
printf "* %-30s %s\n" "zRTP encryption (GPLv3)" $zrtp
printf "* %-30s %s\n" "uPnP support" $build_upnp

View file

@ -15,6 +15,7 @@ COMMON_CFLAGS=\
$(READLINE_CFLAGS) \
$(OSIP_CFLAGS) \
$(ORTP_CFLAGS) \
$(SQLITE3_CFLAGS) \
$(MEDIASTREAMER_CFLAGS)
if BUILD_CONSOLE
@ -29,6 +30,7 @@ linphonec_SOURCES=linphonec.c linphonec.h commands.c
linphonec_CFLAGS=$(COMMON_CFLAGS) $(CONSOLE_FLAGS)
linphonec_LDADD=$(top_builddir)/coreapi/liblinphone.la \
$(READLINE_LIBS) \
$(SQLITE3_LIBS) \
$(X11_LIBS)
if BUILD_WIN32

View file

@ -44,6 +44,7 @@ liblinphone_la_SOURCES=\
lsd.c linphonecore_utils.h \
ec-calibrator.c \
conference.c \
message_storage.c \
$(GITVERSION_FILE)
if BUILD_UPNP
@ -85,7 +86,9 @@ liblinphone_la_LIBADD= \
$(MEDIASTREAMER_LIBS) \
$(ORTP_LIBS) $(OPENSSL_LIBS) \
$(TUNNEL_LIBS) \
$(LIBSOUP_LIBS)
$(LIBSOUP_LIBS) \
$(SQLITE3_LIBS)
if BUILD_TESTS
noinst_PROGRAMS=test_lsd test_ecc test_numbers
@ -117,7 +120,8 @@ AM_CFLAGS=\
$(IPV6_CFLAGS) \
-DORTP_INET6 \
$(VIDEO_CFLAGS) \
$(TUNNEL_CFLAGS)
$(TUNNEL_CFLAGS) \
$(SQLITE3_CFLAGS)
if BUILD_WIZARD
AM_CFLAGS+= -DBUILD_WIZARD

View file

@ -102,6 +102,10 @@ int TunnelManager::eXosipSelect(int max_fds, fd_set *s1, fd_set *s2, fd_set *s3,
void TunnelManager::addServer(const char *ip, int port,unsigned int udpMirrorPort,unsigned int delay) {
if (ip == NULL) {
ip = "";
ms_warning("Adding tunnel server with empty ip, it will not work!");
}
addServer(ip,port);
mUdpMirrorClients.push_back(UdpMirrorClient(ServerAddr(ip,udpMirrorPort),delay));
}

View file

@ -123,7 +123,8 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
sal_op_release(op);
}
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg,const char*t){
/*FIXME impement time*/
belle_sip_request_t* req;
char content_type_raw[256];
size_t content_length = msg?strlen(msg):0;
@ -141,8 +142,8 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
return sal_op_send_request(op,req);
}
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) {
return sal_message_send(op,from,to,"text/plain",msg);
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg, const char*t) {
return sal_message_send(op,from,to,"text/plain",msg,t);
}
void sal_op_message_fill_cbs(SalOp*op) {

View file

@ -200,6 +200,7 @@ int sdp_to_media_description(belle_sdp_session_description_t *session_desc, Sal
}
stream->rtp_port=belle_sdp_media_get_media_port(media);
stream->rtcp_port = stream->rtp_port + 1;
if (stream->rtp_port > 0)
desc->n_active_streams++;

View file

@ -960,6 +960,7 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
LinphoneChatMessage *chat_msg=(LinphoneChatMessage* )sal_op_get_user_pointer(op);
const MSList* calls = linphone_core_get_calls(chat_msg->chat_room->lc);
linphone_core_set_message_state(chat_msg->chat_room,chat_msg->message,chatStatusSal2Linphone(status),chat_msg->time);
if (chat_msg && chat_msg->cb) {
chat_msg->cb(chat_msg
,chatStatusSal2Linphone(status)

View file

@ -62,12 +62,26 @@ void linphone_chat_room_destroy(LinphoneChatRoom *cr){
ms_free(cr->peer);
}
#ifdef WIN32
static inline char *my_ctime_r(const time_t *t, char *buf){
strcpy(buf,ctime(t));
return buf;
}
#else
#define my_ctime_r ctime_r
#endif
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg){
const char *route=NULL;
const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route);
SalOp *op=NULL;
LinphoneCall *call;
char* content_type;
time_t t=time(NULL);
char buf[26];
char *to;
if (lp_config_get_int(cr->lc->config,"sip","chat_use_call_dialogs",0)){
if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL){
@ -82,6 +96,7 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
}
}
}
msg->time=t;
if (op==NULL){
/*sending out of calls*/
op = sal_op_new(cr->lc->sal);
@ -94,11 +109,15 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
}
if (msg->external_body_url) {
content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url);
sal_message_send(op,identity,cr->peer,content_type, NULL);
sal_message_send(op,identity,cr->peer,content_type, NULL,my_ctime_r(&t,buf));
ms_free(content_type);
} else {
sal_text_send(op, identity, cr->peer,msg->message);
sal_text_send(op, identity, cr->peer,msg->message,my_ctime_r(&t,buf));
}
to=linphone_address_as_string_uri_only (cr->peer_url);
linphone_core_set_history_message(cr,identity,to,OUTGOING,msg->message,
my_ctime_r(&t,buf),READ,LinphoneChatMessageStateInProgress);
ms_free(to);
}
/**
@ -130,8 +149,11 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
LinphoneChatRoom *cr=NULL;
LinphoneAddress *addr;
char *cleanfrom;
const char *to;
char *from;
LinphoneChatMessage* msg;
const SalCustomHeader *ch;
char buf[26];
addr=linphone_address_new(sal_msg->from);
linphone_address_clean(addr);
@ -142,7 +164,9 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
}
cr=NULL;
}
to=linphone_core_get_identity(lc);
cleanfrom=linphone_address_as_string(addr);
from=linphone_address_as_string_uri_only(addr);
if (cr==NULL){
/* create a new chat room */
cr=linphone_core_create_chat_room(lc,cleanfrom);
@ -150,6 +174,7 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
msg = linphone_chat_room_create_message(cr, sal_msg->text);
linphone_chat_message_set_from(msg, cr->peer_url);
msg->time=sal_msg->time;
msg->state=LinphoneChatMessageStateDelivered;
ch=sal_op_get_custom_header(op);
if (ch) msg->custom_headers=sal_custom_header_clone(ch);
@ -157,8 +182,12 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
linphone_chat_message_set_external_body_url(msg, sal_msg->url);
}
linphone_address_destroy(addr);
linphone_core_set_history_message(cr,to,from,INCOMING,
msg->message,my_ctime_r(&msg->time,buf),NOT_READ,
LinphoneChatMessageStateDelivered);
linphone_chat_room_message_received(cr,lc,msg);
ms_free(cleanfrom);
ms_free(from);
}
/**
@ -215,6 +244,7 @@ LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr, con
void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangeCb status_cb, void* ud) {
msg->cb=status_cb;
msg->cb_ud=ud;
msg->state=LinphoneChatMessageStateInProgress;
_linphone_chat_room_send_message(cr, msg);
}
@ -308,6 +338,15 @@ time_t linphone_chat_message_get_time(const LinphoneChatMessage* message) {
return message->time;
}
/**
* Get the state of the message
*@param message #LinphoneChatMessage obj
*@return #LinphoneChatMessageState
*/
LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message) {
return message->state;
}
/**
* Get text part of this message
* @return text or NULL if no text.
@ -347,6 +386,9 @@ LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg)
void* message_userdata;
char* external_body_url;
LinphoneAddress* from;
time_t time;
SalCustomHeader *custom_headers;
LinphoneChatMessageState state;
};*/
LinphoneChatMessage* new_message = linphone_chat_room_create_message(msg->chat_room,msg->message);
if (msg->external_body_url) new_message->external_body_url=ms_strdup(msg->external_body_url);
@ -354,6 +396,8 @@ LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg)
new_message->cb_ud=msg->cb_ud;
new_message->message_userdata=msg->message_userdata;
new_message->cb=msg->cb;
new_message->time=msg->time;
new_message->state=msg->state;
if (msg->from) new_message->from=linphone_address_clone(msg->from);
return new_message;
}

View file

@ -366,7 +366,12 @@ int linphone_call_log_get_duration(LinphoneCallLog *cl){
float linphone_call_log_get_quality(LinphoneCallLog *cl){
return cl->quality;
}
/**
* return true if video was enabled at the end of the call
*/
LinphoneCallStatus linphone_call_log_video_enabled(LinphoneCallLog *cl) {
return cl->video_enabled;
}
/** @} */
void linphone_call_log_destroy(LinphoneCallLog *cl){
@ -1306,6 +1311,9 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
#ifdef TUNNEL_ENABLED
lc->tunnel=linphone_core_tunnel_new(lc);
if (lc->tunnel) linphone_tunnel_configure(lc->tunnel);
#endif
#ifdef MSG_STORAGE_ENABLED
lc->db=linphone_message_storage_init();
#endif
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Ready"));

View file

@ -165,6 +165,7 @@ LinphoneAddress *linphone_call_log_get_to(LinphoneCallLog *cl);
LinphoneAddress *linphone_call_log_get_remote_address(LinphoneCallLog *cl);
LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl);
LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl);
LinphoneCallStatus linphone_call_log_video_enabled(LinphoneCallLog *cl);
time_t linphone_call_log_get_start_date(LinphoneCallLog *cl);
int linphone_call_log_get_duration(LinphoneCallLog *cl);
float linphone_call_log_get_quality(LinphoneCallLog *cl);
@ -681,6 +682,7 @@ void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud);
void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr);
LINPHONE_PUBLIC const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state);
LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message);
LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message);
void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from);
LINPHONE_PUBLIC LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message);
@ -1424,6 +1426,10 @@ int linphone_core_get_audio_dscp(const LinphoneCore *lc);
void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp);
int linphone_core_get_video_dscp(const LinphoneCore *lc);
MSList *linphone_chat_room_get_history(const char *to,LinphoneChatRoom *cr,int nb_message);
void linphone_core_set_messages_flag_read(LinphoneChatRoom *cr,const char *from, int read);
void linphone_core_delete_history(LinphoneCore *lc,const char *from);
#ifdef __cplusplus
}
#endif

202
coreapi/message_storage.c Normal file
View file

@ -0,0 +1,202 @@
/*
message_storage.c
Copyright (C) 2012 Belledonne Communications, Grenoble, France
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.
*/
#include "private.h"
#include "linphonecore.h"
#ifdef WIN32
static inline char *my_ctime_r(const time_t *t, char *buf){
strcpy(buf,ctime(t));
return buf;
}
#else
#define my_ctime_r ctime_r
#endif
#ifdef MSG_STORAGE_ENABLED
#include "sqlite3.h"
static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
#define CONFIG_FILE ".linphone-history.db"
char *linphone_message_storage_get_config_file(const char *filename){
const int path_max=1024;
char *config_file=(char *)malloc(path_max*sizeof(char));
if (filename==NULL) filename=CONFIG_FILE;
/*try accessing a local file first if exists*/
if (access(CONFIG_FILE,F_OK)==0){
snprintf(config_file,path_max,"%s",filename);
}else{
#ifdef WIN32
const char *appdata=getenv("APPDATA");
if (appdata){
snprintf(config_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
CreateDirectory(config_file,NULL);
snprintf(config_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename);
}
#else
const char *home=getenv("HOME");
if (home==NULL) home=".";
snprintf(config_file,path_max,"%s/%s",home,filename);
#endif
}
return config_file;
}
void create_chat_message(char **argv, void *data){
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
LinphoneChatMessage* new_message = linphone_chat_room_create_message(cr,argv[4]);
struct tm ret={0};
char tmp1[80]={0};
char tmp2[80]={0};
if(atoi(argv[3])==INCOMING){
linphone_chat_message_set_from(new_message,linphone_address_new(argv[2]));
} else {
linphone_chat_message_set_from(new_message,linphone_address_new(argv[1]));
}
if(argv[5]!=NULL){
int i,j;
sscanf(argv[5],"%3c %3c%d%d:%d:%d %d",tmp1,tmp2,&ret.tm_mday,
&ret.tm_hour,&ret.tm_min,&ret.tm_sec,&ret.tm_year);
ret.tm_year-=1900;
for(i=0;i<7;i++) {
if(strcmp(tmp1,days[i])==0) ret.tm_wday=i;
}
for(j=0;j<12;j++) {
if(strcmp(tmp2,months[j])==0) ret.tm_mon=j;
}
}
new_message->time=argv[5]!=NULL ? mktime(&ret) : time(NULL);
new_message->state=atoi(argv[7]);
cr->messages_hist=ms_list_prepend(cr->messages_hist,(void *)new_message);
}
static int callback(void *data, int argc, char **argv, char **colName){
create_chat_message(argv,data);
return 0;
}
void linphone_sql_request_message(sqlite3 *db,const char *stmt,void *data){
char* errmsg;
int ret;
ret=sqlite3_exec(db,stmt,callback,data,&errmsg);
if(ret != SQLITE_OK) {
printf("Error in creation: %s.\n", errmsg);
}
}
void linphone_sql_request(sqlite3* db,const char *stmt){
char* errmsg;
int ret;
ret=sqlite3_exec(db,stmt,0,0,&errmsg);
if(ret != SQLITE_OK) {
printf("Error in creation: %s.\n", errmsg);
}
}
void linphone_core_set_history_message(LinphoneChatRoom *cr,const char *local_contact,const char *remote_contact,
int direction, const char *message,const char *date, int read, int state){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
char *buf=sqlite3_mprintf("insert into history values(NULL,%Q,%Q,%i,%Q,%Q,%i,%i);",
local_contact,remote_contact,direction,message,date,read,state);
linphone_sql_request(lc->db,buf);
}
void linphone_core_set_message_state(LinphoneChatRoom *cr,const char *message, int state, time_t date){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
char time_str[26];
char *buf=sqlite3_mprintf("update history set status=%i where message = %Q and time = %Q;",
state,message,my_ctime_r(&date,time_str));
linphone_sql_request(lc->db,buf);
}
void linphone_core_set_messages_flag_read(LinphoneChatRoom *cr,const char *from, int read){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
char *buf=sqlite3_mprintf("update history set read=%i where remoteContact = %Q;",
read,from);
linphone_sql_request(lc->db,buf);
}
void linphone_core_delete_history(LinphoneCore *lc,const char *from){
char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",from);
linphone_sql_request(lc->db,buf);
}
MSList *linphone_chat_room_get_history(const char *to,LinphoneChatRoom *cr,int nb_message){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
cr->messages_hist = NULL;
char *buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC limit %i ;",to,nb_message);
linphone_sql_request_message(lc->db,buf,(void *)cr);
return cr->messages_hist;
}
void linphone_close_storage(sqlite3* db){
sqlite3_close(db);
}
void linphone_create_table(sqlite3* db){
char* errmsg;
int ret;
ret=sqlite3_exec(db,"CREATE TABLE if not exists history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);",
0,0,&errmsg);
if(ret != SQLITE_OK) {
printf("Error in creation: %s.\n", errmsg);
}
}
sqlite3 * linphone_message_storage_init(){
int ret;
char *errmsg;
sqlite3 *db;
char *filename;
filename=linphone_message_storage_get_config_file(NULL);
ret=sqlite3_open(filename,&db);
if(ret != SQLITE_OK) {
printf("Error in the opening: %s.\n", errmsg);
sqlite3_close(db);
}
linphone_create_table(db);
return db;
}
#else
void linphone_core_set_history_message(LinphoneChatRoom *cr,const char *local_contact,const char *remote_contact,
int direction, const char *message,const char *date, int read, int state){
}
void linphone_core_set_message_state(LinphoneChatRoom *cr,const char *message, int state, time_t date){
}
void linphone_core_set_messages_flag_read(LinphoneChatRoom *cr,const char *from, int read){
}
MSList *linphone_chat_room_get_history(const char *to,LinphoneChatRoom *cr,int nb_message){
return NULL;
}
void linphone_core_delete_history(LinphoneCore *lc,const char *from){
}
#endif

View file

@ -44,6 +44,10 @@ extern "C" {
#include "upnp.h"
#endif //BUILD_UPNP
#ifdef MSG_STORAGE_ENABLED
#include "sqlite3.h"
#endif
#ifndef LIBLINPHONE_VERSION
#define LIBLINPHONE_VERSION LINPHONE_VERSION
#endif
@ -125,6 +129,7 @@ struct _LinphoneChatMessage {
LinphoneAddress* from;
time_t time;
SalCustomHeader *custom_headers;
LinphoneChatMessageState state;
};
typedef struct StunCandidate{
@ -399,6 +404,7 @@ struct _LinphoneChatRoom{
char *peer;
LinphoneAddress *peer_url;
void * user_data;
MSList *messages_hist;
};
@ -617,6 +623,9 @@ struct _LinphoneCore
LinphoneTunnel *tunnel;
char* device_id;
MSList *last_recv_msg_ids;
#ifdef MSG_STORAGE_ENABLED
sqlite3 *db;
#endif
#ifdef BUILD_UPNP
UpnpContext *upnp;
#endif //BUILD_UPNP
@ -698,6 +707,20 @@ void linphone_call_params_uninit(LinphoneCallParams *params);
int linphone_upnp_init(LinphoneCore *lc);
void linphone_upnp_destroy(LinphoneCore *lc);
#define OUTGOING 0
#define INCOMING 1
#define NOT_READ 0
#define READ 1
#ifdef MSG_STORAGE_ENABLED
sqlite3 * linphone_message_storage_init();
#endif
void linphone_core_set_history_message(LinphoneChatRoom *cr,const char *local_contact,const char *remote_contact,
int direction, const char *message,const char *date, int read, int state);
void linphone_core_set_message_state(LinphoneChatRoom *cr,const char *message, int state,time_t date);
#ifdef __cplusplus
}
#endif

View file

@ -1800,7 +1800,6 @@ static void text_received(Sal *sal, eXosip_event_t *ev){
}
}else ms_warning("No date header in SIP MESSAGE, we don't know when it was sent.");
content_type= osip_message_get_content_type(ev->request);
if (!content_type) {
ms_error("Could not get message because no content type");
@ -1848,8 +1847,6 @@ static void text_received(Sal *sal, eXosip_event_t *ev){
osip_free(from);
}
static void other_request(Sal *sal, eXosip_event_t *ev){
ms_message("in other_request");
if (ev->request==NULL) return;

View file

@ -81,21 +81,8 @@ void sal_remove_in_subscribe(Sal *sal, SalOp *op){
sal->in_subscribes=ms_list_remove(sal->in_subscribes,op);
}
#ifdef WIN32
static inline char *my_ctime_r(const time_t *t, char *buf){
strcpy(buf,ctime(t));
return buf;
}
#else
#define my_ctime_r ctime_r
#endif
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *t){
osip_message_t *sip=NULL;
time_t t=time(NULL);
char buf[26];
if(op->cid == -1)
{
@ -111,7 +98,7 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
sal_op_get_from(op),sal_op_get_route(op));
if (sip!=NULL){
sal_exosip_add_custom_headers(sip,op->base.custom_headers);
osip_message_set_date(sip,my_ctime_r(&t,buf));
osip_message_set_date(sip,t);
osip_message_set_content_type(sip,content_type);
if (msg) osip_message_set_body(sip,msg,strlen(msg));
sal_add_other(op->base.root,op,sip);
@ -141,8 +128,8 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
return 0;
}
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) {
return sal_message_send(op,from,to,"text/plain",msg);
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg,const char *t) {
return sal_message_send(op,from,to,"text/plain",msg,t);
}
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){

View file

@ -241,7 +241,7 @@ void linphone_upnp_igd_callback(void *cookie, upnp_igd_event event, void *arg) {
* If there is no pending binding emit a signal
*/
if(lupnp->pending_bindings == NULL) {
pthread_cond_signal(&lupnp->empty_cond);
ms_cond_signal(&lupnp->empty_cond);
}
ms_mutex_unlock(&lupnp->mutex);
}
@ -1109,7 +1109,10 @@ void linphone_upnp_session_destroy(UpnpSession *session) {
linphone_upnp_context_send_remove_port_binding(lc->upnp, session->video->rtcp, TRUE);
}
}
session->call->stats[LINPHONE_CALL_STATS_AUDIO].upnp_state = LinphoneUpnpStateKo;
session->call->stats[LINPHONE_CALL_STATS_VIDEO].upnp_state = LinphoneUpnpStateKo;
linphone_upnp_stream_destroy(session->audio);
linphone_upnp_stream_destroy(session->video);
ms_free(session);

View file

@ -55,7 +55,7 @@ linphone_SOURCES+= \
endif
linphone_LDADD= $(top_builddir)/coreapi/liblinphone.la \
$(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS)
$(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS) $(SQLITE3_LIBS)
if BUILD_WIN32
@ -79,7 +79,8 @@ AM_CFLAGS= -DIN_LINPHONE -I$(top_srcdir)/coreapi/ \
$(MEDIASTREAMER_CFLAGS) \
$(ORTP_CFLAGS) \
$(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) $(IPV6_CFLAGS) \
$(TUNNEL_CFLAGS)
$(TUNNEL_CFLAGS) \
$(SQLITE3_CFLAGS)
version_date.h: $(top_srcdir)/configure.ac

View file

@ -23,21 +23,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <gtkosxapplication.h>
#endif
#define NB_MSG_HIST 250
void linphone_gtk_quit_chatroom(LinphoneChatRoom *cr) {
GtkWidget *main_window=linphone_gtk_get_main_window ();
GtkWidget *nb=linphone_gtk_get_widget(main_window,"viewswitch");
GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list");
GtkWidget *w=g_object_get_data(G_OBJECT(friendlist),"chatview");
int idx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"idx"));
g_return_if_fail(w!=NULL);
gtk_notebook_remove_page (GTK_NOTEBOOK(nb),idx);
gtk_notebook_remove_page(GTK_NOTEBOOK(nb),idx);
linphone_gtk_create_chat_picture(FALSE);
g_object_set_data(G_OBJECT(friendlist),"chatview",NULL);
g_object_set_data(G_OBJECT(w),"from_message",NULL);
g_object_set_data(G_OBJECT(w),"from_message",NULL);
g_object_set_data(G_OBJECT(w),"cr",NULL);
g_object_set_data(G_OBJECT(friendlist),"from",NULL);
gtk_widget_destroy(w);
}
const char* get_display_name(const LinphoneAddress *from){
const char *display=linphone_address_get_display_name(from);
if (display==NULL || display[0]=='\0') {
display=linphone_address_get_username(from);
}
return display;
}
GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr,const LinphoneAddress *uri){
GtkWidget *w=gtk_hbox_new (FALSE,0);
GtkWidget *i=create_pixmap ("chat.png");
@ -49,12 +61,7 @@ GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr,const LinphoneAddress *ur
gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE);
gtk_widget_set_size_request(b,25,20);
g_signal_connect_swapped(G_OBJECT(b),"clicked",G_CALLBACK(linphone_gtk_quit_chatroom),cr);
const char *display=linphone_address_get_display_name(uri);
if (display==NULL || display[0]=='\0') {
display=linphone_address_get_username(uri);
}
l=gtk_label_new (display);
l=gtk_label_new (get_display_name(uri));
gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0);
gtk_box_pack_start (GTK_BOX(w),l,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(w),b,TRUE,TRUE,0);
@ -75,81 +82,73 @@ void udpate_tab_chat_header(GtkWidget *chat_view,const LinphoneAddress *uri,Linp
gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE);
gtk_widget_set_size_request(b,25,20);
g_signal_connect_swapped(G_OBJECT(b),"clicked",G_CALLBACK(linphone_gtk_quit_chatroom),cr);
const char *display=linphone_address_get_display_name(uri);
if (display==NULL || display[0]=='\0') {
display=linphone_address_get_username(uri);
}
l=gtk_label_new (display);
l=gtk_label_new (get_display_name(uri));
gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0);
gtk_box_pack_start (GTK_BOX(w),l,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(w),b,TRUE,TRUE,0);
gtk_notebook_set_tab_label(notebook,chat_view,w);
gtk_widget_show_all(w);
}
void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
const char *message, gboolean me,LinphoneChatRoom *cr, time_t t){
gboolean me,LinphoneChatRoom *cr,LinphoneChatMessage *msg, gboolean hist){
GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textview"));
GtkTextBuffer *buffer=gtk_text_view_get_buffer(text);
GtkTextIter iter,begin,end;
gtk_text_buffer_get_start_iter(buffer,&begin);
GtkTextIter iter,begin;
int off;
char *from_str=linphone_address_as_string_uri_only(from);
char *from_message=(char *)g_object_get_data(G_OBJECT(w),"from_message");
GList *list=g_object_get_data(G_OBJECT(w),"list");
time_t t;
gtk_text_buffer_get_start_iter(buffer,&begin);
gtk_text_buffer_get_end_iter(buffer,&iter);
off=gtk_text_iter_get_offset(&iter);
GList *list=g_object_get_data(G_OBJECT(w),"list");
if(g_strcmp0((char *)g_object_get_data(G_OBJECT(w),"from_message"),linphone_address_as_string(from))!=0){
if(g_strcmp0(from_message,from_str)!=0){
gtk_text_buffer_get_iter_at_offset(buffer,&iter,off);
const char *display=linphone_address_get_display_name(from);
if (display==NULL || display[0]=='\0') {
display=linphone_address_get_username(from);
}
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,display,-1,"bold",me ? "bg":NULL,NULL);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,get_display_name(from),-1,"bold",me ? "bg":NULL,NULL);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter," : ",-1,"bold",me ? "bg":NULL,NULL);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"\n",-1);
g_object_set_data(G_OBJECT(w),"from_message",linphone_address_as_string(from));
g_object_set_data(G_OBJECT(w),"from_message",from_str);
}
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_get_iter_at_offset(buffer,&begin,off);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,message,-1,"margin",me ? "bg":NULL,NULL);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,linphone_chat_message_get_text(msg),-1,"margin",me ? "bg":NULL,NULL);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"\n",-1);
gtk_text_buffer_get_bounds (buffer, &begin, &end);
GHashTable *hash=(GHashTable *)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"history");
if(me){
g_hash_table_insert(hash,linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)),
(gpointer)gtk_text_buffer_get_text(buffer,&begin,&end,FALSE));
} else {
g_hash_table_insert(hash,linphone_address_as_string_uri_only(from),
(gpointer)gtk_text_buffer_get_text(buffer,&begin,&end,FALSE));
}
g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"history",hash);
gtk_text_buffer_insert(buffer,&iter,"\n",-1);;
gtk_text_buffer_get_end_iter(buffer,&iter);
if(me){
list=g_list_append(list,GINT_TO_POINTER(gtk_text_iter_get_line(&iter)));
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending .. ",-1,
"italic","right","small","font_grey","bg",NULL);
g_object_set_data(G_OBJECT(w),"list",list);
} else {
struct tm *tm=localtime(&t);
char buf[80];
strftime(buf,80,"Send at %H:%M",tm);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,buf,-1,
"italic","right","small","font_grey",NULL);
t=linphone_chat_message_get_time(msg);
switch (linphone_chat_message_get_state (msg)){
case LinphoneChatMessageStateInProgress:
{
list=g_list_append(list,GINT_TO_POINTER(gtk_text_iter_get_line(&iter)));
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending .. ",-1,
"right","small","italic","font_grey","bg",NULL);
g_object_set_data(G_OBJECT(w),"list",list);
break;
}
case LinphoneChatMessageStateDelivered:
{
struct tm *tm=localtime(&t);
char buf[80];
strftime(buf,80,"%H:%M",tm);
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,buf,-1,
"right","small","italic","font_grey",me ? "bg":NULL,NULL);
break;
}
case LinphoneChatMessageStateNotDelivered:
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Error",-1,
"right","small","italic","font_grey",me ? "bg":NULL,NULL);
break;
default : gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1,
"right","small","italic","font_grey",me ? "bg":NULL,NULL);
}
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"\n",-1);
GtkTextMark *mark=gtk_text_buffer_create_mark(buffer,NULL,&iter,FALSE);
gtk_text_view_scroll_mark_onscreen(text,mark);
gtk_text_view_scroll_mark_onscreen(text,mark);
}
const LinphoneAddress* linphone_gtk_get_used_identity(){
@ -160,8 +159,6 @@ const LinphoneAddress* linphone_gtk_get_used_identity(){
else return linphone_core_get_primary_contact_parsed(lc);
}
/* function in dev for displaying ack*/
void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessage *msg){
GtkWidget *main_window=linphone_gtk_get_main_window();
GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list");
@ -181,7 +178,7 @@ void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessag
gtk_text_buffer_get_iter_at_line_offset(b,&start,
GPOINTER_TO_INT(g_list_nth_data(list,0)),
gtk_text_iter_get_chars_in_line(&iter)-1);
}else {
}else{
gtk_text_buffer_get_iter_at_line_offset(b,&start,
GPOINTER_TO_INT(g_list_nth_data(list,0)),0);
}
@ -209,7 +206,7 @@ void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessag
default : result="Sending ..";
}
gtk_text_buffer_insert_with_tags_by_name(b,&iter,result,-1,
"italic","right","small","font_grey","bg",NULL);
"right","small","italic","font_grey","bg",NULL);
list=g_list_remove(list,g_list_nth_data(list,0));
g_object_set_data(G_OBJECT(page),"list",list);
}
@ -231,59 +228,66 @@ void linphone_gtk_send_text(){
LinphoneChatMessage *msg;
msg=linphone_chat_room_create_message(cr,entered);
linphone_chat_room_send_message2(cr,msg,on_chat_state_changed,NULL);
linphone_gtk_push_text(w,
linphone_gtk_get_used_identity(),
entered,TRUE,cr,linphone_chat_message_get_time(msg));
linphone_gtk_push_text(w,linphone_gtk_get_used_identity(),
TRUE,cr,msg,FALSE);
gtk_entry_set_text(GTK_ENTRY(entry),"");
}
}
void display_history_message(GtkWidget *chat_view,MSList *messages,const LinphoneAddress *with){
if(messages != NULL){
MSList *it;
char *from_str;
char *with_str;
for(it=messages;it!=NULL;it=it->next){
LinphoneChatMessage *msg=(LinphoneChatMessage *)it->data;
from_str=linphone_address_as_string_uri_only(linphone_chat_message_get_from(msg));
with_str=linphone_address_as_string_uri_only(with);
linphone_gtk_push_text(chat_view,strcmp(from_str,with_str)==0? with :
linphone_chat_message_get_from(msg),
strcmp(from_str,with_str)==0? FALSE : TRUE,
linphone_chat_message_get_chat_room(msg),msg,TRUE);
}
g_object_set_data(G_OBJECT(chat_view),"from_message",NULL);
ms_free(from_str);
ms_free(with_str);
}
}
GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with){
GtkWidget *chat_view=linphone_gtk_create_widget("main","chatroom_frame");
GtkWidget *main_window=linphone_gtk_get_main_window ();
GHashTable *hash=g_object_get_data(G_OBJECT(main_window),"history");
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
GtkWidget *text=linphone_gtk_get_widget(chat_view,"textview");
GdkColor color;
GdkColor colorb;
int idx;
GtkWidget *button;
GtkWidget *entry;
GList *list=NULL;
MSList *messages;
char *with_str;
color.red = 32512;
color.green = 32512;
color.blue = 32512;
GdkColor colorb;
colorb.red = 56832;
colorb.green = 60928;
colorb.blue = 61952;
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(text),GTK_WRAP_WORD);
gtk_text_view_set_editable (GTK_TEXT_VIEW(text),FALSE);
gtk_notebook_append_page (notebook,chat_view,create_tab_chat_header(cr,with));
with_str=linphone_address_as_string_uri_only(with);
linphone_core_set_messages_flag_read(cr,with_str,1);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text),GTK_WRAP_WORD_CHAR);
gtk_text_view_set_editable(GTK_TEXT_VIEW(text),FALSE);
gtk_notebook_append_page(notebook,chat_view,create_tab_chat_header(cr,with));
idx = gtk_notebook_page_num(notebook, chat_view);
gtk_notebook_set_current_page(notebook, idx);
gtk_widget_show(chat_view);
g_object_set_data(G_OBJECT(chat_view),"cr",cr);
g_object_set_data(G_OBJECT(chat_view),"idx",GINT_TO_POINTER(idx));
g_object_set_data(G_OBJECT(chat_view),"from_message",NULL);
g_object_set_data(G_OBJECT(chat_view),"from_chatroom",(gpointer) with);
GList *list=NULL;
g_object_set_data(G_OBJECT(chat_view),"list",list);
gchar *buf=g_hash_table_lookup(hash,linphone_address_as_string_uri_only(with));
if(buf != NULL){
GtkTextIter start;
GtkTextIter end;
GtkTextBuffer *text_buffer;
text_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
gtk_text_buffer_get_bounds(text_buffer, &start, &end);
gtk_text_buffer_delete (text_buffer, &start, &end);
gtk_text_buffer_insert(text_buffer,&start,buf,-1);
}
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
"right","justification", GTK_JUSTIFY_RIGHT,NULL);
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
@ -300,13 +304,13 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
"margin","indent",10,NULL);
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
"bg","paragraph-background-gdk",&colorb,NULL);
GtkWidget *button = linphone_gtk_get_widget(chat_view,"send");
messages = linphone_chat_room_get_history(with_str,cr,NB_MSG_HIST);
display_history_message(chat_view,messages,with);
button = linphone_gtk_get_widget(chat_view,"send");
g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,NULL);
GtkWidget *entry = linphone_gtk_get_widget(chat_view,"text_entry");
entry = linphone_gtk_get_widget(chat_view,"text_entry");
g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,NULL);
ms_free(with_str);
return chat_view;
}
@ -318,31 +322,31 @@ LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with){
void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,GtkWidget *chat_view){
GtkWidget *main_window=linphone_gtk_get_main_window ();
GHashTable *hash=g_object_get_data(G_OBJECT(main_window),"history");
LinphoneAddress *from=(LinphoneAddress *)g_object_get_data(G_OBJECT(chat_view),"from_chatroom");
if(g_strcmp0(linphone_address_as_string(from),linphone_address_as_string(uri))!=0)
{
LinphoneChatRoom *cr2=(LinphoneChatRoom *)g_object_get_data(G_OBJECT(chat_view),"cr");
char *from_str=linphone_address_as_string(linphone_chat_room_get_peer_address (cr2));
char *uri_str=linphone_address_as_string(uri);
char *uri_only=linphone_address_as_string_uri_only(uri);
MSList *messages=NULL;
linphone_core_set_messages_flag_read(cr,uri_only,1);
if(g_strcmp0(from_str,uri_str)!=0){
GtkTextView *text_view=GTK_TEXT_VIEW(linphone_gtk_get_widget(chat_view,"textview"));
GtkTextIter start;
GtkTextIter end;
gchar *buf=g_hash_table_lookup(hash,linphone_address_as_string_uri_only(uri));
GtkTextBuffer *text_buffer;
GtkTextBuffer *text_buffer;
text_buffer=gtk_text_view_get_buffer(text_view);
gtk_text_buffer_get_bounds(text_buffer, &start, &end);
g_object_set_data(G_OBJECT(chat_view),"cr",cr);
gtk_text_buffer_delete (text_buffer, &start, &end);
if(buf!=NULL){
gtk_text_buffer_insert_with_tags_by_name(text_buffer,&start,buf,-1,"font_grey",NULL);
GtkTextMark *mark=gtk_text_buffer_create_mark(text_buffer, NULL, &start, FALSE);
gtk_text_view_scroll_to_mark(text_view,mark, 0, FALSE, 0, 0);
}
udpate_tab_chat_header(chat_view,uri,cr);
g_object_set_data(G_OBJECT(chat_view),"cr",cr);
g_object_set_data(G_OBJECT(chat_view),"from_chatroom",(gpointer) uri);
g_object_set_data(G_OBJECT(chat_view),"from_message",linphone_address_as_string_uri_only(uri));
g_object_set_data(G_OBJECT(linphone_gtk_get_widget(main_window,"contact_list")),"chatview",(gpointer)chat_view);
messages = linphone_chat_room_get_history(uri_only,cr,NB_MSG_HIST);
g_object_set_data(G_OBJECT(chat_view),"from_message",uri_str);
display_history_message(chat_view,messages,uri);
}
ms_free(from_str);
ms_free(uri_str);
}
void linphone_gtk_chat_destroyed(GtkWidget *w){
@ -360,8 +364,7 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room,
LinphoneChatMessage *msg){
GtkWidget *main_window=linphone_gtk_get_main_window();
GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list");
GtkWidget *w;
GtkWidget *w;
w=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
if(w!=NULL){
@ -369,14 +372,10 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room,
} else {
w=linphone_gtk_init_chatroom(room,linphone_chat_message_get_from(msg));
g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)w);
g_object_set_data(G_OBJECT(friendlist),"from",(gpointer)linphone_chat_message_get_from(msg));
char *from=linphone_address_as_string(linphone_chat_message_get_from(msg));
g_object_set_data(G_OBJECT(friendlist),"from",from);
}
const char *display=linphone_address_get_display_name(linphone_chat_message_get_from(msg));
if (display==NULL || display[0]=='\0') {
display=linphone_address_get_username(linphone_chat_message_get_from(msg));
}
get_display_name(linphone_chat_message_get_from(msg));
#ifdef HAVE_GTK_OSXs
/* Notified when a new message is sent */
linphone_gtk_status_icon_set_blinking(TRUE);
@ -391,7 +390,7 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room,
}
#endif
linphone_gtk_push_text(w,linphone_chat_message_get_from(msg),
linphone_chat_message_get_text(msg),FALSE,room,linphone_chat_message_get_time(msg));
FALSE,room,msg,FALSE);
linphone_gtk_update_chat_picture();
//gtk_window_present(GTK_WINDOW(w));
/*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/

View file

@ -165,6 +165,21 @@ void linphone_gtk_remove_contact(GtkWidget *button){
}
}
void linphone_gtk_delete_history(GtkWidget *button){
GtkWidget *w=gtk_widget_get_toplevel(button);
GtkTreeSelection *select;
GtkTreeIter iter;
GtkTreeModel *model;
LinphoneFriend *lf=NULL;
select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"contact_list")));
if (gtk_tree_selection_get_selected (select, &model, &iter))
{
gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1);
linphone_core_delete_history(linphone_gtk_get_core(),linphone_address_as_string_uri_only(linphone_friend_get_address(lf)));
linphone_gtk_show_friends();
}
}
static void linphone_gtk_call_selected(GtkTreeView *treeview){
linphone_gtk_set_selection_to_uri_bar(treeview);
linphone_gtk_start_call(linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(treeview)),
@ -195,7 +210,7 @@ void linphone_gtk_update_chat_picture(){
GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist));
GtkWidget *chat_view=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
LinphoneFriend *lf=NULL;
LinphoneAddress *uri=(LinphoneAddress *)g_object_get_data(G_OBJECT(friendlist),"from");
char *uri=(char *)g_object_get_data(G_OBJECT(friendlist),"from");
store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)));
if (gtk_tree_model_get_iter_first(model,&iter)) {
do{
@ -203,7 +218,7 @@ void linphone_gtk_update_chat_picture(){
if(chat_view!=NULL){
if(uri !=NULL) {
if(g_strcmp0(linphone_address_as_string(linphone_friend_get_address(lf)),
linphone_address_as_string(uri))==0){
uri)==0){
gtk_list_store_set(store,&iter,FRIEND_CHAT,create_active_chat_picture(),-1);
} else {
gtk_list_store_set(store,&iter,FRIEND_CHAT,create_chat_picture(),-1);
@ -241,7 +256,7 @@ void linphone_gtk_chat_selected(GtkWidget *item){
cr=linphone_gtk_create_chatroom(uri);
}
page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
g_object_set_data(G_OBJECT(friendlist),"from",(gpointer)uri);
g_object_set_data(G_OBJECT(friendlist),"from",linphone_address_as_string(uri));
if(page==NULL){
page=linphone_gtk_init_chatroom(cr,uri);
g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)page);
@ -786,6 +801,7 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){
gchar *text_label=NULL;
gchar *edit_label=NULL;
gchar *delete_label=NULL;
gchar *delete_hist_label=NULL;
gchar *name=NULL;
GtkTreeSelection *select;
GtkTreeIter iter;
@ -808,6 +824,7 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){
text_label=g_strdup_printf(_("Send text to %s"),name);
edit_label=g_strdup_printf(_("Edit contact '%s'"),name);
delete_label=g_strdup_printf(_("Delete contact '%s'"),name);
delete_hist_label=g_strdup_printf(_("Delete chat history of '%s'"),name);
g_free(name);
}
if (call_label){
@ -847,6 +864,15 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){
g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_remove_contact,contact_list);
}
if (delete_hist_label){
menu_item=gtk_image_menu_item_new_with_label(delete_hist_label);
image=gtk_image_new_from_stock(GTK_STOCK_CLEAR,GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
gtk_widget_show(image);
gtk_widget_show(menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_delete_history,contact_list);
}
if (ssc && (sip_setup_context_get_capabilities(ssc) & SIP_SETUP_CAP_BUDDY_LOOKUP)) {
gchar *tmp=g_strdup_printf(_("Add new contact from %s directory"),linphone_proxy_config_get_domain(cfg));

View file

@ -1118,13 +1118,13 @@ void linphone_gtk_notify(LinphoneCall *call, const char *msg){
NotifyNotification *n;
switch(linphone_call_get_state(call)){
case LinphoneCallError:
make_notification(_("Call error"),body=g_markup_printf_escaped("<span size=\"large\">%s</span>\n%s",msg,remote));
make_notification(_("Call error"),body=g_markup_printf_escaped("<b>%s</b>\n%s",msg,remote));
break;
case LinphoneCallEnd:
make_notification(_("Call ended"),body=g_markup_printf_escaped("<span size=\"large\">%s</span>",remote));
make_notification(_("Call ended"),body=g_markup_printf_escaped("<b>%s</b>",remote));
break;
case LinphoneCallIncomingReceived:
n=build_notification(_("Incoming call"),body=g_markup_printf_escaped("<span size=\"large\">%s</span>",remote));
n=build_notification(_("Incoming call"),body=g_markup_printf_escaped("<b>%s</b>",remote));
if (notify_actions_supported()) {
notify_notification_add_action (n,"answer", _("Answer"),
NOTIFY_ACTION_CALLBACK(linphone_gtk_answer_clicked),NULL,NULL);
@ -1134,7 +1134,7 @@ void linphone_gtk_notify(LinphoneCall *call, const char *msg){
show_notification(n);
break;
case LinphoneCallPausedByRemote:
make_notification(_("Call paused"),body=g_markup_printf_escaped(_("<span size=\"large\">by %s</span>"),remote));
make_notification(_("Call paused"),body=g_markup_printf_escaped(_("<b>by %s</b>"),remote));
break;
default:
break;
@ -1419,10 +1419,10 @@ static gboolean do_icon_blink(GtkStatusIcon *gi){
void linphone_gtk_status_icon_set_blinking(gboolean val){
#ifdef HAVE_GTK_OSX
static gint attention_id;
GtkOSXApplication *theMacApp=(GtkOSXApplication*)g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
GtkosxApplication *theMacApp=gtkosx_application_get();
if (val)
attention_id=gtk_osxapplication_attention_request(theMacApp,CRITICAL_REQUEST);
else gtk_osxapplication_cancel_attention_request(theMacApp,attention_id);
attention_id=gtkosx_application_attention_request(theMacApp,CRITICAL_REQUEST);
else gtkosx_application_cancel_attention_request(theMacApp,attention_id);
#else
if (icon!=NULL){
guint tout;
@ -1556,10 +1556,6 @@ static void linphone_gtk_configure_main_window(){
static gboolean buttons_have_borders;
static gboolean show_abcd;
GtkWidget *w=linphone_gtk_get_main_window();
GHashTable *contacts_history;
contacts_history=g_hash_table_new_full(g_str_hash, g_str_equal,g_free, NULL);
g_object_set_data(G_OBJECT(w),"history",(gpointer)contacts_history);
if (!config_loaded){
title=linphone_gtk_get_ui_config("title","Linphone");
@ -1728,10 +1724,10 @@ static void linphone_gtk_init_main_window(){
#ifdef HAVE_GTK_OSX
{
GtkWidget *menubar=linphone_gtk_get_widget(main_window,"menubar1");
GtkOSXApplication *theMacApp = (GtkOSXApplication*)g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
gtk_osxapplication_set_menu_bar(theMacApp,GTK_MENU_SHELL(menubar));
GtkosxApplication *theMacApp = gtkosx_application_get();
gtkosx_application_set_menu_bar(theMacApp,GTK_MENU_SHELL(menubar));
gtk_widget_hide(menubar);
gtk_osxapplication_ready(theMacApp);
gtkosx_application_ready(theMacApp);
}
g_signal_connect(G_OBJECT(main_window), "window-state-event",G_CALLBACK(on_window_state_event), NULL);
#endif
@ -1936,7 +1932,7 @@ int main(int argc, char *argv[]){
add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone");
#ifdef HAVE_GTK_OSX
GtkOSXApplication *theMacApp = (GtkOSXApplication*)g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
GtkosxApplication *theMacApp = gtkosx_application_get();
g_signal_connect(G_OBJECT(theMacApp),"NSApplicationDidBecomeActive",(GCallback)linphone_gtk_show_main_window,NULL);
g_signal_connect(G_OBJECT(theMacApp),"NSApplicationWillTerminate",(GCallback)gtk_main_quit,NULL);
/*never block termination:*/

View file

@ -778,6 +778,7 @@ static LangCodes supported_langs[]={
{ "zh_TW" , N_("Traditional Chinese") },
{ "nb_NO" , N_("Norwegian") },
{ "he" , N_("Hebrew") },
{ "sr" , N_("Serbian") },
{ NULL , NULL }
};

View file

@ -481,8 +481,8 @@ int sal_register_refresh(SalOp *op, int expires);
int sal_unregister(SalOp *h);
/*Messaging */
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg);
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text, const char*t);
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char*t);
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to);

@ -1 +1 @@
Subproject commit b501ae52004676aec90f632d9961945cde59b5da
Subproject commit daa8d61feee22ffcc72a2db189aa88956697de20

2
oRTP

@ -1 +1 @@
Subproject commit b055a505042c4420e104ce81a09790c5373f62bb
Subproject commit 20b527144f9850dd9065d96db7a20244e8a8b227

14
po/README Normal file
View file

@ -0,0 +1,14 @@
How to add a translation file
*****************************
To add a translation file in linphone project you should first :
- change the variable ALL_LINGUAS in configure.ac by adding the language (ex: fr)
- then add the file .po in the directory /po
- run ./autogen.sh
Update the tranlation files
***************************
To update all the translation files, in the directory /po run the following command
$ make update-po

771
po/cs.po

File diff suppressed because it is too large Load diff

766
po/de.po

File diff suppressed because it is too large Load diff

1858
po/es.po

File diff suppressed because it is too large Load diff

849
po/fr.po

File diff suppressed because it is too large Load diff

773
po/he.po

File diff suppressed because it is too large Load diff

767
po/hu.po

File diff suppressed because it is too large Load diff

759
po/it.po

File diff suppressed because it is too large Load diff

773
po/ja.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

768
po/nl.po

File diff suppressed because it is too large Load diff

785
po/pl.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

772
po/ru.po

File diff suppressed because it is too large Load diff

1877
po/sr.po Normal file

File diff suppressed because it is too large Load diff

759
po/sv.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff