From c9db3492bc64b056c2d46df88bd1cf84d64b4c8a Mon Sep 17 00:00:00 2001
From: smorlat <smorlat@3f6dc0c8-ddfe-455d-9043-3cd528dc4637>
Date: Thu, 30 Apr 2009 20:46:14 +0000
Subject: [PATCH] work in progress for setup wizard.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@456 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
---
 linphone/NEWS                    |  2 +
 linphone/coreapi/linphonecore.c  | 16 +++---
 linphone/coreapi/linphonecore.h  | 36 +++++++++++---
 linphone/coreapi/private.h       |  9 ++++
 linphone/coreapi/proxy.c         | 45 +++++++++++++++++
 linphone/coreapi/sipsetup.c      |  6 +++
 linphone/coreapi/sipsetup.h      |  2 +
 linphone/gtk-glade/main.c        |  4 +-
 linphone/gtk-glade/setupwizard.c | 84 +++++++++++++++++++++++++++-----
 9 files changed, 177 insertions(+), 27 deletions(-)

diff --git a/linphone/NEWS b/linphone/NEWS
index 29b4cdcabb..68202bbd79 100644
--- a/linphone/NEWS
+++ b/linphone/NEWS
@@ -1,6 +1,8 @@
 linphone-3.1.2 --
 	* make it work with lastest ffmpeg swscale
 	* improve theora packer
+	* update theora default settings to match performance of 1.0 release.
+	* fix a random crash during video resizing on linux with SDL.
 
 linphone-3.1.1 -- April 14, 2009
 	* fix crash when opening property box, in some rare case
diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c
index 01b078e33a..682a5c44fe 100644
--- a/linphone/coreapi/linphonecore.c
+++ b/linphone/coreapi/linphonecore.c
@@ -2309,15 +2309,19 @@ void linphone_core_set_mtu(LinphoneCore *lc, int mtu){
 	}else ms_set_mtu(0);//use mediastreamer2 default value
 }
 
+void linphone_core_set_waiting_callback(LinphoneCore *lc, LinphoneWaitingCallback cb){
+	lc->wait_cb=cb;
+}
+
 void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose){
-	if (lc->vtable.waiting){
-		lc->wait_ctx=lc->vtable.waiting(lc,NULL,LinphoneWaitingStart,purpose,0);
+	if (lc->wait_cb){
+		lc->wait_ctx=lc->wait_cb(lc,NULL,LinphoneWaitingStart,purpose,0);
 	}
 }
 
 void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float progress){
-	if (lc->vtable.waiting){
-		lc->wait_ctx=lc->vtable.waiting(lc,lc->wait_ctx,LinphoneWaitingProgress,purpose,progress);
+	if (lc->wait_cb){
+		lc->wait_ctx=lc->wait_cb(lc,lc->wait_ctx,LinphoneWaitingProgress,purpose,progress);
 	}else{
 #ifdef WIN32
 		Sleep(50000);
@@ -2328,8 +2332,8 @@ void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float
 }
 
 void linphone_core_stop_waiting(LinphoneCore *lc){
-	if (lc->vtable.waiting){
-		lc->wait_ctx=lc->vtable.waiting(lc,lc->wait_ctx,LinphoneWaitingFinished,NULL,0);
+	if (lc->wait_cb){
+		lc->wait_ctx=lc->wait_cb(lc,lc->wait_ctx,LinphoneWaitingFinished,NULL,0);
 	}
 }
 
diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h
index 7b9afc8165..610aa7dcea 100644
--- a/linphone/coreapi/linphonecore.h
+++ b/linphone/coreapi/linphonecore.h
@@ -327,6 +327,22 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon
 void linphone_proxy_config_set_sip_setup(LinphoneProxyConfig *cfg, const char *type);
 SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig *cfg);
 
+typedef struct _LinphoneAccountCreator{
+	struct _LinphoneCore *lc;
+	struct _SipSetupContext *ssctx;
+	char *username;
+	char *password;
+	char *domain;
+	bool_t succeeded;
+}LinphoneAccountCreator;
+
+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);
+int linphone_account_creator_test(LinphoneAccountCreator *obj);
+LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj);
+void linphone_account_creator_destroy(LinphoneAccountCreator *obj);
+
 
 typedef struct _LinphoneAuthInfo
 {
@@ -418,12 +434,6 @@ typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog
 typedef void (*TextMessageReceived)(struct _LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message);
 typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralState *gstate);
 typedef void (*DtmfReceived)(struct _LinphoneCore* lc, int dtmf);
