From 55c25fac4f651fe749f2fd4009bbf1a9ac1a6e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Sun, 9 Aug 2015 21:59:56 +0200 Subject: [PATCH 1/2] Describes the login frame in a separated UI file --- gtk/.directory | 4 + gtk/CMakeLists.txt | 9 +- gtk/Makefile.am | 9 +- gtk/callee_frame.ui | 84 +++ gtk/chat.c | 2 +- gtk/chat_view.ui | 118 ---- gtk/chatroom_frame.ui | 113 ++++ gtk/conf_callee_view.ui | 89 --- gtk/conf_frame.ui | 86 +++ gtk/conf_view.ui | 91 --- gtk/conference.c | 6 +- gtk/in_call_frame.ui | 426 ++++++++++++++ gtk/in_call_view.ui | 431 -------------- gtk/incall_view.c | 2 +- gtk/linphone.h | 4 +- gtk/login_frame.ui | 250 ++++++++ gtk/loginframe.c | 104 ++-- gtk/main.c | 67 +-- gtk/main.ui | 1232 ++++++++++++++++----------------------- po/POTFILES.in | 9 +- 20 files changed, 1562 insertions(+), 1574 deletions(-) create mode 100644 gtk/.directory create mode 100644 gtk/callee_frame.ui delete mode 100644 gtk/chat_view.ui create mode 100644 gtk/chatroom_frame.ui delete mode 100644 gtk/conf_callee_view.ui create mode 100644 gtk/conf_frame.ui delete mode 100644 gtk/conf_view.ui create mode 100644 gtk/in_call_frame.ui delete mode 100644 gtk/in_call_view.ui create mode 100644 gtk/login_frame.ui diff --git a/gtk/.directory b/gtk/.directory new file mode 100644 index 000000000..40f7ba528 --- /dev/null +++ b/gtk/.directory @@ -0,0 +1,4 @@ +[Dolphin] +Timestamp=2015,8,9,21,25,40 +Version=3 +ViewMode=2 diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index fb496386d..9808e441a 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -39,10 +39,11 @@ set(UI_FILES sip_account.ui tunnel_config.ui waiting.ui - chat_view.ui - in_call_view.ui - conf_view.ui - conf_callee_view.ui + chatroom_frame.ui + in_call_frame.ui + conf_frame.ui + callee_frame.ui + login_frame.ui ) set(PIXMAPS stock_people.png) diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 3ee1a1bf8..086d51d61 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -16,10 +16,11 @@ UI_FILES= about.ui \ config-uri.ui \ provisioning-fetch.ui \ audio_assistant.ui \ - chat_view.ui \ - in_call_view.ui \ - conf_view.ui \ - conf_callee_view.ui + chatroom_frame.ui \ + in_call_frame.ui \ + conf_frame.ui \ + callee_frame.ui \ + login_frame.ui PIXMAPS= \ stock_people.png diff --git a/gtk/callee_frame.ui b/gtk/callee_frame.ui new file mode 100644 index 000000000..4ae4d90ef --- /dev/null +++ b/gtk/callee_frame.ui @@ -0,0 +1,84 @@ + + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + 12 + + + True + False + + + True + False + + + True + True + + + False + False + 0 + + + + + False + True + 0 + + + + + True + False + <b>Callee name</b> + True + right + end + + + True + True + 1 + + + + + 90 + 30 + True + False + + + False + True + 2 + + + + + + + + + + + + + diff --git a/gtk/chat.c b/gtk/chat.c index 4a88b810a..3b21d4a35 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -481,7 +481,7 @@ static gboolean copy_uri_into_clipboard_handler(GtkMenuItem *menuitem, gpointer } GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with){ - GtkWidget *chat_view=linphone_gtk_create_widget("chat_view","chatroom_frame"); + GtkWidget *chat_view=linphone_gtk_create_widget("chatroom_frame"); GtkWidget *main_window=linphone_gtk_get_main_window(); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); GtkWidget *text=linphone_gtk_get_widget(chat_view,"textview"); diff --git a/gtk/chat_view.ui b/gtk/chat_view.ui deleted file mode 100644 index b9f1e2213..000000000 --- a/gtk/chat_view.ui +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - False - - - True - False - 0 - none - - - True - False - - - True - True - never - - - True - True - 4 - False - word-char - False - - - - - True - True - 0 - - - - - True - False - - - True - True - - True - False - False - True - True - - - True - True - 0 - - - - - True - True - True - - - True - False - - - True - False - gtk-ok - - - True - True - 0 - - - - - True - False - Send - - - True - True - 7 - 1 - - - - - - - False - False - 1 - - - - - False - False - 1 - - - - - - - - - - - diff --git a/gtk/chatroom_frame.ui b/gtk/chatroom_frame.ui new file mode 100644 index 000000000..8d3b46c4a --- /dev/null +++ b/gtk/chatroom_frame.ui @@ -0,0 +1,113 @@ + + + + + + True + False + 0 + none + + + True + False + + + True + True + never + + + True + True + 4 + False + word-char + False + + + + + True + True + 0 + + + + + True + False + + + True + True + + True + False + False + True + True + + + True + True + 0 + + + + + True + True + True + + + True + False + + + True + False + gtk-ok + + + True + True + 0 + + + + + True + False + Send + + + True + True + 7 + 1 + + + + + + + False + False + 1 + + + + + False + False + 1 + + + + + + + + + diff --git a/gtk/conf_callee_view.ui b/gtk/conf_callee_view.ui deleted file mode 100644 index 4de3ca08c..000000000 --- a/gtk/conf_callee_view.ui +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - False - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 12 - - - True - False - - - True - False - - - True - True - - - False - False - 0 - - - - - False - True - 0 - - - - - True - False - <b>Callee name</b> - True - right - end - - - True - True - 1 - - - - - 90 - 30 - True - False - - - False - True - 2 - - - - - - - - - - - - - - - diff --git a/gtk/conf_frame.ui b/gtk/conf_frame.ui new file mode 100644 index 000000000..1012efa88 --- /dev/null +++ b/gtk/conf_frame.ui @@ -0,0 +1,86 @@ + + + + + + True + False + 0 + none + + + True + False + + + True + False + + + End conference + True + True + True + + + False + False + end + 0 + + + + + True + True + end + 0 + + + + + True + False + + + gtk-media-record + True + True + True + True + + + + False + False + 0 + + + + + True + False + True + char + + + True + True + 1 + + + + + False + False + end + 1 + + + + + + + + + diff --git a/gtk/conf_view.ui b/gtk/conf_view.ui deleted file mode 100644 index 194a94d1e..000000000 --- a/gtk/conf_view.ui +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - False - - - True - False - 0 - none - - - True - False - - - True - False - - - End conference - True - True - True - - - False - False - end - 0 - - - - - True - True - end - 0 - - - - - True - False - - - gtk-media-record - True - True - True - True - - - - False - False - 0 - - - - - True - False - True - char - - - True - True - 1 - - - - - False - False - end - 1 - - - - - - - - - - - diff --git a/gtk/conference.c b/gtk/conference.c index c0b292b51..75a36cbdd 100644 --- a/gtk/conference.c +++ b/gtk/conference.c @@ -81,7 +81,7 @@ static GtkWidget *find_conferencee_from_call(LinphoneCall *call){ static GtkWidget * create_conference_panel(void){ GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *conf_frame=linphone_gtk_create_widget("conf_view","conf_frame"); + GtkWidget *conf_frame=linphone_gtk_create_widget("conf_frame"); GtkWidget *conf_box=linphone_gtk_get_widget(conf_frame,"conf_box"); GtkWidget *button_conf=linphone_gtk_get_widget(conf_frame,"terminate_conf"); GtkWidget *image=create_pixmap("stopcall-small.png"); @@ -94,7 +94,7 @@ static GtkWidget * create_conference_panel(void){ g_object_set_data(G_OBJECT(mw),"conf_frame",(gpointer)conf_frame); box=gtk_vbox_new(FALSE,0); - participant=linphone_gtk_create_widget("conf_callee_view","callee_frame"); + participant=linphone_gtk_create_widget("callee_frame"); gtk_widget_show(participant); gtk_box_set_homogeneous(GTK_BOX(box),TRUE); init_local_participant(participant); @@ -126,7 +126,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call){ const LinphoneAddress *addr=linphone_call_get_remote_address(call); gchar *markup; - participant=linphone_gtk_create_widget("conf_callee_view","callee_frame"); + participant=linphone_gtk_create_widget("callee_frame"); gtk_widget_show(participant); if (linphone_address_get_display_name(addr)!=NULL){ markup=g_strdup_printf("%s",linphone_address_get_display_name(addr)); diff --git a/gtk/in_call_frame.ui b/gtk/in_call_frame.ui new file mode 100644 index 000000000..5721081b6 --- /dev/null +++ b/gtk/in_call_frame.ui @@ -0,0 +1,426 @@ + + + + + + False + cursor + 0.5 + none + + + True + False + 12 + 12 + + + True + False + + + True + False + center + + + True + True + 0 + + + + + True + False + + + + + + False + False + 1 + + + + + False + + + True + False + gtk-dialog-authentication + 1 + + + False + False + 0 + + + + + True + False + gtk-apply + + + False + False + 1 + + + + + True + False + + + True + True + 2 + 2 + + + + + Set verified + True + True + True + + + + False + False + 3 + + + + + False + True + 2 + + + + + True + False + + + True + False + + + True + True + True + True + none + False + vertical + linphone-micro-enabled + + + False + False + 5 + 0 + + + + + True + False + + + False + False + 5 + 1 + + + + + True + False + 10 + 0 + + + + + True + False + + + True + True + True + True + Click here to set the speakers volume + none + False + vertical + linphone-speaker-enabled + + + False + False + 5 + 0 + + + + + True + False + + + False + False + 5 + 1 + + + + + True + False + 10 + 1 + + + + + False + False + 5 + 3 + + + + + False + spread + + + Answer + True + True + True + + + + False + False + 0 + + + + + Decline + True + True + True + + + + False + False + 1 + + + + + False + False + 4 + + + + + False + + + gtk-media-record + True + True + True + Record this call to an audio file + True + + + + False + False + 0 + + + + + True + False + True + char + + + True + True + 1 + + + + + False + False + 5 + + + + + True + False + 2 + 3 + True + + + Video + True + True + True + + + + + Pause + True + True + True + + + + 1 + 2 + + + + + Mute + True + True + True + + + + 2 + 3 + + + + + Transfer + True + True + True + + + 1 + 2 + + + + + Hang up + True + True + True + + + + 1 + 2 + 1 + 2 + + + + + Conference + True + True + True + + + 2 + 3 + 1 + 2 + + + + + False + False + 7 + 6 + + + + + + + + + True + False + True + + + True + False + In call + True + center + + + True + True + 0 + + + + + True + False + Duration + center + + + True + True + 1 + + + + + 90 + 10 + True + False + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK + Call quality rating + + + False + False + 2 + + + + + + diff --git a/gtk/in_call_view.ui b/gtk/in_call_view.ui deleted file mode 100644 index 4fd1c0045..000000000 --- a/gtk/in_call_view.ui +++ /dev/null @@ -1,431 +0,0 @@ - - - - - - False - - - False - cursor - 0.5 - none - - - True - False - 12 - 12 - - - True - False - - - True - False - center - - - True - True - 0 - - - - - True - False - - - - - - False - False - 1 - - - - - False - - - True - False - gtk-dialog-authentication - 1 - - - False - False - 0 - - - - - True - False - gtk-apply - - - False - False - 1 - - - - - True - False - - - True - True - 2 - 2 - - - - - Set verified - True - True - True - - - - False - False - 3 - - - - - False - True - 2 - - - - - True - False - - - True - False - - - True - True - True - True - none - False - vertical - linphone-micro-enabled - - - False - False - 5 - 0 - - - - - True - False - - - False - False - 5 - 1 - - - - - True - False - 10 - 0 - - - - - True - False - - - True - True - True - True - Click here to set the speakers volume - none - False - vertical - linphone-speaker-enabled - - - False - False - 5 - 0 - - - - - True - False - - - False - False - 5 - 1 - - - - - True - False - 10 - 1 - - - - - False - False - 5 - 3 - - - - - False - spread - - - Answer - True - True - True - - - - False - False - 0 - - - - - Decline - True - True - True - - - - False - False - 1 - - - - - False - False - 4 - - - - - False - - - gtk-media-record - True - True - True - Record this call to an audio file - True - - - - False - False - 0 - - - - - True - False - True - char - - - True - True - 1 - - - - - False - False - 5 - - - - - True - False - 2 - 3 - True - - - Video - True - True - True - - - - - Pause - True - True - True - - - - 1 - 2 - - - - - Mute - True - True - True - - - - 2 - 3 - - - - - Transfer - True - True - True - - - 1 - 2 - - - - - Hang up - True - True - True - - - - 1 - 2 - 1 - 2 - - - - - Conference - True - True - True - - - 2 - 3 - 1 - 2 - - - - - False - False - 7 - 6 - - - - - - - - - True - False - True - - - True - False - In call - True - center - - - True - True - 0 - - - - - True - False - Duration - center - - - True - True - 1 - - - - - 90 - 10 - True - False - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK - Call quality rating - - - False - False - 2 - - - - - - - - diff --git a/gtk/incall_view.c b/gtk/incall_view.c index ed9e17d14..5f2f73fc1 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -361,7 +361,7 @@ void linphone_gtk_enable_video_button(LinphoneCall *call, gboolean sensitive, gb } void linphone_gtk_create_in_call_view(LinphoneCall *call){ - GtkWidget *call_view=linphone_gtk_create_widget("in_call_view","in_call_frame"); + GtkWidget *call_view=linphone_gtk_create_widget("in_call_frame"); GtkWidget *main_window=linphone_gtk_get_main_window (); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); static int call_index=1; diff --git a/gtk/linphone.h b/gtk/linphone.h index 77636ca3a..f931f1cf3 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -98,7 +98,7 @@ GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint LINPHONE_PUBLIC void linphone_gtk_destroy_window(GtkWidget *window); LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_window(const char *window_name, GtkWidget *parent); LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); -LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_widget(const char* widget_name); const char *linphone_gtk_message_storage_get_db_file(const char *filename); LINPHONE_PUBLIC void linphone_gtk_show_assistant(GtkWidget* parent); @@ -212,7 +212,7 @@ LINPHONE_PUBLIC void linphone_gtk_in_call_show_video(LinphoneCall *call); LINPHONE_PUBLIC char *linphone_gtk_address(const LinphoneAddress *addr);/*return human readable identifier for a LinphoneAddress */ LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_camera_preview_window(void); -LINPHONE_PUBLIC void linphone_gtk_login_frame_connect_clicked(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_login_frame_connect_clicked(GtkWidget *button, GtkWidget *login_frame); LINPHONE_PUBLIC gboolean linphone_gtk_call_log_reset_missed_call(GtkWidget *w, GdkEvent *event, gpointer user_data); LINPHONE_PUBLIC void linphone_gtk_history_row_activated(GtkWidget *treeview); diff --git a/gtk/login_frame.ui b/gtk/login_frame.ui new file mode 100644 index 000000000..f65229f14 --- /dev/null +++ b/gtk/login_frame.ui @@ -0,0 +1,250 @@ + + + + + + False + 0 + etched-out + + + True + False + 12 + + + True + False + + + True + False + gtk-missing-image + + + True + True + 0 + + + + + True + False + 0 + none + + + True + False + 12 + 12 + + + True + False + 5 + 2 + + + + + + True + False + Username + + + + + True + False + Password + + + 1 + 2 + + + + + False + Internet connection: + + + 3 + 4 + + + + + True + True + + True + False + False + True + True + + + 1 + 2 + + + + + True + True + False + + True + False + False + True + True + + + 1 + 2 + 1 + 2 + + + + + False + 0 + + + + 0 + + + + + 1 + 2 + 3 + 4 + + + + + Automatically log me in + True + True + False + True + + + 1 + 2 + 4 + 5 + + + + + False + UserID + + + 2 + 3 + + + + + True + + True + False + False + True + True + + + 1 + 2 + 2 + 3 + + + + + + + + + True + False + Login information + True + + + + + True + True + 10 + 1 + + + + + True + False + + + gtk-connect + True + True + True + True + + + + False + False + 0 + + + + + + + + True + True + 2 + + + + + + + + + True + False + <b>Welcome!</b> + True + + + + + + + + + + + ADSL + + + Fiber Channel + + + + diff --git a/gtk/loginframe.c b/gtk/loginframe.c index cbe384c42..40748494b 100644 --- a/gtk/loginframe.c +++ b/gtk/loginframe.c @@ -48,47 +48,35 @@ static gboolean do_login_noprompt(LinphoneProxyConfig *cfg){ return FALSE; } -void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login){ - GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *label=linphone_gtk_get_widget(mw,"login_label"); - const LinphoneAuthInfo *ai; +static void linphone_gtk_init_login_frame(GtkWidget *login_frame, LinphoneProxyConfig *cfg) { + gboolean auto_login=linphone_gtk_get_ui_config_int("automatic_login",0); + const char *login_image=linphone_gtk_get_ui_config("login_image","linphone-banner.png"); + GtkWidget *label=linphone_gtk_get_widget(login_frame,"login_label"); + LinphoneCore *lc=linphone_gtk_get_core(); gchar *str; LinphoneAddress *from; - LinphoneCore *lc=linphone_gtk_get_core(); + const LinphoneAuthInfo *ai; const char *passwd=NULL; const char *userid=NULL; - gboolean auto_login=linphone_gtk_get_ui_config_int("automatic_login",0); - - if (auto_login && !disable_auto_login){ - g_timeout_add(250,(GSourceFunc)do_login_noprompt,cfg); - return; + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(login_frame, "automatic_login")),auto_login); + + if (login_image){ + GdkPixbuf *pbuf=create_pixbuf (login_image); + gtk_image_set_from_pixbuf (GTK_IMAGE(linphone_gtk_get_widget(login_frame, "login_image")), pbuf); + g_object_unref(G_OBJECT(pbuf)); } - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"automatic_login")),auto_login); - - { - const char *login_image=linphone_gtk_get_ui_config("login_image","linphone-banner.png"); - if (login_image){ - GdkPixbuf *pbuf=create_pixbuf (login_image); - gtk_image_set_from_pixbuf (GTK_IMAGE(linphone_gtk_get_widget(mw,"login_image")), - pbuf); - g_object_unref(G_OBJECT(pbuf)); - } - } - - gtk_widget_hide(linphone_gtk_get_widget(mw,"disconnect_item")); - gtk_widget_hide(linphone_gtk_get_widget(mw,"main_frame")); - gtk_widget_show(linphone_gtk_get_widget(mw,"login_frame")); + if (linphone_gtk_get_ui_config_int("login_needs_userid",FALSE)){ - gtk_widget_show(linphone_gtk_get_widget(mw,"userid")); - gtk_widget_show(linphone_gtk_get_widget(mw,"login_userid")); + gtk_widget_show(linphone_gtk_get_widget(login_frame,"userid")); + gtk_widget_show(linphone_gtk_get_widget(login_frame,"login_userid")); } - gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),FALSE); + str=g_strdup_printf(_("Please enter login information for %s"),linphone_proxy_config_get_domain(cfg)); gtk_label_set_text(GTK_LABEL(label),str); - g_object_set_data(G_OBJECT(mw),"login_proxy_config",cfg); + g_object_set_data(G_OBJECT(login_frame),"login_proxy_config",cfg); g_free(str); - + from=linphone_address_new(linphone_proxy_config_get_identity(cfg)); if (linphone_address_get_username(from)[0]=='?'){ const char *username=linphone_gtk_get_ui_config ("login_username",NULL); @@ -99,24 +87,55 @@ void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_au ai=linphone_core_find_auth_info(lc,linphone_proxy_config_get_domain(cfg),linphone_address_get_username(from),NULL); /*display the last entered username, if not '?????'*/ if (linphone_address_get_username(from)[0]!='?') - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_username")), + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_username")), linphone_address_get_username(from)); if (ai) { passwd=linphone_auth_info_get_passwd(ai); userid=linphone_auth_info_get_userid(ai); } - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_password")), + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_password")), passwd!=NULL ? passwd : ""); - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_userid")), + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_userid")), userid ? userid : ""); linphone_address_destroy(from); } +void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login){ + GtkWidget *mw=linphone_gtk_get_main_window(); + gboolean auto_login=linphone_gtk_get_ui_config_int("automatic_login",0); + GtkWidget *main_frame = linphone_gtk_get_widget(mw, "main_frame"); + GtkWidget *main_layout = linphone_gtk_get_widget(mw, "main_layout"); + GtkWidget *login_frame; + + if (auto_login && !disable_auto_login){ + g_timeout_add(250,(GSourceFunc)do_login_noprompt,cfg); + return; + } + + login_frame = linphone_gtk_create_widget("login_frame"); + linphone_gtk_init_login_frame(login_frame, cfg); + g_object_set_data_full(G_OBJECT(mw), "main_frame", g_object_ref(main_frame), g_object_unref); + g_object_set_data(G_OBJECT(mw), "login_frame", login_frame); + gtk_container_remove(GTK_CONTAINER(main_layout), main_frame); + gtk_box_pack_start(GTK_BOX(main_layout), login_frame, TRUE, TRUE, 0); + gtk_widget_show(login_frame); + + gtk_widget_hide(linphone_gtk_get_widget(mw,"disconnect_item")); + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),FALSE); +} + void linphone_gtk_exit_login_frame(void){ GtkWidget *mw=linphone_gtk_get_main_window(); - gtk_widget_show(linphone_gtk_get_widget(mw,"main_frame")); - gtk_widget_hide(linphone_gtk_get_widget(mw,"login_frame")); + GtkWidget *main_layout = linphone_gtk_get_widget(mw, "main_layout"); + GtkWidget *main_frame = GTK_WIDGET(g_object_get_data(G_OBJECT(mw), "main_frame")); + GtkWidget *login_frame = GTK_WIDGET(g_object_get_data(G_OBJECT(mw), "login_frame")); + + gtk_container_remove(GTK_CONTAINER(main_layout), login_frame); + gtk_box_pack_start(GTK_BOX(main_layout), main_frame, TRUE, TRUE, 0); + g_object_set_data(G_OBJECT(mw), "login_frame", NULL); + g_object_set_data(G_OBJECT(mw), "main_frame", NULL); + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),TRUE); gtk_widget_show(linphone_gtk_get_widget(mw,"disconnect_item")); } @@ -136,25 +155,24 @@ void linphone_gtk_logout_clicked(void){ -void linphone_gtk_login_frame_connect_clicked(GtkWidget *button){ - GtkWidget *mw=gtk_widget_get_toplevel(button); +void linphone_gtk_login_frame_connect_clicked(GtkWidget *button, GtkWidget *login_frame){ const char *username; const char *password; const char *userid; char *identity; gboolean autologin; - LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(mw),"login_proxy_config"); + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(login_frame),"login_proxy_config"); LinphoneAddress *from; SipSetupContext *ssctx=linphone_proxy_config_get_sip_setup_context(cfg); - username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_username"))); - password=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_password"))); - userid=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_userid"))); + username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_username"))); + password=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_password"))); + userid=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_userid"))); if (username==NULL || username[0]=='\0') return; - autologin=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"automatic_login"))); + autologin=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(login_frame,"automatic_login"))); linphone_gtk_set_ui_config_int("automatic_login",autologin); linphone_gtk_set_ui_config("login_username",username); diff --git a/gtk/main.c b/gtk/main.c index 822f0f5f1..8a2df40d9 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -377,69 +377,47 @@ void linphone_gtk_destroy_window(GtkWidget *widget) { g_object_unref (G_OBJECT (builder)); } -GtkWidget *linphone_gtk_create_window(const char *window_name, GtkWidget *parent){ - GError* error = NULL; - GtkBuilder* builder = gtk_builder_new (); - char path[512]; - GtkWidget *w; - - if (get_ui_file(window_name,path,sizeof(path))==-1) return NULL; - - gtk_builder_set_translation_domain(builder,GETTEXT_PACKAGE); - - if (!gtk_builder_add_from_file (builder, path, &error)){ - g_error("Couldn't load builder file: %s", error->message); - g_error_free (error); - return NULL; - } - w=GTK_WIDGET(gtk_builder_get_object (builder,window_name)); - if (w==NULL){ - g_error("Could not retrieve '%s' window from xml file",window_name); - return NULL; - } - g_object_set_data(G_OBJECT(w), "builder",builder); - gtk_builder_connect_signals(builder,w); - linphone_gtk_configure_window(w,window_name); - if(parent) { -// gtk_window_set_modal(GTK_WINDOW(w), TRUE); - gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(parent)); - gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER_ON_PARENT); - } else { -// gtk_window_set_modal(GTK_WINDOW(w), FALSE); - } - return w; -} - -GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name) { +GtkWidget *linphone_gtk_create_widget(const char *widget_name) { char path[2048]; - GtkWidget *w = NULL; GtkBuilder *builder = gtk_builder_new(); GError *error = NULL; GObject *obj; - if(get_ui_file(filename, path, sizeof(path)) == -1) goto end; + if(get_ui_file(widget_name, path, sizeof(path)) == -1) goto fail; gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE); if(gtk_builder_add_from_file(builder, path, &error) == 0) { g_error("Couldn't load builder file: %s", error->message); g_error_free(error); - goto end; + goto fail; } obj = gtk_builder_get_object(builder, widget_name); if(obj == NULL) { g_error("'%s' widget not found", widget_name); - goto end; + goto fail; } - w = GTK_WIDGET(obj); g_object_set_data_full(obj, "builder", builder, g_object_unref); - gtk_widget_unparent(w); - gtk_builder_connect_signals(builder, w); + gtk_builder_connect_signals(builder, obj); + return GTK_WIDGET(obj); -end: +fail: + g_object_unref(builder); + return NULL; +} + +GtkWidget *linphone_gtk_create_window(const char *window_name, GtkWidget *parent){ + GtkWidget *w = linphone_gtk_create_widget(window_name); + if(w) { + linphone_gtk_configure_window(w,window_name); + if(parent) { + gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(parent)); + gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER_ON_PARENT); + } + } return w; } @@ -593,8 +571,7 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){ if (addr_to_call!=NULL){ /*make sure we are not showing the login screen*/ GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *login_frame=linphone_gtk_get_widget(mw,"login_frame"); - if (!GTK_WIDGET_VISIBLE(login_frame)){ + if (g_object_get_data(G_OBJECT(mw), "login_frame") == NULL){ GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar"); gtk_entry_set_text(GTK_ENTRY(uri_bar),addr_to_call); addr_to_call=NULL; @@ -1149,7 +1126,7 @@ static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm gchar *msg; GtkWidget *mw=linphone_gtk_get_main_window(); - if (mw && GTK_WIDGET_VISIBLE(linphone_gtk_get_widget(mw,"login_frame"))){ + if (mw && g_object_get_data(G_OBJECT(mw), "login_frame") != NULL){ /*don't prompt for authentication when login frame is visible*/ linphone_core_abort_authentication(lc,NULL); return; diff --git a/gtk/main.ui b/gtk/main.ui index 698fe2bf8..567156394 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -8,6 +8,11 @@ False gtk-add + + True + False + gtk-add + True False @@ -18,6 +23,11 @@ False gtk-edit + + True + False + gtk-edit + True False @@ -72,20 +82,6 @@ - - - - - - - - ADSL - - - Fiber Channel - - - True False @@ -98,13 +94,19 @@ Delete gtk-remove + + True + False + Delete + gtk-remove + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 660 450 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -277,245 +279,234 @@ - + True False + 8 - + True False - 8 - + 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 - 0 - none + 5 + 5 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - 5 - + True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - True - - True - False - False - True - True - - - - True - True - 0 - - + True + + True + False + False + True + True + + + True + True + 0 + - - + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP address or phone number: + True + + + + + True + True + 2 + 0 + + + + + True + True + True + + + + False + True + 1 + + + + + True + True + Initiate a new call + + + + False + False + 6 + 2 + + + + + True + True + True + + + + False + True + 3 + + + + + True + True + True + + + + False + True + end + 4 + + + + + + + + + + + False + True + 8 + 0 + + + + + True + True + + + True + False + 4 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK + 0 + Contacts + True + + + False + False + 3 + 0 + + + + + True + True + automatic + automatic + + True - False + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - SIP address or phone number: - True + True + False + 1 + + + + True True - 2 - 0 - - - - - True - True - True - - - - False - True 1 - - True - True - Initiate a new call - - - - False - False - 6 - 2 - - - - - True - True - True - - - - False - True - 3 - - - - - True - True - True - - - - False - True - end - 4 - - - - - - - - - - - False - True - 8 - 0 - - - - - True - True - - + True False - 4 + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True - False - GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK - 0 - Contacts - True + True + True + immediate + add_image1 + 1 + False False - 3 0 - + True True - automatic - automatic - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - False - 1 - - - - - - + True + edit_image1 + - True - True + False + False 1 - + True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - True - True - immediate - add_image - 1 - - - - False - False - 0 - - - - - True - True - True - edit_image - - - - False - False - 1 - - - - - True - True - True - remove_image - - - - False - False - 2 - - + True + True + remove_image1 + False @@ -525,167 +516,167 @@ - False - False + False + False + 2 + + + False + False + + + + + True + True - + + + + + + + True - True + False - - - - - - - + True False + 2 - + True - False - 2 + True + never - + + 350 True True - never + False + + + + + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + False + 0 + none - - 350 + + False + + + True + True + + True + False + False + True + True + + + True + True + 0 + + + + + True + True + True + none + + + + True + False + + + True + False + gtk-find + + + True + True + 0 + + + + + True + False + Search + + + True + True + 1 + + + + + + + False + True + 1 + + + + + + True - True - False - - + False + <b>Add contacts from directory</b> + True - True - True + False + False + 5 0 - + True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - False - 0 - none - - - False - - - True - True - - True - False - False - True - True - - - True - True - 0 - - - - - True - True - True - none - - - - True - False - - - True - False - gtk-find - - - True - True - 0 - - - - - True - False - Search - - - True - True - 1 - - - - - - - False - True - 1 - - - - - - - True - False - <b>Add contacts from directory</b> - True - - + + Add contact + True + True + False False - 5 0 - - - True - False - - - Add contact - True - True - - - - False - False - 0 - - - - - False - False - 1 - - False @@ -693,433 +684,106 @@ 1 - - - True - False - end - - - gtk-clear - True - True - True - True - - - - False - False - 0 - - - - - - - - - - - False - True - 2 - - - - - True - True - 0 - - - - - 1 - - - - - True - False - - - - True - False - gtk-refresh - 1 - - - True - True - 0 - - - - - True - False - 0.49000000953674316 - Recent calls - - - True - True - 1 - - - - - 1 - False - - - - - - - - - - - True - True - - - - - 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 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - model3 - 0 - - - - - 0 - - - - - True - True - 0 - - - - - True - True - True - none - - - - False - True - 5 - 1 - - - - - - - True - False - 5 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - My current identity: - True - - - True - True - 0 - - - - - True - True - True - none - - - - True - True - 1 - - - - - - - False - False - 2 - - - - - True - True - 0 - - - - - False - 0 - etched-out - - - True - False - 12 - - - True - False - - - True - False - gtk-missing-image - - - True - True - 0 - - - - - True - False - 0 - none - - - True - False - 12 - 12 - - - True - False - 5 - 2 - - - - - - True - False - Username - - - - - True - False - Password - - - 1 - 2 - - - - - False - Internet connection: - - - 3 - 4 - - - - - True - True - - False - False - True - True - - - 1 - 2 - - - - - True - True - False - - False - False - True - True - - - 1 - 2 - 1 - 2 - - - - - False - model4 - 0 - - - - 0 - - - - - 1 - 2 - 3 - 4 - - - - - Automatically log me in - True - True - False - True - - - 1 - 2 - 4 - 5 - - - - - False - UserID - - - 2 - 3 - - - - - True - - False - False - True - True - - - 1 - 2 - 2 - 3 - - - - - - - - - True - False - Login information - True - - - - - True - True - 10 - 1 - - - - - True - False - - - gtk-connect - True - True - True - True - False False - 0 + 1 - + + True + False + end + + + gtk-clear + True + True + True + True + + + + False + False + 0 + + + + + + + + + + + False + True + 2 + True True - 2 + 0 + + 1 + + + + + True + False + + + + True + False + gtk-refresh + 1 + + + True + True + 0 + + + + + True + False + 0.49000000953674316 + Recent calls + + + True + True + 1 + + + + + 1 + False + + + + + + + - - - - True - False - <b>Welcome!</b> - True - + + True + True + @@ -1128,6 +792,97 @@ 1 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + False + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + model3 + 0 + + + + + 0 + + + + + True + True + 0 + + + + + True + True + True + none + + + + False + True + 5 + 1 + + + + + + + True + False + 5 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + My current identity: + True + + + True + True + 0 + + + + + True + True + True + none + + + + True + True + 1 + + + + + + + False + False + 2 + + True @@ -1144,6 +899,7 @@ False True + end 2 diff --git a/po/POTFILES.in b/po/POTFILES.in index 150dd4748..ebfa3dff3 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -14,9 +14,6 @@ gtk/incall_view.c gtk/loginframe.c gtk/config-fetching.c gtk/audio_assistant.c -gtk/conf_callee_view.ui -gtk/conf_view.ui -gtk/in_call_view.ui [type: gettext/glade]gtk/main.ui [type: gettext/glade]gtk/about.ui [type: gettext/glade]gtk/contact.ui @@ -35,7 +32,11 @@ gtk/in_call_view.ui [type: gettext/glade]gtk/ldap.ui [type: gettext/glade]gtk/config-uri.ui [type: gettext/glade]gtk/provisioning-fetch.ui -[type: gettext/glade]gtk/chat_view.ui +[type: gettext/glade]gtk/chatroom_frame.ui +[type: gettext/glade]gtk/callee_frame.ui +[type: gettext/glade]gtk/conf_frame.ui +[type: gettext/glade]gtk/in_call_frame.ui +[type: gettext/glade]gtk/login_frame.ui coreapi/linphonecore.c coreapi/misc.c coreapi/presence.c From 4b9bb8f8e915f43ffe54a9e6f87817dc2a15bcde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Mon, 10 Aug 2015 00:05:59 +0200 Subject: [PATCH 2/2] Fixes fopen() calls on NULL paths and likely memory corrupions concerning dirname() missuses --- coreapi/lpconfig.c | 122 ++++++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 39 deletions(-) diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index 921c88997..891097245 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -728,19 +728,30 @@ const char* lp_config_get_default_string(const LpConfig *lpconfig, const char *s return lp_config_get_string(lpconfig, default_section, key, default_value); } -static char *_lp_config_dirname(char *path) { +/* + * WARNING: this function is very dangerous. + * Read carefuly the folowing notices: + * 1. The 'path' parameter may be modify by + * the function. Be care to keep a copy of + * the original string. + * 2. The return pointer may points on a part of + * 'path'. So, be care to not free the string + * pointed by 'path' before the last used of + * the returned pointer. + * 3. Do not feed it after midnight + */ +static const char *_lp_config_dirname(char *path) { #ifdef _MSC_VER char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; + static char dirname[_MAX_DRIVE + _MAX_DIR]; _splitpath(path, drive, dir, fname, ext); - return ms_strdup_printf("%s%s", drive, dir); + snprintf(dirname, sizeof(dirname), "%s%s", drive, dir); + return dirname; #else - char *tmp = ms_strdup(path); - char *dir = ms_strdup(dirname(tmp)); - ms_free(tmp); - return dir; + return dirname(path); #endif } @@ -748,12 +759,18 @@ bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *file if (lpconfig->filename == NULL) { return FALSE; } else { - char *dir = _lp_config_dirname(lpconfig->filename); + char *filename = ms_strdup(lpconfig->filename); + const char *dir = _lp_config_dirname(filename); char *filepath = ms_strdup_printf("%s/%s", dir, filename); char *realfilepath = lp_realpath(filepath, NULL); - FILE *file = fopen(realfilepath, "r"); - ms_free(dir); + FILE *file; + + ms_free(filename); ms_free(filepath); + + if(realfilepath == NULL) return FALSE; + + file = fopen(realfilepath, "r"); ms_free(realfilepath); if (file) { fclose(file); @@ -763,54 +780,81 @@ bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *file } void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data) { + char *dup_config_file = NULL; + const char *dir = NULL; + char *filepath = NULL; + char *realfilepath = NULL; + FILE *file; + if (lpconfig->filename == NULL) return; - if(strlen(data) > 0) { - char *dir = _lp_config_dirname(lpconfig->filename); - char *filepath = ms_strdup_printf("%s/%s", dir, filename); - char *realfilepath = lp_realpath(filepath, NULL); - FILE *file = fopen(realfilepath, "w"); - if(file != NULL) { - fprintf(file, "%s", data); - fclose(file); - } else { - ms_error("Could not open %s for write", realfilepath); - } - ms_free(dir); - ms_free(filepath); - ms_free(realfilepath); - } else { + + if(strlen(data) == 0) { ms_warning("%s has not been created because there is no data to write", filename); + return; } + + dup_config_file = ms_strdup(lpconfig->filename); + dir = _lp_config_dirname(dup_config_file); + filepath = ms_strdup_printf("%s/%s", dir, filename); + realfilepath = lp_realpath(filepath, NULL); + if(realfilepath == NULL) { + ms_error("Could not resolv %s: %s", filepath, strerror(errno)); + goto end; + } + + file = fopen(realfilepath, "w"); + if(file == NULL) { + ms_error("Could not open %s for write", realfilepath); + goto end; + } + + fprintf(file, "%s", data); + fclose(file); + +end: + ms_free(dup_config_file); + ms_free(filepath); + if(realfilepath) ms_free(realfilepath); } int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename, char *data, size_t max_length) { - char *dir; - char *filepath; - FILE *file; - char* realfilepath; + char *dup_config_file = NULL; + const char *dir = NULL; + char *filepath = NULL; + FILE *file = NULL; + char* realfilepath = NULL; + if (lpconfig->filename == NULL) return -1; - dir = _lp_config_dirname(lpconfig->filename); + + dup_config_file = ms_strdup(lpconfig->filename); + dir = _lp_config_dirname(dup_config_file); filepath = ms_strdup_printf("%s/%s", dir, filename); realfilepath = lp_realpath(filepath, NULL); + if(realfilepath == NULL) { + ms_error("Could not resolv %s: %s", filepath, strerror(errno)); + goto err; + } + file = fopen(realfilepath, "r"); - if(file != NULL) { - if(fread(data, 1, max_length, file)<=0) { - ms_error("%s could not be loaded. %s", realfilepath, strerror(errno)); - goto err; - } - fclose(file); - } else { + if(file == NULL) { ms_error("Could not open %s for read. %s", realfilepath, strerror(errno)); goto err; } - ms_free(dir); + + if(fread(data, 1, max_length, file)<=0) { + ms_error("%s could not be loaded. %s", realfilepath, strerror(errno)); + goto err; + } + fclose(file); + + ms_free(dup_config_file); ms_free(filepath); ms_free(realfilepath); return 0; err: - ms_free(dir); ms_free(filepath); - ms_free(realfilepath); + ms_free(filepath); + if(realfilepath) ms_free(realfilepath); return -1; }