diff --git a/configure.ac b/configure.ac index 89e0f230b..ec64910fe 100644 --- a/configure.ac +++ b/configure.ac @@ -145,7 +145,7 @@ AC_ARG_ENABLE(gtk_ui, esac],[gtk_ui=true]) if test "$gtk_ui" = "true" ; then - PKG_CHECK_MODULES(LIBGTK, gtk+-2.0 >= 2.4.0 gthread-2.0) + PKG_CHECK_MODULES(LIBGTK, gtk+-2.0 >= 2.22.0 gthread-2.0) if test "$enable_x11" = "false" ; then PKG_CHECK_MODULES(LIBGTKMAC,[ige-mac-integration >= 0.9.7 ]) AC_DEFINE([HAVE_GTK_OSX],[1],[Defined when gtk osx is used]) @@ -412,6 +412,11 @@ if test "$has_sighandler_t" = "yes" ; then AC_DEFINE( HAVE_SIGHANDLER_T, 1, [Define if sighandler_t available] ) fi +dnl check libsoup (needed for wizard) +PKG_CHECK_MODULES(LIBSOUP, [libsoup-2.4 >= 2.26]) +AC_SUBST(LIBSOUP_CFLAGS) +AC_SUBST(LIBSOUP_LIBS) + ################################################## # Stricter build options (after external packages) ################################################## diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index eab5bdc5c..96a27d02b 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -38,6 +38,7 @@ liblinphone_la_SOURCES=\ linphonecall.c \ sipsetup.c sipsetup.h \ siplogin.c \ + sipwizard.c \ lsd.c linphonecore_utils.h \ ec-calibrator.c \ conference.c @@ -54,7 +55,8 @@ liblinphone_la_LIBADD= \ $(EXOSIP_LIBS) \ $(MEDIASTREAMER_LIBS) \ $(ORTP_LIBS) $(OPENSSL_LIBS) \ - $(TUNNEL_LIBS) + $(TUNNEL_LIBS) \ + $(LIBSOUP_LIBS) if BUILD_TESTS noinst_PROGRAMS=test_lsd test_ecc @@ -74,11 +76,10 @@ AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \ $(MEDIASTREAMER_CFLAGS) \ $(OSIP_CFLAGS) \ $(EXOSIP_CFLAGS) \ + $(LIBSOUP_CFLAGS) \ -DENABLE_TRACE \ -DLOG_DOMAIN=\"LinphoneCore\" \ $(IPV6_CFLAGS) \ -DORTP_INET6 \ $(VIDEO_CFLAGS) \ $(TUNNEL_CFLAGS) - -AM_CXXFLAGS=$(AM_CFLAGS) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 306569f16..83edb4975 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -417,6 +417,9 @@ typedef struct _LinphoneAccountCreator{ char *username; char *password; char *domain; + char *route; + char *email; + int suscribe; bool_t succeeded; }LinphoneAccountCreator; @@ -424,9 +427,13 @@ LinphoneAccountCreator *linphone_account_creator_new(struct _LinphoneCore *core, void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username); void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password); void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain); +void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route); +void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email); +void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribre); const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj); const char * linphone_account_creator_get_domain(LinphoneAccountCreator *obj); int linphone_account_creator_test_existence(LinphoneAccountCreator *obj); +int linphone_account_creator_test_validation(LinphoneAccountCreator *obj); LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj); void linphone_account_creator_destroy(LinphoneAccountCreator *obj); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 959c321b6..d1ef5355b 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -779,6 +779,18 @@ void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char set_string(&obj->domain,domain); } +void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route) { + set_string(&obj->route,route); +} + +void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email) { + set_string(&obj->email,email); +} + +void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribe) { + obj->suscribe = suscribe; +} + const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj){ return obj->username; } @@ -795,10 +807,16 @@ int linphone_account_creator_test_existence(LinphoneAccountCreator *obj){ return err; } +int linphone_account_creator_test_validation(LinphoneAccountCreator *obj) { + SipSetupContext *ssctx=obj->ssctx; + int err=sip_setup_context_account_validated(ssctx,obj->username); + return err; +} + LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj){ SipSetupContext *ssctx=obj->ssctx; char *uri=ms_strdup_printf("%s@%s",obj->username,obj->domain); - int err=sip_setup_context_create_account(ssctx,uri,obj->password); + int err=sip_setup_context_create_account(ssctx, uri, obj->password, obj->email, obj->suscribe); ms_free(uri); if (err==0) { obj->succeeded=TRUE; diff --git a/coreapi/sipsetup.c b/coreapi/sipsetup.c index 270737df1..a1eaa5789 100644 --- a/coreapi/sipsetup.c +++ b/coreapi/sipsetup.c @@ -24,9 +24,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" extern SipSetup linphone_sip_login; +extern SipSetup linphone_sip_wizard; static SipSetup *all_sip_setups[]={ &linphone_sip_login, + &linphone_sip_wizard, NULL }; @@ -123,9 +125,9 @@ int sip_setup_context_get_capabilities(SipSetupContext *ctx){ return ctx->funcs->capabilities; } -int sip_setup_context_create_account(SipSetupContext * ctx, const char *uri, const char *passwd){ +int sip_setup_context_create_account(SipSetupContext * ctx, const char *uri, const char *passwd, const char *email, int suscribe){ if (ctx->funcs->create_account) - return ctx->funcs->create_account(ctx,uri, passwd); + return ctx->funcs->create_account(ctx, uri, passwd, email, suscribe); else return -1; } @@ -135,6 +137,12 @@ int sip_setup_context_account_exists(SipSetupContext *ctx, const char *uri){ return -1; } +int sip_setup_context_account_validated(SipSetupContext *ctx, const char *uri){ + if (ctx->funcs->account_validated) + return ctx->funcs->account_validated(ctx,uri); + return -1; +} + int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, const char *passwd){ LinphoneAddress *from=linphone_address_new(uri); if (from==NULL) { diff --git a/coreapi/sipsetup.h b/coreapi/sipsetup.h index 6776367c9..2aefbee5c 100644 --- a/coreapi/sipsetup.h +++ b/coreapi/sipsetup.h @@ -97,7 +97,7 @@ struct _SipSetup{ void (*init_instance)(SipSetupContext *ctx); void (*uninit_instance)(SipSetupContext *ctx); int (*account_exists)(SipSetupContext *ctx, const char *uri); - int (*create_account)(SipSetupContext *ctx, const char *uri, const char *passwd); + int (*create_account)(SipSetupContext *ctx, const char *uri, const char *passwd, const char *email, int suscribe); int (*login_account)(SipSetupContext *ctx, const char *uri, const char *passwd); 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); @@ -106,6 +106,7 @@ struct _SipSetup{ const char ** (*get_domains)(SipSetupContext *ctx); int (*logout_account)(SipSetupContext *ctx); BuddyLookupFuncs *buddy_lookup_funcs; + int (*account_validated)(SipSetupContext *ctx, const char *uri); }; typedef struct _SipSetup SipSetup; @@ -131,7 +132,8 @@ unsigned int sip_setup_get_capabilities(SipSetup *s); SipSetupContext * sip_setup_context_new(SipSetup *s, struct _LinphoneProxyConfig *cfg); int sip_setup_context_account_exists(SipSetupContext *ctx, const char *uri); -int sip_setup_context_create_account(SipSetupContext *ctx, const char *uri, const char *passwd); +int sip_setup_context_account_validated(SipSetupContext *ctx, const char *uri); +int sip_setup_context_create_account(SipSetupContext *ctx, const char *uri, const char *passwd, const char *email, int suscribe); int sip_setup_context_get_capabilities(SipSetupContext *ctx); int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, const char *passwd); int sip_setup_context_get_proxy(SipSetupContext *ctx, const char *domain, char *proxy, size_t sz); diff --git a/coreapi/sipwizard.c b/coreapi/sipwizard.c new file mode 100644 index 000000000..ee268e50c --- /dev/null +++ b/coreapi/sipwizard.c @@ -0,0 +1,268 @@ +/* +sipwizard.c +Copyright (C) 2011 Belledonne Communication, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include "private.h" +#include +#include + +typedef struct _BLReq{ + int status; + int result; + SoupMessage *msg; + SoupSession *session; + ortp_thread_t th; +}BLReq; + +static const int XMLRPC_FAILED = -1; +static const int XMLRPC_OK = 0; +static const char *XMLRPC_URL = "https://www.linphone.org/wizard.php"; + +static void sip_wizard_init_instance(SipSetupContext *ctx){ + LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); + /*disable registration until the user logs in*/ + linphone_proxy_config_enable_register(cfg,FALSE); +} + +static const char ** sip_wizard_get_domains(SipSetupContext *ctx) { + LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); + const char **domains = (const char**) &cfg->reg_proxy; + return domains; +} + + +static int xml_rpc_parse_response(BLReq *blreq, SoupMessage *sm){ + SoupBuffer *sb; + GValue retval; + GError *error=NULL; + sb=soup_message_body_flatten(sm->response_body); + ms_message("This the xml-rpc response:\n%s\n",sb->data); + if (soup_xmlrpc_parse_method_response(sb->data,sb->length,&retval,&error)==FALSE){ + if (error!=NULL){ + ms_error("xmlrpc fault: %s",error->message); + g_error_free(error); + }else{ + ms_error("Could not parse xml-rpc response !"); + } + blreq->status=XMLRPC_FAILED; + }else{ + ms_message("Extracting values from return type..."); + blreq->result = g_value_get_int(&retval); + g_value_unset(&retval); + blreq->status=XMLRPC_OK; + } + soup_buffer_free(sb); + return blreq->status; +} + +static void got_headers(BLReq *blreq, SoupMessage*msg){ + ms_message("Got headers !"); + blreq->status=XMLRPC_OK; +} + +#if SERIALIZE_HTTPS +/*on windows libsoup support for threads with gnutls is not yet functionnal (only in git) +This will come in next release of libsoup, probably. +In the meantime, we are forced to serialize all soup https processing with a big +ugly global mutex...*/ + +static GStaticMutex big_mutex = G_STATIC_MUTEX_INIT; +#endif + +static void * process_xml_rpc_request(void *up){ + BLReq *blreq=(BLReq*)up; + SoupMessage *sm=blreq->msg; + int code; + g_signal_connect_swapped(G_OBJECT(sm),"got-headers",(GCallback)got_headers,blreq); + blreq->status=XMLRPC_OK; +#if SERIALIZE_HTTPS + g_static_mutex_lock(&big_mutex); +#endif + code=soup_session_send_message(blreq->session,sm); + if (code==200){ + xml_rpc_parse_response(blreq,sm); + }else{ + ms_error("request failed, error-code=%i (%s)",code,soup_status_get_phrase(code)); + blreq->status=XMLRPC_FAILED; + } +#if SERIALIZE_HTTPS + g_static_mutex_unlock(&big_mutex); +#endif + return NULL; +} + + +static int do_simple_xmlrpc_request(SoupMessage *msg) { + int ret=-1; + BLReq *req; + + if (!msg){ + ms_error("Fail to create SoupMessage !"); + return -1; + }else{ + SoupBuffer *sb=soup_message_body_flatten(msg->request_body); + ms_message("This is the XML-RPC request we are going to send:\n%s\n",sb->data); + soup_buffer_free(sb); + } + + req=ms_new0(BLReq, 1); + req->session=soup_session_sync_new(); + req->msg=msg; + + process_xml_rpc_request(req); + + if (req->status == XMLRPC_OK) { + ret=req->result; + } + + // Freeing allocated structures lead to a crash (why?) + //g_free(req->session); + //g_free(msg); + ms_free(req); + + return ret; +} + +/* + * Return 1 if account already exists + * 0 if account doesn't exists + * -1 if information isn't available + */ +static int sip_wizard_account_exists(SipSetupContext *ctx, const char *identity) { + SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, + "check_account", + G_TYPE_STRING, identity, + G_TYPE_INVALID); + return do_simple_xmlrpc_request(msg); +} + +static int sip_wizard_account_validated(SipSetupContext *ctx, const char *identity) { + SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, + "check_account_validated", + G_TYPE_STRING, identity, + G_TYPE_INVALID); + return do_simple_xmlrpc_request(msg); +} + +static int sip_wizard_create_account(SipSetupContext *ctx, const char *identity, const char *passwd, const char *email, int suscribe) { + SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, + "create_account", + G_TYPE_STRING, identity, + G_TYPE_STRING, passwd, + G_TYPE_STRING, email, + G_TYPE_INT, suscribe, + G_TYPE_INVALID); + return do_simple_xmlrpc_request(msg); +} + +static void guess_display_name(LinphoneAddress *from){ + const char *username=linphone_address_get_username(from); + char *dn=(char*)ms_malloc(strlen(username)+1); + const char *it; + char *wptr=dn; + bool_t begin=TRUE; + bool_t surname=FALSE; + for(it=username;*it!='\0';++it){ + if (begin){ + *wptr=toupper(*it); + begin=FALSE; + }else if (*it=='.'){ + if (surname) break; + *wptr=' '; + begin=TRUE; + surname=TRUE; + }else { + *wptr=*it; + } + wptr++; + } + *wptr='\0'; + linphone_address_set_display_name(from,dn); + ms_free(dn); +} + +static int sip_wizard_do_login(SipSetupContext * ctx, const char *uri, const char *passwd){ + LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); + LinphoneCore *lc=linphone_proxy_config_get_core(cfg); + LinphoneAuthInfo *auth; + LinphoneAddress *parsed_uri; + char *tmp; + + parsed_uri=linphone_address_new(uri); + if (parsed_uri==NULL){ + return -1; + } + if (linphone_address_get_display_name(parsed_uri)!=NULL){ + guess_display_name(parsed_uri); + } + tmp=linphone_address_as_string(parsed_uri); + linphone_proxy_config_set_identity(cfg,tmp); + if (passwd) { + auth=linphone_auth_info_new(linphone_address_get_username(parsed_uri),NULL,passwd,NULL,NULL); + linphone_core_add_auth_info(lc,auth); + } + linphone_proxy_config_enable_register(cfg,TRUE); + linphone_proxy_config_done(cfg); + ms_free(tmp); + linphone_address_destroy(parsed_uri); + return 0; +} + +/* a simple SipSetup built-in plugin to allow creating accounts at runtime*/ + +#ifndef _MSC_VER + +SipSetup linphone_sip_wizard={ + .name="SipWizard", + .capabilities=SIP_SETUP_CAP_ACCOUNT_MANAGER, + .init_instance=sip_wizard_init_instance, + .account_exists=sip_wizard_account_exists, + .create_account=sip_wizard_create_account, + .login_account=sip_wizard_do_login, + .get_domains=sip_wizard_get_domains, + .account_validated=sip_wizard_account_validated +}; + +#else +SipSetup linphone_sip_wizard={ + "SipWizard", + SIP_SETUP_CAP_ACCOUNT_MANAGER, + 0, + NULL, + NULL, + sip_wizard_init_instance, + NULL, + sip_wizard_account_exists, + sip_wizard_create_account, + sip_wizard_do_login, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + sip_wizard_get_domains, + NULL, + NULL, + sip_wizard_account_validated +}; + + + +#endif diff --git a/gtk/linphone.h b/gtk/linphone.h index 57b562038..45c8b54aa 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -56,6 +56,7 @@ GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint GtkWidget *linphone_gtk_create_window(const char *window_name); GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name); +GtkWidget * linphone_gtk_create_assistant(void); LinphoneCore *linphone_gtk_get_core(void); GtkWidget *linphone_gtk_get_main_window(); diff --git a/gtk/main.c b/gtk/main.c index 88f2807fd..27c6f6165 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -50,6 +50,7 @@ const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION; static LinphoneCore *the_core=NULL; static GtkWidget *the_ui=NULL; +GtkWidget *the_wizard=NULL; static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState rs, const char *msg); static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid); @@ -1439,8 +1440,9 @@ static void linphone_gtk_configure_main_window(){ g_object_unref(G_OBJECT(pbuf)); } } - if (linphone_gtk_can_manage_accounts()) + if (linphone_gtk_can_manage_accounts()) { gtk_widget_show(linphone_gtk_get_widget(w,"assistant_item")); + } if (update_check_menu){ gtk_widget_show(linphone_gtk_get_widget(w,"versioncheck_item")); } @@ -1584,6 +1586,13 @@ static void linphone_gtk_check_soundcards(){ } } +// Display the account wizard +void linphone_gtk_display_wizard() { + if (the_wizard == NULL || !gtk_widget_get_visible(the_wizard)) { // Only one instance of the wizard at the same time + the_wizard = linphone_gtk_create_assistant(); + } +} + static void linphone_gtk_quit(void){ static gboolean quit_done=FALSE; if (!quit_done){ @@ -1727,6 +1736,12 @@ int main(int argc, char *argv[]){ gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core()); gtk_timeout_add(30,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL); linphone_gtk_init_main_window(); + + // Veryfing if at least one sip account is configured. If not, show wizard + if (linphone_core_get_proxy_config_list(linphone_gtk_get_core()) == NULL) { + linphone_gtk_display_wizard(); + } + #ifndef HAVE_GTK_OSX linphone_gtk_init_status_icon(); #endif diff --git a/gtk/main.ui b/gtk/main.ui index fde3a794a..f6f418a03 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -129,7 +129,7 @@ False - + True False gtk-dialog-authentication @@ -383,6 +383,11 @@ False gtk-clear + + True + False + gtk-connect + True False @@ -572,6 +577,16 @@ + + + Account assistant + False + False + image12 + False + + + diff --git a/gtk/parameters.ui b/gtk/parameters.ui index 153b5bdde..dcea80e26 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -1,31 +1,31 @@ - + - 500 500 3001 + 500 1 10 - 1 1 65535 + 1 1 10 - 1 1 65535 + 1 1 10 - 1 65535 + 1 1 10 @@ -42,15 +42,15 @@ 10 - 5060 1 65535 + 5060 1 9.9999999995529656 - 1 65535 + 1 1 10 @@ -153,12 +153,14 @@ + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Settings linphone2.png True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -168,34 +170,42 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False True + False Set Maximum Transmission Unit: True True False + False True - + + True + True 0 @@ -203,15 +213,23 @@ True True + False + False + True + True adjustment1 - + + True + True 1 + True + True 0 @@ -221,10 +239,13 @@ True True False + False True - + + True + True 1 @@ -235,10 +256,13 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True - + + True + True 2 @@ -249,6 +273,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Transport</b> True @@ -257,29 +282,34 @@ False + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 2 True + False model8 @@ -293,8 +323,12 @@ True True - + True + False + False + True + True adjustment7 @@ -307,10 +341,10 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - True - adjustment2 - + False + False + True + True 1 @@ -324,10 +358,14 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True + False + False + True + True adjustment3 - + 1 @@ -339,6 +377,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Video RTP/UDP: right @@ -351,6 +390,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Audio RTP/UDP: right @@ -363,6 +403,7 @@ True + False Media encryption type @@ -373,6 +414,7 @@ True + False 0 @@ -384,6 +426,7 @@ + False Tunnel @@ -396,7 +439,8 @@ edit True True - + False + 1 @@ -412,6 +456,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Network protocol and ports</b> True @@ -420,27 +465,31 @@ False + True 1 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False Direct connection to the Internet True True False + False True True - + False @@ -451,33 +500,41 @@ True + False Behind NAT / Firewall (specify gateway IP below) True True False + False True True no_nat - + + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Public IP address: right + True + True 0 @@ -486,14 +543,22 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + False + True + True + + True + True 1 + True + True 1 @@ -507,33 +572,41 @@ True + False Behind NAT / Firewall (use STUN to resolve) True True False + False True True no_nat - + + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Stun server: right + True + True 0 @@ -542,14 +615,22 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + False + True + True + + True + True 1 + True + True 1 @@ -565,6 +646,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>NAT and Firewall</b> True @@ -573,6 +655,7 @@ False + True 2 @@ -581,24 +664,31 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-network + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Network settings + True + True 1 @@ -610,35 +700,43 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 6 2 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + + True + True 0 @@ -649,10 +747,13 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True - + + True + True 1 @@ -668,6 +769,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Ring sound: right @@ -682,7 +784,11 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + False + True + True + 1 @@ -695,9 +801,10 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK model1 - + @@ -716,9 +823,10 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK model2 - + @@ -736,6 +844,7 @@ + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK ALSA special device (optional): right @@ -749,6 +858,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Capture device: right @@ -762,6 +872,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Ring device: right @@ -775,6 +886,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Playback device: right @@ -787,9 +899,10 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK model3 - + @@ -810,8 +923,9 @@ True True False + False True - + 1 @@ -830,6 +944,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Audio</b> True @@ -837,26 +952,32 @@ + True + True 0 True + False 0 none True + False 12 True + False 2 2 True + False Video input device: right @@ -867,8 +988,9 @@ True + False model4 - + @@ -885,6 +1007,7 @@ True + False Prefered video resolution: @@ -895,9 +1018,10 @@ True + False model5 0 - + @@ -919,12 +1043,14 @@ True + False <b>Video</b> True + True False 1 @@ -937,24 +1063,31 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-media-play + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Multimedia settings + True + True 1 @@ -967,10 +1100,12 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK This section defines your SIP address when not using a SIP account 0 @@ -978,17 +1113,20 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 3 2 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Your display name (eg: John Doe): @@ -998,7 +1136,11 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + False + True + True + 1 @@ -1008,6 +1150,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Your username: @@ -1019,6 +1162,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Your resulting SIP address: @@ -1032,7 +1176,11 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + False + True + True + 1 @@ -1047,6 +1195,10 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK False + False + False + True + True 1 @@ -1062,6 +1214,7 @@ True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Default identity</b> True @@ -1069,23 +1222,28 @@ + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -1101,41 +1259,51 @@ + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True True True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-add + True + True 0 - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Add + Wizard + True + True 1 @@ -1149,33 +1317,41 @@ - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-edit + gtk-add + True + True 0 - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Edit + Add + True + True 1 @@ -1189,33 +1365,41 @@ - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-delete + gtk-edit + True + True 0 - + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Remove + Edit + True + True 1 @@ -1229,29 +1413,41 @@ - + + True True True - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + - + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True - gtk-network + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + True + True 0 - + True - Register to FONICS -virtual network ! + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Remove + True + True 1 @@ -1264,6 +1460,50 @@ virtual network ! 3 + + + True + True + False + + + + True + False + + + True + False + gtk-network + + + True + True + 0 + + + + + True + False + Register to FONICS +virtual network ! + + + True + True + 1 + + + + + + + False + False + 4 + + False @@ -1278,6 +1518,7 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Proxy accounts</b> True @@ -1285,23 +1526,28 @@ virtual network ! + True + True 1 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -1309,28 +1555,36 @@ virtual network ! True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-delete + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Erase all passwords + True + True 1 @@ -1350,6 +1604,7 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Privacy</b> True @@ -1357,6 +1612,8 @@ virtual network ! + True + True 2 @@ -1368,24 +1625,31 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK stock_people.png + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Manage SIP Accounts + True + True 1 @@ -1398,29 +1662,34 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK model6 0 - + @@ -1430,12 +1699,14 @@ virtual network ! False + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -1453,12 +1724,15 @@ virtual network ! + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -1467,8 +1741,9 @@ virtual network ! True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True - + False @@ -1483,8 +1758,9 @@ virtual network ! True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True - + False @@ -1498,28 +1774,36 @@ virtual network ! True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-yes + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Enable + True + True 1 @@ -1538,28 +1822,36 @@ virtual network ! True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-no + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Disable + True + True 1 @@ -1575,11 +1867,14 @@ virtual network ! False + True 1 + True + True 1 @@ -1590,6 +1885,7 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Codecs</b> True @@ -1597,23 +1893,28 @@ virtual network ! + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 3 2 @@ -1623,8 +1924,12 @@ virtual network ! True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 stands for "unlimited" + False + False + True + True adjustment5 - + 1 @@ -1641,8 +1946,12 @@ virtual network ! True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 stands for "unlimited" + False + False + True + True adjustment6 - + 1 @@ -1654,6 +1963,7 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Upload speed limit in Kbit/sec: right @@ -1666,6 +1976,7 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Download speed limit in Kbit/sec: right @@ -1677,9 +1988,10 @@ virtual network ! True True False + False 0 True - + 1 @@ -1693,6 +2005,7 @@ virtual network ! True + False <i>Adaptive rate control is a technique to dynamically guess the available bandwidth during a call.</i> True True @@ -1711,6 +2024,7 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Bandwidth control</b> True @@ -1718,6 +2032,8 @@ virtual network ! + True + True 1 @@ -1729,24 +2045,31 @@ virtual network ! True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-execute + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Codecs + True + True 1 @@ -1759,20 +2082,24 @@ virtual network ! True + False True + False 0 none True + False 12 True + False model7 - + @@ -1786,6 +2113,7 @@ virtual network ! True + False <b>Language</b> True @@ -1793,17 +2121,20 @@ virtual network ! False + True 0 True + False 0 none True + False 12 @@ -1811,8 +2142,9 @@ virtual network ! True True False + False True - + @@ -1820,6 +2152,7 @@ virtual network ! True + False <b>Level</b> True @@ -1827,6 +2160,7 @@ virtual network ! False + True 1 @@ -1838,22 +2172,29 @@ virtual network ! True + False True + False gtk-properties 3 + True + True 0 True + False User interface + True + True 1 @@ -1865,12 +2206,15 @@ virtual network ! + True + True 0 True + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK end @@ -1879,25 +2223,33 @@ virtual network ! True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False + True + False True + False gtk-apply + True + True 0 True + False Done + True + True 1 @@ -1913,6 +2265,8 @@ virtual network ! + True + True 5 1 diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 98c44dffc..ff9d91cf0 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -119,12 +119,12 @@ void linphone_gtk_update_my_port(GtkWidget *w){ } else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (UDP)") == 0) { tr.udp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); - tr.tcp_port = 0; + tr.tcp_port = 0; tr.tls_port = 0; } else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (TLS)") == 0){ tr.udp_port = 0; - tr.tcp_port = 0; + tr.tcp_port = 0; tr.tls_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); } diff --git a/gtk/setupwizard.c b/gtk/setupwizard.c index e5f8702f2..ee7e13413 100644 --- a/gtk/setupwizard.c +++ b/gtk/setupwizard.c @@ -18,7 +18,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "linphone.h" -LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w); +#include +#include +#include +static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w); + +static const int PASSWORD_MIN_SIZE = 6; +static const int LOGIN_MIN_SIZE = 4; +static int is_username_available = 0; +static int is_email_correct = 0; +static int is_password_correct = 0; + +static GdkPixbuf *ok; +static GdkPixbuf *notok; static GtkWidget *create_intro(){ GtkWidget *vbox=gtk_vbox_new(FALSE,2); @@ -31,83 +43,295 @@ static GtkWidget *create_intro(){ static GtkWidget *create_setup_signin_choice(){ GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *t1=gtk_radio_button_new_with_label(NULL,_("Create an account by choosing a username")); - GtkWidget *t2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already an account and just want to use it")); + GtkWidget *t1=gtk_radio_button_new_with_label(NULL,_("Create an account on linphone.org")); + GtkWidget *t2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a linphone.org account and I just want to use it")); + GtkWidget *t3=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a sip account and I just want to use it")); gtk_box_pack_start (GTK_BOX (vbox), t1, TRUE, TRUE, 2); gtk_box_pack_start (GTK_BOX (vbox), t2, TRUE, TRUE, 2); + gtk_box_pack_start (GTK_BOX (vbox), t3, TRUE, TRUE, 2); gtk_widget_show_all(vbox); g_object_set_data(G_OBJECT(vbox),"create_account",t1); - g_object_set_data(G_OBJECT(vbox),"setup_account",t2); + g_object_set_data(G_OBJECT(vbox),"setup_linphone_account",t2); + g_object_set_data(G_OBJECT(vbox),"setup_account",t3); return vbox; } -static void create_username_changed(GtkEntry *entry, GtkWidget *w){ +static int all_account_information_entered(GtkWidget *w) { + GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); + GtkEntry* domain = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"domain")); + + if (gtk_entry_get_text_length(username) > 0 && + gtk_entry_get_text_length(domain) > 0 && + g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}$", gtk_entry_get_text(username), 0, 0) && + g_regex_match_simple("^(sip:)?([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$", gtk_entry_get_text(domain), 0, 0)) { + return 1; + } + return 0; +} + +static void account_informations_changed(GtkEntry *entry, GtkWidget *w) { GtkWidget *assistant=gtk_widget_get_toplevel(w); gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - gtk_entry_get_text_length(entry)>=3); + all_account_information_entered(w)>0); } -static GtkWidget *create_username_chooser(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *hbox=gtk_hbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(_("Please choose a username:")); - GtkWidget *label2=gtk_label_new(_("Username:")); - GtkWidget *label3=gtk_label_new(NULL); - GtkWidget *entry=gtk_entry_new(); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (hbox), label2, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), label3, TRUE, TRUE, 2); +static void linphone_account_informations_changed(GtkEntry *entry, GtkWidget *w) { + GtkWidget *assistant=gtk_widget_get_toplevel(w); + GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); + + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, + gtk_entry_get_text_length(username) >= LOGIN_MIN_SIZE); +} + +static GtkWidget *create_linphone_account_informations_page() { + GtkWidget *vbox=gtk_table_new(3, 2, TRUE); + GtkWidget *label=gtk_label_new(_("Enter your linphone.org username")); + + GdkColor color; + gdk_color_parse ("red", &color); + GtkWidget *labelEmpty=gtk_label_new(NULL); + gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); + + GtkWidget *labelUsername=gtk_label_new(_("Username:")); + GtkWidget *entryUsername=gtk_entry_new(); + GtkWidget *labelPassword=gtk_label_new(_("Password:")); + GtkWidget *entryPassword=gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); + + gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelPassword, 0, 1, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryPassword, 1, 2, 2, 3); + gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"username",entry); - g_object_set_data(G_OBJECT(vbox),"errorstring",label3); - g_signal_connect(G_OBJECT(entry),"changed",(GCallback)create_username_changed,vbox); + g_object_set_data(G_OBJECT(vbox),"username",entryUsername); + g_object_set_data(G_OBJECT(vbox),"password",entryPassword); + g_object_set_data(G_OBJECT(vbox),"errorstring",labelEmpty); + g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)linphone_account_informations_changed,vbox); return vbox; } -static GtkWidget *create_username_checking_page(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(NULL); - GtkWidget *progress=gtk_progress_bar_new(); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), progress, TRUE, TRUE, 2); - g_object_set_data(G_OBJECT(vbox),"label",label); - g_object_set_data(G_OBJECT(vbox),"progress",progress); +static GtkWidget *create_account_informations_page() { + GtkWidget *vbox=gtk_table_new(6, 2, FALSE); + GtkWidget *label=gtk_label_new(_("Enter your account informations")); + + GdkColor color; + gdk_color_parse ("red", &color); + GtkWidget *labelEmpty=gtk_label_new(NULL); + gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); + + GtkWidget *labelUsername=gtk_label_new(_("Username*")); + GtkWidget *labelPassword=gtk_label_new(_("Password*")); + GtkWidget *entryPassword=gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); + GtkWidget *labelDomain=gtk_label_new(_("Domain*")); + GtkWidget *labelProxy=gtk_label_new(_("Proxy")); + GtkWidget *entryUsername=gtk_entry_new(); + GtkWidget *entryDomain=gtk_entry_new(); + GtkWidget *entryRoute=gtk_entry_new(); + + gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelPassword, 0, 1, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryPassword, 1, 2, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelDomain, 0, 1, 3, 4); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryDomain, 1, 2, 3, 4); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelProxy, 0, 1, 4, 5); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryRoute, 1, 2, 4, 5); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelEmpty, 0, 2, 5, 6); gtk_widget_show_all(vbox); + + g_object_set_data(G_OBJECT(vbox),"username",entryUsername); + g_object_set_data(G_OBJECT(vbox),"password",entryPassword); + g_object_set_data(G_OBJECT(vbox),"domain",entryDomain); + g_object_set_data(G_OBJECT(vbox),"proxy",entryRoute); + g_object_set_data(G_OBJECT(vbox),"errorstring",labelEmpty); + g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)account_informations_changed,vbox); + g_signal_connect(G_OBJECT(entryDomain),"changed",(GCallback)account_informations_changed,vbox); + g_signal_connect(G_OBJECT(entryRoute),"changed",(GCallback)account_informations_changed,vbox); + return vbox; } -static void *progress_bar_update(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, const char *purpose, float progress){ - GtkWidget *pb=(GtkWidget*)ctx; - if (ws==LinphoneWaitingProgress) gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb)); - else if (ws==LinphoneWaitingFinished) gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb),1); - return ctx; -} - -static void check_username(GtkWidget *page){ - GtkWidget *progress=(GtkWidget*)g_object_get_data(G_OBJECT(page),"progress"); - GtkWidget *label=(GtkWidget*)g_object_get_data(G_OBJECT(page),"label"); +static int create_account(GtkWidget *page) { LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); - gchar *text=g_strdup_printf(_("Checking if '%s' is available..."),linphone_account_creator_get_username(creator)); - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); - int res; - gtk_label_set_text(GTK_LABEL(label),text); - g_free(text); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Please wait...")); - linphone_core_set_waiting_callback(linphone_gtk_get_core(),progress_bar_update,progress); - res=linphone_account_creator_test_existence(c); - if (res==1){ - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Sorry this username already exists. Please try a new one.")); - }else if (res==0){ - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Ok !")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(gtk_widget_get_toplevel(page)),page,TRUE); - }else if (res==-1){ - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Communication problem, please try again later.")); + LinphoneProxyConfig *res=linphone_account_creator_validate(creator); + if (res) { + if (!g_regex_match_simple("^sip:[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}@sip.linphone.org$",creator->username, 0, 0)) { + gchar identity[128]; + g_snprintf(identity, sizeof(identity), "sip:%s@sip.linphone.org", creator->username); + linphone_account_creator_set_username(creator, identity); + linphone_account_creator_set_domain(creator, "sip:sip.linphone.org"); + } + return 1; } - linphone_core_set_waiting_callback(linphone_gtk_get_core(),linphone_gtk_wait,NULL); + return 0; } +static int is_account_information_correct(GtkWidget *w) { + if (is_username_available == 1 && is_email_correct == 1 && is_password_correct == 1) { + return 1; + } + return 0; +} + +static void account_email_changed(GtkEntry *entry, GtkWidget *w) { + // Verifying if email entered is correct, and if form is correctly filled, let the user go next page + + GtkEntry* email = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"email")); + GtkImage* isEmailOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"emailOk")); + GtkWidget *assistant=gtk_widget_get_toplevel(w); + + if (g_regex_match_simple("^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$", gtk_entry_get_text(email), 0, 0)) { + is_email_correct = 1; + gtk_image_set_from_pixbuf(isEmailOk, ok); + } + else { + is_email_correct = 0; + gtk_image_set_from_pixbuf(isEmailOk, notok); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, + is_account_information_correct(w)>0); +} + +static void account_password_changed(GtkEntry *entry, GtkWidget *w) { + // Verifying if passwords entered match, and if form is correctly filled, let the user go next page + + GtkEntry* password = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"password")); + GtkImage* isPasswordOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"passwordOk")); + GtkEntry* password_confirm = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"password_confirm")); + GtkWidget *assistant=gtk_widget_get_toplevel(w); + GtkLabel* passwordError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); + + if (gtk_entry_get_text_length(password) >= PASSWORD_MIN_SIZE && + g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { + is_password_correct = 1; + gtk_image_set_from_pixbuf(isPasswordOk, ok); + gtk_label_set_text(passwordError, ""); + } + else { + if (gtk_entry_get_text_length(password) < PASSWORD_MIN_SIZE) { + gtk_label_set_text(passwordError, "Password is too short !"); + } + else if (!g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { + gtk_label_set_text(passwordError, "Passwords don't match !"); + } + is_password_correct = 0; + gtk_image_set_from_pixbuf(isPasswordOk, notok); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, + is_account_information_correct(w)>0); +} + +void* check_username_availability(void* w) { + GtkWidget *assistant=gtk_widget_get_toplevel(GTK_WIDGET(w)); + GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); + GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"usernameOk")); + GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); + + LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); + linphone_account_creator_set_username(creator, gtk_entry_get_text(username)); + + if (g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { + int account_existing = linphone_account_creator_test_existence(creator); + if (account_existing == 0) { + is_username_available = 1; + gtk_image_set_from_pixbuf(isUsernameOk, ok); + gtk_label_set_text(usernameError, ""); + } + else { + gtk_label_set_text(usernameError, "Username is already in use !"); + is_username_available = 0; + gtk_image_set_from_pixbuf(isUsernameOk, notok); + } + } + else { + if (gtk_entry_get_text_length(username) < LOGIN_MIN_SIZE) { + gtk_label_set_text(usernameError, "Username is too short"); + } + else if (!g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { + gtk_label_set_text(usernameError, "Unauthorized username"); + } + is_username_available = 0; + gtk_image_set_from_pixbuf(isUsernameOk, notok); + } + + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, + is_account_information_correct(w)>0); + + return NULL; +} + +static void account_username_changed(GtkEntry *entry, GtkWidget *w) { + // Verifying if username choosed is available, and if form is correctly filled, let the user go next page + pthread_t thread; + pthread_create(&thread, NULL, check_username_availability, (void*)w); +} + +static GtkWidget *create_account_information_page() { + GtkWidget *vbox=gtk_table_new(7, 3, FALSE); + + GtkWidget *label=gtk_label_new(_("(*) Required fields")); + GtkWidget *labelUsername=gtk_label_new(_("Username: (*)")); + GtkWidget *isUsernameOk=gtk_image_new_from_pixbuf(notok); + GtkWidget *labelPassword=gtk_label_new(_("Password: (*)")); + GtkWidget *isPasswordOk=gtk_image_new_from_pixbuf(notok); + GtkWidget *labelEmail=gtk_label_new(_("Email: (*)")); + GtkWidget *isEmailOk=gtk_image_new_from_pixbuf(notok); + GtkWidget *labelPassword2=gtk_label_new(_("Confirm your password: (*)")); + GtkWidget *entryUsername=gtk_entry_new(); + GtkWidget *entryPassword=gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); + GtkWidget *entryEmail=gtk_entry_new(); + GtkWidget *entryPassword2=gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword2), FALSE); + GtkWidget *checkNewsletter=gtk_check_button_new_with_label("Keep me informed with linphone updates"); + + GdkColor color; + gdk_color_parse ("red", &color); + GtkWidget *labelError=gtk_label_new(NULL); + gtk_widget_modify_fg(labelError, GTK_STATE_NORMAL, &color); + + GtkWidget *passwordVbox1=gtk_vbox_new(FALSE,2); + GtkWidget *passwordVbox2=gtk_vbox_new(FALSE,2); + gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword, TRUE, FALSE, 2); + gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword2, TRUE, FALSE, 2); + gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword, TRUE, FALSE, 2); + gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword2, TRUE, FALSE, 2); + + gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 3, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelEmail, 0, 1, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryEmail, 1, 2, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), isEmailOk, 2, 3, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), isUsernameOk, 2, 3, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), passwordVbox1, 0, 1, 3, 4); + gtk_table_attach_defaults(GTK_TABLE(vbox), passwordVbox2, 1, 2, 3, 4); + gtk_table_attach_defaults(GTK_TABLE(vbox), isPasswordOk, 2, 3, 3, 4); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelError, 1, 4, 5, 6); + gtk_table_attach_defaults(GTK_TABLE(vbox), checkNewsletter, 0, 3, 6, 7); + + gtk_widget_show_all(vbox); + g_object_set_data(G_OBJECT(vbox),"username",entryUsername); + g_object_set_data(G_OBJECT(vbox),"password",entryPassword); + g_object_set_data(G_OBJECT(vbox),"email",entryEmail); + g_object_set_data(G_OBJECT(vbox),"usernameOk",isUsernameOk); + g_object_set_data(G_OBJECT(vbox),"passwordOk",isPasswordOk); + g_object_set_data(G_OBJECT(vbox),"emailOk",isEmailOk); + g_object_set_data(G_OBJECT(vbox),"password_confirm",entryPassword2); + g_object_set_data(G_OBJECT(vbox),"newsletter",checkNewsletter); + g_object_set_data(G_OBJECT(vbox),"error",labelError); + g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)account_username_changed,vbox); + g_signal_connect(G_OBJECT(entryPassword),"changed",(GCallback)account_password_changed,vbox); + g_signal_connect(G_OBJECT(entryEmail),"changed",(GCallback)account_email_changed,vbox); + g_signal_connect(G_OBJECT(entryPassword2),"changed",(GCallback)account_password_changed,vbox); + return vbox; +} + +/* static GtkWidget *create_confirmation_page(){ GtkWidget *vbox=gtk_vbox_new(FALSE,2); GtkWidget *label=gtk_label_new(NULL); @@ -116,15 +340,15 @@ static GtkWidget *create_confirmation_page(){ gtk_widget_show_all(vbox); return vbox; } +*/ + +static GtkWidget *create_error_page(){ + GtkWidget *vbox=gtk_table_new(2, 1, FALSE); + GtkWidget *label=gtk_label_new(_("Error, account not validated, username already used or server unreachable.\nPlease go back and try again.")); + + gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); -static GtkWidget *create_creation_page(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(NULL); - GtkWidget *progress=gtk_progress_bar_new(); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), progress, TRUE, TRUE, 2); g_object_set_data(G_OBJECT(vbox),"label",label); - g_object_set_data(G_OBJECT(vbox),"progress",progress); gtk_widget_show_all(vbox); return vbox; } @@ -137,61 +361,135 @@ static GtkWidget *create_finish_page(){ return vbox; } +static GtkWidget *wait_for_activation() { + GtkWidget *vbox=gtk_table_new(2, 1, FALSE); + GtkWidget *label=gtk_label_new(_("Please validate your account by clicking on the link we just sent you by email.\n" + "Then come back here and press Next button.")); + + gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); + + g_object_set_data(G_OBJECT(vbox),"label",label); + gtk_widget_show_all(vbox); + return vbox; +} + +static int is_account_validated(GtkWidget *page) { + LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); + return linphone_account_creator_test_validation(creator); +} + static void linphone_gtk_assistant_closed(GtkWidget *w){ gtk_widget_destroy(w); } +static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page){ + int pagenum=gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); + + if (pagenum == 5) { + gtk_assistant_commit(GTK_ASSISTANT(assistant)); + } else if (pagenum == gtk_assistant_get_n_pages(GTK_ASSISTANT(assistant)) - 1) { + // Saving the account and making it default + LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); + LinphoneProxyConfig *cfg=linphone_proxy_config_new(); + linphone_proxy_config_set_identity(cfg, creator->username); + linphone_proxy_config_set_server_addr(cfg, creator->domain); + linphone_proxy_config_set_route(cfg, creator->route); + linphone_proxy_config_expires(cfg, 3600); + linphone_proxy_config_enable_publish(cfg, FALSE); + linphone_proxy_config_enable_register(cfg, TRUE); + + gchar *username = creator->username + 4; + const gchar *needle = "@"; + username = g_strndup(username, (g_strrstr(username, needle) - username)); + gchar domain[128]; + g_snprintf(domain, sizeof(domain), "\"%s\"", creator->domain + 4); + LinphoneAuthInfo *info=linphone_auth_info_new(username, username, creator->password, NULL, domain); + linphone_core_add_auth_info(linphone_gtk_get_core(),info); + + if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) + return; + + linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg); + linphone_gtk_load_identities(); + + // If account created on sip.linphone.org, we configure linphone to use TLS by default + g_warning("Domain : %s", creator->domain); + if (strcmp(creator->domain, "sip:sip.linphone.org") == 0) { + LCSipTransports tr; + LinphoneCore* lc = linphone_gtk_get_core(); + linphone_core_get_sip_transports(lc,&tr); + tr.tls_port = tr.udp_port + tr.tcp_port + tr.tls_port; + tr.udp_port = 0; + tr.tcp_port = 0; + linphone_core_set_sip_transports(lc,&tr); + } + } +} + static int linphone_gtk_assistant_forward(int curpage, gpointer data){ GtkWidget *w=(GtkWidget*)data; GtkWidget *box=gtk_assistant_get_nth_page(GTK_ASSISTANT(w),curpage); if (curpage==1){ GtkWidget *create_button=(GtkWidget*)g_object_get_data(G_OBJECT(box),"create_account"); - if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(create_button))){ - g_error("Not implemented yet..."); + GtkWidget *setup_linphone_account=(GtkWidget*)g_object_get_data(G_OBJECT(box),"setup_linphone_account"); + GtkWidget *setup_account=(GtkWidget*)g_object_get_data(G_OBJECT(box),"setup_account"); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(create_button))) { + curpage += 3; // Going to P33 } - }else if (curpage==2){ + else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_linphone_account))) { + curpage += 2; // Going to P32 + } + else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_account))) { + curpage += 1; // Going to P31 + } + } + else if (curpage == 2) { // Account's informations entered LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - linphone_account_creator_set_username(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); - } - return curpage+1; -} + gchar identity[128]; + g_snprintf(identity, sizeof(identity), "sip:%s@%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username"))), gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); -static void linphone_gtk_assistant_apply(GtkWidget *w){ - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(w); - GtkWidget *page=gtk_assistant_get_nth_page(GTK_ASSISTANT(w),gtk_assistant_get_current_page(GTK_ASSISTANT(w))); - GtkWidget *progress=(GtkWidget*)g_object_get_data(G_OBJECT(page),"progress"); - LinphoneProxyConfig *res; - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Please wait...")); - linphone_core_set_waiting_callback(linphone_gtk_get_core(),progress_bar_update,progress); - res=linphone_account_creator_validate(creator); - if (res){ - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Ok !")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),page,TRUE); - }else{ - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Communication problem, please try again later.")); - } - linphone_core_set_waiting_callback(linphone_gtk_get_core(),linphone_gtk_wait,NULL); - if (res) linphone_core_add_proxy_config(linphone_gtk_get_core(),res); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),page,TRUE); -} + gchar proxy[128]; + g_snprintf(proxy, sizeof(proxy), "sip:%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); -static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page){ - int pagenum=gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); - if (pagenum==3){ - check_username(page); - }else if (pagenum==4){ - GtkWidget *label=(GtkWidget*)g_object_get_data(G_OBJECT(page),"label"); - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); - gchar *text=g_strdup_printf("You have choosen '%s' as username.\nDo you confirm the creation of the account ?",linphone_account_creator_get_username(creator)); - gtk_label_set_text(GTK_LABEL(label),text); - g_free(text); - }else if (pagenum==5){ - GtkWidget *label=(GtkWidget*)g_object_get_data(G_OBJECT(page),"label"); - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); - gchar *text=g_strdup_printf("Account creation in progress for '%s'",linphone_account_creator_get_username(creator)); - gtk_label_set_text(GTK_LABEL(label),text); - g_free(text); + linphone_account_creator_set_username(c, identity); + linphone_account_creator_set_domain(c, proxy); + linphone_account_creator_set_route(c, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"proxy")))); + linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); + curpage = gtk_assistant_get_n_pages(GTK_ASSISTANT(w)) - 1; // Going to the last page } + else if (curpage == 3) { // Linphone Account's informations entered + LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); + gchar identity[128]; + g_snprintf(identity, sizeof(identity), "sip:%s@sip.linphone.org", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); + linphone_account_creator_set_username(c, identity); + linphone_account_creator_set_domain(c, "sip:sip.linphone.org"); + linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); + curpage = gtk_assistant_get_n_pages(GTK_ASSISTANT(w)) - 1; // Going to the last page + } + else if (curpage == 4) { // Password & Email entered + LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); + linphone_account_creator_set_username(c, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); + linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); + linphone_account_creator_set_email(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"email")))); + linphone_account_creator_set_suscribe(c,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(box),"newsletter")))); + if (create_account(w) == 1) { + curpage += 1; + } else { // Error when attempting to create the account + curpage += 2; + } + } + else if (curpage == 5) { // Waiting for account validation + if (is_account_validated(w) == 1) { + curpage += 2; // Going to the last page + } else { + curpage += 1; + } + } + else { + curpage += 1; + } + return curpage; } static LinphoneAccountCreator * linphone_gtk_assistant_init(GtkWidget *w){ @@ -208,18 +506,25 @@ static LinphoneAccountCreator * linphone_gtk_assistant_init(GtkWidget *w){ return NULL; } -LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w){ +static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w){ return (LinphoneAccountCreator*)g_object_get_data(G_OBJECT(w),"creator"); } GtkWidget * linphone_gtk_create_assistant(void){ GtkWidget *w=gtk_assistant_new(); + gtk_window_set_resizable (GTK_WINDOW(w), FALSE); + + ok = create_pixbuf(linphone_gtk_get_ui_config("ok","ok.png")); + notok = create_pixbuf(linphone_gtk_get_ui_config("notok","notok.png")); + GtkWidget *p1=create_intro(); GtkWidget *p2=create_setup_signin_choice(); - GtkWidget *p3=create_username_chooser(); - GtkWidget *checking=create_username_checking_page(); - GtkWidget *confirm=create_confirmation_page(); - GtkWidget *creation=create_creation_page(); + GtkWidget *p31=create_account_informations_page(); + GtkWidget *p32=create_linphone_account_informations_page(); + GtkWidget *p33=create_account_information_page(); + //GtkWidget *confirm=create_confirmation_page(); + GtkWidget *validate=wait_for_activation(); + GtkWidget *error=create_error_page(); GtkWidget *end=create_finish_page(); linphone_gtk_assistant_init(w); @@ -227,38 +532,50 @@ GtkWidget * linphone_gtk_create_assistant(void){ gtk_assistant_set_page_type(GTK_ASSISTANT(w),p1,GTK_ASSISTANT_PAGE_INTRO); gtk_assistant_set_page_title(GTK_ASSISTANT(w),p1,_("Welcome to the account setup assistant")); gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p1,TRUE); + gtk_assistant_append_page(GTK_ASSISTANT(w),p2); gtk_assistant_set_page_type(GTK_ASSISTANT(w),p2,GTK_ASSISTANT_PAGE_CONTENT); gtk_assistant_set_page_title(GTK_ASSISTANT(w),p2,_("Account setup assistant")); gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p2,TRUE); - gtk_assistant_append_page(GTK_ASSISTANT(w),p3); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p3,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p3,_("Choosing a username")); - - gtk_assistant_append_page(GTK_ASSISTANT(w),checking); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),checking,GTK_ASSISTANT_PAGE_PROGRESS); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),checking,_("Verifying")); - - gtk_assistant_append_page(GTK_ASSISTANT(w),confirm); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),confirm,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),confirm,_("Confirmation")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),confirm,TRUE); - gtk_assistant_append_page(GTK_ASSISTANT(w),creation); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),creation,GTK_ASSISTANT_PAGE_PROGRESS); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),creation,_("Creating your account")); + gtk_assistant_append_page(GTK_ASSISTANT(w),p31); + gtk_assistant_set_page_type(GTK_ASSISTANT(w),p31,GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p31,FALSE); + gtk_assistant_set_page_title(GTK_ASSISTANT(w),p31,_("Configure your account (step 1/1)")); + + gtk_assistant_append_page(GTK_ASSISTANT(w),p32); + gtk_assistant_set_page_type(GTK_ASSISTANT(w),p32,GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p32,FALSE); + gtk_assistant_set_page_title(GTK_ASSISTANT(w),p32,_("Enter your sip username (step 1/1)")); + + gtk_assistant_append_page(GTK_ASSISTANT(w),p33); + gtk_assistant_set_page_type(GTK_ASSISTANT(w),p33,GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_title(GTK_ASSISTANT(w),p33,_("Enter account information (step 1/2)")); + + /*gtk_assistant_append_page(GTK_ASSISTANT(w),confirm); + gtk_assistant_set_page_type(GTK_ASSISTANT(w),confirm,GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_title(GTK_ASSISTANT(w),confirm,_("Confirmation (step 2/2)")); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w),confirm,TRUE);*/ + + gtk_assistant_append_page(GTK_ASSISTANT(w),validate); + gtk_assistant_set_page_type(GTK_ASSISTANT(w),validate,GTK_ASSISTANT_PAGE_CONTENT); + gtk_assistant_set_page_title(GTK_ASSISTANT(w),validate,_("Validation (step 2/2)")); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w),validate,TRUE); + + gtk_assistant_append_page(GTK_ASSISTANT(w),error); + gtk_assistant_set_page_type(GTK_ASSISTANT(w),error,GTK_ASSISTANT_PAGE_CONTENT); + gtk_assistant_set_page_title(GTK_ASSISTANT(w),error,_("Error")); gtk_assistant_append_page(GTK_ASSISTANT(w),end); gtk_assistant_set_page_type(GTK_ASSISTANT(w),end,GTK_ASSISTANT_PAGE_SUMMARY); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),end,_("Now ready !")); - + gtk_assistant_set_page_title(GTK_ASSISTANT(w),end,_("Terminating")); + gtk_assistant_set_forward_page_func(GTK_ASSISTANT(w),linphone_gtk_assistant_forward,w,NULL); g_signal_connect(G_OBJECT(w),"close",(GCallback)linphone_gtk_assistant_closed,NULL); g_signal_connect(G_OBJECT(w),"cancel",(GCallback)linphone_gtk_assistant_closed,NULL); - g_signal_connect(G_OBJECT(w),"apply",(GCallback)linphone_gtk_assistant_apply,NULL); g_signal_connect(G_OBJECT(w),"prepare",(GCallback)linphone_gtk_assistant_prepare,NULL); + gtk_widget_show(w); - + return w; } - diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am index 60194fcd8..4e7c56ed6 100644 --- a/pixmaps/Makefile.am +++ b/pixmaps/Makefile.am @@ -14,6 +14,8 @@ status-offline.png \ contact-orange.png dialer-orange.png history-orange.png\ startcall-green.png stopcall-red.png addcall-green.png linphone.icns \ contact_starred.png contact_unstarred.png \ -speaker.png +speaker.png \ +ok.png \ +notok.png EXTRA_DIST=$(pixmap_DATA) diff --git a/pixmaps/notok.png b/pixmaps/notok.png new file mode 100644 index 000000000..84813bc2d Binary files /dev/null and b/pixmaps/notok.png differ diff --git a/pixmaps/ok.png b/pixmaps/ok.png new file mode 100644 index 000000000..769986fb7 Binary files /dev/null and b/pixmaps/ok.png differ