diff options
Diffstat (limited to 'indra/llwindow')
| -rw-r--r-- | indra/llwindow/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | indra/llwindow/llkeyboard.cpp | 12 | ||||
| -rw-r--r-- | indra/llwindow/llkeyboard.h | 20 | ||||
| -rw-r--r-- | indra/llwindow/llkeyboardheadless.cpp | 4 | ||||
| -rw-r--r-- | indra/llwindow/llkeyboardheadless.h | 9 | ||||
| -rw-r--r-- | indra/llwindow/llkeyboardsdl.cpp | 459 | ||||
| -rw-r--r-- | indra/llwindow/llkeyboardsdl.h | 27 | ||||
| -rw-r--r-- | indra/llwindow/llopenglview-objc.h | 5 | ||||
| -rw-r--r-- | indra/llwindow/llopenglview-objc.mm | 94 | ||||
| -rw-r--r-- | indra/llwindow/llwindow.cpp | 24 | ||||
| -rw-r--r-- | indra/llwindow/llwindow.h | 2 | ||||
| -rw-r--r-- | indra/llwindow/llwindowheadless.h | 2 | ||||
| -rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 1 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.cpp | 2078 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.h | 319 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 2 | 
16 files changed, 1579 insertions, 1490 deletions
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 08b3df87ab..69f11991ea 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -52,7 +52,6 @@ set(llwindow_LINK_LIBRARIES          llcommon          llimage          llmath -        llrender          llfilesystem          llxml          ll::glm @@ -60,9 +59,12 @@ set(llwindow_LINK_LIBRARIES          ll::uilibraries          ll::SDL          ) + +include_directories(${CMAKE_SOURCE_DIR}/llrender) +  # Libraries on which this library depends, needed for Linux builds  # Sort by high-level to low-level -if (LINUX) +if (NOT (DARWIN OR WINDOWS))    list(APPEND viewer_SOURCE_FILES         llkeyboardsdl.cpp         llwindowsdl.cpp @@ -84,8 +86,7 @@ if (LINUX)          fontconfig          # For FCInit and other FC* functions.          )    endif (BUILD_HEADLESS) - -endif (LINUX) +endif ()  if (DARWIN)    list(APPEND llwindow_SOURCE_FILES @@ -184,3 +185,5 @@ endif (SDL_FOUND)  if (DARWIN)    target_link_libraries(llwindow ${CARBON_LIBRARY})  endif (DARWIN) + +include(LibraryInstall) diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 33eebdadd1..a16c0a318a 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -41,7 +41,6 @@ std::map<KEY,std::string> LLKeyboard::sKeysToNames;  std::map<std::string,KEY> LLKeyboard::sNamesToKeys;  LLKeyStringTranslatorFunc*  LLKeyboard::mStringTranslator = NULL;   // Used for l10n + PC/Mac/Linux accelerator labeling -  //  // Class Implementation  // @@ -195,12 +194,11 @@ void LLKeyboard::resetKeys()  } -bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key) +bool LLKeyboard::translateKey(const NATIVE_KEY_TYPE os_key, KEY *out_key)  { -    std::map<U16, KEY>::iterator iter;      // Only translate keys in the map, ignore all other keys for now -    iter = mTranslateKeyMap.find(os_key); +    auto iter = mTranslateKeyMap.find(os_key);      if (iter == mTranslateKeyMap.end())      {          //LL_WARNS() << "Unknown virtual key " << os_key << LL_ENDL; @@ -214,11 +212,9 @@ bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key)      }  } - -U16 LLKeyboard::inverseTranslateKey(const KEY translated_key) +LLKeyboard::NATIVE_KEY_TYPE LLKeyboard::inverseTranslateKey(const KEY translated_key)  { -    std::map<KEY, U16>::iterator iter; -    iter = mInvTranslateKeyMap.find(translated_key); +    auto iter = mInvTranslateKeyMap.find(translated_key);      if (iter == mInvTranslateKeyMap.end())      {          return 0; diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 713eb7aec2..a527227672 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -55,6 +55,11 @@ class LLWindowCallbacks;  class LLKeyboard  {  public: +#ifndef LL_SDL +    typedef U16 NATIVE_KEY_TYPE; +#else +    typedef U32 NATIVE_KEY_TYPE; +#endif      LLKeyboard();      virtual ~LLKeyboard(); @@ -67,16 +72,15 @@ public:      bool            getKeyDown(const KEY key) { return mKeyLevel[key]; }      bool            getKeyRepeated(const KEY key) { return mKeyRepeated[key]; } -    bool            translateKey(const U16 os_key, KEY *translated_key); -    U16             inverseTranslateKey(const KEY translated_key); +    bool            translateKey(const NATIVE_KEY_TYPE os_key, KEY *translated_key); +    NATIVE_KEY_TYPE     inverseTranslateKey(const KEY translated_key);      bool            handleTranslatedKeyUp(KEY translated_key, U32 translated_mask);     // Translated into "Linden" keycodes      bool            handleTranslatedKeyDown(KEY translated_key, U32 translated_mask);   // Translated into "Linden" keycodes +    virtual bool    handleKeyUp(const NATIVE_KEY_TYPE key, MASK mask) = 0; +    virtual bool    handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) = 0; -    virtual bool    handleKeyUp(const U16 key, MASK mask) = 0; -    virtual bool    handleKeyDown(const U16 key, MASK mask) = 0; - -#ifdef LL_DARWIN +#if defined(LL_DARWIN) && !defined(LL_SDL)      // We only actually use this for macOS.      virtual void    handleModifier(MASK mask) = 0;  #endif // LL_DARWIN @@ -111,8 +115,8 @@ protected:      void            addKeyName(KEY key, const std::string& name);  protected: -    std::map<U16, KEY>  mTranslateKeyMap;       // Map of translations from OS keys to Linden KEYs -    std::map<KEY, U16>  mInvTranslateKeyMap;    // Map of translations from Linden KEYs to OS keys +    std::map<NATIVE_KEY_TYPE, KEY>  mTranslateKeyMap;       // Map of translations from OS keys to Linden KEYs +    std::map<KEY, NATIVE_KEY_TYPE>  mInvTranslateKeyMap;    // Map of translations from Linden KEYs to OS keys      LLWindowCallbacks *mCallbacks;      LLTimer         mKeyLevelTimer[KEY_COUNT];  // Time since level was set diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp index 8669a5b41a..6f8c829dd5 100644 --- a/indra/llwindow/llkeyboardheadless.cpp +++ b/indra/llwindow/llkeyboardheadless.cpp @@ -35,12 +35,8 @@ void LLKeyboardHeadless::resetMaskKeys()  { } -bool LLKeyboardHeadless::handleKeyDown(const U16 key, const U32 mask) -{ return false; } -bool LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask) -{ return false; }  MASK LLKeyboardHeadless::currentMask(bool for_mouse_event)  { return MASK_NONE; } diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h index 2528f0e3f1..439abaf25b 100644 --- a/indra/llwindow/llkeyboardheadless.h +++ b/indra/llwindow/llkeyboardheadless.h @@ -35,8 +35,13 @@ public:      LLKeyboardHeadless();      /*virtual*/ ~LLKeyboardHeadless() {}; -    /*virtual*/ bool    handleKeyUp(const U16 key, MASK mask); -    /*virtual*/ bool    handleKeyDown(const U16 key, MASK mask); +#ifndef LL_SDL +    /*virtual*/ bool    handleKeyUp(const U16 key, MASK mask) { return false; } +    /*virtual*/ bool    handleKeyDown(const U16 key, MASK mask) { return false; } +#else +    /*virtual*/ bool    handleKeyUp(const U32 key, MASK mask) { return false; } +    /*virtual*/ bool    handleKeyDown(const U32 key, MASK mask) { return false; } +#endif      /*virtual*/ void    resetMaskKeys();      /*virtual*/ MASK    currentMask(bool for_mouse_event);      /*virtual*/ void    scanKeyboard(); diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index 97198f0cc0..72b4577276 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -1,6 +1,5 @@  /** - * @file llkeyboardsdl.cpp - * @brief Handler for assignable key bindings + * @author This module has many fathers, and it shows.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code @@ -24,12 +23,11 @@   * $/LicenseInfo$   */ -#if LL_SDL -  #include "linden_common.h"  #include "llkeyboardsdl.h"  #include "llwindowcallbacks.h" -#include "SDL/SDL.h" +#include "SDL2/SDL.h" +#include "SDL2/SDL_keycode.h"  LLKeyboardSDL::LLKeyboardSDL()  { @@ -40,6 +38,10 @@ LLKeyboardSDL::LLKeyboardSDL()      // Virtual key mappings from SDL_keysym.h ...      // SDL maps the letter keys to the ASCII you'd expect, but it's lowercase... + +    // <FS:ND> Looks like we need to map those despite of SDL_TEXTINPUT handling most of this, but without +    // the translation lower->upper here accelerators will not work. +      U16 cur_char;      for (cur_char = 'A'; cur_char <= 'Z'; cur_char++)      { @@ -68,13 +70,12 @@ LLKeyboardSDL::LLKeyboardSDL()      //mTranslateKeyMap[SDLK_KP3] = KEY_PAGE_DOWN;      //mTranslateKeyMap[SDLK_KP0] = KEY_INSERT; -    mTranslateKeyMap[SDLK_SPACE] = ' '; +    mTranslateKeyMap[SDLK_SPACE] = ' ';     // <FS:ND/> Those are handled by SDL2 via text input, do not map them      mTranslateKeyMap[SDLK_RETURN] = KEY_RETURN;      mTranslateKeyMap[SDLK_LEFT] = KEY_LEFT;      mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT;      mTranslateKeyMap[SDLK_UP] = KEY_UP;      mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN; -    mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;      mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN;      mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;      mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE; @@ -111,40 +112,39 @@ LLKeyboardSDL::LLKeyboardSDL()      mTranslateKeyMap[SDLK_F10] = KEY_F10;      mTranslateKeyMap[SDLK_F11] = KEY_F11;      mTranslateKeyMap[SDLK_F12] = KEY_F12; -    mTranslateKeyMap[SDLK_PLUS]   = '='; -    mTranslateKeyMap[SDLK_COMMA]  = ','; -    mTranslateKeyMap[SDLK_MINUS]  = '-'; -    mTranslateKeyMap[SDLK_PERIOD] = '.'; -    mTranslateKeyMap[SDLK_BACKQUOTE] = '`'; -    mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE; -    mTranslateKeyMap[SDLK_SEMICOLON] = ';'; -    mTranslateKeyMap[SDLK_LEFTBRACKET] = '['; -    mTranslateKeyMap[SDLK_BACKSLASH] = '\\'; -    mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']'; -    mTranslateKeyMap[SDLK_QUOTE] = '\''; +    mTranslateKeyMap[SDLK_PLUS]   = '='; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_COMMA]  = ','; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_MINUS]  = '-'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_PERIOD] = '.'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_BACKQUOTE] = '`'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_SEMICOLON] = ';'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_LEFTBRACKET] = '['; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_BACKSLASH] = '\\'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them +    mTranslateKeyMap[SDLK_QUOTE] = '\''; // <FS:ND/> Those are handled by SDL2 via text input, do not map them      // Build inverse map -    std::map<U16, KEY>::iterator iter; -    for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) +    for (auto iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)      {          mInvTranslateKeyMap[iter->second] = iter->first;      }      // numpad map -    mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS; -    mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END; -    mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN; -    mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN; -    mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT; -    mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER; -    mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT; -    mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME; -    mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP; -    mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP; +    mTranslateNumpadMap[SDLK_KP_0] = KEY_PAD_INS; +    mTranslateNumpadMap[SDLK_KP_1] = KEY_PAD_END; +    mTranslateNumpadMap[SDLK_KP_2] = KEY_PAD_DOWN; +    mTranslateNumpadMap[SDLK_KP_3] = KEY_PAD_PGDN; +    mTranslateNumpadMap[SDLK_KP_4] = KEY_PAD_LEFT; +    mTranslateNumpadMap[SDLK_KP_5] = KEY_PAD_CENTER; +    mTranslateNumpadMap[SDLK_KP_6] = KEY_PAD_RIGHT; +    mTranslateNumpadMap[SDLK_KP_7] = KEY_PAD_HOME; +    mTranslateNumpadMap[SDLK_KP_8] = KEY_PAD_UP; +    mTranslateNumpadMap[SDLK_KP_9] = KEY_PAD_PGUP;      mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL;      // build inverse numpad map -    for (iter = mTranslateNumpadMap.begin(); +    for (auto iter = mTranslateNumpadMap.begin();           iter != mTranslateNumpadMap.end();           iter++)      { @@ -154,7 +154,7 @@ LLKeyboardSDL::LLKeyboardSDL()  void LLKeyboardSDL::resetMaskKeys()  { -    SDLMod mask = SDL_GetModState(); +    SDL_Keymod mask = SDL_GetModState();      // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().      //    It looks a bit suspicious, as it won't correct for keys that have been released. @@ -165,7 +165,11 @@ void LLKeyboardSDL::resetMaskKeys()          mKeyLevel[KEY_SHIFT] = true;      } -    if(mask & KMOD_CTRL) +    if(mask & (KMOD_CTRL +#ifdef LL_DARWIN +        | KMOD_GUI +#endif +        ))      {          mKeyLevel[KEY_CONTROL] = true;      } @@ -187,7 +191,11 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask)          out_mask |= MASK_SHIFT;      } -    if(mask & KMOD_CTRL) +    if(mask & (KMOD_CTRL +#ifdef LL_DARWIN +        | KMOD_GUI +#endif +        ))      {          out_mask |= MASK_CONTROL;      } @@ -201,34 +209,34 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask)  } -static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask) +static U32 adjustNativekeyFromUnhandledMask(const U32 key, const U32 mask)  {      // SDL doesn't automatically adjust the keysym according to      // whether NUMLOCK is engaged, so we massage the keysym manually. -    U16 rtn = key; +    U32 rtn = key;      if (!(mask & KMOD_NUM))      {          switch (key)          { -        case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; -        case SDLK_KP0: rtn = SDLK_INSERT; break; -        case SDLK_KP1: rtn = SDLK_END; break; -        case SDLK_KP2: rtn = SDLK_DOWN; break; -        case SDLK_KP3: rtn = SDLK_PAGEDOWN; break; -        case SDLK_KP4: rtn = SDLK_LEFT; break; -        case SDLK_KP6: rtn = SDLK_RIGHT; break; -        case SDLK_KP7: rtn = SDLK_HOME; break; -        case SDLK_KP8: rtn = SDLK_UP; break; -        case SDLK_KP9: rtn = SDLK_PAGEUP; break; +            case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; +            case SDLK_KP_0: rtn = SDLK_INSERT; break; +            case SDLK_KP_1: rtn = SDLK_END; break; +            case SDLK_KP_2: rtn = SDLK_DOWN; break; +            case SDLK_KP_3: rtn = SDLK_PAGEDOWN; break; +            case SDLK_KP_4: rtn = SDLK_LEFT; break; +            case SDLK_KP_6: rtn = SDLK_RIGHT; break; +            case SDLK_KP_7: rtn = SDLK_HOME; break; +            case SDLK_KP_8: rtn = SDLK_UP; break; +            case SDLK_KP_9: rtn = SDLK_PAGEUP; break;          }      }      return rtn;  } -bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) +bool LLKeyboardSDL::handleKeyDown(const U32 key, const U32 mask)  { -    U16     adjusted_nativekey; +    U32 adjusted_nativekey;      KEY translated_key = 0;      U32 translated_mask = MASK_NONE;      bool    handled = false; @@ -246,9 +254,9 @@ bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask)  } -bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask) +bool LLKeyboardSDL::handleKeyUp(const U32 key, const U32 mask)  { -    U16     adjusted_nativekey; +    U32 adjusted_nativekey;      KEY translated_key = 0;      U32 translated_mask = MASK_NONE;      bool    handled = false; @@ -268,16 +276,20 @@ bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask)  MASK LLKeyboardSDL::currentMask(bool for_mouse_event)  {      MASK result = MASK_NONE; -    SDLMod mask = SDL_GetModState(); +    SDL_Keymod mask = SDL_GetModState(); -    if (mask & KMOD_SHIFT)          result |= MASK_SHIFT; -    if (mask & KMOD_CTRL)           result |= MASK_CONTROL; -    if (mask & KMOD_ALT)            result |= MASK_ALT; +    if (mask & KMOD_SHIFT) +        result |= MASK_SHIFT; +    if (mask & KMOD_CTRL) +        result |= MASK_CONTROL; +    if (mask & KMOD_ALT) +        result |= MASK_ALT;      // For keyboard events, consider Meta keys equivalent to Control      if (!for_mouse_event)      { -        if (mask & KMOD_META) result |= MASK_CONTROL; +        if (mask & KMOD_GUI) +            result |= MASK_CONTROL;      }      return result; @@ -310,7 +322,7 @@ void LLKeyboardSDL::scanKeyboard()  } -bool LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key) +bool LLKeyboardSDL::translateNumpadKey( const U32 os_key, KEY *translated_key)  {      return translateKey(os_key, translated_key);  } @@ -320,5 +332,338 @@ U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)      return inverseTranslateKey(translated_key);  } -#endif +enum class WindowsVK : U32 +{ +    VK_UNKNOWN = 0, +    VK_CANCEL = 0x03, +    VK_BACK = 0x08, +    VK_TAB = 0x09, +    VK_CLEAR = 0x0C, +    VK_RETURN = 0x0D, +    VK_SHIFT = 0x10, +    VK_CONTROL = 0x11, +    VK_MENU = 0x12, +    VK_PAUSE = 0x13, +    VK_CAPITAL = 0x14, +    VK_KANA = 0x15, +    VK_HANGUL = 0x15, +    VK_JUNJA = 0x17, +    VK_FINAL = 0x18, +    VK_HANJA = 0x19, +    VK_KANJI = 0x19, +    VK_ESCAPE = 0x1B, +    VK_CONVERT = 0x1C, +    VK_NONCONVERT = 0x1D, +    VK_ACCEPT = 0x1E, +    VK_MODECHANGE = 0x1F, +    VK_SPACE = 0x20, +    VK_PRIOR = 0x21, +    VK_NEXT = 0x22, +    VK_END = 0x23, +    VK_HOME = 0x24, +    VK_LEFT = 0x25, +    VK_UP = 0x26, +    VK_RIGHT = 0x27, +    VK_DOWN = 0x28, +    VK_SELECT = 0x29, +    VK_PRINT = 0x2A, +    VK_EXECUTE = 0x2B, +    VK_SNAPSHOT = 0x2C, +    VK_INSERT = 0x2D, +    VK_DELETE = 0x2E, +    VK_HELP = 0x2F, +    VK_0 = 0x30, +    VK_1 = 0x31, +    VK_2 = 0x32, +    VK_3 = 0x33, +    VK_4 = 0x34, +    VK_5 = 0x35, +    VK_6 = 0x36, +    VK_7 = 0x37, +    VK_8 = 0x38, +    VK_9 = 0x39, +    VK_A = 0x41, +    VK_B = 0x42, +    VK_C = 0x43, +    VK_D = 0x44, +    VK_E = 0x45, +    VK_F = 0x46, +    VK_G = 0x47, +    VK_H = 0x48, +    VK_I = 0x49, +    VK_J = 0x4A, +    VK_K = 0x4B, +    VK_L = 0x4C, +    VK_M = 0x4D, +    VK_N = 0x4E, +    VK_O = 0x4F, +    VK_P = 0x50, +    VK_Q = 0x51, +    VK_R = 0x52, +    VK_S = 0x53, +    VK_T = 0x54, +    VK_U = 0x55, +    VK_V = 0x56, +    VK_W = 0x57, +    VK_X = 0x58, +    VK_Y = 0x59, +    VK_Z = 0x5A, +    VK_LWIN = 0x5B, +    VK_RWIN = 0x5C, +    VK_APPS = 0x5D, +    VK_SLEEP = 0x5F, +    VK_NUMPAD0 = 0x60, +    VK_NUMPAD1 = 0x61, +    VK_NUMPAD2 = 0x62, +    VK_NUMPAD3 = 0x63, +    VK_NUMPAD4 = 0x64, +    VK_NUMPAD5 = 0x65, +    VK_NUMPAD6 = 0x66, +    VK_NUMPAD7 = 0x67, +    VK_NUMPAD8 = 0x68, +    VK_NUMPAD9 = 0x69, +    VK_MULTIPLY = 0x6A, +    VK_ADD = 0x6B, +    VK_SEPARATOR = 0x6C, +    VK_SUBTRACT = 0x6D, +    VK_DECIMAL = 0x6E, +    VK_DIVIDE = 0x6F, +    VK_F1 = 0x70, +    VK_F2 = 0x71, +    VK_F3 = 0x72, +    VK_F4 = 0x73, +    VK_F5 = 0x74, +    VK_F6 = 0x75, +    VK_F7 = 0x76, +    VK_F8 = 0x77, +    VK_F9 = 0x78, +    VK_F10 = 0x79, +    VK_F11 = 0x7A, +    VK_F12 = 0x7B, +    VK_F13 = 0x7C, +    VK_F14 = 0x7D, +    VK_F15 = 0x7E, +    VK_F16 = 0x7F, +    VK_F17 = 0x80, +    VK_F18 = 0x81, +    VK_F19 = 0x82, +    VK_F20 = 0x83, +    VK_F21 = 0x84, +    VK_F22 = 0x85, +    VK_F23 = 0x86, +    VK_F24 = 0x87, +    VK_NUMLOCK = 0x90, +    VK_SCROLL = 0x91, +    VK_LSHIFT = 0xA0, +    VK_RSHIFT = 0xA1, +    VK_LCONTROL = 0xA2, +    VK_RCONTROL = 0xA3, +    VK_LMENU = 0xA4, +    VK_RMENU = 0xA5, +    VK_BROWSER_BACK = 0xA6, +    VK_BROWSER_FORWARD = 0xA7, +    VK_BROWSER_REFRESH = 0xA8, +    VK_BROWSER_STOP = 0xA9, +    VK_BROWSER_SEARCH = 0xAA, +    VK_BROWSER_FAVORITES = 0xAB, +    VK_BROWSER_HOME = 0xAC, +    VK_VOLUME_MUTE = 0xAD, +    VK_VOLUME_DOWN = 0xAE, +    VK_VOLUME_UP = 0xAF, +    VK_MEDIA_NEXT_TRACK = 0xB0, +    VK_MEDIA_PREV_TRACK = 0xB1, +    VK_MEDIA_STOP = 0xB2, +    VK_MEDIA_PLAY_PAUSE = 0xB3, +    VK_MEDIA_LAUNCH_MAIL = 0xB4, +    VK_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5, +    VK_MEDIA_LAUNCH_APP1 = 0xB6, +    VK_MEDIA_LAUNCH_APP2 = 0xB7, +    VK_OEM_1 = 0xBA, +    VK_OEM_PLUS = 0xBB, +    VK_OEM_COMMA = 0xBC, +    VK_OEM_MINUS = 0xBD, +    VK_OEM_PERIOD = 0xBE, +    VK_OEM_2 = 0xBF, +    VK_OEM_3 = 0xC0, +    VK_OEM_4 = 0xDB, +    VK_OEM_5 = 0xDC, +    VK_OEM_6 = 0xDD, +    VK_OEM_7 = 0xDE, +    VK_OEM_8 = 0xDF, +    VK_OEM_102 = 0xE2, +    VK_PROCESSKEY = 0xE5, +    VK_PACKET = 0xE7, +    VK_ATTN = 0xF6, +    VK_CRSEL = 0xF7, +    VK_EXSEL = 0xF8, +    VK_EREOF = 0xF9, +    VK_PLAY = 0xFA, +    VK_ZOOM = 0xFB, +    VK_NONAME = 0xFC, +    VK_PA1 = 0xFD, +    VK_OEM_CLEAR = 0xFE, +}; + +std::map< U32, U32 > mSDL2_to_Win; +std::set< U32 > mIgnoreSDL2Keys; + +U32 LLKeyboardSDL::mapSDL2toWin( U32 aSymbol ) +{ +    // <FS:ND> Map SDLK_ virtual keys to Windows VK_ virtual keys. +    // Text is handled via unicode input (SDL_TEXTINPUT event) and does not need to be translated into VK_ values as those match already. +    if( mSDL2_to_Win.empty() ) +    { +        mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::VK_BACK; +        mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::VK_TAB; +        mSDL2_to_Win[ 12 ] = (U32)WindowsVK::VK_CLEAR; +        mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::VK_RETURN; +        mSDL2_to_Win[ 19 ] = (U32)WindowsVK::VK_PAUSE; +        mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::VK_ESCAPE; +        mSDL2_to_Win[ SDLK_SPACE ] = (U32)WindowsVK::VK_SPACE; +        mSDL2_to_Win[ SDLK_QUOTE ] = (U32)WindowsVK::VK_OEM_7; +        mSDL2_to_Win[ SDLK_COMMA ] = (U32)WindowsVK::VK_OEM_COMMA; +        mSDL2_to_Win[ SDLK_MINUS ] = (U32)WindowsVK::VK_OEM_MINUS; +        mSDL2_to_Win[ SDLK_PERIOD ] = (U32)WindowsVK::VK_OEM_PERIOD; +        mSDL2_to_Win[ SDLK_SLASH ] = (U32)WindowsVK::VK_OEM_2; + +        mSDL2_to_Win[ SDLK_0 ] = (U32)WindowsVK::VK_0; +        mSDL2_to_Win[ SDLK_1 ] = (U32)WindowsVK::VK_1; +        mSDL2_to_Win[ SDLK_2 ] = (U32)WindowsVK::VK_2; +        mSDL2_to_Win[ SDLK_3 ] = (U32)WindowsVK::VK_3; +        mSDL2_to_Win[ SDLK_4 ] = (U32)WindowsVK::VK_4; +        mSDL2_to_Win[ SDLK_5 ] = (U32)WindowsVK::VK_5; +        mSDL2_to_Win[ SDLK_6 ] = (U32)WindowsVK::VK_6; +        mSDL2_to_Win[ SDLK_7 ] = (U32)WindowsVK::VK_7; +        mSDL2_to_Win[ SDLK_8 ] = (U32)WindowsVK::VK_8; +        mSDL2_to_Win[ SDLK_9 ] = (U32)WindowsVK::VK_9; + +        mSDL2_to_Win[ SDLK_SEMICOLON ] = (U32)WindowsVK::VK_OEM_1; +        mSDL2_to_Win[ SDLK_LESS ] = (U32)WindowsVK::VK_OEM_102; +        mSDL2_to_Win[ SDLK_EQUALS ] = (U32)WindowsVK::VK_OEM_PLUS; +        mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::VK_OEM_PLUS; + +        mSDL2_to_Win[ SDLK_LEFTBRACKET ] = (U32)WindowsVK::VK_OEM_4; +        mSDL2_to_Win[ SDLK_BACKSLASH ] = (U32)WindowsVK::VK_OEM_5; +        mSDL2_to_Win[ SDLK_RIGHTBRACKET ] = (U32)WindowsVK::VK_OEM_6; +        mSDL2_to_Win[ SDLK_BACKQUOTE ] = (U32)WindowsVK::VK_OEM_8; + +        mSDL2_to_Win[ SDLK_a ] = (U32)WindowsVK::VK_A; +        mSDL2_to_Win[ SDLK_b ] = (U32)WindowsVK::VK_B; +        mSDL2_to_Win[ SDLK_c ] = (U32)WindowsVK::VK_C; +        mSDL2_to_Win[ SDLK_d ] = (U32)WindowsVK::VK_D; +        mSDL2_to_Win[ SDLK_e ] = (U32)WindowsVK::VK_E; +        mSDL2_to_Win[ SDLK_f ] = (U32)WindowsVK::VK_F; +        mSDL2_to_Win[ SDLK_g ] = (U32)WindowsVK::VK_G; +        mSDL2_to_Win[ SDLK_h ] = (U32)WindowsVK::VK_H; +        mSDL2_to_Win[ SDLK_i ] = (U32)WindowsVK::VK_I; +        mSDL2_to_Win[ SDLK_j ] = (U32)WindowsVK::VK_J; +        mSDL2_to_Win[ SDLK_k ] = (U32)WindowsVK::VK_K; +        mSDL2_to_Win[ SDLK_l ] = (U32)WindowsVK::VK_L; +        mSDL2_to_Win[ SDLK_m ] = (U32)WindowsVK::VK_M; +        mSDL2_to_Win[ SDLK_n ] = (U32)WindowsVK::VK_N; +        mSDL2_to_Win[ SDLK_o ] = (U32)WindowsVK::VK_O; +        mSDL2_to_Win[ SDLK_p ] = (U32)WindowsVK::VK_P; +        mSDL2_to_Win[ SDLK_q ] = (U32)WindowsVK::VK_Q; +        mSDL2_to_Win[ SDLK_r ] = (U32)WindowsVK::VK_R; +        mSDL2_to_Win[ SDLK_s ] = (U32)WindowsVK::VK_S; +        mSDL2_to_Win[ SDLK_t ] = (U32)WindowsVK::VK_T; +        mSDL2_to_Win[ SDLK_u ] = (U32)WindowsVK::VK_U; +        mSDL2_to_Win[ SDLK_v ] = (U32)WindowsVK::VK_V; +        mSDL2_to_Win[ SDLK_w ] = (U32)WindowsVK::VK_W; +        mSDL2_to_Win[ SDLK_x ] = (U32)WindowsVK::VK_X; +        mSDL2_to_Win[ SDLK_y ] = (U32)WindowsVK::VK_Y; +        mSDL2_to_Win[ SDLK_z ] = (U32)WindowsVK::VK_Z; + +        mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::VK_DELETE; + + +        mSDL2_to_Win[ SDLK_NUMLOCKCLEAR ] = (U32)WindowsVK::VK_NUMLOCK; +        mSDL2_to_Win[ SDLK_SCROLLLOCK ] = (U32)WindowsVK::VK_SCROLL; + +        mSDL2_to_Win[ SDLK_HELP ] = (U32)WindowsVK::VK_HELP; +        mSDL2_to_Win[ SDLK_PRINTSCREEN ] = (U32)WindowsVK::VK_SNAPSHOT; +        mSDL2_to_Win[ SDLK_CANCEL ] = (U32)WindowsVK::VK_CANCEL; +        mSDL2_to_Win[ SDLK_APPLICATION ] = (U32)WindowsVK::VK_APPS; + +        mSDL2_to_Win[ SDLK_UNKNOWN    ] = (U32)WindowsVK::VK_UNKNOWN; +        mSDL2_to_Win[ SDLK_BACKSPACE  ] = (U32)WindowsVK::VK_BACK; +        mSDL2_to_Win[ SDLK_TAB        ] = (U32)WindowsVK::VK_TAB; +        mSDL2_to_Win[ SDLK_CLEAR      ] = (U32)WindowsVK::VK_CLEAR; +        mSDL2_to_Win[ SDLK_RETURN     ] = (U32)WindowsVK::VK_RETURN; +        mSDL2_to_Win[ SDLK_PAUSE      ] = (U32)WindowsVK::VK_PAUSE; +        mSDL2_to_Win[ SDLK_ESCAPE     ] = (U32)WindowsVK::VK_ESCAPE; +        mSDL2_to_Win[ SDLK_DELETE     ] = (U32)WindowsVK::VK_DELETE; + +        mSDL2_to_Win[ SDLK_KP_PERIOD  ] = (U32)WindowsVK::VK_OEM_PERIOD; // VK_DECIMAL? +        mSDL2_to_Win[ SDLK_KP_DIVIDE  ] = (U32)WindowsVK::VK_DIVIDE; +        mSDL2_to_Win[ SDLK_KP_MULTIPLY] = (U32)WindowsVK::VK_MULTIPLY; +        mSDL2_to_Win[ SDLK_KP_MINUS   ] = (U32)WindowsVK::VK_OEM_MINUS; // VK_SUBSTRACT? +        mSDL2_to_Win[ SDLK_KP_PLUS    ] = (U32)WindowsVK::VK_OEM_PLUS;  // VK_ADD? +        mSDL2_to_Win[ SDLK_KP_ENTER   ] = (U32)WindowsVK::VK_RETURN; +        mSDL2_to_Win[ SDLK_KP_0 ] = (U32)WindowsVK::VK_NUMPAD0; +        mSDL2_to_Win[ SDLK_KP_1 ] = (U32)WindowsVK::VK_NUMPAD1; +        mSDL2_to_Win[ SDLK_KP_2 ] = (U32)WindowsVK::VK_NUMPAD2; +        mSDL2_to_Win[ SDLK_KP_3 ] = (U32)WindowsVK::VK_NUMPAD3; +        mSDL2_to_Win[ SDLK_KP_4 ] = (U32)WindowsVK::VK_NUMPAD4; +        mSDL2_to_Win[ SDLK_KP_5 ] = (U32)WindowsVK::VK_NUMPAD5; +        mSDL2_to_Win[ SDLK_KP_6 ] = (U32)WindowsVK::VK_NUMPAD6; +        mSDL2_to_Win[ SDLK_KP_7 ] = (U32)WindowsVK::VK_NUMPAD7; +        mSDL2_to_Win[ SDLK_KP_8 ] = (U32)WindowsVK::VK_NUMPAD8; +        mSDL2_to_Win[ SDLK_KP_9 ] = (U32)WindowsVK::VK_NUMPAD9; + +        // ? + +        mSDL2_to_Win[ SDLK_UP         ] = (U32)WindowsVK::VK_UP; +        mSDL2_to_Win[ SDLK_DOWN       ] = (U32)WindowsVK::VK_DOWN; +        mSDL2_to_Win[ SDLK_RIGHT      ] = (U32)WindowsVK::VK_RIGHT; +        mSDL2_to_Win[ SDLK_LEFT       ] = (U32)WindowsVK::VK_LEFT; +        mSDL2_to_Win[ SDLK_INSERT     ] = (U32)WindowsVK::VK_INSERT; +        mSDL2_to_Win[ SDLK_HOME       ] = (U32)WindowsVK::VK_HOME; +        mSDL2_to_Win[ SDLK_END        ] = (U32)WindowsVK::VK_END; +        mSDL2_to_Win[ SDLK_PAGEUP     ] = (U32)WindowsVK::VK_PRIOR; +        mSDL2_to_Win[ SDLK_PAGEDOWN   ] = (U32)WindowsVK::VK_NEXT; +        mSDL2_to_Win[ SDLK_F1         ] = (U32)WindowsVK::VK_F1; +        mSDL2_to_Win[ SDLK_F2         ] = (U32)WindowsVK::VK_F2; +        mSDL2_to_Win[ SDLK_F3         ] = (U32)WindowsVK::VK_F3; +        mSDL2_to_Win[ SDLK_F4         ] = (U32)WindowsVK::VK_F4; +        mSDL2_to_Win[ SDLK_F5         ] = (U32)WindowsVK::VK_F5; +        mSDL2_to_Win[ SDLK_F6         ] = (U32)WindowsVK::VK_F6; +        mSDL2_to_Win[ SDLK_F7         ] = (U32)WindowsVK::VK_F7; +        mSDL2_to_Win[ SDLK_F8         ] = (U32)WindowsVK::VK_F8; +        mSDL2_to_Win[ SDLK_F9         ] = (U32)WindowsVK::VK_F9; +        mSDL2_to_Win[ SDLK_F10        ] = (U32)WindowsVK::VK_F10; +        mSDL2_to_Win[ SDLK_F11        ] = (U32)WindowsVK::VK_F11; +        mSDL2_to_Win[ SDLK_F12        ] = (U32)WindowsVK::VK_F12; +        mSDL2_to_Win[ SDLK_F13        ] = (U32)WindowsVK::VK_F13; +        mSDL2_to_Win[ SDLK_F14        ] = (U32)WindowsVK::VK_F14; +        mSDL2_to_Win[ SDLK_F15        ] = (U32)WindowsVK::VK_F15; +        mSDL2_to_Win[ SDLK_CAPSLOCK   ] = (U32)WindowsVK::VK_CAPITAL; +        mSDL2_to_Win[ SDLK_RSHIFT     ] = (U32)WindowsVK::VK_SHIFT; +        mSDL2_to_Win[ SDLK_LSHIFT     ] = (U32)WindowsVK::VK_SHIFT; +        mSDL2_to_Win[ SDLK_RCTRL      ] = (U32)WindowsVK::VK_CONTROL; +        mSDL2_to_Win[ SDLK_LCTRL      ] = (U32)WindowsVK::VK_CONTROL; +        mSDL2_to_Win[ SDLK_RALT       ] = (U32)WindowsVK::VK_MENU; +        mSDL2_to_Win[ SDLK_LALT       ] = (U32)WindowsVK::VK_MENU; + +        mSDL2_to_Win[ SDLK_MENU       ] = (U32)WindowsVK::VK_MENU; + +        // VK_MODECHANGE ? +        // mSDL2_to_Win[ SDLK_MODE       ] = (U32)WindowsVK::VK_MODE; + +        // ? +        // mSDL2_to_Win[ SDLK_SYSREQ     ] = (U32)WindowsVK::VK_SYSREQ; +        // mSDL2_to_Win[ SDLK_POWER      ] = (U32)WindowsVK::VK_POWER; +        // mSDL2_to_Win[ SDLK_UNDO       ] = (U32)WindowsVK::VK_UNDO; +        // mSDL2_to_Win[ SDLK_KP_EQUALS  ] = (U32)WindowsVK::VK_EQUALS; +        // mSDL2_to_Win[ 311 ] = (U32)WindowsVK::VK_LWIN; +        // mSDL2_to_Win[ 312 ] = (U32)WindowsVK::VK_RWIN; +        // mSDL2_to_Win[ SDLK_COLON ] = ? +    } + +    auto itr = mSDL2_to_Win.find( aSymbol ); +    if( itr != mSDL2_to_Win.end() ) +        return itr->second; + +    return aSymbol; +} diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h index fd348b28f2..3af098c4d1 100644 --- a/indra/llwindow/llkeyboardsdl.h +++ b/indra/llwindow/llkeyboardsdl.h @@ -1,8 +1,7 @@  /** - * @file llkeyboardsdl.h - * @brief Handler for assignable key bindings + * @author This module has many fathers, and it shows.   * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc.   * @@ -24,11 +23,14 @@   * $/LicenseInfo$   */ -#ifndef LL_LLKEYBOARDSDL_H -#define LL_LLKEYBOARDSDL_H +#ifndef LL_LLKEYBOARDSDL2_H +#define LL_LLKEYBOARDSDL2_H  #include "llkeyboard.h" -#include "SDL/SDL.h" +#if !defined(__i386__) && !defined(__x86_64__) +#define SDL_DISABLE_IMMINTRIN_H +#endif +#include "SDL2/SDL.h"  class LLKeyboardSDL : public LLKeyboard  { @@ -36,8 +38,8 @@ public:      LLKeyboardSDL();      /*virtual*/ ~LLKeyboardSDL() {}; -    /*virtual*/ bool    handleKeyUp(const U16 key, MASK mask); -    /*virtual*/ bool    handleKeyDown(const U16 key, MASK mask); +    /*virtual*/ bool    handleKeyUp(const U32 key, MASK mask); +    /*virtual*/ bool    handleKeyDown(const U32 key, MASK mask);      /*virtual*/ void    resetMaskKeys();      /*virtual*/ MASK    currentMask(bool for_mouse_event);      /*virtual*/ void    scanKeyboard(); @@ -45,11 +47,14 @@ public:  protected:      MASK    updateModifiers(const U32 mask);      void    setModifierKeyLevel( KEY key, bool new_state ); -    bool    translateNumpadKey( const U16 os_key, KEY *translated_key ); +    bool    translateNumpadKey( const U32 os_key, KEY *translated_key );      U16 inverseTranslateNumpadKey(const KEY translated_key);  private: -    std::map<U16, KEY> mTranslateNumpadMap;  // special map for translating OS keys to numpad keys -    std::map<KEY, U16> mInvTranslateNumpadMap; // inverse of the above +    std::map<U32, KEY> mTranslateNumpadMap;  // special map for translating OS keys to numpad keys +    std::map<KEY, U32> mInvTranslateNumpadMap; // inverse of the above + +public: +    static U32 mapSDL2toWin( U32 );  };  #endif diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index 028549b82e..a2c55a2dd9 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -42,6 +42,11 @@      unsigned int mMarkedTextLength;      bool mMarkedTextAllowed;      bool mSimulatedRightClick; + +    NSOpenGLPixelFormat *pixelFormat; +    NSOpenGLContext *glContext; + +    bool mHDRDisplay;  }  - (id) initWithSamples:(NSUInteger)samples;  - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync; diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index c9a62eedb1..57b1252cf1 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -31,6 +31,7 @@  #import <Carbon/Carbon.h>  extern BOOL gHiDPISupport; +extern BOOL gHDRDisplaySupport;  #pragma mark local functions @@ -111,6 +112,16 @@ attributedStringInfo getSegments(NSAttributedString *str)  @implementation LLOpenGLView +- (NSOpenGLContext*) glContext +{ +    return glContext; +} + +- (NSOpenGLPixelFormat*) pixelFormat +{ +    return pixelFormat; +} +  - (unsigned long)getVramSize  {      CGLRendererInfoObj info = 0; @@ -135,6 +146,22 @@ attributedStringInfo getSegments(NSAttributedString *str)  	return (unsigned long)vram_megabytes; // return value is in megabytes.  } +- (void)viewWillMoveToWindow:(nullable NSWindow *)newWindow +{ +    if(mHDRDisplay) +    { +        self.wantsExtendedDynamicRangeOpenGLSurface = YES; +        NSLog(@"Wants Extended Dynamic Range OpenGL", nil); +    } +    /* +    else +    { +        self.wantsExtendedDynamicRangeOpenGLSurface = NO; +        NSLog(@"Wants Standard Color Range OpenGL", nil); +    } +    */ +} +  - (void)viewDidMoveToWindow  {  	[[NSNotificationCenter defaultCenter] addObserver:self @@ -226,22 +253,57 @@ attributedStringInfo getSegments(NSAttributedString *str)  	// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.  	// Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.  	// 10.7 and 10.8 don't really care if we're defining a profile or not.  If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons). -	NSOpenGLPixelFormatAttribute attrs[] = { + +	NSOpenGLPixelFormatAttribute SDRAttrs[] = {          NSOpenGLPFANoRecovery,  		NSOpenGLPFADoubleBuffer,  		NSOpenGLPFAClosestPolicy,  		NSOpenGLPFAAccelerated, -		NSOpenGLPFASampleBuffers, 0, -		NSOpenGLPFASamples, 0, -		NSOpenGLPFAStencilSize, 8, +		//NSOpenGLPFASampleBuffers, samples, +		//NSOpenGLPFASamples, 0,  		NSOpenGLPFADepthSize, 24, -		NSOpenGLPFAAlphaSize, 8, -		NSOpenGLPFAColorSize, 24, +		//NSOpenGLPFAAlphaSize, 8, +		NSOpenGLPFAColorSize, 32,  		NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core,  		0      }; -	NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease]; +    NSOpenGLPixelFormatAttribute HDRAttrs[] = { +        NSOpenGLPFANoRecovery, +        NSOpenGLPFADoubleBuffer, +        NSOpenGLPFAClosestPolicy, +        NSOpenGLPFAAccelerated, +        //NSOpenGLPFASampleBuffers, samples, +        //NSOpenGLPFASamples, 0, +        NSOpenGLPFAColorFloat, +        NSOpenGLPFAColorSize, 64, +        NSOpenGLPFADepthSize, 24, +        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, +        0 +    }; + +	//NSOpenGLPixelFormat *pixelFormat = nil; + +    mHDRDisplay = NO; + +    if(gHDRDisplaySupport) +    { +        pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:HDRAttrs] autorelease]; +        if (pixelFormat == nil) +        { +            NSLog(@"Failed to create pixel format for HDR Display!", nil); +            pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:SDRAttrs] autorelease]; +        } +        else +        { +            NSLog(@"pixel format created successfully for HDR Display", nil); +            mHDRDisplay = YES; +        } +    } +    else +    { +        pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:SDRAttrs] autorelease]; +    }  	if (pixelFormat == nil)  	{ @@ -249,7 +311,7 @@ attributedStringInfo getSegments(NSAttributedString *str)  		return nil;  	} -	NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; +	glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];  	if (glContext == nil)  	{ @@ -259,6 +321,19 @@ attributedStringInfo getSegments(NSAttributedString *str)  	[self setPixelFormat:pixelFormat]; +    if(mHDRDisplay) +    { +        CGColorSpaceRef color_space = [self.window.colorSpace CGColorSpace]; +        CGColorSpaceRef color_space_extended = CGColorSpaceCreateExtended(color_space); +        NSColorSpace* extended_ns_color_space +                    = [[NSColorSpace alloc] initWithCGColorSpace:color_space_extended]; + +        self.window.colorSpace = extended_ns_color_space; +        CGColorSpaceRelease(color_space_extended); + +        NSLog(@"Extended color space applied for HDR Display", nil); +    } +  	//for retina support  	[self setWantsBestResolutionOpenGLSurface:gHiDPISupport]; @@ -280,6 +355,9 @@ attributedStringInfo getSegments(NSAttributedString *str)          [glContext setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval];  	} +    GLint opacity = 1; +    [glContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; +  	return self;  } diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index eb11a28360..935050485f 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -74,12 +74,12 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)      LL_WARNS() << "OSMessageBox: " << text << LL_ENDL;  #if LL_MESA_HEADLESS // !!! *FIX: (?)      return OSBTN_OK; +#elif LL_SDL +    result = OSMessageBoxSDL(text, caption, type);  #elif LL_WINDOWS      result = OSMessageBoxWin32(text, caption, type);  #elif LL_DARWIN      result = OSMessageBoxMacOSX(text, caption, type); -#elif LL_SDL -    result = OSMessageBoxSDL(text, caption, type);  #else  #error("OSMessageBox not implemented for this platform!")  #endif @@ -258,12 +258,12 @@ bool LLWindow::copyTextToPrimary(const LLWString &src)  // static  std::vector<std::string> LLWindow::getDynamicFallbackFontList()  { -#if LL_WINDOWS +#if LL_SDL +    return LLWindowSDL::getDynamicFallbackFontList(); +#elif LL_WINDOWS      return LLWindowWin32::getDynamicFallbackFontList();  #elif LL_DARWIN      return LLWindowMacOSX::getDynamicFallbackFontList(); -#elif LL_SDL -    return LLWindowSDL::getDynamicFallbackFontList();  #else      return std::vector<std::string>();  #endif @@ -272,12 +272,12 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList()  // static  std::vector<std::string> LLWindow::getDisplaysResolutionList()  { -#if LL_WINDOWS +#if LL_SDL +    return std::vector<std::string>(); +#elif LL_WINDOWS      return LLWindowWin32::getDisplaysResolutionList();  #elif LL_DARWIN      return LLWindowMacOSX::getDisplaysResolutionList(); -#else -    return std::vector<std::string>();  #endif  } @@ -358,9 +358,9 @@ void LLSplashScreen::show()  {      if (!gSplashScreenp)      { -#if LL_WINDOWS && !LL_MESA_HEADLESS +#if LL_WINDOWS && !LL_MESA_HEADLESS && !LL_SDL          gSplashScreenp = new LLSplashScreenWin32; -#elif LL_DARWIN +#elif LL_DARWIN && !LL_SDL          gSplashScreenp = new LLSplashScreenMacOSX;  #endif          if (gSplashScreenp) @@ -410,7 +410,7 @@ LLWindow* LLWindowManager::createWindow(      U32 max_cores,      F32 max_gl_version)  { -    LLWindow* new_window; +    LLWindow* new_window = nullptr;      if (use_gl)      { @@ -420,7 +420,7 @@ LLWindow* LLWindowManager::createWindow(              fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth);  #elif LL_SDL          new_window = new LLWindowSDL(callbacks, -            title, x, y, width, height, flags, +            title, name, x, y, width, height, flags,              fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);  #elif LL_WINDOWS          new_window = new LLWindowWin32(callbacks, diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index d0fa16b26a..8f8ea7fdb6 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -92,7 +92,7 @@ public:      virtual bool setCursorPosition(LLCoordWindow position) = 0;      virtual bool getCursorPosition(LLCoordWindow *position) = 0; -#if LL_WINDOWS +#if LL_WINDOWS && !LL_SDL      virtual bool getCursorDelta(LLCoordCommon* delta) = 0;  #endif      virtual void showCursor() = 0; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 5696b69a59..acec401133 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -60,7 +60,7 @@ public:      /*virtual*/ void toggleVSync(bool enable_vsync) override { }      /*virtual*/ bool setCursorPosition(LLCoordWindow position) override {return false;}      /*virtual*/ bool getCursorPosition(LLCoordWindow *position) override {return false;} -#if LL_WINDOWS +#if LL_WINDOWS && !LL_SDL      /*virtual*/ bool getCursorDelta(LLCoordCommon* delta) override { return false; }  #endif      /*virtual*/ void showCursor() override {} diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 030bd5ee7e..3ed935c0f2 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -52,6 +52,7 @@  extern bool gDebugWindowProc;  bool gHiDPISupport = true; +bool gHDRDisplaySupport = false;  const S32   BITS_PER_PIXEL = 32;  const S32   MAX_NUM_RESOLUTIONS = 32; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 7433ad6bd2..0a117be1fc 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -25,8 +25,6 @@   * $/LicenseInfo$   */ -#if LL_SDL -  #include "linden_common.h"  #include "llwindowsdl.h" @@ -40,31 +38,65 @@  #include "lldir.h"  #include "llfindlocale.h" -#if LL_GTK -extern "C" { -# include "gtk/gtk.h" -} -#include <locale.h> -#endif // LL_GTK +#ifdef LL_GLIB +#include <glib.h> +#endif  extern "C" {  # include "fontconfig/fontconfig.h"  } -#if LL_LINUX +#if LL_LINUX || __FreeBSD__  // not necessarily available on random SDL platforms, so #if LL_LINUX  // for execv(), waitpid(), fork()  # include <unistd.h>  # include <sys/types.h>  # include <sys/wait.h> +# define GLX_GLXEXT_PROTOTYPES 1 +# include <GL/glx.h> +# include <stdio.h>  #endif // LL_LINUX  extern bool gDebugWindowProc;  const S32 MAX_NUM_RESOLUTIONS = 200; -// static variable for ATI mouse cursor crash work-around: -static bool ATIbug = false; +#if LL_DARWIN + +#include <OpenGL/OpenGL.h> +#include <CoreGraphics/CGDirectDisplay.h> +#include <CoreServices/CoreServices.h> + +bool gHiDPISupport = true; + +namespace +{ +    struct NativeKeyEventData { +        enum EventType { +            KEYUNKNOWN, +            KEYUP, +            KEYDOWN, +            KEYCHAR +        }; + +        EventType   mKeyEvent = KEYUNKNOWN; +        uint32_t    mEventType = 0; +        uint32_t    mEventModifiers = 0; +        uint32_t    mEventKeyCode = 0; +        uint32_t    mEventChars = 0; +        uint32_t    mEventUnmodChars = 0; +        bool        mEventRepeat = false; +    } *mRawKeyEvent = NULL; +} +// +// LLWindowMacOSX +// + +bool LLWindowSDL::sUseMultGL = false; + +#endif + +bool hasHIDPI = 0;  //  // LLWindowSDL @@ -74,6 +106,10 @@ static bool ATIbug = false;  # include <X11/Xutil.h>  #endif //LL_X11 +#if LL_WINDOWS && !LL_MESA_HEADLESS +#pragma comment(lib, "dinput8") +#endif +  // TOFU HACK -- (*exactly* the same hack as LLWindowMacOSX for a similar  // set of reasons): Stash a pointer to the LLWindowSDL object here and  // maintain in the constructor and destructor.  This assumes that there will @@ -97,70 +133,6 @@ void maybe_unlock_display(void)  } -#if LL_GTK -// Lazily initialize and check the runtime GTK version for goodness. -// static -bool LLWindowSDL::ll_try_gtk_init(void) -{ -    static bool done_gtk_diag = false; -    static bool gtk_is_good = false; -    static bool done_setlocale = false; -    static bool tried_gtk_init = false; - -    if (!done_setlocale) -    { -        LL_INFOS() << "Starting GTK Initialization." << LL_ENDL; -        maybe_lock_display(); -        gtk_disable_setlocale(); -        maybe_unlock_display(); -        done_setlocale = true; -    } - -    if (!tried_gtk_init) -    { -        tried_gtk_init = true; -        if (!g_thread_supported ()) g_thread_init (NULL); -        maybe_lock_display(); -        gtk_is_good = gtk_init_check(NULL, NULL); -        maybe_unlock_display(); -        if (!gtk_is_good) -            LL_WARNS() << "GTK Initialization failed." << LL_ENDL; -    } - -    if (gtk_is_good && !done_gtk_diag) -    { -        LL_INFOS() << "GTK Initialized." << LL_ENDL; -        LL_INFOS() << "- Compiled against GTK version " -            << GTK_MAJOR_VERSION << "." -            << GTK_MINOR_VERSION << "." -            << GTK_MICRO_VERSION << LL_ENDL; -        LL_INFOS() << "- Running against GTK version " -            << gtk_major_version << "." -            << gtk_minor_version << "." -            << gtk_micro_version << LL_ENDL; -        maybe_lock_display(); -        const gchar* gtk_warning = gtk_check_version( -            GTK_MAJOR_VERSION, -            GTK_MINOR_VERSION, -            GTK_MICRO_VERSION); -        maybe_unlock_display(); -        if (gtk_warning) -        { -            LL_WARNS() << "- GTK COMPATIBILITY WARNING: " << -                gtk_warning << LL_ENDL; -            gtk_is_good = false; -        } else { -            LL_INFOS() << "- GTK version is good." << LL_ENDL; -        } - -        done_gtk_diag = true; -    } - -    return gtk_is_good; -} -#endif // LL_GTK - -  #if LL_X11  // static  Window LLWindowSDL::get_SDL_XWindowID(void) @@ -181,24 +153,28 @@ Display* LLWindowSDL::get_SDL_Display(void)  }  #endif // LL_X11 -  LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, -             const std::string& title, S32 x, S32 y, S32 width, -             S32 height, U32 flags, -             bool fullscreen, bool clearBg, -             bool disable_vsync, bool use_gl, -             bool ignore_pixel_depth, U32 fsaa_samples) -    : LLWindow(callbacks, fullscreen, flags), -      Lock_Display(NULL), -      Unlock_Display(NULL), mGamma(1.0f) +                         const std::string& title, const std::string& name, S32 x, S32 y, S32 width, +                         S32 height, U32 flags, +                         bool fullscreen, bool clearBg, +                         bool enable_vsync, bool use_gl, +                         bool ignore_pixel_depth, U32 fsaa_samples) +        : LLWindow(callbacks, fullscreen, flags), +        Lock_Display(NULL), +        Unlock_Display(NULL), mGamma(1.0f)  {      // Initialize the keyboard      gKeyboard = new LLKeyboardSDL();      gKeyboard->setCallbacks(callbacks);      // Note that we can't set up key-repeat until after SDL has init'd video +#if LL_DARWIN +    hasHIDPI = gHiDPISupport; +#endif +      // Ignore use_gl for now, only used for drones on PC      mWindow = NULL; +    mContext = {};      mNeedsResize = false;      mOverrideAspectRatio = 0.f;      mGrabbyKeyFlags = 0; @@ -209,26 +185,19 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,  #if LL_X11      mSDL_XWindowID = None; -    mSDL_Display = NULL; +    mSDL_Display = nullptr;  #endif // LL_X11 -#if LL_GTK -    // We MUST be the first to initialize GTK so that GTK doesn't get badly -    // initialized with a non-C locale and cause lots of serious random -    // weirdness. -    ll_try_gtk_init(); -#endif // LL_GTK -      // Assume 4:3 aspect ratio until we know better      mOriginalAspectRatio = 1024.0 / 768.0;      if (title.empty()) -        mWindowTitle = "SDL Window";  // *FIX: (?) +        mWindowTitle = "Second Life";      else          mWindowTitle = title;      // Create the GL context and set it up for windowed or fullscreen, as appropriate. -    if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) +    if(createContext(x, y, width, height, 32, fullscreen, enable_vsync))      {          gGLManager.initGL(); @@ -242,11 +211,8 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,      // Stash an object pointer for OSMessageBox()      gWindowImplementation = this; -#if LL_X11      mFlashing = false; -#endif // LL_X11 -    mKeyScanCode = 0;      mKeyVirtualKey = 0;      mKeyModifiers = KMOD_NONE;  } @@ -258,319 +224,221 @@ static SDL_Surface *Load_BMP_Resource(const char *basename)      // Figure out where our BMP is living on the disk      snprintf(path_buffer, PATH_BUFFER_SIZE-1, "%s%sres-sdl%s%s", -         gDirUtilp->getAppRODataDir().c_str(), -         gDirUtilp->getDirDelimiter().c_str(), -         gDirUtilp->getDirDelimiter().c_str(), -         basename); +             gDirUtilp->getAppRODataDir().c_str(), +             gDirUtilp->getDirDelimiter().c_str(), +             gDirUtilp->getDirDelimiter().c_str(), +             basename);      path_buffer[PATH_BUFFER_SIZE-1] = '\0';      return SDL_LoadBMP(path_buffer);  } -#if LL_X11 -// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM -// on this machine.  It works by searching /var/log/var/log/Xorg.?.log or -// /var/log/XFree86.?.log for a ': (VideoRAM ?|Memory): (%d+) kB' regex, where -// '?' is the X11 display number derived from $DISPLAY -static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str) -{ -    const int line_buf_size = 1000; -    char line_buf[line_buf_size]; -    while (fgets(line_buf, line_buf_size, fp)) -    { -        //LL_DEBUGS() << "XLOG: " << line_buf << LL_ENDL; - -        // Why the ad-hoc parser instead of using a regex?  Our -        // favourite regex implementation - libboost_regex - is -        // quite a heavy and troublesome dependency for the client, so -        // it seems a shame to introduce it for such a simple task. -        // *FIXME: libboost_regex is a dependency now anyway, so we may -        // as well use it instead of this hand-rolled nonsense. -        const char *part1_template = prefix_str; -        const char part2_template[] = " kB"; -        char *part1 = strstr(line_buf, part1_template); -        if (part1) // found start of matching line -        { -            part1 = &part1[strlen(part1_template)]; // -> after -            char *part2 = strstr(part1, part2_template); -            if (part2) // found end of matching line -            { -                // now everything between part1 and part2 is -                // supposed to be numeric, describing the -                // number of kB of Video RAM supported -                int rtn = 0; -                for (; part1 < part2; ++part1) -                { -                    if (*part1 < '0' || *part1 > '9') -                    { -                        // unexpected char, abort parse -                        rtn = 0; -                        break; -                    } -                    rtn *= 10; -                    rtn += (*part1) - '0'; -                } -                if (rtn > 0) -                { -                    // got the kB number.  return it now. -                    return rtn; -                } -            } -        } -    } -    return 0; // 'could not detect' +void LLWindowSDL::setTitle(const std::string title) +{ +    SDL_SetWindowTitle( mWindow, title.c_str() );  } -static int x11_detect_VRAM_kb() +void LLWindowSDL::tryFindFullscreenSize( int &width, int &height )  { -    std::string x_log_location("/var/log/"); -    std::string fname; -    int rtn = 0; // 'could not detect' -    int display_num = 0; -    FILE *fp; -    char *display_env = getenv("DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc -    // parse DISPLAY number so we can go grab the right log file -    if (display_env[0] == ':' && -        display_env[1] >= '0' && display_env[1] <= '9') -    { -        display_num = display_env[1] - '0'; -    } - -    // *TODO: we could be smarter and see which of Xorg/XFree86 has the -    // freshest time-stamp. +    LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; -    // Try Xorg log first -    fname = x_log_location; -    fname += "Xorg."; -    fname += ('0' + display_num); -    fname += ".log"; -    fp = fopen(fname.c_str(), "r"); -    if (fp) +    // If the requested width or height is 0, find the best default for the monitor. +    if((width == 0) || (height == 0))      { -        LL_INFOS() << "Looking in " << fname -            << " for VRAM info..." << LL_ENDL; -        rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); -        fclose(fp); -        if (0 == rtn) +        // Scan through the list of modes, looking for one which has: +        //      height between 700 and 800 +        //      aspect ratio closest to the user's original mode +        S32 resolutionCount = 0; +        LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); + +        if(resolutionList != NULL)          { -            fp = fopen(fname.c_str(), "r"); -            if (fp) +            F32 closestAspect = 0; +            U32 closestHeight = 0; +            U32 closestWidth = 0; +            int i; + +            LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; + +            for(i=0; i < resolutionCount; i++)              { -                rtn = x11_detect_VRAM_kb_fp(fp, ": Video RAM: "); -                fclose(fp); -                if (0 == rtn) +                F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; + +                LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; + +                if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && +                    (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio)))                  { -                    fp = fopen(fname.c_str(), "r"); -                    if (fp) -                    { -                        rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); -                        fclose(fp); -                    } +                    LL_INFOS() << " (new closest mode) " << LL_ENDL; + +                    // This is the closest mode we've seen yet. +                    closestWidth = resolutionList[i].mWidth; +                    closestHeight = resolutionList[i].mHeight; +                    closestAspect = aspect;                  }              } + +            width = closestWidth; +            height = closestHeight;          }      } -    else + +    if((width == 0) || (height == 0))      { -        LL_INFOS() << "Could not open " << fname -            << " - skipped." << LL_ENDL; -        // Try old XFree86 log otherwise -        fname = x_log_location; -        fname += "XFree86."; -        fname += ('0' + display_num); -        fname += ".log"; -        fp = fopen(fname.c_str(), "r"); -        if (fp) -        { -            LL_INFOS() << "Looking in " << fname -                << " for VRAM info..." << LL_ENDL; -            rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); -            fclose(fp); -            if (0 == rtn) -            { -                fp = fopen(fname.c_str(), "r"); -                if (fp) -                { -                    rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); -                    fclose(fp); -                } -            } -        } -        else -        { -            LL_INFOS() << "Could not open " << fname -                << " - skipped." << LL_ENDL; -        } +        // Mode search failed for some reason.  Use the old-school default. +        width = 1024; +        height = 768;      } -    return rtn;  } -#endif // LL_X11 -bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync) +bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync)  {      //bool          glneedsinit = false;      LL_INFOS() << "createContext, fullscreen=" << fullscreen << -        " size=" << width << "x" << height << LL_ENDL; +               " size=" << width << "x" << height << LL_ENDL;      // captures don't survive contexts      mGrabbyKeyFlags = 0;      mReallyCapturedCount = 0; -    if (SDL_Init(SDL_INIT_VIDEO) < 0) -    { -        LL_INFOS() << "sdl_init() failed! " << SDL_GetError() << LL_ENDL; -        setupFailure("sdl_init() failure,  window creation error", "error", OSMB_OK); -        return false; -    } - -    SDL_version c_sdl_version; -    SDL_VERSION(&c_sdl_version); -    LL_INFOS() << "Compiled against SDL " -        << int(c_sdl_version.major) << "." -        << int(c_sdl_version.minor) << "." -        << int(c_sdl_version.patch) << LL_ENDL; -    const SDL_version *r_sdl_version; -    r_sdl_version = SDL_Linked_Version(); -    LL_INFOS() << " Running against SDL " -        << int(r_sdl_version->major) << "." -        << int(r_sdl_version->minor) << "." -        << int(r_sdl_version->patch) << LL_ENDL; +    std::initializer_list<std::tuple< char const*, char const * > > hintList = +            { +                    {SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,"0"}, +                    {SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,"1"}, +                    {SDL_HINT_IME_INTERNAL_EDITING,"1"} +            }; -    const SDL_VideoInfo *video_info = SDL_GetVideoInfo( ); -    if (!video_info) +    for( auto hint: hintList )      { -        LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; -        setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); -        return false; +        SDL_SetHint( std::get<0>(hint), std::get<1>(hint));      } -    if (video_info->current_h > 0) +    std::initializer_list<std::tuple<uint32_t, char const*, bool>> initList= +            { {SDL_INIT_VIDEO,"SDL_INIT_VIDEO", true}, +              {SDL_INIT_AUDIO,"SDL_INIT_AUDIO", false}, +              {SDL_INIT_GAMECONTROLLER,"SDL_INIT_GAMECONTROLLER", false}, +              {SDL_INIT_SENSOR,"SDL_INIT_SENSOR", false} +            }; + +    for( auto subSystem : initList)      { -        mOriginalAspectRatio = (float)video_info->current_w / (float)video_info->current_h; -        LL_INFOS() << "Original aspect ratio was " << video_info->current_w << ":" << video_info->current_h << "=" << mOriginalAspectRatio << LL_ENDL; -    } +        if( SDL_InitSubSystem( std::get<0>(subSystem) ) < 0 ) +        { +            LL_WARNS() << "SDL_InitSubSystem for " << std::get<1>(subSystem) << " failed " << SDL_GetError() << LL_ENDL; -    SDL_EnableUNICODE(1); -    SDL_WM_SetCaption(mWindowTitle.c_str(), mWindowTitle.c_str()); +            if( std::get<2>(subSystem)) +                setupFailure("SDL_Init() failure", "error", OSMB_OK); -    // Set the application icon. -    SDL_Surface *bmpsurface; -    bmpsurface = Load_BMP_Resource("ll_icon.BMP"); -    if (bmpsurface) -    { -        // This attempts to give a black-keyed mask to the icon. -        SDL_SetColorKey(bmpsurface, -                SDL_SRCCOLORKEY, -                SDL_MapRGB(bmpsurface->format, 0,0,0) ); -        SDL_WM_SetIcon(bmpsurface, NULL); -        // The SDL examples cheerfully avoid freeing the icon -        // surface, but I'm betting that's leaky. -        SDL_FreeSurface(bmpsurface); -        bmpsurface = NULL; +        }      } -    // note: these SetAttributes make Tom's 9600-on-AMD64 fail to -    // get a visual, but it's broken anyway when it does, and without -    // these SetAttributes we might easily get an avoidable substandard -    // visual to work with on most other machines. -    SDL_GL_SetAttribute(SDL_GL_RED_SIZE,  8); -    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); -    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); -    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24); -    // We need stencil support for a few (minor) things. -    if (!getenv("LL_GL_NO_STENCIL")) -        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); -        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8); - -        // *FIX: try to toggle vsync here? +    SDL_version c_sdl_version; +    SDL_VERSION(&c_sdl_version); +    LL_INFOS() << "Compiled against SDL " +               << int(c_sdl_version.major) << "." +               << int(c_sdl_version.minor) << "." +               << int(c_sdl_version.patch) << LL_ENDL; +    SDL_version r_sdl_version; +    SDL_GetVersion(&r_sdl_version); +    LL_INFOS() << " Running against SDL " +               << int(r_sdl_version.major) << "." +               << int(r_sdl_version.minor) << "." +               << int(r_sdl_version.patch) << LL_ENDL; + +    if (width == 0) +        width = 1024; +    if (height == 0) +        width = 768; +    if (x == 0) +        x = SDL_WINDOWPOS_UNDEFINED; +    if (y == 0) +        y = SDL_WINDOWPOS_UNDEFINED;      mFullscreen = fullscreen; -    int sdlflags = SDL_OPENGL | SDL_RESIZABLE | SDL_ANYFORMAT; - -    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +    int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; -    if (mFSAASamples > 0) +    if( mFullscreen )      { -        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); -        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); +        sdlflags |= SDL_WINDOW_FULLSCREEN; +        tryFindFullscreenSize( width, height );      } -        mSDLFlags = sdlflags; +    if(hasHIDPI) sdlflags = sdlflags | SDL_WINDOW_ALLOW_HIGHDPI; -    if (mFullscreen) -    { -        LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; - -        // If the requested width or height is 0, find the best default for the monitor. -        if((width == 0) || (height == 0)) -        { -            // Scan through the list of modes, looking for one which has: -            //      height between 700 and 800 -            //      aspect ratio closest to the user's original mode -            S32 resolutionCount = 0; -            LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); - -            if(resolutionList != NULL) -            { -                F32 closestAspect = 0; -                U32 closestHeight = 0; -                U32 closestWidth = 0; -                int i; +    mSDLFlags = sdlflags; -                LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; +    // Setup default backing colors +    GLint redBits{8}, greenBits{8}, blueBits{8}, alphaBits{8}; +    GLint depthBits{24}, stencilBits{8}; -                for(i=0; i < resolutionCount; i++) -                { -                    F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; +    SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   redBits); +    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits); +    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  blueBits); +    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits); +    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits); +    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); -                    LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); +#if LL_DARWIN +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); +#else +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); +#endif +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); -                    if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && -                        (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio))) -                    { -                        LL_INFOS() << " (new closest mode) " << LL_ENDL; +    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); -                        // This is the closest mode we've seen yet. -                        closestWidth = resolutionList[i].mWidth; -                        closestHeight = resolutionList[i].mHeight; -                        closestAspect = aspect; -                    } -                } +    U32 context_flags = 0; +    if (gDebugGL) +    { +        context_flags |= SDL_GL_CONTEXT_DEBUG_FLAG; +    } +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags); +    SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); -                width = closestWidth; -                height = closestHeight; -            } -        } +    // Create the window +    mWindow = SDL_CreateWindow(mWindowTitle.c_str(), x, y, width, height, mSDLFlags); +    if (mWindow == nullptr) +    { +        LL_WARNS() << "Window creation failure. SDL: " << SDL_GetError() << LL_ENDL; +        setupFailure("Window creation error", "Error", OSMB_OK); +        return false; +    } -        if((width == 0) || (height == 0)) -        { -            // Mode search failed for some reason.  Use the old-school default. -            width = 1024; -            height = 768; -        } +    // Create the context +    mContext = SDL_GL_CreateContext(mWindow); +    if(!mContext) +    { +        LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; +        setupFailure("GL Context creation error", "Error", OSMB_OK); +        return false; +    } -        mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); -        if (!mWindow && bits > 16) -        { -            SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); -            mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); -        } +    if (SDL_GL_MakeCurrent(mWindow, mContext) != 0) +    { +        LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL; +        setupFailure("GL Context failed to set current failure", "Error", OSMB_OK); +        return false; +    } +    if(mFullscreen) +    {          if (mWindow)          {              mFullscreen = true; -            mFullscreenWidth   = mWindow->w; -            mFullscreenHeight  = mWindow->h; -            mFullscreenBits    = mWindow->format->BitsPerPixel; +            /* +            mFullscreenWidth = mSurface->w; +            mFullscreenHeight = mSurface->h; +            */ +            SDL_GetWindowSize(mWindow, &mFullscreenWidth, &mFullscreenHeight);              mFullscreenRefresh = -1;              LL_INFOS() << "Running at " << mFullscreenWidth -                << "x"   << mFullscreenHeight -                << "x"   << mFullscreenBits -                << " @ " << mFullscreenRefresh -                << LL_ENDL; +                       << "x"   << mFullscreenHeight +                       << " @ " << mFullscreenRefresh +                       << LL_ENDL;          }          else          { @@ -579,80 +447,37 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b              mFullscreen = false;              mFullscreenWidth   = -1;              mFullscreenHeight  = -1; -            mFullscreenBits    = -1;              mFullscreenRefresh = -1;              std::string error = llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);              OSMessageBox(error, "Error", OSMB_OK); +            return false;          }      } - -    if(!mFullscreen && (mWindow == NULL)) +    else      { -        if (width == 0) -            width = 1024; -        if (height == 0) -            width = 768; - -        LL_INFOS() << "createContext: creating window " << width << "x" << height << "x" << bits << LL_ENDL; -        mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); -        if (!mWindow && bits > 16) -        { -            SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); -            mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); -        } -          if (!mWindow)          {              LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL;              setupFailure("Window creation error", "Error", OSMB_OK);              return false;          } -    } else if (!mFullscreen && (mWindow != NULL)) -    { -        LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; -    } - -    // Detect video memory size. -# if LL_X11 -    gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; -    if (gGLManager.mVRAM != 0) -    { -        LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; -    } else -# endif // LL_X11 -    { -        // fallback to letting SDL detect VRAM. -        // note: I've not seen SDL's detection ever actually find -        // VRAM != 0, but if SDL *does* detect it then that's a bonus. -        gGLManager.mVRAM = video_info->video_mem / 1024; -        if (gGLManager.mVRAM != 0) -        { -            LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; -        }      } -    // If VRAM is not detected, that is handled later -    // *TODO: Now would be an appropriate time to check for some -    // explicitly unsupported cards. -    //const char* RENDERER = (const char*) glGetString(GL_RENDERER); - -    GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; - -    glGetIntegerv(GL_RED_BITS, &redBits); -    glGetIntegerv(GL_GREEN_BITS, &greenBits); -    glGetIntegerv(GL_BLUE_BITS, &blueBits); -    glGetIntegerv(GL_ALPHA_BITS, &alphaBits); -    glGetIntegerv(GL_DEPTH_BITS, &depthBits); -    glGetIntegerv(GL_STENCIL_BITS, &stencilBits); +    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); +    SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); +    SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); +    SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alphaBits); +    SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthBits); +    SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilBits);      LL_INFOS() << "GL buffer:" << LL_ENDL; -        LL_INFOS() << "  Red Bits " << S32(redBits) << LL_ENDL; -        LL_INFOS() << "  Green Bits " << S32(greenBits) << LL_ENDL; -        LL_INFOS() << "  Blue Bits " << S32(blueBits) << LL_ENDL; -    LL_INFOS()  << "  Alpha Bits " << S32(alphaBits) << LL_ENDL; -    LL_INFOS()  << "  Depth Bits " << S32(depthBits) << LL_ENDL; -    LL_INFOS()  << "  Stencil Bits " << S32(stencilBits) << LL_ENDL; +    LL_INFOS() << "  Red Bits " << S32(redBits) << LL_ENDL; +    LL_INFOS() << "  Green Bits " << S32(greenBits) << LL_ENDL; +    LL_INFOS() << "  Blue Bits " << S32(blueBits) << LL_ENDL; +    LL_INFOS() << "  Alpha Bits " << S32(alphaBits) << LL_ENDL; +    LL_INFOS() << "  Depth Bits " << S32(depthBits) << LL_ENDL; +    LL_INFOS() << "  Stencil Bits " << S32(stencilBits) << LL_ENDL;      GLint colorBits = redBits + greenBits + blueBits + alphaBits;      // fixme: actually, it's REALLY important for picking that we get at @@ -660,78 +485,143 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b      // relaxed about if we have to.      if (colorBits < 32)      { +#if 0          close();          setupFailure( -            "Second Life requires True Color (32-bit) to run in a window.\n" -            "Please go to Control Panels -> Display -> Settings and\n" -            "set the screen to 32-bit color.\n" -            "Alternately, if you choose to run fullscreen, Second Life\n" -            "will automatically adjust the screen each time it runs.", -            "Error", -            OSMB_OK); +                "Second Life requires True Color (32-bit) to run in a window.\n" +                "Please go to Control Panels -> Display -> Settings and\n" +                "set the screen to 32-bit color.\n" +                "Alternately, if you choose to run fullscreen, Second Life\n" +                "will automatically adjust the screen each time it runs.", +                "Error", +                OSMB_OK);          return false; +#endif      } -#if 0  // *FIX: we're going to brave it for now... -    if (alphaBits < 8) +    LL_PROFILER_GPU_CONTEXT; + +    // Enable vertical sync +    toggleVSync(enable_vsync); + +    // Set the application icon. +    SDL_Surface* bmpsurface = Load_BMP_Resource("ll_icon.BMP"); +    if (bmpsurface)      { -        close(); -        setupFailure( -            "Second Life is unable to run because it can't get an 8 bit alpha\n" -            "channel.  Usually this is due to video card driver issues.\n" -            "Please make sure you have the latest video card drivers installed.\n" -            "Also be sure your monitor is set to True Color (32-bit) in\n" -            "Control Panels -> Display -> Settings.\n" -            "If you continue to receive this message, contact customer service.", -            "Error", -            OSMB_OK); -        return false; +        SDL_SetWindowIcon(mWindow, bmpsurface); +        SDL_FreeSurface(bmpsurface); +        bmpsurface = NULL;      } -#endif  #if LL_X11      /* Grab the window manager specific information */      SDL_SysWMinfo info;      SDL_VERSION(&info.version); -    if ( SDL_GetWMInfo(&info) ) +    if ( SDL_GetWindowWMInfo(mWindow, &info) )      {          /* Save the information for later use */          if ( info.subsystem == SDL_SYSWM_X11 )          {              mSDL_Display = info.info.x11.display; -            mSDL_XWindowID = info.info.x11.wmwindow; -            Lock_Display = info.info.x11.lock_func; -            Unlock_Display = info.info.x11.unlock_func; +            mSDL_XWindowID = info.info.x11.window;          }          else          {              LL_WARNS() << "We're not running under X11?  Wild." -                << LL_ENDL; +                       << LL_ENDL;          }      }      else      {          LL_WARNS() << "We're not running under any known WM.  Wild." -            << LL_ENDL; +                   << LL_ENDL;      }  #endif // LL_X11 - +# if LL_X11 +    PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; +    queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererIntegerMESA"); +    unsigned int vram_megabytes = 0; +    queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_megabytes); +    if (!vram_megabytes) +    { +        glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, (int *)&vram_megabytes); +        vram_megabytes /= 1024; +    } +    if (!vram_megabytes) +    { +        glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, (int *)&vram_megabytes); +        vram_megabytes /= 1024; +    } +    gGLManager.mVRAM = vram_megabytes; +#elif LL_DARWIN +    CGLRendererInfoObj info = 0; +    GLint vram_megabytes = 0; +    int num_renderers = 0; +    auto err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers); +    if (!err) +    { +        CGLDescribeRenderer(info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); +        CGLDestroyRendererInfo(info); +    } +    else +    { +        vram_megabytes = 256; +    } +    gGLManager.mVRAM = vram_megabytes; +# endif +    SDL_StartTextInput();      //make sure multisampling is disabled by default +#if GL_VERSION_1_3      glDisable(GL_MULTISAMPLE_ARB); - -    // We need to do this here, once video is init'd -    if (-1 == SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, -                      SDL_DEFAULT_REPEAT_INTERVAL)) -        LL_WARNS() << "Couldn't enable key-repeat: " << SDL_GetError() <<LL_ENDL; +#endif      // Don't need to get the current gamma, since there's a call that restores it to the system defaults.      return true;  } +void* LLWindowSDL::createSharedContext() +{ +    SDL_GLContext pContext = SDL_GL_CreateContext(mWindow); +    if (pContext) +    { +        LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; +        return (void*)pContext; +    } + +    LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; +    return nullptr; +} + +void LLWindowSDL::makeContextCurrent(void* contextPtr) +{ +    SDL_GL_MakeCurrent(mWindow, contextPtr); +    LL_PROFILER_GPU_CONTEXT; +} + +void LLWindowSDL::destroySharedContext(void* contextPtr) +{ +    SDL_GL_DeleteContext(contextPtr); +} + +void LLWindowSDL::toggleVSync(bool enable_vsync) +{ +    if (!enable_vsync) +    { +        LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; +        SDL_GL_SetSwapInterval(0); +        SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"0",SDL_HINT_OVERRIDE); +    } +    else +    { +        LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL; +        SDL_GL_SetSwapInterval(1); +        SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"1",SDL_HINT_OVERRIDE); +    } +}  // changing fullscreen resolution, or switching between windowed and fullscreen mode. -bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp) +bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, const LLCoordScreen * const posp)  {      const bool needsRebuild = true;  // Just nuke the context and start over.      bool result = true; @@ -741,7 +631,7 @@ bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool      if(needsRebuild)      {          destroyContext(); -        result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); +        result = createContext(0, 0, size.mX, size.mY, 32, fullscreen, enable_vsync);          if (result)          {              gGLManager.initGL(); @@ -761,6 +651,13 @@ void LLWindowSDL::destroyContext()  {      LL_INFOS() << "destroyContext begins" << LL_ENDL; +    // Stop unicode input +    SDL_StopTextInput(); + +    // Clean up remaining GL state before blowing away window +    LL_INFOS() << "shutdownGL begins" << LL_ENDL; +    gGLManager.shutdownGL(); +  #if LL_X11      mSDL_Display = NULL;      mSDL_XWindowID = None; @@ -768,18 +665,38 @@ void LLWindowSDL::destroyContext()      Unlock_Display = NULL;  #endif // LL_X11 -    // Clean up remaining GL state before blowing away window -    LL_INFOS() << "shutdownGL begins" << LL_ENDL; -    gGLManager.shutdownGL(); +    LL_INFOS() << "Destroying SDL cursors" << LL_ENDL; +    quitCursors(); + +    if (mContext) +    { +        LL_INFOS() << "Destroying SDL GL Context" << LL_ENDL; +        SDL_GL_DeleteContext(mContext); +        mContext = nullptr; +    } +    else +    { +        LL_INFOS() << "SDL GL Context already destroyed" << LL_ENDL; +    } + +    if (mWindow) +    { +        LL_INFOS() << "Destroying SDL Window" << LL_ENDL; +        SDL_DestroyWindow(mWindow); +        mWindow = nullptr; +    } +    else +    { +        LL_INFOS() << "SDL Window already destroyed" << LL_ENDL; +    } +    LL_INFOS() << "destroyContext end" << LL_ENDL; +      LL_INFOS() << "SDL_QuitSS/VID begins" << LL_ENDL;      SDL_QuitSubSystem(SDL_INIT_VIDEO);  // *FIX: this might be risky... - -    mWindow = NULL;  }  LLWindowSDL::~LLWindowSDL()  { -    quitCursors();      destroyContext();      if(mSupportedResolutions != NULL) @@ -793,27 +710,38 @@ LLWindowSDL::~LLWindowSDL()  void LLWindowSDL::show()  { -    // *FIX: What to do with SDL? +    if (mWindow) +    { +        SDL_ShowWindow(mWindow); +    }  }  void LLWindowSDL::hide()  { -    // *FIX: What to do with SDL? +    if (mWindow) +    { +        SDL_HideWindow(mWindow); +    }  }  //virtual  void LLWindowSDL::minimize()  { -    // *FIX: What to do with SDL? +    if (mWindow) +    { +        SDL_MinimizeWindow(mWindow); +    }  }  //virtual  void LLWindowSDL::restore()  { -    // *FIX: What to do with SDL? +    if (mWindow) +    { +        SDL_RestoreWindow(mWindow); +    }  } -  // close() destroys all OS-specific code associated with a window.  // Usually called from LLWindowManager::destroyWindow()  void LLWindowSDL::close() @@ -839,43 +767,53 @@ bool LLWindowSDL::isValid()  bool LLWindowSDL::getVisible()  {      bool result = false; - -    // *FIX: This isn't really right... -    // Then what is?      if (mWindow)      { -        result = true; +        Uint32 flags = SDL_GetWindowFlags(mWindow); +        if (flags & SDL_WINDOW_SHOWN) +        { +            result = true; +        }      } - -    return(result); +    return result;  }  bool LLWindowSDL::getMinimized()  {      bool result = false; - -    if (mWindow && (1 == mIsMinimized)) +    if (mWindow)      { -        result = true; +        Uint32 flags = SDL_GetWindowFlags(mWindow); +        if (flags & SDL_WINDOW_MINIMIZED) +        { +            result = true; +        }      } -    return(result); +    return result;  }  bool LLWindowSDL::getMaximized()  {      bool result = false; -      if (mWindow)      { -        // TODO +        Uint32 flags = SDL_GetWindowFlags(mWindow); +        if (flags & SDL_WINDOW_MAXIMIZED) +        { +            result = true; +        }      } -    return(result); +    return result;  }  bool LLWindowSDL::maximize()  { -    // TODO +    if (mWindow) +    { +        SDL_MaximizeWindow(mWindow); +        return true; +    }      return false;  } @@ -886,19 +824,25 @@ bool LLWindowSDL::getFullscreen()  bool LLWindowSDL::getPosition(LLCoordScreen *position)  { -    // *FIX: can anything be done with this? -    position->mX = 0; -    position->mY = 0; -    return true; +    if (mWindow) +    { +        SDL_GetWindowPosition(mWindow, &position->mX, &position->mY); +        return true; +    } +    return false;  }  bool LLWindowSDL::getSize(LLCoordScreen *size)  {      if (mWindow)      { -        size->mX = mWindow->w; -        size->mY = mWindow->h; -    return (true); +        /* +        if(hasHIDPI) +            SDL_GL_GetDrawableSize(mWindow, &size->mX, &size->mY); +        else +        */ +        SDL_GetWindowSize(mWindow, &size->mX, &size->mY); +        return (true);      }      return (false); @@ -908,9 +852,11 @@ bool LLWindowSDL::getSize(LLCoordWindow *size)  {      if (mWindow)      { -        size->mX = mWindow->w; -        size->mY = mWindow->h; -    return (true); +        if(hasHIDPI) +            SDL_GL_GetDrawableSize(mWindow, &size->mX, &size->mY); +        else +            SDL_GetWindowSize(mWindow, &size->mX, &size->mY); +        return (true);      }      return (false); @@ -918,49 +864,46 @@ bool LLWindowSDL::getSize(LLCoordWindow *size)  bool LLWindowSDL::setPosition(const LLCoordScreen position)  { -    if(mWindow) +    if (mWindow)      { -        // *FIX: (?) -        //MacMoveWindow(mWindow, position.mX, position.mY, false); +        SDL_SetWindowPosition(mWindow, position.mX, position.mY); +        return true;      } -    return true; +    return false;  } -bool LLWindowSDL::setSizeImpl(const LLCoordScreen size) +template< typename T > bool setSizeImpl( const T& newSize, SDL_Window *pWin )  { -    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 +    if( !pWin ) +        return false; -        return true; -    } +    auto nFlags = SDL_GetWindowFlags( pWin ); -    return false; +    if( nFlags & SDL_WINDOW_MAXIMIZED ) +        SDL_RestoreWindow( pWin ); + + +    SDL_SetWindowSize( pWin, newSize.mX, newSize.mY ); +    SDL_Event event; +    event.type = SDL_WINDOWEVENT; +    event.window.event = SDL_WINDOWEVENT_RESIZED; +    event.window.windowID = SDL_GetWindowID( pWin ); +    event.window.data1 = newSize.mX; +    event.window.data2 = newSize.mY; +    SDL_PushEvent( &event ); + +    return true;  } -bool LLWindowSDL::setSizeImpl(const LLCoordWindow size) +bool LLWindowSDL::setSizeImpl(const LLCoordScreen 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 ::setSizeImpl( size, mWindow ); +} -    return false; +bool LLWindowSDL::setSizeImpl(const LLCoordWindow size) +{ +    return ::setSizeImpl( size, mWindow );  } @@ -968,8 +911,9 @@ void LLWindowSDL::swapBuffers()  {      if (mWindow)      { -        SDL_GL_SwapBuffers(); +        SDL_GL_SwapWindow(mWindow);      } +    LL_PROFILER_GPU_COLLECT;  }  U32 LLWindowSDL::getFSAASamples() @@ -984,22 +928,33 @@ void LLWindowSDL::setFSAASamples(const U32 samples)  F32 LLWindowSDL::getGamma()  { -    return 1/mGamma; +    return 1.f / mGamma;  }  bool LLWindowSDL::restoreGamma()  { -    //CGDisplayRestoreColorSyncSettings(); -    SDL_SetGamma(1.0f, 1.0f, 1.0f); +    if (mWindow) +    { +        Uint16 ramp[256]; +        SDL_CalculateGammaRamp(1.f, ramp); +        SDL_SetWindowGammaRamp(mWindow, ramp, ramp, ramp); +    }      return true;  }  bool LLWindowSDL::setGamma(const F32 gamma)  { -    mGamma = gamma; -    if (mGamma == 0) mGamma = 0.1f; -    mGamma = 1/mGamma; -    SDL_SetGamma(mGamma, mGamma, mGamma); +    if (mWindow) +    { +        Uint16 ramp[256]; + +        mGamma = gamma; +        if (mGamma == 0) mGamma = 0.1f; +        mGamma = 1.f / mGamma; + +        SDL_CalculateGammaRamp(mGamma, ramp); +        SDL_SetWindowGammaRamp(mWindow, ramp, ramp, ramp); +    }      return true;  } @@ -1008,10 +963,8 @@ bool LLWindowSDL::isCursorHidden()      return mCursorHidden;  } - -  // Constrains the mouse to the window. -void LLWindowSDL::setMouseClipping( bool b ) +void LLWindowSDL::setMouseClipping(bool b)  {      //SDL_WM_GrabInput(b ? SDL_GRAB_ON : SDL_GRAB_OFF);  } @@ -1021,18 +974,10 @@ void LLWindowSDL::setMinSize(U32 min_width, U32 min_height, bool enforce_immedia  {      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 +    if (mWindow && min_width > 0 && min_height > 0) +    { +        SDL_SetWindowMinimumSize(mWindow, mMinWindowWidth, mMinWindowHeight); +    }  }  bool LLWindowSDL::setCursorPosition(const LLCoordWindow position) @@ -1048,7 +993,14 @@ bool LLWindowSDL::setCursorPosition(const LLCoordWindow position)      //LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL;      // do the actual forced cursor move. -    SDL_WarpMouse(screen_pos.mX, screen_pos.mY); + +    if (mFullscreen) +    { +        SDL_WarpMouseGlobal(screen_pos.mX, screen_pos.mY); +        return result; +    } + +    SDL_WarpMouseInWindow(mWindow, screen_pos.mX, screen_pos.mY);      //LL_INFOS() << llformat("llcw %d,%d -> scr %d,%d", position.mX, position.mY, screen_pos.mX, screen_pos.mY) << LL_ENDL; @@ -1060,7 +1012,6 @@ bool LLWindowSDL::getCursorPosition(LLCoordWindow *position)      //Point cursor_point;      LLCoordScreen screen_pos; -    //GetMouse(&cursor_point);      int x, y;      SDL_GetMouseState(&x, &y); @@ -1070,21 +1021,14 @@ bool LLWindowSDL::getCursorPosition(LLCoordWindow *position)      return convertCoords(screen_pos, position);  } +F32 LLWindowSDL::getSystemUISize() +{ +    if(hasHIDPI) return 2.0f; +    else return 1.f; +}  F32 LLWindowSDL::getNativeAspectRatio()  { -#if 0 -    // RN: this hack presumes that the largest supported resolution is monitor-limited -    // and that pixels in that mode are square, therefore defining the native aspect ratio -    // of the monitor...this seems to work to a close approximation for most CRTs/LCDs -    S32 num_resolutions; -    LLWindowResolution* resolutions = getSupportedResolutions(num_resolutions); - - -    return ((F32)resolutions[num_resolutions - 1].mWidth / (F32)resolutions[num_resolutions - 1].mHeight); -    //rn: AC -#endif -      // MBW -- there are a couple of bad assumptions here.  One is that the display list won't include      //      ridiculous resolutions nobody would ever use.  The other is that the list is in order. @@ -1146,7 +1090,7 @@ void LLWindowSDL::beforeDialog()              // it only works in X11              if (running_x11 && mWindow)              { -                SDL_WM_ToggleFullScreen(mWindow); +                SDL_SetWindowFullscreen( mWindow, 0 );              }          }      } @@ -1162,12 +1106,6 @@ void LLWindowSDL::beforeDialog()      }  #endif // LL_X11 -#if LL_GTK -    // this is a good time to grab some GTK version information for -    // diagnostics, if not already done. -    ll_try_gtk_init(); -#endif // LL_GTK -      maybe_lock_display();  } @@ -1188,46 +1126,14 @@ void LLWindowSDL::afterDialog()          // in X11          if (running_x11 && mWindow)          { -            SDL_WM_ToggleFullScreen(mWindow); +            SDL_SetWindowFullscreen( mWindow, 0 );          }      }  } - -#if LL_X11 -// set/reset the XWMHints flag for 'urgency' that usually makes the icon flash -void LLWindowSDL::x11_set_urgent(bool urgent) -{ -    if (mSDL_Display && !mFullscreen) -    { -        XWMHints *wm_hints; - -        LL_INFOS() << "X11 hint for urgency, " << urgent << LL_ENDL; - -        maybe_lock_display(); -        wm_hints = XGetWMHints(mSDL_Display, mSDL_XWindowID); -        if (!wm_hints) -            wm_hints = XAllocWMHints(); - -        if (urgent) -            wm_hints->flags |= XUrgencyHint; -        else -            wm_hints->flags &= ~XUrgencyHint; - -        XSetWMHints(mSDL_Display, mSDL_XWindowID, wm_hints); -        XFree(wm_hints); -        XSync(mSDL_Display, False); -        maybe_unlock_display(); -    } -} -#endif // LL_X11 -  void LLWindowSDL::flashIcon(F32 seconds)  { -#if !LL_X11 -    LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; -#else -    LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; +    LL_INFOS() << "LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL;      F32 remaining_time = mFlashTimer.getRemainingTimeF32();      if (remaining_time < seconds) @@ -1235,132 +1141,62 @@ void LLWindowSDL::flashIcon(F32 seconds)      mFlashTimer.reset();      mFlashTimer.setTimerExpirySec(remaining_time); -    x11_set_urgent(true); +    SDL_FlashWindow(mWindow, SDL_FLASH_UNTIL_FOCUSED);      mFlashing = true; -#endif // LL_X11  } - -#if LL_GTK  bool LLWindowSDL::isClipboardTextAvailable()  { -    if (ll_try_gtk_init()) -    { -        GtkClipboard * const clipboard = -            gtk_clipboard_get(GDK_NONE); -        return gtk_clipboard_wait_is_text_available(clipboard) ? -            true : false; -    } -    return false; // failure +    return SDL_HasClipboardText() == SDL_TRUE;  } -bool LLWindowSDL::pasteTextFromClipboard(LLWString &text) +bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst)  { -    if (ll_try_gtk_init()) +    if (isClipboardTextAvailable())      { -        GtkClipboard * const clipboard = -            gtk_clipboard_get(GDK_NONE); -        gchar * const data = gtk_clipboard_wait_for_text(clipboard); +        char* data = SDL_GetClipboardText();          if (data)          { -            text = LLWString(utf8str_to_wstring(data)); -            g_free(data); +            dst = LLWString(utf8str_to_wstring(data)); +            SDL_free(data);              return true;          }      } -    return false; // failure +    return false;  } -bool LLWindowSDL::copyTextToClipboard(const LLWString &text) +bool LLWindowSDL::copyTextToClipboard(const LLWString& text)  { -    if (ll_try_gtk_init()) -    { -        const std::string utf8 = wstring_to_utf8str(text); -        GtkClipboard * const clipboard = -            gtk_clipboard_get(GDK_NONE); -        gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); -        return true; -    } -    return false; // failure +    const std::string utf8 = wstring_to_utf8str(text); +    return SDL_SetClipboardText(utf8.c_str()) == 0; // success == 0  } -  bool LLWindowSDL::isPrimaryTextAvailable()  { -    if (ll_try_gtk_init()) -    { -        GtkClipboard * const clipboard = -            gtk_clipboard_get(GDK_SELECTION_PRIMARY); -        return gtk_clipboard_wait_is_text_available(clipboard) ? -            true : false; -    } -    return false; // failure +    return SDL_HasPrimarySelectionText() == SDL_TRUE;  } -bool LLWindowSDL::pasteTextFromPrimary(LLWString &text) +bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst)  { -    if (ll_try_gtk_init()) +    if (isPrimaryTextAvailable())      { -        GtkClipboard * const clipboard = -            gtk_clipboard_get(GDK_SELECTION_PRIMARY); -        gchar * const data = gtk_clipboard_wait_for_text(clipboard); +        char* data = SDL_GetPrimarySelectionText();          if (data)          { -            text = LLWString(utf8str_to_wstring(data)); -            g_free(data); +            dst = LLWString(utf8str_to_wstring(data)); +            SDL_free(data);              return true;          }      } -    return false; // failure -} - -bool LLWindowSDL::copyTextToPrimary(const LLWString &text) -{ -    if (ll_try_gtk_init()) -    { -        const std::string utf8 = wstring_to_utf8str(text); -        GtkClipboard * const clipboard = -            gtk_clipboard_get(GDK_SELECTION_PRIMARY); -        gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); -        return true; -    } -    return false; // failure -} - -#else - -bool LLWindowSDL::isClipboardTextAvailable() -{ -    return false; // unsupported -} - -bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst) -{ -    return false; // unsupported -} - -bool LLWindowSDL::copyTextToClipboard(const LLWString &s) -{ -    return false;  // unsupported -} - -bool LLWindowSDL::isPrimaryTextAvailable() -{ -    return false; // unsupported -} - -bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst) -{ -    return false; // unsupported +    return false;  } -bool LLWindowSDL::copyTextToPrimary(const LLWString &s) +bool LLWindowSDL::copyTextToPrimary(const LLWString& text)  { -    return false;  // unsupported +    const std::string utf8 = wstring_to_utf8str(text); +    return SDL_SetPrimarySelectionText(utf8.c_str()) == 0; // success == 0  } -#endif // LL_GTK -  LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions)  {      if (!mSupportedResolutions) @@ -1368,33 +1204,30 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso          mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS];          mNumSupportedResolutions = 0; -        SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); -        if ( (modes != NULL) && (modes != ((SDL_Rect **) -1)) ) +        // <FS:ND> Use display no from mWindow/mSurface here? +        int max = SDL_GetNumDisplayModes(0); +        max = llclamp( max, 0, MAX_NUM_RESOLUTIONS ); + +        for( int i =0; i < max; ++i )          { -            int count = 0; -            while (*modes && count<MAX_NUM_RESOLUTIONS)  // they're sorted biggest to smallest, so find end... +            SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; +            if (SDL_GetDisplayMode( 0 , i, &mode) != 0)              { -                modes++; -                count++; +                continue;              } -            while (count--) +            int w = mode.w; +            int h = mode.h; +            if ((w >= 800) && (h >= 600))              { -                modes--; -                SDL_Rect *r = *modes; -                int w = r->w; -                int h = r->h; -                if ((w >= 800) && (h >= 600)) +                // make sure we don't add the same resolution multiple times! +                if ( (mNumSupportedResolutions == 0) || +                     ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && +                      (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) )                  { -                    // make sure we don't add the same resolution multiple times! -                    if ( (mNumSupportedResolutions == 0) || -                         ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && -                          (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) ) -                    { -                        mSupportedResolutions[mNumSupportedResolutions].mWidth = w; -                        mSupportedResolutions[mNumSupportedResolutions].mHeight = h; -                        mNumSupportedResolutions++; -                    } +                    mSupportedResolutions[mNumSupportedResolutions].mWidth = w; +                    mSupportedResolutions[mNumSupportedResolutions].mHeight = h; +                    mNumSupportedResolutions++;                  }              }          } @@ -1410,7 +1243,9 @@ bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to)          return false;      to->mX = from.mX; -    to->mY = mWindow->h - from.mY - 1; +    int h; +    SDL_GetWindowSize(mWindow, nullptr, &h); +    to->mY = h - from.mY - 1;      return true;  } @@ -1421,7 +1256,9 @@ bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to)          return false;      to->mX = from.mX; -    to->mY = mWindow->h - from.mY - 1; +    int h; +    SDL_GetWindowSize(mWindow, nullptr, &h); +    to->mY = h - from.mY - 1;      return true;  } @@ -1462,9 +1299,6 @@ bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordScreen *to)      return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));  } - - -  void LLWindowSDL::setupFailure(const std::string& text, const std::string& caption, U32 type)  {      destroyContext(); @@ -1482,13 +1316,13 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture)      else          mReallyCapturedCount = 0; -    SDL_GrabMode wantmode, newmode; +    bool wantGrab;      if (mReallyCapturedCount <= 0) // uncapture      { -        wantmode = SDL_GRAB_OFF; +        wantGrab = false;      } else // capture      { -        wantmode = SDL_GRAB_ON; +        wantGrab = true;      }      if (mReallyCapturedCount < 0) // yuck, imbalance. @@ -1497,64 +1331,31 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture)          LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL;      } +    bool newGrab = wantGrab; +      if (!mFullscreen) /* only bother if we're windowed anyway */      { -#if LL_X11 -        if (mSDL_Display) +        int result; +        if (wantGrab == true)          { -            /* we dirtily mix raw X11 with SDL so that our pointer -               isn't (as often) constrained to the limits of the -               window while grabbed, which feels nicer and -               hopefully eliminates some reported 'sticky pointer' -               problems.  We use raw X11 instead of -               SDL_WM_GrabInput() because the latter constrains -               the pointer to the window and also steals all -               *keyboard* input from the window manager, which was -               frustrating users. */ -            int result; -            if (wantmode == SDL_GRAB_ON) -            { -                //LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL; -                //newmode = SDL_WM_GrabInput(wantmode); -                maybe_lock_display(); -                result = XGrabPointer(mSDL_Display, mSDL_XWindowID, -                              True, 0, GrabModeAsync, -                              GrabModeAsync, -                              None, None, CurrentTime); -                maybe_unlock_display(); -                if (GrabSuccess == result) -                    newmode = SDL_GRAB_ON; -                else -                    newmode = SDL_GRAB_OFF; -            } else if (wantmode == SDL_GRAB_OFF) -            { -                //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; -                newmode = SDL_GRAB_OFF; -                //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF); - -                maybe_lock_display(); -                XUngrabPointer(mSDL_Display, CurrentTime); -                // Make sure the ungrab happens RIGHT NOW. -                XSync(mSDL_Display, False); -                maybe_unlock_display(); -            } else -            { -                newmode = SDL_GRAB_QUERY; // neutral -            } -        } else // not actually running on X11, for some reason -            newmode = wantmode; -#endif // LL_X11 -    } else { -        // pretend we got what we wanted, when really we don't care. -        newmode = wantmode; +            result = SDL_CaptureMouse(SDL_TRUE); +            if (0 == result) +                newGrab = true; +            else +                newGrab = false; +        } +        else +        { +            newGrab = false; +            result = SDL_CaptureMouse(SDL_FALSE); +        }      }      // return boolean success for whether we ended up in the desired state -    return (capture && SDL_GRAB_ON==newmode) || -        (!capture && SDL_GRAB_OFF==newmode); +    return capture == newGrab;  } -U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain) +U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain)  {      /* part of the fix for SL-13243: Some popular window managers like         to totally eat alt-drag for the purposes of moving windows.  We @@ -1572,16 +1373,16 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain)      U32 mask = 0;      switch (keysym)      { -    case SDLK_LALT: -        mask = 1U << 0; break; -    case SDLK_RALT: -        mask = 1U << 1; break; -    case SDLK_LCTRL: -        mask = 1U << 2; break; -    case SDLK_RCTRL: -        mask = 1U << 3; break; -    default: -        break; +        case SDLK_LALT: +            mask = 1U << 0; break; +        case SDLK_RALT: +            mask = 1U << 1; break; +        case SDLK_LCTRL: +            mask = 1U << 2; break; +        case SDLK_RCTRL: +            mask = 1U << 3; break; +        default: +            break;      }      if (gain) @@ -1694,33 +1495,17 @@ finally:  // virtual  void LLWindowSDL::processMiscNativeEvents()  { -#if LL_GTK -    // Pump GTK events to avoid starvation for: -    // * DBUS servicing -    // * Anything else which quietly hooks into the default glib/GTK loop -    if (ll_try_gtk_init()) -    { -        // Yuck, Mozilla's GTK callbacks play with the locale - push/pop -        // the locale to protect it, as exotic/non-C locales -        // causes our code lots of general critical weirdness -        // and crashness. (SL-35450) -        static std::string saved_locale; -        saved_locale = ll_safe_string(setlocale(LC_ALL, NULL)); - -        // Pump until we've nothing left to do or passed 1/15th of a -        // second pumping for this frame. -        static LLTimer pump_timer; -        pump_timer.reset(); -        pump_timer.setTimerExpirySec(1.0f / 15.0f); -        do { -             // Always do at least one non-blocking pump -            gtk_main_iteration_do(false); -        } while (gtk_events_pending() && -             !pump_timer.hasExpired()); - -        setlocale(LC_ALL, saved_locale.c_str() ); -    } -#endif // LL_GTK +#if LL_GLIB +    // Pump until we've nothing left to do or passed 1/15th of a +    // second pumping for this frame. +    static LLTimer pump_timer; +    pump_timer.reset(); +    pump_timer.setTimerExpirySec(1.0f / 15.0f); +    do +    { +        g_main_context_iteration(g_main_context_default(), false); +    } while( g_main_context_pending(g_main_context_default()) && !pump_timer.hasExpired()); +#endif      // hack - doesn't belong here - but this is just for debugging      if (getenv("LL_DEBUG_BLOAT")) @@ -1731,11 +1516,6 @@ void LLWindowSDL::processMiscNativeEvents()  void LLWindowSDL::gatherInput()  { -    const Uint32 CLICK_THRESHOLD = 300;  // milliseconds -    static int leftClick = 0; -    static int rightClick = 0; -    static Uint32 lastLeftDown = 0; -    static Uint32 lastRightDown = 0;      SDL_Event event;      // Handle all outstanding SDL events @@ -1743,104 +1523,128 @@ void LLWindowSDL::gatherInput()      {          switch (event.type)          { +            case SDL_MOUSEWHEEL: +            { +                if( event.wheel.y != 0 ) +                { +                    mCallbacks->handleScrollWheel(this, -event.wheel.y); +                } +                if (event.wheel.x != 0) +                { +                    mCallbacks->handleScrollHWheel(this, -event.wheel.x); +                } +                break; +            } +              case SDL_MOUSEMOTION:              { -                LLCoordWindow winCoord(event.button.x, event.button.y); +                LLCoordWindow winCoord(event.motion.x, event.motion.y);                  LLCoordGL openGlCoord;                  convertCoords(winCoord, &openGlCoord); + +                openGlCoord.mX = openGlCoord.mX * getSystemUISize(); +                openGlCoord.mY = openGlCoord.mY * getSystemUISize(); + +                //LL_INFOS() << "SDL_MOUSEMOTION " << event.button.x << " " << event.button.y << " gl " << openGlCoord.mX << " " << openGlCoord.mY << LL_ENDL; +                  MASK mask = gKeyboard->currentMask(true);                  mCallbacks->handleMouseMove(this, openGlCoord, mask);                  break;              } +            case SDL_TEXTINPUT: +            { +                auto string = utf8str_to_utf16str( event.text.text ); +                mKeyModifiers = gKeyboard->currentMask( false ); +                mInputType = "textinput"; +                for( auto key: string ) +                { +                    mKeyVirtualKey = key; + +                    if( (MASK_CONTROL|MASK_ALT)&mKeyModifiers ) +                        gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers ); +                    else +                        handleUnicodeUTF16( key, mKeyModifiers ); +                } +                break; +            } +              case SDL_KEYDOWN: -            mKeyScanCode = event.key.keysym.scancode; -            mKeyVirtualKey = event.key.keysym.unicode; -            mKeyModifiers = event.key.keysym.mod; +                mKeyVirtualKey = event.key.keysym.sym; +                mKeyModifiers = event.key.keysym.mod; +                mInputType = "keydown"; -            gKeyboard->handleKeyDown(event.key.keysym.sym, event.key.keysym.mod); -            // part of the fix for SL-13243 -            if (SDLCheckGrabbyKeys(event.key.keysym.sym, true) != 0) -                SDLReallyCaptureInput(true); +                // treat all possible Enter/Return keys the same +                if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER) +                { +                    mKeyVirtualKey = SDLK_RETURN; +                } + +                gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers ); + +                // <FS:ND> Slightly hacky :| To make the viewer honor enter (eg to accept form input) we've to not only send handleKeyDown but also send a +                // invoke handleUnicodeUTF16 in case the user hits return. +                // Note that we cannot blindly use handleUnicodeUTF16 for each SDL_KEYDOWN. Doing so will create bogus keyboard input (like % for cursor left). +                if( mKeyVirtualKey == SDLK_RETURN ) +                { +                    // fix return key not working when capslock, scrolllock or numlock are enabled +                    mKeyModifiers &= (~(KMOD_NUM | KMOD_CAPS | KMOD_MODE | KMOD_SCROLL)); +                    handleUnicodeUTF16( mKeyVirtualKey, mKeyModifiers ); +                } + +                // part of the fix for SL-13243 +                if (SDLCheckGrabbyKeys(event.key.keysym.sym, true) != 0) +                    SDLReallyCaptureInput(true); -            if (event.key.keysym.unicode) -            { -                handleUnicodeUTF16(event.key.keysym.unicode, -                           gKeyboard->currentMask(false)); -            }                  break;              case SDL_KEYUP: -            mKeyScanCode = event.key.keysym.scancode; -            mKeyVirtualKey = event.key.keysym.unicode; -            mKeyModifiers = event.key.keysym.mod; +                mKeyVirtualKey = event.key.keysym.sym; +                mKeyModifiers = event.key.keysym.mod; +                mInputType = "keyup"; -            if (SDLCheckGrabbyKeys(event.key.keysym.sym, false) == 0) -                SDLReallyCaptureInput(false); // part of the fix for SL-13243 +                // treat all possible Enter/Return keys the same +                if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER) +                { +                    mKeyVirtualKey = SDLK_RETURN; +                } -            gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod); -            break; +                if (SDLCheckGrabbyKeys(mKeyVirtualKey, false) == 0) +                    SDLReallyCaptureInput(false); // part of the fix for SL-13243 + +                gKeyboard->handleKeyUp(mKeyVirtualKey,mKeyModifiers); +                break;              case SDL_MOUSEBUTTONDOWN:              { -                bool isDoubleClick = false;                  LLCoordWindow winCoord(event.button.x, event.button.y);                  LLCoordGL openGlCoord;                  convertCoords(winCoord, &openGlCoord); -        MASK mask = gKeyboard->currentMask(true); -                if (event.button.button == SDL_BUTTON_LEFT)   // SDL doesn't manage double clicking... -                { -                    Uint32 now = SDL_GetTicks(); -                    if ((now - lastLeftDown) > CLICK_THRESHOLD) -                        leftClick = 1; -                    else -                    { -                        if (++leftClick >= 2) -                        { -                            leftClick = 0; -                isDoubleClick = true; -                        } -                    } -                    lastLeftDown = now; -                } -                else if (event.button.button == SDL_BUTTON_RIGHT) -                { -                    Uint32 now = SDL_GetTicks(); -                    if ((now - lastRightDown) > CLICK_THRESHOLD) -                        rightClick = 1; -                    else -                    { -                        if (++rightClick >= 2) -                        { -                            rightClick = 0; -                            isDoubleClick = true; -                        } -                    } -                    lastRightDown = now; -                } +                openGlCoord.mX *= getSystemUISize(); +                openGlCoord.mY *= getSystemUISize(); + +                MASK mask = gKeyboard->currentMask(true);                  if (event.button.button == SDL_BUTTON_LEFT)  // left                  { -                    if (isDoubleClick) +                    if (event.button.clicks >= 2)                          mCallbacks->handleDoubleClick(this, openGlCoord, mask);                      else                          mCallbacks->handleMouseDown(this, openGlCoord, mask);                  } -                  else if (event.button.button == SDL_BUTTON_RIGHT)  // right                  { -            mCallbacks->handleRightMouseDown(this, openGlCoord, mask); +                    mCallbacks->handleRightMouseDown(this, openGlCoord, mask);                  } -                  else if (event.button.button == SDL_BUTTON_MIDDLE)  // middle                  {                      mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask);                  } -                else if (event.button.button == 4)  // mousewheel up...thanks to X11 for making SDL consider these "buttons". -                    mCallbacks->handleScrollWheel(this, -1); -                else if (event.button.button == 5)  // mousewheel down...thanks to X11 for making SDL consider these "buttons". -                    mCallbacks->handleScrollWheel(this, 1); +                else +                { +                    mCallbacks->handleOtherMouseDown(this, openGlCoord, mask, event.button.button); +                }                  break;              } @@ -1850,86 +1654,73 @@ void LLWindowSDL::gatherInput()                  LLCoordWindow winCoord(event.button.x, event.button.y);                  LLCoordGL openGlCoord;                  convertCoords(winCoord, &openGlCoord); -        MASK mask = gKeyboard->currentMask(true); + +                openGlCoord.mX *= getSystemUISize(); +                openGlCoord.mY *= getSystemUISize(); + +                MASK mask = gKeyboard->currentMask(true);                  if (event.button.button == SDL_BUTTON_LEFT)  // left -            mCallbacks->handleMouseUp(this, openGlCoord, mask); +                { +                    mCallbacks->handleMouseUp(this, openGlCoord, mask); +                }                  else if (event.button.button == SDL_BUTTON_RIGHT)  // right -            mCallbacks->handleRightMouseUp(this, openGlCoord, mask); +                { +                    mCallbacks->handleRightMouseUp(this, openGlCoord, mask); +                }                  else if (event.button.button == SDL_BUTTON_MIDDLE)  // middle -            mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); -                // don't handle mousewheel here... - -                break; -            } - -            case SDL_VIDEOEXPOSE:  // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing! -                mCallbacks->handlePaint(this, 0, 0, mWindow->w, mWindow->h); -                break; - -            case SDL_VIDEORESIZE:  // *FIX: handle this? -            { -        LL_INFOS() << "Handling a resize event: " << event.resize.w << -            "x" << event.resize.h << LL_ENDL; - -        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); -        if (!mWindow) -        { -            // *FIX: More informative dialog? -            LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; -            if(mCallbacks->handleCloseRequest(this))                  { -                    // Get the app to initiate cleanup. -                    mCallbacks->handleQuit(this); -                    // The app is responsible for calling destroyWindow when done with GL +                    mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); +                } +                else +                { +                    mCallbacks->handleOtherMouseUp(this, openGlCoord, mask, event.button.button);                  } -                break; -        } -        mCallbacks->handleResize(this, width, height);                  break;              } -            case SDL_ACTIVEEVENT: -                if (event.active.state & SDL_APPINPUTFOCUS) -                { -            // Note that for SDL (particularly on X11), keyboard -            // and mouse focus are independent things.  Here we are -            // tracking keyboard focus state changes. - -            // We have to do our own state massaging because SDL -            // can send us two unfocus events in a row for example, -            // which confuses the focus code [SL-24071]. -            if (event.active.gain != mHaveInputFocus) -            { -                mHaveInputFocus = !!event.active.gain; -                if (mHaveInputFocus) -                    mCallbacks->handleFocus(this); -                else -                    mCallbacks->handleFocusLost(this); -            } -                } -                if (event.active.state & SDL_APPACTIVE) -                { -            // Change in iconification/minimization state. -            if ((!event.active.gain) != mIsMinimized) +            case SDL_WINDOWEVENT:              { -                mIsMinimized = (!event.active.gain); +                switch(event.window.event) +                { +                    //case SDL_WINDOWEVENT_SIZE_CHANGED: <FS:ND> SDL_WINDOWEVENT_SIZE_CHANGED is followed by SDL_WINDOWEVENT_RESIZED, so handling one shall be enough +                    case SDL_WINDOWEVENT_RESIZED: +                    { +                        LL_INFOS() << "Handling a resize event: " << event.window.data1 << "x" << event.window.data2 << LL_ENDL; +                        S32 width = llmax(event.window.data1, (S32)mMinWindowWidth); +                        S32 height = llmax(event.window.data2, (S32)mMinWindowHeight); -                mCallbacks->handleActivate(this, !mIsMinimized); -                LL_INFOS() << "SDL deiconification state switched to " << bool(event.active.gain) << LL_ENDL; -            } -            else -            { -                LL_INFOS() << "Ignored bogus redundant SDL deiconification state switch to " << bool(event.active.gain) << LL_ENDL; -            } +                        mCallbacks->handleResize(this, width * getSystemUISize(), height * getSystemUISize()); +                        break; +                    } +                    case SDL_WINDOWEVENT_LEAVE: +                        mCallbacks->handleMouseLeave(this); +                        break; +                    case SDL_WINDOWEVENT_FOCUS_GAINED: +                        mCallbacks->handleFocus(this); +                        break; +                    case SDL_WINDOWEVENT_FOCUS_LOST: +                        mCallbacks->handleFocusLost(this); +                        break; +                    case SDL_WINDOWEVENT_EXPOSED: +                    case SDL_WINDOWEVENT_SHOWN: +                    case SDL_WINDOWEVENT_HIDDEN: +                    case SDL_WINDOWEVENT_MINIMIZED: +                    case SDL_WINDOWEVENT_MAXIMIZED: +                    case SDL_WINDOWEVENT_RESTORED: +                    { +                        Uint32 flags = SDL_GetWindowFlags(mWindow); +                        bool minimized = (flags & SDL_WINDOW_MINIMIZED); +                        bool hidden = (flags & SDL_WINDOW_HIDDEN); + +                        mCallbacks->handleActivate(this, !minimized || !hidden); +                        LL_INFOS() << "SDL deiconification state switched to " << minimized << LL_ENDL; +                        break; +                    }                  }                  break; - +            }              case SDL_QUIT:                  if(mCallbacks->handleCloseRequest(this))                  { @@ -1938,28 +1729,26 @@ void LLWindowSDL::gatherInput()                      // The app is responsible for calling destroyWindow when done with GL                  }                  break; -    default: -        //LL_INFOS() << "Unhandled SDL event type " << event.type << LL_ENDL; -        break; +            default: +                //LL_INFOS() << "Unhandled SDL event type " << event.type << LL_ENDL; +                break;          }      }      updateCursor(); -#if LL_X11      // This is a good time to stop flashing the icon if our mFlashTimer has      // expired.      if (mFlashing && mFlashTimer.hasExpired())      { -        x11_set_urgent(false); +        SDL_FlashWindow(mWindow, SDL_FLASH_CANCEL);          mFlashing = false;      } -#endif // LL_X11  }  static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty)  { -    SDL_Cursor *sdlcursor = NULL; +    SDL_Cursor *sdlcursor = nullptr;      SDL_Surface *bmpsurface;      // Load cursor pixel data from BMP file @@ -1968,21 +1757,21 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty      {          SDL_Surface *cursurface;          LL_DEBUGS() << "Loaded cursor file " << filename << " " -             << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL; +                    << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL;          cursurface = SDL_CreateRGBSurface (SDL_SWSURFACE, -                           bmpsurface->w, -                           bmpsurface->h, -                           32, -                           SDL_SwapLE32(0xFFU), -                           SDL_SwapLE32(0xFF00U), -                           SDL_SwapLE32(0xFF0000U), -                           SDL_SwapLE32(0xFF000000U)); +                                           bmpsurface->w, +                                           bmpsurface->h, +                                           32, +                                           SDL_SwapLE32(0xFFU), +                                           SDL_SwapLE32(0xFF00U), +                                           SDL_SwapLE32(0xFF0000U), +                                           SDL_SwapLE32(0xFF000000U));          SDL_FillRect(cursurface, NULL, SDL_SwapLE32(0x00000000U));          // Blit the cursor pixel data onto a 32-bit RGBA surface so we          // only have to cope with processing one type of pixel format.          if (0 == SDL_BlitSurface(bmpsurface, NULL, -                     cursurface, NULL)) +                                 cursurface, NULL))          {              // n.b. we already checked that width is a multiple of 8.              const int bitmap_bytes = (cursurface->w * cursurface->h) / 8; @@ -1997,26 +1786,26 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty              for (i=0; i<cursurface->h; ++i) {                  for (j=0; j<cursurface->w; ++j) {                      U8 *pixelp = -                        ((U8*)cursurface->pixels) -                        + cursurface->pitch * i -                        + j*cursurface->format->BytesPerPixel; +                            ((U8*)cursurface->pixels) +                            + cursurface->pitch * i +                            + j*cursurface->format->BytesPerPixel;                      U8 srcred = pixelp[0];                      U8 srcgreen = pixelp[1];                      U8 srcblue = pixelp[2];                      bool mask_bit = (srcred != 200) -                        || (srcgreen != 200) -                        || (srcblue != 200); +                                    || (srcgreen != 200) +                                    || (srcblue != 200);                      bool data_bit = mask_bit && (srcgreen <= 80);//not 0x80                      unsigned char bit_offset = (cursurface->w/8) * i -                        + j/8; +                                               + j/8;                      cursor_data[bit_offset] |= (data_bit) << (7 - (j&7));                      cursor_mask[bit_offset] |= (mask_bit) << (7 - (j&7));                  }              }              sdlcursor = SDL_CreateCursor((Uint8*)cursor_data, -                             (Uint8*)cursor_mask, -                             cursurface->w, cursurface->h, -                             hotx, hoty); +                                         (Uint8*)cursor_mask, +                                         cursurface->w, cursurface->h, +                                         hotx, hoty);              delete[] cursor_data;              delete[] cursor_mask;          } else { @@ -2033,12 +1822,6 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty  void LLWindowSDL::updateCursor()  { -    if (ATIbug) { -        // cursor-updating is very flaky when this bug is -        // present; do nothing. -        return; -    } -      if (mCurrentCursor != mNextCursor)      {          if (mNextCursor < UI_CURSOR_COUNT) @@ -2050,10 +1833,13 @@ void LLWindowSDL::updateCursor()                  sdlcursor = mSDLCursors[UI_CURSOR_ARROW];              if (sdlcursor)                  SDL_SetCursor(sdlcursor); -        } else { + +            mCurrentCursor = mNextCursor; +        } +        else +        {              LL_WARNS() << "Tried to set invalid cursor number " << mNextCursor << LL_ENDL;          } -        mCurrentCursor = mNextCursor;      }  } @@ -2063,24 +1849,24 @@ void LLWindowSDL::initCursors()      // Blank the cursor pointer array for those we may miss.      for (i=0; i<UI_CURSOR_COUNT; ++i)      { -        mSDLCursors[i] = NULL; +        mSDLCursors[i] = nullptr;      }      // Pre-make an SDL cursor for each of the known cursor types.      // We hardcode the hotspots - to avoid that we'd have to write      // a .cur file loader.      // NOTE: SDL doesn't load RLE-compressed BMP files. -    mSDLCursors[UI_CURSOR_ARROW] = makeSDLCursorFromBMP("llarrow.BMP",0,0); -    mSDLCursors[UI_CURSOR_WAIT] = makeSDLCursorFromBMP("wait.BMP",12,15); -    mSDLCursors[UI_CURSOR_HAND] = makeSDLCursorFromBMP("hand.BMP",7,10); -    mSDLCursors[UI_CURSOR_IBEAM] = makeSDLCursorFromBMP("ibeam.BMP",15,16); -    mSDLCursors[UI_CURSOR_CROSS] = makeSDLCursorFromBMP("cross.BMP",16,14); -    mSDLCursors[UI_CURSOR_SIZENWSE] = makeSDLCursorFromBMP("sizenwse.BMP",14,17); -    mSDLCursors[UI_CURSOR_SIZENESW] = makeSDLCursorFromBMP("sizenesw.BMP",17,17); -    mSDLCursors[UI_CURSOR_SIZEWE] = makeSDLCursorFromBMP("sizewe.BMP",16,14); -    mSDLCursors[UI_CURSOR_SIZENS] = makeSDLCursorFromBMP("sizens.BMP",17,16); -    mSDLCursors[UI_CURSOR_SIZEALL] = makeSDLCursorFromBMP("sizeall.BMP", 17, 17); -    mSDLCursors[UI_CURSOR_NO] = makeSDLCursorFromBMP("llno.BMP",8,8); -    mSDLCursors[UI_CURSOR_WORKING] = makeSDLCursorFromBMP("working.BMP",12,15); +    mSDLCursors[UI_CURSOR_ARROW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); +    mSDLCursors[UI_CURSOR_WAIT] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT); +    mSDLCursors[UI_CURSOR_HAND] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); +    mSDLCursors[UI_CURSOR_IBEAM] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); +    mSDLCursors[UI_CURSOR_CROSS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR); +    mSDLCursors[UI_CURSOR_SIZENWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); +    mSDLCursors[UI_CURSOR_SIZENESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); +    mSDLCursors[UI_CURSOR_SIZEWE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); +    mSDLCursors[UI_CURSOR_SIZENS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); +    mSDLCursors[UI_CURSOR_SIZEALL] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); +    mSDLCursors[UI_CURSOR_NO] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); +    mSDLCursors[UI_CURSOR_WORKING] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAITARROW);      mSDLCursors[UI_CURSOR_TOOLGRAB] = makeSDLCursorFromBMP("lltoolgrab.BMP",2,13);      mSDLCursors[UI_CURSOR_TOOLLAND] = makeSDLCursorFromBMP("lltoolland.BMP",1,6);      mSDLCursors[UI_CURSOR_TOOLFOCUS] = makeSDLCursorFromBMP("lltoolfocus.BMP",8,5); @@ -2113,11 +1899,6 @@ void LLWindowSDL::initCursors()      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) { -        LL_INFOS() << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << LL_ENDL; -        ATIbug = true; -    }  }  void LLWindowSDL::quitCursors() @@ -2167,7 +1948,7 @@ void LLWindowSDL::hideCursor()          // LL_INFOS() << "hideCursor: hiding" << LL_ENDL;          mCursorHidden = true;          mHideCursorPermanent = true; -        SDL_ShowCursor(0); +        SDL_ShowCursor(SDL_DISABLE);      }      else      { @@ -2182,7 +1963,7 @@ void LLWindowSDL::showCursor()          // LL_INFOS() << "showCursor: showing" << LL_ENDL;          mCursorHidden = false;          mHideCursorPermanent = false; -        SDL_ShowCursor(1); +        SDL_ShowCursor(SDL_ENABLE);      }      else      { @@ -2207,8 +1988,6 @@ void LLWindowSDL::hideCursorUntilMouseMove()      }  } - -  //  // LLSplashScreenSDL - I don't think we'll bother to implement this; it's  // fairly obsolete at this point. @@ -2233,133 +2012,71 @@ void LLSplashScreenSDL::hideImpl()  {  } - - -#if LL_GTK -static void response_callback (GtkDialog *dialog, -                   gint       arg1, -                   gpointer   user_data) -{ -    gint *response = (gint*)user_data; -    *response = arg1; -    gtk_widget_destroy(GTK_WIDGET(dialog)); -    gtk_main_quit(); -} -  S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type)  { -    S32 rtn = OSBTN_CANCEL; - -    if(gWindowImplementation != NULL) -        gWindowImplementation->beforeDialog(); +    SDL_MessageBoxData oData = { SDL_MESSAGEBOX_INFORMATION, nullptr, caption.c_str(), text.c_str(), 0, nullptr, nullptr }; +    SDL_MessageBoxButtonData btnOk[] = {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_OK, "OK" }}; +    SDL_MessageBoxButtonData btnOkCancel [] =  {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_OK, "OK" }, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, OSBTN_CANCEL, "Cancel"} }; +    SDL_MessageBoxButtonData btnYesNo[] = { {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_YES, "Yes" }, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, OSBTN_NO, "No"} }; -    if (LLWindowSDL::ll_try_gtk_init()) +    switch (type)      { -        GtkWidget *win = NULL; - -        LL_INFOS() << "Creating a dialog because we're in windowed mode and GTK is happy." << LL_ENDL; - -        GtkDialogFlags flags = GTK_DIALOG_MODAL; -        GtkMessageType messagetype; -        GtkButtonsType buttons; -        switch (type) -        {          default:          case OSMB_OK: -            messagetype = GTK_MESSAGE_WARNING; -            buttons = GTK_BUTTONS_OK; +            oData.flags = SDL_MESSAGEBOX_WARNING; +            oData.buttons = btnOk; +            oData.numbuttons = 1;              break;          case OSMB_OKCANCEL: -            messagetype = GTK_MESSAGE_QUESTION; -            buttons = GTK_BUTTONS_OK_CANCEL; +            oData.flags = SDL_MESSAGEBOX_INFORMATION; +            oData.buttons = btnOkCancel; +            oData.numbuttons = 2;              break;          case OSMB_YESNO: -            messagetype = GTK_MESSAGE_QUESTION; -            buttons = GTK_BUTTONS_YES_NO; +            oData.flags = SDL_MESSAGEBOX_INFORMATION; +            oData.buttons = btnYesNo; +            oData.numbuttons = 2;              break; -        } -        win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, "%s", -                                     text.c_str()); - -# if LL_X11 -        // Make GTK tell the window manager to associate this -        // dialog with our non-GTK SDL window, which should try -        // to keep it on top etc. -        if (gWindowImplementation && -            gWindowImplementation->mSDL_XWindowID != None) -        { -            gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin -            GdkWindow *gdkwin = gdk_window_foreign_new(gWindowImplementation->mSDL_XWindowID); -            gdk_window_set_transient_for(GTK_WIDGET(win)->window, -                             gdkwin); -        } -# endif //LL_X11 - -        gtk_window_set_position(GTK_WINDOW(win), -                    GTK_WIN_POS_CENTER_ON_PARENT); - -        gtk_window_set_type_hint(GTK_WINDOW(win), -                     GDK_WINDOW_TYPE_HINT_DIALOG); - -        if (!caption.empty()) -            gtk_window_set_title(GTK_WINDOW(win), caption.c_str()); - -        gint response = GTK_RESPONSE_NONE; -        g_signal_connect (win, -                  "response", -                  G_CALLBACK (response_callback), -                  &response); - -        // we should be able to use a gtk_dialog_run(), but it's -        // apparently not written to exist in a world without a higher -        // gtk_main(), so we manage its signal/destruction outselves. -        gtk_widget_show_all (win); -        gtk_main(); - -        //LL_INFOS() << "response: " << response << LL_ENDL; -        switch (response) -        { -        case GTK_RESPONSE_OK:     rtn = OSBTN_OK; break; -        case GTK_RESPONSE_YES:    rtn = OSBTN_YES; break; -        case GTK_RESPONSE_NO:     rtn = OSBTN_NO; break; -        case GTK_RESPONSE_APPLY:  rtn = OSBTN_OK; break; -        case GTK_RESPONSE_NONE: -        case GTK_RESPONSE_CANCEL: -        case GTK_RESPONSE_CLOSE: -        case GTK_RESPONSE_DELETE_EVENT: -        default: rtn = OSBTN_CANCEL; -        } -    } -    else -    { -        LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; -        LL_INFOS() << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << LL_ENDL; -        rtn = OSBTN_OK;      } -    if(gWindowImplementation != NULL) -        gWindowImplementation->afterDialog(); +    int btn{0}; +    if( 0 == SDL_ShowMessageBox( &oData, &btn ) ) +        return btn; +    return OSBTN_CANCEL; +} -    return rtn; +bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) +{ +    return (false);  } -static void color_changed_callback(GtkWidget *widget, -                   gpointer user_data) +#if LL_DARWIN +LLSD LLWindowSDL::getNativeKeyData()  { -    GtkColorSelection *colorsel = GTK_COLOR_SELECTION(widget); -    GdkColor *colorp = (GdkColor*)user_data; +    LLSD result = LLSD::emptyMap(); -    gtk_color_selection_get_current_color(colorsel, colorp); -} +    if(mRawKeyEvent) +    { +        result["event_type"] = LLSD::Integer(mRawKeyEvent->mEventType); +        result["event_modifiers"] = LLSD::Integer(mRawKeyEvent->mEventModifiers); +        result["event_keycode"] = LLSD::Integer(mRawKeyEvent->mEventKeyCode); +        result["event_chars"] = (mRawKeyEvent->mEventChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventChars)) : LLSD(); +        result["event_umodchars"] = (mRawKeyEvent->mEventUnmodChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventUnmodChars)) : LLSD(); +        result["event_isrepeat"] = LLSD::Boolean(mRawKeyEvent->mEventRepeat); +    } +    LL_DEBUGS() << "native key data is: " << result << LL_ENDL; +    return result; +} +#else  /*          Make the raw keyboard data available - used to poke through to LLQtWebKit so          that Qt/Webkit has access to the virtual keycodes etc. that it needs  */  LLSD LLWindowSDL::getNativeKeyData()  { -        LLSD result = LLSD::emptyMap(); +    LLSD result = LLSD::emptyMap();      U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave! @@ -2377,130 +2094,13 @@ LLSD LLWindowSDL::getNativeKeyData()      // *todo: test ALTs - I don't have a case for testing these.  Do you?      // *todo: NUM? - I don't care enough right now (and it's not a GDK modifier). -        result["scan_code"] = (S32)mKeyScanCode; -        result["virtual_key"] = (S32)mKeyVirtualKey; +    result["virtual_key"] = (S32)mKeyVirtualKey; +    result["virtual_key_win"] = (S32)LLKeyboardSDL::mapSDL2toWin( mKeyVirtualKey );      result["modifiers"] = (S32)modifiers; - -        return result; -} - - -bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) -{ -    bool rtn = false; - -    beforeDialog(); - -    if (ll_try_gtk_init()) -    { -        GtkWidget *win = NULL; - -        win = gtk_color_selection_dialog_new(NULL); - -# if LL_X11 -        // Get GTK to tell the window manager to associate this -        // dialog with our non-GTK SDL window, which should try -        // to keep it on top etc. -        if (mSDL_XWindowID != None) -        { -            gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin -            GdkWindow *gdkwin = gdk_window_foreign_new(mSDL_XWindowID); -            gdk_window_set_transient_for(GTK_WIDGET(win)->window, -                             gdkwin); -        } -# endif //LL_X11 - -        GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel); - -        GdkColor color, orig_color; -        orig_color.pixel = 0; -        orig_color.red = guint16(65535 * *r); -        orig_color.green= guint16(65535 * *g); -        orig_color.blue = guint16(65535 * *b); -        color = orig_color; - -        gtk_color_selection_set_previous_color (colorsel, &color); -        gtk_color_selection_set_current_color (colorsel, &color); -        gtk_color_selection_set_has_palette (colorsel, true); -        gtk_color_selection_set_has_opacity_control(colorsel, false); - -        gint response = GTK_RESPONSE_NONE; -        g_signal_connect (win, -                  "response", -                  G_CALLBACK (response_callback), -                  &response); - -        g_signal_connect (G_OBJECT (colorsel), "color_changed", -                  G_CALLBACK (color_changed_callback), -                  &color); - -        gtk_window_set_modal(GTK_WINDOW(win), true); -        gtk_widget_show_all(win); -        // hide the help button - we don't service it. -        gtk_widget_hide(GTK_COLOR_SELECTION_DIALOG(win)->help_button); -        gtk_main(); - -        if (response == GTK_RESPONSE_OK && -            (orig_color.red != color.red -             || orig_color.green != color.green -             || orig_color.blue != color.blue) ) -        { -            *r = color.red / 65535.0f; -            *g = color.green / 65535.0f; -            *b = color.blue / 65535.0f; -            rtn = true; -        } -    } - -    afterDialog(); - -    return rtn; -} -#else -S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type) -{ -    LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; -    return 0; -} - -bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) -{ -    return (false); -} -#endif // LL_GTK - -#if LL_LINUX -// extracted from spawnWebBrowser for clarity and to eliminate -//  compiler confusion regarding close(int fd) vs. LLWindow::close() -void exec_cmd(const std::string& cmd, const std::string& arg) -{ -    char* const argv[] = {(char*)cmd.c_str(), (char*)arg.c_str(), NULL}; -    fflush(NULL); -    pid_t pid = fork(); -    if (pid == 0) -    { // child -        // disconnect from stdin/stdout/stderr, or child will -        // keep our output pipe undesirably alive if it outlives us. -        close(0); -        close(1); -        close(2); -        // end ourself by running the command -        execv(cmd.c_str(), argv);   /* Flawfinder: ignore */ -        // if execv returns at all, there was a problem. -        LL_WARNS() << "execv failure when trying to start " << cmd << LL_ENDL; -        _exit(1); // _exit because we don't want atexit() clean-up! -    } else { -        if (pid > 0) -        { -            // parent - wait for child to die -            int childExitStatus; -            waitpid(pid, &childExitStatus, 0); -        } else { -            LL_WARNS() << "fork failure." << LL_ENDL; -        } -    } +    result["input_type"] = mInputType; +    return result;  } -#endif +#endif // LL_DARWIN  // Open a URL with the user's default web browser.  // Must begin with protocol identifier. @@ -2525,55 +2125,16 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)      LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; -#if LL_LINUX -# if LL_X11 -    if (mSDL_Display) +    if (SDL_OpenURL(escaped_url.c_str()) != 0)      { -        maybe_lock_display(); -        // Just in case - before forking. -        XSync(mSDL_Display, False); -        maybe_unlock_display(); +        LL_WARNS() << "spawn_web_browser failed with error: " << SDL_GetError() << LL_ENDL;      } -# endif // LL_X11 - -    std::string cmd, arg; -    cmd  = gDirUtilp->getAppRODataDir(); -    cmd += gDirUtilp->getDirDelimiter(); -    cmd += "etc"; -    cmd += gDirUtilp->getDirDelimiter(); -    cmd += "launch_url.sh"; -    arg = escaped_url; -    exec_cmd(cmd, arg); -#endif // LL_LINUX      LL_INFOS() << "spawn_web_browser returning." << LL_ENDL;  } -  void *LLWindowSDL::getPlatformWindow()  { -#if LL_GTK && LL_LLMOZLIB_ENABLED -    if (LLWindowSDL::ll_try_gtk_init()) -    { -        maybe_lock_display(); - -        GtkWidget *owin = gtk_window_new(GTK_WINDOW_POPUP); -        // Why a layout widget?  A MozContainer would be ideal, but -        // it involves exposing Mozilla headers to mozlib-using apps. -        // A layout widget with a GtkWindow parent has the desired -        // properties of being plain GTK, having a window, and being -        // derived from a GtkContainer. -        GtkWidget *rtnw = gtk_layout_new(NULL, NULL); -        gtk_container_add(GTK_CONTAINER(owin), rtnw); -        gtk_widget_realize(rtnw); -        GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); - -        maybe_unlock_display(); - -        return rtnw; -    } -#endif // LL_GTK && LL_LLMOZLIB_ENABLED -    // Unixoid mozilla really needs GTK.      return NULL;  } @@ -2582,15 +2143,10 @@ void LLWindowSDL::bringToFront()      // This is currently used when we are 'launched' to a specific      // map position externally.      LL_INFOS() << "bringToFront" << LL_ENDL; -#if LL_X11 -    if (mSDL_Display && !mFullscreen) +    if (mWindow && !mFullscreen)      { -        maybe_lock_display(); -        XRaiseWindow(mSDL_Display, mSDL_XWindowID); -        XSync(mSDL_Display, False); -        maybe_unlock_display(); +        SDL_RaiseWindow(mWindow);      } -#endif // LL_X11  }  //static @@ -2634,10 +2190,10 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()              LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL;              LL_INFOS() << "Preferring fonts of language: " -                << locale->lang -                << LL_ENDL; +                       << locale->lang +                       << LL_ENDL;              sort_order = "lang=" + std::string(locale->lang) + ":" -                + sort_order; +                         + sort_order;          }      }      FL_FreeLocale(&locale); @@ -2655,7 +2211,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()          // Sort the list of system fonts from most-to-least-desirable.          FcResult result;          fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, -                NULL, &result); +                        NULL, &result);          FcPatternDestroy(sortpat);      } @@ -2669,8 +2225,8 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()          {              FcChar8 *filename;              if (FcResultMatch == FcPatternGetString(fs->fonts[i], -                                FC_FILE, 0, -                                &filename) +                                                    FC_FILE, 0, +                                                    &filename)                  && filename)              {                  rtns.push_back(std::string((const char*)filename)); @@ -2694,4 +2250,16 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()      return rtns;  } -#endif // LL_SDL +void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position) +{ +    LLCoordWindow win_pos; +    convertCoords( position, &win_pos ); + +    SDL_Rect r; +    r.x = win_pos.mX; +    r.y = win_pos.mY; +    r.w = 500; +    r.h = 16; + +    SDL_SetTextInputRect(&r); +} diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 196ad2986d..076d7234bc 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -24,20 +24,24 @@   * $/LicenseInfo$   */ -#ifndef LL_LLWINDOWSDL_H -#define LL_LLWINDOWSDL_H +#ifndef LL_LLWINDOWSDL2_H +#define LL_LLWINDOWSDL2_H  // Simple Directmedia Layer (http://libsdl.org/) implementation of LLWindow class  #include "llwindow.h"  #include "lltimer.h" -#include "SDL/SDL.h" -#include "SDL/SDL_endian.h" +#if !defined(__i386__) && !defined(__x86_64__) && !_M_X64 +#define SDL_DISABLE_IMMINTRIN_H +#endif +#include "SDL2/SDL.h" +#include "SDL2/SDL_video.h" +#include "SDL2/SDL_endian.h"  #if LL_X11  // get X11-specific headers for use in low-level stuff like copy-and-paste support -#include "SDL/SDL_syswm.h" +#include "SDL2/SDL_syswm.h"  #endif  // AssertMacros.h does bad things. @@ -46,83 +50,139 @@  #undef require -class LLWindowSDL : public LLWindow -{ +class LLWindowSDL : public LLWindow {  public: -    /*virtual*/ void show(); -    /*virtual*/ void hide(); -    /*virtual*/ void close(); -    /*virtual*/ bool getVisible(); -    /*virtual*/ bool getMinimized(); -    /*virtual*/ bool getMaximized(); -    /*virtual*/ bool maximize(); -    /*virtual*/ void minimize(); -    /*virtual*/ void restore(); -    /*virtual*/ bool getFullscreen(); -    /*virtual*/ bool getPosition(LLCoordScreen *position); -    /*virtual*/ bool getSize(LLCoordScreen *size); -    /*virtual*/ bool getSize(LLCoordWindow *size); -    /*virtual*/ bool setPosition(LLCoordScreen position); -    /*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); -    /*virtual*/ void showCursor(); -    /*virtual*/ void hideCursor(); -    /*virtual*/ void showCursorFromMouseMove(); -    /*virtual*/ void hideCursorUntilMouseMove(); -    /*virtual*/ bool isCursorHidden(); -    /*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); -    /*virtual*/ bool copyTextToClipboard(const LLWString & src); - -    /*virtual*/ bool isPrimaryTextAvailable(); -    /*virtual*/ bool pasteTextFromPrimary(LLWString &dst); -    /*virtual*/ bool copyTextToPrimary(const LLWString & src); - -    /*virtual*/ void flashIcon(F32 seconds); -    /*virtual*/ F32 getGamma(); -    /*virtual*/ bool setGamma(const F32 gamma); // Set the gamma -    /*virtual*/ U32 getFSAASamples(); -    /*virtual*/ void setFSAASamples(const U32 samples); -    /*virtual*/ bool restoreGamma();            // Restore original gamma table (before updating gamma) -    /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } -    /*virtual*/ void processMiscNativeEvents(); -    /*virtual*/ void gatherInput(); -    /*virtual*/ void swapBuffers(); -    /*virtual*/ void restoreGLContext() {}; - -    /*virtual*/ void delayInputProcessing() { }; +    void show() override; + +    void hide() override; + +    void close() override; + +    bool getVisible() override; + +    bool getMinimized() override; + +    bool getMaximized() override; + +    bool maximize() override; + +    void minimize() override; + +    void restore() override; + +    bool getFullscreen(); + +    bool getPosition(LLCoordScreen *position) override; + +    bool getSize(LLCoordScreen *size) override; + +    bool getSize(LLCoordWindow *size) override; + +    bool setPosition(LLCoordScreen position) override; + +    bool setSizeImpl(LLCoordScreen size) override; + +    bool setSizeImpl(LLCoordWindow size) override; + +    bool switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, +                                   const LLCoordScreen *const posp = NULL) override; + +    bool setCursorPosition(LLCoordWindow position) override; + +    bool getCursorPosition(LLCoordWindow *position) override; + +    void showCursor() override; + +    void hideCursor() override; + +    void showCursorFromMouseMove() override; + +    void hideCursorUntilMouseMove() override; + +    bool isCursorHidden() override; + +    void updateCursor() override; + +    void captureMouse() override; + +    void releaseMouse() override; + +    void setMouseClipping(bool b) override; + +       void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true) override; + +    bool isClipboardTextAvailable() override; + +    bool pasteTextFromClipboard(LLWString &dst) override; + +    bool copyTextToClipboard(const LLWString &src) override; + +    bool isPrimaryTextAvailable() override; + +    bool pasteTextFromPrimary(LLWString &dst) override; + +    bool copyTextToPrimary(const LLWString &src) override; + +    void flashIcon(F32 seconds) override; + +    F32 getGamma() override; + +    bool setGamma(const F32 gamma) override; // Set the gamma +    U32 getFSAASamples() override; + +    void setFSAASamples(const U32 samples) override; + +    bool restoreGamma() override;            // Restore original gamma table (before updating gamma) +    ESwapMethod getSwapMethod()  override { return mSwapMethod; } + +    void processMiscNativeEvents() override; + +    void gatherInput() override; + +    void swapBuffers() override; + +    void restoreGLContext() {}; + +    void delayInputProcessing()  override {};      // handy coordinate space conversion routines -    /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordWindow *to); -    /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordScreen *to); -    /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordGL *to); -    /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordWindow *to); -    /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordGL *to); -    /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordScreen *to); +    bool convertCoords(LLCoordScreen from, LLCoordWindow *to) override; + +    bool convertCoords(LLCoordWindow from, LLCoordScreen *to) override; + +    bool convertCoords(LLCoordWindow from, LLCoordGL *to) override; + +    bool convertCoords(LLCoordGL from, LLCoordWindow *to) override; + +    bool convertCoords(LLCoordScreen from, LLCoordGL *to) override; + +    bool convertCoords(LLCoordGL from, LLCoordScreen *to) override; + +    LLWindowResolution *getSupportedResolutions(S32 &num_resolutions) override; + +    F32 getNativeAspectRatio() override; + +    F32 getPixelAspectRatio() override; -    /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); -    /*virtual*/ F32 getNativeAspectRatio(); -    /*virtual*/ F32 getPixelAspectRatio(); -    /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } +    void setNativeAspectRatio(F32 ratio)  override { mOverrideAspectRatio = ratio; } -    /*virtual*/ void beforeDialog(); -    /*virtual*/ void afterDialog(); +    F32 getSystemUISize() override; -    /*virtual*/ bool dialogColorPicker(F32 *r, F32 *g, F32 *b); +    void beforeDialog() override; -    /*virtual*/ void *getPlatformWindow(); -    /*virtual*/ void bringToFront(); +    void afterDialog() override; -    /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); +    bool dialogColorPicker(F32 *r, F32 *g, F32 *b) override; + +    void *getPlatformWindow() override; + +    void bringToFront() override; + +    void setLanguageTextInput(const LLCoordGL& pos) override; + +    void spawnWebBrowser(const std::string &escaped_url, bool async) override; + +    void setTitle(const std::string title) override;      static std::vector<std::string> getDynamicFallbackFontList(); @@ -132,40 +192,56 @@ public:      Window mSDL_XWindowID;      Display *mSDL_Display;  #endif +      void (*Lock_Display)(void); -    void (*Unlock_Display)(void); -#if LL_GTK -    // Lazily initialize and check the runtime GTK version for goodness. -    static bool ll_try_gtk_init(void); -#endif // LL_GTK +    void (*Unlock_Display)(void);  #if LL_X11 +      static Window get_SDL_XWindowID(void); -    static Display* get_SDL_Display(void); + +    static Display *get_SDL_Display(void); +  #endif // LL_X11 +#if LL_DARWIN +    static bool sUseMultGL; +#endif + +    void *createSharedContext() override; + +    void makeContextCurrent(void *context) override; + +    void destroySharedContext(void *context) override; + +    void toggleVSync(bool enable_vsync) override; +  protected: -    LLWindowSDL(LLWindowCallbacks* callbacks, -        const std::string& title, int x, int y, int width, int height, U32 flags, -        bool fullscreen, bool clearBg, bool disable_vsync, bool use_gl, -        bool ignore_pixel_depth, U32 fsaa_samples); +    LLWindowSDL(LLWindowCallbacks *callbacks, +                const std::string &title, const std::string& name, int x, int y, int width, int height, U32 flags, +                bool fullscreen, bool clearBg, bool enable_vsync, bool use_gl, +                bool ignore_pixel_depth, U32 fsaa_samples); +      ~LLWindowSDL(); -    /*virtual*/ bool    isValid(); -    /*virtual*/ LLSD    getNativeKeyData(); +    bool isValid() override; + +    LLSD getNativeKeyData() override; + +    void initCursors(); + +    void quitCursors(); -    void    initCursors(); -    void    quitCursors(); -    void    moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); +    void moveWindow(const LLCoordScreen &position, const LLCoordScreen &size);      // Changes display resolution. Returns true if successful -    bool    setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); +    bool setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh);      // Go back to last fullscreen display resolution. -    bool    setFullscreenResolution(); +    bool setFullscreenResolution(); -    bool    shouldPostQuit() { return mPostQuit; } +    bool shouldPostQuit() { return mPostQuit; }  protected:      // @@ -173,47 +249,52 @@ protected:      //      // create or re-create the GL context/window.  Called from the constructor and switchContext(). -    bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync); +    bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync); +      void destroyContext(); -    void setupFailure(const std::string& text, const std::string& caption, U32 type); -    void fixWindowSize(void); -    U32 SDLCheckGrabbyKeys(SDLKey keysym, bool gain); + +    void setupFailure(const std::string &text, const std::string &caption, U32 type); + +    U32 SDLCheckGrabbyKeys(U32 keysym, bool gain); +      bool SDLReallyCaptureInput(bool capture);      //      // Platform specific variables      // -    U32             mGrabbyKeyFlags; -    int         mReallyCapturedCount; -    SDL_Surface *   mWindow; +    U32 mGrabbyKeyFlags; +    int mReallyCapturedCount; + +    SDL_Window *mWindow; +    SDL_GLContext mContext; +    SDL_Cursor *mSDLCursors[UI_CURSOR_COUNT]; +      std::string mWindowTitle; -    double      mOriginalAspectRatio; -    bool        mNeedsResize;       // Constructor figured out the window is too big, it needs a resize. -    LLCoordScreen   mNeedsResizeSize; -    F32         mOverrideAspectRatio; -    F32     mGamma; -    U32     mFSAASamples; +    double mOriginalAspectRatio; +    bool mNeedsResize;        // Constructor figured out the window is too big, it needs a resize. +    LLCoordScreen mNeedsResizeSize; +    F32 mOverrideAspectRatio; +    F32 mGamma; +    U32 mFSAASamples; -    int     mSDLFlags; +    int mSDLFlags; -    SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT]; -    int             mHaveInputFocus; /* 0=no, 1=yes, else unknown */ -    int             mIsMinimized; /* 0=no, 1=yes, else unknown */ +    int mHaveInputFocus; /* 0=no, 1=yes, else unknown */ +    int mIsMinimized; /* 0=no, 1=yes, else unknown */      friend class LLWindowManager;  private: -#if LL_X11 -    void x11_set_urgent(bool urgent);      bool mFlashing;      LLTimer mFlashTimer; -#endif //LL_X11 +    U32 mKeyVirtualKey; +    U32 mKeyModifiers; +    std::string mInputType; -    U32 mKeyScanCode; -        U32 mKeyVirtualKey; -    SDLMod mKeyModifiers; -}; +private: +    void tryFindFullscreenSize(int &aWidth, int &aHeight); +};  class LLSplashScreenSDL : public LLSplashScreen  { @@ -221,9 +302,9 @@ public:      LLSplashScreenSDL();      virtual ~LLSplashScreenSDL(); -    /*virtual*/ void showImpl(); -    /*virtual*/ void updateImpl(const std::string& mesg); -    /*virtual*/ void hideImpl(); +    void showImpl(); +    void updateImpl(const std::string& mesg); +    void hideImpl();  };  S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index fc7d8cec72..cfc2038be9 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -603,6 +603,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,      // Make an instance of our window then define the window class      mhInstance = GetModuleHandle(NULL); +#if !_M_ARM64      // Init Direct Input - needed for joystick / Spacemouse      LPDIRECTINPUT8 di8_interface; @@ -617,6 +618,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,      {          gDirectInput8 = di8_interface;      } +#endif      mSwapMethod = SWAP_METHOD_UNDEFINED;  | 