-typedef enum _LinphoneWaitingState{
-	LinphoneWaitingStart,
-	LinphoneWaitingProgress,
-	LinphoneWaitingFinished
-} LinphoneWaitingState;
-typedef void * (*Waiting)(struct _LinphoneCore *lc, void *context, LinphoneWaitingState ws, const char *purpose, float progress);
 
 typedef struct _LinphoneVTable
 {
@@ -446,7 +456,6 @@ typedef struct _LinphoneVTable
 	TextMessageReceived text_received;
 	GeneralStateChange general_state;
 	DtmfReceived dtmf_received;
-	Waiting waiting;
 } LinphoneCoreVTable;
 
 typedef struct _LCCallbackObj
@@ -463,6 +472,14 @@ typedef enum _LinphoneFirewallPolicy{
 	LINPHONE_POLICY_USE_STUN
 } LinphoneFirewallPolicy;
 
+typedef enum _LinphoneWaitingState{
+	LinphoneWaitingStart,
+	LinphoneWaitingProgress,
+	LinphoneWaitingFinished
+} LinphoneWaitingState;
+typedef void * (*LinphoneWaitingCallback)(struct _LinphoneCore *lc, void *context, LinphoneWaitingState ws, const char *purpose, float progress);
+
+
 typedef struct _LinphoneCore
 {
 	LinphoneCoreVTable vtable;
@@ -511,6 +528,7 @@ typedef struct _LinphoneCore
 	gstate_t gstate_power;
 	gstate_t gstate_reg;
 	gstate_t gstate_call;
+	LinphoneWaitingCallback wait_cb;
 	void *wait_ctx;
 	bool_t use_files;
 	bool_t apply_nat_settings;
@@ -762,6 +780,10 @@ The "show" callback is called for the other linphone, causing gui to show up.
 The method returns 0 if an already running linphone was found*/
 int linphone_core_wake_up_possible_already_running_instance(const char *config_file);
 
+/*set a callback for some blocking operations, it takes you informed of the progress of the operation*/
+void linphone_core_set_waiting_callback(LinphoneCore *lc, LinphoneWaitingCallback cb);
+
+
 /*returns the list of registered SipSetup (linphonecore plugins) */
 const MSList * linphone_core_get_sip_setups(LinphoneCore *lc);
 
diff --git a/linphone/coreapi/private.h b/linphone/coreapi/private.h
index 1e641d7f26..6832684255 100644
--- a/linphone/coreapi/private.h
+++ b/linphone/coreapi/private.h
@@ -102,6 +102,15 @@ static inline bool_t bandwidth_is_greater(int bw1, int bw2){
 	else return bw1>=bw2;
 }
 
+static inline void set_string(char **dest, const char *src){
+	if (*dest){
+		ms_free(*dest);
+		*dest=NULL;
+	}
+	if (src)
+		*dest=ms_strdup(src);
+}
+
 #define PAYLOAD_TYPE_ENABLED	PAYLOAD_TYPE_USER_FLAG_0
 void linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyConfig *obj, osip_message_t *orig_request, osip_message_t *last_answer);
 void linphone_process_authentication(LinphoneCore* lc, eXosip_event_t *ev);
diff --git a/linphone/coreapi/proxy.c b/linphone/coreapi/proxy.c
index 1cfb5c20b3..877474a70b 100644
--- a/linphone/coreapi/proxy.c
+++ b/linphone/coreapi/proxy.c
@@ -634,4 +634,49 @@ SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig
 	return cfg->ssctx;
 }
 
