diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 04fa603b92..f282e91f18 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -180,6 +180,7 @@ set(viewer_SOURCE_FILES
fspanelclassified.cpp
fspanelcontactsets.cpp
fspanelimcontrolpanel.cpp
+ fspanellogin.cpp
fspanelprefs.cpp
fspanelprofile.cpp
fspanelprofileclassifieds.cpp
@@ -905,6 +906,7 @@ set(viewer_HEADER_FILES
fspanelcontactsets.h
fspanelclassified.h
fspanelimcontrolpanel.h
+ fspanellogin.h
fspanelprefs.h
fspanelprofile.h
fspanelprofileclassifieds.h
diff --git a/indra/newview/fspanellogin.cpp b/indra/newview/fspanellogin.cpp
new file mode 100644
index 0000000000..a0f8e03adf
--- /dev/null
+++ b/indra/newview/fspanellogin.cpp
@@ -0,0 +1,1488 @@
+/**
+ * @file fspanellogin.cpp
+ * @brief Login dialog and logo display
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Original file: llpanellogin.cpp
+
+#include "llviewerprecompiledheaders.h"
+
+#include "fspanellogin.h"
+#include "lllayoutstack.h"
+
+#include "indra_constants.h" // for key and mask constants
+#include "llfloaterreg.h"
+#include "llfontgl.h"
+#include "llmd5.h"
+#include "v4color.h"
+
+#include "llappviewer.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcommandhandler.h" // for secondlife:///app/login/
+#include "llcombobox.h"
+#include "llcurl.h"
+#include "llviewercontrol.h"
+#include "llfloaterpreference.h"
+#include "llfocusmgr.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llsecapi.h"
+#include "llstartup.h"
+#include "lltextbox.h"
+#include "llui.h"
+#include "lluiconstants.h"
+#include "llslurl.h"
+#include "llversioninfo.h"
+#include "llviewerhelp.h"
+#include "llviewertexturelist.h"
+#include "llviewermenu.h" // for handle_preferences()
+#include "llviewernetwork.h"
+#include "llviewerwindow.h" // to link into child list
+#include "lluictrlfactory.h"
+#include "llhttpclient.h"
+#include "llweb.h"
+#include "llmediactrl.h"
+#include "llrootview.h"
+
+#include "llfloatertos.h"
+#include "lltrans.h"
+#include "llglheaders.h"
+#include "llpanelloginlistener.h"
+
+#include "fsdata.h"
+
+#if LL_WINDOWS
+#pragma warning(disable: 4355) // 'this' used in initializer list
+#endif // LL_WINDOWS
+
+#include "llsdserialize.h"
+
+const S32 BLACK_BORDER_HEIGHT = 160;
+const S32 MAX_PASSWORD = 16;
+
+FSPanelLogin *FSPanelLogin::sInstance = NULL;
+BOOL FSPanelLogin::sCapslockDidNotification = FALSE;
+
+// We still use this in firestorm...
+// Helper for converting a user name into the canonical "Firstname Lastname" form.
+// For new accounts without a last name "Resident" is added as a last name.
+static std::string canonicalize_username(const std::string& name);
+//
+
+class LLLoginRefreshHandler : public LLCommandHandler
+{
+public:
+ // don't allow from external browsers
+ LLLoginRefreshHandler() : LLCommandHandler("login_refresh", UNTRUSTED_BLOCK) { }
+ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
+ {
+ FSPanelLogin::loadLoginPage();
+ }
+ return true;
+ }
+};
+
+//---------------------------------------------------------------------------
+// Public methods
+//---------------------------------------------------------------------------
+FSPanelLogin::FSPanelLogin(const LLRect &rect,
+ void (*callback)(S32 option, void* user_data),
+ void *cb_data)
+: LLPanel(),
+ mLogoImage(),
+ mCallback(callback),
+ mCallbackData(cb_data)
+ //,mListener(new LLPanelLoginListener(this))
+{
+ setBackgroundVisible(FALSE);
+ setBackgroundOpaque(TRUE);
+
+ mPasswordModified = FALSE;
+ FSPanelLogin::sInstance = this;
+
+ LLView* login_holder = gViewerWindow->getLoginPanelHolder();
+ if (login_holder)
+ {
+ login_holder->addChild(this);
+ }
+
+ // Logo
+ mLogoImage = LLUI::getUIImage("startup_logo");
+
+ buildFromFile( "panel_fs_login.xml");
+
+ reshape(rect.getWidth(), rect.getHeight());
+
+ // Mode Selector
+ LLUICtrl& mode_combo = getChildRef("mode_combo");
+ mode_combo.setValue(gSavedSettings.getString("SessionSettingsFile"));
+ mode_combo.setCommitCallback(boost::bind(&FSPanelLogin::onModeChange, this, getChild("mode_combo")->getValue(), _2));
+ //
+
+ LLLineEditor* password_edit(getChild("password_edit"));
+ password_edit->setKeystrokeCallback(onPassKey, this);
+ // STEAM-14: When user presses Enter with this field in focus, initiate login
+ //password_edit->setCommitCallback(boost::bind(&FSPanelLogin::onClickConnect, this)); // Not needed because of the global fix below
+
+ // change z sort of clickable text to be behind buttons
+ sendChildToBack(getChildView("forgot_password_text"));
+
+ LLComboBox* location_combo = getChild("start_location_combo");
+ updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
+ location_combo->setFocusLostCallback(boost::bind(&FSPanelLogin::onLocationSLURL, this));
+
+ LLComboBox* server_choice_combo = getChild("server_combo");
+ server_choice_combo->setCommitCallback(boost::bind(&FSPanelLogin::onSelectServer, this));
+
+//
+ // Load all of the grids, sorted, and then add a bar and the current grid at the top
+ //server_choice_combo->removeall();
+
+ //std::string current_grid = LLGridManager::getInstance()->getGrid();
+ //std::map known_grids = LLGridManager::getInstance()->getKnownGrids();
+ //for (std::map::iterator grid_choice = known_grids.begin();
+ // grid_choice != known_grids.end();
+ // grid_choice++)
+ //{
+ // if (!grid_choice->first.empty() && current_grid != grid_choice->first)
+ // {
+ // LL_DEBUGS("AppInit")<<"adding "<first<add(grid_choice->second, grid_choice->first);
+ // }
+ //}
+ //server_choice_combo->sortByName();
+ //server_choice_combo->addSeparator(ADD_TOP);
+ //LL_DEBUGS("AppInit")<<"adding current "<add(LLGridManager::getInstance()->getGridLabel(),
+ // current_grid,
+ // ADD_TOP);
+ //server_choice_combo->selectFirstItem();
+ updateServer();
+ if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION)
+ {
+ LLSLURL slurl(gSavedSettings.getString("LoginLocation"));
+ LLStartUp::setStartSLURL(slurl);
+ }
+//
+
+// Moved this down further
+ //LLSLURL start_slurl(LLStartUp::getStartSLURL());
+ //if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ?
+ //{
+ // no, so get the preference setting
+ // std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
+ // LL_INFOS("AppInit") << "default LoginLocation '" << defaultStartLocation << "'" << LL_ENDL;
+ // LLSLURL defaultStart(defaultStartLocation);
+ // if ( defaultStart.isSpatial() )
+ // {
+ // LLStartUp::setStartSLURL(defaultStart);
+ // }
+ // else
+ // {
+ // LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<
+
+ childSetAction("remove_user_btn", onClickRemove, this); // Remove credentials
+ childSetAction("connect_btn", onClickConnect, this);
+
+ getChild("login")->setDefaultBtn(findChild("connect_btn")); // manualy find the button with findChild() as setDefaultButton() uses getChild(), which cant be used in a ctor as it makes a dummy instead
+ getChild("start_location_panel")->setDefaultBtn(findChild("connect_btn")); // Yeah, do that here too.
+
+ std::string channel = LLVersionInfo::getChannel();
+ std::string version = llformat("%s (%d)",
+ LLVersionInfo::getShortVersion().c_str(),
+ LLVersionInfo::getBuild());
+
+ LLTextBox* forgot_password_text = getChild("forgot_password_text");
+ forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
+
+ LLTextBox* create_new_account_text = getChild("create_new_account_text");
+ create_new_account_text->setClickedCallback(onClickNewAccount, NULL);
+
+ // We don't have the help link
+ //LLTextBox* need_help_text = getChild("login_help");
+ //need_help_text->setClickedCallback(onClickHelp, NULL);
+ //
+
+// Grid Manager Help link
+ LLTextBox* grid_mgr_help_text = getChild("grid_login_text");
+ grid_mgr_help_text->setClickedCallback(onClickGridMgrHelp, NULL);
+//
+
+ // get the web browser control
+ LLMediaCtrl* web_browser = getChild("login_html");
+ web_browser->addObserver(this);
+
+ reshapeBrowser();
+
+ // Moved below
+ //loadLoginPage();
+
+ // Show last logged in user favorites in "Start at" combo.
+/// We don't use addUsersWithFavoritesToUsername() in Firestorm. We use addUsersToCombo() when setting
+/// visibility.
+ //addUsersWithFavoritesToUsername();
+//
+ LLComboBox* username_combo(getChild("username_combo"));
+ //username_combo->setTextChangedCallback(boost::bind(&FSPanelLogin::addFavoritesToStartLocation, this));
+// Don't automatically connect on selection!
+ //username_combo->setCommitCallback(boost::bind(&FSPanelLogin::onClickConnect, this));
+ username_combo->setCommitCallback(boost::bind(&FSPanelLogin::onSelectUser, this));
+
+ LLSLURL start_slurl(LLStartUp::getStartSLURL());
+ if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ?
+ {
+ // no, so get the preference setting
+ std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
+ LL_INFOS("AppInit") << "default LoginLocation '" << defaultStartLocation << "'" << LL_ENDL;
+ LLSLURL defaultStart(defaultStartLocation);
+ if ( defaultStart.isSpatial() )
+ {
+ LLStartUp::setStartSLURL(defaultStart);
+ }
+ else
+ {
+ LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<
+}
+
+// We don't use addUsersWithFavoritesToUsername() in Firestorm. We use addUsersToCombo().
+#if 0
+void FSPanelLogin::addUsersWithFavoritesToUsername()
+{
+ LLComboBox* combo = getChild("username_combo");
+ if (!combo) return;
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
+ std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename);
+ if (!file.is_open())
+ {
+ file.open(old_filename);
+ if (!file.is_open()) return;
+ }
+ LLSDSerialize::fromXML(fav_llsd, file);
+ for (LLSD::map_const_iterator iter = fav_llsd.beginMap();
+ iter != fav_llsd.endMap(); ++iter)
+ {
+ combo->add(iter->first);
+ }
+}
+#endif
+//
+
+void FSPanelLogin::addFavoritesToStartLocation()
+{
+ // Clear the combo.
+ LLComboBox* combo = getChild("start_location_combo");
+ if (!combo) return;
+ int num_items = combo->getItemCount();
+ for (int i = num_items - 1; i > 2; i--)
+ {
+ combo->remove(i);
+ }
+
+ // Load favorites into the combo.
+ std::string user_defined_name = getChild("username_combo")->getSimple();
+// FIRE-10122 - User@grid stored_favorites.xml
+ //std::replace(user_defined_name.begin(), user_defined_name.end(), '.', ' ');
+ //std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
+ //std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ std::string canonical_user_name = canonicalize_username(user_defined_name);
+ U32 resident_pos = canonical_user_name.find("Resident");
+ if (resident_pos > 0)
+ {
+ canonical_user_name = canonical_user_name.substr(0, resident_pos - 1);
+ }
+ std::string current_grid = getChild("server_combo")->getSimple();
+ std::string current_user = canonical_user_name + " @ " + current_grid;
+ LL_DEBUGS("Favorites") << "Current user: \"" << current_user << "\"" << LL_ENDL;
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+//
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename);
+// FIRE-10122 - User@grid stored_favorites.xml
+ //if (!file.is_open())
+ //{
+ // file.open(old_filename);
+ // if (!file.is_open()) return;
+ //}
+ if (!file.is_open()) return;
+//
+ LLSDSerialize::fromXML(fav_llsd, file);
+ for (LLSD::map_const_iterator iter = fav_llsd.beginMap();
+ iter != fav_llsd.endMap(); ++iter)
+ {
+ // The account name in stored_favorites.xml has Resident last name even if user has
+ // a single word account name, so it can be compared case-insensitive with the
+ // user defined "firstname lastname".
+// FIRE-10122 - User@grid stored_favorites.xml
+ //S32 res = LLStringUtil::compareInsensitive(user_defined_name, iter->first);
+ S32 res = LLStringUtil::compareInsensitive(current_user, iter->first);
+//
+ if (res != 0)
+ {
+ LL_DEBUGS() << "Skipping favorites for " << iter->first << LL_ENDL;
+ continue;
+ }
+
+ combo->addSeparator();
+ LL_DEBUGS() << "Loading favorites for " << iter->first << LL_ENDL;
+ LLSD user_llsd = iter->second;
+ for (LLSD::array_const_iterator iter1 = user_llsd.beginArray();
+ iter1 != user_llsd.endArray(); ++iter1)
+ {
+ std::string label = (*iter1)["name"].asString();
+ std::string value = (*iter1)["slurl"].asString();
+ if(label != "" && value != "")
+ {
+ combo->add(label, value);
+ }
+ }
+ break;
+ }
+}
+
+// force the size to be correct (XML doesn't seem to be sufficient to do this)
+// (with some padding so the other login screen doesn't show through)
+void FSPanelLogin::reshapeBrowser()
+{
+ LLMediaCtrl* web_browser = getChild("login_html");
+ LLRect rect = gViewerWindow->getWindowRectScaled();
+ LLRect html_rect;
+ html_rect.setCenterAndSize(
+ rect.getCenterX() - 2, rect.getCenterY() + 40,
+ rect.getWidth() + 6, rect.getHeight() - 78 );
+ web_browser->setRect( html_rect );
+ web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE );
+ reshape( rect.getWidth(), rect.getHeight(), 1 );
+}
+
+FSPanelLogin::~FSPanelLogin()
+{
+ FSPanelLogin::sInstance = NULL;
+
+ // Controls having keyboard focus by default
+ // must reset it on destroy. (EXT-2748)
+ gFocusMgr.setDefaultKeyboardFocus(NULL);
+}
+
+// virtual
+void FSPanelLogin::draw()
+{
+ gGL.pushMatrix();
+ {
+ F32 image_aspect = 1.333333f;
+ F32 view_aspect = (F32)getRect().getWidth() / (F32)getRect().getHeight();
+ // stretch image to maintain aspect ratio
+ if (image_aspect > view_aspect)
+ {
+ gGL.translatef(-0.5f * (image_aspect / view_aspect - 1.f) * getRect().getWidth(), 0.f, 0.f);
+ gGL.scalef(image_aspect / view_aspect, 1.f, 1.f);
+ }
+
+ S32 width = getRect().getWidth();
+ S32 height = getRect().getHeight();
+
+ if (getChild("login_widgets")->getVisible())
+ {
+ // draw a background box in black
+ gl_rect_2d( 0, height - 264, width, 264, LLColor4::black );
+ // draw the bottom part of the background image
+ // just the blue background to the native client UI
+ mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
+ };
+ }
+ gGL.popMatrix();
+
+ LLPanel::draw();
+}
+
+// virtual
+BOOL FSPanelLogin::handleKeyHere(KEY key, MASK mask)
+{
+ if ( KEY_F1 == key )
+ {
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(vhelp->f1HelpTopic());
+ return TRUE;
+ }
+
+ return LLPanel::handleKeyHere(key, mask);
+}
+
+// virtual
+void FSPanelLogin::setFocus(BOOL b)
+{
+ if(b != hasFocus())
+ {
+ if(b)
+ {
+ FSPanelLogin::giveFocus();
+ }
+ else
+ {
+ LLPanel::setFocus(b);
+ }
+ }
+}
+
+// static
+void FSPanelLogin::giveFocus()
+{
+ if( sInstance )
+ {
+ // Grab focus and move cursor to first blank input field
+ std::string username = sInstance->getChild("username_combo")->getValue().asString();
+ std::string pass = sInstance->getChild("password_edit")->getValue().asString();
+
+ BOOL have_username = !username.empty();
+ BOOL have_pass = !pass.empty();
+
+ LLLineEditor* edit = NULL;
+ LLComboBox* combo = NULL;
+ if (have_username && !have_pass)
+ {
+ // User saved his name but not his password. Move
+ // focus to password field.
+ edit = sInstance->getChild("password_edit");
+ }
+ else
+ {
+ // User doesn't have a name, so start there.
+ combo = sInstance->getChild("username_combo");
+ }
+
+ if (edit)
+ {
+ edit->setFocus(TRUE);
+ edit->selectAll();
+ }
+ else if (combo)
+ {
+ combo->setFocus(TRUE);
+ }
+ }
+}
+
+// static
+void FSPanelLogin::showLoginWidgets()
+{
+ if (sInstance)
+ {
+ // *NOTE: Mani - This may or may not be obselete code.
+ // It seems to be part of the defunct? reg-in-client project.
+ sInstance->getChildView("login_widgets")->setVisible( true);
+ LLMediaCtrl* web_browser = sInstance->getChild("login_html");
+ sInstance->reshapeBrowser();
+ // *TODO: Append all the usual login parameters, like first_login=Y etc.
+ std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
+ web_browser->navigateTo( splash_screen_url, HTTP_CONTENT_TEXT_HTML );
+ LLUICtrl* username_combo = sInstance->getChild("username_combo");
+ username_combo->setFocus(TRUE);
+ }
+}
+
+// static
+void FSPanelLogin::show(const LLRect &rect,
+ void (*callback)(S32 option, void* user_data),
+ void* callback_data)
+{
+ // instance management
+ if (FSPanelLogin::sInstance)
+ {
+ LL_WARNS("AppInit") << "Duplicate instance of login view deleted" << LL_ENDL;
+ // Don't leave bad pointer in gFocusMgr
+ gFocusMgr.setDefaultKeyboardFocus(NULL);
+
+ delete FSPanelLogin::sInstance;
+ }
+
+ new FSPanelLogin(rect, callback, callback_data);
+
+ if( !gFocusMgr.getKeyboardFocus() )
+ {
+ // Grab focus and move cursor to first enabled control
+ sInstance->setFocus(TRUE);
+ }
+
+ // Make sure that focus always goes here (and use the latest sInstance that was just created)
+ gFocusMgr.setDefaultKeyboardFocus(sInstance);
+}
+
+// static
+//
+//void FSPanelLogin::setFields(LLPointer credential,
+// BOOL remember)
+void FSPanelLogin::setFields(LLPointer credential)
+//
+{
+ if (!sInstance)
+ {
+ LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL;
+ return;
+ }
+ LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
+
+ LLSD identifier = credential->getIdentifier();
+ if((std::string)identifier["type"] == "agent")
+ {
+ std::string firstname = identifier["first_name"].asString();
+ std::string lastname = identifier["last_name"].asString();
+ std::string login_id = firstname;
+ if (!lastname.empty() && lastname != "Resident")
+ {
+ // support traditional First Last name SLURLs
+ login_id += " ";
+ login_id += lastname;
+ }
+//
+ //sInstance->getChild("username_combo")->setLabel(login_id);
+ }
+ //else if((std::string)identifier["type"] == "account")
+ //{
+ // sInstance->getChild("username_combo")->setLabel((std::string)identifier["account_name"]);
+ //}
+ //else
+ //{
+ // sInstance->getChild("username_combo")->setLabel(std::string());
+ //}
+ std::string credName = credential->getCredentialName();
+ sInstance->getChild("username_combo")->selectByValue(credName);
+//
+ sInstance->addFavoritesToStartLocation();
+ // if the password exists in the credential, set the password field with
+ // a filler to get some stars
+ LLSD authenticator = credential->getAuthenticator();
+ LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
+ bool remember; //
+ if(authenticator.isMap() &&
+ authenticator.has("secret") &&
+ (authenticator["secret"].asString().size() > 0))
+ {
+
+ // This is a MD5 hex digest of a password.
+ // We don't actually use the password input field,
+ // fill it with MAX_PASSWORD characters so we get a
+ // nice row of asterixes.
+ const std::string filler("123456789!123456");
+ sInstance->getChild("password_edit")->setValue(filler);
+ remember = true; //
+ }
+ else
+ {
+ sInstance->getChild("password_edit")->setValue(std::string());
+ remember = false; //
+ }
+ sInstance->getChild("remember_check")->setValue(remember);
+}
+
+
+// static
+void FSPanelLogin::getFields(LLPointer& credential,
+ BOOL& remember)
+{
+ if (!sInstance)
+ {
+ LL_WARNS() << "Attempted getFields with no login view shown" << LL_ENDL;
+ return;
+ }
+
+ // load the credential so we can pass back the stored password or hash if the user did
+ // not modify the password field.
+
+//
+ //credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ credential = gSecAPIHandler->loadCredential(credentialName());
+//
+
+ LLSD identifier = LLSD::emptyMap();
+ LLSD authenticator = LLSD::emptyMap();
+
+ if(credential.notNull())
+ {
+ authenticator = credential->getAuthenticator();
+ }
+
+ std::string username = sInstance->getChild("username_combo")->getValue().asString();
+ LLStringUtil::trim(username);
+//
+ size_t arobase = username.find("@");
+ if(arobase != std::string::npos)
+ username = username.substr(0, arobase);
+//
+ std::string password = sInstance->getChild("password_edit")->getValue().asString();
+
+ LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
+ // determine if the username is a first/last form or not.
+ size_t separator_index = username.find_first_of(' ');
+ if (separator_index == username.npos
+ && !LLGridManager::getInstance()->isSystemGrid())
+ {
+ LL_INFOS("Credentials", "Authentication") << "account: " << username << LL_ENDL;
+ // single username, so this is a 'clear' identifier
+ identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT;
+ identifier["account_name"] = username;
+
+ if (FSPanelLogin::sInstance->mPasswordModified)
+ {
+ authenticator = LLSD::emptyMap();
+ // password is plaintext
+ authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
+ authenticator["secret"] = password;
+ }
+ }
+ else
+ {
+ // Be lenient in terms of what separators we allow for two-word names
+ // and allow legacy users to login with firstname.lastname
+ // FIRE-15116: Usernames with underscores don't work on OpenSim
+ //separator_index = username.find_first_of(" ._");
+#ifdef OPENSIM
+ if (LLGridManager::getInstance()->isInSecondLife())
+ {
+ separator_index = username.find_first_of(" ._");
+ }
+ else
+ {
+ separator_index = username.find_first_of(" .");
+ }
+#else
+ separator_index = username.find_first_of(" ._");
+#endif
+ //
+ std::string first = username.substr(0, separator_index);
+ std::string last;
+ if (separator_index != username.npos)
+ {
+ last = username.substr(separator_index + 1, username.npos);
+ LLStringUtil::trim(last);
+ }
+ else
+ {
+ // ...on Linden grids, single username users as considered to have
+ // last name "Resident"
+ // *TODO: Make login.cgi support "account_name" like above
+ last = "Resident";
+ }
+
+ if (last.find_first_of(' ') == last.npos)
+ {
+ LL_INFOS("Credentials", "Authentication") << "agent: " << username << LL_ENDL;
+ // traditional firstname / lastname
+ identifier["type"] = CRED_IDENTIFIER_TYPE_AGENT;
+ identifier["first_name"] = first;
+ identifier["last_name"] = last;
+
+ if (FSPanelLogin::sInstance->mPasswordModified)
+ {
+ authenticator = LLSD::emptyMap();
+ authenticator["type"] = CRED_AUTHENTICATOR_TYPE_HASH;
+ authenticator["algorithm"] = "md5";
+ LLMD5 pass((const U8 *)password.c_str());
+ char md5pass[33]; /* Flawfinder: ignore */
+ pass.hex_digest(md5pass);
+ authenticator["secret"] = md5pass;
+ }
+ }
+ }
+//
+ //credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
+ credential = gSecAPIHandler->createCredential(credentialName(), identifier, authenticator);
+//
+ remember = sInstance->getChild("remember_check")->getValue();
+}
+
+
+// static
+BOOL FSPanelLogin::areCredentialFieldsDirty()
+{
+ if (!sInstance)
+ {
+ LL_WARNS() << "Attempted getServer with no login view shown" << LL_ENDL;
+ }
+ else
+ {
+ std::string username = sInstance->getChild("username_combo")->getValue().asString();
+ LLStringUtil::trim(username);
+ std::string password = sInstance->getChild("password_edit")->getValue().asString();
+ LLComboBox* combo = sInstance->getChild("username_combo");
+ if(combo && combo->isDirty())
+ {
+ return true;
+ }
+ LLLineEditor* ctrl = sInstance->getChild("password_edit");
+ if(ctrl && ctrl->isDirty())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+// static
+void FSPanelLogin::updateLocationSelectorsVisibility()
+{
+ if (sInstance)
+ {
+ BOOL show_start = gSavedSettings.getBOOL("ShowStartLocation");
+ sInstance->getChild("start_location_panel")->setVisible(show_start);
+
+ BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid");
+ sInstance->getChild("grid_panel")->setVisible(show_server);
+// Refresh the username combo
+ sInstance->addUsersToCombo(show_server);
+//
+ }
+}
+
+// static - called from LLStartUp::setStartSLURL
+void FSPanelLogin::onUpdateStartSLURL(const LLSLURL& new_start_slurl)
+{
+ if (!sInstance) return;
+
+ LL_DEBUGS("AppInit")<getChild("start_location_combo");
+ /*
+ * Determine whether or not the new_start_slurl modifies the grid.
+ *
+ * Note that some forms that could be in the slurl are grid-agnostic.,
+ * such as "home". Other forms, such as
+ * https://grid.example.com/region/Party%20Town/20/30/5
+ * specify a particular grid; in those cases we want to change the grid
+ * and the grid selector to match the new value.
+ */
+ enum LLSLURL::SLURL_TYPE new_slurl_type = new_start_slurl.getType();
+ switch ( new_slurl_type )
+ {
+ case LLSLURL::LOCATION:
+ {
+ std::string slurl_grid = LLGridManager::getInstance()->getGrid(new_start_slurl.getGrid());
+ if ( ! slurl_grid.empty() ) // is that a valid grid?
+ {
+ if ( slurl_grid != LLGridManager::getInstance()->getGrid() ) // new grid?
+ {
+ // the slurl changes the grid, so update everything to match
+ LLGridManager::getInstance()->setGridChoice(slurl_grid);
+
+ // update the grid selector to match the slurl
+ LLComboBox* server_combo = sInstance->getChild("server_combo");
+ std::string server_label(LLGridManager::getInstance()->getGridLabel(slurl_grid));
+ server_combo->setSimple(server_label);
+
+ updateServer(); // to change the links and splash screen
+ }
+ location_combo->setTextEntry(new_start_slurl.getLocationString());
+ }
+ else
+ {
+ // the grid specified by the slurl is not known
+ LLNotificationsUtil::add("InvalidLocationSLURL");
+ LL_WARNS("AppInit")<<"invalid LoginLocation:"<setTextEntry(LLStringUtil::null);
+ }
+ }
+ break;
+
+ case LLSLURL::HOME_LOCATION:
+ location_combo->setCurrentByIndex(1); // home location
+ break;
+
+ case LLSLURL::LAST_LOCATION:
+ location_combo->setCurrentByIndex(0); // last location
+ break;
+
+ default:
+ LL_WARNS("AppInit")<<"invalid login slurl, using home"<setCurrentByIndex(1); // home location
+ break;
+ }
+}
+
+void FSPanelLogin::setLocation(const LLSLURL& slurl)
+{
+ LL_DEBUGS("AppInit")<<"setting Location "<getParent()->removeChild( FSPanelLogin::sInstance );
+
+ delete sInstance;
+ sInstance = NULL;
+ }
+}
+
+// static
+void FSPanelLogin::setAlwaysRefresh(bool refresh)
+{
+ if (sInstance && LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
+ {
+ LLMediaCtrl* web_browser = sInstance->getChild("login_html");
+
+ if (web_browser)
+ {
+ web_browser->setAlwaysRefresh(refresh);
+ }
+ }
+}
+
+
+
+void FSPanelLogin::loadLoginPage()
+{
+ if (!sInstance) return;
+
+ LLURI login_page = LLURI(LLGridManager::getInstance()->getLoginPage());
+ LLSD params(login_page.queryMap());
+
+ LL_DEBUGS("AppInit") << "login_page: " << login_page << LL_ENDL;
+
+ // Language
+ params["lang"] = LLUI::getLanguage();
+
+ // First Login?
+ if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ {
+ params["firstlogin"] = "TRUE"; // not bool: server expects string TRUE
+ }
+
+ // Channel and Version
+ params["version"] = llformat("%s (%d)",
+ LLVersionInfo::getShortVersion().c_str(),
+ LLVersionInfo::getBuild());
+ params["channel"] = LLVersionInfo::getChannel();
+
+ // Grid
+ params["grid"] = LLGridManager::getInstance()->getGridId();
+
+ // add OS info
+ params["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+
+ // sourceid
+ params["sourceid"] = gSavedSettings.getString("sourceid");
+
+ // Make an LLURI with this augmented info
+ LLURI login_uri(LLURI::buildHTTP(login_page.authority(),
+ login_page.path(),
+ params));
+
+//
+ //gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());
+//
+
+ LLMediaCtrl* web_browser = sInstance->getChild("login_html");
+ if (web_browser->getCurrentNavUrl() != login_uri.asString())
+ {
+ LL_DEBUGS("AppInit") << "loading: " << login_uri << LL_ENDL;
+ web_browser->navigateTo( login_uri.asString(), HTTP_CONTENT_TEXT_HTML );
+ }
+}
+
+void FSPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)
+{
+}
+
+//---------------------------------------------------------------------------
+// Protected methods
+//---------------------------------------------------------------------------
+
+// static
+void FSPanelLogin::onClickConnect(void *)
+{
+ if (sInstance && sInstance->mCallback)
+ {
+ // JC - Make sure the fields all get committed.
+ sInstance->setFocus(FALSE);
+
+ LLComboBox* combo = sInstance->getChild("server_combo");
+ LLSD combo_val = combo->getSelectedValue();
+
+ // the grid definitions may come from a user-supplied grids.xml, so they may not be good
+ LL_DEBUGS("AppInit")<<"grid "<setGridChoice(combo_val.asString());
+ }
+ catch (LLInvalidGridName ex)
+ {
+ LLSD args;
+ args["GRID"] = ex.name();
+ LLNotificationsUtil::add("InvalidGrid", args);
+ return;
+ }
+
+ // The start location SLURL has already been sent to LLStartUp::setStartSLURL
+
+ std::string username = sInstance->getChild("username_combo")->getValue().asString();
+ gSavedSettings.setString("UserLoginInfo", credentialName()); //
+
+// Block release
+ LLSD blocked = FSData::instance().allowedLogin();
+ if (!blocked.isMap()) //hack for testing for an empty LLSD
+ {
+//
+ if(username.empty())
+ {
+ // user must type in something into the username field
+//
+ //LLNotificationsUtil::add("MustHaveAccountToLogIn");
+ LLSD args;
+ args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
+ LLNotificationsUtil::add("MustHaveAccountToLogIn", args);
+//
+ }
+ else
+ {
+ LLPointer cred;
+ BOOL remember;
+ getFields(cred, remember);
+ std::string identifier_type;
+ cred->identifierType(identifier_type);
+ LLSD allowed_credential_types;
+ LLGridManager::getInstance()->getLoginIdentifierTypes(allowed_credential_types);
+
+ // check the typed in credential type against the credential types expected by the server.
+ for(LLSD::array_iterator i = allowed_credential_types.beginArray();
+ i != allowed_credential_types.endArray();
+ i++)
+ {
+
+ if(i->asString() == identifier_type)
+ {
+ // yay correct credential type
+ sInstance->mCallback(0, sInstance->mCallbackData);
+ return;
+ }
+ }
+
+ // Right now, maingrid is the only thing that is picky about
+ // credential format, as it doesn't yet allow account (single username)
+ // format creds. - Rox. James, we wanna fix the message when we change
+ // this.
+ LLNotificationsUtil::add("InvalidCredentialFormat");
+ }
+ }
+// Blocked Release
+ else
+ {
+ LLNotificationsUtil::add("BlockLoginInfo", blocked);
+ }
+//
+ }
+}
+
+// static
+void FSPanelLogin::onClickNewAccount(void*)
+{
+ if (sInstance)
+ {
+//
+#ifdef OPENSIM
+ LLSD grid_info;
+ LLGridManager::getInstance()->getGridData(grid_info);
+
+ if (LLGridManager::getInstance()->isInOpenSim() && grid_info.has(GRID_REGISTER_NEW_ACCOUNT))
+ LLWeb::loadURLInternal(grid_info[GRID_REGISTER_NEW_ACCOUNT]);
+ else
+#endif // OPENSIM
+//
+ LLWeb::loadURLExternal(LLTrans::getString("create_account_url"));
+ }
+}
+
+
+// static
+void FSPanelLogin::onClickVersion(void*)
+{
+ LLFloaterReg::showInstance("sl_about");
+}
+
+//static
+void FSPanelLogin::onClickForgotPassword(void*)
+{
+ if (sInstance)
+ {
+//
+#ifdef OPENSIM
+ LLSD grid_info;
+ LLGridManager::getInstance()->getGridData(grid_info);
+
+ if (LLGridManager::getInstance()->isInOpenSim() && grid_info.has(GRID_FORGOT_PASSWORD))
+ LLWeb::loadURLInternal(grid_info[GRID_FORGOT_PASSWORD]);
+ else
+#endif // OPENSIM
+//
+ LLWeb::loadURLExternal(sInstance->getString( "forgot_password_url" ));
+ }
+}
+
+//static
+void FSPanelLogin::onClickHelp(void*)
+{
+ if (sInstance)
+ {
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(vhelp->preLoginTopic());
+ }
+}
+
+// static
+void FSPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
+{
+ FSPanelLogin *This = (FSPanelLogin *) user_data;
+ This->mPasswordModified = TRUE;
+ if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE)
+ {
+ // *TODO: use another way to notify user about enabled caps lock, see EXT-6858
+ sCapslockDidNotification = TRUE;
+ }
+}
+
+
+void FSPanelLogin::updateServer()
+{
+ if (!sInstance)
+ {
+ return;
+ }
+ try
+ {
+ // if they've selected another grid, we should load the credentials
+ // for that grid and set them to the UI.
+ if(!sInstance->areCredentialFieldsDirty())
+ {
+//
+ //LLPointer credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ LLPointer credential = gSecAPIHandler->loadCredential(credentialName());
+ //bool remember = sInstance->getChild("remember_check")->getValue();
+ //sInstance->setFields(credential, remember);
+ sInstance->setFields(credential);
+//
+ }
+
+ // update the login panel links
+ // Unused by Firestorm
+ //bool system_grid = LLGridManager::getInstance()->isSystemGrid();
+ //
+
+ // Want to vanish not only create_new_account_btn, but also the
+ // title text over it, so turn on/off the whole layout_panel element.
+ // or not!
+ //sInstance->getChild("links")->setVisible(system_grid);
+ //sInstance->getChildView("forgot_password_text")->setVisible(system_grid);
+ //
+
+ // grid changed so show new splash screen (possibly)
+ updateServerCombo();
+ loadLoginPage();
+
+ // FIRE-12905: Allow longer passwords in OpenSim
+#ifdef OPENSIM
+ sInstance->getChild("password_edit")->setMaxTextLength(LLGridManager::getInstance()->isInSecondLife() ? 16 : 255);
+#endif
+ //
+ }
+ catch (LLInvalidGridName ex)
+ {
+ LL_WARNS("AppInit")<<"server '"< credential;
+
+ LLComboBox* server_combo = getChild("server_combo");
+ LLSD server_combo_val = server_combo->getSelectedValue();
+ LL_INFOS("AppInit") << "grid "<setGridChoice(server_combo_val.asString());
+ // FIRE-10122 - User@grid stored_favorites.xml
+ //addFavoritesToStartLocation();
+
+ /*
+ * Determine whether or not the value in the start_location_combo makes sense
+ * with the new grid value.
+ *
+ * Note that some forms that could be in the location combo are grid-agnostic,
+ * such as "MyRegion/128/128/0". There could be regions with that name on any
+ * number of grids, so leave them alone. Other forms, such as
+ * https://grid.example.com/region/Party%20Town/20/30/5 specify a particular
+ * grid; in those cases we want to clear the location.
+ */
+ LLComboBox* location_combo = getChild("start_location_combo");
+ S32 index = location_combo->getCurrentIndex();
+ switch (index)
+ {
+ case 0: // last location
+ case 1: // home location
+ // do nothing - these are grid-agnostic locations
+ break;
+
+ default:
+ {
+ std::string location = location_combo->getValue().asString();
+ LLSLURL slurl(location); // generata a slurl from the location combo contents
+ if ( slurl.getType() == LLSLURL::LOCATION
+ && slurl.getGrid() != LLGridManager::getInstance()->getGrid()
+ )
+ {
+ // the grid specified by the location is not this one, so clear the combo
+ location_combo->setCurrentByIndex(0); // last location on the new grid
+ location_combo->setTextEntry(LLStringUtil::null);
+ }
+ }
+ break;
+ }
+ updateServer();
+}
+
+void FSPanelLogin::onLocationSLURL()
+{
+ LLComboBox* location_combo = getChild("start_location_combo");
+ std::string location = location_combo->getValue().asString();
+ LL_DEBUGS("AppInit") << location << LL_ENDL;
+
+ LLStartUp::setStartSLURL(location); // calls onUpdateStartSLURL, above
+}
+
+/////////////////////////////
+// Firestorm functions //
+/////////////////////////////
+
+std::string canonicalize_username(const std::string& name)
+{
+ std::string cname = name;
+
+// Strip off any grid appendage
+ U32 arobase = cname.find("@");
+ if(arobase > 0)
+ cname = cname.substr(0, arobase - 1);
+//
+
+ // determine if the username is a first/last form or not.
+ size_t separator_index = cname.find_first_of(" ._");
+ std::string first = cname.substr(0, separator_index);
+ std::string last;
+ if (separator_index != cname.npos)
+ {
+ last = cname.substr(separator_index + 1, cname.npos);
+ LLStringUtil::trim(last);
+ }
+ else
+ {
+ // ...on Linden grids, single username users as considered to have
+ // last name "Resident"
+ last = "Resident";
+ }
+
+ // Username in traditional "firstname lastname" form.
+ return first + ' ' + last;
+}
+
+void FSPanelLogin::addUsersToCombo(BOOL show_server)
+{
+ LLComboBox* combo = getChild("username_combo");
+ if (!combo) return;
+
+ combo->removeall();
+ std::string current_creds=credentialName();
+ if(current_creds.find("@") < 1)
+ {
+ current_creds = gSavedSettings.getString("UserLoginInfo");
+ }
+
+ std::vector logins = gSecAPIHandler->listCredentials();
+ LLUUID selectid;
+ LLStringUtil::trim(current_creds);
+ for (std::vector::iterator login_choice = logins.begin();
+ login_choice != logins.end();
+ login_choice++)
+ {
+ std::string name = *login_choice;
+ LLStringUtil::trim(name);
+
+ std::string credname = name;
+ std::string gridname = name;
+ size_t arobase = gridname.find("@");
+ if (arobase != std::string::npos && arobase + 1 < gridname.length() && arobase > 1)
+ {
+ gridname = gridname.substr(arobase + 1, gridname.length() - arobase - 1);
+ name = name.substr(0,arobase);
+
+ const std::string grid_label = LLGridManager::getInstance()->getGridLabel(gridname);
+
+ bool add_grid = false;
+ /// We only want to append a grid label when the user has enabled logging into other grids, or
+ /// they are using the OpenSim build. That way users who only want Second Life Agni can remain
+ /// blissfully ignorant. We will also not show them any saved credential that isn't Agni because
+ /// they don't want them.
+ if (SECOND_LIFE_MAIN_LABEL == grid_label)
+ {
+ if (show_server)
+ name.append( " @ " + grid_label);
+ add_grid = true;
+ }
+#ifdef OPENSIM
+ else if (!grid_label.empty() && show_server)
+ {
+ name.append(" @ " + grid_label);
+ add_grid = true;
+ }
+#else // OPENSIM
+ else if (SECOND_LIFE_BETA_LABEL == grid_label && show_server)
+ {
+ name.append(" @ " + grid_label);
+ add_grid = true;
+ }
+#endif // OPENSIM
+ if (add_grid)
+ {
+ combo->add(name,LLSD(credname));
+ }
+ }
+ }
+ combo->sortByName();
+ combo->selectByValue(LLSD(current_creds));
+}
+
+// static
+void FSPanelLogin::onClickRemove(void*)
+{
+ if (sInstance)
+ {
+ LLComboBox* combo = sInstance->getChild("username_combo");
+ std::string credName = combo->getValue().asString();
+ LLNotificationsUtil::add("ConfirmRemoveCredential", LLSD().with("NAME", credName), LLSD().with("CredName", credName), boost::bind(&FSPanelLogin::onRemoveCallback, _1, _2));
+ }
+}
+
+// static
+void FSPanelLogin::onRemoveCallback(const LLSD& notification, const LLSD& response)
+{
+ if (sInstance)
+ {
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ std::string credName = notification["payload"]["CredName"].asString();
+ if (credName == gSavedSettings.getString("UserLoginInfo"))
+ {
+ gSavedSettings.getControl("UserLoginInfo")->resetToDefault();
+ }
+ LLPointer credential = gSecAPIHandler->loadCredential(credName);
+ gSecAPIHandler->deleteCredential(credential);
+ sInstance->addUsersToCombo(gSavedSettings.getBOOL("ForceShowGrid"));
+
+ if (!sInstance->getChild("username_combo")->selectFirstItem())
+ {
+ sInstance->getChild("username_combo")->clear();
+ sInstance->getChild("password_edit")->clear();
+ }
+ }
+ }
+}
+
+//static
+void FSPanelLogin::onClickGridMgrHelp(void*)
+{
+ if (sInstance)
+ {
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(vhelp->gridMgrHelpTopic());
+ }
+}
+
+void FSPanelLogin::onSelectUser()
+{
+ // *NOTE: The paramters for this method are ignored.
+ LL_INFOS("AppInit") << "onSelectUser()" << LL_ENDL;
+
+ LLComboBox* combo = sInstance->getChild("username_combo");
+ LLSD combo_val = combo->getSelectedValue();
+ if (combo_val.isUndefined())
+ {
+ combo_val = combo->getValue();
+ }
+ LLPointer credential = gSecAPIHandler->loadCredential(combo_val);
+
+ //combo = sInstance->getChild("start_location_combo");
+ //LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation")));
+
+ std::string credName = combo_val.asString();
+
+ // if they've selected another grid, we should load the credentials
+ // for that grid and set them to the UI.
+ if(sInstance && !sInstance->areCredentialFieldsDirty())
+ {
+ LLPointer credential = gSecAPIHandler->loadCredential(credName);
+ sInstance->setFields(credential);
+ }
+ U32 arobase = credName.find("@");
+ if (arobase != -1 && arobase +1 < credName.length())
+ credName = credName.substr(arobase + 1, credName.length() - arobase - 1);
+ if(LLGridManager::getInstance()->getGrid() == credName)
+ {
+ // Even if we didn't change grids, this user might have favorites stored.
+ addFavoritesToStartLocation();
+ return;
+ }
+
+ try
+ {
+ LLGridManager::getInstance()->setGridChoice(credName);
+ }
+ catch (LLInvalidGridName ex)
+ {
+ // do nothing
+ }
+ updateServer();
+ addFavoritesToStartLocation();
+}
+
+// static
+void FSPanelLogin::updateServerCombo()
+{
+ if (!sInstance) return;
+
+#ifdef OPENSIM
+ LLGridManager::getInstance()->addGridListChangedCallback(&FSPanelLogin::gridListChanged);
+#endif // OPENSIM
+ // We add all of the possible values, sorted, and then add a bar and the current value at the top
+ LLComboBox* server_choice_combo = sInstance->getChild("server_combo");
+ server_choice_combo->removeall();
+
+ std::string current_grid = LLGridManager::getInstance()->getGrid();
+ std::map known_grids = LLGridManager::getInstance()->getKnownGrids();
+
+ for (std::map::iterator grid_choice = known_grids.begin();
+ grid_choice != known_grids.end();
+ grid_choice++)
+ {
+ if (!grid_choice->first.empty() && current_grid != grid_choice->first)
+ {
+ LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
+ server_choice_combo->add(grid_choice->second, grid_choice->first);
+ }
+ }
+ server_choice_combo->sortByName();
+ server_choice_combo->addSeparator(ADD_TOP);
+
+ LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
+ server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
+ current_grid,
+ ADD_TOP);
+ server_choice_combo->selectFirstItem();
+ update_grid_help();
+}
+
+// static
+std::string FSPanelLogin::credentialName()
+{
+ std::string username = sInstance->getChild("username_combo")->getValue().asString();
+ LLStringUtil::trim(username);
+
+ size_t arobase = username.find("@");
+ if (arobase != std::string::npos && arobase + 1 < username.length())
+ username = username.substr(0,arobase);
+ LLStringUtil::trim(username);
+
+ return username + "@" + LLGridManager::getInstance()->getGrid();
+}
+
+// static
+void FSPanelLogin::gridListChanged(bool success)
+{
+ updateServer();
+}
+
+/////////////////////////
+// Mode selector //
+/////////////////////////
+
+void FSPanelLogin::onModeChange(const LLSD& original_value, const LLSD& new_value)
+{
+ // make sure toolbar settings are reset on mode change
+ LL_INFOS() << "Clearing toolbar settings." << LL_ENDL;
+ gSavedSettings.setBOOL("ResetToolbarSettings",TRUE);
+
+ if (original_value.asString() != new_value.asString())
+ {
+ LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&FSPanelLogin::onModeChangeConfirm, this, original_value, new_value, _1, _2));
+ }
+}
+
+void FSPanelLogin::onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0:
+ gSavedSettings.getControl("SessionSettingsFile")->set(new_value);
+ LLAppViewer::instance()->requestQuit();
+ break;
+ case 1:
+ // revert to original value
+ getChild("mode_combo")->setValue(original_value);
+ break;
+ default:
+ break;
+ }
+}
+//
diff --git a/indra/newview/fspanellogin.h b/indra/newview/fspanellogin.h
new file mode 100644
index 0000000000..20b98c700e
--- /dev/null
+++ b/indra/newview/fspanellogin.h
@@ -0,0 +1,136 @@
+/**
+ * @file fspanellogin.h
+ * @brief Login username entry fields.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Original file: llpanellogin.cpp
+
+#ifndef FS_PANELLOGIN_H
+#define FS_PANELLOGIN_H
+
+#include "llpanel.h"
+#include "llpointer.h" // LLPointer<>
+#include "llmediactrl.h" // LLMediaCtrlObserver
+#include
+
+class LLLineEditor;
+class LLUIImage;
+class LLPanelLoginListener;
+class LLSLURL;
+class LLCredential;
+
+class FSPanelLogin:
+ public LLPanel,
+ public LLViewerMediaObserver
+{
+ LOG_CLASS(FSPanelLogin);
+public:
+ FSPanelLogin(const LLRect &rect,
+ void (*callback)(S32 option, void* user_data),
+ void *callback_data);
+ ~FSPanelLogin();
+
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+ virtual void draw();
+ virtual void setFocus( BOOL b );
+
+ // Show the XUI first name, last name, and password widgets. They are
+ // hidden on startup for reg-in-client
+ static void showLoginWidgets();
+
+ static void show(const LLRect &rect,
+ void (*callback)(S32 option, void* user_data),
+ void* callback_data);
+
+//
+ //static void setFields(LLPointer credential, BOOL remember);
+ static void setFields(LLPointer credential);
+//
+
+ static void getFields(LLPointer& credential, BOOL& remember);
+
+ static BOOL areCredentialFieldsDirty();
+ static void setLocation(const LLSLURL& slurl);
+
+ /// Call when preferences that control visibility may have changed
+ static void updateLocationSelectorsVisibility();
+
+ static void closePanel();
+
+ void setSiteIsAlive( bool alive );
+
+ static void loadLoginPage();
+ static void giveFocus();
+ static void setAlwaysRefresh(bool refresh);
+
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+ static void updateServer(); // update the combo box, change the login page to the new server, clear the combo
+
+ /// to be called from LLStartUp::setStartSLURL
+ static void onUpdateStartSLURL(const LLSLURL& new_start_slurl);
+
+private:
+ friend class LLPanelLoginListener;
+ void reshapeBrowser();
+ void addFavoritesToStartLocation();
+//
+ //void addUsersWithFavoritesToUsername();
+ void addUsersToCombo(BOOL show_server);
+ void onSelectUser();
+ void onModeChange(const LLSD& original_value, const LLSD& new_value);
+ void onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response);
+//
+ void onSelectServer();
+ void onLocationSLURL();
+
+ static void onClickConnect(void*);
+ static void onClickNewAccount(void*);
+ static void onClickVersion(void*);
+ static void onClickForgotPassword(void*);
+ static void onClickHelp(void*);
+ static void onPassKey(LLLineEditor* caller, void* user_data);
+ static void updateServerCombo();
+//
+ static void onClickRemove(void*);
+ static void onRemoveCallback(const LLSD& notification, const LLSD& response);
+ static void onClickGridMgrHelp(void*);
+ static void gridListChanged(bool success);
+ static std::string credentialName();
+//
+
+private:
+ LLPointer mLogoImage;
+ //boost::scoped_ptr mListener;
+
+ void (*mCallback)(S32 option, void *userdata);
+ void* mCallbackData;
+
+ BOOL mPasswordModified;
+
+ static FSPanelLogin* sInstance;
+ static BOOL sCapslockDidNotification;
+};
+
+#endif //FS_PANELLOGIN_H
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 36bfdf32ba..3cb725573b 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -63,7 +63,10 @@
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnotificationtemplate.h"
-#include "llpanellogin.h"
+// [FS Login Panel]
+//#include "llpanellogin.h"
+#include "fspanellogin.h"
+// [FS Login Panel]
#include "llpanelvoicedevicesettings.h"
#include "llradiogroup.h"
#include "llsearchcombobox.h"
@@ -1053,7 +1056,10 @@ void LLFloaterPreference::onOpen(const LLSD& key)
//onNotificationsChange("ObjectIMOptions");
//
- LLPanelLogin::setAlwaysRefresh(true);
+ // [FS Login Panel]
+ //LLPanelLogin::setAlwaysRefresh(true);
+ FSPanelLogin::setAlwaysRefresh(true);
+ // [FS Login Panel]
refresh();
@@ -1181,7 +1187,10 @@ void LLFloaterPreference::onClose(bool app_quitting)
gSavedSettings.setS32("LastPrefTab", getChild("pref core")->getCurrentPanelIndex());
}
//
- LLPanelLogin::setAlwaysRefresh(false);
+ // [FS Login Panel]
+ //LLPanelLogin::setAlwaysRefresh(false);
+ FSPanelLogin::setAlwaysRefresh(false);
+ // [FS Login Panel]
if (!app_quitting)
{
cancel();
@@ -1251,7 +1260,10 @@ void LLFloaterPreference::onBtnOK()
LL_INFOS() << "Can't close preferences!" << LL_ENDL;
}
- LLPanelLogin::updateLocationSelectorsVisibility();
+ // [FS Login Panel]
+ //LLPanelLogin::updateLocationSelectorsVisibility();
+ FSPanelLogin::updateLocationSelectorsVisibility();
+ // [FS Login Panel]
//Need to reload the navmesh if the pathing console is up
LLHandle pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
if ( !pathfindingConsoleHandle.isDead() )
@@ -1276,7 +1288,10 @@ void LLFloaterPreference::onBtnApply( )
apply();
saveSettings();
- LLPanelLogin::updateLocationSelectorsVisibility();
+ // [FS Login Panel]
+ //LLPanelLogin::updateLocationSelectorsVisibility();
+ FSPanelLogin::updateLocationSelectorsVisibility();
+ // [FS Login Panel]
}
// static
@@ -4377,7 +4392,7 @@ void LLPanelPreferenceOpensim::apply()
void LLPanelPreferenceOpensim::cancel()
{
LLGridManager::getInstance()->resetGrids();
- LLPanelLogin::updateServer();
+ FSPanelLogin::updateServer();
}
void LLPanelPreferenceOpensim::onClickAddGrid()
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index 854d9d785b..9c6e4aa2b2 100755
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
@@ -31,7 +31,10 @@
// viewer includes
#include "llsecapi.h"
#include "lllogininstance.h" // to check if logged in yet
-#include "llpanellogin.h"
+// [FS Login Panel]
+//#include "llpanellogin.h"
+#include "fspanellogin.h"
+// [FS Login Panel]
#include "llstartup.h" // getStartupState()
#include "llslurl.h"
#include "llviewercontrol.h" // gSavedSettings
@@ -100,7 +103,10 @@ bool LLLoginHandler::handle(const LLSD& tokens,
&& tokens[0].asString() == "show")
{
// We're using reg-in-client, so show the XUI login widgets
- LLPanelLogin::showLoginWidgets();
+ // [FS Login Panel]
+ //LLPanelLogin::showLoginWidgets();
+ FSPanelLogin::showLoginWidgets();
+ // [FS Login Panel]
return true;
}
@@ -144,7 +150,10 @@ bool LLLoginHandler::handle(const LLSD& tokens,
// as the login page may change from grid to grid, as well as
// things like username/password/etc, we simply refresh the
// login page to make sure everything is set up correctly
- LLPanelLogin::loadLoginPage();
+ // [FS Login Panel]
+ //LLPanelLogin::loadLoginPage();
+ FSPanelLogin::loadLoginPage();
+ // [FS Login Panel]
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
}
return true;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 5471b7ff81..7eb71c74f4 100755
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -26,6 +26,8 @@
#include "llviewerprecompiledheaders.h"
+#if 0
+
#include "llpanellogin.h"
#include "lllayoutstack.h"
@@ -1484,3 +1486,5 @@ void LLPanelLogin::onModeChangeConfirm(const LLSD& original_value, const LLSD& n
}
}
//
+
+#endif
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 277567b778..5608fb0023 100755
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#if 0
+
#ifndef LL_LLPANELLOGIN_H
#define LL_LLPANELLOGIN_H
@@ -132,3 +134,5 @@ private:
};
#endif
+
+#endif
diff --git a/indra/newview/llpanelloginlistener.cpp b/indra/newview/llpanelloginlistener.cpp
index 33efde11f3..843a8ff41e 100755
--- a/indra/newview/llpanelloginlistener.cpp
+++ b/indra/newview/llpanelloginlistener.cpp
@@ -28,6 +28,9 @@
// Precompiled header
#include "llviewerprecompiledheaders.h"
+
+#if 0
+
// associated header
#include "llpanelloginlistener.h"
// STL headers
@@ -49,3 +52,5 @@ void LLPanelLoginListener::onClickConnect(const LLSD&) const
{
mPanel->onClickConnect(NULL);
}
+
+#endif
diff --git a/indra/newview/llpanelloginlistener.h b/indra/newview/llpanelloginlistener.h
index 45dcea269c..98d3c77ea9 100755
--- a/indra/newview/llpanelloginlistener.h
+++ b/indra/newview/llpanelloginlistener.h
@@ -26,6 +26,8 @@
* $/LicenseInfo$
*/
+#if 0
+
#if ! defined(LL_LLPANELLOGINLISTENER_H)
#define LL_LLPANELLOGINLISTENER_H
@@ -45,3 +47,5 @@ private:
};
#endif /* ! defined(LL_LLPANELLOGINLISTENER_H) */
+
+#endif
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 3602de13b3..3c699075eb 100755
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -51,7 +51,10 @@
#include "llappviewer.h"
#include "llweb.h"
#include "lluictrlfactory.h"
-#include "llpanellogin.h"
+// [FS Login Panel]
+//#include "llpanellogin.h"
+#include "fspanellogin.h"
+// [FS Login Panel]
LLProgressView* LLProgressView::sInstance = NULL;
LLProgressViewMini* LLProgressViewMini::sInstance = NULL;
@@ -510,7 +513,10 @@ void LLProgressView::onIdle(void* user_data)
self->mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME)
{
self->mFadeFromLoginTimer.stop();
- LLPanelLogin::closePanel();
+ // [FS Login Panel]
+ //LLPanelLogin::closePanel();
+ FSPanelLogin::closePanel();
+ // [FS Login Panel]
// Nothing to do anymore.
gIdleCallbacks.deleteFunction(onIdle, user_data);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d30dda3543..9e229437c3 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -124,7 +124,10 @@
#include "llkeyboard.h"
#include "llloginhandler.h" // gLoginHandler, SLURL support
#include "lllogininstance.h" // Host the login module.
-#include "llpanellogin.h"
+// [FS Login Panel]
+//#include "llpanellogin.h"
+#include "fspanellogin.h"
+// [FS Login Panel]
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
#include "llpanelclassified.h"
@@ -1089,11 +1092,14 @@ bool idle_startup()
{
//
//LLPanelLogin::setFields( gUserCredential, gRememberPassword);
- LLPanelLogin::setFields(gUserCredential);
+ FSPanelLogin::setFields(gUserCredential);
//
}
display_startup();
- LLPanelLogin::giveFocus();
+ // [FS Login Panel]
+ //LLPanelLogin::giveFocus();
+ FSPanelLogin::giveFocus();
+ // [FS Login Panel]
// MAINT-3231 Show first run dialog only for Desura viewer
if (gSavedSettings.getString("sourceid") == "1208_desura")
@@ -1195,7 +1201,10 @@ bool idle_startup()
{
// TODO if not use viewer auth
// Load all the name information out of the login view
- LLPanelLogin::getFields(gUserCredential, gRememberPassword);
+ // [FS Login Panel]
+ //LLPanelLogin::getFields(gUserCredential, gRememberPassword);
+ FSPanelLogin::getFields(gUserCredential, gRememberPassword);
+ // [FS Login Panel]
// end TODO
// HACK: Try to make not jump on login
@@ -1336,7 +1345,11 @@ bool idle_startup()
{
LLSLURL slurl;
// WS: Close the Panel only, if we have DisableLoginScreens enabled. Else fade away.
- if(gSavedSettings.getBOOL("FSDisableLoginScreens")) LLPanelLogin::closePanel();
+ if(gSavedSettings.getBOOL("FSDisableLoginScreens"))
+ // [FS Login Panel]
+ //LLPanelLogin::closePanel();
+ FSPanelLogin::closePanel();
+ // [FS Login Panel]
}
@@ -2839,7 +2852,10 @@ void login_show()
gToolBarView->setVisible(FALSE);
}
- LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), login_callback, NULL );
+ // [FS Login Panel]
+ //LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), login_callback, NULL );
+ FSPanelLogin::show( gViewerWindow->getWindowRectScaled(), login_callback, NULL );
+ // [FS Login Panel]
}
// Callback for when login screen is closed. Option 0 = connect, option 1 = quit.
@@ -2867,7 +2883,10 @@ void login_callback(S32 option, void *userdata)
if (LLAppViewer::instance()->quitRequested())
{
- LLPanelLogin::closePanel();
+ // [FS Login Panel]
+ //LLPanelLogin::closePanel();
+ FSPanelLogin::closePanel();
+ // [FS Login Panel]
}
return;
}
@@ -2892,7 +2911,10 @@ bool first_run_dialog_callback(const LLSD& notification, const LLSD& response)
LLWeb::loadURLExternal(LLTrans::getString("create_account_url") );
}
- LLPanelLogin::giveFocus();
+ // [FS Login Panel]
+ //LLPanelLogin::giveFocus();
+ FSPanelLogin::giveFocus();
+ // [FS Login Panel]
return false;
}
@@ -2926,7 +2948,10 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
LL_WARNS("AppInit") << "Missing case in login_alert_status switch" << LL_ENDL;
}
- LLPanelLogin::giveFocus();
+ // [FS Login Panel]
+ //LLPanelLogin::giveFocus();
+ FSPanelLogin::giveFocus();
+ // [FS Login Panel]
return false;
}
@@ -3693,7 +3718,10 @@ bool LLStartUp::startLLProxy()
bool login_alert_done(const LLSD& notification, const LLSD& response)
{
- LLPanelLogin::giveFocus();
+ // [FS Login Panel]
+ //LLPanelLogin::giveFocus();
+ FSPanelLogin::giveFocus();
+ // [FS Login Panel]
return false;
}
@@ -3754,7 +3782,10 @@ LLSD transform_cert_args(LLPointer cert)
void general_cert_done(const LLSD& notification, const LLSD& response)
{
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
- LLPanelLogin::giveFocus();
+ // [FS Login Panel]
+ //LLPanelLogin::giveFocus();
+ FSPanelLogin::giveFocus();
+ // [FS Login Panel]
}
// check to see if the user wants to trust the cert.
@@ -3778,7 +3809,10 @@ void trust_cert_done(const LLSD& notification, const LLSD& response)
gSavedSettings.setBOOL("AutoLogin", FALSE);
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
default:
- LLPanelLogin::giveFocus();
+ // [FS Login Panel]
+ //LLPanelLogin::giveFocus();
+ FSPanelLogin::giveFocus();
+ // [FS Login Panel]
break;
}
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 3cf596b84e..12cbbf7f2d 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -35,7 +35,10 @@
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "llnotifications.h"
-#include "llpanellogin.h"
+// [FS Login Panel]
+//#include "llpanellogin.h"
+#include "fspanellogin.h"
+// [FS Login Panel]
#include "llregionhandle.h"
#include "llslurl.h"
#include "llstartup.h" // gStartupState
@@ -206,7 +209,10 @@ bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string
// We're at the login screen, so make sure user can see
// the login location box to know where they are going.
- LLPanelLogin::setLocation(slurl);
+ // [FS Login Panel]
+ //LLPanelLogin::setLocation(slurl);
+ FSPanelLogin::setLocation(slurl);
+ // [FS Login Panel]
return true;
}
//
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 4f328703d5..4d67fc6c26 100755
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -69,7 +69,10 @@
#include "llnavigationbar.h"
#include "llfloatertools.h"
#include "llpaneloutfitsinventory.h"
-#include "llpanellogin.h"
+// [FS Login Panel]
+//#include "llpanellogin.h"
+#include "fspanellogin.h"
+// [FS Login Panel]
#include "llpaneltopinfobar.h"
#include "llspellcheck.h"
#include "llslurl.h"
@@ -587,7 +590,10 @@ bool handleAvatarZOffsetChanged(const LLSD& sdValue)
bool handleForceShowGrid(const LLSD& newvalue)
{
- LLPanelLogin::updateServer( );
+ // [FS Login Panel]
+ //LLPanelLogin::updateServer( );
+ FSPanelLogin::updateServer( );
+ // [FS Login Panel]
return true;
}
diff --git a/indra/newview/skins/default/xui/da/panel_fs_login.xml b/indra/newview/skins/default/xui/da/panel_fs_login.xml
new file mode 100644
index 0000000000..b7cb76d4cb
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/panel_fs_login.xml
@@ -0,0 +1,46 @@
+
+
+
+ http://secondlife.com/account/request.php
+
+
+
+
+ LOG PÅ
+
+
+ Brugernavn:
+
+
+
+ Password:
+
+
+
+
+ Start ved:
+
+
+
+
+
+
+
+
+
+ Hjælp til login
+
+
+ Har du glemt brugernavn eller password?
+
+
+
+
+
+
+ CREATE YǾUR ACCǾUNT
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/de/panel_fs_login.xml b/indra/newview/skins/default/xui/de/panel_fs_login.xml
new file mode 100644
index 0000000000..cc22944148
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_fs_login.xml
@@ -0,0 +1,56 @@
+
+
+
+ http://de.secondlife.com/registration/
+
+
+ http://secondlife.com/account/request.php?lang=de
+
+
+
+
+ ANMELDEN
+
+
+ Benutzername:
+
+
+
+
+ Kennwort:
+
+
+
+
+ Hier starten:
+
+
+
+
+
+
+
+
+
+ Gridauswahl:
+
+
+
+
+ Registrieren
+
+
+ Benutzernamen oder Kennwort vergessen?
+
+
+
+
+
+
+ MODUS-WAHL
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/en/panel_fs_login.xml b/indra/newview/skins/default/xui/en/panel_fs_login.xml
new file mode 100644
index 0000000000..ab89b1c0c1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_login.xml
@@ -0,0 +1,302 @@
+
+
+
+ http://phoenixviewer.com/app/loginV3/
+
+
+ http://secondlife.eniac15.lindenlab.com/reg-in-client/
+
+
+ http://secondlife.com/account/request.php
+
+
+
+
+
+
+ LOG IN
+
+
+ Username:
+
+
+
+
+
+
+
+
+ Password:
+
+
+
+
+
+
+ Start at:
+
+
+
+
+
+
+
+
+
+ Log into Grid:
+
+
+
+
+
+ Create an account
+
+
+ Forgot your username or password?
+
+
+
+
+
+
+ SELECT MODE
+
+
+
+
+
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/es/panel_fs_login.xml b/indra/newview/skins/default/xui/es/panel_fs_login.xml
new file mode 100644
index 0000000000..19e777000c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_fs_login.xml
@@ -0,0 +1,57 @@
+
+
+
+ https://secondlife.com/my/account/request.php?lang=es-ES
+
+
+
+
+ CONECTAR
+
+
+ Nombre de usuario:
+
+
+
+
+ Contraseña:
+
+
+
+
+ Iniciar en:
+
+
+
+
+
+
+
+
+
+ Iniciar en la red:
+
+
+
+
+ Registrarme
+
+
+ ¿Olvidaste el nombre de usuario o la contraseña?
+
+
+
+
+
+
+ SELECCIONAR MODO:
+
+
+
+
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/fr/panel_fs_login.xml b/indra/newview/skins/default/xui/fr/panel_fs_login.xml
new file mode 100644
index 0000000000..849c1bc80e
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_fs_login.xml
@@ -0,0 +1,53 @@
+
+
+
+
+ http://fr.secondlife.com/registration/
+
+
+ http://secondlife.com/account/request.php?lang=fr
+
+
+
+
+ Nom d'utilisateur :
+
+
+
+
+ Mot de passe :
+
+
+
+
+ Mode :
+
+
+
+
+
+
+ Point d'entrée :
+
+
+
+
+
+
+
+ Grille :
+
+
+
+
+ S'inscrire
+
+
+ Nom d'utilisateur ou mot de passe oublié ?
+
+
+ Besoin d'aide ?
+
+
+
+
diff --git a/indra/newview/skins/default/xui/it/panel_fs_login.xml b/indra/newview/skins/default/xui/it/panel_fs_login.xml
new file mode 100644
index 0000000000..f8f5837bff
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_fs_login.xml
@@ -0,0 +1,51 @@
+
+
+
+ http://secondlife.com/account/request.php?lang=it
+
+
+
+
+ ACCEDI
+
+
+ Nome utente:
+
+
+
+
+ Password:
+
+
+
+
+ Inizia da:
+
+
+
+
+
+
+
+ Accedi alla Grid:
+
+
+
+
+
+ Ti serve aiuto con la fase di accesso?
+
+
+ Hai dimenticato il nome utente o la password?
+
+
+
+
+
+
+ CREA IL TUO ACCOUNT
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/ja/panel_fs_login.xml b/indra/newview/skins/default/xui/ja/panel_fs_login.xml
new file mode 100644
index 0000000000..8d80362a77
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_fs_login.xml
@@ -0,0 +1,59 @@
+
+
+
+ http://secondlife.com/account/request.php?lang=ja
+
+
+
+
+ ログイン
+
+
+ ユーザーネーム:
+
+
+
+
+ パスワード:
+
+
+
+
+ 開始地点:
+
+
+
+
+
+
+
+
+
+ グリッド選択:
+
+
+
+
+
+ アカウント作成
+
+
+ ユーザー名またはパスワードをお忘れですか?
+
+
+
+
+
+
+ モード選択
+
+
+
+
+
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/pl/panel_fs_login.xml b/indra/newview/skins/default/xui/pl/panel_fs_login.xml
new file mode 100644
index 0000000000..d3f3928d67
--- /dev/null
+++ b/indra/newview/skins/default/xui/pl/panel_fs_login.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+ ZALOGUJ SIĘ
+
+
+ Użytkownik:
+
+
+
+
+ Hasło:
+
+
+
+
+ Rozpocznij w:
+
+
+
+
+
+
+
+
+
+ Loguj na siatkę:
+
+
+
+
+ Utwórz nowe konto
+
+
+ Zapomniałeś/aś nazwy lub hasła?
+
+
+
+
+
+
+ WYBIERZ TRYB
+
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/pt/panel_fs_login.xml b/indra/newview/skins/default/xui/pt/panel_fs_login.xml
new file mode 100644
index 0000000000..d7e9fa76ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_fs_login.xml
@@ -0,0 +1,46 @@
+
+
+
+ http://secondlife.com/account/request.php?lang=pt
+
+
+
+
+ LOGIN
+
+
+ Nome de usuário:
+
+
+
+ Senha:
+
+
+
+
+ Começar em:
+
+
+
+
+
+
+
+
+
+ Precisa de ajuda com o login?
+
+
+ Esqueceu seu nome ou senha?
+
+
+
+
+
+
+ CRIE SUA CONTA
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/ru/panel_fs_login.xml b/indra/newview/skins/default/xui/ru/panel_fs_login.xml
new file mode 100644
index 0000000000..f0877731c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_fs_login.xml
@@ -0,0 +1,46 @@
+
+
+
+ http://secondlife.com/account/request.php
+
+
+
+
+ ВОЙТИ
+
+
+ Имя пользователя:
+
+
+
+ Пароль:
+
+
+
+
+ Место старта:
+
+
+
+
+
+
+
+
+
+ Нужна помощь при входе?
+
+
+ Забыли имя или пароль?
+
+
+
+
+
+
+ СОЗДАЙТЕ СВОЙ АККАУНТ
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/tr/panel_fs_login.xml b/indra/newview/skins/default/xui/tr/panel_fs_login.xml
new file mode 100644
index 0000000000..28d316e46b
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_fs_login.xml
@@ -0,0 +1,46 @@
+
+
+
+ http://secondlife.com/account/request.php
+
+
+
+
+ OTURUM AÇ
+
+
+ Kullanıcı Adı:
+
+
+
+ Parola:
+
+
+
+
+ Buradan başla:
+
+
+
+
+
+
+
+
+
+ Oturum açarken yardım mı gerekiyor?
+
+
+ Kullanıcı adınızı veya parolanızı mı unuttunuz?
+
+
+
+
+
+
+ HESABINIZI OLUŞTURUN
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/zh/panel_fs_login.xml b/indra/newview/skins/default/xui/zh/panel_fs_login.xml
new file mode 100644
index 0000000000..672d9bb1a2
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_fs_login.xml
@@ -0,0 +1,46 @@
+
+
+
+ http://secondlife.com/account/request.php
+
+
+
+
+ 登入
+
+
+ 使用者名稱:
+
+
+
+ 密碼:
+
+
+
+
+ 開始地點:
+
+
+
+
+
+
+
+
+
+ 登入時需要幫助?
+
+
+ 忘記你的使用者名稱或密碼?
+
+
+
+
+
+
+ 建立你的帳號
+
+
+
+
+