From c58e884ef7fb54b86c1eb64028849056b5a63972 Mon Sep 17 00:00:00 2001 From: smorlat Date: Wed, 21 Oct 2009 19:21:07 +0000 Subject: [PATCH] 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 --- linphone/coreapi/friend.c | 32 ++++- linphone/coreapi/linphonecore.c | 79 ++++++++++- linphone/coreapi/linphonecore.h | 5 + .../coreapi/plugins/buddylookup/src/lookup.c | 129 +++++++++--------- linphone/coreapi/sipsetup.c | 50 ++++--- linphone/coreapi/sipsetup.h | 35 +++-- linphone/gtk-glade/buddylookup.c | 23 +++- linphone/gtk-glade/friendlist.c | 44 +++--- 8 files changed, 280 insertions(+), 117 deletions(-) diff --git a/linphone/coreapi/friend.c b/linphone/coreapi/friend.c index 6ee1c42db..ba86e6941 100644 --- a/linphone/coreapi/friend.c +++ b/linphone/coreapi/friend.c @@ -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){ diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c index bbf5a8e04..239fdd19f 100644 --- a/linphone/coreapi/linphonecore.c +++ b/linphone/coreapi/linphonecore.c @@ -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); diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h index cd81fc2cc..5485cbd26 100644 --- a/linphone/coreapi/linphonecore.h +++ b/linphone/coreapi/linphonecore.h @@ -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 */ 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); diff --git a/linphone/coreapi/plugins/buddylookup/src/lookup.c b/linphone/coreapi/plugins/buddylookup/src/lookup.c index 488a2146d..08f581e0b 100644 --- a/linphone/coreapi/plugins/buddylookup/src/lookup.c +++ b/linphone/coreapi/plugins/buddylookup/src/lookup.c @@ -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 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 submit_request(SipSetupContext *ctx, BuddyLookupRequest *req){ + BLReq *blreq=(BLReq*)req; + return lookup_buddy(ctx,blreq); +} + +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(){ diff --git a/linphone/coreapi/sipsetup.c b/linphone/coreapi/sipsetup.c index 738e273db..cd7fb6693 100644 --- a/linphone/coreapi/sipsetup.c +++ b/linphone/coreapi/sipsetup.c @@ -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); +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; +} + +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; } -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_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); diff --git a/linphone/coreapi/sipsetup.h b/linphone/coreapi/sipsetup.h index 6e3443953..6776367c9 100644 --- a/linphone/coreapi/sipsetup.h +++ b/linphone/coreapi/sipsetup.h @@ -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 } diff --git a/linphone/gtk-glade/buddylookup.c b/linphone/gtk-glade/buddylookup.c index 8aa5479a9..509a7b7b4 100644 --- a/linphone/gtk-glade/buddylookup.c +++ b/linphone/gtk-glade/buddylookup.c @@ -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)); diff --git a/linphone/gtk-glade/friendlist.c b/linphone/gtk-glade/friendlist.c index 5cc370719..59f05e58b 100644 --- a/linphone/gtk-glade/friendlist.c +++ b/linphone/gtk-glade/friendlist.c @@ -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); + gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); column = gtk_tree_view_column_new_with_attributes (_("Presence status"), @@ -214,9 +210,15 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist) "text", FRIEND_PRESENCE_STATUS, NULL); g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); gtk_tree_view_column_set_visible(column,linphone_gtk_get_ui_config_int("friendlist_status",1)); + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column,renderer,FALSE); + gtk_tree_view_column_add_attribute (column,renderer, + "pixbuf", + FRIEND_PRESENCE_IMG); + gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (friendlist)); gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); #if GTK_CHECK_VERSION(2,12,0) @@ -320,6 +322,7 @@ void linphone_gtk_show_friends(void){ } } if (!online_only || (linphone_friend_get_status(lf)!=LINPHONE_STATUS_OFFLINE)){ + BuddyInfo *bi; if (name==NULL || name[0]=='\0') display=addr; gtk_list_store_append(store,&iter); gtk_list_store_set(store,&iter,FRIEND_NAME, display, @@ -331,6 +334,15 @@ void linphone_gtk_show_friends(void){ escaped=g_markup_escape_text(uri,-1); gtk_list_store_set(store,&iter,FRIEND_SIP_ADDRESS,escaped,-1); g_free(escaped); + bi=linphone_friend_get_info(lf); + if (bi!=NULL && bi->image_data!=NULL){ + GdkPixbuf *pbuf= + _gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,40,TRUE); + if (pbuf) { + gtk_list_store_set(store,&iter,FRIEND_ICON,pbuf,-1); + g_object_unref(G_OBJECT(pbuf)); + } + } } ms_free(uri); if (name) ms_free(name);