+void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username){
+	set_string(&obj->username,username);
+}
+
+void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password){
+	set_string(&obj->password,password);
+}
+
+void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain){
+	set_string(&obj->domain,domain);
+}
+
+int linphone_account_creator_test(LinphoneAccountCreator *obj){
+	SipSetupContext *ssctx=obj->ssctx;
+	char *uri=ms_strdup_printf("%s@%s",obj->username,obj->domain);
+	int err=sip_setup_context_account_exists(ssctx,uri);
+	ms_free(uri);
+	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);
+	ms_free(uri);
+	if (err==0) {
+		obj->succeeded=TRUE;
+		return sip_setup_context_get_proxy_config(ssctx);
+	}
+	return NULL;
+}
+
+void linphone_account_creator_destroy(LinphoneAccountCreator *obj){
+	if (obj->username)
+		ms_free(obj->username);
+	if (obj->password)
+		ms_free(obj->password);
+	if (obj->domain)
+		ms_free(obj->domain);
+	if (!obj->succeeded){
+		linphone_proxy_config_destroy(sip_setup_context_get_proxy_config(obj->ssctx));
+	}
+}
+
+
 
diff --git a/linphone/coreapi/sipsetup.c b/linphone/coreapi/sipsetup.c
index 790474f771..250d71eb3b 100644
--- a/linphone/coreapi/sipsetup.c
+++ b/linphone/coreapi/sipsetup.c
@@ -112,6 +112,12 @@ int sip_setup_context_create_account(SipSetupContext * ctx, const char *uri, con
 	else return -1;
 }
 
