summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/contributions.txt1
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp4
-rw-r--r--indra/llimage/llimageworker.cpp5
-rw-r--r--indra/llimagej2coj/llimagej2coj.cpp1
-rw-r--r--indra/llmath/llquantize.h25
-rw-r--r--indra/llmath/llquaternion.cpp20
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp18
-rw-r--r--indra/llui/lllineeditor.cpp14
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/lltexteditor.cpp13
-rw-r--r--indra/llui/lltexteditor.h2
-rw-r--r--indra/llwindow/llwindow.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp194
-rw-r--r--indra/llwindow/llwindowwin32.h4
-rw-r--r--indra/lscript/lscript_byteconvert.h41
-rw-r--r--indra/lscript/lscript_execute.h4
-rw-r--r--indra/lscript/lscript_execute/lscript_execute.cpp160
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh25
-rw-r--r--indra/newview/llinventorymodel.cpp2
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp2
-rw-r--r--indra/newview/llselectmgr.cpp15
-rw-r--r--indra/newview/lltoolfocus.cpp8
-rwxr-xr-xindra/newview/viewer_manifest.py6
23 files changed, 440 insertions, 128 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index cdda70a5c2..208bc534bf 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -95,6 +95,7 @@ Gigs Taggart
VWR-101
VWR-166
VWR-234
+ VWR-315
VWR-326
VWR-493
VWR-1203
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index bef5ea5dbb..83f16e1556 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -743,6 +743,10 @@ void LLMotionController::updateMotion()
{
motion_set_t::iterator curiter = iter++;
LLMotion* motionp = *curiter;
+ if( !motionp)
+ {
+ continue; // maybe shouldn't happen but i've seen it -MG
+ }
LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
if (status == LLMotion::STATUS_SUCCESS)
{
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 9a200cdf61..75cf24947d 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -79,10 +79,7 @@ bool LLImageWorker::doWork(S32 param)
}
else
{
- S32 nc = param ? 1 : mFormattedImage->getComponents();
- mDecodedImage = new LLImageRaw(mFormattedImage->getWidth(),
- mFormattedImage->getHeight(),
- nc);
+ mDecodedImage = new LLImageRaw(); // allow possibly smaller size set during decoding
}
}
if (!decoded)
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 68a3152f0a..7def8ca07f 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -10,7 +10,6 @@
#include "llimagej2coj.h"
// this is defined so that we get static linking.
-#define OPJ_STATIC
#include "openjpeg/openjpeg.h"
#include "lltimer.h"
diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h
index 8aa03628f2..93cd16c13a 100644
--- a/indra/llmath/llquantize.h
+++ b/indra/llmath/llquantize.h
@@ -20,6 +20,18 @@ const U8 FIRSTVALIDCHAR = 54;
const U8 MAXSTRINGVAL = U8MAX - FIRSTVALIDCHAR; //we don't allow newline or null
+inline U16 F32_to_U16_ROUND(F32 val, F32 lower, F32 upper)
+{
+ val = llclamp(val, lower, upper);
+ // make sure that the value is positive and normalized to <0, 1>
+ val -= lower;
+ val /= (upper - lower);
+
+ // round the value. Sreturn the U16
+ return (U16)(llround(val*U16MAX));
+}
+
+
inline U16 F32_to_U16(F32 val, F32 lower, F32 upper)
{
val = llclamp(val, lower, upper);
@@ -47,6 +59,19 @@ inline F32 U16_to_F32(U16 ival, F32 lower, F32 upper)
return val;
}
+
+inline U8 F32_to_U8_ROUND(F32 val, F32 lower, F32 upper)
+{
+ val = llclamp(val, lower, upper);
+ // make sure that the value is positive and normalized to <0, 1>
+ val -= lower;
+ val /= (upper - lower);
+
+ // return the rounded U8
+ return (U8)(llround(val*U8MAX));
+}
+
+
inline U8 F32_to_U8(F32 val, F32 lower, F32 upper)
{
val = llclamp(val, lower, upper);
diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp
index 8b2808164f..d5fe931187 100644
--- a/indra/llmath/llquaternion.cpp
+++ b/indra/llmath/llquaternion.cpp
@@ -87,23 +87,27 @@ void LLQuaternion::quantize16(F32 lower, F32 upper)
F32 z = mQ[VZ];
F32 s = mQ[VS];
- x = U16_to_F32(F32_to_U16(x, lower, upper), lower, upper);
- y = U16_to_F32(F32_to_U16(y, lower, upper), lower, upper);
- z = U16_to_F32(F32_to_U16(z, lower, upper), lower, upper);
- s = U16_to_F32(F32_to_U16(s, lower, upper), lower, upper);
+ x = U16_to_F32(F32_to_U16_ROUND(x, lower, upper), lower, upper);
+ y = U16_to_F32(F32_to_U16_ROUND(y, lower, upper), lower, upper);
+ z = U16_to_F32(F32_to_U16_ROUND(z, lower, upper), lower, upper);
+ s = U16_to_F32(F32_to_U16_ROUND(s, lower, upper), lower, upper);
mQ[VX] = x;
mQ[VY] = y;
mQ[VZ] = z;
mQ[VS] = s;
+
+ normQuat();
}
void LLQuaternion::quantize8(F32 lower, F32 upper)
{
- mQ[VX] = U8_to_F32(F32_to_U8(mQ[VX], lower, upper), lower, upper);
- mQ[VY] = U8_to_F32(F32_to_U8(mQ[VY], lower, upper), lower, upper);
- mQ[VZ] = U8_to_F32(F32_to_U8(mQ[VZ], lower, upper), lower, upper);
- mQ[VS] = U8_to_F32(F32_to_U8(mQ[VS], lower, upper), lower, upper);
+ mQ[VX] = U8_to_F32(F32_to_U8_ROUND(mQ[VX], lower, upper), lower, upper);
+ mQ[VY] = U8_to_F32(F32_to_U8_ROUND(mQ[VY], lower, upper), lower, upper);
+ mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper);
+ mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper);
+
+ normQuat();
}
// LLVector3 Magnitude and Normalization Functions
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 7b07dfd0e0..142e6a50e8 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -316,7 +316,7 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
while (mZStream.avail_out > 0)
{
- if (mZStream.avail_in == 0 && !mZInputExhausted)
+ if (mZStream.avail_in == 0 && !mZInputExhausted)
{
S32 to_read = llmin(COMPRESSED_INPUT_BUFFER_SIZE,
(S32)(mVFile->getSize() - mVFile->tell()));
@@ -324,14 +324,9 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
if ( to_read > 0 )
{
mVFile->read((U8*)mZInputBuffer, to_read); /*Flawfinder: ignore*/
+ mZStream.next_in = (Bytef*)mZInputBuffer;
+ mZStream.avail_in = mVFile->getLastBytesRead();
}
- else
- {
- llwarns << "LLHTTPAssetRequest::readCompressedData has zero read length" << llendl;
- break;
- }
- mZStream.next_in = (Bytef*)mZInputBuffer;
- mZStream.avail_in = mVFile->getLastBytesRead();
mZInputExhausted = mZStream.avail_in == 0;
}
@@ -339,8 +334,13 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
int r = deflate(&mZStream,
mZInputExhausted ? Z_FINISH : Z_NO_FLUSH);
- if (r == Z_STREAM_END || r < 0)
+ if (r == Z_STREAM_END || r < 0 || mZInputExhausted)
{
+ if (r < 0)
+ {
+ llwarns << "LLHTTPAssetRequest::readCompressedData: deflate returned error code "
+ << (S32) r << llendl;
+ }
break;
}
}
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index ccf18a3506..30feb85b2c 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -135,7 +135,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
mHandleEditKeysDirectly( FALSE ),
mSelectAllonFocusReceived( FALSE ),
mPassDelete(FALSE),
- mReadOnly(FALSE)
+ mReadOnly(FALSE),
+ mLastIMEPosition( -1, -1 )
{
llassert( max_length_bytes > 0 );
@@ -1609,6 +1610,17 @@ void LLLineEditor::draw()
LLFontGL::NORMAL,
1);
}
+
+ // Make sure the IME is in the right place
+ S32 pixels_after_scroll = findPixelNearestPos(); // RCalculcate for IME position
+ LLRect screen_pos = getScreenRect();
+ LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD );
+ if ( ime_pos.mX != mLastIMEPosition.mX || ime_pos.mY != mLastIMEPosition.mY )
+ {
+ mLastIMEPosition.mX = ime_pos.mX;
+ mLastIMEPosition.mY = ime_pos.mY;
+ getWindow()->setLanguageTextInput( ime_pos );
+ }
}
}
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index db6aea8432..6de2fc3eba 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -256,6 +256,8 @@ protected:
S32 mBorderThickness;
+ LLCoordGL mLastIMEPosition; // Last screen position used for the IME editor
+
BOOL mIgnoreArrowKeys;
BOOL mIgnoreTab;
BOOL mDrawAsterixes;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 52f8c19ebd..1ec62f6927 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -286,7 +286,8 @@ LLTextEditor::LLTextEditor(
mMouseDownX(0),
mMouseDownY(0),
mLastSelectionX(-1),
- mLastSelectionY(-1)
+ mLastSelectionY(-1),
+ mLastIMEPosition(-1,-1)
{
mSourceID.generate();
@@ -2799,7 +2800,15 @@ void LLTextEditor::drawCursor()
1);
}
-
+ // Make sure the IME is in the right place
+ LLRect screen_pos = getScreenRect();
+ LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) );
+ if ( ime_pos.mX != mLastIMEPosition.mX || ime_pos.mY != mLastIMEPosition.mY )
+ {
+ mLastIMEPosition.mX = ime_pos.mX;
+ mLastIMEPosition.mY = ime_pos.mY;
+ getWindow()->setLanguageTextInput( ime_pos );
+ }
}
}
}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 7c7ec9c13b..e19e799033 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -414,6 +414,8 @@ protected:
BOOL mParseHTML;
LLString mHTML;
+
+ LLCoordGL mLastIMEPosition; // Last position of the IME editor
};
class LLTextSegment
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 1347d8e94c..f1c188f8e9 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -200,7 +200,7 @@ public:
// control platform's Language Text Input mechanisms.
virtual void allowLanguageTextInput( BOOL b ) {};
- virtual void setLanguageTextInput( LLCoordWindow pos ) {};
+ virtual void setLanguageTextInput( const LLCoordGL & pos ) {};
protected:
LLWindow(BOOL fullscreen, U32 flags);
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 299ccc39f3..cb108143f4 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -65,11 +65,10 @@ void show_window_creation_error(const char* title)
//static
BOOL LLWindowWin32::sIsClassRegistered = FALSE;
-BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; /* XXX */
-BOOL LLWindowWin32::sWinIMEOpened = FALSE;
-HKL LLWindowWin32::sWinInputLocale;
-DWORD LLWindowWin32::sWinIMEConversionMode;
-DWORD LLWindowWin32::sWinIMESentenceMode;
+BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE;
+HKL LLWindowWin32::sWinInputLocale = 0;
+DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE;
+DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC;
// The following class LLWinImm delegates Windows IMM APIs.
// We need this because some language versions of Windows,
@@ -87,13 +86,15 @@ public:
public:
// Wrappers for IMM API.
- static BOOL isIME(HKL hkl) { return sTheInstance.mImmIsIME(hkl); }
- static HIMC getContext(HWND hwnd) { return sTheInstance.mImmGetContext(hwnd); }
- static BOOL releaseContext(HWND hwnd, HIMC himc) { return sTheInstance.mImmReleaseContext(hwnd, himc); }
- static BOOL getOpenStatus(HIMC himc) { return sTheInstance.mImmGetOpenStatus(himc); }
- static BOOL setOpenStatus(HIMC himc, BOOL status) { return sTheInstance.mImmSetOpenStatus(himc, status); }
- static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) { return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); }
- static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) { return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); }
+ static BOOL isIME(HKL hkl);
+ static HIMC getContext(HWND hwnd);
+ static BOOL releaseContext(HWND hwnd, HIMC himc);
+ static BOOL getOpenStatus(HIMC himc);
+ static BOOL setOpenStatus(HIMC himc, BOOL status);
+ static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence);
+ static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence);
+ static BOOL getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);
+ static BOOL setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);
private:
LLWinImm();
@@ -108,6 +109,8 @@ private:
BOOL (WINAPI *mImmSetOpenStatus)(HIMC, BOOL);
BOOL (WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
BOOL (WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD);
+ BOOL (WINAPI *mImmGetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
+ BOOL (WINAPI *mImmSetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
private:
HMODULE mHImmDll;
@@ -116,8 +119,13 @@ private:
LLWinImm LLWinImm::sTheInstance;
-LLWinImm::LLWinImm()
+LLWinImm::LLWinImm() : mHImmDll(NULL)
{
+ // Check system metrics
+ if ( !GetSystemMetrics( SM_DBCSENABLED ) )
+ return;
+
+
mHImmDll = LoadLibraryA("Imm32");
if (mHImmDll != NULL)
{
@@ -128,13 +136,18 @@ LLWinImm::LLWinImm()
mImmSetOpenStatus = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(mHImmDll, "ImmSetOpenStatus");
mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus");
mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmSetConversionStatus");
+ mImmGetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmGetCompositionWindow");
+ mImmSetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmSetCompositionWindow");
+
if (mImmIsIME == NULL ||
mImmGetContext == NULL ||
mImmReleaseContext == NULL ||
mImmGetOpenStatus == NULL ||
mImmSetOpenStatus == NULL ||
mImmGetConversionStatus == NULL ||
- mImmSetConversionStatus == NULL)
+ mImmSetConversionStatus == NULL ||
+ mImmGetCompostitionWindow == NULL ||
+ mImmSetCompostitionWindow == NULL)
{
// If any of the above API entires are not found, we can't use IMM API.
// So, turn off the IMM support. We should log some warning message in
@@ -145,10 +158,96 @@ LLWinImm::LLWinImm()
// is one of disadvantages to use static constraction to DLL loading.
FreeLibrary(mHImmDll);
mHImmDll = NULL;
+
+ // If we unload the library, make sure all the function pointers are cleared
+ mImmIsIME = NULL;
+ mImmGetContext = NULL;
+ mImmReleaseContext = NULL;
+ mImmGetOpenStatus = NULL;
+ mImmSetOpenStatus = NULL;
+ mImmGetConversionStatus = NULL;
+ mImmSetConversionStatus = NULL;
+ mImmGetCompostitionWindow = NULL;
+ mImmSetCompostitionWindow = NULL;
}
}
}
+
+// static
+BOOL LLWinImm::isIME(HKL hkl)
+{
+ if ( sTheInstance.mImmIsIME )
+ return sTheInstance.mImmIsIME(hkl);
+ return FALSE;
+}
+
+// static
+HIMC LLWinImm::getContext(HWND hwnd)
+{
+ if ( sTheInstance.mImmGetContext )
+ return sTheInstance.mImmGetContext(hwnd);
+ return 0;
+}
+
+//static
+BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc)
+{
+ if ( sTheInstance.mImmIsIME )
+ return sTheInstance.mImmReleaseContext(hwnd, himc);
+ return FALSE;
+}
+
+// static
+BOOL LLWinImm::getOpenStatus(HIMC himc)
+{
+ if ( sTheInstance.mImmGetOpenStatus )
+ return sTheInstance.mImmGetOpenStatus(himc);
+ return FALSE;
+}
+
+// static
+BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
+{
+ if ( sTheInstance.mImmSetOpenStatus )
+ return sTheInstance.mImmSetOpenStatus(himc, status);
+ return FALSE;
+}
+
+// static
+BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence)
+{
+ if ( sTheInstance.mImmGetConversionStatus )
+ return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence);
+ return FALSE;
+}
+
+// static
+BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence)
+{
+ if ( sTheInstance.mImmSetConversionStatus )
+ return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence);
+ return FALSE;
+}
+
+// static
+BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
+{
+ if ( sTheInstance.mImmGetCompostitionWindow )
+ return sTheInstance.mImmGetCompostitionWindow(himc, form);
+ return FALSE;
+}
+
+// static
+BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
+{
+ if ( sTheInstance.mImmSetCompostitionWindow )
+ return sTheInstance.mImmSetCompostitionWindow(himc, form);
+ return FALSE;
+}
+
+
+// ----------------------------------------------------------------------------------------
LLWinImm::~LLWinImm()
{
if (mHImmDll != NULL)
@@ -3202,53 +3301,74 @@ void LLWindowWin32::focusClient()
void LLWindowWin32::allowLanguageTextInput(BOOL b)
{
- if (b == sLanguageTextInputAllowed || !LLWinImm::isAvailable())
+ if ( !LLWinImm::isAvailable() )
{
- /* Not actually allowing/disallowing. Do nothing. */
return;
}
sLanguageTextInputAllowed = b;
if (b)
{
- /* Allowing: Restore the previous IME status,
- so that the user has a feeling that the previous
- text input continues naturally. Be careful, however,
- the IME status is meaningful only during the user keeps
- using same Input Locale (aka Keyboard Layout). */
- if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
+ // Allowing: Restore the previous IME status, so that the user has a feeling that the previous
+ // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
+ // using same Input Locale (aka Keyboard Layout).
+ HIMC himc = LLWinImm::getContext(mWindowHandle);
+ LLWinImm::setOpenStatus(himc, TRUE);
+ if (GetKeyboardLayout(0) == sWinInputLocale && sWinIMEConversionMode != IME_CMODE_RESERVED)
{
- HIMC himc = LLWinImm::getContext(mWindowHandle);
- LLWinImm::setOpenStatus(himc, TRUE);
LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
- LLWinImm::releaseContext(mWindowHandle, himc);
+ sWinIMEConversionMode = IME_CMODE_RESERVED; // Set saved state so we won't do this repeatedly
}
+ LLWinImm::releaseContext(mWindowHandle, himc);
}
else
{
- /* Disallowing: Turn off the IME so that succeeding
- key events bypass IME and come to us directly.
- However, do it after saving the current IME
- status. We need to restore the status when
- allowing language text input again. */
+ // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
+ // However, do it after saving the current IME status. We need to restore the status when
+ // allowing language text input again.
sWinInputLocale = GetKeyboardLayout(0);
- sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
- if (sWinIMEOpened)
+ if ( LLWinImm::isIME(sWinInputLocale) )
{
HIMC himc = LLWinImm::getContext(mWindowHandle);
- sWinIMEOpened = LLWinImm::getOpenStatus(himc);
- if (sWinIMEOpened)
+ if ( LLWinImm::getOpenStatus(himc) )
{
LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
- /* We need both ImmSetConversionStatus and ImmSetOpenStatus here
- to surely disable IME's keyboard hooking, because Some IME reacts
- only on the former and some other on the latter... */
+ // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
+ // keyboard hooking, because Some IME reacts only on the former and some other on the latter...
LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
LLWinImm::setOpenStatus(himc, FALSE);
}
LLWinImm::releaseContext(mWindowHandle, himc);
+ }
+ }
+
+}
+
+
+// Put the IME window at the right place (near current text input). Point coordinates should be the top of the current text line.
+void LLWindowWin32::setLanguageTextInput( const LLCoordGL & position )
+{
+ if (sLanguageTextInputAllowed && LLWinImm::isAvailable())
+ {
+ HIMC himc = LLWinImm::getContext(mWindowHandle);
+
+ LLCoordWindow win_pos;
+ convertCoords( position, &win_pos );
+
+ if ( win_pos.mX >= 0 && win_pos.mY >= 0 )
+ {
+ COMPOSITIONFORM ime_form;
+ memset( &ime_form, 0, sizeof(ime_form) );
+ ime_form.dwStyle = CFS_POINT;
+ ime_form.ptCurrentPos.x = win_pos.mX;
+ ime_form.ptCurrentPos.y = win_pos.mY;
+
+ LLWinImm::setCompositionWindow( himc, &ime_form );
}
+
+ LLWinImm::releaseContext(mWindowHandle, himc);
+
}
}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 5eb2cfbb79..cb105c2128 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -87,6 +87,7 @@ public:
/*virtual*/ void focusClient();
/*virtual*/ void allowLanguageTextInput(BOOL b);
+ /*virtual*/ void setLanguageTextInput( const LLCoordGL & pos );
protected:
LLWindowWin32(
@@ -156,11 +157,10 @@ protected:
BOOL mMousePositionModified;
BOOL mInputProcessingPaused;
- // The following five variables are for Language Text Input control.
+ // The following variables are for Language Text Input control.
// They are all static, since one context is shared by all LLWindowWin32
// instances.
static BOOL sLanguageTextInputAllowed;
- static BOOL sWinIMEOpened;
static HKL sWinInputLocale;
static DWORD sWinIMEConversionMode;
static DWORD sWinIMESentenceMode;
diff --git a/indra/lscript/lscript_byteconvert.h b/indra/lscript/lscript_byteconvert.h
index d30c84b28c..d960eb8c66 100644
--- a/indra/lscript/lscript_byteconvert.h
+++ b/indra/lscript/lscript_byteconvert.h
@@ -761,9 +761,17 @@ inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEven
major_version = LSL2_MAJOR_VERSION_TWO;
state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
}
+ if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
// get the actual position in memory of the desired state
S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
+ if ( state_offset < 0 || state_offset > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
// save that value
S32 state_offset_base = state_offset;
@@ -773,18 +781,32 @@ inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEven
// get the location of the event offset
S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
+ if ( event_offset < 0 || event_offset > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
// now, jump to the event
S32 event_start = bytestream2integer(stream, event_offset);
+ if ( event_start < 0 || event_start > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
event_start += event_jump_offset;
S32 event_start_original = event_start;
// now skip past the parameters
S32 opcode_offset = bytestream2integer(stream, event_start);
+ if ( opcode_offset < 0 || opcode_offset > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
+
return opcode_offset + event_start_original;
}
+
inline U64 get_handled_events(U8 *stream, S32 state)
{
U64 retvalue = 0;
@@ -809,6 +831,7 @@ inline U64 get_handled_events(U8 *stream, S32 state)
return retvalue;
}
+// Returns -1 on error
inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
{
// get the start of the state table
@@ -829,21 +852,39 @@ inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType eve
state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
}
+ if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
+
S32 state_offset = bytestream2integer(stream, state_offset_offset);
state_offset += sr;
state_offset_offset = state_offset;
+ if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
// skip to jump table
S32 jump_table = bytestream2integer(stream, state_offset_offset);
jump_table += state_offset;
+ if ( jump_table < 0 || jump_table > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
// get the position of the jump to the desired state
S32 stack_size_offset = jump_table + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event) + LSCRIPTDataSize[LST_INTEGER];
// get the handled events
S32 stack_size = bytestream2integer(stream, stack_size_offset);
+ if ( stack_size < 0 || stack_size > TOP_OF_MEMORY )
+ {
+ return -1;
+ }
+
return stack_size;
}
diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h
index 84cd6e3b0a..1c2952f5ae 100644
--- a/indra/lscript/lscript_execute.h
+++ b/indra/lscript/lscript_execute.h
@@ -359,6 +359,10 @@ public:
LLScriptEventData mEventData;
static S64 sGlobalInstructionCount;
+
+private:
+ void recordBoundaryError( const LLUUID &id );
+ void setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id );
};
#endif
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index b166e922a2..d00d3372ce 100644
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -245,6 +245,32 @@ void LLScriptExecute::init()
}
+
+// Utility routine for when there's a boundary error parsing bytecode
+void LLScriptExecute::recordBoundaryError( const LLUUID &id )
+{
+ set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
+ llwarns << "Script boundary error for ID " << id << llendl;
+}
+
+
+// set IP to the event handler with some error checking
+void LLScriptExecute::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
+{
+ S32 opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
+ if ( opcode_start == -1 )
+ {
+ recordBoundaryError( id );
+ }
+ else
+ {
+ set_ip( mBuffer, opcode_start );
+ }
+}
+
+
+
+
S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &state_transition)
@@ -353,14 +379,20 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
// now, push any additional stack space
S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
- lscript_pusharge(mBuffer, additional_size);
-
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size;
- set_bp(mBuffer, sp);
- // set IP to the event handler
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
- set_ip(mBuffer, opcode_start);
+ if ( additional_size == -1 )
+ {
+ recordBoundaryError( id );
+ }
+ else
+ {
+ lscript_pusharge(mBuffer, additional_size);
+
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size;
+ set_bp(mBuffer, sp);
+ // set IP to the event handler
+ setStateEventOpcoodeStartSafely( current_state, LSTT_STATE_EXIT, id );
+ }
return NO_DELETE_FLAG;
}
}
@@ -411,20 +443,27 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
current_events &= ~LSCRIPTStateBitField[event];
set_event_register(mBuffer, LREG_CE, current_events, major_version);
// now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- lscript_pusharge(mBuffer, additional_size);
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+ if ( additional_size == -1 )
+ { // b_done will be set, so we'll exit the loop at the bottom
+ recordBoundaryError( id );
+ }
+ else
+ {
+ additional_size -= size;
+ lscript_pusharge(mBuffer, additional_size);
// now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size + size;
+ set_bp(mBuffer, sp);
// set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
+ setStateEventOpcoodeStartSafely( current_state, event, id );
+ }
b_done = TRUE;
}
else if ( (current_events & LSCRIPTStateBitField[LSTT_REZ])
- &&(current_events & event_register))
+ &&(current_events & event_register))
{
for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
{
@@ -449,17 +488,24 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
data++;
}
// now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- lscript_pusharge(mBuffer, additional_size);
-
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
- mEventData.mEventDataList.deleteCurrentData();
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+ if ( additional_size == -1 )
+ { // b_done will be set, so we'll exit the loop at the bottom
+ recordBoundaryError( id );
+ }
+ else
+ {
+ additional_size -= size;
+ lscript_pusharge(mBuffer, additional_size);
+
+ // now set the bp correctly
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size + size;
+ set_bp(mBuffer, sp);
+ // set IP to the function
+ setStateEventOpcoodeStartSafely( current_state, event, id );
+ mEventData.mEventDataList.deleteCurrentData();
+ }
b_done = TRUE;
break;
}
@@ -496,16 +542,23 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
}
b_done = TRUE;
// now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- lscript_pusharge(mBuffer, additional_size);
-
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+ if ( additional_size == -1 )
+ { // b_done was just set, so we'll exit the loop at the bottom
+ recordBoundaryError( id );
+ }
+ else
+ {
+ additional_size -= size;
+ lscript_pusharge(mBuffer, additional_size);
+
+ // now set the bp correctly
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size + size;
+ set_bp(mBuffer, sp);
+ // set IP to the function
+ setStateEventOpcoodeStartSafely( current_state, event, id );
+ }
}
else
{
@@ -530,23 +583,30 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
current_events &= ~LSCRIPTStateBitField[event];
set_event_register(mBuffer, LREG_CE, current_events, major_version);
// now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- lscript_pusharge(mBuffer, additional_size);
-
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+ if ( additional_size == -1 )
+ { // b_done will be set, so we'll exit the loop at the bottom
+ recordBoundaryError( id );
+ }
+ else
+ {
+ additional_size -= size;
+ lscript_pusharge(mBuffer, additional_size);
+
+ // now set the bp correctly
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size + size;
+ set_bp(mBuffer, sp);
+ // set IP to the function
+ setStateEventOpcoodeStartSafely( current_state, event, id );
+ }
}
b_done = TRUE;
}
- }
+ } // while (!b_done)
+ } // end of else ... in state processing code
- return NO_DELETE_FLAG;
- }
+ return NO_DELETE_FLAG;
}
BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index ac967c4853..f720fc0ec1 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -84,7 +84,30 @@ export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-
export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin'
export SL_OPT="`cat gridargs.dat` $@"
-eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || echo Unclean shutdown.
+# Run the program
+eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr
+
+# Handle any resulting errors
+if [ -n "$LL_RUN_ERR" ]; then
+ LL_RUN_ERR_MSG=""
+ if [ "$LL_RUN_ERR" = "runerr" ]; then
+ # generic error running the binary
+ echo '*** Unclean shutdown. ***'
+ if [ "`arch`" = "x86_64" ]; then
+ echo
+ cat << EOFMARKER
+You are running the Second Life Viewer on a x86_64 platform. The
+most common problems when launching the Viewer (particularly
+'bin/do-not-directly-run-secondlife-bin: not found' and 'error while
+loading shared libraries') may be solved by installing your Linux
+distribution's 32-bit compatibility packages.
+For example, on Ubuntu and other Debian-based Linuxes you might run:
+$ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl
+EOFMARKER
+ fi
+ fi
+fi
+
echo
echo '*********************************************************'
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index ead985a992..a37044f364 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -306,7 +306,7 @@ LLUUID LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type)
}
// Convenience function to create a new category. You could call
-// updateCatgory() with a newly generated UUID category, but this
+// updateCategory() with a newly generated UUID category, but this
// version will take care of details like what the name should be
// based on preferred type. Returns the UUID of the new category.
LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index a2cc0f5a81..844afca629 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -495,7 +495,6 @@ bool LLPanelGroupGeneral::apply(LLString& mesg)
gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile);
mChanged = FALSE;
- notifyObservers();
return true;
}
@@ -810,6 +809,7 @@ void LLPanelGroupGeneral::updateChanged()
mSpinEnrollmentFee,
mCtrlReceiveNotices,
mCtrlListGroup,
+ mActiveTitleLabel,
mComboActiveTitle
};
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 0fbcd93b0b..5fbe3f0c8e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -4783,19 +4783,17 @@ void LLSelectMgr::updateSilhouettes()
iter != roots.end(); iter++)
{
LLViewerObject* objectp = *iter;
- LLSelectNode* rect_select_node = new LLSelectNode(objectp, TRUE);
- rect_select_node->selectAllTEs(TRUE);
+ LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
+ rect_select_root_node->selectAllTEs(TRUE);
if (!canSelectObject(objectp))
{
continue;
}
- mHighlightedObjects->addNode(rect_select_node);
-
if (!select_linked_set)
{
- rect_select_node->mIndividualSelection = TRUE;
+ rect_select_root_node->mIndividualSelection = TRUE;
}
else
{
@@ -4808,11 +4806,14 @@ void LLSelectMgr::updateSilhouettes()
continue;
}
- rect_select_node = new LLSelectNode(objectp->mChildList[i], TRUE);
+ LLSelectNode* rect_select_node = new LLSelectNode(objectp->mChildList[i], TRUE);
rect_select_node->selectAllTEs(TRUE);
- mHighlightedObjects->addNode(rect_select_node);
+ mHighlightedObjects->addNodeAtEnd(rect_select_node);
}
}
+
+ // Add the root last, to preserve order for link operations.
+ mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
}
num_sils_genned = 0;
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index cdfc6c2ebf..d5abfbdab6 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -262,9 +262,11 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
{
LLCoordGL mouse_pos;
LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal());
- gCamera->projectPosAgentToScreen(focus_pos, mouse_pos);
-
- LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
+ BOOL success = gCamera->projectPosAgentToScreen(focus_pos, mouse_pos);
+ if (success)
+ {
+ LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
+ }
}
else if (mMouseSteering)
{
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6b38bd1765..2078bd47f5 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -140,6 +140,11 @@ class WindowsManifest(ViewerManifest):
# For using FMOD for sound... DJS
self.path("fmod.dll")
+ # For textures
+ if self.prefix(src="../../libraries/i686-win32/lib_release", dst=""):
+ self.path("openjpeg.dll")
+ self.end_prefix()
+
# Mozilla appears to force a dependency on these files so we need to ship it (CP)
self.path("msvcr71.dll")
self.path("msvcp71.dll")
@@ -482,6 +487,7 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libuuid.so", "libuuid.so.1")
self.path("libSDL-1.2.so.0")
self.path("libELFIO.so")
+ self.path("libopenjpeg.so.2")
#self.path("libtcmalloc.so.0") - bugged
#self.path("libstacktrace.so.0") - probably bugged
self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason