diff --git a/Makefile.am b/Makefile.am index a1cd5594e364052b7282facd35f54e048c4b6dce..15cf2a90d6c77968778c8554de829468fe9fd50b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,6 +53,7 @@ EXTRA_DIST = config.rpath BUGS linphone.kdevelop \ README.mingw \ README.macos \ autogen.sh \ + linphone.spec \ linphone.spec.in \ $(GTK_FILELIST) \ gen-gtkfilelist.sh \ @@ -69,20 +70,24 @@ all-local: linphone.spec linphone.iss linphone.spec: linphone.spec.in -.phony: rpm -rpm: +.phony: rpm rpm-novideo rpm-base +rpm-base: $(MAKE) dist - cd oRTP && $(MAKE) dist && mv -f ortp*.tar.gz ../ - cd mediastreamer2 && $(MAKE) dist && mv -f mediastreamer*.tar.gz ../ -# Create "Specfile" at the same level as the tarball content -rm -f $(PACKAGE)-$(VERSION).tar gunzip $(PACKAGE)-$(VERSION).tar.gz - cp $(PACKAGE).spec Specfile - tar --append --file=$(PACKAGE)-$(VERSION).tar Specfile +#remove ms2 and ortp spec file to make sure linphone spec file is used bu rpmbuild + tar --delete --file=$(PACKAGE)-$(VERSION).tar $(PACKAGE)-$(VERSION)/mediastreamer2/mediastreamer2.spec + tar --delete --file=$(PACKAGE)-$(VERSION).tar $(PACKAGE)-$(VERSION)/oRTP/ortp.spec gzip $(PACKAGE)-$(VERSION).tar + +rpm: rpm-base # <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=2068410> TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz +rpm-novideo: rpm-base +# <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=2068410> + TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz --without video + #a zip containing win32 binaries, suitable to generate an installer if BUILD_ZRTP diff --git a/NEWS b/NEWS index d7c8f5559285b84a83f448cd42f3183a5d4cccf4..a4b134ddfc544607bd471a5b3da9e5c0d43cdd97 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ -linphone-3.5.0 -- future date +linphone-3.5.1 -- ?? + * gtk - implement friend search by typing into the friendlist, and friend sorting + +linphone-3.5.0 -- December 22, 2011 * added VP-8 video codec + * added G722 audio codec + * added SIP/TCP and SIP/TLS + * added SRTP media encryption + * Audio conferencing * UI: call history tab, menu simplified * UI: cosmetics for incall views * UI: integration with libnotify diff --git a/README.macos b/README.macos index 98b5b9fb60adf78a30ae815e577d859bf7b38878..d8c07159056b4c6d8b3a7a46b72ae3294f52fee7 100644 --- a/README.macos +++ b/README.macos @@ -15,26 +15,18 @@ You need: $ port install libosip2 $ port install libeXosip2 $ port install ffmpeg-devel - -- Install SDL (for video display) -Unfortunately the current (august 2011) version of sdl in macports crashes all the time. Fortunately these bugs are fixed in the development branch of SDL. -So we recommend to download SDL 1.3 with mercurial (hg) and compile it by yourself, like this: -First, make sure you have mercurial: - $ sudo port install mercurial -Fetch SDL: - $ hg clone http://hg.libsdl.org/SDL -Compile: - $ cd SDL - $ ./autogen.sh - $ ./configure --prefix=/opt/local && make -j4 + +- Install srtp (optional) for call encryption + $ 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 When this version will be integrated into macports, only this will be necessary: $ port install libsdl-devel - Install gtk. It is recommended to use the quartz backend for better integration. - $ port install cairo +quartz +no_x11 - $ port install pango +quartz +no_x11 $ port install gtk2 +quartz +no_x11 $ port install ige-mac-integration $ port install hicolor-icon-theme @@ -45,7 +37,7 @@ If you got the source code from git, run ./autogen.sh first. Then or otherwise, do: - $ ./configure --prefix=/opt/local --with-readline=/opt/local --disable-strict --disable-x11 && make + $ ./configure --prefix=/opt/local --with-readline=/opt/local --disable-strict --disable-x11 --with-srtp=/opt/local && make Install to /opt/local @@ -58,6 +50,8 @@ Use git: $ git clone https://github.com/jralls/gtk-mac-bundler.git $ cd gtk-mac-bundler && make install $ export PATH=$PATH:~/.local/bin + #make this dummy charset.alias file for the bundler to be happy: + $ sudo touch touch /opt/local/lib/charset.alias Then run, inside linphone source tree: 1. Run configure as told before but with "--enable-relativeprefix" appended. diff --git a/README.mingw b/README.mingw index 0c84e250ecb3eeac687c7da454e4da1546c36400..91fe0f9be16cf18e648b24cf953b3a119c01476c 100644 --- a/README.mingw +++ b/README.mingw @@ -48,11 +48,8 @@ rm /include/stdint.h /include/inttypes.h #Remove libgcc specific libraries, only needed for MSVC: rm /lib/libgcc.a /lib/libmingw32.a /lib/libmingwex.a -#Remove libintl from gtk, we don't need it and it conflicts with the one supplied by mingw. -rm /lib/libintl.dll.a -rm /lib/libintl.la -rm /lib/libintl.a -rm /include/libintl.h +#To get the translations working, remove from C:/MinGW/lib : +libintl.a libintl.la libintl.dll.a * Download and install Inno Setup Compiler (required only if you run 'make setup.exe'). Add it to your windows Path environment variable. diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 659a9f78e58daa47b028204f46e2e8a356ebc0f8..fdcaefdcf6c27a5b6a25c7d72311b634360bd3b9 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -74,8 +74,8 @@ endif AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \ $(ORTP_CFLAGS) \ - $(OSIP_CFLAGS) \ $(MEDIASTREAMER_CFLAGS) \ + $(OSIP_CFLAGS) \ $(EXOSIP_CFLAGS) \ -DENABLE_TRACE \ -DLOG_DOMAIN=\"LinphoneCore\" \ diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 7b79a78d6dde39bc343607cad74905829ae3aa06..a2dfffee3779c60e687caa9a9fb6a76f5ffd9fb3 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -374,7 +374,7 @@ static void call_accepted(SalOp *op){ }else{ /*send a bye*/ ms_error("Incompatible SDP offer received in 200Ok, need to abort the call"); - linphone_core_abort_call(lc,call,"No codec intersection"); + linphone_core_abort_call(lc,call,_("Incompatible, check codecs...")); } } @@ -523,7 +523,6 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de lc->vtable.display_status(lc,msg480); break; case SalReasonNotFound: - msg=_("Not found"); if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); break; @@ -563,10 +562,14 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de lc->ringstream=NULL; } linphone_call_stop_media_streams (call); - if (sr!=SalReasonDeclined) linphone_call_set_state(call,LinphoneCallError,msg); - else{ + if (sr == SalReasonDeclined) { call->reason=LinphoneReasonDeclined; linphone_call_set_state(call,LinphoneCallEnd,"Call declined."); + } else if (sr == SalReasonNotFound) { + call->reason=LinphoneReasonNotFound; + linphone_call_set_state(call,LinphoneCallError,"User not found."); + } else { + linphone_call_set_state(call,LinphoneCallError,msg); } } @@ -623,12 +626,11 @@ static void register_success(SalOp *op, bool_t registered){ LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op); char *msg; - cfg->registered=registered; linphone_proxy_config_set_error(cfg,LinphoneReasonNone); linphone_proxy_config_set_state(cfg, registered ? LinphoneRegistrationOk : LinphoneRegistrationCleared , registered ? "Registration sucessful" : "Unregistration done"); if (lc->vtable.display_status){ - if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op)); + if (registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op)); else msg=ms_strdup_printf(_("Unregistration on %s done."),sal_op_get_proxy(op)); lc->vtable.display_status(lc,msg); ms_free(msg); diff --git a/coreapi/conference.c b/coreapi/conference.c index aafed5d606c5351f192b041282979e6134422009..d4abc1a91a05972dbb262ea88cfefb160cc24486 100644 --- a/coreapi/conference.c +++ b/coreapi/conference.c @@ -298,5 +298,8 @@ int linphone_core_terminate_conference(LinphoneCore *lc) { } int linphone_core_get_conference_size(LinphoneCore *lc) { + if (lc->conf_ctx.conf == NULL) { + return 0; + } return ms_audio_conference_get_size(lc->conf_ctx.conf); } diff --git a/coreapi/help/doxygen.dox b/coreapi/help/doxygen.dox index 0ddb4e76f274cea31b3786d05cfe515a74961655..d1ec25b9ced38d5ebd34fb3e62b77626a9d13c96 100644 --- a/coreapi/help/doxygen.dox +++ b/coreapi/help/doxygen.dox @@ -316,6 +316,38 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach linphone_core_set_ringer_device(lc, "AQ: Audio Queue Device"); linphone_core_set_capture_device(lc, "AU: Audio Unit Receiver"); \endcode +<b> GSM call interaction </b> +<br> To ensure gentle interaction with GSM calls, it is recommended to register an AudioSession delegate. This allows the application to be notified when its audio session is interrupted/resumed (presumably by a GSM call). +\code + // declare a class handling the AVAudioSessionDelegate protocol + @interface MyClass : NSObject <AVAudioSessionDelegate> { [...] } + // implement 2 methods : here's an example implementation + -(void) beginInterruption { + LinphoneCall* c = linphone_core_get_current_call(theLinphoneCore); + ms_message("Sound interruption detected!"); + if (c) { + linphone_core_pause_call(theLinphoneCore, c); + } + } + + -(void) endInterruption { + ms_message("Sound interruption ended!"); + const MSList* c = linphone_core_get_calls(theLinphoneCore); + + if (c) { + ms_message("Auto resuming call"); + linphone_core_resume_call(theLinphoneCore, (LinphoneCall*) c->data); + } + } +\endcode +@see http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioSessionDelegate_ProtocolReference/Reference/Reference.html + +<br> Declare an instance of your class as AudioSession's delegate : +\code + [audioSession setDelegate:myClassInstance]; +\endcode +@see http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html + <b> Video </b> <br>Since 3.5 video support has been added to liblinphone for IOS. It requires the application to provide liblinphone with pointers to IOS's views hosting video display and video previous. <br> These 2 UIView objects must be passed to the core using functions #linphone_core_set_native_video_window_id() and #linphone_core_set_native_preview_window_id(). here under speudo code: diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 30f5997628c1ef3438b5fd52dd9a3d183d4b11f6..33c168522498166fd64680f07eb1235cac48ac3a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4164,7 +4164,7 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; if (linphone_proxy_config_register_enabled(cfg) ) { if (!isReachable) { - cfg->registered=0; + linphone_proxy_config_set_state(cfg, LinphoneRegistrationNone,"Registration impossible (network down)"); }else{ cfg->commit=TRUE; } @@ -4365,6 +4365,8 @@ const char *linphone_reason_to_string(LinphoneReason err){ return "Bad credentials"; case LinphoneReasonDeclined: return "Call declined"; + case LinphoneReasonNotFound: + return "User not found"; } return "unknown error"; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index b9cd9cae50e8026bc4bf06b24ed884b573696b44..14c850de836952363e74a5de24a180a2330f8d23 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -202,6 +202,7 @@ enum _LinphoneReason{ LinphoneReasonNoResponse, /**<No response received from remote*/ LinphoneReasonBadCredentials, /**<Authentication failed due to bad or missing credentials*/ LinphoneReasonDeclined, /**<The call has been declined*/ + LinphoneReasonNotFound, }; typedef enum _LinphoneReason LinphoneReason; @@ -1077,7 +1078,7 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para /** * True if tunnel support was compiled. */ -bool_t linphone_core_tunnel_available(); +bool_t linphone_core_tunnel_available(void); /** * Update tunnel using configuration. diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 26dc0e035c9cc0e64015112e0ba48da8250c839e..ca2c03d4056667c072fbf7c97f9135b0d9329dc5 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1574,6 +1574,10 @@ extern "C" void Java_org_linphone_core_LinphoneCallImpl_setAuthenticationTokenVe linphone_call_set_authentication_token_verified(call, verified); } +extern "C" jfloat Java_org_linphone_core_LinphoneCallImpl_getPlayVolume(JNIEnv* env, jobject thiz, jlong ptr) { + LinphoneCall *call = (LinphoneCall *) ptr; + return linphone_call_get_play_volume(call); +} extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_soundResourcesLocked(JNIEnv* env,jobject thiz,jlong ptr){ return linphone_core_sound_resources_locked((LinphoneCore *) ptr); diff --git a/coreapi/misc.c b/coreapi/misc.c index 7aeaf0f33adb5de6364040300653ddb22bf6b2e9..607ee6b3f5d931fe03d00900b92415bc4edf0cdf 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -461,6 +461,7 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ struct sockaddr_storage ss; socklen_t ss_len; ortp_socket_t sock1=-1, sock2=-1; + int loops=0; bool_t video_enabled=linphone_core_video_enabled(lc); bool_t got_audio,got_video; bool_t cone_audio=FALSE,cone_video=FALSE; @@ -479,16 +480,10 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ /*create the two audio and video RTP sockets, and send STUN message to our stun server */ sock1=create_socket(call->audio_port); - if (sock1<0) return; + if (sock1==-1) return; if (video_enabled){ sock2=create_socket(call->video_port); - if (sock2<0) return ; - } - sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,11,TRUE); - sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,1,FALSE); - if (sock2>=0){ - sendStunRequest(sock2,(struct sockaddr*)&ss,ss_len,22,TRUE); - sendStunRequest(sock2,(struct sockaddr*)&ss,ss_len,2,FALSE); + if (sock2==-1) return ; } got_audio=FALSE; got_video=FALSE; @@ -496,6 +491,15 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ do{ double elapsed; int id; + if (loops%20==0){ + ms_message("Sending stun requests..."); + sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,11,TRUE); + sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,1,FALSE); + if (sock2!=-1){ + sendStunRequest(sock2,(struct sockaddr*)&ss,ss_len,22,TRUE); + sendStunRequest(sock2,(struct sockaddr*)&ss,ss_len,2,FALSE); + } + } #ifdef WIN32 Sleep(10); #else @@ -522,29 +526,25 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ } gettimeofday(&cur,NULL); elapsed=((cur.tv_sec-init.tv_sec)*1000.0) + ((cur.tv_usec-init.tv_usec)/1000.0); - if (elapsed>2000) break; - }while(!(got_audio && (got_video||sock2<0) ) ); + if (elapsed>2000) { + ms_message("Stun responses timeout, going ahead."); + break; + } + loops++; + }while(!(got_audio && (got_video||sock2==-1) ) ); if (!got_audio){ ms_error("No stun server response for audio port."); }else{ if (!cone_audio) { - ms_warning("NAT is symmetric for audio port"); - /* - ac->addr[0]='\0'; - ac->port=0; - */ + ms_message("NAT is symmetric for audio port"); } } - if (sock2>=0){ + if (sock2!=-1){ if (!got_video){ ms_error("No stun server response for video port."); }else{ if (!cone_video) { - ms_warning("NAT is symmetric for video port."); - /* - vc->addr[0]='\0'; - vc->port=0; - */ + ms_message("NAT is symmetric for video port."); } } } @@ -553,7 +553,7 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ strcpy(call->localdesc->addr,ac->addr); } close_socket(sock1); - if (sock2>=0) close_socket(sock2); + if (sock2!=-1) close_socket(sock2); } } diff --git a/coreapi/private.h b/coreapi/private.h index a21fc8b20aec9bb17379c52530ac201f087230dd..77f62c33407ce7ccc3038df588fc4a75aade32e7 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -255,7 +255,6 @@ struct _LinphoneProxyConfig SalOp *publish_op; bool_t commit; bool_t reg_sendregister; - bool_t registered; bool_t publish; bool_t dial_escape_plus; void* user_data; diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 011be670672f228ea7c4efb739946b20c694c808..959c321b6862d194c5275683a693d025d69f31ab 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -84,7 +84,7 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ * Returns a boolean indicating that the user is sucessfully registered on the proxy. **/ bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj){ - return obj->registered; + return obj->state == LinphoneRegistrationOk; } /** @@ -232,9 +232,8 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){ void linphone_proxy_config_edit(LinphoneProxyConfig *obj){ if (obj->reg_sendregister){ /* unregister */ - if (obj->registered) { + if (obj->state != LinphoneRegistrationNone && obj->state != LinphoneRegistrationCleared) { sal_unregister(obj->op); - obj->registered=FALSE; } } } @@ -301,7 +300,7 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ **/ void linphone_proxy_config_refresh_register(LinphoneProxyConfig *obj){ if (obj->reg_sendregister && obj->op){ - obj->registered=FALSE; + linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress, "Refresh registration"); sal_register_refresh(obj->op,obj->expires); } } diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 533fa860abd0cc53111ed1f892948ffe12fcbfcf..7a2f3e051b37fc795429aa136577a264f4c9677f 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -374,17 +374,14 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i memset(&tlsCtx, 0, sizeof(tlsCtx)); snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa); eXosip_set_tls_ctx(&tlsCtx); - } + } +#ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE eXosip_tls_verify_certificate(ctx->verify_server_certs); +#endif break; default: ms_warning("unexpected proto, using datagram"); } -#if 0 - /* it does not work, exosip does not implement this option correctly*/ - err=0; - eXosip_set_option(EXOSIP_OPT_DNS_CAPABILITIES,&err); /*0=no NAPTR */ -#endif /*see if it looks like an IPv6 address*/ int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports); @@ -399,10 +396,6 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i return -1; } err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure); -#ifdef HAVE_EXOSIP_GET_SOCKET - ms_message("Exosip has socket number %i",eXosip_get_socket(proto)); -#endif - ctx->running=TRUE; return err; } @@ -451,7 +444,9 @@ void sal_set_root_ca(Sal* ctx, const char* rootCa) { void sal_verify_server_certificates(Sal *ctx, bool_t verify){ ctx->verify_server_certs=verify; +#ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE eXosip_tls_verify_certificate(verify); +#endif } static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){ diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 9dacac717882571f03567d4e85c1f051ca615469..d5a056feff907b5bf5249e598d3084cf5e8747c7 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -239,6 +239,119 @@ static void linphone_gtk_init_bookmark_icon(void){ g_signal_connect(G_OBJECT(GTK_EDITABLE(entry)),"changed",(GCallback)check_contact,linphone_gtk_get_core()); } +static gboolean friend_search_func(GtkTreeModel *model, gint column, + const gchar *key, + GtkTreeIter *iter, + gpointer search_data){ + char *name=NULL; + gboolean ret=TRUE; + gtk_tree_model_get(model,iter,FRIEND_NAME,&name,-1); + if (name!=NULL){ + ret=strstr(name,key)==NULL; + g_free(name); + } + return ret; +} + +static gint friend_sort(GtkTreeModel *model, GtkTreeIter *a,GtkTreeIter *b,gpointer user_data){ + char *n1=NULL,*n2=NULL; + int ret; + gtk_tree_model_get(model,a,FRIEND_NAME,&n1,-1); + gtk_tree_model_get(model,b,FRIEND_NAME,&n2,-1); + if (n1 && n2) { + ret=strcmp(n1,n2); + g_free(n1); + g_free(n2); + }else if (n1){ + g_free(n1); + ret=-1; + }else if (n2){ + g_free(n2); + ret=1; + }else ret=0; + return ret; +} + +static void on_name_column_clicked(GtkTreeModel *model){ + GtkSortType st; + gint column; + + gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(model),&column,&st); + if (column==FRIEND_NAME){ + if (st==GTK_SORT_ASCENDING) st=GTK_SORT_DESCENDING; + else st=GTK_SORT_ASCENDING; + }else st=GTK_SORT_ASCENDING; + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),FRIEND_NAME,st); +} + + +static int get_friend_weight(const LinphoneFriend *lf){ + int w=0; + switch(linphone_friend_get_status(lf)){ + case LinphoneStatusOnline: + w+=1000; + break; + case LinphoneStatusOffline: + if (linphone_friend_get_send_subscribe(lf)) + w+=100; + break; + default: + w+=500; + break; + } + return w; +} + +static int friend_compare_func(const LinphoneFriend *lf1, const LinphoneFriend *lf2){ + int w1,w2; + w1=get_friend_weight(lf1); + w2=get_friend_weight(lf2); + if (w1==w2){ + const char *u1,*u2; + const LinphoneAddress *addr1,*addr2; + addr1=linphone_friend_get_address(lf1); + addr2=linphone_friend_get_address(lf2); + u1=linphone_address_get_username(addr1); + u2=linphone_address_get_username(addr2); + if (u1 && u2) return strcasecmp(u1,u2); + if (u1) return 1; + else return -1; + } + return w2-w1; +} + +static gint friend_sort_with_presence(GtkTreeModel *model, GtkTreeIter *a,GtkTreeIter *b,gpointer user_data){ + LinphoneFriend *lf1=NULL,*lf2=NULL; + gtk_tree_model_get(model,a,FRIEND_ID,&lf1,-1); + gtk_tree_model_get(model,b,FRIEND_ID,&lf2,-1); + return friend_compare_func(lf1,lf2); +} + + +static MSList *sort_friend_list(const MSList *friends){ + MSList *ret=NULL; + const MSList *elem; + LinphoneFriend *lf; + + for(elem=friends;elem!=NULL;elem=elem->next){ + lf=(LinphoneFriend*)elem->data; + ret=ms_list_insert_sorted(ret,lf,(MSCompareFunc)friend_compare_func); + } + return ret; +} + +static void on_presence_column_clicked(GtkTreeModel *model){ + GtkSortType st; + gint column; + + gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(model),&column,&st); + if (column==FRIEND_ID){ + if (st==GTK_SORT_ASCENDING) st=GTK_SORT_DESCENDING; + else st=GTK_SORT_ASCENDING; + }else st=GTK_SORT_ASCENDING; + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),FRIEND_ID,st); +} + static void linphone_gtk_friend_list_init(GtkWidget *friendlist) { GtkListStore *store; @@ -254,12 +367,21 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist) gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store)); g_object_unref(G_OBJECT(store)); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(friendlist),friend_search_func,NULL,NULL); + gtk_tree_view_set_search_column(GTK_TREE_VIEW(friendlist),FRIEND_NAME); + + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_NAME,friend_sort,NULL,NULL); + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_ID,friend_sort_with_presence,NULL,NULL); + renderer = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "pixbuf", FRIEND_ICON, NULL); g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_name_column_clicked,GTK_TREE_MODEL(store)); + gtk_tree_view_column_set_clickable(column,TRUE); + renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start(column,renderer,FALSE); gtk_tree_view_column_add_attribute (column,renderer, @@ -273,6 +395,8 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist) "text", FRIEND_PRESENCE_STATUS, NULL); g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_presence_column_clicked,GTK_TREE_MODEL(store)); + gtk_tree_view_column_set_clickable(column,TRUE); gtk_tree_view_column_set_visible(column,linphone_gtk_get_ui_config_int("friendlist_status",1)); renderer = gtk_cell_renderer_pixbuf_new(); @@ -344,52 +468,6 @@ void linphone_gtk_directory_search_button_clicked(GtkWidget *button){ linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"directory_search_entry")); } -static int get_friend_weight(const LinphoneFriend *lf){ - int w=0; - switch(linphone_friend_get_status(lf)){ - case LinphoneStatusOnline: - w+=1000; - break; - case LinphoneStatusOffline: - if (linphone_friend_get_send_subscribe(lf)) - w+=100; - break; - default: - w+=500; - break; - } - return w; -} - -static int friend_compare_func(const LinphoneFriend *lf1, const LinphoneFriend *lf2){ - int w1,w2; - w1=get_friend_weight(lf1); - w2=get_friend_weight(lf2); - if (w1==w2){ - const char *u1,*u2; - const LinphoneAddress *addr1,*addr2; - addr1=linphone_friend_get_address(lf1); - addr2=linphone_friend_get_address(lf2); - u1=linphone_address_get_username(addr1); - u2=linphone_address_get_username(addr2); - if (u1 && u2) return strcasecmp(u1,u2); - if (u1) return 1; - else return -1; - } - return w2-w1; -} - -static MSList *sort_friend_list(const MSList *friends){ - MSList *ret=NULL; - const MSList *elem; - LinphoneFriend *lf; - - for(elem=friends;elem!=NULL;elem=elem->next){ - lf=(LinphoneFriend*)elem->data; - ret=ms_list_insert_sorted(ret,lf,(MSCompareFunc)friend_compare_func); - } - return ret; -} void linphone_gtk_show_friends(void){ GtkWidget *mw=linphone_gtk_get_main_window(); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 75060da9ab770bdf6695016f7320c50db7646301..5674d5544b12f0ca247aaa170ad993de2bca1f2b 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -94,6 +94,7 @@ static void linphone_gtk_in_call_set_animation_image(GtkWidget *callview, const } static void linphone_gtk_in_call_set_animation_spinner(GtkWidget *callview){ +#if GTK_CHECK_VERSION(2,20,0) GtkWidget *container=linphone_gtk_get_widget(callview,"in_call_animation"); GList *elem=gtk_container_get_children(GTK_CONTAINER(container)); GtkWidget *spinner=gtk_spinner_new(); @@ -103,6 +104,7 @@ static void linphone_gtk_in_call_set_animation_spinner(GtkWidget *callview){ gtk_container_add(GTK_CONTAINER(container),spinner); gtk_widget_set_size_request(spinner, 20,20); gtk_spinner_start(GTK_SPINNER(spinner)); +#endif } diff --git a/gtk/main.c b/gtk/main.c index 73e99cc964cf9fbc72239a0d559fdefb23ffa5a9..88f2807fd5848c9082f48dd4a94023a6e783ae4b 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1208,7 +1208,9 @@ static void linphone_gtk_init_status_icon(){ const char *title; title=linphone_gtk_get_ui_config("title",_("Linphone - a video internet phone")); icon=gtk_status_icon_new_from_pixbuf(pbuf); +#if GTK_CHECK_VERSION(2,20,0) gtk_status_icon_set_name(icon,title); +#endif g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)handle_icon_click,NULL); g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL); gtk_status_icon_set_tooltip(icon,title); @@ -1583,14 +1585,19 @@ static void linphone_gtk_check_soundcards(){ } static void linphone_gtk_quit(void){ - linphone_gtk_uninit_instance(); - linphone_gtk_destroy_log_window(); - linphone_core_destroy(the_core); - linphone_gtk_log_uninit(); + static gboolean quit_done=FALSE; + if (!quit_done){ + quit_done=TRUE; + g_source_remove_by_user_data(linphone_gtk_get_core()); + linphone_gtk_uninit_instance(); + linphone_gtk_destroy_log_window(); + linphone_core_destroy(the_core); + linphone_gtk_log_uninit(); #ifdef HAVE_NOTIFY - notify_uninit(); + notify_uninit(); #endif - gdk_threads_leave(); + gdk_threads_leave(); + } } #ifdef HAVE_GTK_OSX diff --git a/gtk/main.ui b/gtk/main.ui index 2cfe555e7db37a4e042d66bdb74033336859395c..fde3a794a62a9ae95fa6c2a22071f08ecc18bda6 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> - <requires lib="gtk+" version="2.22"/> - <!-- interface-naming-policy toplevel-contextual --> + <requires lib="gtk+" version="2.18"/> <object class="GtkWindow" id="dummy_conf_window"> <property name="can_focus">False</property> <child> @@ -652,8 +651,6 @@ <property name="invisible_char">â—</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> - <property name="primary_icon_sensitive">True</property> - <property name="secondary_icon_sensitive">True</property> <signal name="activate" handler="linphone_gtk_uri_bar_activate" swapped="no"/> </object> <packing> @@ -745,8 +742,6 @@ <property name="invisible_char_set">True</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> - <property name="primary_icon_sensitive">True</property> - <property name="secondary_icon_sensitive">True</property> <signal name="changed" handler="linphone_gtk_show_friends" swapped="no"/> </object> <packing> @@ -808,10 +803,15 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="reorderable">True</property> + <property name="search_column">0</property> <signal name="button-press-event" handler="linphone_gtk_contact_list_button_pressed" swapped="no"/> <signal name="cursor-changed" handler="linphone_gtk_contact_clicked" swapped="no"/> <signal name="row-activated" handler="linphone_gtk_contact_activated" swapped="no"/> <signal name="popup-menu" handler="linphone_gtk_popup_contact_menu" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> </object> </child> </object> @@ -837,8 +837,6 @@ <property name="invisible_char_set">True</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> - <property name="primary_icon_sensitive">True</property> - <property name="secondary_icon_sensitive">True</property> <signal name="activate" handler="linphone_gtk_directory_search_activate" swapped="no"/> <signal name="icon-press" handler="linphone_gtk_directory_search_activate" swapped="no"/> <signal name="focus-in-event" handler="linphone_gtk_directory_search_focus_in" swapped="no"/> @@ -1037,6 +1035,9 @@ <property name="headers_visible">False</property> <signal name="cursor-changed" handler="linphone_gtk_history_row_selected" swapped="no"/> <signal name="row-activated" handler="linphone_gtk_history_row_activated" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection2"/> + </child> </object> </child> </object> @@ -1540,8 +1541,6 @@ <property name="invisible_char">â—</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> - <property name="primary_icon_sensitive">True</property> - <property name="secondary_icon_sensitive">True</property> </object> <packing> <property name="left_attach">1</property> @@ -1556,8 +1555,6 @@ <property name="invisible_char">â—</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> - <property name="primary_icon_sensitive">True</property> - <property name="secondary_icon_sensitive">True</property> </object> <packing> <property name="left_attach">1</property> diff --git a/gtk/parameters.ui b/gtk/parameters.ui index 2403b3316b9e03e0ea59cdae57339c85489dda76..153b5bddecec410d7fb6aa9cc499c408c26527b4 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.22"/> + <requires lib="gtk+" version="2.18"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkAdjustment" id="adjustment1"> <property name="value">500</property> diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 30890c7651c749aa56b01464dd451600e795c87b..c45f34e31facf5906ee0947fa1531fe177ee623d 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -989,7 +989,7 @@ void linphone_gtk_show_parameters(void){ g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_combo")),"changed",(GCallback)linphone_gtk_proto_changed,NULL); - if (linphone_core_tunnel_available(lc)){ + if (linphone_core_tunnel_available()){ gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_edit_button")), TRUE); gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_label")), TRUE); } diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index 3d1c9696f94a7f1f715da0092741ad1f2c1117b5..d0f97130d57b28691bedde3c2c78f2cce5abeeb2 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -240,4 +240,6 @@ public interface LinphoneCall { void setAuthenticationTokenVerified(boolean verified); boolean isInConference(); + + float getPlayVolume(); } diff --git a/linphone.spec.in b/linphone.spec.in index e4a7c307509dc823f358a80811ae8506671effaa..171cb5e39313f22fad27d107621a49af9be32f0d 100644 --- a/linphone.spec.in +++ b/linphone.spec.in @@ -23,10 +23,9 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: i686 %endif -BuildRequires: gnome-panel-devel libgnomeui-devel glib2-devel alsa-lib-devel -BuildRequires: libosip2-devel speex-devel gettext desktop-file-utils -BuildRequires: readline-devel ncurses-devel -BuildRequires: intltool gettext-devel +BuildRequires: gtk2-devel +BuildRequires: libeXosip2-devel speex-devel gettext +BuildRequires: intltool gettext-devel %if %{video} BuildRequires: ffmpeg-devel SDL-devel %endif @@ -40,58 +39,12 @@ Summary: Development libraries for linphone Group: Development/Libraries Requires: %{name} = %{version}-%{release} Requires: ortp-devel = @ORTP_VERSION@ +Requires: mediastreamer2-devel = @MS2_VERSION@ Requires: glib2-devel %description devel Libraries and headers required to develop software with linphone. -%package -n ortp -Summary: A C library implementing the RTP protocol (rfc1889) -Group: System Environment/Libraries -Version: @ORTP_VERSION@ - -%description -n ortp -oRTP is a LGPL licensed C library implementing the RTP protocol (rfc1889). It -is available for most *nix clones (primilarly Linux and HP-UX), and Win32. - -%package -n ortp-devel -Summary: Development libraries for ortp -Group: Development/Libraries -Version: @ORTP_VERSION@ -Requires: ortp = @ORTP_VERSION@ - -%description -n ortp-devel -oRTP is a LGPL licensed C library implementing the RTP protocol (rfc1889). It -is available for most *nix clones (primilarly Linux and HP-UX), and Win32. - -This package contains header files and development libraries needed to -develop programs using the oRTP library. - -%package -n mediastreamer2 -Summary: Audio/Video real-time streaming -Group: Development/Libraries -Version: @MS2_VERSION@ - -%description -n mediastreamer2 -Mediastreamer2 is a GPL licensed library to make audio and video -real-time streaming and processing. Written in pure C, it is based -upon the oRTP library. - -%package -n mediastreamer2-devel -Summary: Headers, libraries and docs for the mediastreamer2 library -Group: Development/Libraries -Version: @MS2_VERSION@ -Requires: mediastreamer2 = @MS2_VERSION@ -Requires: ortp-devel = @ORTP_VERSION@ - -%description -n mediastreamer2-devel -Mediastreamer2 is a GPL licensed library to make audio and video -real-time streaming and processing. Written in pure C, it is based -upon the ortp library. - -This package contains header files and development libraries needed to -develop programs using the mediastreamer2 library. - %prep %setup -q #%patch -p 1 -b .pkgconfig @@ -100,25 +53,19 @@ develop programs using the mediastreamer2 library. %build %configure \ - --with-osip=/usr \ - --with-speex=/usr \ - --with-readline=/usr \ -%if %{video} - --enable-video \ - --with-ffmpeg=/usr \ - --with-sdl=/usr \ +%if !%{video} + --disable-video \ %endif - --enable-ipv6 + --docdir=%{_docdir} --enable-ipv6 --enable-static --enable-external-mediastreamer --enable-external-ortp %__make %{?_smp_mflags} %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT -install -p -m 0644 pixmaps/linphone2.png $RPM_BUILD_ROOT%{_datadir}/pixmaps +install -p -m 0644 pixmaps/linphone.png $RPM_BUILD_ROOT%{_datadir}/pixmaps %find_lang %{name} -rm $RPM_BUILD_ROOT%{_datadir}/gnome/apps/Internet/linphone.desktop -desktop-file-install --vendor=fedora \ +desktop-file-install \ --delete-original \ --dir $RPM_BUILD_ROOT%{_datadir}/applications \ --add-category X-Fedora \ @@ -133,28 +80,17 @@ rm -rf $RPM_BUILD_ROOT %postun -p /sbin/ldconfig -%post -n ortp -p /sbin/ldconfig - -%postun -n ortp -p /sbin/ldconfig - -%post -n mediastreamer2 -p /sbin/ldconfig - -%postun -n mediastreamer2 -p /sbin/ldconfig %files -f %{name}.lang %defattr(-,root,root) %doc AUTHORS ChangeLog COPYING NEWS README TODO %{_bindir}/* -%{_libdir}/bonobo/servers/*.server %{_libdir}/liblinphone.so.* -%exclude %{_libdir}/libortp* -%{_libexecdir}/* %{_mandir}/* -%{_datadir}/applications/*%{name}.desktop -%{_datadir}/gnome/help/linphone -%{_datadir}/gnome-2.0/ui/*.xml +%{_datadir}/applications/%{name}.desktop %{_datadir}/pixmaps/linphone -%{_datadir}/pixmaps/linphone2.png +%{_datadir}/linphone +%{_datadir}/pixmaps/linphone.png %{_datadir}/sounds/linphone %files devel @@ -164,33 +100,7 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/liblinphone.la %{_libdir}/liblinphone.so %{_libdir}/pkgconfig/linphone.pc - -%files -n ortp -%defattr(-,root,root) -%doc oRTP/AUTHORS oRTP/ChangeLog oRTP/COPYING oRTP/NEWS oRTP/README oRTP/TODO -%{_libdir}/libortp.so.* -%exclude %{_libdir}/liblinphone* - -%files -n ortp-devel -%defattr(-,root,root) -%{_includedir}/ortp -%{_libdir}/pkgconfig/ortp.pc -%{_libdir}/libortp.a -%{_libdir}/libortp.la -%{_libdir}/libortp.so -%{_datadir}/gtk-doc/html/ortp - -%files -n mediastreamer2 -%defattr(-,root,root) -%doc mediastreamer2/AUTHORS mediastreamer2/ChangeLog mediastreamer2/COPYING -%doc mediastreamer2/NEWS mediastreamer2/README -%{_libdir}/libmediastreamer.so.* - -%files -n mediastreamer2-devel -%{_includedir}/mediastreamer2 -%{_libdir}/pkgconfig/mediastreamer.pc -%{_libdir}/libmediastreamer.so -%{_libdir}/libmediastreamer.*a +%{_docdir} %changelog * Wed Sep 28 2005 Francois-Xavier 'FiX' KOWALSKI <francois-xavier.kowalski@hp.com> - 1.2.0pre3 diff --git a/m4/exosip.m4 b/m4/exosip.m4 index 921e3353b38bbf1b5d288b8f04a76a66d3216b82..9be357f71a27e5b5e625803d5959b75e4120a212 100644 --- a/m4/exosip.m4 +++ b/m4/exosip.m4 @@ -42,6 +42,10 @@ AC_CHECK_LIB([eXosip2],[eXosip_get_version], [AC_DEFINE([HAVE_EXOSIP_GET_VERSION],[1],[Defined when eXosip_get_version is available])], [], [-losipparser2 -losip2 ]) +AC_CHECK_LIB([eXosip2],[eXosip_tls_verify_certificate], + [AC_DEFINE([HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE],[1],[Defined when eXosip_tls_verify_certificate is available])], + [AC_MSG_WARN([Could not find eXosip_tls_verify_certificate in eXosip2 !])], + [-losipparser2 -losip2 ]) AC_CHECK_LIB([eXosip2],[eXosip_get_socket], [AC_DEFINE([HAVE_EXOSIP_GET_SOCKET],[1],[Defined when eXosip_get_socket is available])], [AC_MSG_WARN([Could not find eXosip_get_socket in eXosip2 !])], diff --git a/mediastreamer2 b/mediastreamer2 index c1f6d3e6d4f36928fffd2e7380759544bcd23d84..4aaab3296337eb313d9b554dff1860cd23b3dbc9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit c1f6d3e6d4f36928fffd2e7380759544bcd23d84 +Subproject commit 4aaab3296337eb313d9b554dff1860cd23b3dbc9 diff --git a/oRTP b/oRTP index 73dff1e14c73e76e5d46f617a320389e29606ffd..a936749fac4d3e2f788a0c03b3c4ea2021b3ae13 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 73dff1e14c73e76e5d46f617a320389e29606ffd +Subproject commit a936749fac4d3e2f788a0c03b3c4ea2021b3ae13