Commit c58e884e authored by smorlat's avatar smorlat

use buddy lookup to display buddy images in contact list (not finished).

buddy lookup important refactoring.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@727 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 3536b484
......@@ -2,7 +2,7 @@
* friend.c
*
* Sat May 15 15:25:16 2004
* Copyright 2004 Simon Morlat
* Copyright 2004-2009 Simon Morlat
* Email
****************************************************************************/
......@@ -561,6 +561,7 @@ void linphone_friend_destroy(LinphoneFriend *lf){
linphone_friend_notify(lf,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED);
linphone_friend_unsubscribe(lf);
if (lf->url!=NULL) osip_from_free(lf->url);
if (lf->info!=NULL) buddy_info_free(lf->info);
ms_free(lf);
}
......@@ -606,6 +607,9 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
return lf->status;
}
BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf){
return lf->info;
}
void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
if (fr->url==NULL) {
......@@ -638,6 +642,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
__linphone_friend_do_subscribe(fr);
}
ms_message("linphone_friend_apply() done.");
lc->bl_refresh=TRUE;
}
void linphone_friend_edit(LinphoneFriend *fr){
......@@ -667,6 +672,31 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
}
}
static bool_t username_match(const char *u1, const char *u2){
if (u1==NULL && u2==NULL) return TRUE;
if (u1 && u2 && strcasecmp(u1,u2)==0) return TRUE;
return FALSE;
}
LinphoneFriend *linphone_core_get_friend_by_uri(const LinphoneCore *lc, const char *uri){
osip_from_t *from;
osip_from_init(&from);
const MSList *elem;
if (osip_from_parse(from,uri)!=0){
osip_from_free(from);
return NULL;
}
for(elem=lc->friends;elem!=NULL;elem=ms_list_next(elem)){
LinphoneFriend *lf=(LinphoneFriend*)elem->data;
const char *it_username=lf->url->url->username;
const char *it_host=lf->url->url->host;
if (strcasecmp(from->url->host,it_host)==0 && username_match(from->url->username,it_username)){
return lf;
}
}
return NULL;
}
#define key_compare(key, word) strncasecmp((key),(word),strlen(key))
LinphoneSubscribePolicy __policy_str_to_enum(const char* pol){
......
......@@ -1036,6 +1036,77 @@ static void proxy_update(LinphoneCore *lc, time_t curtime){
if (doit) ms_list_for_each(lc->sip_conf.proxies,(void (*)(void*))&linphone_proxy_config_update);
}
static void assign_buddy_info(LinphoneCore *lc, BuddyInfo *info){
LinphoneFriend *lf=linphone_core_get_friend_by_uri(lc,info->sip_uri);
if (lf!=NULL){
lf->info=info;
ms_message("%s has a BuddyInfo assigned.",info->sip_uri);
}else{
ms_warning("Could not any friend with uri %s",info->sip_uri);
}
}
static void analyze_buddy_lookup_results(LinphoneCore *lc, LinphoneProxyConfig *cfg){
MSList *elem;
SipSetupContext *ctx=linphone_proxy_config_get_sip_setup_context(cfg);
for (elem=lc->bl_reqs;elem!=NULL;elem=ms_list_next(elem)){
BuddyLookupRequest *req=(BuddyLookupRequest *)elem->data;
if (req->status==BuddyLookupDone || req->status==BuddyLookupFailure){
if (req->results!=NULL){
BuddyInfo *i=(BuddyInfo*)req->results->data;
ms_list_free(req->results);
req->results=NULL;
assign_buddy_info(lc,i);
}
sip_setup_context_buddy_lookup_free(ctx,req);
elem->data=NULL;
}
}
/*purge completed requests */
while((elem=ms_list_find(lc->bl_reqs,NULL))!=NULL){
lc->bl_reqs=ms_list_remove_link(lc->bl_reqs,elem);
}
}
static void linphone_core_grab_buddy_infos(LinphoneCore *lc, LinphoneProxyConfig *cfg){
const MSList *elem;
SipSetupContext *ctx=linphone_proxy_config_get_sip_setup_context(cfg);
for(elem=linphone_core_get_friend_list(lc);elem!=NULL;elem=elem->next){
LinphoneFriend *lf=(LinphoneFriend*)elem->data;
if (lf->info==NULL){
char *url=linphone_friend_get_url(lf);
if (linphone_core_lookup_known_proxy(lc,url)==cfg){
char *name=linphone_friend_get_name(lf);
if (name!=NULL && strlen(name)>0){
BuddyLookupRequest *req;
req=sip_setup_context_create_buddy_lookup_request(ctx);
buddy_lookup_request_set_key(req,name);
buddy_lookup_request_set_max_results(req,1);
sip_setup_context_buddy_lookup_submit(ctx,req);
lc->bl_reqs=ms_list_append(lc->bl_reqs,req);
}
ms_free(name);
}
ms_free(url);
}
}
}
static void linphone_core_do_plugin_tasks(LinphoneCore *lc){
LinphoneProxyConfig *cfg=NULL;
linphone_core_get_default_proxy(lc,&cfg);
if (cfg){
if (lc->bl_refresh){
SipSetupContext *ctx=linphone_proxy_config_get_sip_setup_context(cfg);
if (ctx && (sip_setup_context_get_capabilities(ctx) & SIP_SETUP_CAP_BUDDY_LOOKUP)){
linphone_core_grab_buddy_infos(lc,cfg);
lc->bl_refresh=FALSE;
}
}
if (lc->bl_reqs) analyze_buddy_lookup_results(lc,cfg);
}
}
void linphone_core_iterate(LinphoneCore *lc)
{
eXosip_event_t *ev;
......@@ -1109,6 +1180,9 @@ void linphone_core_iterate(LinphoneCore *lc)
}
if (disconnected)
linphone_core_disconnected(lc);
linphone_core_do_plugin_tasks(lc);
if (one_second_elapsed && lp_config_needs_commit(lc->config)){
lp_config_sync(lc->config);
}
......@@ -1197,7 +1271,10 @@ bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, char **rea
osip_from_free(uri);
return FALSE;
}
sipaddr=ortp_strdup_printf("sip:%s@%s",url,uri->url->host);
if (uri->url->port!=NULL && uri->url->port[0]!='\0')
sipaddr=ortp_strdup_printf("sip:%s@%s:%s",url,uri->url->host,uri->url->port);
else
sipaddr=ortp_strdup_printf("sip:%s@%s",url,uri->url->host);
if (real_parsed_url!=NULL) *real_parsed_url=osip_to_create(sipaddr);
if (real_url!=NULL) *real_url=sipaddr;
else ms_free(sipaddr);
......
......@@ -212,6 +212,7 @@ typedef struct _LinphoneFriend{
LinphoneOnlineStatus status;
struct _LinphoneProxyConfig *proxy;
struct _LinphoneCore *lc;
BuddyInfo *info;
bool_t subscribe;
bool_t inc_subscribe_pending;
}LinphoneFriend;
......@@ -233,6 +234,7 @@ char *linphone_friend_get_url(LinphoneFriend *lf); /* name <sip address> */
bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf);
LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf);
LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf);
BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf);
#define linphone_friend_in_list(lf) ((lf)->lc!=NULL)
#define linphone_friend_url(lf) ((lf)->url)
......@@ -477,6 +479,7 @@ typedef struct _LinphoneCore
struct _VideoStream *videostream;
struct _VideoStream *previewstream;
struct _RtpProfile *local_profile;
MSList *bl_reqs;
MSList *subscribers; /* unknown subscribers */
int minutes_away;
LinphoneOnlineStatus presence_mode;
......@@ -501,6 +504,7 @@ typedef struct _LinphoneCore
bool_t use_files;
bool_t apply_nat_settings;
bool_t ready;
bool_t bl_refresh;
#ifdef VINCENT_MAURY_RSVP
/* QoS parameters*/
int rsvp_enable;
......@@ -695,6 +699,7 @@ void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf);
const MSList * linphone_core_get_friend_list(LinphoneCore *lc);
/* notify all friends that have subscribed */
void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os);
LinphoneFriend *linphone_core_get_friend_by_uri(const LinphoneCore *lc, const char *uri);
/* returns a list of LinphoneCallLog */
MSList * linphone_core_get_call_logs(LinphoneCore *lc);
......
......@@ -9,18 +9,15 @@
static bool_t buddy_lookup_init(void){
return TRUE;
}
};
typedef struct _BuddyLookupState{
SoupSession *session;
BuddyLookupStatus status;
typedef struct _BLReq{
BuddyLookupRequest base;
SoupMessage *msg;
SoupSession *session;
ortp_thread_t th;
MSList *results;
bool_t processing;
}BuddyLookupState;
}BLReq;
#define get_buddy_lookup_state(ctx) ((BuddyLookupState*)((ctx)->data))
void set_proxy(SoupSession *session, const char *proxy){
SoupURI *uri=soup_uri_new(proxy);
......@@ -29,21 +26,12 @@ void set_proxy(SoupSession *session, const char *proxy){
}
static void buddy_lookup_instance_init(SipSetupContext *ctx){
BuddyLookupState *s=ms_new0(BuddyLookupState,1);
const char *proxy=NULL;
s->session=soup_session_sync_new();
proxy=getenv("http_proxy");
if (proxy && strlen(proxy)>0) set_proxy(s->session,proxy);
ctx->data=s;
}
static void buddy_lookup_instance_uninit(SipSetupContext *ctx){
BuddyLookupState *s=get_buddy_lookup_state(ctx);
g_object_unref(G_OBJECT(s->session));
ms_free(s);
}
static SoupMessage * build_xmlrpc_request(const char *identity, const char *password, const char *key, const char *domain, const char *url){
static SoupMessage * build_xmlrpc_request(const char *identity, const char *password, const char *key, const char *domain, const char *url, int max_results){
SoupMessage * msg;
msg=soup_xmlrpc_request_new(url,
......@@ -51,7 +39,7 @@ static SoupMessage * build_xmlrpc_request(const char *identity, const char *pass
G_TYPE_STRING, identity,
G_TYPE_STRING, password ? password : "",
G_TYPE_STRING, key,
G_TYPE_INT , 100,
G_TYPE_INT , max_results,
G_TYPE_INT , 0,
G_TYPE_STRING, domain,
G_TYPE_INVALID);
......@@ -65,10 +53,9 @@ static SoupMessage * build_xmlrpc_request(const char *identity, const char *pass
return msg;
}
static void got_headers(SipSetupContext *ctx, SoupMessage*msg){
BuddyLookupState *s=get_buddy_lookup_state(ctx);
static void got_headers(BLReq *blreq, SoupMessage*msg){
ms_message("Got headers !");
s->status=BuddyLookupConnected;
blreq->base.status=BuddyLookupConnected;
}
static void fill_item(GHashTable *ht , const char *name, char *dest, size_t dest_size){
......@@ -81,7 +68,7 @@ static void fill_item(GHashTable *ht , const char *name, char *dest, size_t dest
}else ms_warning("no field named '%s'", name);
}
static void fill_buddy_info(BuddyLookupState *s, BuddyInfo *bi, GHashTable *ht){
static void fill_buddy_info(BLReq *blreq, BuddyInfo *bi, GHashTable *ht){
char tmp[256];
fill_item(ht,"first_name",bi->firstname,sizeof(bi->firstname));
fill_item(ht,"last_name",bi->lastname,sizeof(bi->lastname));
......@@ -105,7 +92,7 @@ static void fill_buddy_info(BuddyLookupState *s, BuddyInfo *bi, GHashTable *ht){
guint status;
ms_message("This buddy has an image, let's download it: %s",tmp);
msg=soup_message_new("GET",tmp);
if ((status=soup_session_send_message(s->session,msg))==200){
if ((status=soup_session_send_message(blreq->session,msg))==200){
SoupMessageBody *body=msg->response_body;
ms_message("Received %i bytes",body->length);
strncpy(bi->image_type,"png",sizeof(bi->image_type));
......@@ -119,7 +106,7 @@ static void fill_buddy_info(BuddyLookupState *s, BuddyInfo *bi, GHashTable *ht){
}
static MSList * make_buddy_list(BuddyLookupState *s, GValue *retval){
static MSList * make_buddy_list(BLReq *blreq, GValue *retval){
MSList *ret=NULL;
if (G_VALUE_TYPE(retval)==G_TYPE_VALUE_ARRAY){
GValueArray *array=(GValueArray*)g_value_get_boxed(retval);
......@@ -130,7 +117,7 @@ static MSList * make_buddy_list(BuddyLookupState *s, GValue *retval){
if (G_VALUE_TYPE(gelem)==G_TYPE_HASH_TABLE){
GHashTable *ht=(GHashTable*)g_value_get_boxed(gelem);
BuddyInfo *bi=buddy_info_new();
fill_buddy_info(s,bi,ht);
fill_buddy_info(blreq,bi,ht);
ret=ms_list_append(ret,bi);
}else{
ms_error("Element is not a hash table");
......@@ -141,8 +128,7 @@ static MSList * make_buddy_list(BuddyLookupState *s, GValue *retval){
}
static int xml_rpc_parse_response(SipSetupContext *ctx, SoupMessage *sm){
BuddyLookupState *s=get_buddy_lookup_state(ctx);
static int xml_rpc_parse_response(BLReq *blreq, SoupMessage *sm){
SoupBuffer *sb;
GValue retval;
GError *error=NULL;
......@@ -155,38 +141,35 @@ static int xml_rpc_parse_response(SipSetupContext *ctx, SoupMessage *sm){
}else{
ms_error("Could not parse xml-rpc response !");
}
s->status=BuddyLookupFailure;
blreq->base.status=BuddyLookupFailure;
}else{
ms_message("Extracting values from return type...");
s->results=make_buddy_list(s,&retval);
blreq->base.results=make_buddy_list(blreq,&retval);
g_value_unset(&retval);
s->status=BuddyLookupDone;
blreq->base.status=BuddyLookupDone;
}
soup_buffer_free(sb);
return s->status==BuddyLookupDone ? 0 : -1;
return blreq->base.status==BuddyLookupDone ? 0 : -1;
}
static void * process_xml_rpc_request(void *up){
SipSetupContext *ctx=(SipSetupContext*)up;
BuddyLookupState *s=get_buddy_lookup_state(ctx);
SoupMessage *sm=s->msg;
BLReq *blreq=(BLReq*)up;
SoupMessage *sm=blreq->msg;
int code;
g_signal_connect_swapped(G_OBJECT(sm),"got-headers",(GCallback)got_headers,ctx);
s->status=BuddyLookupConnecting;
code=soup_session_send_message(s->session,sm);
g_signal_connect_swapped(G_OBJECT(sm),"got-headers",(GCallback)got_headers,blreq);
blreq->base.status=BuddyLookupConnecting;
code=soup_session_send_message(blreq->session,sm);
if (code==200){
ms_message("Got a response from server, yeah !");
xml_rpc_parse_response(ctx,sm);
xml_rpc_parse_response(blreq,sm);
}else{
ms_error("request failed, error-code=%i (%s)",code,soup_status_get_phrase(code));
s->status=BuddyLookupFailure;
blreq->base.status=BuddyLookupFailure;
}
s->processing=FALSE;
return NULL;
}
static int lookup_buddy(SipSetupContext *ctx, const char *key){
BuddyLookupState *s=get_buddy_lookup_state(ctx);
static int lookup_buddy(SipSetupContext *ctx, BLReq *req){
LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx);
LinphoneCore *lc=linphone_proxy_config_get_core(cfg);
LpConfig *config=linphone_core_get_config(lc);
......@@ -199,15 +182,6 @@ static int lookup_buddy(SipSetupContext *ctx, const char *key){
ms_error("No url defined for BuddyLookup in config file, aborting search.");
return -1;
}
if (s->th!=0){
if (s->processing){
ms_message("Canceling previous request...");
soup_session_cancel_message(s->session,s->msg, SOUP_STATUS_CANCELLED);
}
ortp_thread_join(s->th,NULL);
s->th=0;
g_object_unref(G_OBJECT(s->msg));
}
osip_from_t *from;
osip_from_init(&from);
......@@ -219,42 +193,61 @@ static int lookup_buddy(SipSetupContext *ctx, const char *key){
aa=linphone_core_find_auth_info(lc,from->url->host,from->url->username);
if (aa) ms_message("There is a password: %s",aa->passwd);
else ms_message("No password for %s on %s",from->url->username,from->url->host);
sm=build_xmlrpc_request(identity, aa ? aa->passwd : NULL, key, from->url->host, url);
sm=build_xmlrpc_request(identity, aa ? aa->passwd : NULL, req->base.key, from->url->host, url, req->base.max_results);
osip_from_free(from);
s->msg=sm;
s->processing=TRUE;
ortp_thread_create(&s->th,NULL,process_xml_rpc_request,ctx);
req->msg=sm;
ortp_thread_create(&req->th,NULL,process_xml_rpc_request,req);
if (!sm) return -1;
return 0;
}
static BuddyLookupStatus get_buddy_lookup_status(SipSetupContext *ctx){
BuddyLookupState *s=get_buddy_lookup_state(ctx);
return s->status;
static BuddyLookupRequest * create_request(SipSetupContext *ctx){
BLReq *req=ms_new0(BLReq,1);
const char *proxy=NULL;
req->session=soup_session_sync_new();
proxy=getenv("http_proxy");
if (proxy && strlen(proxy)>0) set_proxy(req->session,proxy);
return (BuddyLookupRequest*)req;
}
static int submit_request(SipSetupContext *ctx, BuddyLookupRequest *req){
BLReq *blreq=(BLReq*)req;
return lookup_buddy(ctx,blreq);
}
static int get_buddy_lookup_results(SipSetupContext *ctx, MSList **results){
BuddyLookupState *s=get_buddy_lookup_state(ctx);
if (s->results){
*results=s->results;
s->results=NULL;
static int free_request(SipSetupContext *ctx, BuddyLookupRequest *req){
BLReq *blreq=(BLReq*)req;
if (blreq->th!=0){
soup_session_cancel_message(blreq->session,blreq->msg, SOUP_STATUS_CANCELLED);
ortp_thread_join(blreq->th,NULL);
blreq->th=0;
g_object_unref(G_OBJECT(blreq->msg));
}
if (blreq->session)
g_object_unref(G_OBJECT(blreq->session));
buddy_lookup_request_free(req);
return 0;
}
static void buddy_lookup_exit(void){
}
static BuddyLookupFuncs bl_funcs={
.request_create=create_request,
.request_submit=submit_request,
.request_free=free_request
};
static SipSetup buddy_lookup_funcs={
.name="BuddyLookup",
.capabilities=SIP_SETUP_CAP_BUDDY_LOOKUP,
.init=buddy_lookup_init,
.init_instance=buddy_lookup_instance_init,
.lookup_buddy=lookup_buddy,
.get_buddy_lookup_status=get_buddy_lookup_status,
.get_buddy_lookup_results=get_buddy_lookup_results,
.uninit_instance=buddy_lookup_instance_uninit,
.exit=buddy_lookup_exit
.exit=buddy_lookup_exit,
.buddy_lookup_funcs=&bl_funcs,
};
void libbuddylookup_init(){
......
......@@ -79,6 +79,27 @@ void sip_setup_unregister_all(void){
}
}
void buddy_lookup_request_set_key(BuddyLookupRequest *req, const char *key){
if (req->key!=NULL) {
ms_free(req->key);
req->key=NULL;
}
if (key) req->key=ms_strdup(key);
}
void buddy_lookup_request_set_max_results(BuddyLookupRequest *req, int ncount){
req->max_results=ncount;
}
void buddy_lookup_request_free(BuddyLookupRequest *req){
if (req->key) ms_free(req->key);
if (req->results){
ms_list_for_each(req->results,(void (*)(void*))buddy_info_free);
ms_list_free(req->results);
}
ms_free(req);
}
LinphoneProxyConfig *sip_setup_context_get_proxy_config(const SipSetupContext *ctx){
return ctx->cfg;
}
......@@ -144,21 +165,21 @@ int sip_setup_context_get_relay(SipSetupContext *ctx,char *relay, size_t size){
return -1;
}
int sip_setup_context_lookup_buddy(SipSetupContext *ctx, const char *key){
if (ctx->funcs->lookup_buddy)
return ctx->funcs->lookup_buddy(ctx,key);
return -1;
BuddyLookupRequest *sip_setup_context_create_buddy_lookup_request(SipSetupContext *ctx){
if (ctx->funcs->buddy_lookup_funcs)
return ctx->funcs->buddy_lookup_funcs->request_create(ctx);
return NULL;
}
BuddyLookupStatus sip_setup_context_get_buddy_lookup_status(SipSetupContext *ctx){
if (ctx->funcs->get_buddy_lookup_status)
return ctx->funcs->get_buddy_lookup_status(ctx);
return BuddyLookupFailure;
int sip_setup_context_buddy_lookup_submit(SipSetupContext *ctx , BuddyLookupRequest *req){
if (ctx->funcs->buddy_lookup_funcs)
return ctx->funcs->buddy_lookup_funcs->request_submit(ctx,req);
return -1;
}
int sip_setup_context_get_buddy_lookup_results(SipSetupContext *ctx, MSList **results /*of BuddyInfo */){
if (ctx->funcs->get_buddy_lookup_results)
return ctx->funcs->get_buddy_lookup_results(ctx,results);
int sip_setup_context_buddy_lookup_free(SipSetupContext *ctx , BuddyLookupRequest *req){
if (ctx->funcs->buddy_lookup_funcs)
return ctx->funcs->buddy_lookup_funcs->request_free(ctx,req);
return -1;
}
......@@ -175,11 +196,6 @@ const char ** sip_setup_context_get_domains(SipSetupContext *ctx){
}
void sip_setup_context_free_results(MSList *results){
ms_list_for_each(results,(void (*)(void*))&buddy_info_free);
ms_list_free(results);
}
int sip_setup_context_logout(SipSetupContext *ctx){
if (ctx->funcs->logout_account){
return ctx->funcs->logout_account(ctx);
......
......@@ -73,6 +73,20 @@ typedef struct _BuddyInfo{
int image_length;
}BuddyInfo;
typedef struct _BuddyLookupRequest {
char *key;
int max_results;
BuddyLookupStatus status;
MSList *results; /*of BuddyInfo */
}BuddyLookupRequest;
typedef struct _BuddyLookupFuncs{
BuddyLookupRequest * (*request_create)(SipSetupContext *ctx);
int (*request_submit)(SipSetupContext *ctx, BuddyLookupRequest *req);
int (*request_free)(SipSetupContext *ctx, BuddyLookupRequest *req);
}BuddyLookupFuncs;
struct _SipSetup{
char *name;
......@@ -88,17 +102,16 @@ struct _SipSetup{
int (*get_proxy)(SipSetupContext *ctx, const char *domain, char *proxy, size_t sz);
int (*get_stun_servers)(SipSetupContext *ctx, char *stun1, char *stun2, size_t size);
int (*get_relay)(SipSetupContext *ctx, char *relay, size_t size);
int (*lookup_buddy)(SipSetupContext *ctx, const char *key);
BuddyLookupStatus (*get_buddy_lookup_status)(SipSetupContext *ctx);
int (*get_buddy_lookup_results)(SipSetupContext *ctx, MSList **results);
const char * (*get_notice)(SipSetupContext *ctx);
const char ** (*get_domains)(SipSetupContext *ctx);
int (*logout_account)(SipSetupContext *ctx);
BuddyLookupFuncs *buddy_lookup_funcs;
};
typedef struct _SipSetup SipSetup;
#ifdef __cplusplus
extern "C"{
#endif
......@@ -106,6 +119,9 @@ extern "C"{
BuddyInfo *buddy_info_new();
void buddy_info_free(BuddyInfo *info);
void buddy_lookup_request_set_key(BuddyLookupRequest *req, const char *key);
void buddy_lookup_request_set_max_results(BuddyLookupRequest *req, int ncount);
void sip_setup_register(SipSetup *ss);
void sip_setup_register_all(void);
......@@ -121,20 +137,21 @@ int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, cons
int sip_setup_context_get_proxy(SipSetupContext *ctx, const char *domain, char *proxy, size_t sz);
int sip_setup_context_get_stun_servers(SipSetupContext *ctx, char *stun1, char *stun2, size_t size);
int sip_setup_context_get_relay(SipSetupContext *ctx, char *relay, size_t size);
int sip_setup_context_lookup_buddy(SipSetupContext *ctx, const char *key);
BuddyLookupStatus sip_setup_context_get_buddy_lookup_status(SipSetupContext *ctx);
int sip_setup_context_get_buddy_lookup_results(SipSetupContext *ctx, MSList **results /*of BuddyInfo */);
BuddyLookupRequest *sip_setup_context_create_buddy_lookup_request(SipSetupContext *ctx);
int sip_setup_context_buddy_lookup_submit(SipSetupContext *ctx , BuddyLookupRequest *req);
int sip_setup_context_buddy_lookup_free(SipSetupContext *ctx , BuddyLookupRequest *req);
const char * sip_setup_context_get_notice(SipSetupContext *ctx);
const char ** sip_setup_context_get_domains(SipSetupContext *ctx);
void sip_setup_context_free_results(MSList *results);
void sip_setup_context_free(SipSetupContext *ctx);
int sip_setup_context_logout(SipSetupContext *ctx);
/*internal methods*/
/*internal methods for use WITHIN plugins: do not use elsewhere*/
struct _LinphoneProxyConfig *sip_setup_context_get_proxy_config(const SipSetupContext *ctx);
void buddy_lookup_request_free(BuddyLookupRequest *req);
#ifdef __cplusplus
}
......
......@@ -138,9 +138,13 @@ static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
gchar *tmp;
MSList *results=NULL;
GtkProgressBar *pb=GTK_PROGRESS_BAR(linphone_gtk_get_widget(w,"progressbar"));
ctx=(SipSetupContext*)g_object_get_data(G_OBJECT(w),"SipSetupContext");
BuddyLookupRequest *req=(BuddyLookupRequest*)g_object_get_data(G_OBJECT(w),"buddylookup_request");
ctx=(SipSetupContext*)g_object_get_data(G_OBJECT(w),"SipSetupContext");
last_state=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"last_state"));
bls=sip_setup_context_get_buddy_lookup_status(ctx);
if (req==NULL) return FALSE;
bls=req->status;
if (last_state==bls) return TRUE;
switch(bls){
case BuddyLookupNone:
......@@ -164,7 +168,7 @@ static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
gtk_progress_bar_set_text(pb,_("Receiving data..."));
break;
case BuddyLookupDone:
sip_setup_context_get_buddy_lookup_results(ctx,&results);
results=req->results;
linphone_gtk_display_lookup_results(
linphone_gtk_get_widget(w,"search_results"),
results);
......@@ -174,7 +178,8 @@ static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
ms_list_size(results));
gtk_progress_bar_set_text(pb,tmp);
g_free(tmp);
if (results) sip_setup_context_free_results(results);
sip_setup_context_buddy_lookup_free(ctx,req);
g_object_set_data(G_OBJECT(w),"buddylookup_request",NULL);
break;
}
g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(bls));
......@@ -190,9 +195,17 @@ static gboolean keyword_typing_finished(GtkWidget *w){
}
keyword=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"keyword")));
if (strlen(keyword)>=1){
BuddyLookupRequest *req;
guint tid2;
ctx=(SipSetupContext*)g_object_get_data(G_OBJECT(w),"SipSetupContext");
sip_setup_context_lookup_buddy(ctx,keyword);
req=(BuddyLookupRequest*)g_object_get_data(G_OBJECT(w),"buddylookup_request");
if (req!=NULL){
sip_setup_context_buddy_lookup_free(ctx,req);
}
req=sip_setup_context_create_buddy_lookup_request(ctx);
buddy_lookup_request_set_key(req,keyword);
sip_setup_context_buddy_lookup_submit(ctx,req);
g_object_set_data(G_OBJECT(w),"buddylookup_request",req);
if (g_object_get_data(G_OBJECT(w),"buddylookup_processing")==NULL){
tid2=g_timeout_add(20,(GSourceFunc)linphone_gtk_process_buddy_lookup,w);
g_object_set_data(G_OBJECT(w),"buddylookup_processing",GINT_TO_POINTER(tid2));
......
......@@ -28,6 +28,7 @@ enum{
FRIEND_PRESENCE_STATUS,
FRIEND_ID,
FRIEND_SIP_ADDRESS,
FRIEND_ICON,
FRIEND_LIST_NCOL
};
......@@ -185,28 +186,23 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist)
store = gtk_list_store_new(FRIEND_LIST_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER,
G_TYPE_STRING);
/* need to add friends to the store here ...*/
G_TYPE_STRING, GDK_TYPE_PIXBUF);
gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
renderer = gtk_cell_renderer_pixbuf_new();
column = gtk_tree_view_column_new_with_attributes (NULL,
renderer,
"pixbuf", FRIEND_PRESENCE_IMG,
NULL);
gtk_tree_view_column_set_min_width (column, 29);
gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column);
gtk_tree_view_column_set_visible(column,linphone_gtk_get_ui_config_int("friendlist_icon",1));
renderer = gtk_cell_renderer_text_new ();
renderer = gtk_cell_renderer_pixbuf_new ();
column = gtk_tree_view_column_new_with_attributes (_("Name"),
renderer,
"text", FRIEND_NAME,
"pixbuf", FRIEND_ICON,
NULL);
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start(column,renderer,FALSE);
gtk_tree_view_column_add_attribute (column,renderer,
"text",
FRIEND_NAME);