diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 75c68acb781609b3bdcd73ae3b65b9535123f844..12b0e953b6eccda8dcdcde1f08575917e405030f 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
 //
@@ -340,6 +343,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 8a1a0dcaaae8321429e086efc94607f405c780c7..68ab91402bbf88c6fae92ac32d900356a3fe9ab8 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"
@@ -56,6 +57,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_LOGITECH_LCD_H
+#include "lllogitechlcd.h"
+#endif
+extern llLCD	*gLcdScreen; 
+#endif
+
 // Must be done at run time, not compile time. JC
 S32 pref_min_width()
 {
@@ -84,6 +93,7 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton
 	mDisplayPanel(NULL),
 	mDisplayPanel2(NULL),
 	mAudioPanel(NULL),
+	mLCDPanel(NULL),
 	mMsgPanel(NULL)
 {
 	mGeneralPanel = new LLPanelGeneral();
@@ -128,6 +138,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 (gLcdScreen->Enabled())
+	{
+		mLCDPanel = new LLPanelLCD();
+		mTabContainer->addTabPanel(mLCDPanel, mLCDPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
+		mLCDPanel->setDefaultBtn(default_btn);
+	}
+#endif
 	mMsgPanel = new LLPanelMsgs();
 	mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
 	mMsgPanel->setDefaultBtn(default_btn);
@@ -212,6 +231,14 @@ void LLPreferenceCore::apply()
 	#if LL_LIBXUL_ENABLED
 	mWebPanel->apply();
 	#endif
+#if LL_WINDOWS
+	// only add this option if we actually have a logitech keyboard / speaker set
+	if (gLcdScreen->Enabled())
+	{
+		mLCDPanel->apply();
+	}
+#endif
+//	mWebPanel->apply();
 }
 
 
@@ -230,6 +257,14 @@ void LLPreferenceCore::cancel()
 	#if LL_LIBXUL_ENABLED
 	mWebPanel->cancel();
 	#endif
+#if LL_WINDOWS
+	// only add this option if we actually have a logitech keyboard / speaker set
+	if (gLcdScreen->Enabled())
+	{
+		mLCDPanel->cancel();
+	}
+#endif
+//	mWebPanel->cancel();
 }
 
 // static
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index dcfa123137cc78b45c586f77acbd5b28a7a6c720..c40532fb4850c3d0064a5063a87da5e0936a22e6 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;
@@ -65,6 +66,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 72aca1999ead2f342c71658076d82baf0009fa5c..6990102d249240f8109902666bf83b5790e09025 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 c44c7acffec7f8b585a5dd5d86e9ee83180428a3..f33a5d93e1426cbc2e59c09213c245e1131a76c2 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 20c6b6895dd20dc88205f7bcb41d11b2e69ca316..e629b65af119ecb50d934a23592cb5aeb44b49e1 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -107,6 +107,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 6fd31f3e72ff78f3c32a1ee4d1ebc5cd28b86b41..076ae2eccee6136e16b87213eb9054dd290a8862 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -731,7 +731,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