diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 93eb24f36d51132a49e614a650ddfdb80e9cc292..bddae82b7f21bcf2d7c3f9d8e93cbf3434e3d8cc 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -47,6 +47,9 @@
 #include "llfloaterhtml.h"
 #include "llweb.h"
 
+// Used for LCD display
+extern void AddNewIMToLCD(const LLString &newLine);
+extern void AddNewChatToLCD(const LLString &newLine);
 //
 // Constants
 //
@@ -330,6 +333,20 @@ void LLFloaterChat::addChat(const LLChat& chat,
 			chat.mChatType == CHAT_TYPE_DEBUG_MSG
 			&& !gSavedSettings.getBOOL("ScriptErrorsAsChat");
 
+#if LL_WINDOWS
+	// add into LCD displays
+	if (!invisible_script_debug_chat)
+	{
+		if (!from_instant_message)
+		{
+			AddNewChatToLCD(chat.mText);
+		}
+		else
+		{
+			AddNewIMToLCD(chat.mText);
+		}
+	}
+#endif
 	if (!invisible_script_debug_chat 
 		&& !chat.mMuted 
 		&& gConsole 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c96fd4ac0a7aca4ba2ea517310dd1d7e04d86144..3a56eab2e21e48a7a0dcd65ffcb04ce45c178992 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -31,6 +31,7 @@
 #include "llpaneldebug.h"
 #include "llpanelgeneral.h"
 #include "llpanelinput.h"
+#include "llpanelLCD.h"
 #include "llpanelmsgs.h"
 //#include "llpanelweb.h"
 #include "llprefschat.h"
@@ -57,6 +58,14 @@ const S32 PREF_FLOATER_MIN_HEIGHT = 2 * SCROLLBAR_SIZE + 2 * LLPANEL_BORDER_WIDT
 
 LLFloaterPreference* LLFloaterPreference::sInstance = NULL;
 
+#if LL_WINDOWS
+// for Logitech LCD keyboards / speakers
+#ifndef LL_LCD_H
+#include "..\Logitech_LCD\LCD.h"
+#endif
+extern cLCD	*LcdScreen; 
+#endif
+
 // Must be done at run time, not compile time. JC
 S32 pref_min_width()
 {
@@ -85,6 +94,7 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton
 	mDisplayPanel(NULL),
 	mDisplayPanel2(NULL),
 	mAudioPanel(NULL),
+	mLCDPanel(NULL),
 	mMsgPanel(NULL)
 {
 	mGeneralPanel = new LLPanelGeneral();
@@ -123,6 +133,15 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton
 	mTabContainer->addTabPanel(mPrefsIM->getPanel(), mPrefsIM->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer);
 	mPrefsIM->getPanel()->setDefaultBtn(default_btn);
 
+#if LL_WINDOWS
+	// only add this option if we actually have a logitech keyboard / speaker set
+	if (LcdScreen->Enabled())
+	{
+		mLCDPanel = new LLPanelLCD();
+		mTabContainer->addTabPanel(mLCDPanel, mLCDPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
+		mLCDPanel->setDefaultBtn(default_btn);
+	}
+#endif
 	mMsgPanel = new LLPanelMsgs();
 	gUICtrlFactory->buildPanel(mMsgPanel, "panel_settings_msgbox.xml");
 	mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
@@ -148,6 +167,13 @@ void LLPreferenceCore::apply()
 	mPrefsChat->apply();
 	mPrefsIM->apply();
 	mMsgPanel->apply();
+#if LL_WINDOWS
+	// only add this option if we actually have a logitech keyboard / speaker set
+	if (LcdScreen->Enabled())
+	{
+		mLCDPanel->apply();
+	}
+#endif
 //	mWebPanel->apply();
 }
 
@@ -164,6 +190,13 @@ void LLPreferenceCore::cancel()
 	mPrefsChat->cancel();
 	mPrefsIM->cancel();
 	mMsgPanel->cancel();
+#if LL_WINDOWS
+	// only add this option if we actually have a logitech keyboard / speaker set
+	if (LcdScreen->Enabled())
+	{
+		mLCDPanel->cancel();
+	}
+#endif
 //	mWebPanel->cancel();
 }
 
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 8c33aba4768efd84fb6df2eee8e21c9f4f7f2e9e..9988d0c353c54d68535709922b355ca2e005e728 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -20,6 +20,7 @@
 
 class LLPanelGeneral;
 class LLPanelInput;
+class LLPanelLCD;
 class LLPanelDisplay;
 class LLPanelDisplay2;
 class LLPanelDisplay3;
@@ -64,6 +65,7 @@ class LLPreferenceCore
 	LLPrefsChat				*mPrefsChat;
 	LLPrefsIM				*mPrefsIM;
 	LLPanelMsgs				*mMsgPanel;
+	LLPanelLCD				*mLCDPanel;
 //	LLPanelWeb*				mWebPanel;
 };
 
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index c2b496d1ac3046df62524ade6cb429b99e6a1d5f..59fd8e0a3a1e469c721415a376baaec3503b5adf 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -403,6 +403,10 @@ void LLStatusBar::refresh()
 			pos_y -= pos_y % 2;
 		}
 
+		mRegionDetails.mTime = mTextTime->getText();
+		mRegionDetails.mBalance = mBalance;
+		mRegionDetails.mAccesString = (char *)region->getSimAccessString();
+		mRegionDetails.mPing = region->getNetDetailsForLCD();
 		if (parcel && parcel->getName())
 		{
 			location_name = region->getName()
@@ -410,6 +414,43 @@ void LLStatusBar::refresh()
 						   pos_x, pos_y, pos_z,
 						   region->getSimAccessString(),
 						   parcel->getName());
+
+			// keep these around for the LCD to use
+			mRegionDetails.mRegionName = region->getName();
+			mRegionDetails.mParcelName = (char *)parcel->getName();
+			mRegionDetails.mX = pos_x;
+			mRegionDetails.mY = pos_y;
+			mRegionDetails.mZ = pos_z;
+			mRegionDetails.mArea = parcel->getArea();
+			mRegionDetails.mForSale = parcel->getForSale();
+			mRegionDetails.mTraffic = gParcelMgr->getDwelling();
+			
+			if (parcel->isPublic())
+			{
+				snprintf(mRegionDetails.mOwner, MAX_STRING, "Public");
+			}
+			else
+			{
+				if (parcel->getIsGroupOwned())
+				{
+					if(!parcel->getGroupID().isNull())
+					{
+						gCacheName->getGroupName(parcel->getGroupID(), mRegionDetails.mOwner);
+					}
+					else
+					{
+						snprintf(mRegionDetails.mOwner, MAX_STRING, "Group Owned");
+					}
+				}
+				else
+				{
+					// Figure out the owner's name
+					char owner_first[MAX_STRING];	/*Flawfinder: ignore*/
+					char owner_last[MAX_STRING];	/*Flawfinder: ignore*/
+					gCacheName->getName(parcel->getOwnerID(), owner_first, owner_last);
+					snprintf(mRegionDetails.mOwner, MAX_STRING, "%s %s", owner_first, owner_last); 		/* Flawfinder: ignore */
+				}
+			}
 		}
 		else
 		{
@@ -417,12 +458,34 @@ void LLStatusBar::refresh()
 				+ llformat(" %d, %d, %d (%s)", 
 						   pos_x, pos_y, pos_z,
 						   region->getSimAccessString());
+			// keep these around for the LCD to use
+			mRegionDetails.mRegionName = region->getName();
+			mRegionDetails.mParcelName = "Unknown";
+			
+			mRegionDetails.mX = pos_x;
+			mRegionDetails.mY = pos_y;
+			mRegionDetails.mZ = pos_z;
+			mRegionDetails.mArea = 0;
+			mRegionDetails.mForSale = FALSE;
+			snprintf(mRegionDetails.mOwner, MAX_STRING, "Unknown");
+			mRegionDetails.mTraffic = 0.0f;
 		}
 	}
 	else
 	{
 		// no region
 		location_name = "(Unknown)";
+		// keep these around for the LCD to use
+		mRegionDetails.mRegionName = LLString("Unknown");
+		mRegionDetails.mParcelName = "Unknown";
+		mRegionDetails.mAccesString = "Unknown";
+		mRegionDetails.mX = 0;
+		mRegionDetails.mY = 0;
+		mRegionDetails.mZ = 0;
+		mRegionDetails.mArea = 0;
+		mRegionDetails.mForSale = FALSE;
+		snprintf(mRegionDetails.mOwner, MAX_STRING, "Unknown");
+		mRegionDetails.mTraffic = 0.0f;
 	}
 	mTextParcelName->setText(location_name);
 
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index c3f520315c6dc90df9b2fcfa88fb641c1f81794e..7e9f05cf1e6b89048a3e7690aa4462a395cca2ee 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -24,6 +24,25 @@ class LLUUID;
 class LLFrameTimer;
 class LLStatGraph;
 