+int sip_setup_context_account_exists(SipSetupContext *ctx, const char *uri){
+	if (ctx->funcs->account_exists)
+		return ctx->funcs->account_exists(ctx,uri);
+	return -1;
+}
+
 int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, const char *passwd){
 	osip_from_t *from;
 	osip_from_init(&from);
diff --git a/linphone/coreapi/sipsetup.h b/linphone/coreapi/sipsetup.h
index 6cde352cb2..74ec9cf734 100644
--- a/linphone/coreapi/sipsetup.h
+++ b/linphone/coreapi/sipsetup.h
@@ -75,6 +75,7 @@ struct _SipSetup{
 	unsigned int capabilities;
 	bool_t (*init)(void);
 	void (*init_instance)(SipSetupContext *ctx);
+	int (*account_exists)(SipSetupContext *ctx, const char *uri);
 	int (*create_account)(SipSetupContext *ctx, const char *uri, const char *passwd);
 	int (*login_account)(SipSetupContext *ctx, const char *uri, const char *passwd);
 	int (*get_proxy)(SipSetupContext *ctx, const char *domain, char *proxy, size_t sz);
@@ -103,6 +104,7 @@ void sip_setup_unregister_all(void);
 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_get_capabilities(SipSetupContext *ctx);
 int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, const char *passwd);
diff --git a/linphone/gtk-glade/main.c b/linphone/gtk-glade/main.c
index e842cb21a9..8e9687c63a 100644
--- a/linphone/gtk-glade/main.c
+++ b/linphone/gtk-glade/main.c
@@ -74,8 +74,7 @@ static LinphoneCoreVTable vtable={
 	.display_question=linphone_gtk_display_question,
 	.call_log_updated=linphone_gtk_call_log_updated,
 	.text_received=linphone_gtk_text_received,
-	.general_state=linphone_gtk_general_state,
-	.waiting=linphone_gtk_wait
+	.general_state=linphone_gtk_general_state
 };
 
 static gboolean verbose=0;
@@ -120,6 +119,7 @@ const char *linphone_gtk_get_config_file(){
 static void linphone_gtk_init_liblinphone(const char *file){
 	linphone_core_set_user_agent("Linphone", LINPHONE_VERSION);
 	the_core=linphone_core_new(&vtable,file,NULL);
+	linphone_core_set_waiting_callback(the_core,linphone_gtk_wait);
 }
 
 
diff --git a/linphone/gtk-glade/setupwizard.c b/linphone/gtk-glade/setupwizard.c
index 1546ef036f..01694b9d03 100644
--- a/linphone/gtk-glade/setupwizard.c
+++ b/linphone/gtk-glade/setupwizard.c
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "linphone.h"
 
-GtkWidget *create_intro(){
+static GtkWidget *create_intro(){
 	GtkWidget *vbox=gtk_vbox_new(FALSE,2);
 	GtkWidget *label=gtk_label_new(_("Welcome !\nThis assistant will help you to use a SIP account for your calls."));
 	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2);
@@ -27,7 +27,7 @@ GtkWidget *create_intro(){
 	return vbox;
 }
 
-GtkWidget *create_setup_signin_choice(){
+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"));
@@ -39,7 +39,13 @@ GtkWidget *create_setup_signin_choice(){
 	return vbox;
 }
 
-GtkWidget *create_username_chooser(){
+static void create_username_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);
+}
+
+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:"));
@@ -54,31 +60,78 @@ GtkWidget *create_username_chooser(){
 	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);
 	return vbox;
 }
 
-GtkWidget *create_finish_page(){
+static GtkWidget *create_username_checking_page(){
 	GtkWidget *vbox=gtk_vbox_new(FALSE,2);
-	GtkWidget *label=gtk_label_new(_("Thank you. Your account is now configured and ready for use."));
+	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;
 }
 
-static int next_page_handler(int curpage, gpointer data){
-	return curpage+1;
+static void check_username(GtkWidget *page){
+	GtkWidget *progress=g_object_get_data(G_OBJECT(page),"progress");
+	GtkWidget *label=g_object_get_data(G_OBJECT(page),"label");
+	const char *username=g_object_get_data(G_OBJECT(page),"username");
+	gchar *text=g_strdup_printf(_("Checking if '%s' is available..."),username);
+	gtk_label_set_text(GTK_LABEL(label),text);
+	g_free(text);
+	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),_("Please wait..."));
+}
+
+static GtkWidget *create_finish_page(){
+	GtkWidget *vbox=gtk_vbox_new(FALSE,2);
+	GtkWidget *label=gtk_label_new(_("Thank you. Your account is now configured and ready for use."));
+	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2);
+	gtk_widget_show_all(vbox);
+	return vbox;
 }
 
 static void linphone_gtk_assistant_closed(GtkWidget *w){
 	gtk_widget_destroy(w);
 }
 
+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...");
+		}
+	}else if (curpage==2){
+		GtkWidget *next=gtk_assistant_get_nth_page(GTK_ASSISTANT(w),curpage+1);
+		g_object_set_data(G_OBJECT(next),"username",
+				g_strdup(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))));
+	}
+	return curpage+1;
+}
+
+static void linphone_gtk_assistant_apply(GtkWidget *w){
+	g_message("in apply()");
+}
+
+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);
+	}
+}
+
 GtkWidget * linphone_gtk_create_assistant(void){
 	GtkWidget *w=gtk_assistant_new();
 	GtkWidget *p1=create_intro();
 	GtkWidget *p2=create_setup_signin_choice();
 	GtkWidget *p3=create_username_chooser();
-	GtkWidget *p4=create_finish_page();
+	GtkWidget *checking=create_username_checking_page();
+	GtkWidget *end=create_finish_page();
 	gtk_assistant_append_page(GTK_ASSISTANT(w),p1);
 	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"));
@@ -90,13 +143,20 @@ GtkWidget * linphone_gtk_create_assistant(void){
 	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,_("Account setup assistant - enter your information"));
-	gtk_assistant_append_page(GTK_ASSISTANT(w),p4);
-	gtk_assistant_set_page_type(GTK_ASSISTANT(w),p4,GTK_ASSISTANT_PAGE_SUMMARY);
-	gtk_assistant_set_page_title(GTK_ASSISTANT(w),p4,_("Now ready !"));
 	
-	gtk_assistant_set_forward_page_func(GTK_ASSISTANT(w),next_page_handler,w,NULL);
+	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,_("Account setup assistant - verifying"));
+	
+	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_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;
-- 
GitLab