diff options
Diffstat (limited to 'indra/llwindow')
-rw-r--r-- | indra/llwindow/lldragdropwin32.cpp | 10 | ||||
-rw-r--r-- | indra/llwindow/llkeyboard.cpp | 2 | ||||
-rw-r--r-- | indra/llwindow/llkeyboard.h | 12 | ||||
-rw-r--r-- | indra/llwindow/llkeyboardmacosx.cpp | 17 | ||||
-rw-r--r-- | indra/llwindow/llkeyboardsdl.cpp | 20 | ||||
-rw-r--r-- | indra/llwindow/llkeyboardwin32.cpp | 60 | ||||
-rw-r--r-- | indra/llwindow/llwindow.cpp | 94 | ||||
-rw-r--r-- | indra/llwindow/llwindow.h | 17 | ||||
-rw-r--r-- | indra/llwindow/llwindowcallbacks.cpp | 2 | ||||
-rw-r--r-- | indra/llwindow/llwindowcallbacks.h | 2 | ||||
-rw-r--r-- | indra/llwindow/llwindowheadless.h | 5 | ||||
-rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 343 | ||||
-rw-r--r-- | indra/llwindow/llwindowmacosx.h | 7 | ||||
-rw-r--r-- | indra/llwindow/llwindowmesaheadless.h | 4 | ||||
-rw-r--r-- | indra/llwindow/llwindowsdl.cpp | 89 | ||||
-rw-r--r-- | indra/llwindow/llwindowsdl.h | 8 | ||||
-rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 194 | ||||
-rw-r--r-- | indra/llwindow/llwindowwin32.h | 5 |
18 files changed, 534 insertions, 357 deletions
diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index d4d444eb28..15acddd987 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -124,10 +124,9 @@ class LLDragDropWin32Target: ScreenToClient( mAppWindowHandle, &pt2 ); LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( cursor_coord_window.convert(), mask, LLWindowCallbacks::DNDA_START_TRACKING, mDropUrl ); switch (result) @@ -180,10 +179,9 @@ class LLDragDropWin32Target: ScreenToClient( mAppWindowHandle, &pt2 ); LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( cursor_coord_window.convert(), mask, LLWindowCallbacks::DNDA_TRACK, mDropUrl ); switch (result) @@ -237,15 +235,13 @@ class LLDragDropWin32Target: LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); if ( NULL != window_imp ) { - LLCoordGL gl_coord( 0, 0 ); - POINT pt_client; pt_client.x = pt.x; pt_client.y = pt.y; ScreenToClient( mAppWindowHandle, &pt_client ); LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + LLCoordGL gl_coord(cursor_coord_window.convert()); llinfos << "### (Drop) URL is: " << mDropUrl << llendl; llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; llinfos << "### client coords are: " << pt_client.x << " x " << pt_client.y << llendl; diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 53cecf9d4a..8b356ba138 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -46,7 +46,7 @@ LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10 // Class Implementation // -LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF) +LLKeyboard::LLKeyboard() : mCallbacks(NULL) { S32 i; diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index ba472cfde5..c155c1b362 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -63,14 +63,6 @@ class LLWindowCallbacks; class LLKeyboard { public: - typedef enum e_numpad_distinct - { - ND_NEVER, - ND_NUMLOCK_OFF, - ND_NUMLOCK_ON - } ENumpadDistinct; - -public: LLKeyboard(); virtual ~LLKeyboard(); @@ -107,8 +99,6 @@ public: static BOOL keyFromString(const std::string& str, KEY *key); // False on failure static std::string stringFromKey(KEY key); static std::string stringFromAccelerator( MASK accel_mask, KEY key ); - e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; } - void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; } void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; } F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. @@ -135,8 +125,6 @@ protected: static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling - e_numpad_distinct mNumpadDistinct; - EKeyboardInsertMode mInsertMode; static std::map<KEY,std::string> sKeysToNames; diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp index ecc2631669..7f8f303517 100644 --- a/indra/llwindow/llkeyboardmacosx.cpp +++ b/indra/llwindow/llkeyboardmacosx.cpp @@ -299,28 +299,11 @@ void LLKeyboardMacOSX::scanKeyboard() BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key ) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); - if(iter != mTranslateNumpadMap.end()) - { - *translated_key = iter->second; - return TRUE; - } - } return translateKey(os_key, translated_key); } U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key); - if(iter != mInvTranslateNumpadMap.end()) - { - return iter->second; - } - } return inverseTranslateKey(translated_key); } diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index 4bb9603368..7c9aa1d340 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -312,29 +312,11 @@ void LLKeyboardSDL::scanKeyboard() BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); - if(iter != mTranslateNumpadMap.end()) - { - *translated_key = iter->second; - return TRUE; - } - } - BOOL success = translateKey(os_key, translated_key); - return success; + return translateKey(os_key, translated_key); } U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key); - if(iter != mInvTranslateNumpadMap.end()) - { - return iter->second; - } - } return inverseTranslateKey(translated_key); } diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index df78816bd6..be3fe5deb0 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -299,69 +299,13 @@ void LLKeyboardWin32::scanKeyboard() BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key); - if (iter != mTranslateNumpadMap.end()) - { - *translated_key = iter->second; - return TRUE; - } - } - - BOOL success = translateKey(os_key, translated_key); - if(mNumpadDistinct != ND_NEVER) { - if(!success) return success; - if(mask & MASK_EXTENDED) - { - // this is where we'd create new keycodes for extended keys - // the set of extended keys includes the 'normal' arrow keys and - // the pgup/dn/insert/home/end/delete cluster above the arrow keys - // see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx - - // only process the return key if numlock is off - if(((mNumpadDistinct == ND_NUMLOCK_OFF && - !(GetKeyState(VK_NUMLOCK) & 1)) - || mNumpadDistinct == ND_NUMLOCK_ON) && - *translated_key == KEY_RETURN) { - *translated_key = KEY_PAD_RETURN; - } - } - else - { - // the non-extended keys, those are in the numpad - switch (*translated_key) - { - case KEY_LEFT: - *translated_key = KEY_PAD_LEFT; break; - case KEY_RIGHT: - *translated_key = KEY_PAD_RIGHT; break; - case KEY_UP: - *translated_key = KEY_PAD_UP; break; - case KEY_DOWN: - *translated_key = KEY_PAD_DOWN; break; - case KEY_HOME: - *translated_key = KEY_PAD_HOME; break; - case KEY_END: - *translated_key = KEY_PAD_END; break; - case KEY_PAGE_UP: - *translated_key = KEY_PAD_PGUP; break; - case KEY_PAGE_DOWN: - *translated_key = KEY_PAD_PGDN; break; - case KEY_INSERT: - *translated_key = KEY_PAD_INS; break; - case KEY_DELETE: - *translated_key = KEY_PAD_DEL; break; - } - } - } - return success; + return translateKey(os_key, translated_key); } U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key) { // if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number - if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1)) + if(GetKeyState(VK_NUMLOCK) & 1) { std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key); if (iter != mInvTranslateNumpadMap.end()) diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index dc3a1099b1..93b9d36939 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -50,14 +50,15 @@ LLSplashScreen *gSplashScreenp = NULL; BOOL gDebugClicks = FALSE; BOOL gDebugWindowProc = FALSE; -const S32 gURLProtocolWhitelistCount = 3; -const std::string gURLProtocolWhitelist[] = { "file:", "http:", "https:" }; +const S32 gURLProtocolWhitelistCount = 4; +const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:" }; // CP: added a handler list - this is what's used to open the protocol and is based on registry entry // only meaningful difference currently is that file: protocols are opened using http: // since no protocol handler exists in registry for file: // Important - these lists should match - protocol to handler -const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" }; +// Maestro: This list isn't referenced anywhere that I could find +//const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" }; S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type) @@ -108,9 +109,12 @@ LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags) mSupportedResolutions(NULL), mNumSupportedResolutions(0), mCurrentCursor(UI_CURSOR_ARROW), + mNextCursor(UI_CURSOR_ARROW), mCursorHidden(FALSE), mBusyCount(0), mIsMouseClipping(FALSE), + mMinWindowWidth(0), + mMinWindowHeight(0), mSwapMethod(SWAP_METHOD_UNDEFINED), mHideCursorPermanent(FALSE), mFlags(flags), @@ -179,6 +183,51 @@ void *LLWindow::getMediaWindow() return getPlatformWindow(); } +BOOL LLWindow::setSize(LLCoordScreen size) +{ + if (!getMaximized()) + { + size.mX = llmax(size.mX, mMinWindowWidth); + size.mY = llmax(size.mY, mMinWindowHeight); + } + return setSizeImpl(size); +} + +BOOL LLWindow::setSize(LLCoordWindow size) +{ + //HACK: we are inconsistently using minimum window dimensions + // in this case, we are constraining the inner "client" rect and other times + // we constrain the outer "window" rect + // There doesn't seem to be a good way to do this consistently without a bunch of platform + // specific code + if (!getMaximized()) + { + size.mX = llmax(size.mX, mMinWindowWidth); + size.mY = llmax(size.mY, mMinWindowHeight); + } + return setSizeImpl(size); +} + + +// virtual +void LLWindow::setMinSize(U32 min_width, U32 min_height, bool enforce_immediately) +{ + mMinWindowWidth = min_width; + mMinWindowHeight = min_height; + + if (enforce_immediately) + { + LLCoordScreen cur_size; + if (!getMaximized() && getSize(&cur_size)) + { + if (cur_size.mX < mMinWindowWidth || cur_size.mY < mMinWindowHeight) + { + setSizeImpl(LLCoordScreen(llmin(cur_size.mX, mMinWindowWidth), llmin(cur_size.mY, mMinWindowHeight))); + } + } + } +} + //virtual void LLWindow::processMiscNativeEvents() { @@ -403,3 +452,42 @@ BOOL LLWindowManager::isWindowValid(LLWindow *window) { return sWindowList.find(window) != sWindowList.end(); } + +//coordinate conversion utility funcs that forward to llwindow +LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const +{ + const LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this); + + LLWindow* windowp = &(*LLWindow::beginInstances()); + LLCoordGL out; + windowp->convertCoords(self, &out); + return out.convert(); +} + +void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from) +{ + LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this); + + LLWindow* windowp = &(*LLWindow::beginInstances()); + LLCoordGL from_gl(from); + windowp->convertCoords(from_gl, &self); +} + +LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const +{ + const LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this); + + LLWindow* windowp = &(*LLWindow::beginInstances()); + LLCoordGL out; + windowp->convertCoords(self, &out); + return out.convert(); +} + +void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from) +{ + LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this); + + LLWindow* windowp = &(*LLWindow::beginInstances()); + LLCoordGL from_gl(from); + windowp->convertCoords(from_gl, &self); +} diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index e8a86a1880..e9147d552e 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -39,7 +39,7 @@ class LLWindowCallbacks; // Refer to llwindow_test in test/common/llwindow for usage example -class LLWindow +class LLWindow : public LLInstanceTracker<LLWindow> { public: struct LLWindowResolution @@ -72,7 +72,9 @@ public: virtual BOOL getSize(LLCoordScreen *size) = 0; virtual BOOL getSize(LLCoordWindow *size) = 0; virtual BOOL setPosition(LLCoordScreen position) = 0; - virtual BOOL setSize(LLCoordScreen size) = 0; + BOOL setSize(LLCoordScreen size); + BOOL setSize(LLCoordWindow size); + virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0; virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; @@ -91,8 +93,9 @@ public: virtual S32 getBusyCount() const; // Sets cursor, may set to arrow+hourglass - virtual void setCursor(ECursorType cursor) = 0; + virtual void setCursor(ECursorType cursor) { mNextCursor = cursor; }; virtual ECursorType getCursor() const; + virtual void updateCursor() = 0; virtual void captureMouse() = 0; virtual void releaseMouse() = 0; @@ -169,6 +172,9 @@ protected: // Defaults to true virtual BOOL canDelete(); + virtual BOOL setSizeImpl(LLCoordScreen size) = 0; + virtual BOOL setSizeImpl(LLCoordWindow size) = 0; + protected: LLWindowCallbacks* mCallbacks; @@ -181,6 +187,7 @@ protected: LLWindowResolution* mSupportedResolutions; S32 mNumSupportedResolutions; ECursorType mCurrentCursor; + ECursorType mNextCursor; BOOL mCursorHidden; S32 mBusyCount; // how deep is the "cursor busy" stack? BOOL mIsMouseClipping; // Is this window currently clipping the mouse @@ -188,6 +195,8 @@ protected: BOOL mHideCursorPermanent; U32 mFlags; U16 mHighSurrogate; + S32 mMinWindowWidth; + S32 mMinWindowHeight; // Handle a UTF-16 encoding unit received from keyboard. // Converting the series of UTF-16 encoding units to UTF-32 data, @@ -271,7 +280,7 @@ extern BOOL gDebugWindowProc; // Protocols, like "http" and "https" we support in URLs extern const S32 gURLProtocolWhitelistCount; extern const std::string gURLProtocolWhitelist[]; -extern const std::string gURLProtocolWhitelistHandler[]; +//extern const std::string gURLProtocolWhitelistHandler[]; void simpleEscapeString ( std::string& stringIn ); diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index c2705bbf74..9712ae1d91 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -28,8 +28,6 @@ #include "llwindowcallbacks.h" -#include "llcoord.h" - // // LLWindowCallbacks // diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 8572b442f1..7da5959700 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -26,7 +26,7 @@ #ifndef LLWINDOWCALLBACKS_H #define LLWINDOWCALLBACKS_H -class LLCoordGL; +#include "llcoord.h" class LLWindow; class LLWindowCallbacks diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index ac53e6a86e..1f767f4c97 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -46,7 +46,8 @@ public: /*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;}; /*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;}; /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; - /*virtual*/ BOOL setSize(LLCoordScreen size) {return FALSE;}; + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; @@ -55,7 +56,7 @@ public: /*virtual*/ void showCursorFromMouseMove() {}; /*virtual*/ void hideCursorUntilMouseMove() {}; /*virtual*/ BOOL isCursorHidden() {return FALSE;}; - /*virtual*/ void setCursor(ECursorType cursor) {}; + /*virtual*/ void updateCursor() {}; //virtual ECursorType getCursor() { return mCurrentCursor; }; /*virtual*/ void captureMouse() {}; /*virtual*/ void releaseMouse() {}; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index d116f0dfff..97637c937f 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llwindowmacosx.cpp * @brief Platform-dependent implementation of llwindow * * $LicenseInfo:firstyear=2001&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$ */ @@ -220,10 +220,10 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, // Route them to a dummy callback structure until the end of constructor. LLWindowCallbacks null_callbacks; mCallbacks = &null_callbacks; - + // Voodoo for calling cocoa from carbon (see llwindowmacosx-objc.mm). setupCocoa(); - + // Initialize the keyboard gKeyboard = new LLKeyboardMacOSX(); gKeyboard->setCallbacks(callbacks); @@ -254,10 +254,10 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mRawKeyEvent = NULL; mFSAASamples = fsaa_samples; mForceRebuild = FALSE; - + // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state. // Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state. - mBounceTimer.stop(); + mBounceTimer.stop(); // Get the original aspect ratio of the main device. mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); @@ -270,7 +270,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator); mGlobalHandlerRef = NULL; mWindowHandlerRef = NULL; - + mDragOverrideCursor = -1; // We're not clipping yet @@ -445,7 +445,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits mFullscreenBits = -1; mFullscreenRefresh = -1; - std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height); + std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height); OSMessageBox(error, "Error", OSMB_OK); } } @@ -477,7 +477,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits kFirstWindowOfClass, true, (long)this); - + if (!mWindow) { setupFailure("Window creation error", "Error", OSMB_OK); @@ -493,7 +493,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits InstallStandardEventHandler(GetWindowEventTarget(mWindow)); InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler #if LL_OS_DRAGDROP_ENABLED - InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this ); + InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this ); InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this ); #endif // LL_OS_DRAGDROP_ENABLED } @@ -790,7 +790,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL; frames_per_swap = 1; } - aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap); + aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap); //enable multi-threaded OpenGL if (sUseMultGL) @@ -803,7 +803,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if (cgl_err != kCGLNoError ) { LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; - } + } else { LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; @@ -1109,7 +1109,7 @@ BOOL LLWindowMacOSX::maximize() { ZoomWindow(mWindow, inContent, true); } - + return mMaximized; } @@ -1164,6 +1164,8 @@ void LLWindowMacOSX::gatherInput() } } + + updateCursor(); } BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position) @@ -1254,7 +1256,7 @@ BOOL LLWindowMacOSX::setPosition(const LLCoordScreen position) return TRUE; } -BOOL LLWindowMacOSX::setSize(const LLCoordScreen size) +BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size) { if(mWindow) { @@ -1264,6 +1266,31 @@ BOOL LLWindowMacOSX::setSize(const LLCoordScreen size) return TRUE; } +BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size) +{ + Rect client_rect; + if (mWindow) + { + OSStatus err = GetWindowBounds(mWindow, kWindowContentRgn, &client_rect); + if (err == noErr) + { + client_rect.right = client_rect.left + size.mX; + client_rect.bottom = client_rect.top + size.mY; + err = SetWindowBounds(mWindow, kWindowContentRgn, &client_rect); + } + if (err == noErr) + { + return TRUE; + } + else + { + llinfos << "Error setting size" << err << llendl; + return FALSE; + } + } + return FALSE; +} + void LLWindowMacOSX::swapBuffers() { aglSwapBuffers(mContext); @@ -1432,7 +1459,7 @@ static void fixOrigin(void) GrafPtr port; Rect portrect; - ::GetPort(&port); + ::GetPort(&port); ::GetPortBounds(port, &portrect); if((portrect.left != 0) || (portrect.top != 0)) { @@ -1446,17 +1473,17 @@ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) Point cursor_point; LLCoordScreen screen_pos; GrafPtr save; - + if(mWindow == NULL) return FALSE; - + ::GetPort(&save); ::SetPort(GetWindowPort(mWindow)); fixOrigin(); // gets the mouse location in local coordinates ::GetMouse(&cursor_point); - + // lldebugs << "getCursorPosition(): cursor is at " << cursor_point.h << ", " << cursor_point.v << " port origin: " << portrect.left << ", " << portrect.top << llendl; ::SetPort(save); @@ -1521,7 +1548,7 @@ F32 LLWindowMacOSX::getNativeAspectRatio() { // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution // switching, and stashes it in mOriginalAspectRatio. Here, we just return it. - + if (mOverrideAspectRatio > 0.f) { return mOverrideAspectRatio; @@ -1996,7 +2023,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e if (mPreeditor && (result = GetEventParameter(event, kEventParamTextInputSendFixLen, typeLongInteger, ¶m_type, sizeof(fix_len), NULL, &fix_len)) == noErr - && typeLongInteger == param_type + && typeLongInteger == param_type && (result = GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, ¶m_type, 0, &text_len, NULL)) == noErr && typeUnicodeText == param_type) @@ -2016,7 +2043,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e mPreeditor->markAsPreedit(location, length); } mPreeditor->resetPreedit(); - + // Receive the text from input method. U16 *const text = new U16[text_len / sizeof(U16)]; GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, NULL, text_len, NULL, text); @@ -2055,11 +2082,11 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray, NULL, text_range_array_size, NULL, text_range_array); - // WARNING: We assume ranges are in ascending order, + // WARNING: We assume ranges are in ascending order, // although the condition is undocumented. It seems // OK to assume this. I also assumed // the ranges are contiguous in previous versions, but I - // have heard a rumore that older versions os ATOK may + // have heard a rumore that older versions os ATOK may // return ranges with some _gap_. I don't know whether // it is true, but I'm preparing my code for the case. @@ -2123,7 +2150,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e } } break; - + case kEventTextInputUnicodeForKeyEvent: { UInt32 modifiers = 0; @@ -2132,7 +2159,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e // First, process the raw event. { EventRef rawEvent = NULL; - + // Get the original event and extract the modifier keys, so we can ignore command-key events. if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr) { @@ -2141,7 +2168,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e // and call this function recursively to handle the raw key event. eventHandler (myHandler, rawEvent); - + // save the raw event until we're done processing the unicode input as well. mRawKeyEvent = rawEvent; } @@ -2172,7 +2199,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e else { MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); - + llassert( actualType == typeUnicodeText ); // The result is a UTF16 buffer. Pass the characters in turn to handleUnicodeChar. @@ -2198,7 +2225,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e result = err; } break; - + case kEventTextInputOffsetToPos: { EventParamType param_type; @@ -2211,7 +2238,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e S32 preedit, preedit_length; mPreeditor->getPreeditRange(&preedit, &preedit_length); const LLWString & text = mPreeditor->getPreeditString(); - + LLCoordGL caret_coord; LLRect preedit_bounds; if (0 <= offset @@ -2225,10 +2252,10 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e qd_point.h = caret_base_coord_screen.mX; qd_point.v = caret_base_coord_screen.mY; SetEventParameter(event, kEventParamTextInputReplyPoint, typeQDPoint, sizeof(qd_point), &qd_point); - + short line_height = (short) preedit_bounds.getHeight(); SetEventParameter(event, kEventParamTextInputReplyLineHeight, typeShortInteger, sizeof(line_height), &line_height); - + result = noErr; } else @@ -2281,7 +2308,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e case kEventRawKeyRepeat: if (gDebugWindowProc) { - printf("key down, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", + printf("key down, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", (unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers); fflush(stdout); } @@ -2292,7 +2319,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e case kEventRawKeyUp: if (gDebugWindowProc) { - printf("key up, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", + printf("key up, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", (unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers); fflush(stdout); } @@ -2350,7 +2377,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e } // When the state of the 'Fn' key (the one that changes some of the mappings on a powerbook/macbook keyboard - // to an embedded keypad) changes, it may subsequently cause a key up event to be lost, which may lead to + // to an embedded keypad) changes, it may subsequently cause a key up event to be lost, which may lead to // a movement key getting "stuck" down. This is bad. // This is an OS bug -- even the GetKeys() API doesn't tell you the key has been released. // This workaround causes all held-down keys to be reset whenever the state of the Fn key changes. This isn't @@ -2360,14 +2387,14 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e if (gDebugWindowProc) printf("Fn key state change event\n"); gKeyboard->resetKeys(); } - + if (gDebugWindowProc) fflush(stdout); mLastModifiers = modifiers; result = eventNotHandledErr; break; } - + mRawKeyEvent = NULL; } break; @@ -2462,7 +2489,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e case kEventMouseButtonSecondary: mCallbacks->handleRightMouseDown(this, outCoords, mask); break; - + case kEventMouseButtonTertiary: mCallbacks->handleMiddleMouseDown(this, outCoords, mask); break; @@ -2524,7 +2551,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e case kEventClassWindow: switch(evtKind) - { + { case kEventWindowActivated: if (mTSMDocument) { @@ -2539,20 +2566,20 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e } mCallbacks->handleFocusLost(this); break; - + case kEventWindowBoundsChanging: { // This is where we would constrain move/resize to a particular screen - const S32 MIN_WIDTH = 1024; - const S32 MIN_HEIGHT = 768; - + const S32 MIN_WIDTH = mMinWindowWidth; + const S32 MIN_HEIGHT = mMinWindowHeight; + Rect currentBounds; Rect previousBounds; GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, ¤tBounds); GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &previousBounds); - + // Put an offset into window un-maximize operation since the kEventWindowGetIdealSize // event only allows the specification of size and not position. if (mMaximized) @@ -2560,7 +2587,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e short leftOffset = mPreviousWindowRect.left - currentBounds.left; currentBounds.left += leftOffset; currentBounds.right += leftOffset; - + short topOffset = mPreviousWindowRect.top - currentBounds.top; currentBounds.top += topOffset; currentBounds.bottom += topOffset; @@ -2580,7 +2607,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e { currentBounds.bottom = currentBounds.top + MIN_HEIGHT; } - + SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), ¤tBounds); result = noErr; } @@ -2591,38 +2618,38 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e // Get new window bounds Rect newBounds; GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &newBounds); - + // Get previous window bounds Rect oldBounds; GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &oldBounds); - + // Determine if the new size is larger than the old bool newBoundsLarger = ((newBounds.right - newBounds.left) >= (oldBounds.right - oldBounds.left)); newBoundsLarger &= ((newBounds.bottom - newBounds.top) >= (oldBounds.bottom - oldBounds.top)); - + // Check to see if this is a zoom event (+ button on window pane) unsigned int eventParams; GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL, sizeof(int), NULL, &eventParams); bool isZoomEvent = ((eventParams & kWindowBoundsChangeZoom) != 0); - + // Maximized flag is if zoom event and increasing window size mMaximized = (isZoomEvent && newBoundsLarger); - + aglUpdateContext(mContext); - + mCallbacks->handleResize(this, newBounds.right - newBounds.left, newBounds.bottom - newBounds.top); } break; - + case kEventWindowGetIdealSize: // Only recommend a new ideal size when un-maximizing if (mMaximized == TRUE) { Point nonMaximizedSize; - + nonMaximizedSize.v = mPreviousWindowRect.bottom - mPreviousWindowRect.top; nonMaximizedSize.h = mPreviousWindowRect.right - mPreviousWindowRect.left; - + SetEventParameter(event, kEventParamDimensions, typeQDPoint, sizeof(Point), &nonMaximizedSize); result = noErr; } @@ -2677,7 +2704,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e if (mPreeditor) { switch(evtKind) - { + { case kEventTSMDocumentAccessGetLength: { @@ -2696,14 +2723,14 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e { // Return the selected range, excluding preedit. // In our preeditor, preedit and selection are exclusive, so, - // when it has a preedit, there is no selection and the + // when it has a preedit, there is no selection and the // insertion point is on the preedit that corrupses into the // beginning of the preedit when the preedit was removed. S32 preedit, preedit_length; mPreeditor->getPreeditRange(&preedit, &preedit_length); const LLWString & text = mPreeditor->getPreeditString(); - + CFRange range; if (preedit_length) { @@ -2767,7 +2794,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e memcpy(target_pointer, text_utf16.c_str() + range.location, range.length * sizeof(UniChar)); // Note that result has already been set above. - } + } } break; @@ -2782,46 +2809,52 @@ const char* cursorIDToName(int id) { switch (id) { - case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW"; - case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT"; - case UI_CURSOR_HAND: return "UI_CURSOR_HAND"; - case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM"; - case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS"; - case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE"; - case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW"; - case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE"; - case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS"; - case UI_CURSOR_NO: return "UI_CURSOR_NO"; - case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING"; - case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB"; - case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND"; - case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS"; - case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE"; - case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG"; - case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY"; - case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI"; - case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI"; - case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED"; - case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED"; - case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED"; - case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE"; - case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE"; - case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE"; - case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA"; - case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN"; - case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN"; - case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3"; - case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; - case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; - case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; - case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; - case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT"; - case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; - case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; + case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW"; + case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT"; + case UI_CURSOR_HAND: return "UI_CURSOR_HAND"; + case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM"; + case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS"; + case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE"; + case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW"; + case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE"; + case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS"; + case UI_CURSOR_NO: return "UI_CURSOR_NO"; + case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING"; + case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB"; + case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND"; + case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS"; + case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE"; + case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG"; + case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY"; + case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI"; + case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI"; + case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED"; + case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED"; + case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED"; + case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE"; + case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE"; + case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE"; + case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA"; + case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN"; + case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN"; + case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3"; + case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; + case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; + case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; + case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; + case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT"; + case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; + case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; + case UI_CURSOR_TOOLPATHFINDING: return "UI_CURSOR_PATHFINDING"; + case UI_CURSOR_TOOLPATHFINDING_PATH_START: return "UI_CURSOR_PATHFINDING_START"; + case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: return "UI_CURSOR_PATHFINDING_START_ADD"; + case UI_CURSOR_TOOLPATHFINDING_PATH_END: return "UI_CURSOR_PATHFINDING_END"; + case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: return "UI_CURSOR_PATHFINDING_END_ADD"; + case UI_CURSOR_TOOLNO: return "UI_CURSOR_NO"; } llerrs << "cursorIDToName: unknown cursor id" << id << llendl; - + return "UI_CURSOR_ARROW"; } @@ -2837,42 +2870,42 @@ static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY) fullpath += gDirUtilp->getDirDelimiter(); fullpath += cursorIDToName(cursorid); fullpath += ".tif"; - + gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY); } -void LLWindowMacOSX::setCursor(ECursorType cursor) +void LLWindowMacOSX::updateCursor() { OSStatus result = noErr; - if (mDragOverrideCursor != -1) + if (mDragOverrideCursor != -1) { // A drag is in progress...remember the requested cursor and we'll // restore it when it is done - mCurrentCursor = cursor; + mCurrentCursor = mNextCursor; return; } - if (cursor == UI_CURSOR_ARROW + if (mNextCursor == UI_CURSOR_ARROW && mBusyCount > 0) { - cursor = UI_CURSOR_WORKING; + mNextCursor = UI_CURSOR_WORKING; } - if(mCurrentCursor == cursor) + if(mCurrentCursor == mNextCursor) return; // RN: replace multi-drag cursors with single versions - if (cursor == UI_CURSOR_ARROWDRAGMULTI) + if (mNextCursor == UI_CURSOR_ARROWDRAGMULTI) { - cursor = UI_CURSOR_ARROWDRAG; + mNextCursor = UI_CURSOR_ARROWDRAG; } - else if (cursor == UI_CURSOR_ARROWCOPYMULTI) + else if (mNextCursor == UI_CURSOR_ARROWCOPYMULTI) { - cursor = UI_CURSOR_ARROWCOPY; + mNextCursor = UI_CURSOR_ARROWCOPY; } - switch(cursor) + switch(mNextCursor) { default: case UI_CURSOR_ARROW: @@ -2923,7 +2956,13 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) case UI_CURSOR_TOOLSIT: case UI_CURSOR_TOOLBUY: case UI_CURSOR_TOOLOPEN: - result = setImageCursor(gCursors[cursor]); + case UI_CURSOR_TOOLPATHFINDING: + case UI_CURSOR_TOOLPATHFINDING_PATH_START: + case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: + case UI_CURSOR_TOOLPATHFINDING_PATH_END: + case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: + case UI_CURSOR_TOOLNO: + result = setImageCursor(gCursors[mNextCursor]); break; } @@ -2933,7 +2972,7 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) InitCursor(); } - mCurrentCursor = cursor; + mCurrentCursor = mNextCursor; } ECursorType LLWindowMacOSX::getCursor() const @@ -2967,6 +3006,12 @@ void LLWindowMacOSX::initCursors() initPixmapCursor(UI_CURSOR_TOOLSIT, 20, 15); initPixmapCursor(UI_CURSOR_TOOLBUY, 20, 15); initPixmapCursor(UI_CURSOR_TOOLOPEN, 20, 15); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLNO, 8, 8); initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10); initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10); @@ -3268,14 +3313,14 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) LLSD LLWindowMacOSX::getNativeKeyData() { LLSD result = LLSD::emptyMap(); - + if(mRawKeyEvent) { char char_code = 0; UInt32 key_code = 0; UInt32 modifiers = 0; UInt32 keyboard_type = 0; - + GetEventParameter (mRawKeyEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &char_code); GetEventParameter (mRawKeyEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code); GetEventParameter (mRawKeyEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); @@ -3285,7 +3330,7 @@ LLSD LLWindowMacOSX::getNativeKeyData() result["key_code"] = (S32)key_code; result["modifiers"] = (S32)modifiers; result["keyboard_type"] = (S32)keyboard_type; - + #if 0 // This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc) // cause llsd serialization to create XML that the llsd deserializer won't parse! @@ -3294,7 +3339,7 @@ LLSD LLWindowMacOSX::getNativeKeyData() EventParamType actualType = typeUTF8Text; UInt32 actualSize = 0; char *buffer = NULL; - + err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL); if(err == noErr) { @@ -3307,7 +3352,7 @@ LLSD LLWindowMacOSX::getNativeKeyData() } delete[] buffer; } - + result["unicode"] = unicode; #endif @@ -3315,7 +3360,7 @@ LLSD LLWindowMacOSX::getNativeKeyData() lldebugs << "native key data is: " << result << llendl; - + return result; } @@ -3362,17 +3407,17 @@ void *LLWindowMacOSX::getPlatformWindow() void *LLWindowMacOSX::getMediaWindow() { - /* - Mozilla needs to be initialized with a WindowRef to function properly. + /* + Mozilla needs to be initialized with a WindowRef to function properly. (There's no good reason for this, since it shouldn't be interacting with our window in any way, but that's another issue.) - If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window, + If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window, which trips up Mozilla. Instead of using our actual window, we create an invisible window which will persist for the lifetime of the application and pass that to Mozilla. This satisfies its deep-seated need to latch onto a WindowRef and solves the issue with switching between fullscreen and windowed modes. Note that we will never destroy this window (by design!), but since only one will ever be created per run of the application, that's okay. */ - + if(sMediaWindow == NULL) { Rect window_rect = {100, 100, 200, 200}; @@ -3381,13 +3426,13 @@ void *LLWindowMacOSX::getMediaWindow() NULL, &window_rect, (ConstStr255Param) "\p", - false, // Create the window invisible. + false, // Create the window invisible. zoomDocProc, // Window with a grow box and a zoom box kLastWindowOfClass, // create it behind other windows false, // no close box 0); } - + return (void*)sMediaWindow; } @@ -3437,7 +3482,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) } UseInputWindow(mTSMDocument, !b); - + // Take care of old and new preeditors. if (preeditor != mPreeditor || !b) { @@ -3456,7 +3501,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) return; } mLanguageTextInputAllowed = b; - + if (b) { if (mTSMScriptCode != smRoman) @@ -3505,7 +3550,7 @@ MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; } if(modifiers & optionKey) { mask |= MASK_ALT; } return mask; -} +} #if LL_OS_DRAGDROP_ENABLED @@ -3516,53 +3561,53 @@ OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; lldebugs << "drag tracking handler, message = " << message << llendl; - + switch(message) { case kDragTrackingInWindow: result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_TRACK); break; - + case kDragTrackingEnterHandler: result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_START_TRACKING); break; - + case kDragTrackingLeaveHandler: result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_STOP_TRACKING); break; - + default: break; } - + return result; } -OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, +OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef drag) -{ +{ LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED); } OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action) -{ +{ OSErr result = dragNotAcceptedErr; // overall function result OSErr err = noErr; // for local error handling - + // Get the mouse position and modifiers of this drag. SInt16 modifiers, mouseDownModifiers, mouseUpModifiers; ::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers); MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); - + Point mouse_point; // This will return the mouse point in global screen coords ::GetDragMouse(drag, &mouse_point, NULL); LLCoordScreen screen_coords(mouse_point.h, mouse_point.v); LLCoordGL gl_pos; convertCoords(screen_coords, &gl_pos); - + // Look at the pasteboard and try to extract an URL from it PasteboardRef pasteboard; if(GetDragPasteboard(drag, &pasteboard) == noErr) @@ -3570,22 +3615,22 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop ItemCount num_items = 0; // Treat an error here as an item count of 0 (void)PasteboardGetItemCount(pasteboard, &num_items); - + // Only deal with single-item drags. if(num_items == 1) { PasteboardItemID item_id = NULL; CFArrayRef flavors = NULL; CFDataRef data = NULL; - + err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based. - + // Try to extract an URL from the pasteboard if(err == noErr) { err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors); } - + if(err == noErr) { if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL)) @@ -3598,9 +3643,9 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop // This is a string that might be an URL. err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data); } - + } - + if(flavors != NULL) { CFRelease(flavors); @@ -3611,12 +3656,12 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop std::string url; url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data)); CFRelease(data); - + if(!url.empty()) { - LLWindowCallbacks::DragNDropResult res = + LLWindowCallbacks::DragNDropResult res = mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); - + switch (res) { case LLWindowCallbacks::DND_NONE: // No drop allowed if (action == LLWindowCallbacks::DNDA_TRACK) @@ -3651,7 +3696,7 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop // Restore the cursor ECursorType temp_cursor = mCurrentCursor; // get around the "setting the same cursor" code in setCursor() - mCurrentCursor = UI_CURSOR_COUNT; + mCurrentCursor = UI_CURSOR_COUNT; setCursor(temp_cursor); } else { @@ -3663,7 +3708,7 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop } } } - + return result; } diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 6c9e075a21..af83b50097 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -36,8 +36,8 @@ #include <AGL/agl.h> // AssertMacros.h does bad things. +#include "fix_macros.h" #undef verify -#undef check #undef require @@ -58,7 +58,8 @@ public: /*virtual*/ BOOL getSize(LLCoordScreen *size); /*virtual*/ BOOL getSize(LLCoordWindow *size); /*virtual*/ BOOL setPosition(LLCoordScreen position); - /*virtual*/ BOOL setSize(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); @@ -67,7 +68,7 @@ public: /*virtual*/ void showCursorFromMouseMove(); /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void setCursor(ECursorType cursor); + /*virtual*/ void updateCursor(); /*virtual*/ ECursorType getCursor() const; /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index fd4bd635e2..8f70aee4f6 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -50,7 +50,7 @@ public: /*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;}; /*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;}; /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; - /*virtual*/ BOOL setSize(LLCoordScreen size) {return FALSE;}; + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; @@ -59,7 +59,7 @@ public: /*virtual*/ void showCursorFromMouseMove() {}; /*virtual*/ void hideCursorUntilMouseMove() {}; /*virtual*/ BOOL isCursorHidden() {return FALSE;}; - /*virtual*/ void setCursor(ECursorType cursor) {}; + /*virtual*/ void updateCursor() {}; //virtual ECursorType getCursor() { return mCurrentCursor; }; /*virtual*/ void captureMouse() {}; /*virtual*/ void releaseMouse() {}; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 8acb52516a..a15114cb9b 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -63,9 +63,6 @@ extern BOOL gDebugWindowProc; const S32 MAX_NUM_RESOLUTIONS = 200; -const S32 MIN_WINDOW_WIDTH = 1024; -const S32 MIN_WINDOW_HEIGHT = 768; - // static variable for ATI mouse cursor crash work-around: static bool ATIbug = false; @@ -966,7 +963,7 @@ BOOL LLWindowSDL::setPosition(const LLCoordScreen position) return TRUE; } -BOOL LLWindowSDL::setSize(const LLCoordScreen size) +BOOL LLWindowSDL::setSizeImpl(const LLCoordScreen size) { if(mWindow) { @@ -984,6 +981,25 @@ BOOL LLWindowSDL::setSize(const LLCoordScreen size) return FALSE; } +BOOL LLWindowSDL::setSizeImpl(const LLCoordWindow size) +{ + if(mWindow) + { + // Push a resize event onto SDL's queue - we'll handle it + // when it comes out again. + SDL_Event event; + event.type = SDL_VIDEORESIZE; + event.resize.w = size.mX; + event.resize.h = size.mY; + SDL_PushEvent(&event); // copied into queue + + return TRUE; + } + + return FALSE; +} + + void LLWindowSDL::swapBuffers() { if (mWindow) @@ -1036,6 +1052,25 @@ void LLWindowSDL::setMouseClipping( BOOL b ) //SDL_WM_GrabInput(b ? SDL_GRAB_ON : SDL_GRAB_OFF); } +// virtual +void LLWindowSDL::setMinSize(U32 min_width, U32 min_height, bool enforce_immediately) +{ + LLWindow::setMinSize(min_width, min_height, enforce_immediately); + +#if LL_X11 + // Set the minimum size limits for X11 window + // so the window manager doesn't allow resizing below those limits. + XSizeHints* hints = XAllocSizeHints(); + hints->flags |= PMinSize; + hints->min_width = mMinWindowWidth; + hints->min_height = mMinWindowHeight; + + XSetWMNormalHints(mSDL_Display, mSDL_XWindowID, hints); + + XFree(hints); +#endif +} + BOOL LLWindowSDL::setCursorPosition(const LLCoordWindow position) { BOOL result = TRUE; @@ -1849,8 +1884,8 @@ void LLWindowSDL::gatherInput() llinfos << "Handling a resize event: " << event.resize.w << "x" << event.resize.h << llendl; - S32 width = llmax(event.resize.w, MIN_WINDOW_WIDTH); - S32 height = llmax(event.resize.h, MIN_WINDOW_HEIGHT); + S32 width = llmax(event.resize.w, (S32)mMinWindowWidth); + S32 height = llmax(event.resize.h, (S32)mMinWindowHeight); // *FIX: I'm not sure this is necessary! mWindow = SDL_SetVideoMode(width, height, 32, mSDLFlags); @@ -1866,7 +1901,7 @@ void LLWindowSDL::gatherInput() } break; } - + mCallbacks->handleResize(this, width, height); break; } @@ -1920,6 +1955,8 @@ void LLWindowSDL::gatherInput() break; } } + + updateCursor(); #if LL_X11 // This is a good time to stop flashing the icon if our mFlashTimer has @@ -2006,7 +2043,7 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty return sdlcursor; } -void LLWindowSDL::setCursor(ECursorType cursor) +void LLWindowSDL::updateCursor() { if (ATIbug) { // cursor-updating is very flaky when this bug is @@ -2014,11 +2051,11 @@ void LLWindowSDL::setCursor(ECursorType cursor) return; } - if (mCurrentCursor != cursor) + if (mCurrentCursor != mNextCursor) { - if (cursor < UI_CURSOR_COUNT) + if (mNextCursor < UI_CURSOR_COUNT) { - SDL_Cursor *sdlcursor = mSDLCursors[cursor]; + SDL_Cursor *sdlcursor = mSDLCursors[mNextCursor]; // Try to default to the arrow for any cursors that // did not load correctly. if (!sdlcursor && mSDLCursors[UI_CURSOR_ARROW]) @@ -2026,9 +2063,9 @@ void LLWindowSDL::setCursor(ECursorType cursor) if (sdlcursor) SDL_SetCursor(sdlcursor); } else { - llwarns << "Tried to set invalid cursor number " << cursor << llendl; + llwarns << "Tried to set invalid cursor number " << mNextCursor << llendl; } - mCurrentCursor = cursor; + mCurrentCursor = mNextCursor; } } @@ -2080,6 +2117,12 @@ void LLWindowSDL::initCursors() mSDLCursors[UI_CURSOR_TOOLSIT] = makeSDLCursorFromBMP("toolsit.BMP",20,15); mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",20,15); mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",20,15); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING] = makeSDLCursorFromBMP("lltoolpathfinding.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START] = makeSDLCursorFromBMP("lltoolpathfindingpathstart.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathstartadd.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END] = makeSDLCursorFromBMP("lltoolpathfindingpathend.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathendadd.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLNO] = makeSDLCursorFromBMP("llno.BMP",8,8); if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) { llinfos << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << llendl; @@ -2473,6 +2516,23 @@ void exec_cmd(const std::string& cmd, const std::string& arg) // Must begin with protocol identifier. void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) { + bool found = false; + S32 i; + for (i = 0; i < gURLProtocolWhitelistCount; i++) + { + if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos) + { + found = true; + break; + } + } + + if (!found) + { + llwarns << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << llendl; + return; + } + llinfos << "spawn_web_browser: " << escaped_url << llendl; #if LL_LINUX || LL_SOLARIS @@ -2603,8 +2663,9 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() if (sortpat) { // Sort the list of system fonts from most-to-least-desirable. + FcResult result; fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, - NULL, NULL); + NULL, &result); FcPatternDestroy(sortpat); } diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index fa544b16ce..c5ce892a04 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -41,8 +41,8 @@ #endif // AssertMacros.h does bad things. +#include "fix_macros.h" #undef verify -#undef check #undef require @@ -63,7 +63,8 @@ public: /*virtual*/ BOOL getSize(LLCoordScreen *size); /*virtual*/ BOOL getSize(LLCoordWindow *size); /*virtual*/ BOOL setPosition(LLCoordScreen position); - /*virtual*/ BOOL setSize(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); @@ -72,10 +73,11 @@ public: /*virtual*/ void showCursorFromMouseMove(); /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void setCursor(ECursorType cursor); + /*virtual*/ void updateCursor(); /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); /*virtual*/ void setMouseClipping( BOOL b ); + /*virtual*/ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); /*virtual*/ BOOL isClipboardTextAvailable(); /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 799f0a3fab..43c0090993 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -58,7 +58,6 @@ #include <dinput.h> #include <Dbt.h.> -#include "llmemtype.h" // culled from winuser.h #ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ const S32 WM_MOUSEWHEEL = 0x020A; @@ -367,6 +366,10 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags) { + + //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways + LoadLibrary(L"opengl32.dll"); + mFSAASamples = fsaa_samples; mIconResource = gIconResource; mOverrideAspectRatio = 0.f; @@ -862,7 +865,7 @@ BOOL LLWindowWin32::setPosition(const LLCoordScreen position) return TRUE; } -BOOL LLWindowWin32::setSize(const LLCoordScreen size) +BOOL LLWindowWin32::setSizeImpl(const LLCoordScreen size) { LLCoordScreen position; @@ -872,10 +875,30 @@ BOOL LLWindowWin32::setSize(const LLCoordScreen size) return FALSE; } + WINDOWPLACEMENT placement; + placement.length = sizeof(WINDOWPLACEMENT); + + if (!GetWindowPlacement(mWindowHandle, &placement)) return FALSE; + + placement.showCmd = SW_RESTORE; + + if (!SetWindowPlacement(mWindowHandle, &placement)) return FALSE; + moveWindow(position, size); return TRUE; } +BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) +{ + RECT window_rect = {0, 0, size.mX, size.mY }; + DWORD dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + DWORD dw_style = WS_OVERLAPPEDWINDOW; + + AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); + + return setSizeImpl(LLCoordScreen(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top)); +} + // changing fullscreen resolution BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) { @@ -886,12 +909,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO DWORD current_refresh; DWORD dw_ex_style; DWORD dw_style; - RECT window_rect; + RECT window_rect = {0, 0, 0, 0}; S32 width = size.mX; S32 height = size.mY; BOOL auto_show = FALSE; - if (mhRC) + if (mhRC) { auto_show = TRUE; resetDisplayResolution(); @@ -986,7 +1009,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO dw_ex_style = WS_EX_APPWINDOW; dw_style = WS_POPUP; - // Move window borders out not to cover window contents + // Move window borders out not to cover window contents. + // This converts client rect to window rect, i.e. expands it by the window border size. AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); } // If it failed, we don't want to run fullscreen @@ -1014,6 +1038,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO dw_style = WS_OVERLAPPEDWINDOW; } + // don't post quit messages when destroying old windows mPostQuit = FALSE; @@ -1065,6 +1090,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO return FALSE; } + LL_INFOS("Window") << "Device context retrieved." << llendl ; + if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) { close(); @@ -1073,6 +1100,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO return FALSE; } + LL_INFOS("Window") << "Pixel format chosen." << llendl ; + // Verify what pixel format we actually received. if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) @@ -1083,6 +1112,37 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO return FALSE; } + // (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash + LL_INFOS("Window") << "--- begin pixel format dump ---" << llendl ; + LL_INFOS("Window") << "pixel_format is " << pixel_format << llendl ; + LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << llendl ; + LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << llendl ; + LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << llendl ; + LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << llendl ; + LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << llendl ; + LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << llendl ; + LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << llendl ; + LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << llendl ; + LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << llendl ; + LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << llendl ; + LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << llendl ; + LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << llendl ; + LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << llendl ; + LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << llendl ; + LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << llendl ; + LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << llendl ; + LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << llendl ; + LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << llendl ; + LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << llendl ; + LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << llendl ; + LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << llendl ; + LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << llendl ; + LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << llendl ; + LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << llendl ; + LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << llendl ; + LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << llendl ; + LL_INFOS("Window") << "--- end pixel format dump ---" << llendl ; + if (pfd.cColorBits < 32) { close(); @@ -1420,7 +1480,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } else { - llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << " context." << llendl; + llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << + (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << llendl; done = true; if (LLRender::sGLCoreProfile) @@ -1510,24 +1571,16 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) { - LLCoordScreen screen_pos; - mMousePositionModified = TRUE; if (!mWindowHandle) { return FALSE; } - if (!convertCoords(position, &screen_pos)) - { - return FALSE; - } // Inform the application of the new mouse position (needed for per-frame // hover/picking to function). - LLCoordGL gl_pos; - convertCoords(position, &gl_pos); - mCallbacks->handleMouseMove(this, gl_pos, (MASK)0); + mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking. // Because we have preemptively notified the application of the new @@ -1537,24 +1590,23 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) { } - return SetCursorPos(screen_pos.mX, screen_pos.mY); + LLCoordScreen screen_pos(position.convert()); + return ::SetCursorPos(screen_pos.mX, screen_pos.mY); } BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position) { POINT cursor_point; - LLCoordScreen screen_pos; - if (!mWindowHandle || - !GetCursorPos(&cursor_point)) + if (!mWindowHandle + || !GetCursorPos(&cursor_point) + || !position) { return FALSE; } - screen_pos.mX = cursor_point.x; - screen_pos.mY = cursor_point.y; - - return convertCoords(screen_pos, position); + *position = LLCoordScreen(cursor_point.x, cursor_point.y).convert(); + return TRUE; } void LLWindowWin32::hideCursor() @@ -1649,6 +1701,12 @@ void LLWindowWin32::initCursors() mCursor[ UI_CURSOR_TOOLSIT ] = LoadCursor(module, TEXT("TOOLSIT")); mCursor[ UI_CURSOR_TOOLBUY ] = LoadCursor(module, TEXT("TOOLBUY")); mCursor[ UI_CURSOR_TOOLOPEN ] = LoadCursor(module, TEXT("TOOLOPEN")); + mCursor[ UI_CURSOR_TOOLPATHFINDING ] = LoadCursor(module, TEXT("TOOLPATHFINDING")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTARTADD")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTART")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHEND")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHENDADD")); + mCursor[ UI_CURSOR_TOOLNO ] = LoadCursor(module, TEXT("TOOLNO")); // Color cursors mCursor[ UI_CURSOR_TOOLPLAY ] = loadColorCursor(TEXT("TOOLPLAY")); @@ -1667,18 +1725,18 @@ void LLWindowWin32::initCursors() -void LLWindowWin32::setCursor(ECursorType cursor) +void LLWindowWin32::updateCursor() { - if (cursor == UI_CURSOR_ARROW + if (mNextCursor == UI_CURSOR_ARROW && mBusyCount > 0) { - cursor = UI_CURSOR_WORKING; + mNextCursor = UI_CURSOR_WORKING; } - if( mCurrentCursor != cursor ) + if( mCurrentCursor != mNextCursor ) { - mCurrentCursor = cursor; - SetCursor( mCursor[cursor] ); + mCurrentCursor = mNextCursor; + SetCursor( mCursor[mNextCursor] ); } } @@ -1714,9 +1772,7 @@ void LLWindowWin32::gatherInput() MSG msg; int msg_count = 0; - LLMemType m1(LLMemType::MTYPE_GATHER_INPUT); - - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && msg_count < MAX_MESSAGE_PER_UPDATE) + while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput"); TranslateMessage(&msg); @@ -1760,6 +1816,8 @@ void LLWindowWin32::gatherInput() mInputProcessingPaused = FALSE; + updateCursor(); + // clear this once we've processed all mouse messages that might have occurred after // we slammed the mouse position mMousePositionModified = FALSE; @@ -1770,6 +1828,10 @@ static LLFastTimer::DeclareTimer FTM_MOUSEHANDLER("Handle Mouse"); LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param) { + // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN. + // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. + static bool sHandleLeftMouseUp = true; + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA); @@ -2116,10 +2178,20 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE)); return 0; + case WM_NCLBUTTONDOWN: + { + window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN"); + // A click in a non-client area, e.g. title bar or window border. + sHandleLeftMouseUp = false; + } + break; + case WM_LBUTTONDOWN: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN"); LLFastTimer t2(FTM_MOUSEHANDLER); + sHandleLeftMouseUp = true; + if (LLWinImm::isAvailable() && window_imp->mPreeditor) { window_imp->interruptLanguageTextInput(); @@ -2130,15 +2202,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2160,15 +2232,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2184,6 +2256,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP"); LLFastTimer t2(FTM_MOUSEHANDLER); + + if (!sHandleLeftMouseUp) + { + sHandleLeftMouseUp = true; + break; + } + //if (gDebugClicks) //{ // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; @@ -2193,15 +2272,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2228,15 +2307,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2257,15 +2336,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2292,15 +2371,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2321,15 +2400,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks // will occur at the wrong location. JC - LLCoordWindow cursor_coord_window; if (window_imp->mMousePositionModified) { + LLCoordWindow cursor_coord_window; window_imp->getCursorPosition(&cursor_coord_window); - window_imp->convertCoords(cursor_coord_window, &gl_coord); + gl_coord = cursor_coord_window.convert(); } else { - window_imp->convertCoords(window_coord, &gl_coord); + gl_coord = window_coord.convert(); } MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates @@ -2401,17 +2480,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_MOUSEMOVE: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEMOVE"); - window_imp->convertCoords(window_coord, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask); return 0; } case WM_GETMINMAXINFO: { LPMINMAXINFO min_max = (LPMINMAXINFO)l_param; - min_max->ptMinTrackSize.x = 1024; - min_max->ptMinTrackSize.y = 768; + min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth; + min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight; return 0; } @@ -3291,7 +3369,7 @@ void LLWindowWin32::setLanguageTextInput( const LLCoordGL & position ) LLWinImm::setCompositionWindow( himc, &ime_form ); - sWinIMEWindowPosition.set( win_pos.mX, win_pos.mY ); + sWinIMEWindowPosition = win_pos; } LLWinImm::releaseContext(mWindowHandle, himc); diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 387e4cbdb6..54c9ac4d4d 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -57,7 +57,8 @@ public: /*virtual*/ BOOL getSize(LLCoordScreen *size); /*virtual*/ BOOL getSize(LLCoordWindow *size); /*virtual*/ BOOL setPosition(LLCoordScreen position); - /*virtual*/ BOOL setSize(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); @@ -66,7 +67,7 @@ public: /*virtual*/ void showCursorFromMouseMove(); /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void setCursor(ECursorType cursor); + /*virtual*/ void updateCursor(); /*virtual*/ ECursorType getCursor() const; /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); |