+// used by LCD screen
+class cLLRegionDetails
+{
+public:
+	LLString mRegionName;
+	char	*mParcelName;
+	char	*mAccesString;
+	S32		mX;
+	S32		mY;
+	S32		mZ;
+	S32		mArea;
+	BOOL	mForSale;
+	char	mOwner[MAX_STRING];
+	F32		mTraffic;
+	S32		mBalance;
+	LLString	mTime;
+	U32		mPing;
+};
+
 class LLStatusBar
 :	public LLPanel
 {
@@ -60,6 +79,7 @@ class LLStatusBar
 	S32 getSquareMetersCredit() const;
 	S32 getSquareMetersCommitted() const;
 	S32 getSquareMetersLeft() const;
+	cLLRegionDetails mRegionDetails;
 
 protected:
 	static void onClickParcelInfo(void*);
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index d7677c70e461f9dda68c5aaad5cb677623952334..ae772aebf11bd469121d37ce92d734d50ffd08ed 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -104,6 +104,7 @@ class LLViewerParcelMgr
 	F32		getSelectionHeight() const	{ return F32(mEastNorth.mdV[VY] - mWestSouth.mdV[VY]); }
 	BOOL	getSelection(LLVector3d &min, LLVector3d &max) { min = mWestSouth; max = mEastNorth; return !selectionEmpty();}
 	LLViewerRegion* getSelectionRegion();
+	F32		getDwelling() const { return mSelectedDwell;}
 
 	void	getDisplayInfo(S32* area, S32* claim, S32* rent, BOOL* for_sale, F32* dwell);
 
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 3bc529a9e38f24da9b11737e93980b7de2c992bf..cc93ea8bdc6a0fa11021dd52cb5a063b89d005f8 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -724,7 +724,10 @@ void LLViewerRegion::calculateCameraDistance()
 	mCameraDistanceSquared = (F32)(gAgent.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
 }
 
-// ---------------- Friends ----------------
+U32 LLViewerRegion::getNetDetailsForLCD()
+{
+	return mPingDelay;
+}
 
 std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
 {
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 05c37fe08ffc97a589ddd3d24412497e35418209..a1b9cfd3eae9913a851c2a26d29335989cee3139 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -212,6 +212,9 @@ class LLViewerRegion
 
 	friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region);
 
+	// used by LCD to get details for debug screen
+	U32 getNetDetailsForLCD();
+
 public:
 	struct CompareDistance
 	{
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index f1df0d39e0688869c2e0806d32b94d9f6fb0d9bc..fefa86123d72b4df946f871ffc6ae906f1f06a17 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -153,7 +153,11 @@ const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
 	// ST_TEX_BAKES
 	StatAttributes("Texture Bakes", FALSE, FALSE),
 	// ST_TEX_REBAKES
-	StatAttributes("Texture Rebakes", FALSE, FALSE)
+	StatAttributes("Texture Rebakes", FALSE, FALSE),
+
+	// ST_LOGITECH_KEYBOARD
+	StatAttributes("Logitech LCD", FALSE, FALSE)
+
 };
 
 LLViewerStats::LLViewerStats()
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 33ed6bcbcf8e8d0d1b3b9dac79ab46a25248c87c..f0ef106054118405038a0ac79f90c4493e495b41 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -137,8 +137,9 @@ class LLViewerStats
 		ST_WINDOW_HEIGHT = 55,
 		ST_TEX_BAKES = 56,
 		ST_TEX_REBAKES = 57,
+		ST_LOGITECH_LCD = 58,
 		
-		ST_COUNT = 58
+		ST_COUNT = 59
 	};
 
 
diff --git a/indra/newview/res/icon1.ico b/indra/newview/res/icon1.ico
new file mode 100644
index 0000000000000000000000000000000000000000..ad607598fa4b33036f8450ef4af8764f80ee5146
Binary files /dev/null and b/indra/newview/res/icon1.ico differ
diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h
index c7e1552dff8dc5834a8bd112d9b70cc5ae73cda0..e4d01b1050970a127e7ed25e83a20d6f8707e4c5 100644
--- a/indra/newview/res/resource.h
+++ b/indra/newview/res/resource.h
@@ -19,6 +19,7 @@
 #define IDB_LOGIN                       149
 #define IDC_CURSOR4                     153
 #define IDC_CURSOR5                     154
+#define IDI_LCD_LL_ICON                 157
 #define IDC_RADIO_56                    1000
 #define IDC_RADIO_128                   1001
 #define IDC_RADIO_256                   1002
@@ -151,7 +152,7 @@
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        156
+#define _APS_NEXT_RESOURCE_VALUE        167
 #define _APS_NEXT_COMMAND_VALUE         40002
 #define _APS_NEXT_CONTROL_VALUE         1139
 #define _APS_NEXT_SYMED_VALUE           101