diff options
author | Erik Kundiman <erik@megapahit.org> | 2024-05-16 13:52:40 +0800 |
---|---|---|
committer | Erik Kundiman <erik@megapahit.org> | 2024-05-16 13:52:40 +0800 |
commit | 6d51e91895a7f2435c46a876410ccc6c63fe8c82 (patch) | |
tree | f2b48ebd99cb414227bf365f47665b8d4baa752b /indra/llwindow | |
parent | d1b5917bb9c92e4e47eba19b43781e4d1328b1ca (diff) | |
parent | 094dcc07f8c1d90ae723dbe60eddacb90a09eae8 (diff) |
Merge tag '7.1.7-release'
source for viewer 7.1.7.8974243247
Diffstat (limited to 'indra/llwindow')
37 files changed, 9280 insertions, 8770 deletions
diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h index ceda7ff74c..ef36f7d4a8 100644 --- a/indra/llwindow/llappdelegate-objc.h +++ b/indra/llwindow/llappdelegate-objc.h @@ -28,11 +28,11 @@ #import "llopenglview-objc.h" @interface LLAppDelegate : NSObject <NSApplicationDelegate> { - LLNSWindow *window; - NSWindow *inputWindow; - LLNonInlineTextView *inputView; - NSTimer *frameTimer; - NSString *currentInputLanguage; + LLNSWindow *window; + NSWindow *inputWindow; + LLNonInlineTextView *inputView; + NSTimer *frameTimer; + NSString *currentInputLanguage; std::string secondLogPath; } diff --git a/indra/llwindow/llcursortypes.cpp b/indra/llwindow/llcursortypes.cpp index 3079cc2419..3e531873db 100644 --- a/indra/llwindow/llcursortypes.cpp +++ b/indra/llwindow/llcursortypes.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llcursortypes.cpp * @brief Cursor types and lookup of types from a string * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,63 +30,63 @@ ECursorType getCursorFromString(const std::string& cursor_string) { - static std::map<std::string,U32> cursor_string_table; - if (cursor_string_table.empty()) - { - cursor_string_table["UI_CURSOR_ARROW"] = UI_CURSOR_ARROW; - cursor_string_table["UI_CURSOR_WAIT"] = UI_CURSOR_WAIT; - cursor_string_table["UI_CURSOR_HAND"] = UI_CURSOR_HAND; - cursor_string_table["UI_CURSOR_IBEAM"] = UI_CURSOR_IBEAM; - cursor_string_table["UI_CURSOR_CROSS"] = UI_CURSOR_CROSS; - cursor_string_table["UI_CURSOR_SIZENWSE"] = UI_CURSOR_SIZENWSE; - cursor_string_table["UI_CURSOR_SIZENESW"] = UI_CURSOR_SIZENESW; - cursor_string_table["UI_CURSOR_SIZEWE"] = UI_CURSOR_SIZEWE; - cursor_string_table["UI_CURSOR_SIZENS"] = UI_CURSOR_SIZENS; - cursor_string_table["UI_CURSOR_SIZEALL"] = UI_CURSOR_SIZEALL; - cursor_string_table["UI_CURSOR_NO"] = UI_CURSOR_NO; - cursor_string_table["UI_CURSOR_WORKING"] = UI_CURSOR_WORKING; - cursor_string_table["UI_CURSOR_TOOLGRAB"] = UI_CURSOR_TOOLGRAB; - cursor_string_table["UI_CURSOR_TOOLLAND"] = UI_CURSOR_TOOLLAND; - cursor_string_table["UI_CURSOR_TOOLFOCUS"] = UI_CURSOR_TOOLFOCUS; - cursor_string_table["UI_CURSOR_TOOLCREATE"] = UI_CURSOR_TOOLCREATE; - cursor_string_table["UI_CURSOR_ARROWDRAG"] = UI_CURSOR_ARROWDRAG; - cursor_string_table["UI_CURSOR_ARROWCOPY"] = UI_CURSOR_ARROWCOPY; - cursor_string_table["UI_CURSOR_ARROWDRAGMULTI"] = UI_CURSOR_ARROWDRAGMULTI; - cursor_string_table["UI_CURSOR_ARROWCOPYMULTI"] = UI_CURSOR_ARROWCOPYMULTI; - cursor_string_table["UI_CURSOR_NOLOCKED"] = UI_CURSOR_NOLOCKED; - cursor_string_table["UI_CURSOR_ARROWLOCKED"] = UI_CURSOR_ARROWLOCKED; - cursor_string_table["UI_CURSOR_GRABLOCKED"] = UI_CURSOR_GRABLOCKED; - cursor_string_table["UI_CURSOR_TOOLTRANSLATE"] = UI_CURSOR_TOOLTRANSLATE; - cursor_string_table["UI_CURSOR_TOOLROTATE"] = UI_CURSOR_TOOLROTATE; - cursor_string_table["UI_CURSOR_TOOLSCALE"] = UI_CURSOR_TOOLSCALE; - cursor_string_table["UI_CURSOR_TOOLCAMERA"] = UI_CURSOR_TOOLCAMERA; - cursor_string_table["UI_CURSOR_TOOLPAN"] = UI_CURSOR_TOOLPAN; - cursor_string_table["UI_CURSOR_TOOLZOOMIN"] = UI_CURSOR_TOOLZOOMIN; - cursor_string_table["UI_CURSOR_TOOLZOOMOUT"] = UI_CURSOR_TOOLZOOMOUT; - cursor_string_table["UI_CURSOR_TOOLPICKOBJECT3"] = UI_CURSOR_TOOLPICKOBJECT3; - cursor_string_table["UI_CURSOR_TOOLPLAY"] = UI_CURSOR_TOOLPLAY; - cursor_string_table["UI_CURSOR_TOOLPAUSE"] = UI_CURSOR_TOOLPAUSE; - cursor_string_table["UI_CURSOR_TOOLMEDIAOPEN"] = UI_CURSOR_TOOLMEDIAOPEN; - cursor_string_table["UI_CURSOR_PIPETTE"] = UI_CURSOR_PIPETTE; - cursor_string_table["UI_CURSOR_TOOLSIT"] = UI_CURSOR_TOOLSIT; - cursor_string_table["UI_CURSOR_TOOLBUY"] = UI_CURSOR_TOOLBUY; - cursor_string_table["UI_CURSOR_TOOLOPEN"] = UI_CURSOR_TOOLOPEN; - cursor_string_table["UI_CURSOR_TOOLPATHFINDING"] = UI_CURSOR_TOOLPATHFINDING; - cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTART"] = UI_CURSOR_TOOLPATHFINDING_PATH_START; - cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTARTADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD; - cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHEND"] = UI_CURSOR_TOOLPATHFINDING_PATH_END; - cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHENDADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD; - cursor_string_table["UI_CURSOR_TOOLNO"] = UI_CURSOR_TOOLNO; - } + static std::map<std::string,U32> cursor_string_table; + if (cursor_string_table.empty()) + { + cursor_string_table["UI_CURSOR_ARROW"] = UI_CURSOR_ARROW; + cursor_string_table["UI_CURSOR_WAIT"] = UI_CURSOR_WAIT; + cursor_string_table["UI_CURSOR_HAND"] = UI_CURSOR_HAND; + cursor_string_table["UI_CURSOR_IBEAM"] = UI_CURSOR_IBEAM; + cursor_string_table["UI_CURSOR_CROSS"] = UI_CURSOR_CROSS; + cursor_string_table["UI_CURSOR_SIZENWSE"] = UI_CURSOR_SIZENWSE; + cursor_string_table["UI_CURSOR_SIZENESW"] = UI_CURSOR_SIZENESW; + cursor_string_table["UI_CURSOR_SIZEWE"] = UI_CURSOR_SIZEWE; + cursor_string_table["UI_CURSOR_SIZENS"] = UI_CURSOR_SIZENS; + cursor_string_table["UI_CURSOR_SIZEALL"] = UI_CURSOR_SIZEALL; + cursor_string_table["UI_CURSOR_NO"] = UI_CURSOR_NO; + cursor_string_table["UI_CURSOR_WORKING"] = UI_CURSOR_WORKING; + cursor_string_table["UI_CURSOR_TOOLGRAB"] = UI_CURSOR_TOOLGRAB; + cursor_string_table["UI_CURSOR_TOOLLAND"] = UI_CURSOR_TOOLLAND; + cursor_string_table["UI_CURSOR_TOOLFOCUS"] = UI_CURSOR_TOOLFOCUS; + cursor_string_table["UI_CURSOR_TOOLCREATE"] = UI_CURSOR_TOOLCREATE; + cursor_string_table["UI_CURSOR_ARROWDRAG"] = UI_CURSOR_ARROWDRAG; + cursor_string_table["UI_CURSOR_ARROWCOPY"] = UI_CURSOR_ARROWCOPY; + cursor_string_table["UI_CURSOR_ARROWDRAGMULTI"] = UI_CURSOR_ARROWDRAGMULTI; + cursor_string_table["UI_CURSOR_ARROWCOPYMULTI"] = UI_CURSOR_ARROWCOPYMULTI; + cursor_string_table["UI_CURSOR_NOLOCKED"] = UI_CURSOR_NOLOCKED; + cursor_string_table["UI_CURSOR_ARROWLOCKED"] = UI_CURSOR_ARROWLOCKED; + cursor_string_table["UI_CURSOR_GRABLOCKED"] = UI_CURSOR_GRABLOCKED; + cursor_string_table["UI_CURSOR_TOOLTRANSLATE"] = UI_CURSOR_TOOLTRANSLATE; + cursor_string_table["UI_CURSOR_TOOLROTATE"] = UI_CURSOR_TOOLROTATE; + cursor_string_table["UI_CURSOR_TOOLSCALE"] = UI_CURSOR_TOOLSCALE; + cursor_string_table["UI_CURSOR_TOOLCAMERA"] = UI_CURSOR_TOOLCAMERA; + cursor_string_table["UI_CURSOR_TOOLPAN"] = UI_CURSOR_TOOLPAN; + cursor_string_table["UI_CURSOR_TOOLZOOMIN"] = UI_CURSOR_TOOLZOOMIN; + cursor_string_table["UI_CURSOR_TOOLZOOMOUT"] = UI_CURSOR_TOOLZOOMOUT; + cursor_string_table["UI_CURSOR_TOOLPICKOBJECT3"] = UI_CURSOR_TOOLPICKOBJECT3; + cursor_string_table["UI_CURSOR_TOOLPLAY"] = UI_CURSOR_TOOLPLAY; + cursor_string_table["UI_CURSOR_TOOLPAUSE"] = UI_CURSOR_TOOLPAUSE; + cursor_string_table["UI_CURSOR_TOOLMEDIAOPEN"] = UI_CURSOR_TOOLMEDIAOPEN; + cursor_string_table["UI_CURSOR_PIPETTE"] = UI_CURSOR_PIPETTE; + cursor_string_table["UI_CURSOR_TOOLSIT"] = UI_CURSOR_TOOLSIT; + cursor_string_table["UI_CURSOR_TOOLBUY"] = UI_CURSOR_TOOLBUY; + cursor_string_table["UI_CURSOR_TOOLOPEN"] = UI_CURSOR_TOOLOPEN; + cursor_string_table["UI_CURSOR_TOOLPATHFINDING"] = UI_CURSOR_TOOLPATHFINDING; + cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTART"] = UI_CURSOR_TOOLPATHFINDING_PATH_START; + cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTARTADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD; + cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHEND"] = UI_CURSOR_TOOLPATHFINDING_PATH_END; + cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHENDADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD; + cursor_string_table["UI_CURSOR_TOOLNO"] = UI_CURSOR_TOOLNO; + } + + std::map<std::string,U32>::const_iterator iter = cursor_string_table.find(cursor_string); - std::map<std::string,U32>::const_iterator iter = cursor_string_table.find(cursor_string); - - if (iter != cursor_string_table.end()) - { - return (ECursorType)iter->second; - } + if (iter != cursor_string_table.end()) + { + return (ECursorType)iter->second; + } - return UI_CURSOR_ARROW; + return UI_CURSOR_ARROW; } diff --git a/indra/llwindow/llcursortypes.h b/indra/llwindow/llcursortypes.h index d03b18e275..9a0c2909bf 100644 --- a/indra/llwindow/llcursortypes.h +++ b/indra/llwindow/llcursortypes.h @@ -1,25 +1,25 @@ -/** +/** * @file llcursortypes.h * @brief Cursor types * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,51 +29,51 @@ // If you add types here, add them in LLCursor::getCursorFromString enum ECursorType { - UI_CURSOR_ARROW, - UI_CURSOR_WAIT, - UI_CURSOR_HAND, - UI_CURSOR_IBEAM, - UI_CURSOR_CROSS, - UI_CURSOR_SIZENWSE, - UI_CURSOR_SIZENESW, - UI_CURSOR_SIZEWE, - UI_CURSOR_SIZENS, - UI_CURSOR_SIZEALL, - UI_CURSOR_NO, - UI_CURSOR_WORKING, - UI_CURSOR_TOOLGRAB, - UI_CURSOR_TOOLLAND, - UI_CURSOR_TOOLFOCUS, - UI_CURSOR_TOOLCREATE, - UI_CURSOR_ARROWDRAG, - UI_CURSOR_ARROWCOPY, // drag with copy - UI_CURSOR_ARROWDRAGMULTI, - UI_CURSOR_ARROWCOPYMULTI, // drag with copy - UI_CURSOR_NOLOCKED, - UI_CURSOR_ARROWLOCKED, - UI_CURSOR_GRABLOCKED, - UI_CURSOR_TOOLTRANSLATE, - UI_CURSOR_TOOLROTATE, - UI_CURSOR_TOOLSCALE, - UI_CURSOR_TOOLCAMERA, - UI_CURSOR_TOOLPAN, - UI_CURSOR_TOOLZOOMIN, - UI_CURSOR_TOOLZOOMOUT, - UI_CURSOR_TOOLPICKOBJECT3, - UI_CURSOR_TOOLPLAY, - UI_CURSOR_TOOLPAUSE, - UI_CURSOR_TOOLMEDIAOPEN, - UI_CURSOR_PIPETTE, - UI_CURSOR_TOOLSIT, - UI_CURSOR_TOOLBUY, - UI_CURSOR_TOOLOPEN, - UI_CURSOR_TOOLPATHFINDING, - UI_CURSOR_TOOLPATHFINDING_PATH_START, - UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD, - UI_CURSOR_TOOLPATHFINDING_PATH_END, - UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD, - UI_CURSOR_TOOLNO, - UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) + UI_CURSOR_ARROW, + UI_CURSOR_WAIT, + UI_CURSOR_HAND, + UI_CURSOR_IBEAM, + UI_CURSOR_CROSS, + UI_CURSOR_SIZENWSE, + UI_CURSOR_SIZENESW, + UI_CURSOR_SIZEWE, + UI_CURSOR_SIZENS, + UI_CURSOR_SIZEALL, + UI_CURSOR_NO, + UI_CURSOR_WORKING, + UI_CURSOR_TOOLGRAB, + UI_CURSOR_TOOLLAND, + UI_CURSOR_TOOLFOCUS, + UI_CURSOR_TOOLCREATE, + UI_CURSOR_ARROWDRAG, + UI_CURSOR_ARROWCOPY, // drag with copy + UI_CURSOR_ARROWDRAGMULTI, + UI_CURSOR_ARROWCOPYMULTI, // drag with copy + UI_CURSOR_NOLOCKED, + UI_CURSOR_ARROWLOCKED, + UI_CURSOR_GRABLOCKED, + UI_CURSOR_TOOLTRANSLATE, + UI_CURSOR_TOOLROTATE, + UI_CURSOR_TOOLSCALE, + UI_CURSOR_TOOLCAMERA, + UI_CURSOR_TOOLPAN, + UI_CURSOR_TOOLZOOMIN, + UI_CURSOR_TOOLZOOMOUT, + UI_CURSOR_TOOLPICKOBJECT3, + UI_CURSOR_TOOLPLAY, + UI_CURSOR_TOOLPAUSE, + UI_CURSOR_TOOLMEDIAOPEN, + UI_CURSOR_PIPETTE, + UI_CURSOR_TOOLSIT, + UI_CURSOR_TOOLBUY, + UI_CURSOR_TOOLOPEN, + UI_CURSOR_TOOLPATHFINDING, + UI_CURSOR_TOOLPATHFINDING_PATH_START, + UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD, + UI_CURSOR_TOOLPATHFINDING_PATH_END, + UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD, + UI_CURSOR_TOOLNO, + UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) }; LL_COMMON_API ECursorType getCursorFromString(const std::string& cursor_string); diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index 0d1a47408b..b164eb9579 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,268 +35,268 @@ #include "llwindowcallbacks.h" #include "lldragdropwin32.h" -class LLDragDropWin32Target: - public IDropTarget +class LLDragDropWin32Target: + public IDropTarget { - public: - //////////////////////////////////////////////////////////////////////////////// - // - LLDragDropWin32Target( HWND hWnd ) : - mRefCount( 1 ), - mAppWindowHandle( hWnd ), - mAllowDrop(false), - mIsSlurl(false) - { - }; - - virtual ~LLDragDropWin32Target() - { - }; - - //////////////////////////////////////////////////////////////////////////////// - // - ULONG __stdcall AddRef( void ) - { - return InterlockedIncrement( &mRefCount ); - }; - - //////////////////////////////////////////////////////////////////////////////// - // - ULONG __stdcall Release( void ) - { - LONG count = InterlockedDecrement( &mRefCount ); - - if ( count == 0 ) - { - delete this; - return 0; - } - else - { - return count; - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - HRESULT __stdcall QueryInterface( REFIID iid, void** ppvObject ) - { - if ( iid == IID_IUnknown || iid == IID_IDropTarget ) - { - AddRef(); - *ppvObject = this; - return S_OK; - } - else - { - *ppvObject = 0; - return E_NOINTERFACE; - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - HRESULT __stdcall DragEnter( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) - { - FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - - // support CF_TEXT using a HGLOBAL? - if ( S_OK == pDataObject->QueryGetData( &fmtetc ) ) - { - mAllowDrop = true; - mDropUrl = std::string(); - mIsSlurl = false; - - STGMEDIUM stgmed; - if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) - { - PVOID data = GlobalLock( stgmed.hGlobal ); - mDropUrl = std::string( (char*)data ); - // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); - if (NULL != window_imp) - { - LLCoordGL gl_coord( 0, 0 ); - - POINT pt2; - pt2.x = pt.x; - pt2.y = pt.y; - ScreenToClient( mAppWindowHandle, &pt2 ); - - LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); - MASK mask = gKeyboard->currentMask(TRUE); - - LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( cursor_coord_window.convert(), mask, - LLWindowCallbacks::DNDA_START_TRACKING, mDropUrl ); - - switch (result) - { - case LLWindowCallbacks::DND_COPY: - *pdwEffect = DROPEFFECT_COPY; - break; - case LLWindowCallbacks::DND_LINK: - *pdwEffect = DROPEFFECT_LINK; - break; - case LLWindowCallbacks::DND_MOVE: - *pdwEffect = DROPEFFECT_MOVE; - break; - case LLWindowCallbacks::DND_NONE: - default: - *pdwEffect = DROPEFFECT_NONE; - break; - } - }; - - GlobalUnlock( stgmed.hGlobal ); - ReleaseStgMedium( &stgmed ); - }; - SetFocus( mAppWindowHandle ); - } - else - { - mAllowDrop = false; - *pdwEffect = DROPEFFECT_NONE; - }; - - return S_OK; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - HRESULT __stdcall DragOver( DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) - { - if ( mAllowDrop ) - { - // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); - if (NULL != window_imp) - { - LLCoordGL gl_coord( 0, 0 ); - - POINT pt2; - pt2.x = pt.x; - pt2.y = pt.y; - ScreenToClient( mAppWindowHandle, &pt2 ); - - LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); - MASK mask = gKeyboard->currentMask(TRUE); - - LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( cursor_coord_window.convert(), mask, - LLWindowCallbacks::DNDA_TRACK, mDropUrl ); - - switch (result) - { - case LLWindowCallbacks::DND_COPY: - *pdwEffect = DROPEFFECT_COPY; - break; - case LLWindowCallbacks::DND_LINK: - *pdwEffect = DROPEFFECT_LINK; - break; - case LLWindowCallbacks::DND_MOVE: - *pdwEffect = DROPEFFECT_MOVE; - break; - case LLWindowCallbacks::DND_NONE: - default: - *pdwEffect = DROPEFFECT_NONE; - break; - } - }; - } - else - { - *pdwEffect = DROPEFFECT_NONE; - }; - - return S_OK; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - HRESULT __stdcall DragLeave( void ) - { - // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); - if (NULL != window_imp) - { - LLCoordGL gl_coord( 0, 0 ); - MASK mask = gKeyboard->currentMask(TRUE); - window_imp->completeDragNDropRequest( gl_coord, mask, LLWindowCallbacks::DNDA_STOP_TRACKING, mDropUrl ); - }; - return S_OK; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - HRESULT __stdcall Drop( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) - { - if ( mAllowDrop ) - { - // window impl stored in Window data (neat!) - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); - if ( NULL != window_imp ) - { - POINT pt_client; - pt_client.x = pt.x; - pt_client.y = pt.y; - ScreenToClient( mAppWindowHandle, &pt_client ); - - LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); - LLCoordGL gl_coord(cursor_coord_window.convert()); - LL_INFOS() << "### (Drop) URL is: " << mDropUrl << LL_ENDL; - LL_INFOS() << "### raw coords are: " << pt.x << " x " << pt.y << LL_ENDL; - LL_INFOS() << "### client coords are: " << pt_client.x << " x " << pt_client.y << LL_ENDL; - LL_INFOS() << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << LL_ENDL; - LL_INFOS() << LL_ENDL; - - // no keyboard modifier option yet but we could one day - MASK mask = gKeyboard->currentMask( TRUE ); - - // actually do the drop - LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, - LLWindowCallbacks::DNDA_DROPPED, mDropUrl ); - - switch (result) - { - case LLWindowCallbacks::DND_COPY: - *pdwEffect = DROPEFFECT_COPY; - break; - case LLWindowCallbacks::DND_LINK: - *pdwEffect = DROPEFFECT_LINK; - break; - case LLWindowCallbacks::DND_MOVE: - *pdwEffect = DROPEFFECT_MOVE; - break; - case LLWindowCallbacks::DND_NONE: - default: - *pdwEffect = DROPEFFECT_NONE; - break; - } - }; - } - else - { - *pdwEffect = DROPEFFECT_NONE; - }; - - return S_OK; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - private: - LONG mRefCount; - HWND mAppWindowHandle; - bool mAllowDrop; - std::string mDropUrl; - bool mIsSlurl; - friend class LLWindowWin32; + public: + //////////////////////////////////////////////////////////////////////////////// + // + LLDragDropWin32Target( HWND hWnd ) : + mRefCount( 1 ), + mAppWindowHandle( hWnd ), + mAllowDrop(false), + mIsSlurl(false) + { + }; + + virtual ~LLDragDropWin32Target() + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + ULONG __stdcall AddRef( void ) + { + return InterlockedIncrement( &mRefCount ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + ULONG __stdcall Release( void ) + { + LONG count = InterlockedDecrement( &mRefCount ); + + if ( count == 0 ) + { + delete this; + return 0; + } + else + { + return count; + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall QueryInterface( REFIID iid, void** ppvObject ) + { + if ( iid == IID_IUnknown || iid == IID_IDropTarget ) + { + AddRef(); + *ppvObject = this; + return S_OK; + } + else + { + *ppvObject = 0; + return E_NOINTERFACE; + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall DragEnter( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) + { + FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + + // support CF_TEXT using a HGLOBAL? + if ( S_OK == pDataObject->QueryGetData( &fmtetc ) ) + { + mAllowDrop = true; + mDropUrl = std::string(); + mIsSlurl = false; + + STGMEDIUM stgmed; + if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) + { + PVOID data = GlobalLock( stgmed.hGlobal ); + mDropUrl = std::string( (char*)data ); + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt2 ); + + LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); + MASK mask = gKeyboard->currentMask(TRUE); + + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( cursor_coord_window.convert(), mask, + LLWindowCallbacks::DNDA_START_TRACKING, mDropUrl ); + + switch (result) + { + case LLWindowCallbacks::DND_COPY: + *pdwEffect = DROPEFFECT_COPY; + break; + case LLWindowCallbacks::DND_LINK: + *pdwEffect = DROPEFFECT_LINK; + break; + case LLWindowCallbacks::DND_MOVE: + *pdwEffect = DROPEFFECT_MOVE; + break; + case LLWindowCallbacks::DND_NONE: + default: + *pdwEffect = DROPEFFECT_NONE; + break; + } + }; + + GlobalUnlock( stgmed.hGlobal ); + ReleaseStgMedium( &stgmed ); + }; + SetFocus( mAppWindowHandle ); + } + else + { + mAllowDrop = false; + *pdwEffect = DROPEFFECT_NONE; + }; + + return S_OK; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall DragOver( DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) + { + if ( mAllowDrop ) + { + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt2 ); + + LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); + MASK mask = gKeyboard->currentMask(TRUE); + + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( cursor_coord_window.convert(), mask, + LLWindowCallbacks::DNDA_TRACK, mDropUrl ); + + switch (result) + { + case LLWindowCallbacks::DND_COPY: + *pdwEffect = DROPEFFECT_COPY; + break; + case LLWindowCallbacks::DND_LINK: + *pdwEffect = DROPEFFECT_LINK; + break; + case LLWindowCallbacks::DND_MOVE: + *pdwEffect = DROPEFFECT_MOVE; + break; + case LLWindowCallbacks::DND_NONE: + default: + *pdwEffect = DROPEFFECT_NONE; + break; + } + }; + } + else + { + *pdwEffect = DROPEFFECT_NONE; + }; + + return S_OK; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall DragLeave( void ) + { + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->completeDragNDropRequest( gl_coord, mask, LLWindowCallbacks::DNDA_STOP_TRACKING, mDropUrl ); + }; + return S_OK; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall Drop( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) + { + if ( mAllowDrop ) + { + // window impl stored in Window data (neat!) + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); + if ( NULL != window_imp ) + { + POINT pt_client; + pt_client.x = pt.x; + pt_client.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt_client ); + + LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); + LLCoordGL gl_coord(cursor_coord_window.convert()); + LL_INFOS() << "### (Drop) URL is: " << mDropUrl << LL_ENDL; + LL_INFOS() << "### raw coords are: " << pt.x << " x " << pt.y << LL_ENDL; + LL_INFOS() << "### client coords are: " << pt_client.x << " x " << pt_client.y << LL_ENDL; + LL_INFOS() << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << LL_ENDL; + LL_INFOS() << LL_ENDL; + + // no keyboard modifier option yet but we could one day + MASK mask = gKeyboard->currentMask( TRUE ); + + // actually do the drop + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, + LLWindowCallbacks::DNDA_DROPPED, mDropUrl ); + + switch (result) + { + case LLWindowCallbacks::DND_COPY: + *pdwEffect = DROPEFFECT_COPY; + break; + case LLWindowCallbacks::DND_LINK: + *pdwEffect = DROPEFFECT_LINK; + break; + case LLWindowCallbacks::DND_MOVE: + *pdwEffect = DROPEFFECT_MOVE; + break; + case LLWindowCallbacks::DND_NONE: + default: + *pdwEffect = DROPEFFECT_NONE; + break; + } + }; + } + else + { + *pdwEffect = DROPEFFECT_NONE; + }; + + return S_OK; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + private: + LONG mRefCount; + HWND mAppWindowHandle; + bool mAllowDrop; + std::string mDropUrl; + bool mIsSlurl; + friend class LLWindowWin32; }; //////////////////////////////////////////////////////////////////////////////// // LLDragDropWin32::LLDragDropWin32() : - mDropTarget( NULL ), - mDropWindowHandle( NULL ) + mDropTarget( NULL ), + mDropWindowHandle( NULL ) { } @@ -311,48 +311,48 @@ LLDragDropWin32::~LLDragDropWin32() // bool LLDragDropWin32::init( HWND hWnd ) { - if ( NOERROR != OleInitialize( NULL ) ) - return FALSE; - - mDropTarget = new LLDragDropWin32Target( hWnd ); - if ( mDropTarget ) - { - HRESULT result = CoLockObjectExternal( mDropTarget, TRUE, FALSE ); - if ( S_OK == result ) - { - result = RegisterDragDrop( hWnd, mDropTarget ); - if ( S_OK != result ) - { - // RegisterDragDrop failed - return false; - }; - - // all ok - mDropWindowHandle = hWnd; - } - else - { - // Unable to lock OLE object - return false; - }; - }; - - // success - return true; + if ( NOERROR != OleInitialize( NULL ) ) + return FALSE; + + mDropTarget = new LLDragDropWin32Target( hWnd ); + if ( mDropTarget ) + { + HRESULT result = CoLockObjectExternal( mDropTarget, TRUE, FALSE ); + if ( S_OK == result ) + { + result = RegisterDragDrop( hWnd, mDropTarget ); + if ( S_OK != result ) + { + // RegisterDragDrop failed + return false; + }; + + // all ok + mDropWindowHandle = hWnd; + } + else + { + // Unable to lock OLE object + return false; + }; + }; + + // success + return true; } //////////////////////////////////////////////////////////////////////////////// // void LLDragDropWin32::reset() { - if ( mDropTarget ) - { - RevokeDragDrop( mDropWindowHandle ); - CoLockObjectExternal( mDropTarget, FALSE, TRUE ); - mDropTarget->Release(); - }; - - OleUninitialize(); + if ( mDropTarget ) + { + RevokeDragDrop( mDropWindowHandle ); + CoLockObjectExternal( mDropTarget, FALSE, TRUE ); + mDropTarget->Release(); + }; + + OleUninitialize(); } #endif // LL_OS_DRAGDROP_ENABLED diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h index 4673242cba..1b30dced27 100644 --- a/indra/llwindow/lldragdropwin32.h +++ b/indra/llwindow/lldragdropwin32.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,16 +36,16 @@ class LLDragDropWin32 { - public: - LLDragDropWin32(); - ~LLDragDropWin32(); + public: + LLDragDropWin32(); + ~LLDragDropWin32(); - bool init( HWND hWnd ); - void reset(); + bool init( HWND hWnd ); + void reset(); - private: - IDropTarget* mDropTarget; - HWND mDropWindowHandle; + private: + IDropTarget* mDropTarget; + HWND mDropWindowHandle; }; #endif // LL_LLDRAGDROP32_H @@ -57,15 +57,15 @@ class LLDragDropWin32 #include "llwin32headerslean.h" #include <ole2.h> -// impostor class that does nothing +// impostor class that does nothing class LLDragDropWin32 { - public: - LLDragDropWin32() {}; - ~LLDragDropWin32() {}; + public: + LLDragDropWin32() {}; + ~LLDragDropWin32() {}; - bool init( HWND hWnd ) { return false; }; - void reset() { }; + bool init( HWND hWnd ) { return false; }; + void reset() { }; }; #endif // LL_LLDRAGDROP32_H diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index aaa2f6aef1..f972e8f628 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldxhardware.cpp * @brief LLDXHardware implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -103,7 +103,7 @@ HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam) pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" ); if( pfnCoSetProxyBlanket != 0 ) { - // Switch security level to IMPERSONATE. + // Switch security level to IMPERSONATE. pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 ); } @@ -218,111 +218,111 @@ HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam) //static S32 LLDXHardware::getMBVideoMemoryViaWMI() { - DWORD vram = 0; - if (SUCCEEDED(GetVideoMemoryViaWMI(NULL, &vram))) - { - return vram / (1024 * 1024);; - } - return 0; + DWORD vram = 0; + if (SUCCEEDED(GetVideoMemoryViaWMI(NULL, &vram))) + { + return vram / (1024 * 1024);; + } + return 0; } //Getting the version of graphics controller driver via WMI std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor) { - std::string mDriverVersion; - HRESULT hres; - CoInitializeEx(0, COINIT_APARTMENTTHREADED); - IWbemLocator *pLoc = NULL; - - hres = CoCreateInstance( - CLSID_WbemLocator, - 0, - CLSCTX_INPROC_SERVER, - IID_IWbemLocator, (LPVOID *)&pLoc); - - if (FAILED(hres)) - { - LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << hres << LL_ENDL; - return std::string(); // Program has failed. - } - - IWbemServices *pSvc = NULL; - - // Connect to the root\cimv2 namespace with - // the current user and obtain pointer pSvc - // to make IWbemServices calls. - hres = pLoc->ConnectServer( - _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace - NULL, // User name. NULL = current user - NULL, // User password. NULL = current - 0, // Locale. NULL indicates current - NULL, // Security flags. - 0, // Authority (e.g. Kerberos) - 0, // Context object - &pSvc // pointer to IWbemServices proxy - ); - - if (FAILED(hres)) - { - LL_WARNS("AppInit") << "Could not connect. Error code = 0x" << hres << LL_ENDL; - pLoc->Release(); - CoUninitialize(); - return std::string(); // Program has failed. - } - - LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL; - - // Set security levels on the proxy ------------------------- - hres = CoSetProxyBlanket( - pSvc, // Indicates the proxy to set - RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx - RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx - NULL, // Server principal name - RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx - RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx - NULL, // client identity - EOAC_NONE // proxy capabilities - ); - - if (FAILED(hres)) - { - LL_WARNS("AppInit") << "Could not set proxy blanket. Error code = 0x" << hres << LL_ENDL; - pSvc->Release(); - pLoc->Release(); - CoUninitialize(); - return std::string(); // Program has failed. - } - IEnumWbemClassObject* pEnumerator = NULL; - - // Get the data from the query - ULONG uReturn = 0; - hres = pSvc->ExecQuery( - bstr_t("WQL"), - bstr_t("SELECT * FROM Win32_VideoController"), //Consider using Availability to filter out disabled controllers - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - NULL, - &pEnumerator); - - if (FAILED(hres)) - { - LL_WARNS("AppInit") << "Query for operating system name failed." << " Error code = 0x" << hres << LL_ENDL; - pSvc->Release(); - pLoc->Release(); - CoUninitialize(); - return std::string(); // Program has failed. - } - - while (pEnumerator) - { - IWbemClassObject *pclsObj = NULL; - HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, - &pclsObj, &uReturn); - - if (0 == uReturn) - { - break; // If quantity less then 1. - } - + std::string mDriverVersion; + HRESULT hres; + CoInitializeEx(0, COINIT_APARTMENTTHREADED); + IWbemLocator *pLoc = NULL; + + hres = CoCreateInstance( + CLSID_WbemLocator, + 0, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, (LPVOID *)&pLoc); + + if (FAILED(hres)) + { + LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << hres << LL_ENDL; + return std::string(); // Program has failed. + } + + IWbemServices *pSvc = NULL; + + // Connect to the root\cimv2 namespace with + // the current user and obtain pointer pSvc + // to make IWbemServices calls. + hres = pLoc->ConnectServer( + _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace + NULL, // User name. NULL = current user + NULL, // User password. NULL = current + 0, // Locale. NULL indicates current + NULL, // Security flags. + 0, // Authority (e.g. Kerberos) + 0, // Context object + &pSvc // pointer to IWbemServices proxy + ); + + if (FAILED(hres)) + { + LL_WARNS("AppInit") << "Could not connect. Error code = 0x" << hres << LL_ENDL; + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL; + + // Set security levels on the proxy ------------------------- + hres = CoSetProxyBlanket( + pSvc, // Indicates the proxy to set + RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx + RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx + NULL, // Server principal name + RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx + RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx + NULL, // client identity + EOAC_NONE // proxy capabilities + ); + + if (FAILED(hres)) + { + LL_WARNS("AppInit") << "Could not set proxy blanket. Error code = 0x" << hres << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + IEnumWbemClassObject* pEnumerator = NULL; + + // Get the data from the query + ULONG uReturn = 0; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT * FROM Win32_VideoController"), //Consider using Availability to filter out disabled controllers + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + LL_WARNS("AppInit") << "Query for operating system name failed." << " Error code = 0x" << hres << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + while (pEnumerator) + { + IWbemClassObject *pclsObj = NULL; + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; // If quantity less then 1. + } + if (vendor != GPU_ANY) { VARIANT vtCaptionProp; @@ -378,32 +378,32 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor) VARIANT vtVersionProp; - // Get the value of the DriverVersion property - hr = pclsObj->Get(L"DriverVersion", 0, &vtVersionProp, 0, 0); - - if (FAILED(hr)) - { - LL_WARNS("AppInit") << "Query for DriverVersion property failed." << " Error code = 0x" << hr << LL_ENDL; - pSvc->Release(); - pLoc->Release(); - CoUninitialize(); - return std::string(); // Program has failed. - } - - // use characters in the returned driver version - BSTR driverVersion(vtVersionProp.bstrVal); - - //convert BSTR to std::string - std::wstring ws(driverVersion, SysStringLen(driverVersion)); - std::string str(ws.begin(), ws.end()); - LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL; - - if (mDriverVersion.empty()) - { - mDriverVersion = str; - } - else if (mDriverVersion != str) - { + // Get the value of the DriverVersion property + hr = pclsObj->Get(L"DriverVersion", 0, &vtVersionProp, 0, 0); + + if (FAILED(hr)) + { + LL_WARNS("AppInit") << "Query for DriverVersion property failed." << " Error code = 0x" << hr << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + // use characters in the returned driver version + BSTR driverVersion(vtVersionProp.bstrVal); + + //convert BSTR to std::string + std::wstring ws(driverVersion, SysStringLen(driverVersion)); + std::string str(ws.begin(), ws.end()); + LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL; + + if (mDriverVersion.empty()) + { + mDriverVersion = str; + } + else if (mDriverVersion != str) + { if (vendor == GPU_ANY) { // Expected from systems with gpus from different vendors @@ -414,211 +414,211 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor) // Not Expected! LL_WARNS("DriverVersion") << "Multiple video drivers detected from same vendor. Version of second driver : " << str << LL_ENDL; } - } - - VariantClear(&vtVersionProp); - pclsObj->Release(); - } - - // Cleanup - // ======== - if (pSvc) - { - pSvc->Release(); - } - if (pLoc) - { - pLoc->Release(); - } - if (pEnumerator) - { - pEnumerator->Release(); - } + } + + VariantClear(&vtVersionProp); + pclsObj->Release(); + } + + // Cleanup + // ======== + if (pSvc) + { + pSvc->Release(); + } + if (pLoc) + { + pLoc->Release(); + } + if (pEnumerator) + { + pEnumerator->Release(); + } // supposed to always call CoUninitialize even if init returned false - CoUninitialize(); + CoUninitialize(); - return mDriverVersion; + return mDriverVersion; } void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize) { - HRESULT hr; - VARIANT var; - - VariantInit( &var ); - hr = containerp->GetProp(wszPropName, &var ); - if( SUCCEEDED(hr) ) - { - // Switch off the type. There's 4 different types: - switch( var.vt ) - { - case VT_UI4: - swprintf( wszPropValue, L"%d", var.ulVal ); /* Flawfinder: ignore */ - break; - case VT_I4: - swprintf( wszPropValue, L"%d", var.lVal ); /* Flawfinder: ignore */ - break; - case VT_BOOL: - wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */ - break; - case VT_BSTR: - wcsncpy( wszPropValue, var.bstrVal, outputSize-1 ); /* Flawfinder: ignore */ - wszPropValue[outputSize-1] = 0; - break; - } - } - // Clear the variant (this is needed to free BSTR memory) - VariantClear( &var ); + HRESULT hr; + VARIANT var; + + VariantInit( &var ); + hr = containerp->GetProp(wszPropName, &var ); + if( SUCCEEDED(hr) ) + { + // Switch off the type. There's 4 different types: + switch( var.vt ) + { + case VT_UI4: + swprintf( wszPropValue, L"%d", var.ulVal ); /* Flawfinder: ignore */ + break; + case VT_I4: + swprintf( wszPropValue, L"%d", var.lVal ); /* Flawfinder: ignore */ + break; + case VT_BOOL: + wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */ + break; + case VT_BSTR: + wcsncpy( wszPropValue, var.bstrVal, outputSize-1 ); /* Flawfinder: ignore */ + wszPropValue[outputSize-1] = 0; + break; + } + } + // Clear the variant (this is needed to free BSTR memory) + VariantClear( &var ); } std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) { WCHAR wszPropValue[256]; - get_wstring(containerp, wszPropName, wszPropValue, 256); + get_wstring(containerp, wszPropName, wszPropValue, 256); - return utf16str_to_utf8str(wszPropValue); + return utf16str_to_utf8str(wszPropValue); } LLVersion::LLVersion() { - mValid = FALSE; - S32 i; - for (i = 0; i < 4; i++) - { - mFields[i] = 0; - } + mValid = FALSE; + S32 i; + for (i = 0; i < 4; i++) + { + mFields[i] = 0; + } } BOOL LLVersion::set(const std::string &version_string) { - S32 i; - for (i = 0; i < 4; i++) - { - mFields[i] = 0; - } - // Split the version string. - std::string str(version_string); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep(".", "", boost::keep_empty_tokens); - tokenizer tokens(str, sep); - - tokenizer::iterator iter = tokens.begin(); - S32 count = 0; - for (;(iter != tokens.end()) && (count < 4);++iter) - { - mFields[count] = atoi(iter->c_str()); - count++; - } - if (count < 4) - { - //LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL; - for (i = 0; i < 4; i++) - { - mFields[i] = 0; - } - mValid = FALSE; - } - else - { - mValid = TRUE; - } - return mValid; + S32 i; + for (i = 0; i < 4; i++) + { + mFields[i] = 0; + } + // Split the version string. + std::string str(version_string); + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(".", "", boost::keep_empty_tokens); + tokenizer tokens(str, sep); + + tokenizer::iterator iter = tokens.begin(); + S32 count = 0; + for (;(iter != tokens.end()) && (count < 4);++iter) + { + mFields[count] = atoi(iter->c_str()); + count++; + } + if (count < 4) + { + //LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL; + for (i = 0; i < 4; i++) + { + mFields[i] = 0; + } + mValid = FALSE; + } + else + { + mValid = TRUE; + } + return mValid; } S32 LLVersion::getField(const S32 field_num) { - if (!mValid) - { - return -1; - } - else - { - return mFields[field_num]; - } + if (!mValid) + { + return -1; + } + else + { + return mFields[field_num]; + } } std::string LLDXDriverFile::dump() { - if (gWriteDebug) - { - gWriteDebug("Filename:"); - gWriteDebug(mName.c_str()); - gWriteDebug("\n"); - gWriteDebug("Ver:"); - gWriteDebug(mVersionString.c_str()); - gWriteDebug("\n"); - gWriteDebug("Date:"); - gWriteDebug(mDateString.c_str()); - gWriteDebug("\n"); - } - LL_INFOS() << mFilepath << LL_ENDL; - LL_INFOS() << mName << LL_ENDL; - LL_INFOS() << mVersionString << LL_ENDL; - LL_INFOS() << mDateString << LL_ENDL; - - return ""; + if (gWriteDebug) + { + gWriteDebug("Filename:"); + gWriteDebug(mName.c_str()); + gWriteDebug("\n"); + gWriteDebug("Ver:"); + gWriteDebug(mVersionString.c_str()); + gWriteDebug("\n"); + gWriteDebug("Date:"); + gWriteDebug(mDateString.c_str()); + gWriteDebug("\n"); + } + LL_INFOS() << mFilepath << LL_ENDL; + LL_INFOS() << mName << LL_ENDL; + LL_INFOS() << mVersionString << LL_ENDL; + LL_INFOS() << mDateString << LL_ENDL; + + return ""; } LLDXDevice::~LLDXDevice() { - for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer()); - mDriverFiles.clear(); + for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer()); + mDriverFiles.clear(); } std::string LLDXDevice::dump() { - if (gWriteDebug) - { - gWriteDebug("StartDevice\n"); - gWriteDebug("DeviceName:"); - gWriteDebug(mName.c_str()); - gWriteDebug("\n"); - gWriteDebug("PCIString:"); - gWriteDebug(mPCIString.c_str()); - gWriteDebug("\n"); - } - LL_INFOS() << LL_ENDL; - LL_INFOS() << "DeviceName:" << mName << LL_ENDL; - LL_INFOS() << "PCIString:" << mPCIString << LL_ENDL; - LL_INFOS() << "Drivers" << LL_ENDL; - LL_INFOS() << "-------" << LL_ENDL; - for (driver_file_map_t::iterator iter = mDriverFiles.begin(), - end = mDriverFiles.end(); - iter != end; iter++) - { - LLDXDriverFile *filep = iter->second; - filep->dump(); - } - if (gWriteDebug) - { - gWriteDebug("EndDevice\n"); - } - - return ""; + if (gWriteDebug) + { + gWriteDebug("StartDevice\n"); + gWriteDebug("DeviceName:"); + gWriteDebug(mName.c_str()); + gWriteDebug("\n"); + gWriteDebug("PCIString:"); + gWriteDebug(mPCIString.c_str()); + gWriteDebug("\n"); + } + LL_INFOS() << LL_ENDL; + LL_INFOS() << "DeviceName:" << mName << LL_ENDL; + LL_INFOS() << "PCIString:" << mPCIString << LL_ENDL; + LL_INFOS() << "Drivers" << LL_ENDL; + LL_INFOS() << "-------" << LL_ENDL; + for (driver_file_map_t::iterator iter = mDriverFiles.begin(), + end = mDriverFiles.end(); + iter != end; iter++) + { + LLDXDriverFile *filep = iter->second; + filep->dump(); + } + if (gWriteDebug) + { + gWriteDebug("EndDevice\n"); + } + + return ""; } LLDXDriverFile *LLDXDevice::findDriver(const std::string &driver) { - for (driver_file_map_t::iterator iter = mDriverFiles.begin(), - end = mDriverFiles.end(); - iter != end; iter++) - { - LLDXDriverFile *filep = iter->second; - if (!utf8str_compare_insensitive(filep->mName,driver)) - { - return filep; - } - } - - return NULL; + for (driver_file_map_t::iterator iter = mDriverFiles.begin(), + end = mDriverFiles.end(); + iter != end; iter++) + { + LLDXDriverFile *filep = iter->second; + if (!utf8str_compare_insensitive(filep->mName,driver)) + { + return filep; + } + } + + return NULL; } LLDXHardware::LLDXHardware() { - mVRAM = 0; - gWriteDebug = NULL; + mVRAM = 0; + gWriteDebug = NULL; } void LLDXHardware::cleanup() @@ -630,58 +630,58 @@ void LLDXHardware::cleanup() /* std::string LLDXHardware::dumpDevices() { - if (gWriteDebug) - { - gWriteDebug("\n"); - gWriteDebug("StartAllDevices\n"); - } - for (device_map_t::iterator iter = mDevices.begin(), - end = mDevices.end(); - iter != end; iter++) - { - LLDXDevice *devicep = iter->second; - devicep->dump(); - } - if (gWriteDebug) - { - gWriteDebug("EndAllDevices\n\n"); - } - return ""; + if (gWriteDebug) + { + gWriteDebug("\n"); + gWriteDebug("StartAllDevices\n"); + } + for (device_map_t::iterator iter = mDevices.begin(), + end = mDevices.end(); + iter != end; iter++) + { + LLDXDevice *devicep = iter->second; + devicep->dump(); + } + if (gWriteDebug) + { + gWriteDebug("EndAllDevices\n\n"); + } + return ""; } LLDXDevice *LLDXHardware::findDevice(const std::string &vendor, const std::string &devices) { - // Iterate through different devices tokenized in devices string - std::string str(devices); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("|", "", boost::keep_empty_tokens); - tokenizer tokens(str, sep); - - tokenizer::iterator iter = tokens.begin(); - for (;iter != tokens.end();++iter) - { - std::string dev_str = *iter; - for (device_map_t::iterator iter = mDevices.begin(), - end = mDevices.end(); - iter != end; iter++) - { - LLDXDevice *devicep = iter->second; - if ((devicep->mVendorID == vendor) - && (devicep->mDeviceID == dev_str)) - { - return devicep; - } - } - } - - return NULL; + // Iterate through different devices tokenized in devices string + std::string str(devices); + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("|", "", boost::keep_empty_tokens); + tokenizer tokens(str, sep); + + tokenizer::iterator iter = tokens.begin(); + for (;iter != tokens.end();++iter) + { + std::string dev_str = *iter; + for (device_map_t::iterator iter = mDevices.begin(), + end = mDevices.end(); + iter != end; iter++) + { + LLDXDevice *devicep = iter->second; + if ((devicep->mVendorID == vendor) + && (devicep->mDeviceID == dev_str)) + { + return devicep; + } + } + } + + return NULL; } */ BOOL LLDXHardware::getInfo(BOOL vram_only) { - LLTimer hw_timer; - BOOL ok = FALSE; + LLTimer hw_timer; + BOOL ok = FALSE; HRESULT hr; // CLSID_DxDiagProvider does not work with Multithreaded? @@ -689,35 +689,35 @@ BOOL LLDXHardware::getInfo(BOOL vram_only) IDxDiagProvider *dx_diag_providerp = NULL; IDxDiagContainer *dx_diag_rootp = NULL; - IDxDiagContainer *devices_containerp = NULL; - // IDxDiagContainer *system_device_containerp= NULL; - IDxDiagContainer *device_containerp = NULL; - IDxDiagContainer *file_containerp = NULL; - IDxDiagContainer *driver_containerp = NULL; - DWORD dw_device_count; + IDxDiagContainer *devices_containerp = NULL; + // IDxDiagContainer *system_device_containerp= NULL; + IDxDiagContainer *device_containerp = NULL; + IDxDiagContainer *file_containerp = NULL; + IDxDiagContainer *driver_containerp = NULL; + DWORD dw_device_count; - mVRAM = 0; + mVRAM = 0; // CoCreate a IDxDiagProvider* - LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL; + LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL; hr = CoCreateInstance(CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, IID_IDxDiagProvider, (LPVOID*) &dx_diag_providerp); - if (FAILED(hr)) - { - LL_WARNS("AppInit") << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; - gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); - goto LCleanup; - } + if (FAILED(hr)) + { + LL_WARNS("AppInit") << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; + gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); + goto LCleanup; + } if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed { // Fill out a DXDIAG_INIT_PARAMS struct and pass it to IDxDiagContainer::Initialize - // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are - // digital signed as logo'd by WHQL which may connect via internet to update - // WHQL certificates. + // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are + // digital signed as logo'd by WHQL which may connect via internet to update + // WHQL certificates. DXDIAG_INIT_PARAMS dx_diag_init_params; ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS)); @@ -726,31 +726,31 @@ BOOL LLDXHardware::getInfo(BOOL vram_only) dx_diag_init_params.bAllowWHQLChecks = TRUE; dx_diag_init_params.pReserved = NULL; - LL_DEBUGS("AppInit") << "dx_diag_providerp->Initialize" << LL_ENDL; + LL_DEBUGS("AppInit") << "dx_diag_providerp->Initialize" << LL_ENDL; hr = dx_diag_providerp->Initialize(&dx_diag_init_params); if(FAILED(hr)) - { + { goto LCleanup; - } + } - LL_DEBUGS("AppInit") << "dx_diag_providerp->GetRootContainer" << LL_ENDL; + LL_DEBUGS("AppInit") << "dx_diag_providerp->GetRootContainer" << LL_ENDL; hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp ); if(FAILED(hr) || !dx_diag_rootp) - { + { goto LCleanup; - } + } - HRESULT hr; + HRESULT hr; - // Get display driver information - LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer" << LL_ENDL; - hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp); - if(FAILED(hr) || !devices_containerp) - { + // Get display driver information + LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer" << LL_ENDL; + hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp); + if(FAILED(hr) || !devices_containerp) + { // do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp - devices_containerp = NULL; + devices_containerp = NULL; goto LCleanup; - } + } // make sure there is something inside hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count); @@ -759,251 +759,251 @@ BOOL LLDXHardware::getInfo(BOOL vram_only) goto LCleanup; } - // Get device 0 - // By default 0 device is the primary one, howhever in case of various hybrid graphics - // like itegrated AMD and PCI AMD GPUs system might switch. - LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL; - hr = devices_containerp->GetChildContainer(L"0", &device_containerp); - if(FAILED(hr) || !device_containerp) - { + // Get device 0 + // By default 0 device is the primary one, howhever in case of various hybrid graphics + // like itegrated AMD and PCI AMD GPUs system might switch. + LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL; + hr = devices_containerp->GetChildContainer(L"0", &device_containerp); + if(FAILED(hr) || !device_containerp) + { + goto LCleanup; + } + + DWORD vram = 0; + + WCHAR deviceID[512]; + + get_wstring(device_containerp, L"szDeviceID", deviceID, 512); + // Example: searches id like 1F06 in pnp string (aka VEN_10DE&DEV_1F06) + // doesn't seem to work on some systems since format is unrecognizable + // but in such case keyDeviceID works + if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram))) + { + mVRAM = vram/(1024*1024); + } + else + { + get_wstring(device_containerp, L"szKeyDeviceID", deviceID, 512); + LL_WARNS() << "szDeviceID" << deviceID << LL_ENDL; + // '+9' to avoid ENUM\\PCI\\ prefix + // Returns string like Enum\\PCI\\VEN_10DE&DEV_1F06&SUBSYS... + // and since GetVideoMemoryViaWMI searches by PNPDeviceID it is sufficient + if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram))) + { + mVRAM = vram / (1024 * 1024); + } + } + + if (mVRAM == 0) + { // Get the English VRAM string + std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); + + // We don't need the device any more + SAFE_RELEASE(device_containerp); + + // Dump the string as an int into the structure + char *stopstring; + mVRAM = strtol(ram_str.c_str(), &stopstring, 10); + LL_INFOS("AppInit") << "VRAM Detected: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL; + } + + if (vram_only) + { + ok = TRUE; goto LCleanup; - } - - DWORD vram = 0; - - WCHAR deviceID[512]; - - get_wstring(device_containerp, L"szDeviceID", deviceID, 512); - // Example: searches id like 1F06 in pnp string (aka VEN_10DE&DEV_1F06) - // doesn't seem to work on some systems since format is unrecognizable - // but in such case keyDeviceID works - if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram))) - { - mVRAM = vram/(1024*1024); - } - else - { - get_wstring(device_containerp, L"szKeyDeviceID", deviceID, 512); - LL_WARNS() << "szDeviceID" << deviceID << LL_ENDL; - // '+9' to avoid ENUM\\PCI\\ prefix - // Returns string like Enum\\PCI\\VEN_10DE&DEV_1F06&SUBSYS... - // and since GetVideoMemoryViaWMI searches by PNPDeviceID it is sufficient - if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram))) - { - mVRAM = vram / (1024 * 1024); - } - } - - if (mVRAM == 0) - { // Get the English VRAM string - std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); - - // We don't need the device any more - SAFE_RELEASE(device_containerp); - - // Dump the string as an int into the structure - char *stopstring; - mVRAM = strtol(ram_str.c_str(), &stopstring, 10); - LL_INFOS("AppInit") << "VRAM Detected: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL; - } - - if (vram_only) - { - ok = TRUE; - goto LCleanup; - } - - - /* for now, we ONLY do vram_only the rest of this - is commented out, to ensure no-one is tempted - to use it - - // Now let's get device and driver information - // Get the IDxDiagContainer object called "DxDiag_SystemDevices". - // This call may take some time while dxdiag gathers the info. - DWORD num_devices = 0; - WCHAR wszContainer[256]; - LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer DxDiag_SystemDevices" << LL_ENDL; - hr = dx_diag_rootp->GetChildContainer(L"DxDiag_SystemDevices", &system_device_containerp); - if (FAILED(hr)) - { - goto LCleanup; - } - - hr = system_device_containerp->GetNumberOfChildContainers(&num_devices); - if (FAILED(hr)) - { - goto LCleanup; - } - - LL_DEBUGS("AppInit") << "DX9 iterating over devices" << LL_ENDL; - S32 device_num = 0; - for (device_num = 0; device_num < (S32)num_devices; device_num++) - { - hr = system_device_containerp->EnumChildContainerNames(device_num, wszContainer, 256); - if (FAILED(hr)) - { - goto LCleanup; - } - - hr = system_device_containerp->GetChildContainer(wszContainer, &device_containerp); - if (FAILED(hr) || device_containerp == NULL) - { - goto LCleanup; - } - - std::string device_name = get_string(device_containerp, L"szDescription"); - - std::string device_id = get_string(device_containerp, L"szDeviceID"); - - LLDXDevice *dxdevicep = new LLDXDevice; - dxdevicep->mName = device_name; - dxdevicep->mPCIString = device_id; - mDevices[dxdevicep->mPCIString] = dxdevicep; - - // Split the PCI string based on vendor, device, subsys, rev. - std::string str(device_id); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("&\\", "", boost::keep_empty_tokens); - tokenizer tokens(str, sep); - - tokenizer::iterator iter = tokens.begin(); - S32 count = 0; - BOOL valid = TRUE; - for (;(iter != tokens.end()) && (count < 3);++iter) - { - switch (count) - { - case 0: - if (strcmp(iter->c_str(), "PCI")) - { - valid = FALSE; - } - break; - case 1: - dxdevicep->mVendorID = iter->c_str(); - break; - case 2: - dxdevicep->mDeviceID = iter->c_str(); - break; - default: - // Ignore it - break; - } - count++; - } - - - - - // Now, iterate through the related drivers - hr = device_containerp->GetChildContainer(L"Drivers", &driver_containerp); - if (FAILED(hr) || !driver_containerp) - { - goto LCleanup; - } - - DWORD num_files = 0; - hr = driver_containerp->GetNumberOfChildContainers(&num_files); - if (FAILED(hr)) - { - goto LCleanup; - } - - S32 file_num = 0; - for (file_num = 0; file_num < (S32)num_files; file_num++ ) - { - - hr = driver_containerp->EnumChildContainerNames(file_num, wszContainer, 256); - if (FAILED(hr)) - { - goto LCleanup; - } - - hr = driver_containerp->GetChildContainer(wszContainer, &file_containerp); - if (FAILED(hr) || file_containerp == NULL) - { - goto LCleanup; - } - - std::string driver_path = get_string(file_containerp, L"szPath"); - std::string driver_name = get_string(file_containerp, L"szName"); - std::string driver_version = get_string(file_containerp, L"szVersion"); - std::string driver_date = get_string(file_containerp, L"szDatestampEnglish"); - - LLDXDriverFile *dxdriverfilep = new LLDXDriverFile; - dxdriverfilep->mName = driver_name; - dxdriverfilep->mFilepath= driver_path; - dxdriverfilep->mVersionString = driver_version; - dxdriverfilep->mVersion.set(driver_version); - dxdriverfilep->mDateString = driver_date; - - dxdevicep->mDriverFiles[driver_name] = dxdriverfilep; - - SAFE_RELEASE(file_containerp); - } - SAFE_RELEASE(device_containerp); - } - */ + } + + + /* for now, we ONLY do vram_only the rest of this + is commented out, to ensure no-one is tempted + to use it + + // Now let's get device and driver information + // Get the IDxDiagContainer object called "DxDiag_SystemDevices". + // This call may take some time while dxdiag gathers the info. + DWORD num_devices = 0; + WCHAR wszContainer[256]; + LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer DxDiag_SystemDevices" << LL_ENDL; + hr = dx_diag_rootp->GetChildContainer(L"DxDiag_SystemDevices", &system_device_containerp); + if (FAILED(hr)) + { + goto LCleanup; + } + + hr = system_device_containerp->GetNumberOfChildContainers(&num_devices); + if (FAILED(hr)) + { + goto LCleanup; + } + + LL_DEBUGS("AppInit") << "DX9 iterating over devices" << LL_ENDL; + S32 device_num = 0; + for (device_num = 0; device_num < (S32)num_devices; device_num++) + { + hr = system_device_containerp->EnumChildContainerNames(device_num, wszContainer, 256); + if (FAILED(hr)) + { + goto LCleanup; + } + + hr = system_device_containerp->GetChildContainer(wszContainer, &device_containerp); + if (FAILED(hr) || device_containerp == NULL) + { + goto LCleanup; + } + + std::string device_name = get_string(device_containerp, L"szDescription"); + + std::string device_id = get_string(device_containerp, L"szDeviceID"); + + LLDXDevice *dxdevicep = new LLDXDevice; + dxdevicep->mName = device_name; + dxdevicep->mPCIString = device_id; + mDevices[dxdevicep->mPCIString] = dxdevicep; + + // Split the PCI string based on vendor, device, subsys, rev. + std::string str(device_id); + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("&\\", "", boost::keep_empty_tokens); + tokenizer tokens(str, sep); + + tokenizer::iterator iter = tokens.begin(); + S32 count = 0; + BOOL valid = TRUE; + for (;(iter != tokens.end()) && (count < 3);++iter) + { + switch (count) + { + case 0: + if (strcmp(iter->c_str(), "PCI")) + { + valid = FALSE; + } + break; + case 1: + dxdevicep->mVendorID = iter->c_str(); + break; + case 2: + dxdevicep->mDeviceID = iter->c_str(); + break; + default: + // Ignore it + break; + } + count++; + } + + + + + // Now, iterate through the related drivers + hr = device_containerp->GetChildContainer(L"Drivers", &driver_containerp); + if (FAILED(hr) || !driver_containerp) + { + goto LCleanup; + } + + DWORD num_files = 0; + hr = driver_containerp->GetNumberOfChildContainers(&num_files); + if (FAILED(hr)) + { + goto LCleanup; + } + + S32 file_num = 0; + for (file_num = 0; file_num < (S32)num_files; file_num++ ) + { + + hr = driver_containerp->EnumChildContainerNames(file_num, wszContainer, 256); + if (FAILED(hr)) + { + goto LCleanup; + } + + hr = driver_containerp->GetChildContainer(wszContainer, &file_containerp); + if (FAILED(hr) || file_containerp == NULL) + { + goto LCleanup; + } + + std::string driver_path = get_string(file_containerp, L"szPath"); + std::string driver_name = get_string(file_containerp, L"szName"); + std::string driver_version = get_string(file_containerp, L"szVersion"); + std::string driver_date = get_string(file_containerp, L"szDatestampEnglish"); + + LLDXDriverFile *dxdriverfilep = new LLDXDriverFile; + dxdriverfilep->mName = driver_name; + dxdriverfilep->mFilepath= driver_path; + dxdriverfilep->mVersionString = driver_version; + dxdriverfilep->mVersion.set(driver_version); + dxdriverfilep->mDateString = driver_date; + + dxdevicep->mDriverFiles[driver_name] = dxdriverfilep; + + SAFE_RELEASE(file_containerp); + } + SAFE_RELEASE(device_containerp); + } + */ } // dumpDevices(); ok = TRUE; - + LCleanup: - if (!ok) - { - LL_WARNS("AppInit") << "DX9 probe failed" << LL_ENDL; - gWriteDebug("DX9 probe failed\n"); - } - - SAFE_RELEASE(file_containerp); - SAFE_RELEASE(driver_containerp); - SAFE_RELEASE(device_containerp); - SAFE_RELEASE(devices_containerp); + if (!ok) + { + LL_WARNS("AppInit") << "DX9 probe failed" << LL_ENDL; + gWriteDebug("DX9 probe failed\n"); + } + + SAFE_RELEASE(file_containerp); + SAFE_RELEASE(driver_containerp); + SAFE_RELEASE(device_containerp); + SAFE_RELEASE(devices_containerp); SAFE_RELEASE(dx_diag_rootp); SAFE_RELEASE(dx_diag_providerp); - + CoUninitialize(); - + return ok; } LLSD LLDXHardware::getDisplayInfo() { - LLTimer hw_timer; + LLTimer hw_timer; HRESULT hr; - LLSD ret; + LLSD ret; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); IDxDiagProvider *dx_diag_providerp = NULL; IDxDiagContainer *dx_diag_rootp = NULL; - IDxDiagContainer *devices_containerp = NULL; - IDxDiagContainer *device_containerp = NULL; - IDxDiagContainer *file_containerp = NULL; - IDxDiagContainer *driver_containerp = NULL; - DWORD dw_device_count; + IDxDiagContainer *devices_containerp = NULL; + IDxDiagContainer *device_containerp = NULL; + IDxDiagContainer *file_containerp = NULL; + IDxDiagContainer *driver_containerp = NULL; + DWORD dw_device_count; // CoCreate a IDxDiagProvider* - LL_INFOS() << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL; + LL_INFOS() << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL; hr = CoCreateInstance(CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, IID_IDxDiagProvider, (LPVOID*) &dx_diag_providerp); - if (FAILED(hr)) - { - LL_WARNS() << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; - gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); - goto LCleanup; - } + if (FAILED(hr)) + { + LL_WARNS() << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; + gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); + goto LCleanup; + } if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed { // Fill out a DXDIAG_INIT_PARAMS struct and pass it to IDxDiagContainer::Initialize - // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are - // digital signed as logo'd by WHQL which may connect via internet to update - // WHQL certificates. + // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are + // digital signed as logo'd by WHQL which may connect via internet to update + // WHQL certificates. DXDIAG_INIT_PARAMS dx_diag_init_params; ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS)); @@ -1012,31 +1012,31 @@ LLSD LLDXHardware::getDisplayInfo() dx_diag_init_params.bAllowWHQLChecks = TRUE; dx_diag_init_params.pReserved = NULL; - LL_INFOS() << "dx_diag_providerp->Initialize" << LL_ENDL; + LL_INFOS() << "dx_diag_providerp->Initialize" << LL_ENDL; hr = dx_diag_providerp->Initialize(&dx_diag_init_params); if(FAILED(hr)) - { + { goto LCleanup; - } + } - LL_INFOS() << "dx_diag_providerp->GetRootContainer" << LL_ENDL; + LL_INFOS() << "dx_diag_providerp->GetRootContainer" << LL_ENDL; hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp ); if(FAILED(hr) || !dx_diag_rootp) - { + { goto LCleanup; - } + } - HRESULT hr; + HRESULT hr; - // Get display driver information - LL_INFOS() << "dx_diag_rootp->GetChildContainer" << LL_ENDL; - hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp); - if(FAILED(hr) || !devices_containerp) - { + // Get display driver information + LL_INFOS() << "dx_diag_rootp->GetChildContainer" << LL_ENDL; + hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp); + if(FAILED(hr) || !devices_containerp) + { // do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp devices_containerp = NULL; goto LCleanup; - } + } // make sure there is something inside hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count); @@ -1045,26 +1045,26 @@ LLSD LLDXHardware::getDisplayInfo() goto LCleanup; } - // Get device 0 - LL_INFOS() << "devices_containerp->GetChildContainer" << LL_ENDL; - hr = devices_containerp->GetChildContainer(L"0", &device_containerp); - if(FAILED(hr) || !device_containerp) - { + // Get device 0 + LL_INFOS() << "devices_containerp->GetChildContainer" << LL_ENDL; + hr = devices_containerp->GetChildContainer(L"0", &device_containerp); + if(FAILED(hr) || !device_containerp) + { goto LCleanup; - } - - // Get the English VRAM string - std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); - - - // Dump the string as an int into the structure - char *stopstring; - ret["VRAM"] = strtol(ram_str.c_str(), &stopstring, 10); - std::string device_name = get_string(device_containerp, L"szDescription"); - ret["DeviceName"] = device_name; - std::string device_driver= get_string(device_containerp, L"szDriverVersion"); - ret["DriverVersion"] = device_driver; - + } + + // Get the English VRAM string + std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); + + + // Dump the string as an int into the structure + char *stopstring; + ret["VRAM"] = strtol(ram_str.c_str(), &stopstring, 10); + std::string device_name = get_string(device_containerp, L"szDescription"); + ret["DeviceName"] = device_name; + std::string device_driver= get_string(device_containerp, L"szDriverVersion"); + ret["DriverVersion"] = device_driver; + // ATI has a slightly different version string if(device_name.length() >= 4 && device_name.substr(0,4) == "ATI ") { @@ -1081,7 +1081,7 @@ LLSD LLDXHardware::getDisplayInfo() // get the value DWORD dwType = REG_SZ; DWORD dwSize = sizeof(WCHAR) * RV_SIZE; - if(ERROR_SUCCESS == RegQueryValueEx(hKey, TEXT("ReleaseVersion"), + if(ERROR_SUCCESS == RegQueryValueEx(hKey, TEXT("ReleaseVersion"), NULL, &dwType, (LPBYTE)release_version, &dwSize)) { // print the value @@ -1092,7 +1092,7 @@ LLSD LLDXHardware::getDisplayInfo() } RegCloseKey(hKey); } - } + } } LCleanup: @@ -1100,20 +1100,20 @@ LCleanup: { LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL; } - SAFE_RELEASE(file_containerp); - SAFE_RELEASE(driver_containerp); - SAFE_RELEASE(device_containerp); - SAFE_RELEASE(devices_containerp); + SAFE_RELEASE(file_containerp); + SAFE_RELEASE(driver_containerp); + SAFE_RELEASE(device_containerp); + SAFE_RELEASE(devices_containerp); SAFE_RELEASE(dx_diag_rootp); SAFE_RELEASE(dx_diag_providerp); - + CoUninitialize(); - return ret; + return ret; } void LLDXHardware::setWriteDebugFunc(void (*func)(const char*)) { - gWriteDebug = func; + gWriteDebug = func; } #endif diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h index 9cec3e2f1b..12273e97bc 100644 --- a/indra/llwindow/lldxhardware.h +++ b/indra/llwindow/lldxhardware.h @@ -1,25 +1,25 @@ -/** +/** * @file lldxhardware.h * @brief LLDXHardware definition * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,57 +36,57 @@ class LLVersion { public: - LLVersion(); - BOOL set(const std::string &version_string); - S32 getField(const S32 field_num); + LLVersion(); + BOOL set(const std::string &version_string); + S32 getField(const S32 field_num); protected: - std::string mVersionString; - S32 mFields[4]; - BOOL mValid; + std::string mVersionString; + S32 mFields[4]; + BOOL mValid; }; class LLDXDriverFile { public: - std::string dump(); + std::string dump(); public: - std::string mFilepath; - std::string mName; - std::string mVersionString; - LLVersion mVersion; - std::string mDateString; + std::string mFilepath; + std::string mName; + std::string mVersionString; + LLVersion mVersion; + std::string mDateString; }; class LLDXDevice { public: - ~LLDXDevice(); - std::string dump(); + ~LLDXDevice(); + std::string dump(); - LLDXDriverFile *findDriver(const std::string &driver); + LLDXDriverFile *findDriver(const std::string &driver); public: - std::string mName; - std::string mPCIString; - std::string mVendorID; - std::string mDeviceID; + std::string mName; + std::string mPCIString; + std::string mVendorID; + std::string mDeviceID; - typedef std::map<std::string, LLDXDriverFile *> driver_file_map_t; - driver_file_map_t mDriverFiles; + typedef std::map<std::string, LLDXDriverFile *> driver_file_map_t; + driver_file_map_t mDriverFiles; }; class LLDXHardware { public: - LLDXHardware(); + LLDXHardware(); - void setWriteDebugFunc(void (*func)(const char*)); - void cleanup(); + void setWriteDebugFunc(void (*func)(const char*)); + void cleanup(); - // Returns TRUE on success. - // vram_only TRUE does a "light" probe. - BOOL getInfo(BOOL vram_only); + // Returns TRUE on success. + // vram_only TRUE does a "light" probe. + BOOL getInfo(BOOL vram_only); // WMI can return multiple GPU drivers // specify which one to output @@ -96,28 +96,28 @@ public: GPU_AMD, GPU_ANY } EGPUVendor; - std::string getDriverVersionWMI(EGPUVendor vendor); + std::string getDriverVersionWMI(EGPUVendor vendor); - S32 getVRAM() const { return mVRAM; } + S32 getVRAM() const { return mVRAM; } - LLSD getDisplayInfo(); + LLSD getDisplayInfo(); - // Will get memory of best GPU in MB, return memory on sucsess, 0 on failure - // Note: WMI is not accurate in some cases - static S32 getMBVideoMemoryViaWMI(); + // Will get memory of best GPU in MB, return memory on sucsess, 0 on failure + // Note: WMI is not accurate in some cases + static S32 getMBVideoMemoryViaWMI(); - // Find a particular device that matches the following specs. - // Empty strings indicate that you don't care. - // You can separate multiple devices with '|' chars to indicate you want - // ANY of them to match and return. - // LLDXDevice *findDevice(const std::string &vendor, const std::string &devices); + // Find a particular device that matches the following specs. + // Empty strings indicate that you don't care. + // You can separate multiple devices with '|' chars to indicate you want + // ANY of them to match and return. + // LLDXDevice *findDevice(const std::string &vendor, const std::string &devices); - // std::string dumpDevices(); + // std::string dumpDevices(); public: - typedef std::map<std::string, LLDXDevice *> device_map_t; - // device_map_t mDevices; + typedef std::map<std::string, LLDXDevice *> device_map_t; + // device_map_t mDevices; protected: - S32 mVRAM; + S32 mVRAM; }; extern void (*gWriteDebug)(const char* msg); diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 7d28486287..f154351ce3 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboard.cpp * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,7 +39,7 @@ LLKeyboard *gKeyboard = NULL; //static 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 +LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10n + PC/Mac/Linux accelerator labeling // @@ -48,104 +48,104 @@ LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10 LLKeyboard::LLKeyboard() : mCallbacks(NULL) { - S32 i; - - // Constructor for LLTimer inits each timer. We want them to - // be constructed without being initialized, so we shut them down here. - for (i = 0; i < KEY_COUNT; i++) - { - mKeyLevelFrameCount[i] = 0; - mKeyLevel[i] = FALSE; - mKeyUp[i] = FALSE; - mKeyDown[i] = FALSE; - mKeyRepeated[i] = FALSE; - } - - mInsertMode = LL_KIM_INSERT; - mCurTranslatedKey = KEY_NONE; - mCurScanKey = KEY_NONE; - - addKeyName(' ', "Space" ); - addKeyName(KEY_RETURN, "Enter" ); - addKeyName(KEY_LEFT, "Left" ); - addKeyName(KEY_RIGHT, "Right" ); - addKeyName(KEY_UP, "Up" ); - addKeyName(KEY_DOWN, "Down" ); - addKeyName(KEY_ESCAPE, "Esc" ); - addKeyName(KEY_HOME, "Home" ); - addKeyName(KEY_END, "End" ); - addKeyName(KEY_PAGE_UP, "PgUp" ); - addKeyName(KEY_PAGE_DOWN, "PgDn" ); - addKeyName(KEY_F1, "F1" ); - addKeyName(KEY_F2, "F2" ); - addKeyName(KEY_F3, "F3" ); - addKeyName(KEY_F4, "F4" ); - addKeyName(KEY_F5, "F5" ); - addKeyName(KEY_F6, "F6" ); - addKeyName(KEY_F7, "F7" ); - addKeyName(KEY_F8, "F8" ); - addKeyName(KEY_F9, "F9" ); - addKeyName(KEY_F10, "F10" ); - addKeyName(KEY_F11, "F11" ); - addKeyName(KEY_F12, "F12" ); - addKeyName(KEY_TAB, "Tab" ); - addKeyName(KEY_ADD, "Add" ); - addKeyName(KEY_SUBTRACT, "Subtract" ); - addKeyName(KEY_MULTIPLY, "Multiply" ); - addKeyName(KEY_DIVIDE, "Divide" ); - addKeyName(KEY_PAD_DIVIDE, "PAD_DIVIDE" ); - addKeyName(KEY_PAD_LEFT, "PAD_LEFT" ); - addKeyName(KEY_PAD_RIGHT, "PAD_RIGHT" ); - addKeyName(KEY_PAD_DOWN, "PAD_DOWN" ); - addKeyName(KEY_PAD_UP, "PAD_UP" ); - addKeyName(KEY_PAD_HOME, "PAD_HOME" ); - addKeyName(KEY_PAD_END, "PAD_END" ); - addKeyName(KEY_PAD_PGUP, "PAD_PGUP" ); - addKeyName(KEY_PAD_PGDN, "PAD_PGDN" ); - addKeyName(KEY_PAD_CENTER, "PAD_CENTER" ); - addKeyName(KEY_PAD_INS, "PAD_INS" ); - addKeyName(KEY_PAD_DEL, "PAD_DEL" ); - addKeyName(KEY_PAD_RETURN, "PAD_Enter" ); - addKeyName(KEY_BUTTON0, "PAD_BUTTON0" ); - addKeyName(KEY_BUTTON1, "PAD_BUTTON1" ); - addKeyName(KEY_BUTTON2, "PAD_BUTTON2" ); - addKeyName(KEY_BUTTON3, "PAD_BUTTON3" ); - addKeyName(KEY_BUTTON4, "PAD_BUTTON4" ); - addKeyName(KEY_BUTTON5, "PAD_BUTTON5" ); - addKeyName(KEY_BUTTON6, "PAD_BUTTON6" ); - addKeyName(KEY_BUTTON7, "PAD_BUTTON7" ); - addKeyName(KEY_BUTTON8, "PAD_BUTTON8" ); - addKeyName(KEY_BUTTON9, "PAD_BUTTON9" ); - addKeyName(KEY_BUTTON10, "PAD_BUTTON10" ); - addKeyName(KEY_BUTTON11, "PAD_BUTTON11" ); - addKeyName(KEY_BUTTON12, "PAD_BUTTON12" ); - addKeyName(KEY_BUTTON13, "PAD_BUTTON13" ); - addKeyName(KEY_BUTTON14, "PAD_BUTTON14" ); - addKeyName(KEY_BUTTON15, "PAD_BUTTON15" ); - - addKeyName(KEY_BACKSPACE, "Backsp" ); - addKeyName(KEY_DELETE, "Del" ); - addKeyName(KEY_SHIFT, "Shift" ); - addKeyName(KEY_CONTROL, "Ctrl" ); - addKeyName(KEY_ALT, "Alt" ); - addKeyName(KEY_HYPHEN, "-" ); - addKeyName(KEY_EQUALS, "=" ); - addKeyName(KEY_INSERT, "Ins" ); - addKeyName(KEY_CAPSLOCK, "CapsLock" ); + S32 i; + + // Constructor for LLTimer inits each timer. We want them to + // be constructed without being initialized, so we shut them down here. + for (i = 0; i < KEY_COUNT; i++) + { + mKeyLevelFrameCount[i] = 0; + mKeyLevel[i] = FALSE; + mKeyUp[i] = FALSE; + mKeyDown[i] = FALSE; + mKeyRepeated[i] = FALSE; + } + + mInsertMode = LL_KIM_INSERT; + mCurTranslatedKey = KEY_NONE; + mCurScanKey = KEY_NONE; + + addKeyName(' ', "Space" ); + addKeyName(KEY_RETURN, "Enter" ); + addKeyName(KEY_LEFT, "Left" ); + addKeyName(KEY_RIGHT, "Right" ); + addKeyName(KEY_UP, "Up" ); + addKeyName(KEY_DOWN, "Down" ); + addKeyName(KEY_ESCAPE, "Esc" ); + addKeyName(KEY_HOME, "Home" ); + addKeyName(KEY_END, "End" ); + addKeyName(KEY_PAGE_UP, "PgUp" ); + addKeyName(KEY_PAGE_DOWN, "PgDn" ); + addKeyName(KEY_F1, "F1" ); + addKeyName(KEY_F2, "F2" ); + addKeyName(KEY_F3, "F3" ); + addKeyName(KEY_F4, "F4" ); + addKeyName(KEY_F5, "F5" ); + addKeyName(KEY_F6, "F6" ); + addKeyName(KEY_F7, "F7" ); + addKeyName(KEY_F8, "F8" ); + addKeyName(KEY_F9, "F9" ); + addKeyName(KEY_F10, "F10" ); + addKeyName(KEY_F11, "F11" ); + addKeyName(KEY_F12, "F12" ); + addKeyName(KEY_TAB, "Tab" ); + addKeyName(KEY_ADD, "Add" ); + addKeyName(KEY_SUBTRACT, "Subtract" ); + addKeyName(KEY_MULTIPLY, "Multiply" ); + addKeyName(KEY_DIVIDE, "Divide" ); + addKeyName(KEY_PAD_DIVIDE, "PAD_DIVIDE" ); + addKeyName(KEY_PAD_LEFT, "PAD_LEFT" ); + addKeyName(KEY_PAD_RIGHT, "PAD_RIGHT" ); + addKeyName(KEY_PAD_DOWN, "PAD_DOWN" ); + addKeyName(KEY_PAD_UP, "PAD_UP" ); + addKeyName(KEY_PAD_HOME, "PAD_HOME" ); + addKeyName(KEY_PAD_END, "PAD_END" ); + addKeyName(KEY_PAD_PGUP, "PAD_PGUP" ); + addKeyName(KEY_PAD_PGDN, "PAD_PGDN" ); + addKeyName(KEY_PAD_CENTER, "PAD_CENTER" ); + addKeyName(KEY_PAD_INS, "PAD_INS" ); + addKeyName(KEY_PAD_DEL, "PAD_DEL" ); + addKeyName(KEY_PAD_RETURN, "PAD_Enter" ); + addKeyName(KEY_BUTTON0, "PAD_BUTTON0" ); + addKeyName(KEY_BUTTON1, "PAD_BUTTON1" ); + addKeyName(KEY_BUTTON2, "PAD_BUTTON2" ); + addKeyName(KEY_BUTTON3, "PAD_BUTTON3" ); + addKeyName(KEY_BUTTON4, "PAD_BUTTON4" ); + addKeyName(KEY_BUTTON5, "PAD_BUTTON5" ); + addKeyName(KEY_BUTTON6, "PAD_BUTTON6" ); + addKeyName(KEY_BUTTON7, "PAD_BUTTON7" ); + addKeyName(KEY_BUTTON8, "PAD_BUTTON8" ); + addKeyName(KEY_BUTTON9, "PAD_BUTTON9" ); + addKeyName(KEY_BUTTON10, "PAD_BUTTON10" ); + addKeyName(KEY_BUTTON11, "PAD_BUTTON11" ); + addKeyName(KEY_BUTTON12, "PAD_BUTTON12" ); + addKeyName(KEY_BUTTON13, "PAD_BUTTON13" ); + addKeyName(KEY_BUTTON14, "PAD_BUTTON14" ); + addKeyName(KEY_BUTTON15, "PAD_BUTTON15" ); + + addKeyName(KEY_BACKSPACE, "Backsp" ); + addKeyName(KEY_DELETE, "Del" ); + addKeyName(KEY_SHIFT, "Shift" ); + addKeyName(KEY_CONTROL, "Ctrl" ); + addKeyName(KEY_ALT, "Alt" ); + addKeyName(KEY_HYPHEN, "-" ); + addKeyName(KEY_EQUALS, "=" ); + addKeyName(KEY_INSERT, "Ins" ); + addKeyName(KEY_CAPSLOCK, "CapsLock" ); } LLKeyboard::~LLKeyboard() { - // nothing + // nothing } void LLKeyboard::addKeyName(KEY key, const std::string& name) { - sKeysToNames[key] = name; - std::string nameuc = name; - LLStringUtil::toUpper(nameuc); - sNamesToKeys[nameuc] = key; + sKeysToNames[key] = name; + std::string nameuc = name; + LLStringUtil::toUpper(nameuc); + sNamesToKeys[nameuc] = key; } void LLKeyboard::resetKeyDownAndHandle() @@ -168,202 +168,202 @@ void LLKeyboard::resetKeyDownAndHandle() // is wrong because the keyup event is never received by the main window. JC void LLKeyboard::resetKeys() { - S32 i; - - for (i = 0; i < KEY_COUNT; i++) - { - if( mKeyLevel[i] ) - { - mKeyLevel[i] = FALSE; - } - } - - for (i = 0; i < KEY_COUNT; i++) - { - mKeyUp[i] = FALSE; - } - - for (i = 0; i < KEY_COUNT; i++) - { - mKeyDown[i] = FALSE; - } - - for (i = 0; i < KEY_COUNT; i++) - { - mKeyRepeated[i] = FALSE; - } + S32 i; + + for (i = 0; i < KEY_COUNT; i++) + { + if( mKeyLevel[i] ) + { + mKeyLevel[i] = FALSE; + } + } + + for (i = 0; i < KEY_COUNT; i++) + { + mKeyUp[i] = FALSE; + } + + for (i = 0; i < KEY_COUNT; i++) + { + mKeyDown[i] = FALSE; + } + + for (i = 0; i < KEY_COUNT; i++) + { + mKeyRepeated[i] = FALSE; + } } BOOL LLKeyboard::translateKey(const U32 os_key, KEY *out_key) { - std::map<U32, KEY>::iterator iter; - - // Only translate keys in the map, ignore all other keys for now - iter = mTranslateKeyMap.find(os_key); - if (iter == mTranslateKeyMap.end()) - { - //LL_WARNS() << "Unknown virtual key " << os_key << LL_ENDL; - *out_key = 0; - return FALSE; - } - else - { - *out_key = iter->second; - return TRUE; - } + std::map<U32, KEY>::iterator iter; + + // Only translate keys in the map, ignore all other keys for now + iter = mTranslateKeyMap.find(os_key); + if (iter == mTranslateKeyMap.end()) + { + //LL_WARNS() << "Unknown virtual key " << os_key << LL_ENDL; + *out_key = 0; + return FALSE; + } + else + { + *out_key = iter->second; + return TRUE; + } } U32 LLKeyboard::inverseTranslateKey(const KEY translated_key) { - std::map<KEY, U32>::iterator iter; - iter = mInvTranslateKeyMap.find(translated_key); - if (iter == mInvTranslateKeyMap.end()) - { - return 0; - } - else - { - return iter->second; - } + std::map<KEY, U32>::iterator iter; + iter = mInvTranslateKeyMap.find(translated_key); + if (iter == mInvTranslateKeyMap.end()) + { + return 0; + } + else + { + return iter->second; + } } BOOL LLKeyboard::handleTranslatedKeyDown(KEY translated_key, U32 translated_mask) { - BOOL handled = FALSE; - BOOL repeated = FALSE; - - // is this the first time the key went down? - // if so, generate "character" message - if( !mKeyLevel[translated_key] ) - { - mKeyLevel[translated_key] = TRUE; - mKeyLevelTimer[translated_key].reset(); - mKeyLevelFrameCount[translated_key] = 0; - mKeyRepeated[translated_key] = FALSE; - } - else - { - // Level is already down, assume it's repeated. - repeated = TRUE; - mKeyRepeated[translated_key] = TRUE; - } - - mKeyDown[translated_key] = TRUE; - mCurTranslatedKey = (KEY)translated_key; - handled = mCallbacks->handleTranslatedKeyDown(translated_key, translated_mask, repeated); - return handled; + BOOL handled = FALSE; + BOOL repeated = FALSE; + + // is this the first time the key went down? + // if so, generate "character" message + if( !mKeyLevel[translated_key] ) + { + mKeyLevel[translated_key] = TRUE; + mKeyLevelTimer[translated_key].reset(); + mKeyLevelFrameCount[translated_key] = 0; + mKeyRepeated[translated_key] = FALSE; + } + else + { + // Level is already down, assume it's repeated. + repeated = TRUE; + mKeyRepeated[translated_key] = TRUE; + } + + mKeyDown[translated_key] = TRUE; + mCurTranslatedKey = (KEY)translated_key; + handled = mCallbacks->handleTranslatedKeyDown(translated_key, translated_mask, repeated); + return handled; } BOOL LLKeyboard::handleTranslatedKeyUp(KEY translated_key, U32 translated_mask) -{ - BOOL handled = FALSE; - if( mKeyLevel[translated_key] ) - { - mKeyLevel[translated_key] = FALSE; - - // Only generate key up events if the key is thought to - // be down. This allows you to call resetKeys() in the - // middle of a frame and ignore subsequent KEY_UP - // messages in the same frame. This was causing the - // sequence W<return> in chat to move agents forward. JC - mKeyUp[translated_key] = TRUE; - handled = mCallbacks->handleTranslatedKeyUp(translated_key, translated_mask); - } - - LL_DEBUGS("UserInput") << "keyup -" << translated_key << "-" << LL_ENDL; - - return handled; +{ + BOOL handled = FALSE; + if( mKeyLevel[translated_key] ) + { + mKeyLevel[translated_key] = FALSE; + + // Only generate key up events if the key is thought to + // be down. This allows you to call resetKeys() in the + // middle of a frame and ignore subsequent KEY_UP + // messages in the same frame. This was causing the + // sequence W<return> in chat to move agents forward. JC + mKeyUp[translated_key] = TRUE; + handled = mCallbacks->handleTranslatedKeyUp(translated_key, translated_mask); + } + + LL_DEBUGS("UserInput") << "keyup -" << translated_key << "-" << LL_ENDL; + + return handled; } void LLKeyboard::toggleInsertMode() { - if (LL_KIM_INSERT == mInsertMode) - { - mInsertMode = LL_KIM_OVERWRITE; - } - else - { - mInsertMode = LL_KIM_INSERT; - } + if (LL_KIM_INSERT == mInsertMode) + { + mInsertMode = LL_KIM_OVERWRITE; + } + else + { + mInsertMode = LL_KIM_INSERT; + } } // Returns time in seconds since key was pressed. F32 LLKeyboard::getKeyElapsedTime(KEY key) { - return mKeyLevelTimer[key].getElapsedTimeF32(); + return mKeyLevelTimer[key].getElapsedTimeF32(); } // Returns time in frames since key was pressed. S32 LLKeyboard::getKeyElapsedFrameCount(KEY key) { - return mKeyLevelFrameCount[key]; + return mKeyLevelFrameCount[key]; } // static BOOL LLKeyboard::keyFromString(const std::string& str, KEY *key) { - std::string instring(str); - size_t length = instring.size(); - - if (length < 1) - { - return FALSE; - } - if (length == 1) - { - char ch = toupper(instring[0]); - if (('0' <= ch && ch <= '9') || - ('A' <= ch && ch <= 'Z') || - ('!' <= ch && ch <= '/') || // !"#$%&'()*+,-./ - (':' <= ch && ch <= '@') || // :;<=>?@ - ('[' <= ch && ch <= '`') || // [\]^_` - ('{' <= ch && ch <= '~')) // {|}~ - { - *key = ch; - return TRUE; - } - } - - LLStringUtil::toUpper(instring); - KEY res = get_if_there(sNamesToKeys, instring, (KEY)0); - if (res != 0) - { - *key = res; - return TRUE; - } - LL_WARNS() << "keyFromString failed: " << str << LL_ENDL; - return FALSE; + std::string instring(str); + size_t length = instring.size(); + + if (length < 1) + { + return FALSE; + } + if (length == 1) + { + char ch = toupper(instring[0]); + if (('0' <= ch && ch <= '9') || + ('A' <= ch && ch <= 'Z') || + ('!' <= ch && ch <= '/') || // !"#$%&'()*+,-./ + (':' <= ch && ch <= '@') || // :;<=>?@ + ('[' <= ch && ch <= '`') || // [\]^_` + ('{' <= ch && ch <= '~')) // {|}~ + { + *key = ch; + return TRUE; + } + } + + LLStringUtil::toUpper(instring); + KEY res = get_if_there(sNamesToKeys, instring, (KEY)0); + if (res != 0) + { + *key = res; + return TRUE; + } + LL_WARNS() << "keyFromString failed: " << str << LL_ENDL; + return FALSE; } // static std::string LLKeyboard::stringFromKey(KEY key, bool translate) { - std::string res = get_if_there(sKeysToNames, key, std::string()); - if (res.empty()) - { - char buffer[2]; /* Flawfinder: ignore */ - buffer[0] = key; - buffer[1] = '\0'; - res = std::string(buffer); - } - - if (translate) - { - LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; - if (trans != NULL) - { - res = trans(res.c_str()); - } - } - - return res; + std::string res = get_if_there(sKeysToNames, key, std::string()); + if (res.empty()) + { + char buffer[2]; /* Flawfinder: ignore */ + buffer[0] = key; + buffer[1] = '\0'; + res = std::string(buffer); + } + + if (translate) + { + LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; + if (trans != NULL) + { + res = trans(res.c_str()); + } + } + + return res; } //static @@ -430,13 +430,13 @@ std::string LLKeyboard::stringFromAccelerator(MASK accel_mask) } else { - res.append(trans("accel-mac-command")); // Symbol would be "\xE2\x8C\x98" + res.append(trans("accel-mac-command")); // Symbol would be "\xE2\x8C\x98" } } if (accel_mask & MASK_ALT) - res.append(trans("accel-mac-option")); // Symbol would be "\xE2\x8C\xA5" + res.append(trans("accel-mac-option")); // Symbol would be "\xE2\x8C\xA5" if (accel_mask & MASK_SHIFT) - res.append(trans("accel-mac-shift")); // Symbol would be "\xE2\x8C\xA7" + res.append(trans("accel-mac-shift")); // Symbol would be "\xE2\x8C\xA7" #else if (accel_mask & MASK_CONTROL) res.append(trans("accel-win-control")); @@ -450,26 +450,26 @@ std::string LLKeyboard::stringFromAccelerator(MASK accel_mask) //static std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key ) { - std::string res; - - // break early if this is a silly thing to do. - if( KEY_NONE == key ) - { - return res; - } - - res.append(stringFromAccelerator(accel_mask)); - std::string key_string = LLKeyboard::stringFromKey(key); - if ((accel_mask & MASK_NORMALKEYS) && - (key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+')) - { - res.append( " " ); - } - - std::string keystr = stringFromKey( key ); - res.append( keystr ); - - return res; + std::string res; + + // break early if this is a silly thing to do. + if( KEY_NONE == key ) + { + return res; + } + + res.append(stringFromAccelerator(accel_mask)); + std::string key_string = LLKeyboard::stringFromKey(key); + if ((accel_mask & MASK_NORMALKEYS) && + (key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+')) + { + res.append( " " ); + } + + std::string keystr = stringFromKey( key ); + res.append( keystr ); + + return res; } //static @@ -488,56 +488,56 @@ std::string LLKeyboard::stringFromAccelerator(MASK accel_mask, EMouseClickType c //static BOOL LLKeyboard::maskFromString(const std::string& str, MASK *mask) { - std::string instring(str); - if (instring == "NONE") - { - *mask = MASK_NONE; - return TRUE; - } - else if (instring == "SHIFT") - { - *mask = MASK_SHIFT; - return TRUE; - } - else if (instring == "CTL") - { - *mask = MASK_CONTROL; - return TRUE; - } - else if (instring == "ALT") - { - *mask = MASK_ALT; - return TRUE; - } - else if (instring == "CTL_SHIFT") - { - *mask = MASK_CONTROL | MASK_SHIFT; - return TRUE; - } - else if (instring == "ALT_SHIFT") - { - *mask = MASK_ALT | MASK_SHIFT; - return TRUE; - } - else if (instring == "CTL_ALT") - { - *mask = MASK_CONTROL | MASK_ALT; - return TRUE; - } - else if (instring == "CTL_ALT_SHIFT") - { - *mask = MASK_CONTROL | MASK_ALT | MASK_SHIFT; - return TRUE; - } - else - { - return FALSE; - } + std::string instring(str); + if (instring == "NONE") + { + *mask = MASK_NONE; + return TRUE; + } + else if (instring == "SHIFT") + { + *mask = MASK_SHIFT; + return TRUE; + } + else if (instring == "CTL") + { + *mask = MASK_CONTROL; + return TRUE; + } + else if (instring == "ALT") + { + *mask = MASK_ALT; + return TRUE; + } + else if (instring == "CTL_SHIFT") + { + *mask = MASK_CONTROL | MASK_SHIFT; + return TRUE; + } + else if (instring == "ALT_SHIFT") + { + *mask = MASK_ALT | MASK_SHIFT; + return TRUE; + } + else if (instring == "CTL_ALT") + { + *mask = MASK_CONTROL | MASK_ALT; + return TRUE; + } + else if (instring == "CTL_ALT_SHIFT") + { + *mask = MASK_CONTROL | MASK_ALT | MASK_SHIFT; + return TRUE; + } + else + { + return FALSE; + } } //static void LLKeyboard::setStringTranslatorFunc( LLKeyStringTranslatorFunc *trans_func ) { - mStringTranslator = trans_func; + mStringTranslator = trans_func; } diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 2c3bd94d55..1a6292f29f 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboard.h * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,20 +34,20 @@ #include "lltimer.h" #include "indra_constants.h" -enum EKeystate +enum EKeystate { - KEYSTATE_DOWN, - KEYSTATE_LEVEL, - KEYSTATE_UP + KEYSTATE_DOWN, + KEYSTATE_LEVEL, + KEYSTATE_UP }; typedef boost::function<bool(EKeystate keystate)> LLKeyFunc; typedef std::string (LLKeyStringTranslatorFunc)(const char *label); - + enum EKeyboardInsertMode { - LL_KIM_INSERT, - LL_KIM_OVERWRITE + LL_KIM_INSERT, + LL_KIM_OVERWRITE }; class LLWindowCallbacks; @@ -55,81 +55,81 @@ class LLWindowCallbacks; class LLKeyboard { public: - LLKeyboard(); - virtual ~LLKeyboard(); + LLKeyboard(); + virtual ~LLKeyboard(); + + void resetKeyDownAndHandle(); + void resetKeys(); - void resetKeyDownAndHandle(); - void resetKeys(); + F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; } + F32 getCurKeyElapsedFrameCount() { return getKeyDown(mCurScanKey) ? (F32)getKeyElapsedFrameCount( mCurScanKey ) : 0.f; } + BOOL getKeyDown(const KEY key) { return mKeyLevel[key]; } + BOOL getKeyRepeated(const KEY key) { return mKeyRepeated[key]; } - F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; } - F32 getCurKeyElapsedFrameCount() { return getKeyDown(mCurScanKey) ? (F32)getKeyElapsedFrameCount( mCurScanKey ) : 0.f; } - BOOL getKeyDown(const KEY key) { return mKeyLevel[key]; } - BOOL getKeyRepeated(const KEY key) { return mKeyRepeated[key]; } + BOOL translateKey(const U32 os_key, KEY *translated_key); + U32 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 - BOOL translateKey(const U32 os_key, KEY *translated_key); - U32 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 U32 key, MASK mask) = 0; + virtual BOOL handleKeyDown(const U32 key, MASK mask) = 0; - virtual BOOL handleKeyUp(const U32 key, MASK mask) = 0; - virtual BOOL handleKeyDown(const U32 key, MASK mask) = 0; - #if defined(LL_DARWIN) && !defined(LL_SDL) - // We only actually use this for OS X. - virtual void handleModifier(MASK mask) = 0; + // We only actually use this for OS X. + virtual void handleModifier(MASK mask) = 0; #endif // LL_DARWIN - // Asynchronously poll the control, alt, and shift keys and set the - // appropriate internal key masks. - virtual void resetMaskKeys() = 0; - virtual void scanKeyboard() = 0; // scans keyboard, calls functions as necessary - // Mac must differentiate between Command = Control for keyboard events - // and Command != Control for mouse events. - virtual MASK currentMask(BOOL for_mouse_event) = 0; - virtual KEY currentKey() { return mCurTranslatedKey; } - - EKeyboardInsertMode getInsertMode() { return mInsertMode; } - void toggleInsertMode(); - - static BOOL maskFromString(const std::string& str, MASK *mask); // False on failure - static BOOL keyFromString(const std::string& str, KEY *key); // False on failure - static std::string stringFromKey(KEY key, bool translate = true); + // Asynchronously poll the control, alt, and shift keys and set the + // appropriate internal key masks. + virtual void resetMaskKeys() = 0; + virtual void scanKeyboard() = 0; // scans keyboard, calls functions as necessary + // Mac must differentiate between Command = Control for keyboard events + // and Command != Control for mouse events. + virtual MASK currentMask(BOOL for_mouse_event) = 0; + virtual KEY currentKey() { return mCurTranslatedKey; } + + EKeyboardInsertMode getInsertMode() { return mInsertMode; } + void toggleInsertMode(); + + static BOOL maskFromString(const std::string& str, MASK *mask); // False on failure + static BOOL keyFromString(const std::string& str, KEY *key); // False on failure + static std::string stringFromKey(KEY key, bool translate = true); static std::string stringFromMouse(EMouseClickType click, bool translate = true); - static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"... - static std::string stringFromAccelerator( MASK accel_mask, KEY key ); + static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"... + static std::string stringFromAccelerator( MASK accel_mask, KEY key ); static std::string stringFromAccelerator(MASK accel_mask, EMouseClickType click); - void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; } - F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. - S32 getKeyElapsedFrameCount( KEY key ); // Returns time in frames since key was pressed. + void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; } + F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. + S32 getKeyElapsedFrameCount( KEY key ); // Returns time in frames since key was pressed. + + static void setStringTranslatorFunc( LLKeyStringTranslatorFunc *trans_func ); - static void setStringTranslatorFunc( LLKeyStringTranslatorFunc *trans_func ); - protected: - void addKeyName(KEY key, const std::string& name); + void addKeyName(KEY key, const std::string& name); protected: - std::map<U32, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs - std::map<KEY, U32> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys - LLWindowCallbacks *mCallbacks; - - LLTimer mKeyLevelTimer[KEY_COUNT]; // Time since level was set - S32 mKeyLevelFrameCount[KEY_COUNT]; // Frames since level was set - BOOL mKeyLevel[KEY_COUNT]; // Levels - BOOL mKeyRepeated[KEY_COUNT]; // Key was repeated - BOOL mKeyUp[KEY_COUNT]; // Up edge - BOOL mKeyDown[KEY_COUNT]; // Down edge - KEY mCurTranslatedKey; - KEY mCurScanKey; // Used during the scanKeyboard() - - static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling - - EKeyboardInsertMode mInsertMode; - - static std::map<KEY,std::string> sKeysToNames; - static std::map<std::string,KEY> sNamesToKeys; + std::map<U32, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs + std::map<KEY, U32> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys + LLWindowCallbacks *mCallbacks; + + LLTimer mKeyLevelTimer[KEY_COUNT]; // Time since level was set + S32 mKeyLevelFrameCount[KEY_COUNT]; // Frames since level was set + BOOL mKeyLevel[KEY_COUNT]; // Levels + BOOL mKeyRepeated[KEY_COUNT]; // Key was repeated + BOOL mKeyUp[KEY_COUNT]; // Up edge + BOOL mKeyDown[KEY_COUNT]; // Down edge + KEY mCurTranslatedKey; + KEY mCurScanKey; // Used during the scanKeyboard() + + static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling + + EKeyboardInsertMode mInsertMode; + + static std::map<KEY,std::string> sKeysToNames; + static std::map<std::string,KEY> sNamesToKeys; }; // Interface to get key from assigned command diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp index 3ca421f9f9..3e81aff626 100644 --- a/indra/llwindow/llkeyboardheadless.cpp +++ b/indra/llwindow/llkeyboardheadless.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardheadless.cpp * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,33 +48,33 @@ MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event) #ifdef LL_DARWIN void LLKeyboardHeadless::handleModifier(MASK mask) { - + } #endif void LLKeyboardHeadless::scanKeyboard() { - for (S32 key = 0; key < KEY_COUNT; key++) - { - // Generate callback if any event has occurred on this key this frame. - // Can't just test mKeyLevel, because this could be a slow frame and - // key might have gone down then up. JC - if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) - { - mCurScanKey = key; - mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); - } - } + for (S32 key = 0; key < KEY_COUNT; key++) + { + // Generate callback if any event has occurred on this key this frame. + // Can't just test mKeyLevel, because this could be a slow frame and + // key might have gone down then up. JC + if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) + { + mCurScanKey = key; + mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); + } + } - // Reset edges for next frame - for (S32 key = 0; key < KEY_COUNT; key++) - { - mKeyUp[key] = FALSE; - mKeyDown[key] = FALSE; - if (mKeyLevel[key]) - { - mKeyLevelFrameCount[key]++; - } - } + // Reset edges for next frame + for (S32 key = 0; key < KEY_COUNT; key++) + { + mKeyUp[key] = FALSE; + mKeyDown[key] = FALSE; + if (mKeyLevel[key]) + { + mKeyLevelFrameCount[key]++; + } + } } - + diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h index 929751586c..73910ed883 100644 --- a/indra/llwindow/llkeyboardheadless.h +++ b/indra/llwindow/llkeyboardheadless.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardheadless.h * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,16 +32,16 @@ class LLKeyboardHeadless : public LLKeyboard { public: - LLKeyboardHeadless(); - /*virtual*/ ~LLKeyboardHeadless() {}; + LLKeyboardHeadless(); + /*virtual*/ ~LLKeyboardHeadless() {}; - /*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(); + /*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(); #ifdef LL_DARWIN - /*virtual*/ void handleModifier(MASK mask); + /*virtual*/ void handleModifier(MASK mask); #endif }; diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp index 85bb7b9aeb..a1aeb2e5e4 100644 --- a/indra/llwindow/llkeyboardmacosx.cpp +++ b/indra/llwindow/llkeyboardmacosx.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardmacosx.cpp * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,284 +34,284 @@ LLKeyboardMacOSX::LLKeyboardMacOSX() { - // Virtual keycode mapping table. Yes, this was as annoying to generate as it looks. - mTranslateKeyMap[0x00] = 'A'; - mTranslateKeyMap[0x01] = 'S'; - mTranslateKeyMap[0x02] = 'D'; - mTranslateKeyMap[0x03] = 'F'; - mTranslateKeyMap[0x04] = 'H'; - mTranslateKeyMap[0x05] = 'G'; - mTranslateKeyMap[0x06] = 'Z'; - mTranslateKeyMap[0x07] = 'X'; - mTranslateKeyMap[0x08] = 'C'; - mTranslateKeyMap[0x09] = 'V'; - mTranslateKeyMap[0x0b] = 'B'; - mTranslateKeyMap[0x0c] = 'Q'; - mTranslateKeyMap[0x0d] = 'W'; - mTranslateKeyMap[0x0e] = 'E'; - mTranslateKeyMap[0x0f] = 'R'; - mTranslateKeyMap[0x10] = 'Y'; - mTranslateKeyMap[0x11] = 'T'; - mTranslateKeyMap[0x12] = '1'; - mTranslateKeyMap[0x13] = '2'; - mTranslateKeyMap[0x14] = '3'; - mTranslateKeyMap[0x15] = '4'; - mTranslateKeyMap[0x16] = '6'; - mTranslateKeyMap[0x17] = '5'; - mTranslateKeyMap[0x18] = '='; // KEY_EQUALS - mTranslateKeyMap[0x19] = '9'; - mTranslateKeyMap[0x1a] = '7'; - mTranslateKeyMap[0x1b] = '-'; // KEY_HYPHEN - mTranslateKeyMap[0x1c] = '8'; - mTranslateKeyMap[0x1d] = '0'; - mTranslateKeyMap[0x1e] = ']'; - mTranslateKeyMap[0x1f] = 'O'; - mTranslateKeyMap[0x20] = 'U'; - mTranslateKeyMap[0x21] = '['; - mTranslateKeyMap[0x22] = 'I'; - mTranslateKeyMap[0x23] = 'P'; - mTranslateKeyMap[0x24] = KEY_RETURN, - mTranslateKeyMap[0x25] = 'L'; - mTranslateKeyMap[0x26] = 'J'; - mTranslateKeyMap[0x27] = '\''; - mTranslateKeyMap[0x28] = 'K'; - mTranslateKeyMap[0x29] = ';'; - mTranslateKeyMap[0x2a] = '\\'; - mTranslateKeyMap[0x2b] = ','; - mTranslateKeyMap[0x2c] = KEY_DIVIDE; - mTranslateKeyMap[0x2d] = 'N'; - mTranslateKeyMap[0x2e] = 'M'; - mTranslateKeyMap[0x2f] = '.'; - mTranslateKeyMap[0x30] = KEY_TAB; - mTranslateKeyMap[0x31] = ' '; // space! - mTranslateKeyMap[0x32] = '`'; - mTranslateKeyMap[0x33] = KEY_BACKSPACE; - mTranslateKeyMap[0x35] = KEY_ESCAPE; - //mTranslateKeyMap[0x37] = 0; // Command key. (not used yet) - mTranslateKeyMap[0x38] = KEY_SHIFT; - mTranslateKeyMap[0x39] = KEY_CAPSLOCK; - mTranslateKeyMap[0x3a] = KEY_ALT; - mTranslateKeyMap[0x3b] = KEY_CONTROL; - mTranslateKeyMap[0x41] = '.'; // keypad - mTranslateKeyMap[0x43] = '*'; // keypad - mTranslateKeyMap[0x45] = '+'; // keypad - mTranslateKeyMap[0x4b] = KEY_PAD_DIVIDE; // keypad - mTranslateKeyMap[0x4c] = KEY_RETURN; // keypad enter - mTranslateKeyMap[0x4e] = '-'; // keypad - mTranslateKeyMap[0x51] = '='; // keypad - mTranslateKeyMap[0x52] = '0'; // keypad - mTranslateKeyMap[0x53] = '1'; // keypad - mTranslateKeyMap[0x54] = '2'; // keypad - mTranslateKeyMap[0x55] = '3'; // keypad - mTranslateKeyMap[0x56] = '4'; // keypad - mTranslateKeyMap[0x57] = '5'; // keypad - mTranslateKeyMap[0x58] = '6'; // keypad - mTranslateKeyMap[0x59] = '7'; // keypad - mTranslateKeyMap[0x5b] = '8'; // keypad - mTranslateKeyMap[0x5c] = '9'; // keypad - mTranslateKeyMap[0x60] = KEY_F5; - mTranslateKeyMap[0x61] = KEY_F6; - mTranslateKeyMap[0x62] = KEY_F7; - mTranslateKeyMap[0x63] = KEY_F3; - mTranslateKeyMap[0x64] = KEY_F8; - mTranslateKeyMap[0x65] = KEY_F9; - mTranslateKeyMap[0x67] = KEY_F11; - mTranslateKeyMap[0x6d] = KEY_F10; - mTranslateKeyMap[0x6f] = KEY_F12; - mTranslateKeyMap[0x72] = KEY_INSERT; - mTranslateKeyMap[0x73] = KEY_HOME; - mTranslateKeyMap[0x74] = KEY_PAGE_UP; - mTranslateKeyMap[0x75] = KEY_DELETE; - mTranslateKeyMap[0x76] = KEY_F4; - mTranslateKeyMap[0x77] = KEY_END; - mTranslateKeyMap[0x78] = KEY_F2; - mTranslateKeyMap[0x79] = KEY_PAGE_DOWN; - mTranslateKeyMap[0x7a] = KEY_F1; - mTranslateKeyMap[0x7b] = KEY_LEFT; - mTranslateKeyMap[0x7c] = KEY_RIGHT; - mTranslateKeyMap[0x7d] = KEY_DOWN; - mTranslateKeyMap[0x7e] = KEY_UP; - - // Build inverse map - std::map<U16, KEY>::iterator iter; - for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) - { - mInvTranslateKeyMap[iter->second] = iter->first; - } - - // build numpad maps - mTranslateNumpadMap[0x52] = KEY_PAD_INS; // keypad 0 - mTranslateNumpadMap[0x53] = KEY_PAD_END; // keypad 1 - mTranslateNumpadMap[0x54] = KEY_PAD_DOWN; // keypad 2 - mTranslateNumpadMap[0x55] = KEY_PAD_PGDN; // keypad 3 - mTranslateNumpadMap[0x56] = KEY_PAD_LEFT; // keypad 4 - mTranslateNumpadMap[0x57] = KEY_PAD_CENTER; // keypad 5 - mTranslateNumpadMap[0x58] = KEY_PAD_RIGHT; // keypad 6 - mTranslateNumpadMap[0x59] = KEY_PAD_HOME; // keypad 7 - mTranslateNumpadMap[0x5b] = KEY_PAD_UP; // keypad 8 - mTranslateNumpadMap[0x5c] = KEY_PAD_PGUP; // keypad 9 - mTranslateNumpadMap[0x41] = KEY_PAD_DEL; // keypad . - mTranslateNumpadMap[0x4c] = KEY_PAD_RETURN; // keypad enter - - // Build inverse numpad map - for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) - { - mInvTranslateNumpadMap[iter->second] = iter->first; - } + // Virtual keycode mapping table. Yes, this was as annoying to generate as it looks. + mTranslateKeyMap[0x00] = 'A'; + mTranslateKeyMap[0x01] = 'S'; + mTranslateKeyMap[0x02] = 'D'; + mTranslateKeyMap[0x03] = 'F'; + mTranslateKeyMap[0x04] = 'H'; + mTranslateKeyMap[0x05] = 'G'; + mTranslateKeyMap[0x06] = 'Z'; + mTranslateKeyMap[0x07] = 'X'; + mTranslateKeyMap[0x08] = 'C'; + mTranslateKeyMap[0x09] = 'V'; + mTranslateKeyMap[0x0b] = 'B'; + mTranslateKeyMap[0x0c] = 'Q'; + mTranslateKeyMap[0x0d] = 'W'; + mTranslateKeyMap[0x0e] = 'E'; + mTranslateKeyMap[0x0f] = 'R'; + mTranslateKeyMap[0x10] = 'Y'; + mTranslateKeyMap[0x11] = 'T'; + mTranslateKeyMap[0x12] = '1'; + mTranslateKeyMap[0x13] = '2'; + mTranslateKeyMap[0x14] = '3'; + mTranslateKeyMap[0x15] = '4'; + mTranslateKeyMap[0x16] = '6'; + mTranslateKeyMap[0x17] = '5'; + mTranslateKeyMap[0x18] = '='; // KEY_EQUALS + mTranslateKeyMap[0x19] = '9'; + mTranslateKeyMap[0x1a] = '7'; + mTranslateKeyMap[0x1b] = '-'; // KEY_HYPHEN + mTranslateKeyMap[0x1c] = '8'; + mTranslateKeyMap[0x1d] = '0'; + mTranslateKeyMap[0x1e] = ']'; + mTranslateKeyMap[0x1f] = 'O'; + mTranslateKeyMap[0x20] = 'U'; + mTranslateKeyMap[0x21] = '['; + mTranslateKeyMap[0x22] = 'I'; + mTranslateKeyMap[0x23] = 'P'; + mTranslateKeyMap[0x24] = KEY_RETURN, + mTranslateKeyMap[0x25] = 'L'; + mTranslateKeyMap[0x26] = 'J'; + mTranslateKeyMap[0x27] = '\''; + mTranslateKeyMap[0x28] = 'K'; + mTranslateKeyMap[0x29] = ';'; + mTranslateKeyMap[0x2a] = '\\'; + mTranslateKeyMap[0x2b] = ','; + mTranslateKeyMap[0x2c] = KEY_DIVIDE; + mTranslateKeyMap[0x2d] = 'N'; + mTranslateKeyMap[0x2e] = 'M'; + mTranslateKeyMap[0x2f] = '.'; + mTranslateKeyMap[0x30] = KEY_TAB; + mTranslateKeyMap[0x31] = ' '; // space! + mTranslateKeyMap[0x32] = '`'; + mTranslateKeyMap[0x33] = KEY_BACKSPACE; + mTranslateKeyMap[0x35] = KEY_ESCAPE; + //mTranslateKeyMap[0x37] = 0; // Command key. (not used yet) + mTranslateKeyMap[0x38] = KEY_SHIFT; + mTranslateKeyMap[0x39] = KEY_CAPSLOCK; + mTranslateKeyMap[0x3a] = KEY_ALT; + mTranslateKeyMap[0x3b] = KEY_CONTROL; + mTranslateKeyMap[0x41] = '.'; // keypad + mTranslateKeyMap[0x43] = '*'; // keypad + mTranslateKeyMap[0x45] = '+'; // keypad + mTranslateKeyMap[0x4b] = KEY_PAD_DIVIDE; // keypad + mTranslateKeyMap[0x4c] = KEY_RETURN; // keypad enter + mTranslateKeyMap[0x4e] = '-'; // keypad + mTranslateKeyMap[0x51] = '='; // keypad + mTranslateKeyMap[0x52] = '0'; // keypad + mTranslateKeyMap[0x53] = '1'; // keypad + mTranslateKeyMap[0x54] = '2'; // keypad + mTranslateKeyMap[0x55] = '3'; // keypad + mTranslateKeyMap[0x56] = '4'; // keypad + mTranslateKeyMap[0x57] = '5'; // keypad + mTranslateKeyMap[0x58] = '6'; // keypad + mTranslateKeyMap[0x59] = '7'; // keypad + mTranslateKeyMap[0x5b] = '8'; // keypad + mTranslateKeyMap[0x5c] = '9'; // keypad + mTranslateKeyMap[0x60] = KEY_F5; + mTranslateKeyMap[0x61] = KEY_F6; + mTranslateKeyMap[0x62] = KEY_F7; + mTranslateKeyMap[0x63] = KEY_F3; + mTranslateKeyMap[0x64] = KEY_F8; + mTranslateKeyMap[0x65] = KEY_F9; + mTranslateKeyMap[0x67] = KEY_F11; + mTranslateKeyMap[0x6d] = KEY_F10; + mTranslateKeyMap[0x6f] = KEY_F12; + mTranslateKeyMap[0x72] = KEY_INSERT; + mTranslateKeyMap[0x73] = KEY_HOME; + mTranslateKeyMap[0x74] = KEY_PAGE_UP; + mTranslateKeyMap[0x75] = KEY_DELETE; + mTranslateKeyMap[0x76] = KEY_F4; + mTranslateKeyMap[0x77] = KEY_END; + mTranslateKeyMap[0x78] = KEY_F2; + mTranslateKeyMap[0x79] = KEY_PAGE_DOWN; + mTranslateKeyMap[0x7a] = KEY_F1; + mTranslateKeyMap[0x7b] = KEY_LEFT; + mTranslateKeyMap[0x7c] = KEY_RIGHT; + mTranslateKeyMap[0x7d] = KEY_DOWN; + mTranslateKeyMap[0x7e] = KEY_UP; + + // Build inverse map + std::map<U16, KEY>::iterator iter; + for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) + { + mInvTranslateKeyMap[iter->second] = iter->first; + } + + // build numpad maps + mTranslateNumpadMap[0x52] = KEY_PAD_INS; // keypad 0 + mTranslateNumpadMap[0x53] = KEY_PAD_END; // keypad 1 + mTranslateNumpadMap[0x54] = KEY_PAD_DOWN; // keypad 2 + mTranslateNumpadMap[0x55] = KEY_PAD_PGDN; // keypad 3 + mTranslateNumpadMap[0x56] = KEY_PAD_LEFT; // keypad 4 + mTranslateNumpadMap[0x57] = KEY_PAD_CENTER; // keypad 5 + mTranslateNumpadMap[0x58] = KEY_PAD_RIGHT; // keypad 6 + mTranslateNumpadMap[0x59] = KEY_PAD_HOME; // keypad 7 + mTranslateNumpadMap[0x5b] = KEY_PAD_UP; // keypad 8 + mTranslateNumpadMap[0x5c] = KEY_PAD_PGUP; // keypad 9 + mTranslateNumpadMap[0x41] = KEY_PAD_DEL; // keypad . + mTranslateNumpadMap[0x4c] = KEY_PAD_RETURN; // keypad enter + + // Build inverse numpad map + for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) + { + mInvTranslateNumpadMap[iter->second] = iter->first; + } } void LLKeyboardMacOSX::resetMaskKeys() { - U32 mask = getModifiers(); - - // 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. - // Is this the way it's supposed to work? - - // We apply the modifier masks directly within getModifiers. So check to see which masks we've applied. - - if(mask & MAC_SHIFT_KEY) - { - mKeyLevel[KEY_SHIFT] = TRUE; - } - - if(mask & MAC_CTRL_KEY) - { - mKeyLevel[KEY_CONTROL] = TRUE; - } - - if(mask & MAC_ALT_KEY) - { - mKeyLevel[KEY_ALT] = TRUE; - } + U32 mask = getModifiers(); + + // 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. + // Is this the way it's supposed to work? + + // We apply the modifier masks directly within getModifiers. So check to see which masks we've applied. + + if(mask & MAC_SHIFT_KEY) + { + mKeyLevel[KEY_SHIFT] = TRUE; + } + + if(mask & MAC_CTRL_KEY) + { + mKeyLevel[KEY_CONTROL] = TRUE; + } + + if(mask & MAC_ALT_KEY) + { + mKeyLevel[KEY_ALT] = TRUE; + } } /* static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &outMask) { - // Translate the virtual keycode into the keycodes the keyboard system expects. - U16 virtualKey = (mask >> 24) & 0x0000007F; - outKey = macKeyTransArray[virtualKey]; + // Translate the virtual keycode into the keycodes the keyboard system expects. + U16 virtualKey = (mask >> 24) & 0x0000007F; + outKey = macKeyTransArray[virtualKey]; - return(outKey != 0); + return(outKey != 0); } */ void LLKeyboardMacOSX::handleModifier(MASK mask) { - updateModifiers(mask); + updateModifiers(mask); } MASK LLKeyboardMacOSX::updateModifiers(const U32 mask) { - // translate the mask - MASK out_mask = 0; + // translate the mask + MASK out_mask = 0; - if(mask & MAC_SHIFT_KEY) - { - out_mask |= MASK_SHIFT; - } + if(mask & MAC_SHIFT_KEY) + { + out_mask |= MASK_SHIFT; + } - if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY)) - { - out_mask |= MASK_CONTROL; - } + if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY)) + { + out_mask |= MASK_CONTROL; + } - if(mask & MAC_ALT_KEY) - { - out_mask |= MASK_ALT; - } + if(mask & MAC_ALT_KEY) + { + out_mask |= MASK_ALT; + } - return out_mask; + return out_mask; } BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask) { - KEY translated_key = 0; - U32 translated_mask = 0; - BOOL handled = FALSE; - - translated_mask = updateModifiers(mask); - - if(translateNumpadKey(key, &translated_key)) - { - handled = handleTranslatedKeyDown(translated_key, translated_mask); - } - - return handled; + KEY translated_key = 0; + U32 translated_mask = 0; + BOOL handled = FALSE; + + translated_mask = updateModifiers(mask); + + if(translateNumpadKey(key, &translated_key)) + { + handled = handleTranslatedKeyDown(translated_key, translated_mask); + } + + return handled; } BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask) { - KEY translated_key = 0; - U32 translated_mask = 0; - BOOL handled = FALSE; + KEY translated_key = 0; + U32 translated_mask = 0; + BOOL handled = FALSE; - translated_mask = updateModifiers(mask); + translated_mask = updateModifiers(mask); - if(translateNumpadKey(key, &translated_key)) - { - handled = handleTranslatedKeyUp(translated_key, translated_mask); - } + if(translateNumpadKey(key, &translated_key)) + { + handled = handleTranslatedKeyUp(translated_key, translated_mask); + } - return handled; + return handled; } MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event) { - MASK result = MASK_NONE; - U32 mask = getModifiers(); - - if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT; - if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL; - if (mask & MAC_ALT_KEY) result |= MASK_ALT; - - // For keyboard events, consider Command equivalent to Control - if (!for_mouse_event) - { - if (mask & MAC_CMD_KEY) result |= MASK_CONTROL; - } - - return result; + MASK result = MASK_NONE; + U32 mask = getModifiers(); + + if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT; + if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL; + if (mask & MAC_ALT_KEY) result |= MASK_ALT; + + // For keyboard events, consider Command equivalent to Control + if (!for_mouse_event) + { + if (mask & MAC_CMD_KEY) result |= MASK_CONTROL; + } + + return result; } void LLKeyboardMacOSX::scanKeyboard() { - S32 key; - for (key = 0; key < KEY_COUNT; key++) - { - // Generate callback if any event has occurred on this key this frame. - // Can't just test mKeyLevel, because this could be a slow frame and - // key might have gone down then up. JC - if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) - { - mCurScanKey = key; - mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); - } - } - - // Reset edges for next frame - for (key = 0; key < KEY_COUNT; key++) - { - mKeyUp[key] = FALSE; - mKeyDown[key] = FALSE; - if (mKeyLevel[key]) - { - mKeyLevelFrameCount[key]++; - } - } + S32 key; + for (key = 0; key < KEY_COUNT; key++) + { + // Generate callback if any event has occurred on this key this frame. + // Can't just test mKeyLevel, because this could be a slow frame and + // key might have gone down then up. JC + if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) + { + mCurScanKey = key; + mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); + } + } + + // Reset edges for next frame + for (key = 0; key < KEY_COUNT; key++) + { + mKeyUp[key] = FALSE; + mKeyDown[key] = FALSE; + if (mKeyLevel[key]) + { + mKeyLevelFrameCount[key]++; + } + } } BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key ) { - return translateKey(os_key, translated_key); + return translateKey(os_key, translated_key); } -U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key) +U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key) { - return inverseTranslateKey(translated_key); + return inverseTranslateKey(translated_key); } #endif // LL_DARWIN diff --git a/indra/llwindow/llkeyboardmacosx.h b/indra/llwindow/llkeyboardmacosx.h index f9d014ab70..d6895f684d 100644 --- a/indra/llwindow/llkeyboardmacosx.h +++ b/indra/llwindow/llkeyboardmacosx.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardmacosx.h * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,34 +31,34 @@ // These more or less mirror their equivalents in NSEvent.h. enum EMacEventKeys { - MAC_SHIFT_KEY = 1 << 17, - MAC_CTRL_KEY = 1 << 18, - MAC_ALT_KEY = 1 << 19, - MAC_CMD_KEY = 1 << 20, - MAC_FN_KEY = 1 << 23 + MAC_SHIFT_KEY = 1 << 17, + MAC_CTRL_KEY = 1 << 18, + MAC_ALT_KEY = 1 << 19, + MAC_CMD_KEY = 1 << 20, + MAC_FN_KEY = 1 << 23 }; class LLKeyboardMacOSX : public LLKeyboard { public: - LLKeyboardMacOSX(); - /*virtual*/ ~LLKeyboardMacOSX() {}; - - /*virtual*/ BOOL handleKeyUp(const U16 key, MASK mask); - /*virtual*/ BOOL handleKeyDown(const U16 key, MASK mask); - /*virtual*/ void resetMaskKeys(); - /*virtual*/ MASK currentMask(BOOL for_mouse_event); - /*virtual*/ void scanKeyboard(); - /*virtual*/ void handleModifier(MASK mask); - + LLKeyboardMacOSX(); + /*virtual*/ ~LLKeyboardMacOSX() {}; + + /*virtual*/ BOOL handleKeyUp(const U16 key, MASK mask); + /*virtual*/ BOOL handleKeyDown(const U16 key, MASK mask); + /*virtual*/ void resetMaskKeys(); + /*virtual*/ MASK currentMask(BOOL for_mouse_event); + /*virtual*/ void scanKeyboard(); + /*virtual*/ void handleModifier(MASK mask); + protected: - MASK updateModifiers(const U32 mask); - void setModifierKeyLevel( KEY key, BOOL new_state ); - BOOL translateNumpadKey( const U16 os_key, KEY *translated_key ); - U16 inverseTranslateNumpadKey(const KEY translated_key); + MASK updateModifiers(const U32 mask); + void setModifierKeyLevel( KEY key, BOOL new_state ); + BOOL translateNumpadKey( const U16 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<U16, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys + std::map<KEY, U16> mInvTranslateNumpadMap; // inverse of the above }; #endif diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index d7c6656df8..d1e5cd6c5a 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardsdl.cpp * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,299 +33,299 @@ LLKeyboardSDL::LLKeyboardSDL() { - // Set up key mapping for SDL - eventually can read this from a file? - // Anything not in the key map gets dropped - // Add default A-Z - - // Virtual key mappings from SDL_keysym.h ... - - // SDL maps the letter keys to the ASCII you'd expect, but it's lowercase... - U32 cur_char; - for (cur_char = 'A'; cur_char <= 'Z'; cur_char++) - { - mTranslateKeyMap[cur_char] = cur_char; - } - for (cur_char = 'a'; cur_char <= 'z'; cur_char++) - { - mTranslateKeyMap[cur_char] = (cur_char - 'a') + 'A'; - } - - for (cur_char = '0'; cur_char <= '9'; cur_char++) - { - mTranslateKeyMap[cur_char] = cur_char; - } - - // These ones are translated manually upon keydown/keyup because - // SDL doesn't handle their numlock transition. - //mTranslateKeyMap[SDLK_KP_4] = KEY_PAD_LEFT; - //mTranslateKeyMap[SDLK_KP_6] = KEY_PAD_RIGHT; - //mTranslateKeyMap[SDLK_KP_8] = KEY_PAD_UP; - //mTranslateKeyMap[SDLK_KP_2] = KEY_PAD_DOWN; - //mTranslateKeyMap[SDLK_KP_PERIOD] = KEY_DELETE; - //mTranslateKeyMap[SDLK_KP_7] = KEY_HOME; - //mTranslateKeyMap[SDLK_KP_1] = KEY_END; - //mTranslateKeyMap[SDLK_KP_9] = KEY_PAGE_UP; - //mTranslateKeyMap[SDLK_KP_3] = KEY_PAGE_DOWN; - //mTranslateKeyMap[SDLK_KP_0] = KEY_INSERT; - - mTranslateKeyMap[SDLK_SPACE] = ' '; - 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; - mTranslateKeyMap[SDLK_DELETE] = KEY_DELETE; - mTranslateKeyMap[SDLK_LSHIFT] = KEY_SHIFT; - mTranslateKeyMap[SDLK_RSHIFT] = KEY_SHIFT; - mTranslateKeyMap[SDLK_LCTRL] = KEY_CONTROL; - mTranslateKeyMap[SDLK_RCTRL] = KEY_CONTROL; - mTranslateKeyMap[SDLK_LALT] = KEY_ALT; - mTranslateKeyMap[SDLK_RALT] = KEY_ALT; - mTranslateKeyMap[SDLK_HOME] = KEY_HOME; - mTranslateKeyMap[SDLK_END] = KEY_END; - mTranslateKeyMap[SDLK_PAGEUP] = KEY_PAGE_UP; - mTranslateKeyMap[SDLK_PAGEDOWN] = KEY_PAGE_DOWN; - mTranslateKeyMap[SDLK_MINUS] = KEY_HYPHEN; - mTranslateKeyMap[SDLK_EQUALS] = KEY_EQUALS; - mTranslateKeyMap[SDLK_KP_EQUALS] = KEY_EQUALS; - mTranslateKeyMap[SDLK_INSERT] = KEY_INSERT; - mTranslateKeyMap[SDLK_CAPSLOCK] = KEY_CAPSLOCK; - mTranslateKeyMap[SDLK_TAB] = KEY_TAB; - mTranslateKeyMap[SDLK_KP_PLUS] = KEY_ADD; - mTranslateKeyMap[SDLK_KP_MINUS] = KEY_SUBTRACT; - mTranslateKeyMap[SDLK_KP_MULTIPLY] = KEY_MULTIPLY; - mTranslateKeyMap[SDLK_KP_DIVIDE] = KEY_PAD_DIVIDE; - mTranslateKeyMap[SDLK_F1] = KEY_F1; - mTranslateKeyMap[SDLK_F2] = KEY_F2; - mTranslateKeyMap[SDLK_F3] = KEY_F3; - mTranslateKeyMap[SDLK_F4] = KEY_F4; - mTranslateKeyMap[SDLK_F5] = KEY_F5; - mTranslateKeyMap[SDLK_F6] = KEY_F6; - mTranslateKeyMap[SDLK_F7] = KEY_F7; - mTranslateKeyMap[SDLK_F8] = KEY_F8; - mTranslateKeyMap[SDLK_F9] = KEY_F9; - 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] = '\''; - - // Build inverse map - std::map<U32, KEY>::iterator iter; - for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) - { - mInvTranslateKeyMap[iter->second] = iter->first; - } - - // numpad map - 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(); - iter != mTranslateNumpadMap.end(); - iter++) - { - mInvTranslateNumpadMap[iter->second] = iter->first; - } + // Set up key mapping for SDL - eventually can read this from a file? + // Anything not in the key map gets dropped + // Add default A-Z + + // Virtual key mappings from SDL_keysym.h ... + + // SDL maps the letter keys to the ASCII you'd expect, but it's lowercase... + U32 cur_char; + for (cur_char = 'A'; cur_char <= 'Z'; cur_char++) + { + mTranslateKeyMap[cur_char] = cur_char; + } + for (cur_char = 'a'; cur_char <= 'z'; cur_char++) + { + mTranslateKeyMap[cur_char] = (cur_char - 'a') + 'A'; + } + + for (cur_char = '0'; cur_char <= '9'; cur_char++) + { + mTranslateKeyMap[cur_char] = cur_char; + } + + // These ones are translated manually upon keydown/keyup because + // SDL doesn't handle their numlock transition. + //mTranslateKeyMap[SDLK_KP_4] = KEY_PAD_LEFT; + //mTranslateKeyMap[SDLK_KP_6] = KEY_PAD_RIGHT; + //mTranslateKeyMap[SDLK_KP_8] = KEY_PAD_UP; + //mTranslateKeyMap[SDLK_KP_2] = KEY_PAD_DOWN; + //mTranslateKeyMap[SDLK_KP_PERIOD] = KEY_DELETE; + //mTranslateKeyMap[SDLK_KP_7] = KEY_HOME; + //mTranslateKeyMap[SDLK_KP_1] = KEY_END; + //mTranslateKeyMap[SDLK_KP_9] = KEY_PAGE_UP; + //mTranslateKeyMap[SDLK_KP_3] = KEY_PAGE_DOWN; + //mTranslateKeyMap[SDLK_KP_0] = KEY_INSERT; + + mTranslateKeyMap[SDLK_SPACE] = ' '; + 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; + mTranslateKeyMap[SDLK_DELETE] = KEY_DELETE; + mTranslateKeyMap[SDLK_LSHIFT] = KEY_SHIFT; + mTranslateKeyMap[SDLK_RSHIFT] = KEY_SHIFT; + mTranslateKeyMap[SDLK_LCTRL] = KEY_CONTROL; + mTranslateKeyMap[SDLK_RCTRL] = KEY_CONTROL; + mTranslateKeyMap[SDLK_LALT] = KEY_ALT; + mTranslateKeyMap[SDLK_RALT] = KEY_ALT; + mTranslateKeyMap[SDLK_HOME] = KEY_HOME; + mTranslateKeyMap[SDLK_END] = KEY_END; + mTranslateKeyMap[SDLK_PAGEUP] = KEY_PAGE_UP; + mTranslateKeyMap[SDLK_PAGEDOWN] = KEY_PAGE_DOWN; + mTranslateKeyMap[SDLK_MINUS] = KEY_HYPHEN; + mTranslateKeyMap[SDLK_EQUALS] = KEY_EQUALS; + mTranslateKeyMap[SDLK_KP_EQUALS] = KEY_EQUALS; + mTranslateKeyMap[SDLK_INSERT] = KEY_INSERT; + mTranslateKeyMap[SDLK_CAPSLOCK] = KEY_CAPSLOCK; + mTranslateKeyMap[SDLK_TAB] = KEY_TAB; + mTranslateKeyMap[SDLK_KP_PLUS] = KEY_ADD; + mTranslateKeyMap[SDLK_KP_MINUS] = KEY_SUBTRACT; + mTranslateKeyMap[SDLK_KP_MULTIPLY] = KEY_MULTIPLY; + mTranslateKeyMap[SDLK_KP_DIVIDE] = KEY_PAD_DIVIDE; + mTranslateKeyMap[SDLK_F1] = KEY_F1; + mTranslateKeyMap[SDLK_F2] = KEY_F2; + mTranslateKeyMap[SDLK_F3] = KEY_F3; + mTranslateKeyMap[SDLK_F4] = KEY_F4; + mTranslateKeyMap[SDLK_F5] = KEY_F5; + mTranslateKeyMap[SDLK_F6] = KEY_F6; + mTranslateKeyMap[SDLK_F7] = KEY_F7; + mTranslateKeyMap[SDLK_F8] = KEY_F8; + mTranslateKeyMap[SDLK_F9] = KEY_F9; + 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] = '\''; + + // Build inverse map + std::map<U32, KEY>::iterator iter; + for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) + { + mInvTranslateKeyMap[iter->second] = iter->first; + } + + // numpad map + 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(); + iter != mTranslateNumpadMap.end(); + iter++) + { + mInvTranslateNumpadMap[iter->second] = iter->first; + } } void LLKeyboardSDL::resetMaskKeys() { - SDL_Keymod 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. - // Is this the way it's supposed to work? + // 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. + // Is this the way it's supposed to work? - if(mask & KMOD_SHIFT) - { - mKeyLevel[KEY_SHIFT] = TRUE; - } + if(mask & KMOD_SHIFT) + { + mKeyLevel[KEY_SHIFT] = TRUE; + } - if(mask & (KMOD_CTRL + if(mask & (KMOD_CTRL #ifdef LL_DARWIN - | KMOD_GUI + | KMOD_GUI #endif - )) - { - mKeyLevel[KEY_CONTROL] = TRUE; - } - - if(mask & KMOD_ALT) - { - mKeyLevel[KEY_ALT] = TRUE; - } + )) + { + mKeyLevel[KEY_CONTROL] = TRUE; + } + + if(mask & KMOD_ALT) + { + mKeyLevel[KEY_ALT] = TRUE; + } } MASK LLKeyboardSDL::updateModifiers(const U32 mask) { - // translate the mask - MASK out_mask = MASK_NONE; + // translate the mask + MASK out_mask = MASK_NONE; - if(mask & KMOD_SHIFT) - { - out_mask |= MASK_SHIFT; - } + if(mask & KMOD_SHIFT) + { + out_mask |= MASK_SHIFT; + } - if(mask & (KMOD_CTRL + if(mask & (KMOD_CTRL #ifdef LL_DARWIN - | KMOD_GUI + | KMOD_GUI #endif - )) - { - out_mask |= MASK_CONTROL; - } + )) + { + out_mask |= MASK_CONTROL; + } - if(mask & KMOD_ALT) - { - out_mask |= MASK_ALT; - } + if(mask & KMOD_ALT) + { + out_mask |= MASK_ALT; + } - return out_mask; + return out_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. - U32 rtn = key; - if (!(mask & KMOD_NUM)) - { - switch (key) - { - 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; + // SDL doesn't automatically adjust the keysym according to + // whether NUMLOCK is engaged, so we massage the keysym manually. + U32 rtn = key; + if (!(mask & KMOD_NUM)) + { + switch (key) + { + 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 U32 key, const U32 mask) { - U32 adjusted_nativekey; - KEY translated_key = 0; - U32 translated_mask = MASK_NONE; - BOOL handled = FALSE; + U32 adjusted_nativekey; + KEY translated_key = 0; + U32 translated_mask = MASK_NONE; + BOOL handled = FALSE; + + adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); - adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); + translated_mask = updateModifiers(mask); - translated_mask = updateModifiers(mask); - - if(translateNumpadKey(adjusted_nativekey, &translated_key)) - { - handled = handleTranslatedKeyDown(translated_key, translated_mask); - } + if(translateNumpadKey(adjusted_nativekey, &translated_key)) + { + handled = handleTranslatedKeyDown(translated_key, translated_mask); + } - return handled; + return handled; } BOOL LLKeyboardSDL::handleKeyUp(const U32 key, const U32 mask) { - U32 adjusted_nativekey; - KEY translated_key = 0; - U32 translated_mask = MASK_NONE; - BOOL handled = FALSE; + U32 adjusted_nativekey; + KEY translated_key = 0; + U32 translated_mask = MASK_NONE; + BOOL handled = FALSE; - adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); + adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); - translated_mask = updateModifiers(mask); + translated_mask = updateModifiers(mask); - if(translateNumpadKey(adjusted_nativekey, &translated_key)) - { - handled = handleTranslatedKeyUp(translated_key, translated_mask); - } + if(translateNumpadKey(adjusted_nativekey, &translated_key)) + { + handled = handleTranslatedKeyUp(translated_key, translated_mask); + } - return handled; + return handled; } MASK LLKeyboardSDL::currentMask(BOOL for_mouse_event) { - MASK result = MASK_NONE; - SDL_Keymod mask = SDL_GetModState(); + MASK result = MASK_NONE; + 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_GUI) result |= MASK_CONTROL; - } + // For keyboard events, consider Meta keys equivalent to Control + if (!for_mouse_event) + { + if (mask & KMOD_GUI) result |= MASK_CONTROL; + } - return result; + return result; } void LLKeyboardSDL::scanKeyboard() { - for (S32 key = 0; key < KEY_COUNT; key++) - { - // Generate callback if any event has occurred on this key this frame. - // Can't just test mKeyLevel, because this could be a slow frame and - // key might have gone down then up. JC - if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) - { - mCurScanKey = key; - mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); - } - } - - // Reset edges for next frame - for (S32 key = 0; key < KEY_COUNT; key++) - { - mKeyUp[key] = FALSE; - mKeyDown[key] = FALSE; - if (mKeyLevel[key]) - { - mKeyLevelFrameCount[key]++; - } - } + for (S32 key = 0; key < KEY_COUNT; key++) + { + // Generate callback if any event has occurred on this key this frame. + // Can't just test mKeyLevel, because this could be a slow frame and + // key might have gone down then up. JC + if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) + { + mCurScanKey = key; + mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); + } + } + + // Reset edges for next frame + for (S32 key = 0; key < KEY_COUNT; key++) + { + mKeyUp[key] = FALSE; + mKeyDown[key] = FALSE; + if (mKeyLevel[key]) + { + mKeyLevelFrameCount[key]++; + } + } } - + BOOL LLKeyboardSDL::translateNumpadKey( const U32 os_key, KEY *translated_key) { - return translateKey(os_key, translated_key); + return translateKey(os_key, translated_key); } U32 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) { - return inverseTranslateKey(translated_key); + return inverseTranslateKey(translated_key); } #endif diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h index 43f8e1ccb4..ac6e9f2cef 100644 --- a/indra/llwindow/llkeyboardsdl.h +++ b/indra/llwindow/llkeyboardsdl.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardsdl.h * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,23 +36,23 @@ class LLKeyboardSDL : public LLKeyboard { public: - LLKeyboardSDL(); - /*virtual*/ ~LLKeyboardSDL() {}; + LLKeyboardSDL(); + /*virtual*/ ~LLKeyboardSDL() {}; - /*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(); + /*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(); protected: - MASK updateModifiers(const U32 mask); - void setModifierKeyLevel( KEY key, BOOL new_state ); - BOOL translateNumpadKey( const U32 os_key, KEY *translated_key ); - U32 inverseTranslateNumpadKey(const KEY translated_key); + MASK updateModifiers(const U32 mask); + void setModifierKeyLevel( KEY key, BOOL new_state ); + BOOL translateNumpadKey( const U32 os_key, KEY *translated_key ); + U32 inverseTranslateNumpadKey(const KEY translated_key); private: - std::map<U32, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys - std::map<KEY, U32> 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 }; #endif diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index 4c207faa81..4934e21d55 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardwin32.cpp * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,110 +37,110 @@ LLKeyboardWin32::LLKeyboardWin32() { - // Set up key mapping for windows - eventually can read this from a file? - // Anything not in the key map gets dropped - // Add default A-Z - - // Virtual key mappings from WinUser.h - - KEY cur_char; - for (cur_char = 'A'; cur_char <= 'Z'; cur_char++) - { - mTranslateKeyMap[cur_char] = (KEY)cur_char; - } - - for (cur_char = '0'; cur_char <= '9'; cur_char++) - { - mTranslateKeyMap[cur_char] = (KEY)cur_char; - } - // numpad number keys - for (cur_char = 0x60; cur_char <= 0x69; cur_char++) - { - mTranslateKeyMap[cur_char] = (KEY)('0' + (cur_char - 0x60)); - } - - - mTranslateKeyMap[VK_SPACE] = ' '; - mTranslateKeyMap[VK_OEM_1] = ';'; - // When the user hits, for example, Ctrl-= as a keyboard shortcut, - // Windows generates VK_OEM_PLUS. This is true on both QWERTY and DVORAK - // keyboards in the US. Numeric keypad '+' generates VK_ADD below. - // Thus we translate it as '='. - // Potential bug: This may not be true on international keyboards. JC - mTranslateKeyMap[VK_OEM_PLUS] = '='; - mTranslateKeyMap[VK_OEM_COMMA] = ','; - mTranslateKeyMap[VK_OEM_MINUS] = '-'; - mTranslateKeyMap[VK_OEM_PERIOD] = '.'; - mTranslateKeyMap[VK_OEM_2] = '/';//This used to be KEY_PAD_DIVIDE, but that breaks typing into text fields in media prims - mTranslateKeyMap[VK_OEM_3] = '`'; - mTranslateKeyMap[VK_OEM_4] = '['; - mTranslateKeyMap[VK_OEM_5] = '\\'; - mTranslateKeyMap[VK_OEM_6] = ']'; - mTranslateKeyMap[VK_OEM_7] = '\''; - mTranslateKeyMap[VK_ESCAPE] = KEY_ESCAPE; - mTranslateKeyMap[VK_RETURN] = KEY_RETURN; - mTranslateKeyMap[VK_LEFT] = KEY_LEFT; - mTranslateKeyMap[VK_RIGHT] = KEY_RIGHT; - mTranslateKeyMap[VK_UP] = KEY_UP; - mTranslateKeyMap[VK_DOWN] = KEY_DOWN; - mTranslateKeyMap[VK_BACK] = KEY_BACKSPACE; - mTranslateKeyMap[VK_INSERT] = KEY_INSERT; - mTranslateKeyMap[VK_DELETE] = KEY_DELETE; - mTranslateKeyMap[VK_SHIFT] = KEY_SHIFT; - mTranslateKeyMap[VK_CONTROL] = KEY_CONTROL; - mTranslateKeyMap[VK_MENU] = KEY_ALT; - mTranslateKeyMap[VK_CAPITAL] = KEY_CAPSLOCK; - mTranslateKeyMap[VK_HOME] = KEY_HOME; - mTranslateKeyMap[VK_END] = KEY_END; - mTranslateKeyMap[VK_PRIOR] = KEY_PAGE_UP; - mTranslateKeyMap[VK_NEXT] = KEY_PAGE_DOWN; - mTranslateKeyMap[VK_TAB] = KEY_TAB; - mTranslateKeyMap[VK_ADD] = KEY_ADD; - mTranslateKeyMap[VK_SUBTRACT] = KEY_SUBTRACT; - mTranslateKeyMap[VK_MULTIPLY] = KEY_MULTIPLY; - mTranslateKeyMap[VK_DIVIDE] = KEY_DIVIDE; - mTranslateKeyMap[VK_F1] = KEY_F1; - mTranslateKeyMap[VK_F2] = KEY_F2; - mTranslateKeyMap[VK_F3] = KEY_F3; - mTranslateKeyMap[VK_F4] = KEY_F4; - mTranslateKeyMap[VK_F5] = KEY_F5; - mTranslateKeyMap[VK_F6] = KEY_F6; - mTranslateKeyMap[VK_F7] = KEY_F7; - mTranslateKeyMap[VK_F8] = KEY_F8; - mTranslateKeyMap[VK_F9] = KEY_F9; - mTranslateKeyMap[VK_F10] = KEY_F10; - mTranslateKeyMap[VK_F11] = KEY_F11; - mTranslateKeyMap[VK_F12] = KEY_F12; - mTranslateKeyMap[VK_CLEAR] = KEY_PAD_CENTER; - - // Build inverse map - std::map<U16, KEY>::iterator iter; - for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) - { - mInvTranslateKeyMap[iter->second] = iter->first; - } - - // numpad map - mTranslateNumpadMap[0x60] = KEY_PAD_INS; // keypad 0 - mTranslateNumpadMap[0x61] = KEY_PAD_END; // keypad 1 - mTranslateNumpadMap[0x62] = KEY_PAD_DOWN; // keypad 2 - mTranslateNumpadMap[0x63] = KEY_PAD_PGDN; // keypad 3 - mTranslateNumpadMap[0x64] = KEY_PAD_LEFT; // keypad 4 - mTranslateNumpadMap[0x65] = KEY_PAD_CENTER; // keypad 5 - mTranslateNumpadMap[0x66] = KEY_PAD_RIGHT; // keypad 6 - mTranslateNumpadMap[0x67] = KEY_PAD_HOME; // keypad 7 - mTranslateNumpadMap[0x68] = KEY_PAD_UP; // keypad 8 - mTranslateNumpadMap[0x69] = KEY_PAD_PGUP; // keypad 9 - mTranslateNumpadMap[0x6A] = KEY_PAD_MULTIPLY; // keypad * - mTranslateNumpadMap[0x6B] = KEY_PAD_ADD; // keypad + - mTranslateNumpadMap[0x6D] = KEY_PAD_SUBTRACT; // keypad - - mTranslateNumpadMap[0x6E] = KEY_PAD_DEL; // keypad . - mTranslateNumpadMap[0x6F] = KEY_PAD_DIVIDE; // keypad / - - for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) - { - mInvTranslateNumpadMap[iter->second] = iter->first; - } + // Set up key mapping for windows - eventually can read this from a file? + // Anything not in the key map gets dropped + // Add default A-Z + + // Virtual key mappings from WinUser.h + + KEY cur_char; + for (cur_char = 'A'; cur_char <= 'Z'; cur_char++) + { + mTranslateKeyMap[cur_char] = (KEY)cur_char; + } + + for (cur_char = '0'; cur_char <= '9'; cur_char++) + { + mTranslateKeyMap[cur_char] = (KEY)cur_char; + } + // numpad number keys + for (cur_char = 0x60; cur_char <= 0x69; cur_char++) + { + mTranslateKeyMap[cur_char] = (KEY)('0' + (cur_char - 0x60)); + } + + + mTranslateKeyMap[VK_SPACE] = ' '; + mTranslateKeyMap[VK_OEM_1] = ';'; + // When the user hits, for example, Ctrl-= as a keyboard shortcut, + // Windows generates VK_OEM_PLUS. This is true on both QWERTY and DVORAK + // keyboards in the US. Numeric keypad '+' generates VK_ADD below. + // Thus we translate it as '='. + // Potential bug: This may not be true on international keyboards. JC + mTranslateKeyMap[VK_OEM_PLUS] = '='; + mTranslateKeyMap[VK_OEM_COMMA] = ','; + mTranslateKeyMap[VK_OEM_MINUS] = '-'; + mTranslateKeyMap[VK_OEM_PERIOD] = '.'; + mTranslateKeyMap[VK_OEM_2] = '/';//This used to be KEY_PAD_DIVIDE, but that breaks typing into text fields in media prims + mTranslateKeyMap[VK_OEM_3] = '`'; + mTranslateKeyMap[VK_OEM_4] = '['; + mTranslateKeyMap[VK_OEM_5] = '\\'; + mTranslateKeyMap[VK_OEM_6] = ']'; + mTranslateKeyMap[VK_OEM_7] = '\''; + mTranslateKeyMap[VK_ESCAPE] = KEY_ESCAPE; + mTranslateKeyMap[VK_RETURN] = KEY_RETURN; + mTranslateKeyMap[VK_LEFT] = KEY_LEFT; + mTranslateKeyMap[VK_RIGHT] = KEY_RIGHT; + mTranslateKeyMap[VK_UP] = KEY_UP; + mTranslateKeyMap[VK_DOWN] = KEY_DOWN; + mTranslateKeyMap[VK_BACK] = KEY_BACKSPACE; + mTranslateKeyMap[VK_INSERT] = KEY_INSERT; + mTranslateKeyMap[VK_DELETE] = KEY_DELETE; + mTranslateKeyMap[VK_SHIFT] = KEY_SHIFT; + mTranslateKeyMap[VK_CONTROL] = KEY_CONTROL; + mTranslateKeyMap[VK_MENU] = KEY_ALT; + mTranslateKeyMap[VK_CAPITAL] = KEY_CAPSLOCK; + mTranslateKeyMap[VK_HOME] = KEY_HOME; + mTranslateKeyMap[VK_END] = KEY_END; + mTranslateKeyMap[VK_PRIOR] = KEY_PAGE_UP; + mTranslateKeyMap[VK_NEXT] = KEY_PAGE_DOWN; + mTranslateKeyMap[VK_TAB] = KEY_TAB; + mTranslateKeyMap[VK_ADD] = KEY_ADD; + mTranslateKeyMap[VK_SUBTRACT] = KEY_SUBTRACT; + mTranslateKeyMap[VK_MULTIPLY] = KEY_MULTIPLY; + mTranslateKeyMap[VK_DIVIDE] = KEY_DIVIDE; + mTranslateKeyMap[VK_F1] = KEY_F1; + mTranslateKeyMap[VK_F2] = KEY_F2; + mTranslateKeyMap[VK_F3] = KEY_F3; + mTranslateKeyMap[VK_F4] = KEY_F4; + mTranslateKeyMap[VK_F5] = KEY_F5; + mTranslateKeyMap[VK_F6] = KEY_F6; + mTranslateKeyMap[VK_F7] = KEY_F7; + mTranslateKeyMap[VK_F8] = KEY_F8; + mTranslateKeyMap[VK_F9] = KEY_F9; + mTranslateKeyMap[VK_F10] = KEY_F10; + mTranslateKeyMap[VK_F11] = KEY_F11; + mTranslateKeyMap[VK_F12] = KEY_F12; + mTranslateKeyMap[VK_CLEAR] = KEY_PAD_CENTER; + + // Build inverse map + std::map<U16, KEY>::iterator iter; + for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) + { + mInvTranslateKeyMap[iter->second] = iter->first; + } + + // numpad map + mTranslateNumpadMap[0x60] = KEY_PAD_INS; // keypad 0 + mTranslateNumpadMap[0x61] = KEY_PAD_END; // keypad 1 + mTranslateNumpadMap[0x62] = KEY_PAD_DOWN; // keypad 2 + mTranslateNumpadMap[0x63] = KEY_PAD_PGDN; // keypad 3 + mTranslateNumpadMap[0x64] = KEY_PAD_LEFT; // keypad 4 + mTranslateNumpadMap[0x65] = KEY_PAD_CENTER; // keypad 5 + mTranslateNumpadMap[0x66] = KEY_PAD_RIGHT; // keypad 6 + mTranslateNumpadMap[0x67] = KEY_PAD_HOME; // keypad 7 + mTranslateNumpadMap[0x68] = KEY_PAD_UP; // keypad 8 + mTranslateNumpadMap[0x69] = KEY_PAD_PGUP; // keypad 9 + mTranslateNumpadMap[0x6A] = KEY_PAD_MULTIPLY; // keypad * + mTranslateNumpadMap[0x6B] = KEY_PAD_ADD; // keypad + + mTranslateNumpadMap[0x6D] = KEY_PAD_SUBTRACT; // keypad - + mTranslateNumpadMap[0x6E] = KEY_PAD_DEL; // keypad . + mTranslateNumpadMap[0x6F] = KEY_PAD_DIVIDE; // keypad / + + for (iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) + { + mInvTranslateNumpadMap[iter->second] = iter->first; + } } // Asynchronously poll the control, alt and shift keys and set the @@ -148,177 +148,177 @@ LLKeyboardWin32::LLKeyboardWin32() // Note: this does not generate edges. void LLKeyboardWin32::resetMaskKeys() { - // GetAsyncKeyState returns a short and uses the most significant - // bit to indicate that the key is down. - if (GetAsyncKeyState(VK_SHIFT) & 0x8000) - { - mKeyLevel[KEY_SHIFT] = TRUE; - } - - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) - { - mKeyLevel[KEY_CONTROL] = TRUE; - } - - if (GetAsyncKeyState(VK_MENU) & 0x8000) - { - mKeyLevel[KEY_ALT] = TRUE; - } + // GetAsyncKeyState returns a short and uses the most significant + // bit to indicate that the key is down. + if (GetAsyncKeyState(VK_SHIFT) & 0x8000) + { + mKeyLevel[KEY_SHIFT] = TRUE; + } + + if (GetAsyncKeyState(VK_CONTROL) & 0x8000) + { + mKeyLevel[KEY_CONTROL] = TRUE; + } + + if (GetAsyncKeyState(VK_MENU) & 0x8000) + { + mKeyLevel[KEY_ALT] = TRUE; + } } //void LLKeyboardWin32::setModifierKeyLevel( KEY key, BOOL new_state ) //{ -// if( mKeyLevel[key] != new_state ) -// { -// mKeyLevelFrameCount[key] = 0; +// if( mKeyLevel[key] != new_state ) +// { +// mKeyLevelFrameCount[key] = 0; // -// if( new_state ) -// { -// mKeyLevelTimer[key].reset(); -// } -// mKeyLevel[key] = new_state; -// } +// if( new_state ) +// { +// mKeyLevelTimer[key].reset(); +// } +// mKeyLevel[key] = new_state; +// } //} MASK LLKeyboardWin32::updateModifiers() { - //RN: this seems redundant, as we should have already received the appropriate - // messages for the modifier keys - - // Scan the modifier keys as of the last Windows key message - // (keydown encoded in high order bit of short) - mKeyLevel[KEY_CAPSLOCK] = (GetKeyState(VK_CAPITAL) & 0x0001) != 0; // Low order bit carries the toggle state. - // Get mask for keyboard events - MASK mask = currentMask(FALSE); - return mask; + //RN: this seems redundant, as we should have already received the appropriate + // messages for the modifier keys + + // Scan the modifier keys as of the last Windows key message + // (keydown encoded in high order bit of short) + mKeyLevel[KEY_CAPSLOCK] = (GetKeyState(VK_CAPITAL) & 0x0001) != 0; // Low order bit carries the toggle state. + // Get mask for keyboard events + MASK mask = currentMask(FALSE); + return mask; } // mask is ignored, except for extended flag -- we poll the modifier keys for the other flags BOOL LLKeyboardWin32::handleKeyDown(const U16 key, MASK mask) { - KEY translated_key; - U32 translated_mask; - BOOL handled = FALSE; + KEY translated_key; + U32 translated_mask; + BOOL handled = FALSE; - translated_mask = updateModifiers(); + translated_mask = updateModifiers(); - if (translateExtendedKey(key, mask, &translated_key)) - { - handled = handleTranslatedKeyDown(translated_key, translated_mask); - } + if (translateExtendedKey(key, mask, &translated_key)) + { + handled = handleTranslatedKeyDown(translated_key, translated_mask); + } - return handled; + return handled; } // mask is ignored, except for extended flag -- we poll the modifier keys for the other flags BOOL LLKeyboardWin32::handleKeyUp(const U16 key, MASK mask) { - KEY translated_key; - U32 translated_mask; - BOOL handled = FALSE; + KEY translated_key; + U32 translated_mask; + BOOL handled = FALSE; - translated_mask = updateModifiers(); + translated_mask = updateModifiers(); - if (translateExtendedKey(key, mask, &translated_key)) - { - handled = handleTranslatedKeyUp(translated_key, translated_mask); - } + if (translateExtendedKey(key, mask, &translated_key)) + { + handled = handleTranslatedKeyUp(translated_key, translated_mask); + } - return handled; + return handled; } MASK LLKeyboardWin32::currentMask(BOOL) { - MASK mask = MASK_NONE; + MASK mask = MASK_NONE; - if (mKeyLevel[KEY_SHIFT]) mask |= MASK_SHIFT; - if (mKeyLevel[KEY_CONTROL]) mask |= MASK_CONTROL; - if (mKeyLevel[KEY_ALT]) mask |= MASK_ALT; + if (mKeyLevel[KEY_SHIFT]) mask |= MASK_SHIFT; + if (mKeyLevel[KEY_CONTROL]) mask |= MASK_CONTROL; + if (mKeyLevel[KEY_ALT]) mask |= MASK_ALT; - return mask; + return mask; } void LLKeyboardWin32::scanKeyboard() { - S32 key; - MSG msg; - PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD); - for (key = 0; key < KEY_COUNT; key++) - { - // Generate callback if any event has occurred on this key this frame. - // Can't just test mKeyLevel, because this could be a slow frame and - // key might have gone down then up. JC - if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) - { - mCurScanKey = key; - mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); - } - } - - // Reset edges for next frame - for (key = 0; key < KEY_COUNT; key++) - { - mKeyUp[key] = FALSE; - mKeyDown[key] = FALSE; - if (mKeyLevel[key]) - { - mKeyLevelFrameCount[key]++; - } - } + S32 key; + MSG msg; + PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD); + for (key = 0; key < KEY_COUNT; key++) + { + // Generate callback if any event has occurred on this key this frame. + // Can't just test mKeyLevel, because this could be a slow frame and + // key might have gone down then up. JC + if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) + { + mCurScanKey = key; + mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); + } + } + + // Reset edges for next frame + for (key = 0; key < KEY_COUNT; key++) + { + mKeyUp[key] = FALSE; + mKeyDown[key] = FALSE; + if (mKeyLevel[key]) + { + mKeyLevelFrameCount[key]++; + } + } } BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key) { - return translateKey(os_key, translated_key); + return translateKey(os_key, translated_key); } U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key) { - // if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number - if(GetKeyState(VK_NUMLOCK) & 1) - { - std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key); - if (iter != mInvTranslateNumpadMap.end()) - { - return iter->second; - } - } - - // if numlock is off or we're not converting numbers to arrows, we map our keypad arrows - // to regular arrows since Windows doesn't distinguish between them - KEY converted_key = translated_key; - switch (converted_key) - { - case KEY_PAD_LEFT: - converted_key = KEY_LEFT; break; - case KEY_PAD_RIGHT: - converted_key = KEY_RIGHT; break; - case KEY_PAD_UP: - converted_key = KEY_UP; break; - case KEY_PAD_DOWN: - converted_key = KEY_DOWN; break; - case KEY_PAD_HOME: - converted_key = KEY_HOME; break; - case KEY_PAD_END: - converted_key = KEY_END; break; - case KEY_PAD_PGUP: - converted_key = KEY_PAGE_UP; break; - case KEY_PAD_PGDN: - converted_key = KEY_PAGE_DOWN; break; - case KEY_PAD_INS: - converted_key = KEY_INSERT; break; - case KEY_PAD_DEL: - converted_key = KEY_DELETE; break; - case KEY_PAD_RETURN: - converted_key = KEY_RETURN; break; - } - // convert our virtual keys to OS keys - return inverseTranslateKey(converted_key); + // if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number + if(GetKeyState(VK_NUMLOCK) & 1) + { + std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key); + if (iter != mInvTranslateNumpadMap.end()) + { + return iter->second; + } + } + + // if numlock is off or we're not converting numbers to arrows, we map our keypad arrows + // to regular arrows since Windows doesn't distinguish between them + KEY converted_key = translated_key; + switch (converted_key) + { + case KEY_PAD_LEFT: + converted_key = KEY_LEFT; break; + case KEY_PAD_RIGHT: + converted_key = KEY_RIGHT; break; + case KEY_PAD_UP: + converted_key = KEY_UP; break; + case KEY_PAD_DOWN: + converted_key = KEY_DOWN; break; + case KEY_PAD_HOME: + converted_key = KEY_HOME; break; + case KEY_PAD_END: + converted_key = KEY_END; break; + case KEY_PAD_PGUP: + converted_key = KEY_PAGE_UP; break; + case KEY_PAD_PGDN: + converted_key = KEY_PAGE_DOWN; break; + case KEY_PAD_INS: + converted_key = KEY_INSERT; break; + case KEY_PAD_DEL: + converted_key = KEY_DELETE; break; + case KEY_PAD_RETURN: + converted_key = KEY_RETURN; break; + } + // convert our virtual keys to OS keys + return inverseTranslateKey(converted_key); } #endif diff --git a/indra/llwindow/llkeyboardwin32.h b/indra/llwindow/llkeyboardwin32.h index b7da450164..838566d69c 100644 --- a/indra/llwindow/llkeyboardwin32.h +++ b/indra/llwindow/llkeyboardwin32.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyboardwin32.h * @brief Handler for assignable key bindings * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,30 +29,30 @@ #include "llkeyboard.h" -// this mask distinguishes extended keys, which include non-numpad arrow keys +// this mask distinguishes extended keys, which include non-numpad arrow keys // (and, curiously, the num lock and numpad '/') const MASK MASK_EXTENDED = 0x0100; class LLKeyboardWin32 : public LLKeyboard { public: - LLKeyboardWin32(); - /*virtual*/ ~LLKeyboardWin32() {}; + LLKeyboardWin32(); + /*virtual*/ ~LLKeyboardWin32() {}; - /*virtual*/ BOOL handleKeyUp(const U16 key, MASK mask); - /*virtual*/ BOOL handleKeyDown(const U16 key, MASK mask); - /*virtual*/ void resetMaskKeys(); - /*virtual*/ MASK currentMask(BOOL for_mouse_event); - /*virtual*/ void scanKeyboard(); - BOOL translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key); - U16 inverseTranslateExtendedKey(const KEY translated_key); + /*virtual*/ BOOL handleKeyUp(const U16 key, MASK mask); + /*virtual*/ BOOL handleKeyDown(const U16 key, MASK mask); + /*virtual*/ void resetMaskKeys(); + /*virtual*/ MASK currentMask(BOOL for_mouse_event); + /*virtual*/ void scanKeyboard(); + BOOL translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key); + U16 inverseTranslateExtendedKey(const KEY translated_key); protected: - MASK updateModifiers(); - //void setModifierKeyLevel( KEY key, BOOL new_state ); + MASK updateModifiers(); + //void setModifierKeyLevel( KEY key, BOOL new_state ); private: - std::map<U16, KEY> mTranslateNumpadMap; - std::map<KEY, U16> mInvTranslateNumpadMap; + std::map<U16, KEY> mTranslateNumpadMap; + std::map<KEY, U16> mInvTranslateNumpadMap; }; #endif diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp index e41ebd42f3..62ad406967 100644 --- a/indra/llwindow/llmousehandler.cpp +++ b/indra/llwindow/llmousehandler.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmousehandler.cpp * @brief LLMouseHandler class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,38 +29,38 @@ //virtual BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) { - BOOL handled = FALSE; - if (down) - { - switch (clicktype) - { - case CLICK_LEFT: handled = handleMouseDown(x, y, mask); break; - case CLICK_RIGHT: handled = handleRightMouseDown(x, y, mask); break; - case CLICK_MIDDLE: handled = handleMiddleMouseDown(x, y, mask); break; - case CLICK_DOUBLELEFT: handled = handleDoubleClick(x, y, mask); break; - case CLICK_BUTTON4: - case CLICK_BUTTON5: - LL_INFOS() << "Handle mouse button " << clicktype + 1 << " down." << LL_ENDL; - break; - default: - LL_WARNS() << "Unhandled enum." << LL_ENDL; - } - } - else - { - switch (clicktype) - { - case CLICK_LEFT: handled = handleMouseUp(x, y, mask); break; - case CLICK_RIGHT: handled = handleRightMouseUp(x, y, mask); break; - case CLICK_MIDDLE: handled = handleMiddleMouseUp(x, y, mask); break; - case CLICK_DOUBLELEFT: handled = handleDoubleClick(x, y, mask); break; - case CLICK_BUTTON4: - case CLICK_BUTTON5: - LL_INFOS() << "Handle mouse button " << clicktype + 1 << " up." << LL_ENDL; - break; - default: - LL_WARNS() << "Unhandled enum." << LL_ENDL; - } - } - return handled; + BOOL handled = FALSE; + if (down) + { + switch (clicktype) + { + case CLICK_LEFT: handled = handleMouseDown(x, y, mask); break; + case CLICK_RIGHT: handled = handleRightMouseDown(x, y, mask); break; + case CLICK_MIDDLE: handled = handleMiddleMouseDown(x, y, mask); break; + case CLICK_DOUBLELEFT: handled = handleDoubleClick(x, y, mask); break; + case CLICK_BUTTON4: + case CLICK_BUTTON5: + LL_INFOS() << "Handle mouse button " << clicktype + 1 << " down." << LL_ENDL; + break; + default: + LL_WARNS() << "Unhandled enum." << LL_ENDL; + } + } + else + { + switch (clicktype) + { + case CLICK_LEFT: handled = handleMouseUp(x, y, mask); break; + case CLICK_RIGHT: handled = handleRightMouseUp(x, y, mask); break; + case CLICK_MIDDLE: handled = handleMiddleMouseUp(x, y, mask); break; + case CLICK_DOUBLELEFT: handled = handleDoubleClick(x, y, mask); break; + case CLICK_BUTTON4: + case CLICK_BUTTON5: + LL_INFOS() << "Handle mouse button " << clicktype + 1 << " up." << LL_ENDL; + break; + default: + LL_WARNS() << "Unhandled enum." << LL_ENDL; + } + } + return handled; } diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h index d221dd117c..dea28a0fc3 100644 --- a/indra/llwindow/llmousehandler.h +++ b/indra/llwindow/llmousehandler.h @@ -1,25 +1,25 @@ -/** +/** * @file llmousehandler.h * @brief LLMouseHandler class definition * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,42 +32,42 @@ #include "indra_constants.h" // Mostly-abstract interface. -// Intended for use via multiple inheritance. +// Intended for use via multiple inheritance. // A class may have as many interfaces as it likes, but never needs to inherit one more than once. class LLMouseHandler { public: - LLMouseHandler() {} - virtual ~LLMouseHandler() {} + LLMouseHandler() {} + virtual ~LLMouseHandler() {} - typedef enum { - SHOW_NEVER, - SHOW_IF_NOT_BLOCKED, - SHOW_ALWAYS, - } EShowToolTip; + typedef enum { + SHOW_NEVER, + SHOW_IF_NOT_BLOCKED, + SHOW_ALWAYS, + } EShowToolTip; - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0; - virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0; - virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) = 0; - virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0; - virtual const std::string& getName() const = 0; + virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0; + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0; + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) = 0; + virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0; + virtual const std::string& getName() const = 0; - virtual void onMouseCaptureLost() = 0; + virtual void onMouseCaptureLost() = 0; - virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const = 0; - virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const = 0; + virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const = 0; + virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const = 0; - virtual BOOL hasMouseCapture() = 0; + virtual BOOL hasMouseCapture() = 0; }; #endif diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index 072d40f739..97f4125484 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -35,11 +35,11 @@ @interface LLOpenGLView : NSOpenGLView <NSTextInputClient> { - std::string mLastDraggedUrl; - unsigned int mModifiers; - float mMousePos[2]; - bool mHasMarkedText; - unsigned int mMarkedTextLength; + std::string mLastDraggedUrl; + unsigned int mModifiers; + float mMousePos[2]; + bool mHasMarkedText; + unsigned int mMarkedTextLength; bool mMarkedTextAllowed; bool mSimulatedRightClick; bool mOldResize; @@ -78,7 +78,7 @@ @interface LLNonInlineTextView : NSTextView { - LLOpenGLView *glview; + LLOpenGLView *glview; unichar mKeyPressed; } diff --git a/indra/llwindow/llpreeditor.h b/indra/llwindow/llpreeditor.h index 9802fd8606..943d70c3dd 100644 --- a/indra/llwindow/llpreeditor.h +++ b/indra/llwindow/llpreeditor.h @@ -1,4 +1,4 @@ -/** +/** * @file llpreeditor.h * @brief I believe this is used for languages like Japanese that require * an "input method editor" to type Kanji. @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,69 +33,69 @@ class LLPreeditor { public: - typedef std::vector<S32> segment_lengths_t; - typedef std::vector<BOOL> standouts_t; - - // We don't delete against LLPreeditor, but compilers complain without this... - - virtual ~LLPreeditor() {}; + typedef std::vector<S32> segment_lengths_t; + typedef std::vector<BOOL> standouts_t; + + // We don't delete against LLPreeditor, but compilers complain without this... + + virtual ~LLPreeditor() {}; + + // Discard any preedit info. on this preeditor. + + virtual void resetPreedit() = 0; - // Discard any preedit info. on this preeditor. - - virtual void resetPreedit() = 0; + // Update the preedit feedback using specified details. + // Existing preedit is discarded and replaced with the new one. (I.e., updatePreedit is not cumulative.) + // All arguments are IN. + // preedit_count is the number of elements in arrays preedit_list and preedit_standouts. + // preedit list is an array of preedit texts (clauses.) + // preedit_standouts indicates whether each preedit text should be shown as standout clause. + // caret_position is the preedit-local position of text editing caret, in # of llwchar. - // Update the preedit feedback using specified details. - // Existing preedit is discarded and replaced with the new one. (I.e., updatePreedit is not cumulative.) - // All arguments are IN. - // preedit_count is the number of elements in arrays preedit_list and preedit_standouts. - // preedit list is an array of preedit texts (clauses.) - // preedit_standouts indicates whether each preedit text should be shown as standout clause. - // caret_position is the preedit-local position of text editing caret, in # of llwchar. - - virtual void updatePreedit(const LLWString &preedit_string, - const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position) = 0; + virtual void updatePreedit(const LLWString &preedit_string, + const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position) = 0; - // Turn the specified sub-contents into an active preedit. - // Both position and length are IN and count with UTF-32 (llwchar) characters. - // This method primarily facilitates reconversion. + // Turn the specified sub-contents into an active preedit. + // Both position and length are IN and count with UTF-32 (llwchar) characters. + // This method primarily facilitates reconversion. - virtual void markAsPreedit(S32 position, S32 length) = 0; + virtual void markAsPreedit(S32 position, S32 length) = 0; - // Get the position and the length of the active preedit in the contents. - // Both position and length are OUT and count with UTF-32 (llwchar) characters. - // When this preeditor has no active preedit, position receives - // the caret position, and length receives 0. + // Get the position and the length of the active preedit in the contents. + // Both position and length are OUT and count with UTF-32 (llwchar) characters. + // When this preeditor has no active preedit, position receives + // the caret position, and length receives 0. - virtual void getPreeditRange(S32 *position, S32 *length) const = 0; + virtual void getPreeditRange(S32 *position, S32 *length) const = 0; - // Get the position and the length of the current selection in the contents. - // Both position and length are OUT and count with UTF-32 (llwchar) characters. - // When this preeditor has no selection, position receives - // the caret position, and length receives 0. + // Get the position and the length of the current selection in the contents. + // Both position and length are OUT and count with UTF-32 (llwchar) characters. + // When this preeditor has no selection, position receives + // the caret position, and length receives 0. - virtual void getSelectionRange(S32 *position, S32 *length) const = 0; + virtual void getSelectionRange(S32 *position, S32 *length) const = 0; - // Get the locations where the preedit and related UI elements are displayed. - // Locations are relative to the app window and measured in GL coordinate space (before scaling.) - // query_position is IN argument, and other three are OUT. + // Get the locations where the preedit and related UI elements are displayed. + // Locations are relative to the app window and measured in GL coordinate space (before scaling.) + // query_position is IN argument, and other three are OUT. - virtual BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const = 0; + virtual BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const = 0; - // Get the size (height) of the current font used in this preeditor. + // Get the size (height) of the current font used in this preeditor. - virtual S32 getPreeditFontSize() const = 0; + virtual S32 getPreeditFontSize() const = 0; - // Get the contents of this preeditor as a LLWString. If there is an active preedit, - // the returned LLWString contains it. + // Get the contents of this preeditor as a LLWString. If there is an active preedit, + // the returned LLWString contains it. - virtual LLWString getPreeditString() const = 0; + virtual LLWString getPreeditString() const = 0; - // Handle a UTF-32 char on this preeditor, i.e., add the character - // to the contents. - // This is a back door of the method of same name of LLWindowCallback. - // called_from_parent should be set to FALSE if calling through LLPreeditor. + // Handle a UTF-32 char on this preeditor, i.e., add the character + // to the contents. + // This is a back door of the method of same name of LLWindowCallback. + // called_from_parent should be set to FALSE if calling through LLPreeditor. - virtual BOOL handleUnicodeCharHere(llwchar uni_char) = 0; + virtual BOOL handleUnicodeCharHere(llwchar uni_char) = 0; }; #endif diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index b4fd7c6387..b51b4fad82 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llwindow.cpp * @brief Basic graphical window class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -55,43 +55,43 @@ const S32 gURLProtocolWhitelistCount = 5; const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:", "mailto:" }; // CP: added a handler list - this is what's used to open the protocol and is based on registry entry -// only meaningful difference currently is that file: protocols are opened using http: -// since no protocol handler exists in registry for file: +// only meaningful difference currently is that file: protocols are opened using http: +// since no protocol handler exists in registry for file: // Important - these lists should match - protocol to handler // Maestro: This list isn't referenced anywhere that I could find -//const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" }; +//const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" }; S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type) { - // Properly hide the splash screen when displaying the message box - BOOL was_visible = FALSE; - if (LLSplashScreen::isVisible()) - { - was_visible = TRUE; - LLSplashScreen::hide(); - } + // Properly hide the splash screen when displaying the message box + BOOL was_visible = FALSE; + if (LLSplashScreen::isVisible()) + { + was_visible = TRUE; + LLSplashScreen::hide(); + } - S32 result = 0; + S32 result = 0; #if LL_MESA_HEADLESS // !!! *FIX: (?) - LL_WARNS() << "OSMessageBox: " << text << LL_ENDL; - return OSBTN_OK; + LL_WARNS() << "OSMessageBox: " << text << LL_ENDL; + return OSBTN_OK; #elif LL_SDL - result = OSMessageBoxSDL(text, caption, type); + result = OSMessageBoxSDL(text, caption, type); #elif LL_WINDOWS - result = OSMessageBoxWin32(text, caption, type); + result = OSMessageBoxWin32(text, caption, type); #elif LL_DARWIN - result = OSMessageBoxMacOSX(text, caption, type); + result = OSMessageBoxMacOSX(text, caption, type); #else #error("OSMessageBox not implemented for this platform!") #endif - if (was_visible) - { - LLSplashScreen::show(); - } + if (was_visible) + { + LLSplashScreen::show(); + } - return result; + return result; } @@ -100,27 +100,27 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type) // LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags) - : mCallbacks(callbacks), - mPostQuit(TRUE), - mFullscreen(fullscreen), - mFullscreenWidth(0), - mFullscreenHeight(0), - mFullscreenBits(0), - mFullscreenRefresh(0), - mSupportedResolutions(NULL), - mNumSupportedResolutions(0), - mCurrentCursor(UI_CURSOR_ARROW), - mNextCursor(UI_CURSOR_ARROW), - mCursorHidden(FALSE), - mBusyCount(0), - mIsMouseClipping(FALSE), - mMinWindowWidth(0), - mMinWindowHeight(0), - mSwapMethod(SWAP_METHOD_UNDEFINED), - mHideCursorPermanent(FALSE), - mFlags(flags), - mHighSurrogate(0), - mRefreshRate(0) + : mCallbacks(callbacks), + mPostQuit(TRUE), + mFullscreen(fullscreen), + mFullscreenWidth(0), + mFullscreenHeight(0), + mFullscreenBits(0), + mFullscreenRefresh(0), + mSupportedResolutions(NULL), + mNumSupportedResolutions(0), + mCurrentCursor(UI_CURSOR_ARROW), + mNextCursor(UI_CURSOR_ARROW), + mCursorHidden(FALSE), + mBusyCount(0), + mIsMouseClipping(FALSE), + mMinWindowWidth(0), + mMinWindowHeight(0), + mSwapMethod(SWAP_METHOD_UNDEFINED), + mHideCursorPermanent(FALSE), + mFlags(flags), + mHighSurrogate(0), + mRefreshRate(0) { } @@ -131,13 +131,13 @@ LLWindow::~LLWindow() //virtual BOOL LLWindow::isValid() { - return TRUE; + return TRUE; } //virtual BOOL LLWindow::canDelete() { - return TRUE; + return TRUE; } //virtual @@ -149,126 +149,126 @@ void LLWindow::setTitle(const std::string title) // virtual void LLWindow::incBusyCount() { - ++mBusyCount; + ++mBusyCount; } // virtual void LLWindow::decBusyCount() { - if (mBusyCount > 0) - { - --mBusyCount; - } + if (mBusyCount > 0) + { + --mBusyCount; + } } //virtual void LLWindow::resetBusyCount() { - mBusyCount = 0; + mBusyCount = 0; } //virtual S32 LLWindow::getBusyCount() const { - return mBusyCount; + return mBusyCount; } //virtual ECursorType LLWindow::getCursor() const { - return mCurrentCursor; + return mCurrentCursor; } //virtual BOOL LLWindow::dialogColorPicker(F32 *r, F32 *g, F32 *b) { - return FALSE; + return FALSE; } void *LLWindow::getMediaWindow() { - // Default to returning the platform window. - return getPlatformWindow(); + // Default to returning the platform window. + return getPlatformWindow(); } BOOL LLWindow::setSize(LLCoordScreen size) { - if (!getMaximized()) - { - size.mX = llmax(size.mX, mMinWindowWidth); - size.mY = llmax(size.mY, mMinWindowHeight); - } - return setSizeImpl(size); + if (!getMaximized()) + { + size.mX = llmax(size.mX, mMinWindowWidth); + size.mY = llmax(size.mY, mMinWindowHeight); + } + return setSizeImpl(size); } BOOL LLWindow::setSize(LLCoordWindow size) { - //HACK: we are inconsistently using minimum window dimensions - // in this case, we are constraining the inner "client" rect and other times - // we constrain the outer "window" rect - // There doesn't seem to be a good way to do this consistently without a bunch of platform - // specific code - if (!getMaximized()) - { - size.mX = llmax(size.mX, mMinWindowWidth); - size.mY = llmax(size.mY, mMinWindowHeight); - } - return setSizeImpl(size); + //HACK: we are inconsistently using minimum window dimensions + // in this case, we are constraining the inner "client" rect and other times + // we constrain the outer "window" rect + // There doesn't seem to be a good way to do this consistently without a bunch of platform + // specific code + if (!getMaximized()) + { + size.mX = llmax(size.mX, mMinWindowWidth); + size.mY = llmax(size.mY, mMinWindowHeight); + } + return setSizeImpl(size); } // virtual void LLWindow::setMinSize(U32 min_width, U32 min_height, bool enforce_immediately) { - mMinWindowWidth = min_width; - mMinWindowHeight = min_height; + mMinWindowWidth = min_width; + mMinWindowHeight = min_height; - if (enforce_immediately) - { - LLCoordScreen cur_size; - if (!getMaximized() && getSize(&cur_size)) - { - if (cur_size.mX < mMinWindowWidth || cur_size.mY < mMinWindowHeight) - { - setSizeImpl(LLCoordScreen(llmin(cur_size.mX, mMinWindowWidth), llmin(cur_size.mY, mMinWindowHeight))); - } - } - } + if (enforce_immediately) + { + LLCoordScreen cur_size; + if (!getMaximized() && getSize(&cur_size)) + { + if (cur_size.mX < mMinWindowWidth || cur_size.mY < mMinWindowHeight) + { + setSizeImpl(LLCoordScreen(llmin(cur_size.mX, mMinWindowWidth), llmin(cur_size.mY, mMinWindowHeight))); + } + } + } } //virtual void LLWindow::processMiscNativeEvents() { - // do nothing unless subclassed + // do nothing unless subclassed } //virtual BOOL LLWindow::isPrimaryTextAvailable() { - return FALSE; // no + return FALSE; // no } //virtual BOOL LLWindow::pasteTextFromPrimary(LLWString &dst) { - return FALSE; // fail + return FALSE; // fail } // virtual BOOL LLWindow::copyTextToPrimary(const LLWString &src) { - return FALSE; // fail + return FALSE; // fail } // static std::vector<std::string> LLWindow::getDynamicFallbackFontList() { #if LL_SDL - return LLWindowSDL::getDynamicFallbackFontList(); + return LLWindowSDL::getDynamicFallbackFontList(); #elif LL_WINDOWS - return LLWindowWin32::getDynamicFallbackFontList(); + return LLWindowWin32::getDynamicFallbackFontList(); #elif LL_DARWIN - return LLWindowMacOSX::getDynamicFallbackFontList(); + return LLWindowMacOSX::getDynamicFallbackFontList(); #else - return std::vector<std::string>(); + return std::vector<std::string>(); #endif } @@ -276,11 +276,11 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList() std::vector<std::string> LLWindow::getDisplaysResolutionList() { #ifdef LL_SDL - return std::vector<std::string>(); + return std::vector<std::string>(); #elif LL_WINDOWS - return LLWindowWin32::getDisplaysResolutionList(); + return LLWindowWin32::getDisplaysResolutionList(); #elif LL_DARWIN - return LLWindowMacOSX::getDisplaysResolutionList(); + return LLWindowMacOSX::getDisplaysResolutionList(); #endif } @@ -290,45 +290,45 @@ std::vector<std::string> LLWindow::getDisplaysResolutionList() void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask) { - // Note that we could discard unpaired surrogates, but I'm - // following the Unicode Consortium's recommendation here; - // that is, to preserve those unpaired surrogates in UTF-32 - // values. _To_preserve_ means to pass to the callback in our - // context. - - if (mHighSurrogate == 0) - { - if (UTF16_IS_HIGH_SURROGATE(utf16)) - { - mHighSurrogate = utf16; - } - else - { - mCallbacks->handleUnicodeChar(utf16, mask); - } - } - else - { - if (UTF16_IS_LOW_SURROGATE(utf16)) - { - /* A legal surrogate pair. */ - mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate, utf16), mask); - mHighSurrogate = 0; - } - else if (UTF16_IS_HIGH_SURROGATE(utf16)) - { - /* Two consecutive high surrogates. */ - mCallbacks->handleUnicodeChar(mHighSurrogate, mask); - mHighSurrogate = utf16; - } - else - { - /* A non-low-surrogate preceeded by a high surrogate. */ - mCallbacks->handleUnicodeChar(mHighSurrogate, mask); - mHighSurrogate = 0; - mCallbacks->handleUnicodeChar(utf16, mask); - } - } + // Note that we could discard unpaired surrogates, but I'm + // following the Unicode Consortium's recommendation here; + // that is, to preserve those unpaired surrogates in UTF-32 + // values. _To_preserve_ means to pass to the callback in our + // context. + + if (mHighSurrogate == 0) + { + if (UTF16_IS_HIGH_SURROGATE(utf16)) + { + mHighSurrogate = utf16; + } + else + { + mCallbacks->handleUnicodeChar(utf16, mask); + } + } + else + { + if (UTF16_IS_LOW_SURROGATE(utf16)) + { + /* A legal surrogate pair. */ + mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate, utf16), mask); + mHighSurrogate = 0; + } + else if (UTF16_IS_HIGH_SURROGATE(utf16)) + { + /* Two consecutive high surrogates. */ + mCallbacks->handleUnicodeChar(mHighSurrogate, mask); + mHighSurrogate = utf16; + } + else + { + /* A non-low-surrogate preceeded by a high surrogate. */ + mCallbacks->handleUnicodeChar(mHighSurrogate, mask); + mHighSurrogate = 0; + mCallbacks->handleUnicodeChar(utf16, mask); + } + } } // @@ -338,18 +338,18 @@ void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask) // static bool LLSplashScreen::isVisible() { - return gSplashScreenp ? true: false; + return gSplashScreenp ? true: false; } // static LLSplashScreen *LLSplashScreen::create() { #if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (?) - return 0; + return 0; #elif LL_WINDOWS - return new LLSplashScreenWin32; + return new LLSplashScreenWin32; #elif LL_DARWIN - return new LLSplashScreenMacOSX; + return new LLSplashScreenMacOSX; #else #error("LLSplashScreen not implemented on this platform!") #endif @@ -359,41 +359,41 @@ LLSplashScreen *LLSplashScreen::create() //static void LLSplashScreen::show() { - if (!gSplashScreenp) - { + if (!gSplashScreenp) + { #if !LL_SDL #if LL_WINDOWS && !LL_MESA_HEADLESS - gSplashScreenp = new LLSplashScreenWin32; + gSplashScreenp = new LLSplashScreenWin32; #elif LL_DARWIN - gSplashScreenp = new LLSplashScreenMacOSX; + gSplashScreenp = new LLSplashScreenMacOSX; #endif #endif // !LL_SDL - if (gSplashScreenp) - { - gSplashScreenp->showImpl(); - } - } + if (gSplashScreenp) + { + gSplashScreenp->showImpl(); + } + } } //static void LLSplashScreen::update(const std::string& str) { - LLSplashScreen::show(); - if (gSplashScreenp) - { - gSplashScreenp->updateImpl(str); - } + LLSplashScreen::show(); + if (gSplashScreenp) + { + gSplashScreenp->updateImpl(str); + } } //static void LLSplashScreen::hide() { - if (gSplashScreenp) - { - gSplashScreenp->hideImpl(); - } - delete gSplashScreenp; - gSplashScreenp = NULL; + if (gSplashScreenp) + { + gSplashScreenp->hideImpl(); + } + delete gSplashScreenp; + gSplashScreenp = NULL; } // @@ -404,111 +404,111 @@ void LLSplashScreen::hide() static std::set<LLWindow*> sWindowList; LLWindow* LLWindowManager::createWindow( - LLWindowCallbacks* callbacks, - 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, + LLWindowCallbacks* callbacks, + 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, U32 max_cores, U32 max_vram, F32 max_gl_version) { - LLWindow* new_window = nullptr; + LLWindow* new_window = nullptr; - if (use_gl) - { + if (use_gl) + { #if LL_MESA_HEADLESS - new_window = new LLWindowMesaHeadless(callbacks, - title, name, x, y, width, height, flags, - fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); + new_window = new LLWindowMesaHeadless(callbacks, + title, name, x, y, width, height, flags, + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); #elif LL_SDL - new_window = new LLWindowSDL(callbacks, - title, x, y, width, height, flags, - fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + new_window = new LLWindowSDL(callbacks, + title, x, y, width, height, flags, + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS - new_window = new LLWindowWin32(callbacks, - title, name, x, y, width, height, flags, - fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples, max_cores, max_vram, max_gl_version); + new_window = new LLWindowWin32(callbacks, + title, name, x, y, width, height, flags, + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples, max_cores, max_vram, max_gl_version); #elif LL_DARWIN - new_window = new LLWindowMacOSX(callbacks, - title, name, x, y, width, height, flags, - fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + new_window = new LLWindowMacOSX(callbacks, + title, name, x, y, width, height, flags, + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #endif - } - else - { - new_window = new LLWindowHeadless(callbacks, - title, name, x, y, width, height, flags, - fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); - } - - if (FALSE == new_window->isValid()) - { - delete new_window; - LL_WARNS() << "LLWindowManager::create() : Error creating window." << LL_ENDL; - return NULL; - } - sWindowList.insert(new_window); - return new_window; + } + else + { + new_window = new LLWindowHeadless(callbacks, + title, name, x, y, width, height, flags, + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); + } + + if (FALSE == new_window->isValid()) + { + delete new_window; + LL_WARNS() << "LLWindowManager::create() : Error creating window." << LL_ENDL; + return NULL; + } + sWindowList.insert(new_window); + return new_window; } BOOL LLWindowManager::destroyWindow(LLWindow* window) { - if (sWindowList.find(window) == sWindowList.end()) - { - LL_ERRS() << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!" - << LL_ENDL; - return FALSE; - } + if (sWindowList.find(window) == sWindowList.end()) + { + LL_ERRS() << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!" + << LL_ENDL; + return FALSE; + } - window->close(); + window->close(); - sWindowList.erase(window); + sWindowList.erase(window); - delete window; + delete window; - return TRUE; + return TRUE; } BOOL LLWindowManager::isWindowValid(LLWindow *window) { - return sWindowList.find(window) != sWindowList.end(); + return sWindowList.find(window) != sWindowList.end(); } //coordinate conversion utility funcs that forward to llwindow LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const { - const LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this); + const LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this); - LLCoordGL out; - LLWindow::instance_snapshot().begin()->convertCoords(self, &out); - return out.convert(); + LLCoordGL out; + LLWindow::instance_snapshot().begin()->convertCoords(self, &out); + return out.convert(); } void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from) { - LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this); + LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this); - LLCoordGL from_gl(from); - LLWindow::instance_snapshot().begin()->convertCoords(from_gl, &self); + LLCoordGL from_gl(from); + LLWindow::instance_snapshot().begin()->convertCoords(from_gl, &self); } LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const { - const LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this); + const LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this); - LLCoordGL out; - LLWindow::instance_snapshot().begin()->convertCoords(self, &out); - return out.convert(); + LLCoordGL out; + LLWindow::instance_snapshot().begin()->convertCoords(self, &out); + return out.convert(); } void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from) { - LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this); + LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this); - LLCoordGL from_gl(from); - LLWindow::instance_snapshot().begin()->convertCoords(from_gl, &self); + LLCoordGL from_gl(from); + LLWindow::instance_snapshot().begin()->convertCoords(from_gl, &self); } diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index f435d46584..aff9334cb6 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindow.h * @brief Basic graphical window class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,40 +44,40 @@ class LLWindow : public LLInstanceTracker<LLWindow> { public: - struct LLWindowResolution - { - S32 mWidth; - S32 mHeight; - }; - enum ESwapMethod - { - SWAP_METHOD_UNDEFINED, - SWAP_METHOD_EXCHANGE, - SWAP_METHOD_COPY - }; - enum EFlags - { - // currently unused - }; + struct LLWindowResolution + { + S32 mWidth; + S32 mHeight; + }; + enum ESwapMethod + { + SWAP_METHOD_UNDEFINED, + SWAP_METHOD_EXCHANGE, + SWAP_METHOD_COPY + }; + enum EFlags + { + // currently unused + }; public: - virtual void show() = 0; - virtual void hide() = 0; - virtual void close() = 0; - virtual BOOL getVisible() = 0; - virtual BOOL getMinimized() = 0; - virtual BOOL getMaximized() = 0; - virtual BOOL maximize() = 0; - virtual void minimize() = 0; - virtual void restore() = 0; - BOOL getFullscreen() { return mFullscreen; }; - virtual BOOL getPosition(LLCoordScreen *position) = 0; - virtual BOOL getSize(LLCoordScreen *size) = 0; - virtual BOOL getSize(LLCoordWindow *size) = 0; - virtual BOOL setPosition(LLCoordScreen position) = 0; - BOOL setSize(LLCoordScreen size); - BOOL setSize(LLCoordWindow size); - virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) = 0; + virtual void show() = 0; + virtual void hide() = 0; + virtual void close() = 0; + virtual BOOL getVisible() = 0; + virtual BOOL getMinimized() = 0; + virtual BOOL getMaximized() = 0; + virtual BOOL maximize() = 0; + virtual void minimize() = 0; + virtual void restore() = 0; + BOOL getFullscreen() { return mFullscreen; }; + virtual BOOL getPosition(LLCoordScreen *position) = 0; + virtual BOOL getSize(LLCoordScreen *size) = 0; + virtual BOOL getSize(LLCoordWindow *size) = 0; + virtual BOOL setPosition(LLCoordScreen position) = 0; + BOOL setSize(LLCoordScreen size); + BOOL setSize(LLCoordWindow size); + virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); + virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) = 0; //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread // returns a pointer to be handed back to destroySharedConext/makeContextCurrent @@ -91,161 +91,167 @@ public: virtual void toggleVSync(bool enable_vsync) = 0; virtual BOOL setCursorPosition(LLCoordWindow position) = 0; - virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; + virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; #if LL_WINDOWS virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0; #endif - virtual void showCursor() = 0; - virtual void hideCursor() = 0; - virtual BOOL isCursorHidden() = 0; - virtual void showCursorFromMouseMove() = 0; - virtual void hideCursorUntilMouseMove() = 0; + virtual void showCursor() = 0; + virtual void hideCursor() = 0; + virtual BOOL isCursorHidden() = 0; + virtual void showCursorFromMouseMove() = 0; + virtual void hideCursorUntilMouseMove() = 0; // Provide a way to set the Viewer window title after the // windows has been created. The initial use case for this - // is described in SL-16102 (update window title with agent + // is described in SL-16102 (update window title with agent // name, location etc. for non-interactive viewer) but it // may also be useful in other cases. virtual void setTitle(const std::string title); - // These two functions create a way to make a busy cursor instead - // of an arrow when someone's busy doing something. Draw an - // arrow/hour if busycount > 0. - virtual void incBusyCount(); - virtual void decBusyCount(); - virtual void resetBusyCount(); - virtual S32 getBusyCount() const; + // These two functions create a way to make a busy cursor instead + // of an arrow when someone's busy doing something. Draw an + // arrow/hour if busycount > 0. + virtual void incBusyCount(); + virtual void decBusyCount(); + virtual void resetBusyCount(); + virtual S32 getBusyCount() const; - // Sets cursor, may set to arrow+hourglass - virtual void setCursor(ECursorType cursor) { mNextCursor = cursor; }; + // Sets cursor, may set to arrow+hourglass + virtual void setCursor(ECursorType cursor) { mNextCursor = cursor; }; virtual ECursorType getCursor() const; virtual ECursorType getNextCursor() const { return mNextCursor; }; - virtual void updateCursor() = 0; - - virtual void captureMouse() = 0; - virtual void releaseMouse() = 0; - virtual void setMouseClipping( BOOL b ) = 0; - - virtual BOOL isClipboardTextAvailable() = 0; - virtual BOOL pasteTextFromClipboard(LLWString &dst) = 0; - virtual BOOL copyTextToClipboard(const LLWString &src) = 0; - - virtual BOOL isPrimaryTextAvailable(); - virtual BOOL pasteTextFromPrimary(LLWString &dst); - virtual BOOL copyTextToPrimary(const LLWString &src); - - virtual void flashIcon(F32 seconds) = 0; - virtual F32 getGamma() = 0; - virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma - virtual void setFSAASamples(const U32 fsaa_samples) = 0; //set number of FSAA samples - virtual U32 getFSAASamples() = 0; - virtual BOOL restoreGamma() = 0; // Restore original gamma table (before updating gamma) - virtual ESwapMethod getSwapMethod() { return mSwapMethod; } - virtual void processMiscNativeEvents(); - virtual void gatherInput() = 0; - virtual void delayInputProcessing() = 0; - virtual void swapBuffers() = 0; - virtual void bringToFront() = 0; - virtual void focusClient() { }; // this may not have meaning or be required on other platforms, therefore, it's not abstract - virtual void setOldResize(bool oldresize) { }; - // handy coordinate space conversion routines - // NB: screen to window and vice verse won't work on width/height coordinate pairs, - // as the conversion must take into account left AND right border widths, etc. - virtual BOOL convertCoords( LLCoordScreen from, LLCoordWindow *to) = 0; - virtual BOOL convertCoords( LLCoordWindow from, LLCoordScreen *to) = 0; - virtual BOOL convertCoords( LLCoordWindow from, LLCoordGL *to) = 0; - virtual BOOL convertCoords( LLCoordGL from, LLCoordWindow *to) = 0; - virtual BOOL convertCoords( LLCoordScreen from, LLCoordGL *to) = 0; - virtual BOOL convertCoords( LLCoordGL from, LLCoordScreen *to) = 0; - - // query supported resolutions - virtual LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) = 0; - virtual F32 getNativeAspectRatio() = 0; - virtual F32 getPixelAspectRatio() = 0; - virtual void setNativeAspectRatio(F32 aspect) = 0; - - // query VRAM usage - virtual U32 getAvailableVRAMMegabytes() = 0; - - virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode) - virtual void afterDialog() {}; // undo whatever was done in beforeDialog() - - // opens system default color picker, modally - // Returns TRUE if valid color selected - virtual BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b); + virtual void updateCursor() = 0; + + virtual void captureMouse() = 0; + virtual void releaseMouse() = 0; + virtual void setMouseClipping( BOOL b ) = 0; + + virtual BOOL isClipboardTextAvailable() = 0; + virtual BOOL pasteTextFromClipboard(LLWString &dst) = 0; + virtual BOOL copyTextToClipboard(const LLWString &src) = 0; + + virtual BOOL isPrimaryTextAvailable(); + virtual BOOL pasteTextFromPrimary(LLWString &dst); + virtual BOOL copyTextToPrimary(const LLWString &src); + + virtual void flashIcon(F32 seconds) = 0; + virtual F32 getGamma() = 0; + virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma + virtual void setFSAASamples(const U32 fsaa_samples) = 0; //set number of FSAA samples + virtual U32 getFSAASamples() = 0; + virtual BOOL restoreGamma() = 0; // Restore original gamma table (before updating gamma) + virtual ESwapMethod getSwapMethod() { return mSwapMethod; } + virtual void processMiscNativeEvents(); + virtual void gatherInput() = 0; + virtual void delayInputProcessing() = 0; + virtual void swapBuffers() = 0; + virtual void bringToFront() = 0; + virtual void focusClient() { }; // this may not have meaning or be required on other platforms, therefore, it's not abstract + virtual void setOldResize(bool oldresize) { }; + // handy coordinate space conversion routines + // NB: screen to window and vice verse won't work on width/height coordinate pairs, + // as the conversion must take into account left AND right border widths, etc. + virtual BOOL convertCoords( LLCoordScreen from, LLCoordWindow *to) = 0; + virtual BOOL convertCoords( LLCoordWindow from, LLCoordScreen *to) = 0; + virtual BOOL convertCoords( LLCoordWindow from, LLCoordGL *to) = 0; + virtual BOOL convertCoords( LLCoordGL from, LLCoordWindow *to) = 0; + virtual BOOL convertCoords( LLCoordScreen from, LLCoordGL *to) = 0; + virtual BOOL convertCoords( LLCoordGL from, LLCoordScreen *to) = 0; + + // query supported resolutions + virtual LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) = 0; + virtual F32 getNativeAspectRatio() = 0; + virtual F32 getPixelAspectRatio() = 0; + virtual void setNativeAspectRatio(F32 aspect) = 0; + + // query VRAM usage + virtual U32 getAvailableVRAMMegabytes() = 0; + + virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode) + virtual void afterDialog() {}; // undo whatever was done in beforeDialog() + + // opens system default color picker, modally + // Returns TRUE if valid color selected + virtual BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b); // return a platform-specific window reference (HWND on Windows, WindowRef on the Mac, Gtk window on Linux) - virtual void *getPlatformWindow() = 0; + virtual void *getPlatformWindow() = 0; // return the platform-specific window reference we use to initialize llmozlib (HWND on Windows, WindowRef on the Mac, Gtk window on Linux) - virtual void *getMediaWindow(); - - // control platform's Language Text Input mechanisms. - virtual void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) {} - virtual void setLanguageTextInput( const LLCoordGL & pos ) {}; - virtual void updateLanguageTextInputArea() {} - virtual void interruptLanguageTextInput() {} - virtual void spawnWebBrowser(const std::string& escaped_url, bool async) {}; + virtual void *getMediaWindow(); + + // control platform's Language Text Input mechanisms. + virtual void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) {} + virtual void setLanguageTextInput( const LLCoordGL & pos ) {}; + virtual void updateLanguageTextInputArea() {} + virtual void interruptLanguageTextInput() {} + virtual void spawnWebBrowser(const std::string& escaped_url, bool async) {}; + + static std::vector<std::string> getDynamicFallbackFontList(); - static std::vector<std::string> getDynamicFallbackFontList(); - - // Provide native key event data - virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); } + // Provide native key event data + virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); } - // Get system UI size based on DPI (for 96 DPI UI size should be 1.0) - virtual F32 getSystemUISize() { return 1.0; } + // Get system UI size based on DPI (for 96 DPI UI size should be 1.0) + virtual F32 getSystemUISize() { return 1.0; } - static std::vector<std::string> getDisplaysResolutionList(); + static std::vector<std::string> getDisplaysResolutionList(); // windows only DirectInput8 for joysticks virtual void* getDirectInput8() { return NULL; }; - virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; }; + virtual bool getInputDevices(U32 device_type_filter, + std::function<bool(std::string&, LLSD&, void*)> osx_callback, + void* win_callback, + void* userdata) + { + return false; + }; virtual S32 getRefreshRate() { return mRefreshRate; } protected: - LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); - virtual ~LLWindow(); - // Defaults to true - virtual BOOL isValid(); - // Defaults to true - virtual BOOL canDelete(); + LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); + virtual ~LLWindow(); + // Defaults to true + virtual BOOL isValid(); + // Defaults to true + virtual BOOL canDelete(); - virtual BOOL setSizeImpl(LLCoordScreen size) = 0; - virtual BOOL setSizeImpl(LLCoordWindow size) = 0; + virtual BOOL setSizeImpl(LLCoordScreen size) = 0; + virtual BOOL setSizeImpl(LLCoordWindow size) = 0; protected: - LLWindowCallbacks* mCallbacks; - - BOOL mPostQuit; // should this window post a quit message when destroyed? - BOOL mFullscreen; - S32 mFullscreenWidth; - S32 mFullscreenHeight; - S32 mFullscreenBits; - S32 mFullscreenRefresh; - LLWindowResolution* mSupportedResolutions; - S32 mNumSupportedResolutions; - ECursorType mCurrentCursor; - ECursorType mNextCursor; - BOOL mCursorHidden; - S32 mBusyCount; // how deep is the "cursor busy" stack? - BOOL mIsMouseClipping; // Is this window currently clipping the mouse - ESwapMethod mSwapMethod; - BOOL mHideCursorPermanent; - U32 mFlags; - U16 mHighSurrogate; - S32 mMinWindowWidth; - S32 mMinWindowHeight; + LLWindowCallbacks* mCallbacks; + + BOOL mPostQuit; // should this window post a quit message when destroyed? + BOOL mFullscreen; + S32 mFullscreenWidth; + S32 mFullscreenHeight; + S32 mFullscreenBits; + S32 mFullscreenRefresh; + LLWindowResolution* mSupportedResolutions; + S32 mNumSupportedResolutions; + ECursorType mCurrentCursor; + ECursorType mNextCursor; + BOOL mCursorHidden; + S32 mBusyCount; // how deep is the "cursor busy" stack? + BOOL mIsMouseClipping; // Is this window currently clipping the mouse + ESwapMethod mSwapMethod; + BOOL mHideCursorPermanent; + U32 mFlags; + U16 mHighSurrogate; + S32 mMinWindowWidth; + S32 mMinWindowHeight; S32 mRefreshRate; - // Handle a UTF-16 encoding unit received from keyboard. - // Converting the series of UTF-16 encoding units to UTF-32 data, - // this method passes the resulting UTF-32 data to mCallback's - // handleUnicodeChar. The mask should be that to be passed to the - // callback. This method uses mHighSurrogate as a dedicated work - // variable. - void handleUnicodeUTF16(U16 utf16, MASK mask); + // Handle a UTF-16 encoding unit received from keyboard. + // Converting the series of UTF-16 encoding units to UTF-32 data, + // this method passes the resulting UTF-32 data to mCallback's + // handleUnicodeChar. The mask should be that to be passed to the + // callback. This method uses mHighSurrogate as a dedicated work + // variable. + void handleUnicodeUTF16(U16 utf16, MASK mask); - friend class LLWindowManager; + friend class LLWindowManager; }; @@ -258,24 +264,24 @@ protected: class LLSplashScreen { public: - LLSplashScreen() { }; - virtual ~LLSplashScreen() { }; + LLSplashScreen() { }; + virtual ~LLSplashScreen() { }; - // Call to display the window. - static LLSplashScreen * create(); - static void show(); - static void hide(); - static void update(const std::string& string); + // Call to display the window. + static LLSplashScreen * create(); + static void show(); + static void hide(); + static void update(const std::string& string); - static bool isVisible(); + static bool isVisible(); protected: - // These are overridden by the platform implementation - virtual void showImpl() = 0; - virtual void updateImpl(const std::string& string) = 0; - virtual void hideImpl() = 0; + // These are overridden by the platform implementation + virtual void showImpl() = 0; + virtual void updateImpl(const std::string& string) = 0; + virtual void hideImpl() = 0; - static BOOL sVisible; + static BOOL sVisible; }; @@ -297,21 +303,21 @@ const S32 OSBTN_CANCEL = 3; class LLWindowManager { public: - static LLWindow *createWindow( - LLWindowCallbacks* callbacks, - const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, - U32 flags = 0, - BOOL fullscreen = FALSE, - BOOL clearBg = FALSE, - BOOL enable_vsync = FALSE, - BOOL use_gl = TRUE, - BOOL ignore_pixel_depth = FALSE, - U32 fsaa_samples = 0, + static LLWindow *createWindow( + LLWindowCallbacks* callbacks, + const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, + U32 flags = 0, + BOOL fullscreen = FALSE, + BOOL clearBg = FALSE, + BOOL enable_vsync = FALSE, + BOOL use_gl = TRUE, + BOOL ignore_pixel_depth = FALSE, + U32 fsaa_samples = 0, U32 max_cores = 0, U32 max_vram = 0, F32 max_gl_version = 4.6f); - static BOOL destroyWindow(LLWindow* window); - static BOOL isWindowValid(LLWindow *window); + static BOOL destroyWindow(LLWindow* window); + static BOOL isWindowValid(LLWindow *window); }; // diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index e39edec588..ddf913045f 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llwindowcallbacks.cpp * @brief OS event callback class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,13 +34,13 @@ BOOL LLWindowCallbacks::handleTranslatedKeyDown(const KEY key, const MASK mask, BOOL repeated) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleTranslatedKeyUp(const KEY key, const MASK mask) { - return FALSE; + return FALSE; } void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) @@ -49,7 +49,7 @@ void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL BOOL LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleUnicodeString(char *uni_str, bool editing) @@ -59,23 +59,23 @@ BOOL LLWindowCallbacks::handleUnicodeString(char *uni_str, bool editing) BOOL LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } void LLWindowCallbacks::handleMouseLeave(LLWindow *window) { - return; + return; } BOOL LLWindowCallbacks::handleCloseRequest(LLWindow *window) { - //allow the window to close - return TRUE; + //allow the window to close + return TRUE; } void LLWindowCallbacks::handleQuit(LLWindow *window) @@ -84,22 +84,22 @@ void LLWindowCallbacks::handleQuit(LLWindow *window) BOOL LLWindowCallbacks::handleRightMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleMiddleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleMiddleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleOtherMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask, S32 button) @@ -114,12 +114,12 @@ BOOL LLWindowCallbacks::handleOtherMouseUp(LLWindow *window, const LLCoordGL pos BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleActivateApp(LLWindow *window, BOOL activating) { - return FALSE; + return FALSE; } void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, MASK mask) @@ -144,7 +144,7 @@ void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S3 void LLWindowCallbacks::handleFocus(LLWindow *window) { - LL_WARNS("COCOA") << "Called handleFocus proto" << LL_ENDL; + LL_WARNS("COCOA") << "Called handleFocus proto" << LL_ENDL; } void LLWindowCallbacks::handleFocusLost(LLWindow *window) @@ -155,15 +155,15 @@ void LLWindowCallbacks::handleMenuSelect(LLWindow *window, const S32 menu_item) { } -BOOL LLWindowCallbacks::handlePaint(LLWindow *window, const S32 x, const S32 y, - const S32 width, const S32 height) +BOOL LLWindowCallbacks::handlePaint(LLWindow *window, const S32 x, const S32 y, + const S32 width, const S32 height) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleDoubleClick(LLWindow *window, const LLCoordGL pos, MASK mask) { - return FALSE; + return FALSE; } void LLWindowCallbacks::handleWindowBlock(LLWindow *window) @@ -180,27 +180,27 @@ void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *da LLWindowCallbacks::DragNDropResult LLWindowCallbacks::handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, DragNDropAction action, std::string data ) { - return LLWindowCallbacks::DND_NONE; + return LLWindowCallbacks::DND_NONE; } BOOL LLWindowCallbacks::handleTimerEvent(LLWindow *window) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) { - return FALSE; + return FALSE; } BOOL LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow *window) { - return FALSE; + return FALSE; } void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg) @@ -225,7 +225,7 @@ std::string LLWindowCallbacks::translateString(const char* tag) //virtual std::string LLWindowCallbacks::translateString(const char* tag, - const std::map<std::string, std::string>& args) + const std::map<std::string, std::string>& args) { - return std::string(); + return std::string(); } diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 22a5a9e891..b7a843e748 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindowcallbacks.h * @brief OS event callback class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,69 +32,69 @@ class LLWindow; class LLWindowCallbacks { public: - virtual ~LLWindowCallbacks() {} - virtual BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated); - virtual BOOL handleTranslatedKeyUp(KEY key, MASK mask); - virtual void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); - virtual BOOL handleUnicodeChar(llwchar uni_char, MASK mask); - virtual BOOL handleUnicodeString(char *uni_str, bool editing); + virtual ~LLWindowCallbacks() {} + virtual BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated); + virtual BOOL handleTranslatedKeyUp(KEY key, MASK mask); + virtual void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); + virtual BOOL handleUnicodeChar(llwchar uni_char, MASK mask); + virtual BOOL handleUnicodeString(char *uni_str, bool editing); - virtual BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); - virtual BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - virtual void handleMouseLeave(LLWindow *window); - // return TRUE to allow window to close, which will then cause handleQuit to be called - virtual BOOL handleCloseRequest(LLWindow *window); - // window is about to be destroyed, clean up your business - virtual void handleQuit(LLWindow *window); - virtual BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); - virtual BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - virtual BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); - virtual BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - virtual BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); - virtual BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); - virtual BOOL handleActivate(LLWindow *window, BOOL activated); - virtual BOOL handleActivateApp(LLWindow *window, BOOL activating); - virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); + virtual BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); + virtual BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); + virtual void handleMouseLeave(LLWindow *window); + // return TRUE to allow window to close, which will then cause handleQuit to be called + virtual BOOL handleCloseRequest(LLWindow *window); + // window is about to be destroyed, clean up your business + virtual void handleQuit(LLWindow *window); + virtual BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); + virtual BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); + virtual BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); + virtual BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); + virtual BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); + virtual BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); + virtual BOOL handleActivate(LLWindow *window, BOOL activated); + virtual BOOL handleActivateApp(LLWindow *window, BOOL activating); + virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask); - virtual void handleScrollWheel(LLWindow *window, S32 clicks); - virtual void handleScrollHWheel(LLWindow *window, S32 clicks); - virtual void handleResize(LLWindow *window, S32 width, S32 height); - virtual void handleFocus(LLWindow *window); - virtual void handleFocusLost(LLWindow *window); - virtual void handleMenuSelect(LLWindow *window, S32 menu_item); - virtual BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height); - virtual BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); // double-click of left mouse button - virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while - virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while - virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data); - virtual BOOL handleTimerEvent(LLWindow *window); - virtual BOOL handleDeviceChange(LLWindow *window); - virtual BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); - virtual BOOL handleWindowDidChangeScreen(LLWindow *window); + virtual void handleScrollWheel(LLWindow *window, S32 clicks); + virtual void handleScrollHWheel(LLWindow *window, S32 clicks); + virtual void handleResize(LLWindow *window, S32 width, S32 height); + virtual void handleFocus(LLWindow *window); + virtual void handleFocusLost(LLWindow *window); + virtual void handleMenuSelect(LLWindow *window, S32 menu_item); + virtual BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height); + virtual BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); // double-click of left mouse button + virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while + virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while + virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data); + virtual BOOL handleTimerEvent(LLWindow *window); + virtual BOOL handleDeviceChange(LLWindow *window); + virtual BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); + virtual BOOL handleWindowDidChangeScreen(LLWindow *window); + + enum DragNDropAction { + DNDA_START_TRACKING = 0,// Start tracking an incoming drag + DNDA_TRACK, // User is dragging an incoming drag around the window + DNDA_STOP_TRACKING, // User is no longer dragging an incoming drag around the window (may have either cancelled or dropped on the window) + DNDA_DROPPED // User dropped an incoming drag on the window (this is the "commit" event) + }; + + enum DragNDropResult { + DND_NONE = 0, // No drop allowed + DND_MOVE, // Drop accepted would result in a "move" operation + DND_COPY, // Drop accepted would result in a "copy" operation + DND_LINK // Drop accepted would result in a "link" operation + }; + virtual DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, DragNDropAction action, std::string data); - enum DragNDropAction { - DNDA_START_TRACKING = 0,// Start tracking an incoming drag - DNDA_TRACK, // User is dragging an incoming drag around the window - DNDA_STOP_TRACKING, // User is no longer dragging an incoming drag around the window (may have either cancelled or dropped on the window) - DNDA_DROPPED // User dropped an incoming drag on the window (this is the "commit" event) - }; - - enum DragNDropResult { - DND_NONE = 0, // No drop allowed - DND_MOVE, // Drop accepted would result in a "move" operation - DND_COPY, // Drop accepted would result in a "copy" operation - DND_LINK // Drop accepted would result in a "link" operation - }; - virtual DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, DragNDropAction action, std::string data); - - virtual void handlePingWatchdog(LLWindow *window, const char * msg); - virtual void handlePauseWatchdog(LLWindow *window); - virtual void handleResumeWatchdog(LLWindow *window); + virtual void handlePingWatchdog(LLWindow *window, const char * msg); + virtual void handlePauseWatchdog(LLWindow *window); + virtual void handleResumeWatchdog(LLWindow *window); // Look up a localized string, usually for an error message virtual std::string translateString(const char* tag); - virtual std::string translateString(const char* tag, - const std::map<std::string, std::string>& args); + virtual std::string translateString(const char* tag, + const std::map<std::string, std::string>& args); }; diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp index c3738af6ca..bbeb710445 100644 --- a/indra/llwindow/llwindowheadless.cpp +++ b/indra/llwindow/llwindowheadless.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llwindowheadless.cpp * @brief Headless implementation of LLWindow class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,13 +34,13 @@ // LLWindowHeadless // LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, - U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) - : LLWindow(callbacks, fullscreen, flags) + U32 flags, BOOL fullscreen, BOOL clear_background, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) + : LLWindow(callbacks, fullscreen, flags) { - // Initialize a headless keyboard. - gKeyboard = new LLKeyboardHeadless(); - gKeyboard->setCallbacks(callbacks); + // Initialize a headless keyboard. + gKeyboard = new LLKeyboardHeadless(); + gKeyboard->setCallbacks(callbacks); } diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 2f2c0de5bd..af2cdb63fa 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindowheadless.h * @brief Headless definition of LLWindow class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,28 +32,28 @@ class LLWindowHeadless : public LLWindow { public: - /*virtual*/ void show() override {} - /*virtual*/ void hide() override {} - /*virtual*/ void close() override {} - /*virtual*/ BOOL getVisible() override {return FALSE;} - /*virtual*/ BOOL getMinimized() override {return FALSE;} - /*virtual*/ BOOL getMaximized() override {return FALSE;} - /*virtual*/ BOOL maximize() override {return FALSE;} - /*virtual*/ void minimize() override {} - /*virtual*/ void restore() override {} - // TODO: LLWindow::getFullscreen() is (intentionally?) NOT virtual. - // Apparently the coder of LLWindowHeadless didn't realize that. Is it a - // mistake to shadow the base-class method with an LLWindowHeadless - // override when called on the subclass, yet call the base-class method - // when indirecting through a polymorphic pointer or reference? - BOOL getFullscreen() {return FALSE;} - /*virtual*/ BOOL getPosition(LLCoordScreen *position) override {return FALSE;} - /*virtual*/ BOOL getSize(LLCoordScreen *size) override {return FALSE;} - /*virtual*/ BOOL getSize(LLCoordWindow *size) override {return FALSE;} - /*virtual*/ BOOL setPosition(LLCoordScreen position) override {return FALSE;} - /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) override {return FALSE;} - /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) override {return FALSE;} - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override {return FALSE;} + /*virtual*/ void show() override {} + /*virtual*/ void hide() override {} + /*virtual*/ void close() override {} + /*virtual*/ BOOL getVisible() override {return FALSE;} + /*virtual*/ BOOL getMinimized() override {return FALSE;} + /*virtual*/ BOOL getMaximized() override {return FALSE;} + /*virtual*/ BOOL maximize() override {return FALSE;} + /*virtual*/ void minimize() override {} + /*virtual*/ void restore() override {} + // TODO: LLWindow::getFullscreen() is (intentionally?) NOT virtual. + // Apparently the coder of LLWindowHeadless didn't realize that. Is it a + // mistake to shadow the base-class method with an LLWindowHeadless + // override when called on the subclass, yet call the base-class method + // when indirecting through a polymorphic pointer or reference? + BOOL getFullscreen() {return FALSE;} + /*virtual*/ BOOL getPosition(LLCoordScreen *position) override {return FALSE;} + /*virtual*/ BOOL getSize(LLCoordScreen *size) override {return FALSE;} + /*virtual*/ BOOL getSize(LLCoordWindow *size) override {return FALSE;} + /*virtual*/ BOOL setPosition(LLCoordScreen position) override {return FALSE;} + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) override {return FALSE;} + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) override {return FALSE;} + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override {return FALSE;} void* createSharedContext() override { return nullptr; } void makeContextCurrent(void*) override {} void destroySharedContext(void*) override {} @@ -63,56 +63,56 @@ public: #if LL_WINDOWS /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) override { return FALSE; } #endif - /*virtual*/ void showCursor() override {} - /*virtual*/ void hideCursor() override {} - /*virtual*/ void showCursorFromMouseMove() override {} - /*virtual*/ void hideCursorUntilMouseMove() override {} - /*virtual*/ BOOL isCursorHidden() override {return FALSE;} - /*virtual*/ void updateCursor() override {} - //virtual ECursorType getCursor() override { return mCurrentCursor; } - /*virtual*/ void captureMouse() override {} - /*virtual*/ void releaseMouse() override {} - /*virtual*/ void setMouseClipping( BOOL b ) override {} - /*virtual*/ BOOL isClipboardTextAvailable() override {return FALSE; } - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) override {return FALSE; } - /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) override {return FALSE; } - /*virtual*/ void flashIcon(F32 seconds) override {} - /*virtual*/ F32 getGamma() override {return 1.0f; } - /*virtual*/ BOOL setGamma(const F32 gamma) override {return FALSE; } // Set the gamma - /*virtual*/ void setFSAASamples(const U32 fsaa_samples) override { } - /*virtual*/ U32 getFSAASamples() override { return 0; } - /*virtual*/ BOOL restoreGamma() override {return FALSE; } // Restore original gamma table (before updating gamma) - //virtual ESwapMethod getSwapMethod() override { return mSwapMethod; } - /*virtual*/ void gatherInput() override {} - /*virtual*/ void delayInputProcessing() override {} - /*virtual*/ void swapBuffers() override; + /*virtual*/ void showCursor() override {} + /*virtual*/ void hideCursor() override {} + /*virtual*/ void showCursorFromMouseMove() override {} + /*virtual*/ void hideCursorUntilMouseMove() override {} + /*virtual*/ BOOL isCursorHidden() override {return FALSE;} + /*virtual*/ void updateCursor() override {} + //virtual ECursorType getCursor() override { return mCurrentCursor; } + /*virtual*/ void captureMouse() override {} + /*virtual*/ void releaseMouse() override {} + /*virtual*/ void setMouseClipping( BOOL b ) override {} + /*virtual*/ BOOL isClipboardTextAvailable() override {return FALSE; } + /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) override {return FALSE; } + /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) override {return FALSE; } + /*virtual*/ void flashIcon(F32 seconds) override {} + /*virtual*/ F32 getGamma() override {return 1.0f; } + /*virtual*/ BOOL setGamma(const F32 gamma) override {return FALSE; } // Set the gamma + /*virtual*/ void setFSAASamples(const U32 fsaa_samples) override { } + /*virtual*/ U32 getFSAASamples() override { return 0; } + /*virtual*/ BOOL restoreGamma() override {return FALSE; } // Restore original gamma table (before updating gamma) + //virtual ESwapMethod getSwapMethod() override { return mSwapMethod; } + /*virtual*/ void gatherInput() override {} + /*virtual*/ void delayInputProcessing() override {} + /*virtual*/ void swapBuffers() override; + - // handy coordinate space conversion routines - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return FALSE; } - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return FALSE; } - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override { return FALSE; } - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override { return FALSE; } - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override { return FALSE; } - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override { return FALSE; } - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; } - /*virtual*/ F32 getNativeAspectRatio() override { return 1.0f; } - /*virtual*/ F32 getPixelAspectRatio() override { return 1.0f; } - /*virtual*/ void setNativeAspectRatio(F32 ratio) override {} + /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; } + /*virtual*/ F32 getNativeAspectRatio() override { return 1.0f; } + /*virtual*/ F32 getPixelAspectRatio() override { return 1.0f; } + /*virtual*/ void setNativeAspectRatio(F32 ratio) override {} U32 getAvailableVRAMMegabytes() override { return 4096; } - /*virtual*/ void *getPlatformWindow() override { return 0; } - /*virtual*/ void bringToFront() override {} - - LLWindowHeadless(LLWindowCallbacks* callbacks, - const std::string& title, const std::string& name, - S32 x, S32 y, - S32 width, S32 height, - U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); - virtual ~LLWindowHeadless(); + /*virtual*/ void *getPlatformWindow() override { return 0; } + /*virtual*/ void bringToFront() override {} + + LLWindowHeadless(LLWindowCallbacks* callbacks, + const std::string& title, const std::string& name, + S32 x, S32 y, + S32 width, S32 height, + U32 flags, BOOL fullscreen, BOOL clear_background, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); + virtual ~LLWindowHeadless(); private: }; @@ -120,12 +120,12 @@ private: class LLSplashScreenHeadless : public LLSplashScreen { public: - LLSplashScreenHeadless() {} - virtual ~LLSplashScreenHeadless() {} + LLSplashScreenHeadless() {} + virtual ~LLSplashScreenHeadless() {} - /*virtual*/ void showImpl() override {} - /*virtual*/ void updateImpl(const std::string& mesg) override {} - /*virtual*/ void hideImpl() override {} + /*virtual*/ void showImpl() override {} + /*virtual*/ void updateImpl(const std::string& mesg) override {} + /*virtual*/ void hideImpl() override {} }; diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 77024d3a9c..31dc83493e 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -1,4 +1,4 @@ -/** +/** * @file llwindowmacosx-objc.h * @brief Prototypes for functions shared between llwindowmacosx.cpp * and llwindowmacosx-objc.mm. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,8 +40,8 @@ typedef std::vector<int> segment_lengths; typedef std::vector<int> segment_standouts; struct attributedStringInfo { - segment_lengths seg_lengths; - segment_standouts seg_standouts; + segment_lengths seg_lengths; + segment_standouts seg_standouts; }; // This will actually hold an NSCursor*, but that type is only available in objective C. @@ -57,7 +57,7 @@ struct NativeKeyEventData { KEYDOWN, KEYCHAR }; - + EventType mKeyEvent = KEYUNKNOWN; uint32_t mEventType = 0; uint32_t mEventModifiers = 0; diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 690fe058db..2e75d309ea 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -27,6 +27,7 @@ #include <AppKit/AppKit.h> #include <Cocoa/Cocoa.h> +#include <errno.h> #include "llopenglview-objc.h" #include "llwindowmacosx-objc.h" #include "llappdelegate-objc.h" diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 778e5d3898..453905b19b 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -43,11 +43,18 @@ #include <CoreServices/CoreServices.h> #include <CoreGraphics/CGDisplayConfiguration.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOMessage.h> +#include <IOKit/hid/IOHIDUsageTables.h> +#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/usb/IOUSBLib.h> + extern BOOL gDebugWindowProc; BOOL gHiDPISupport = TRUE; -const S32 BITS_PER_PIXEL = 32; -const S32 MAX_NUM_RESOLUTIONS = 32; +const S32 BITS_PER_PIXEL = 32; +const S32 MAX_NUM_RESOLUTIONS = 32; const S32 DEFAULT_REFRESH_RATE = 60; @@ -65,34 +72,34 @@ BOOL LLWindowMacOSX::sUseMultGL = FALSE; BOOL check_for_card(const char* RENDERER, const char* bad_card) { - if (!strnicmp(RENDERER, bad_card, strlen(bad_card))) - { - std::string buffer = llformat( - "Your video card appears to be a %s, which Second Life does not support.\n" - "\n" - "Second Life requires a video card with 32 Mb of memory or more, as well as\n" - "multitexture support. We explicitly support nVidia GeForce 2 or better, \n" - "and ATI Radeon 8500 or better.\n" - "\n" - "If you own a supported card and continue to receive this message, try \n" - "updating to the latest video card drivers. Otherwise look in the\n" - "secondlife.com support section or e-mail technical support\n" - "\n" - "You can try to run Second Life, but it will probably crash or run\n" - "very slowly. Try anyway?", - bad_card); - S32 button = OSMessageBox(buffer.c_str(), "Unsupported video card", OSMB_YESNO); - if (OSBTN_YES == button) - { - return FALSE; - } - else - { - return TRUE; - } - } - - return FALSE; + if (!strnicmp(RENDERER, bad_card, strlen(bad_card))) + { + std::string buffer = llformat( + "Your video card appears to be a %s, which Second Life does not support.\n" + "\n" + "Second Life requires a video card with 32 Mb of memory or more, as well as\n" + "multitexture support. We explicitly support nVidia GeForce 2 or better, \n" + "and ATI Radeon 8500 or better.\n" + "\n" + "If you own a supported card and continue to receive this message, try \n" + "updating to the latest video card drivers. Otherwise look in the\n" + "secondlife.com support section or e-mail technical support\n" + "\n" + "You can try to run Second Life, but it will probably crash or run\n" + "very slowly. Try anyway?", + bad_card); + S32 button = OSMessageBox(buffer.c_str(), "Unsupported video card", OSMB_YESNO); + if (OSBTN_YES == button) + { + return FALSE; + } + else + { + return TRUE; + } + } + + return FALSE; } // Switch to determine whether we capture all displays, or just the main one. @@ -110,93 +117,93 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key); static LLWindowMacOSX *gWindowImplementation = NULL; LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, - 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(NULL, fullscreen, flags) -{ - // *HACK: During window construction we get lots of OS events for window - // reshape, activate, etc. that the viewer isn't ready to handle. - // Route them to a dummy callback structure until the end of constructor. - LLWindowCallbacks null_callbacks; - mCallbacks = &null_callbacks; - - // Voodoo for calling cocoa from carbon (see llwindowmacosx-objc.mm). - setupCocoa(); - - // Initialize the keyboard - gKeyboard = new LLKeyboardMacOSX(); - gKeyboard->setCallbacks(callbacks); - - // Ignore use_gl for now, only used for drones on PC - mWindow = NULL; - mContext = NULL; - mPixelFormat = NULL; - mDisplay = CGMainDisplayID(); - mSimulatedRightClick = FALSE; - mLastModifiers = 0; - mHandsOffEvents = FALSE; - mCursorDecoupled = FALSE; - mCursorLastEventDeltaX = 0; - mCursorLastEventDeltaY = 0; - mCursorIgnoreNextDelta = FALSE; - mNeedsResize = FALSE; - mOverrideAspectRatio = 0.f; - mMaximized = FALSE; - mMinimized = FALSE; - mLanguageTextInputAllowed = FALSE; - mPreeditor = NULL; - mFSAASamples = fsaa_samples; - mForceRebuild = FALSE; - - // Get the original aspect ratio of the main device. - mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); - - // Stash the window title - mWindowTitle = title; - //mWindowTitle[0] = title.length(); - - mDragOverrideCursor = -1; - - // Set up global event handlers (the fullscreen case needs this) - //InstallStandardEventHandler(GetApplicationEventTarget()); - - // Stash an object pointer for OSMessageBox() - gWindowImplementation = this; - // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) - { - if(mWindow != NULL) - { - makeWindowOrderFront(mWindow); - } - - if (!gGLManager.initGL()) - { - setupFailure( - "Second Life is unable to run because your video card drivers\n" - "are out of date or unsupported. Please make sure you have\n" - "the latest video card drivers installed.\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); - return; - } + 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(NULL, fullscreen, flags) +{ + // *HACK: During window construction we get lots of OS events for window + // reshape, activate, etc. that the viewer isn't ready to handle. + // Route them to a dummy callback structure until the end of constructor. + LLWindowCallbacks null_callbacks; + mCallbacks = &null_callbacks; + + // Voodoo for calling cocoa from carbon (see llwindowmacosx-objc.mm). + setupCocoa(); + + // Initialize the keyboard + gKeyboard = new LLKeyboardMacOSX(); + gKeyboard->setCallbacks(callbacks); + + // Ignore use_gl for now, only used for drones on PC + mWindow = NULL; + mContext = NULL; + mPixelFormat = NULL; + mDisplay = CGMainDisplayID(); + mSimulatedRightClick = FALSE; + mLastModifiers = 0; + mHandsOffEvents = FALSE; + mCursorDecoupled = FALSE; + mCursorLastEventDeltaX = 0; + mCursorLastEventDeltaY = 0; + mCursorIgnoreNextDelta = FALSE; + mNeedsResize = FALSE; + mOverrideAspectRatio = 0.f; + mMaximized = FALSE; + mMinimized = FALSE; + mLanguageTextInputAllowed = FALSE; + mPreeditor = NULL; + mFSAASamples = fsaa_samples; + mForceRebuild = FALSE; + + // Get the original aspect ratio of the main device. + mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); + + // Stash the window title + mWindowTitle = title; + //mWindowTitle[0] = title.length(); + + mDragOverrideCursor = -1; + + // Set up global event handlers (the fullscreen case needs this) + //InstallStandardEventHandler(GetApplicationEventTarget()); + + // Stash an object pointer for OSMessageBox() + gWindowImplementation = this; + // Create the GL context and set it up for windowed or fullscreen, as appropriate. + if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) + { + if(mWindow != NULL) + { + makeWindowOrderFront(mWindow); + } + + if (!gGLManager.initGL()) + { + setupFailure( + "Second Life is unable to run because your video card drivers\n" + "are out of date or unsupported. Please make sure you have\n" + "the latest video card drivers installed.\n" + "If you continue to receive this message, contact customer service.", + "Error", + OSMB_OK); + return; + } //start with arrow cursor - initCursors(); - setCursor( UI_CURSOR_ARROW ); - - allowLanguageTextInput(NULL, FALSE); - } + initCursors(); + setCursor( UI_CURSOR_ARROW ); + + allowLanguageTextInput(NULL, FALSE); + } + + mCallbacks = callbacks; + stop_glerror(); + - mCallbacks = callbacks; - stop_glerror(); - - } // These functions are used as wrappers for our internal event handling callbacks. @@ -205,39 +212,42 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask) { mRawKeyEvent = event; - bool retVal = gKeyboard->handleKeyUp(key, mask); + bool retVal = gKeyboard->handleKeyUp(key, mask); mRawKeyEvent = NULL; return retVal; } bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask, wchar_t character) { - if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y')) - { - key = gKeyboard->inverseTranslateKey('Y'); - } - else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z')) + //if (mask!=MASK_NONE) { - key = gKeyboard->inverseTranslateKey('Z'); + if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y')) + { + key = gKeyboard->inverseTranslateKey('Y'); + } + else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z')) + { + key = gKeyboard->inverseTranslateKey('Z'); + } } mRawKeyEvent = event; - bool retVal = gKeyboard->handleKeyDown(key, mask); + bool retVal = gKeyboard->handleKeyDown(key, mask); mRawKeyEvent = NULL; return retVal; } void callResetKeys() { - gKeyboard->resetKeys(); + gKeyboard->resetKeys(); } bool callUnicodeCallback(wchar_t character, unsigned int mask) { NativeKeyEventData eventData; - + memset(&eventData, 0, sizeof(NativeKeyEventData)); - + eventData.mKeyEvent = NativeKeyEventData::KEYCHAR; eventData.mEventType = 0; eventData.mEventModifiers = mask; @@ -245,9 +255,9 @@ bool callUnicodeCallback(wchar_t character, unsigned int mask) eventData.mEventChars = character; eventData.mEventUnmodChars = character; eventData.mEventRepeat = false; - + mRawKeyEvent = &eventData; - + bool result = gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask); mRawKeyEvent = NULL; return result; @@ -255,18 +265,18 @@ bool callUnicodeCallback(wchar_t character, unsigned int mask) void callFocus() { - if (gWindowImplementation) - { - gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); - } + if (gWindowImplementation) + { + gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); + } } void callFocusLost() { - if (gWindowImplementation) - { - gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); - } + if (gWindowImplementation) + { + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + } } void callRightMouseDown(float *pos, MASK mask) @@ -275,11 +285,11 @@ void callRightMouseDown(float *pos, MASK mask) { gWindowImplementation->interruptLanguageTextInput(); } - - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - gWindowImplementation->getCallbacks()->handleRightMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + gWindowImplementation->getCallbacks()->handleRightMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); } void callRightMouseUp(float *pos, MASK mask) @@ -288,11 +298,11 @@ void callRightMouseUp(float *pos, MASK mask) { gWindowImplementation->interruptLanguageTextInput(); } - - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - gWindowImplementation->getCallbacks()->handleRightMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + gWindowImplementation->getCallbacks()->handleRightMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); } void callLeftMouseDown(float *pos, MASK mask) @@ -301,11 +311,11 @@ void callLeftMouseDown(float *pos, MASK mask) { gWindowImplementation->interruptLanguageTextInput(); } - - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); } void callLeftMouseUp(float *pos, MASK mask) @@ -314,12 +324,12 @@ void callLeftMouseUp(float *pos, MASK mask) { gWindowImplementation->interruptLanguageTextInput(); } - - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - gWindowImplementation->getCallbacks()->handleMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); - + + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + gWindowImplementation->getCallbacks()->handleMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + } void callDoubleClick(float *pos, MASK mask) @@ -328,37 +338,37 @@ void callDoubleClick(float *pos, MASK mask) { gWindowImplementation->interruptLanguageTextInput(); } - - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - gWindowImplementation->getCallbacks()->handleDoubleClick(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + gWindowImplementation->getCallbacks()->handleDoubleClick(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); } void callResize(unsigned int width, unsigned int height) { - if (gWindowImplementation != NULL) - { - gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); - } + if (gWindowImplementation != NULL) + { + gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); + } } void callMouseMoved(float *pos, MASK mask) { - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - float deltas[2]; - gWindowImplementation->getMouseDeltas(deltas); - outCoords.mX += deltas[0]; - outCoords.mY += deltas[1]; - gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); - //gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + float deltas[2]; + gWindowImplementation->getMouseDeltas(deltas); + outCoords.mX += deltas[0]; + outCoords.mY += deltas[1]; + gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + //gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); } void callMouseDragged(float *pos, MASK mask) { - LLCoordGL outCoords; + LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); float deltas[2]; @@ -370,78 +380,78 @@ void callMouseDragged(float *pos, MASK mask) void callScrollMoved(float deltaX, float deltaY) { - if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) - { - gWindowImplementation->getCallbacks()->handleScrollHWheel(gWindowImplementation, deltaX); - gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, deltaY); - } + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleScrollHWheel(gWindowImplementation, deltaX); + gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, deltaY); + } } void callMouseExit() { - gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation); + gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation); } void callWindowFocus() { if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) - { - gWindowImplementation->getCallbacks()->handleFocus (gWindowImplementation); - } - else - { - LL_WARNS("COCOA") << "Window Implementation or callbacks not yet initialized." << LL_ENDL; - } + { + gWindowImplementation->getCallbacks()->handleFocus (gWindowImplementation); + } + else + { + LL_WARNS("COCOA") << "Window Implementation or callbacks not yet initialized." << LL_ENDL; + } } void callWindowUnfocus() { - if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) - { - gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); - } + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + } } void callWindowHide() -{ - if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) - { - gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, false); - } +{ + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, false); + } } void callWindowUnhide() -{ - if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) - { - gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, true); - } +{ + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, true); + } } void callWindowDidChangeScreen() { - if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) - { - gWindowImplementation->getCallbacks()->handleWindowDidChangeScreen(gWindowImplementation); - } + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleWindowDidChangeScreen(gWindowImplementation); + } } void callDeltaUpdate(float *delta, MASK mask) { - gWindowImplementation->updateMouseDeltas(delta); + gWindowImplementation->updateMouseDeltas(delta); } void callOtherMouseDown(float *pos, MASK mask, int button) { - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - float deltas[2]; - gWindowImplementation->getMouseDeltas(deltas); - outCoords.mX += deltas[0]; - outCoords.mY += deltas[1]; + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + float deltas[2]; + gWindowImplementation->getMouseDeltas(deltas); + outCoords.mX += deltas[0]; + outCoords.mY += deltas[1]; if (button == 2) { @@ -455,12 +465,12 @@ void callOtherMouseDown(float *pos, MASK mask, int button) void callOtherMouseUp(float *pos, MASK mask, int button) { - LLCoordGL outCoords; - outCoords.mX = ll_round(pos[0]); - outCoords.mY = ll_round(pos[1]); - float deltas[2]; - gWindowImplementation->getMouseDeltas(deltas); - outCoords.mX += deltas[0]; + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + float deltas[2]; + gWindowImplementation->getMouseDeltas(deltas); + outCoords.mX += deltas[0]; outCoords.mY += deltas[1]; if (button == 2) { @@ -474,169 +484,169 @@ void callOtherMouseUp(float *pos, MASK mask, int button) void callModifier(MASK mask) { - gKeyboard->handleModifier(mask); + gKeyboard->handleModifier(mask); } void callHandleDragEntered(std::string url) { - gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING); + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING); } void callHandleDragExited(std::string url) { - gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING); + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING); } void callHandleDragUpdated(std::string url) { - gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK); + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK); } void callHandleDragDropped(std::string url) { - gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED); + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED); } void callQuitHandler() { - if (gWindowImplementation) - { - if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) - { - gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); - } - } + if (gWindowImplementation) + { + if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + { + gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); + } + } } void getPreeditSelectionRange(int *position, int *length) { - if (gWindowImplementation->getPreeditor()) - { - gWindowImplementation->getPreeditor()->getSelectionRange(position, length); - } + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->getSelectionRange(position, length); + } } void getPreeditMarkedRange(int *position, int *length) { - if (gWindowImplementation->getPreeditor()) - { - gWindowImplementation->getPreeditor()->getPreeditRange(position, length); - } + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->getPreeditRange(position, length); + } } void setPreeditMarkedRange(int position, int length) { - if (gWindowImplementation->getPreeditor()) - { - gWindowImplementation->getPreeditor()->markAsPreedit(position, length); - } + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->markAsPreedit(position, length); + } } bool handleUnicodeCharacter(wchar_t c) { bool success = false; - if (gWindowImplementation->getPreeditor()) - { + if (gWindowImplementation->getPreeditor()) + { success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); - } - + } + return success; } void resetPreedit() { - if (gWindowImplementation->getPreeditor()) - { - gWindowImplementation->getPreeditor()->resetPreedit(); - } + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->resetPreedit(); + } } // For reasons of convenience, handle IME updates here. // This largely mirrors the old implementation, only sans the carbon parameters. void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments) { - if (gWindowImplementation->getPreeditor()) - { - LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); - preeditor->resetPreedit(); - // This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter. - if (replacementRange[0] < replacementRange[1]) - { - const LLWString& text = preeditor->getPreeditString(); - const S32 location = wstring_wstring_length_from_utf16_length(text, 0, replacementRange[0]); - const S32 length = wstring_wstring_length_from_utf16_length(text, location, replacementRange[1]); - preeditor->markAsPreedit(location, length); - } - - LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len)); - - S32 caret_position = fix_str.length(); - - preeditor->updatePreedit(fix_str, segments.seg_lengths, segments.seg_standouts, caret_position); - } + if (gWindowImplementation->getPreeditor()) + { + LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); + preeditor->resetPreedit(); + // This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter. + if (replacementRange[0] < replacementRange[1]) + { + const LLWString& text = preeditor->getPreeditString(); + const S32 location = wstring_wstring_length_from_utf16_length(text, 0, replacementRange[0]); + const S32 length = wstring_wstring_length_from_utf16_length(text, location, replacementRange[1]); + preeditor->markAsPreedit(location, length); + } + + LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len)); + + S32 caret_position = fix_str.length(); + + preeditor->updatePreedit(fix_str, segments.seg_lengths, segments.seg_standouts, caret_position); + } } void getPreeditLocation(float *location, unsigned int length) { - if (gWindowImplementation->getPreeditor()) - { - LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); - LLCoordGL coord; - LLCoordScreen screen; - LLRect rect; - - preeditor->getPreeditLocation(length, &coord, &rect, NULL); - - float c[4] = {float(coord.mX), float(coord.mY), 0, 0}; - - convertRectToScreen(gWindowImplementation->getWindow(), c); - - location[0] = c[0]; - location[1] = c[1]; - } + if (gWindowImplementation->getPreeditor()) + { + LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); + LLCoordGL coord; + LLCoordScreen screen; + LLRect rect; + + preeditor->getPreeditLocation(length, &coord, &rect, NULL); + + float c[4] = {float(coord.mX), float(coord.mY), 0, 0}; + + convertRectToScreen(gWindowImplementation->getWindow(), c); + + location[0] = c[0]; + location[1] = c[1]; + } } void LLWindowMacOSX::updateMouseDeltas(float* deltas) { - if (mCursorDecoupled) - { - mCursorLastEventDeltaX = ll_round(deltas[0]); - mCursorLastEventDeltaY = ll_round(-deltas[1]); - - if (mCursorIgnoreNextDelta) - { - mCursorLastEventDeltaX = 0; - mCursorLastEventDeltaY = 0; - mCursorIgnoreNextDelta = FALSE; - } - } else { - mCursorLastEventDeltaX = 0; - mCursorLastEventDeltaY = 0; - } + if (mCursorDecoupled) + { + mCursorLastEventDeltaX = ll_round(deltas[0]); + mCursorLastEventDeltaY = ll_round(-deltas[1]); + + if (mCursorIgnoreNextDelta) + { + mCursorLastEventDeltaX = 0; + mCursorLastEventDeltaY = 0; + mCursorIgnoreNextDelta = FALSE; + } + } else { + mCursorLastEventDeltaX = 0; + mCursorLastEventDeltaY = 0; + } } void LLWindowMacOSX::getMouseDeltas(float* delta) { - delta[0] = mCursorLastEventDeltaX; - delta[1] = mCursorLastEventDeltaY; + delta[0] = mCursorLastEventDeltaX; + delta[1] = mCursorLastEventDeltaY; } BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync) { - mFullscreen = fullscreen; - - if (mWindow == NULL) - { - mWindow = getMainAppWindow(); - } - - if(mContext == NULL) - { - // Our OpenGL view is already defined within SecondLife.xib. - // Get the view instead. - mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync); - mContext = getCGLContextObj(mGLView); - gGLManager.mVRAM = getVramSize(mGLView); + mFullscreen = fullscreen; + + if (mWindow == NULL) + { + mWindow = getMainAppWindow(); + } + + if(mContext == NULL) + { + // Our OpenGL view is already defined within SecondLife.xib. + // Get the view instead. + mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync); + mContext = getCGLContextObj(mGLView); + gGLManager.mVRAM = getVramSize(mGLView); if(!mPixelFormat) { @@ -659,30 +669,30 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits GLint numPixelFormats; CGLChoosePixelFormat (attribs, &mPixelFormat, &numPixelFormats); - + if(mPixelFormat == NULL) { CGLChoosePixelFormat (attribs, &mPixelFormat, &numPixelFormats); } } - } - - // This sets up our view to recieve text from our non-inline text input window. - setupInputWindow(mWindow, mGLView); - - // Hook up the context to a drawable - - if(mContext != NULL) - { - - - U32 err = CGLSetCurrentContext(mContext); - if (err != kCGLNoError) - { - setupFailure("Can't activate GL rendering context", "Error", OSMB_OK); - return FALSE; - } - } + } + + // This sets up our view to recieve text from our non-inline text input window. + setupInputWindow(mWindow, mGLView); + + // Hook up the context to a drawable + + if(mContext != NULL) + { + + + U32 err = CGLSetCurrentContext(mContext); + if (err != kCGLNoError) + { + setupFailure("Can't activate GL rendering context", "Error", OSMB_OK); + return FALSE; + } + } mRefreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(mDisplay)); if(mRefreshRate == 0) @@ -691,29 +701,29 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits mRefreshRate = DEFAULT_REFRESH_RATE; } - // Disable vertical sync for swap + // Disable vertical sync for swap toggleVSync(enable_vsync); - //enable multi-threaded OpenGL - if (sUseMultGL) - { - CGLError cgl_err; - CGLContextObj ctx = CGLGetCurrentContext(); + //enable multi-threaded OpenGL + if (sUseMultGL) + { + CGLError cgl_err; + CGLContextObj ctx = CGLGetCurrentContext(); - cgl_err = CGLEnable( ctx, kCGLCEMPEngine); + cgl_err = CGLEnable( ctx, kCGLCEMPEngine); - if (cgl_err != kCGLNoError ) - { - LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; - } - else - { + if (cgl_err != kCGLNoError ) + { + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + } + else + { LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; - } - } - makeFirstResponder(mWindow, mGLView); - - return TRUE; + } + } + makeFirstResponder(mWindow, mGLView); + + return TRUE; } @@ -721,66 +731,66 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // This makes this method obsolete. BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp) { - return FALSE; + return FALSE; } void LLWindowMacOSX::destroyContext() { - if (!mContext) - { - // We don't have a context - return; - } - // Unhook the GL context from any drawable it may have - if(mContext != NULL) - { - LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL; - CGLSetCurrentContext(NULL); - } - - // Clean up remaining GL state before blowing away window - gGLManager.shutdownGL(); - - // Clean up the pixel format - if(mPixelFormat != NULL) - { - CGLDestroyPixelFormat(mPixelFormat); - mPixelFormat = NULL; - } - - // Clean up the GL context - if(mContext != NULL) - { - CGLDestroyContext(mContext); - } - - // Destroy our LLOpenGLView - if(mGLView != NULL) - { - removeGLView(mGLView); - mGLView = NULL; - } - - // Close the window - if(mWindow != NULL) - { + if (!mContext) + { + // We don't have a context + return; + } + // Unhook the GL context from any drawable it may have + if(mContext != NULL) + { + LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL; + CGLSetCurrentContext(NULL); + } + + // Clean up remaining GL state before blowing away window + gGLManager.shutdownGL(); + + // Clean up the pixel format + if(mPixelFormat != NULL) + { + CGLDestroyPixelFormat(mPixelFormat); + mPixelFormat = NULL; + } + + // Clean up the GL context + if(mContext != NULL) + { + CGLDestroyContext(mContext); + } + + // Destroy our LLOpenGLView + if(mGLView != NULL) + { + removeGLView(mGLView); + mGLView = NULL; + } + + // Close the window + if(mWindow != NULL) + { NSWindowRef dead_window = mWindow; mWindow = NULL; - closeWindow(dead_window); - } + closeWindow(dead_window); + } } LLWindowMacOSX::~LLWindowMacOSX() { - destroyContext(); + destroyContext(); - if(mSupportedResolutions != NULL) - { - delete []mSupportedResolutions; - } + if(mSupportedResolutions != NULL) + { + delete []mSupportedResolutions; + } - gWindowImplementation = NULL; + gWindowImplementation = NULL; } @@ -791,20 +801,20 @@ void LLWindowMacOSX::show() void LLWindowMacOSX::hide() { - setMouseClipping(FALSE); + setMouseClipping(FALSE); } //virtual void LLWindowMacOSX::minimize() { - setMouseClipping(FALSE); - showCursor(); + setMouseClipping(FALSE); + showCursor(); } //virtual void LLWindowMacOSX::restore() { - show(); + show(); } @@ -812,193 +822,193 @@ void LLWindowMacOSX::restore() // Usually called from LLWindowManager::destroyWindow() void LLWindowMacOSX::close() { - // Is window is already closed? - // if (!mWindow) - // { - // return; - // } + // Is window is already closed? + // if (!mWindow) + // { + // return; + // } - // Make sure cursor is visible and we haven't mangled the clipping state. - setMouseClipping(FALSE); - showCursor(); + // Make sure cursor is visible and we haven't mangled the clipping state. + setMouseClipping(FALSE); + showCursor(); - destroyContext(); + destroyContext(); } BOOL LLWindowMacOSX::isValid() { - if(mFullscreen) - { - return(TRUE); - } + if(mFullscreen) + { + return(TRUE); + } - return (mWindow != NULL); + return (mWindow != NULL); } BOOL LLWindowMacOSX::getVisible() { - BOOL result = FALSE; + BOOL result = FALSE; - if(mFullscreen) - { - result = TRUE; - }if (mWindow) - { - result = TRUE; - } + if(mFullscreen) + { + result = TRUE; + }if (mWindow) + { + result = TRUE; + } - return(result); + return(result); } BOOL LLWindowMacOSX::getMinimized() { - return mMinimized; + return mMinimized; } BOOL LLWindowMacOSX::getMaximized() { - return mMaximized; + return mMaximized; } BOOL LLWindowMacOSX::maximize() { - if (mWindow && !mMaximized) - { - } + if (mWindow && !mMaximized) + { + } - return mMaximized; + return mMaximized; } BOOL LLWindowMacOSX::getFullscreen() { - return mFullscreen; + return mFullscreen; } void LLWindowMacOSX::gatherInput() { - updateCursor(); + updateCursor(); } BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position) { - S32 err = -1; + S32 err = -1; - if(mFullscreen) - { - position->mX = 0; - position->mY = 0; - err = noErr; - } - else if(mWindow) - { - const CGPoint & pos = getContentViewBoundsPosition(mWindow); + if(mFullscreen) + { + position->mX = 0; + position->mY = 0; + err = noErr; + } + else if(mWindow) + { + const CGPoint & pos = getContentViewBoundsPosition(mWindow); - position->mX = pos.x; - position->mY = pos.y; + position->mX = pos.x; + position->mY = pos.y; - err = noErr; - } - else - { - LL_ERRS() << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << LL_ENDL; - } + err = noErr; + } + else + { + LL_ERRS() << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << LL_ENDL; + } - return (err == noErr); + return (err == noErr); } BOOL LLWindowMacOSX::getSize(LLCoordScreen *size) { - S32 err = -1; + S32 err = -1; - if(mFullscreen) - { - size->mX = mFullscreenWidth; - size->mY = mFullscreenHeight; - err = noErr; - } - else if(mWindow) - { - const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow); + if(mFullscreen) + { + size->mX = mFullscreenWidth; + size->mY = mFullscreenHeight; + err = noErr; + } + else if(mWindow) + { + const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow); - size->mX = sz.width; - size->mY = sz.height; + size->mX = sz.width; + size->mY = sz.height; err = noErr; - } - else - { - LL_ERRS() << "LLWindowMacOSX::getSize(): no window and not fullscreen!" << LL_ENDL; - } + } + else + { + LL_ERRS() << "LLWindowMacOSX::getSize(): no window and not fullscreen!" << LL_ENDL; + } - return (err == noErr); + return (err == noErr); } BOOL LLWindowMacOSX::getSize(LLCoordWindow *size) { - S32 err = -1; - - if(mFullscreen) - { - size->mX = mFullscreenWidth; - size->mY = mFullscreenHeight; - err = noErr; - } - else if(mWindow) - { - const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow); - - size->mX = sz.width; - size->mY = sz.height; + S32 err = -1; + + if(mFullscreen) + { + size->mX = mFullscreenWidth; + size->mY = mFullscreenHeight; + err = noErr; + } + else if(mWindow) + { + const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow); + + size->mX = sz.width; + size->mY = sz.height; err = noErr; - - - } - else - { - LL_ERRS() << "LLWindowMacOSX::getSize(): no window and not fullscreen!" << LL_ENDL; - } - - return (err == noErr); + + + } + else + { + LL_ERRS() << "LLWindowMacOSX::getSize(): no window and not fullscreen!" << LL_ENDL; + } + + return (err == noErr); } BOOL LLWindowMacOSX::setPosition(const LLCoordScreen position) { - if(mWindow) - { - float pos[2] = {float(position.mX), float(position.mY)}; - setWindowPos(mWindow, pos); - } + if(mWindow) + { + float pos[2] = {float(position.mX), float(position.mY)}; + setWindowPos(mWindow, pos); + } - return TRUE; + return TRUE; } BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size) { - if(mWindow) - { + if(mWindow) + { LLCoordWindow to; convertCoords(size, &to); - setWindowSize(mWindow, to.mX, to.mY); + setWindowSize(mWindow, to.mX, to.mY); return TRUE; - } + } - return FALSE; + return FALSE; } BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size) { - if (mWindow) - { + if (mWindow) + { const int titlePadding = 22; setWindowSize(mWindow, size.mX, size.mY + titlePadding); return TRUE; - } - - return FALSE; + } + + return FALSE; } void LLWindowMacOSX::swapBuffers() { - CGLFlushDrawable(mContext); + CGLFlushDrawable(mContext); } void LLWindowMacOSX::restoreGLContext() @@ -1008,106 +1018,106 @@ void LLWindowMacOSX::restoreGLContext() F32 LLWindowMacOSX::getGamma() { - F32 result = 2.2; // Default to something sane - - CGGammaValue redMin; - CGGammaValue redMax; - CGGammaValue redGamma; - CGGammaValue greenMin; - CGGammaValue greenMax; - CGGammaValue greenGamma; - CGGammaValue blueMin; - CGGammaValue blueMax; - CGGammaValue blueGamma; - - if(CGGetDisplayTransferByFormula( - mDisplay, - &redMin, - &redMax, - &redGamma, - &greenMin, - &greenMax, - &greenGamma, - &blueMin, - &blueMax, - &blueGamma) == noErr) - { - // So many choices... - // Let's just return the green channel gamma for now. - result = greenGamma; - } - - return result; + F32 result = 2.2; // Default to something sane + + CGGammaValue redMin; + CGGammaValue redMax; + CGGammaValue redGamma; + CGGammaValue greenMin; + CGGammaValue greenMax; + CGGammaValue greenGamma; + CGGammaValue blueMin; + CGGammaValue blueMax; + CGGammaValue blueGamma; + + if(CGGetDisplayTransferByFormula( + mDisplay, + &redMin, + &redMax, + &redGamma, + &greenMin, + &greenMax, + &greenGamma, + &blueMin, + &blueMax, + &blueGamma) == noErr) + { + // So many choices... + // Let's just return the green channel gamma for now. + result = greenGamma; + } + + return result; } U32 LLWindowMacOSX::getFSAASamples() { - return mFSAASamples; + return mFSAASamples; } void LLWindowMacOSX::setFSAASamples(const U32 samples) { - mFSAASamples = samples; - mForceRebuild = TRUE; + mFSAASamples = samples; + mForceRebuild = TRUE; } BOOL LLWindowMacOSX::restoreGamma() { - CGDisplayRestoreColorSyncSettings(); - return true; + CGDisplayRestoreColorSyncSettings(); + return true; } BOOL LLWindowMacOSX::setGamma(const F32 gamma) { - CGGammaValue redMin; - CGGammaValue redMax; - CGGammaValue redGamma; - CGGammaValue greenMin; - CGGammaValue greenMax; - CGGammaValue greenGamma; - CGGammaValue blueMin; - CGGammaValue blueMax; - CGGammaValue blueGamma; - - // MBW -- XXX -- Should we allow this in windowed mode? - - if(CGGetDisplayTransferByFormula( - mDisplay, - &redMin, - &redMax, - &redGamma, - &greenMin, - &greenMax, - &greenGamma, - &blueMin, - &blueMax, - &blueGamma) != noErr) - { - return false; - } - - if(CGSetDisplayTransferByFormula( - mDisplay, - redMin, - redMax, - gamma, - greenMin, - greenMax, - gamma, - blueMin, - blueMax, - gamma) != noErr) - { - return false; - } - - - return true; + CGGammaValue redMin; + CGGammaValue redMax; + CGGammaValue redGamma; + CGGammaValue greenMin; + CGGammaValue greenMax; + CGGammaValue greenGamma; + CGGammaValue blueMin; + CGGammaValue blueMax; + CGGammaValue blueGamma; + + // MBW -- XXX -- Should we allow this in windowed mode? + + if(CGGetDisplayTransferByFormula( + mDisplay, + &redMin, + &redMax, + &redGamma, + &greenMin, + &greenMax, + &greenGamma, + &blueMin, + &blueMax, + &blueGamma) != noErr) + { + return false; + } + + if(CGSetDisplayTransferByFormula( + mDisplay, + redMin, + redMax, + gamma, + greenMin, + greenMax, + gamma, + blueMin, + blueMax, + gamma) != noErr) + { + return false; + } + + + return true; } BOOL LLWindowMacOSX::isCursorHidden() { - return mCursorHidden; + return mCursorHidden; } @@ -1115,142 +1125,142 @@ BOOL LLWindowMacOSX::isCursorHidden() // Constrains the mouse to the window. void LLWindowMacOSX::setMouseClipping( BOOL b ) { - // Just stash the requested state. We'll simulate this when the cursor is hidden by decoupling. - mIsMouseClipping = b; + // Just stash the requested state. We'll simulate this when the cursor is hidden by decoupling. + mIsMouseClipping = b; - if(b) - { - // LL_INFOS() << "setMouseClipping(TRUE)" << LL_ENDL; - } - else - { - // LL_INFOS() << "setMouseClipping(FALSE)" << LL_ENDL; - } + if(b) + { + // LL_INFOS() << "setMouseClipping(TRUE)" << LL_ENDL; + } + else + { + // LL_INFOS() << "setMouseClipping(FALSE)" << LL_ENDL; + } - adjustCursorDecouple(); + adjustCursorDecouple(); } BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) { - BOOL result = FALSE; - LLCoordScreen screen_pos; + BOOL result = FALSE; + LLCoordScreen screen_pos; - if (!convertCoords(position, &screen_pos)) - { - return FALSE; - } + if (!convertCoords(position, &screen_pos)) + { + return FALSE; + } - CGPoint newPosition; + CGPoint newPosition; - // LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL; + // LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL; - newPosition.x = screen_pos.mX; - newPosition.y = screen_pos.mY; + newPosition.x = screen_pos.mX; + newPosition.y = screen_pos.mY; - CGSetLocalEventsSuppressionInterval(0.0); - if(CGWarpMouseCursorPosition(newPosition) == noErr) - { - result = TRUE; - } + CGSetLocalEventsSuppressionInterval(0.0); + if(CGWarpMouseCursorPosition(newPosition) == noErr) + { + result = TRUE; + } - // Under certain circumstances, this will trigger us to decouple the cursor. - adjustCursorDecouple(true); + // Under certain circumstances, this will trigger us to decouple the cursor. + adjustCursorDecouple(true); - // trigger mouse move callback - LLCoordGL gl_pos; - convertCoords(position, &gl_pos); - float scale = getSystemUISize(); - gl_pos.mX *= scale; - gl_pos.mY *= scale; - mCallbacks->handleMouseMove(this, gl_pos, (MASK)0); + // trigger mouse move callback + LLCoordGL gl_pos; + convertCoords(position, &gl_pos); + float scale = getSystemUISize(); + gl_pos.mX *= scale; + gl_pos.mY *= scale; + mCallbacks->handleMouseMove(this, gl_pos, (MASK)0); - return result; + return result; } BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) { - float cursor_point[2]; - LLCoordScreen screen_pos; + float cursor_point[2]; + LLCoordScreen screen_pos; + + if(mWindow == NULL) + return FALSE; - if(mWindow == NULL) - return FALSE; - - getCursorPos(mWindow, cursor_point); + getCursorPos(mWindow, cursor_point); - if(mCursorDecoupled) - { - // CGMouseDelta x, y; + if(mCursorDecoupled) + { + // CGMouseDelta x, y; - // If the cursor's decoupled, we need to read the latest movement delta as well. - // CGGetLastMouseDelta( &x, &y ); - // cursor_point.h += x; - // cursor_point.v += y; + // If the cursor's decoupled, we need to read the latest movement delta as well. + // CGGetLastMouseDelta( &x, &y ); + // cursor_point.h += x; + // cursor_point.v += y; - // CGGetLastMouseDelta may behave strangely when the cursor's first captured. - // Stash in the event handler instead. - cursor_point[0] += mCursorLastEventDeltaX; - cursor_point[1] += mCursorLastEventDeltaY; - } + // CGGetLastMouseDelta may behave strangely when the cursor's first captured. + // Stash in the event handler instead. + cursor_point[0] += mCursorLastEventDeltaX; + cursor_point[1] += mCursorLastEventDeltaY; + } - float scale = getSystemUISize(); - position->mX = cursor_point[0] * scale; - position->mY = cursor_point[1] * scale; + float scale = getSystemUISize(); + position->mX = cursor_point[0] * scale; + position->mY = cursor_point[1] * scale; - return TRUE; + return TRUE; } void LLWindowMacOSX::adjustCursorDecouple(bool warpingMouse) { - if(mIsMouseClipping && mCursorHidden) - { - if(warpingMouse) - { - // The cursor should be decoupled. Make sure it is. - if(!mCursorDecoupled) - { - // LL_INFOS() << "adjustCursorDecouple: decoupling cursor" << LL_ENDL; - CGAssociateMouseAndMouseCursorPosition(false); - mCursorDecoupled = true; - mCursorIgnoreNextDelta = TRUE; - } - } - } - else - { - // The cursor should not be decoupled. Make sure it isn't. - if(mCursorDecoupled) - { - // LL_INFOS() << "adjustCursorDecouple: recoupling cursor" << LL_ENDL; - CGAssociateMouseAndMouseCursorPosition(true); - mCursorDecoupled = false; - } - } + if(mIsMouseClipping && mCursorHidden) + { + if(warpingMouse) + { + // The cursor should be decoupled. Make sure it is. + if(!mCursorDecoupled) + { + // LL_INFOS() << "adjustCursorDecouple: decoupling cursor" << LL_ENDL; + CGAssociateMouseAndMouseCursorPosition(false); + mCursorDecoupled = true; + mCursorIgnoreNextDelta = TRUE; + } + } + } + else + { + // The cursor should not be decoupled. Make sure it isn't. + if(mCursorDecoupled) + { + // LL_INFOS() << "adjustCursorDecouple: recoupling cursor" << LL_ENDL; + CGAssociateMouseAndMouseCursorPosition(true); + mCursorDecoupled = false; + } + } } F32 LLWindowMacOSX::getNativeAspectRatio() { - if (mFullscreen) - { - return (F32)mFullscreenWidth / (F32)mFullscreenHeight; - } - else - { - // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution - // switching, and stashes it in mOriginalAspectRatio. Here, we just return it. + if (mFullscreen) + { + return (F32)mFullscreenWidth / (F32)mFullscreenHeight; + } + else + { + // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution + // switching, and stashes it in mOriginalAspectRatio. Here, we just return it. - if (mOverrideAspectRatio > 0.f) - { - return mOverrideAspectRatio; - } + if (mOverrideAspectRatio > 0.f) + { + return mOverrideAspectRatio; + } - return mOriginalAspectRatio; - } + return mOriginalAspectRatio; + } } F32 LLWindowMacOSX::getPixelAspectRatio() { - //OS X always enforces a 1:1 pixel aspect ratio, regardless of video mode - return 1.f; + //OS X always enforces a 1:1 pixel aspect ratio, regardless of video mode + return 1.f; } U32 LLWindowMacOSX::getAvailableVRAMMegabytes() { @@ -1281,165 +1291,165 @@ void LLWindowMacOSX::afterDialog() void LLWindowMacOSX::flashIcon(F32 seconds) { - // For consistency with OS X conventions, the number of seconds given is ignored and - // left up to the OS (which will actually bounce it for one second). - requestUserAttention(); + // For consistency with OS X conventions, the number of seconds given is ignored and + // left up to the OS (which will actually bounce it for one second). + requestUserAttention(); } BOOL LLWindowMacOSX::isClipboardTextAvailable() { - return pasteBoardAvailable(); + return pasteBoardAvailable(); } BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) { unsigned short* pboard_data = copyFromPBoard(); // must free returned data - llutf16string str(pboard_data); + llutf16string str(pboard_data); free(pboard_data); - dst = utf16str_to_wstring(str); - if (dst != L"") - { - return true; - } else { - return false; - } + dst = utf16str_to_wstring(str); + if (dst != L"") + { + return true; + } else { + return false; + } } BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s) { - BOOL result = false; - llutf16string utf16str = wstring_to_utf16str(s); - - result = copyToPBoard(utf16str.data(), utf16str.length()); + BOOL result = false; + llutf16string utf16str = wstring_to_utf16str(s); - return result; + result = copyToPBoard(utf16str.data(), utf16str.length()); + + return result; } // protected BOOL LLWindowMacOSX::resetDisplayResolution() { - // This is only called from elsewhere in this class, and it's not used by the Mac implementation. - return true; + // This is only called from elsewhere in this class, and it's not used by the Mac implementation. + return true; } LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_resolutions) { - if (!mSupportedResolutions) - { - CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr); - - if(modes != NULL) - { - CFIndex index, cnt; - - mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; - mNumSupportedResolutions = 0; - - // Examine each mode - cnt = CFArrayGetCount( modes ); - - for ( index = 0; (index < cnt) && (mNumSupportedResolutions < MAX_NUM_RESOLUTIONS); index++ ) - { - // Pull the mode dictionary out of the CFArray - CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex( modes, index ); - long width = getDictLong(mode, kCGDisplayWidth); - long height = getDictLong(mode, kCGDisplayHeight); - long bits = getDictLong(mode, kCGDisplayBitsPerPixel); - - if(bits == BITS_PER_PIXEL && width >= 800 && height >= 600) - { - BOOL resolution_exists = FALSE; - for(S32 i = 0; i < mNumSupportedResolutions; i++) - { - if (mSupportedResolutions[i].mWidth == width && - mSupportedResolutions[i].mHeight == height) - { - resolution_exists = TRUE; - } - } - if (!resolution_exists) - { - mSupportedResolutions[mNumSupportedResolutions].mWidth = width; - mSupportedResolutions[mNumSupportedResolutions].mHeight = height; - mNumSupportedResolutions++; - } - } - } + if (!mSupportedResolutions) + { + CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr); + + if(modes != NULL) + { + CFIndex index, cnt; + + mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; + mNumSupportedResolutions = 0; + + // Examine each mode + cnt = CFArrayGetCount( modes ); + + for ( index = 0; (index < cnt) && (mNumSupportedResolutions < MAX_NUM_RESOLUTIONS); index++ ) + { + // Pull the mode dictionary out of the CFArray + CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex( modes, index ); + long width = getDictLong(mode, kCGDisplayWidth); + long height = getDictLong(mode, kCGDisplayHeight); + long bits = getDictLong(mode, kCGDisplayBitsPerPixel); + + if(bits == BITS_PER_PIXEL && width >= 800 && height >= 600) + { + BOOL resolution_exists = FALSE; + for(S32 i = 0; i < mNumSupportedResolutions; i++) + { + if (mSupportedResolutions[i].mWidth == width && + mSupportedResolutions[i].mHeight == height) + { + resolution_exists = TRUE; + } + } + if (!resolution_exists) + { + mSupportedResolutions[mNumSupportedResolutions].mWidth = width; + mSupportedResolutions[mNumSupportedResolutions].mHeight = height; + mNumSupportedResolutions++; + } + } + } CFRelease(modes); - } - } + } + } - num_resolutions = mNumSupportedResolutions; - return mSupportedResolutions; + num_resolutions = mNumSupportedResolutions; + return mSupportedResolutions; } BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to) { - to->mX = from.mX; - to->mY = from.mY; - return TRUE; + to->mX = from.mX; + to->mY = from.mY; + return TRUE; } BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to) { - to->mX = from.mX; - to->mY = from.mY; - return TRUE; + to->mX = from.mX; + to->mY = from.mY; + return TRUE; } BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to) { - if(mWindow) - { - float mouse_point[2]; + if(mWindow) + { + float mouse_point[2]; - mouse_point[0] = from.mX; - mouse_point[1] = from.mY; - - convertScreenToWindow(mWindow, mouse_point); + mouse_point[0] = from.mX; + mouse_point[1] = from.mY; - to->mX = mouse_point[0]; - to->mY = mouse_point[1]; + convertScreenToWindow(mWindow, mouse_point); - return TRUE; - } - return FALSE; + to->mX = mouse_point[0]; + to->mY = mouse_point[1]; + + return TRUE; + } + return FALSE; } BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to) { - if(mWindow) - { - float mouse_point[2]; + if(mWindow) + { + float mouse_point[2]; - mouse_point[0] = from.mX; - mouse_point[1] = from.mY; - - convertWindowToScreen(mWindow, mouse_point); + mouse_point[0] = from.mX; + mouse_point[1] = from.mY; - to->mX = mouse_point[0]; - to->mY = mouse_point[1]; + convertWindowToScreen(mWindow, mouse_point); - return TRUE; - } - return FALSE; + to->mX = mouse_point[0]; + to->mY = mouse_point[1]; + + return TRUE; + } + return FALSE; } BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to) { - LLCoordWindow window_coord; + LLCoordWindow window_coord; - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); } BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to) { - LLCoordWindow window_coord; + LLCoordWindow window_coord; - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); } @@ -1447,66 +1457,66 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to) void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& caption, U32 type) { - destroyContext(); + destroyContext(); - OSMessageBox(text, caption, type); + OSMessageBox(text, caption, type); } - // Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature - // it is handled at a very low-level + // Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature + // it is handled at a very low-level const char* cursorIDToName(int id) { - switch (id) - { - case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW"; - case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT"; - case UI_CURSOR_HAND: return "UI_CURSOR_HAND"; - case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM"; - case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS"; - case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE"; - case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW"; - case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE"; - case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS"; - case UI_CURSOR_SIZEALL: return "UI_CURSOR_SIZEALL"; - case UI_CURSOR_NO: return "UI_CURSOR_NO"; - case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING"; - case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB"; - case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND"; - case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS"; - case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE"; - case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG"; - case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY"; - case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI"; - case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI"; - case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED"; - case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED"; - case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED"; - case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE"; - case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE"; - case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE"; - case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA"; - case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN"; - case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN"; - case UI_CURSOR_TOOLZOOMOUT: return "UI_CURSOR_TOOLZOOMOUT"; - case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3"; - case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; - case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; - case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; - case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; - case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT"; - case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; - case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; - case UI_CURSOR_TOOLPATHFINDING: return "UI_CURSOR_PATHFINDING"; - case UI_CURSOR_TOOLPATHFINDING_PATH_START: return "UI_CURSOR_PATHFINDING_START"; - case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: return "UI_CURSOR_PATHFINDING_START_ADD"; - case UI_CURSOR_TOOLPATHFINDING_PATH_END: return "UI_CURSOR_PATHFINDING_END"; - case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: return "UI_CURSOR_PATHFINDING_END_ADD"; - case UI_CURSOR_TOOLNO: return "UI_CURSOR_NO"; - } - - LL_ERRS() << "cursorIDToName: unknown cursor id" << id << LL_ENDL; - - return "UI_CURSOR_ARROW"; + switch (id) + { + case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW"; + case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT"; + case UI_CURSOR_HAND: return "UI_CURSOR_HAND"; + case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM"; + case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS"; + case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE"; + case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW"; + case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE"; + case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS"; + case UI_CURSOR_SIZEALL: return "UI_CURSOR_SIZEALL"; + case UI_CURSOR_NO: return "UI_CURSOR_NO"; + case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING"; + case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB"; + case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND"; + case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS"; + case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE"; + case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG"; + case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY"; + case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI"; + case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI"; + case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED"; + case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED"; + case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED"; + case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE"; + case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE"; + case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE"; + case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA"; + case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN"; + case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN"; + case UI_CURSOR_TOOLZOOMOUT: return "UI_CURSOR_TOOLZOOMOUT"; + case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3"; + case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; + case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; + case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; + case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; + case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT"; + case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; + case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; + case UI_CURSOR_TOOLPATHFINDING: return "UI_CURSOR_PATHFINDING"; + case UI_CURSOR_TOOLPATHFINDING_PATH_START: return "UI_CURSOR_PATHFINDING_START"; + case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: return "UI_CURSOR_PATHFINDING_START_ADD"; + case UI_CURSOR_TOOLPATHFINDING_PATH_END: return "UI_CURSOR_PATHFINDING_END"; + case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: return "UI_CURSOR_PATHFINDING_END_ADD"; + case UI_CURSOR_TOOLNO: return "UI_CURSOR_NO"; + } + + LL_ERRS() << "cursorIDToName: unknown cursor id" << id << LL_ENDL; + + return "UI_CURSOR_ARROW"; } static CursorRef gCursors[UI_CURSOR_COUNT]; @@ -1514,233 +1524,233 @@ static CursorRef gCursors[UI_CURSOR_COUNT]; static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY) { - // cursors are in <Application Bundle>/Contents/Resources/cursors_mac/UI_CURSOR_FOO.tif - std::string fullpath = gDirUtilp->add( - gDirUtilp->getAppRODataDir(), - "cursors_mac", - cursorIDToName(cursorid) + std::string(".tif")); + // cursors are in <Application Bundle>/Contents/Resources/cursors_mac/UI_CURSOR_FOO.tif + std::string fullpath = gDirUtilp->add( + gDirUtilp->getAppRODataDir(), + "cursors_mac", + cursorIDToName(cursorid) + std::string(".tif")); - gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY); + gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY); } void LLWindowMacOSX::updateCursor() { - S32 result = 0; - - if (mDragOverrideCursor != -1) - { - // A drag is in progress...remember the requested cursor and we'll - // restore it when it is done - mCurrentCursor = mNextCursor; - return; - } - - if (mNextCursor == UI_CURSOR_ARROW - && mBusyCount > 0) - { - mNextCursor = UI_CURSOR_WORKING; - } - + S32 result = 0; + + if (mDragOverrideCursor != -1) + { + // A drag is in progress...remember the requested cursor and we'll + // restore it when it is done + mCurrentCursor = mNextCursor; + return; + } + + if (mNextCursor == UI_CURSOR_ARROW + && mBusyCount > 0) + { + mNextCursor = UI_CURSOR_WORKING; + } + if(mCurrentCursor == mNextCursor) { if(mCursorHidden && mHideCursorPermanent && isCGCursorVisible()) { - hideNSCursor(); + hideNSCursor(); adjustCursorDecouple(); } return; } - // RN: replace multi-drag cursors with single versions - if (mNextCursor == UI_CURSOR_ARROWDRAGMULTI) - { - mNextCursor = UI_CURSOR_ARROWDRAG; - } - else if (mNextCursor == UI_CURSOR_ARROWCOPYMULTI) - { - mNextCursor = UI_CURSOR_ARROWCOPY; - } - - switch(mNextCursor) - { - default: - case UI_CURSOR_ARROW: - setArrowCursor(); - if(mCursorHidden) - { - // Since InitCursor resets the hide level, correct for it here. - hideNSCursor(); - } - break; - - // MBW -- XXX -- Some of the standard Windows cursors have no standard Mac equivalents. - // Find out what they look like and replicate them. - - // These are essentially correct - case UI_CURSOR_WAIT: /* Apple purposely doesn't allow us to set the beachball cursor manually. Let NSApp figure out when to do this. */ break; - case UI_CURSOR_IBEAM: setIBeamCursor(); break; - case UI_CURSOR_CROSS: setCrossCursor(); break; - case UI_CURSOR_HAND: setPointingHandCursor(); break; - // case UI_CURSOR_NO: SetThemeCursor(kThemeNotAllowedCursor); break; - case UI_CURSOR_ARROWCOPY: setCopyCursor(); break; - - // Double-check these - case UI_CURSOR_NO: - case UI_CURSOR_SIZEWE: - case UI_CURSOR_SIZENS: - case UI_CURSOR_SIZENWSE: - case UI_CURSOR_SIZENESW: - case UI_CURSOR_WORKING: - case UI_CURSOR_TOOLGRAB: - case UI_CURSOR_TOOLLAND: - case UI_CURSOR_TOOLFOCUS: - case UI_CURSOR_TOOLCREATE: - case UI_CURSOR_ARROWDRAG: - case UI_CURSOR_NOLOCKED: - case UI_CURSOR_ARROWLOCKED: - case UI_CURSOR_GRABLOCKED: - case UI_CURSOR_PIPETTE: - case UI_CURSOR_TOOLTRANSLATE: - case UI_CURSOR_TOOLROTATE: - case UI_CURSOR_TOOLSCALE: - case UI_CURSOR_TOOLCAMERA: - case UI_CURSOR_TOOLPAN: - case UI_CURSOR_TOOLZOOMIN: - case UI_CURSOR_TOOLPICKOBJECT3: - case UI_CURSOR_TOOLPLAY: - case UI_CURSOR_TOOLPAUSE: - case UI_CURSOR_TOOLMEDIAOPEN: - case UI_CURSOR_TOOLSIT: - case UI_CURSOR_TOOLBUY: - case UI_CURSOR_TOOLOPEN: - case UI_CURSOR_TOOLPATHFINDING: - case UI_CURSOR_TOOLPATHFINDING_PATH_START: - case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: - case UI_CURSOR_TOOLPATHFINDING_PATH_END: - case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: - case UI_CURSOR_TOOLNO: - result = setImageCursor(gCursors[mNextCursor]); - break; - - } - - if(result != noErr) - { - setArrowCursor(); - } - - mCurrentCursor = mNextCursor; + // RN: replace multi-drag cursors with single versions + if (mNextCursor == UI_CURSOR_ARROWDRAGMULTI) + { + mNextCursor = UI_CURSOR_ARROWDRAG; + } + else if (mNextCursor == UI_CURSOR_ARROWCOPYMULTI) + { + mNextCursor = UI_CURSOR_ARROWCOPY; + } + + switch(mNextCursor) + { + default: + case UI_CURSOR_ARROW: + setArrowCursor(); + if(mCursorHidden) + { + // Since InitCursor resets the hide level, correct for it here. + hideNSCursor(); + } + break; + + // MBW -- XXX -- Some of the standard Windows cursors have no standard Mac equivalents. + // Find out what they look like and replicate them. + + // These are essentially correct + case UI_CURSOR_WAIT: /* Apple purposely doesn't allow us to set the beachball cursor manually. Let NSApp figure out when to do this. */ break; + case UI_CURSOR_IBEAM: setIBeamCursor(); break; + case UI_CURSOR_CROSS: setCrossCursor(); break; + case UI_CURSOR_HAND: setPointingHandCursor(); break; + // case UI_CURSOR_NO: SetThemeCursor(kThemeNotAllowedCursor); break; + case UI_CURSOR_ARROWCOPY: setCopyCursor(); break; + + // Double-check these + case UI_CURSOR_NO: + case UI_CURSOR_SIZEWE: + case UI_CURSOR_SIZENS: + case UI_CURSOR_SIZENWSE: + case UI_CURSOR_SIZENESW: + case UI_CURSOR_WORKING: + case UI_CURSOR_TOOLGRAB: + case UI_CURSOR_TOOLLAND: + case UI_CURSOR_TOOLFOCUS: + case UI_CURSOR_TOOLCREATE: + case UI_CURSOR_ARROWDRAG: + case UI_CURSOR_NOLOCKED: + case UI_CURSOR_ARROWLOCKED: + case UI_CURSOR_GRABLOCKED: + case UI_CURSOR_PIPETTE: + case UI_CURSOR_TOOLTRANSLATE: + case UI_CURSOR_TOOLROTATE: + case UI_CURSOR_TOOLSCALE: + case UI_CURSOR_TOOLCAMERA: + case UI_CURSOR_TOOLPAN: + case UI_CURSOR_TOOLZOOMIN: + case UI_CURSOR_TOOLPICKOBJECT3: + case UI_CURSOR_TOOLPLAY: + case UI_CURSOR_TOOLPAUSE: + case UI_CURSOR_TOOLMEDIAOPEN: + case UI_CURSOR_TOOLSIT: + case UI_CURSOR_TOOLBUY: + case UI_CURSOR_TOOLOPEN: + case UI_CURSOR_TOOLPATHFINDING: + case UI_CURSOR_TOOLPATHFINDING_PATH_START: + case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: + case UI_CURSOR_TOOLPATHFINDING_PATH_END: + case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: + case UI_CURSOR_TOOLNO: + result = setImageCursor(gCursors[mNextCursor]); + break; + + } + + if(result != noErr) + { + setArrowCursor(); + } + + mCurrentCursor = mNextCursor; } ECursorType LLWindowMacOSX::getCursor() const { - return mCurrentCursor; + return mCurrentCursor; } void LLWindowMacOSX::initCursors() { - initPixmapCursor(UI_CURSOR_NO, 8, 8); - initPixmapCursor(UI_CURSOR_WORKING, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLGRAB, 2, 14); - initPixmapCursor(UI_CURSOR_TOOLLAND, 13, 8); - initPixmapCursor(UI_CURSOR_TOOLFOCUS, 7, 6); - initPixmapCursor(UI_CURSOR_TOOLCREATE, 7, 7); - initPixmapCursor(UI_CURSOR_ARROWDRAG, 1, 1); - initPixmapCursor(UI_CURSOR_ARROWCOPY, 1, 1); - initPixmapCursor(UI_CURSOR_NOLOCKED, 8, 8); - initPixmapCursor(UI_CURSOR_ARROWLOCKED, 1, 1); - initPixmapCursor(UI_CURSOR_GRABLOCKED, 2, 14); - initPixmapCursor(UI_CURSOR_PIPETTE, 3, 29); - initPixmapCursor(UI_CURSOR_TOOLTRANSLATE, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLROTATE, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLSCALE, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLCAMERA, 7, 6); - initPixmapCursor(UI_CURSOR_TOOLPAN, 7, 6); - initPixmapCursor(UI_CURSOR_TOOLZOOMIN, 7, 6); + initPixmapCursor(UI_CURSOR_NO, 8, 8); + initPixmapCursor(UI_CURSOR_WORKING, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLGRAB, 2, 14); + initPixmapCursor(UI_CURSOR_TOOLLAND, 13, 8); + initPixmapCursor(UI_CURSOR_TOOLFOCUS, 7, 6); + initPixmapCursor(UI_CURSOR_TOOLCREATE, 7, 7); + initPixmapCursor(UI_CURSOR_ARROWDRAG, 1, 1); + initPixmapCursor(UI_CURSOR_ARROWCOPY, 1, 1); + initPixmapCursor(UI_CURSOR_NOLOCKED, 8, 8); + initPixmapCursor(UI_CURSOR_ARROWLOCKED, 1, 1); + initPixmapCursor(UI_CURSOR_GRABLOCKED, 2, 14); + initPixmapCursor(UI_CURSOR_PIPETTE, 3, 29); + initPixmapCursor(UI_CURSOR_TOOLTRANSLATE, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLROTATE, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLSCALE, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLCAMERA, 7, 6); + initPixmapCursor(UI_CURSOR_TOOLPAN, 7, 6); + initPixmapCursor(UI_CURSOR_TOOLZOOMIN, 7, 6); initPixmapCursor(UI_CURSOR_TOOLZOOMOUT, 7, 6); - initPixmapCursor(UI_CURSOR_TOOLPICKOBJECT3, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLMEDIAOPEN, 1, 1); - initPixmapCursor(UI_CURSOR_TOOLSIT, 20, 15); - initPixmapCursor(UI_CURSOR_TOOLBUY, 20, 15); - initPixmapCursor(UI_CURSOR_TOOLOPEN, 20, 15); - initPixmapCursor(UI_CURSOR_TOOLPATHFINDING, 16, 16); - initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START, 16, 16); - initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD, 16, 16); - initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END, 16, 16); - initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD, 16, 16); - initPixmapCursor(UI_CURSOR_TOOLNO, 8, 8); - - initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10); - initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10); - initPixmapCursor(UI_CURSOR_SIZEWE, 10, 10); - initPixmapCursor(UI_CURSOR_SIZENS, 10, 10); + initPixmapCursor(UI_CURSOR_TOOLPICKOBJECT3, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLMEDIAOPEN, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLSIT, 20, 15); + initPixmapCursor(UI_CURSOR_TOOLBUY, 20, 15); + initPixmapCursor(UI_CURSOR_TOOLOPEN, 20, 15); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD, 16, 16); + initPixmapCursor(UI_CURSOR_TOOLNO, 8, 8); + + initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10); + initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10); + initPixmapCursor(UI_CURSOR_SIZEWE, 10, 10); + initPixmapCursor(UI_CURSOR_SIZENS, 10, 10); initPixmapCursor(UI_CURSOR_SIZEALL, 10, 10); } void LLWindowMacOSX::captureMouse() { - // By registering a global CarbonEvent handler for mouse move events, we ensure that - // mouse events are always processed. Thus, capture and release are unnecessary. + // By registering a global CarbonEvent handler for mouse move events, we ensure that + // mouse events are always processed. Thus, capture and release are unnecessary. } void LLWindowMacOSX::releaseMouse() { - // By registering a global CarbonEvent handler for mouse move events, we ensure that - // mouse events are always processed. Thus, capture and release are unnecessary. + // By registering a global CarbonEvent handler for mouse move events, we ensure that + // mouse events are always processed. Thus, capture and release are unnecessary. } void LLWindowMacOSX::hideCursor() { - if(!mCursorHidden) - { - // LL_INFOS() << "hideCursor: hiding" << LL_ENDL; - mCursorHidden = TRUE; - mHideCursorPermanent = TRUE; - hideNSCursor(); - } - else - { - // LL_INFOS() << "hideCursor: already hidden" << LL_ENDL; - } + if(!mCursorHidden) + { + // LL_INFOS() << "hideCursor: hiding" << LL_ENDL; + mCursorHidden = TRUE; + mHideCursorPermanent = TRUE; + hideNSCursor(); + } + else + { + // LL_INFOS() << "hideCursor: already hidden" << LL_ENDL; + } - adjustCursorDecouple(); + adjustCursorDecouple(); } void LLWindowMacOSX::showCursor() { - if(mCursorHidden || !isCGCursorVisible()) - { - // LL_INFOS() << "showCursor: showing" << LL_ENDL; - mCursorHidden = FALSE; - mHideCursorPermanent = FALSE; - showNSCursor(); - } - else - { - // LL_INFOS() << "showCursor: already visible" << LL_ENDL; - } + if(mCursorHidden || !isCGCursorVisible()) + { + // LL_INFOS() << "showCursor: showing" << LL_ENDL; + mCursorHidden = FALSE; + mHideCursorPermanent = FALSE; + showNSCursor(); + } + else + { + // LL_INFOS() << "showCursor: already visible" << LL_ENDL; + } - adjustCursorDecouple(); + adjustCursorDecouple(); } void LLWindowMacOSX::showCursorFromMouseMove() { - if (!mHideCursorPermanent) - { - showCursor(); - } + if (!mHideCursorPermanent) + { + showCursor(); + } } void LLWindowMacOSX::hideCursorUntilMouseMove() { - if (!mHideCursorPermanent) - { - hideCursor(); - mHideCursorPermanent = FALSE; - } + if (!mHideCursorPermanent) + { + hideCursor(); + mHideCursorPermanent = FALSE; + } } @@ -1750,7 +1760,7 @@ void LLWindowMacOSX::hideCursorUntilMouseMove() // LLSplashScreenMacOSX::LLSplashScreenMacOSX() { - mWindow = NULL; + mWindow = NULL; } LLSplashScreenMacOSX::~LLSplashScreenMacOSX() @@ -1759,201 +1769,681 @@ LLSplashScreenMacOSX::~LLSplashScreenMacOSX() void LLSplashScreenMacOSX::showImpl() { - // This code _could_ be used to display a spash screen... + // This code _could_ be used to display a spash screen... } void LLSplashScreenMacOSX::updateImpl(const std::string& mesg) { - if(mWindow != NULL) - { - CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8); - } + if(mWindow != NULL) + { + CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8); + } } void LLSplashScreenMacOSX::hideImpl() { - if(mWindow != NULL) - { - mWindow = NULL; - } + if(mWindow != NULL) + { + mWindow = NULL; + } } S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type) { - return showAlert(text, caption, type); + return showAlert(text, caption, type); } // Open a URL with the user's default web browser. // Must begin with protocol identifier. void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) { - // I'm fairly certain that this is all legitimate under Apple's currently supported APIs. - - bool found = false; - S32 i; - for (i = 0; i < gURLProtocolWhitelistCount; i++) - { - if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos) - { - found = true; - break; - } - } - - if (!found) - { - LL_WARNS() << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << LL_ENDL; - return; - } - - S32 result = 0; - CFURLRef urlRef = NULL; - - LL_INFOS() << "Opening URL " << escaped_url << LL_ENDL; - - CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8); - if (stringRef) - { - // This will succeed if the string is a full URL, including the http:// - // Note that URLs specified this way need to be properly percent-escaped. - urlRef = CFURLCreateWithString(NULL, stringRef, NULL); - - // Don't use CRURLCreateWithFileSystemPath -- only want valid URLs - - CFRelease(stringRef); - } - - if (urlRef) - { - result = LSOpenCFURLRef(urlRef, NULL); - - if (result != noErr) - { - LL_INFOS() << "Error " << result << " on open." << LL_ENDL; - } - - CFRelease(urlRef); - } - else - { - LL_INFOS() << "Error: couldn't create URL." << LL_ENDL; - } + // I'm fairly certain that this is all legitimate under Apple's currently supported APIs. + + bool found = false; + S32 i; + for (i = 0; i < gURLProtocolWhitelistCount; i++) + { + if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos) + { + found = true; + break; + } + } + + if (!found) + { + LL_WARNS() << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << LL_ENDL; + return; + } + + S32 result = 0; + CFURLRef urlRef = NULL; + + LL_INFOS() << "Opening URL " << escaped_url << LL_ENDL; + + CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8); + if (stringRef) + { + // This will succeed if the string is a full URL, including the http:// + // Note that URLs specified this way need to be properly percent-escaped. + urlRef = CFURLCreateWithString(NULL, stringRef, NULL); + + // Don't use CRURLCreateWithFileSystemPath -- only want valid URLs + + CFRelease(stringRef); + } + + if (urlRef) + { + result = LSOpenCFURLRef(urlRef, NULL); + + if (result != noErr) + { + LL_INFOS() << "Error " << result << " on open." << LL_ENDL; + } + + CFRelease(urlRef); + } + else + { + LL_INFOS() << "Error: couldn't create URL." << LL_ENDL; + } +} + +// String should match ndof, so string mapping code was copied as is +static char mapChar( char c ) +{ + unsigned char uc = ( unsigned char ) c; + + switch( uc ) + { + case '/': return '-'; // use dash instead of slash + + case 0x7F: return ' '; + case 0x80: return 'A'; + case 0x81: return 'A'; + case 0x82: return 'C'; + case 0x83: return 'E'; + case 0x84: return 'N'; + case 0x85: return 'O'; + case 0x86: return 'U'; + case 0x87: return 'a'; + case 0x88: return 'a'; + case 0x89: return 'a'; + case 0x8A: return 'a'; + case 0x8B: return 'a'; + case 0x8C: return 'a'; + case 0x8D: return 'c'; + case 0x8E: return 'e'; + case 0x8F: return 'e'; + case 0x90: return ' '; + case 0x91: return ' '; // ? ' + case 0x92: return ' '; // ? ' + case 0x93: return ' '; // ? " + case 0x94: return ' '; // ? " + case 0x95: return ' '; + case 0x96: return ' '; + case 0x97: return ' '; + case 0x98: return ' '; + case 0x99: return ' '; + case 0x9A: return ' '; + case 0x9B: return 0x27; + case 0x9C: return 0x22; + case 0x9D: return ' '; + case 0x9E: return ' '; + case 0x9F: return ' '; + case 0xA0: return ' '; + case 0xA1: return ' '; + case 0xA2: return ' '; + case 0xA3: return ' '; + case 0xA4: return ' '; + case 0xA5: return ' '; + case 0xA6: return ' '; + case 0xA7: return ' '; + case 0xA8: return ' '; + case 0xA9: return ' '; + case 0xAA: return ' '; + case 0xAB: return ' '; + case 0xAC: return ' '; + case 0xAD: return ' '; + case 0xAE: return ' '; + case 0xAF: return ' '; + case 0xB0: return ' '; + case 0xB1: return ' '; + case 0xB2: return ' '; + case 0xB3: return ' '; + case 0xB4: return ' '; + case 0xB5: return ' '; + case 0xB6: return ' '; + case 0xB7: return ' '; + case 0xB8: return ' '; + case 0xB9: return ' '; + case 0xBA: return ' '; + case 0xBB: return ' '; + case 0xBC: return ' '; + case 0xBD: return ' '; + case 0xBE: return ' '; + case 0xBF: return ' '; + case 0xC0: return ' '; + case 0xC1: return ' '; + case 0xC2: return ' '; + case 0xC3: return ' '; + case 0xC4: return ' '; + case 0xC5: return ' '; + case 0xC6: return ' '; + case 0xC7: return ' '; + case 0xC8: return ' '; + case 0xC9: return ' '; + case 0xCA: return ' '; + case 0xCB: return 'A'; + case 0xCC: return 'A'; + case 0xCD: return 'O'; + case 0xCE: return ' '; + case 0xCF: return ' '; + case 0xD0: return '-'; + case 0xD1: return '-'; + case 0xD2: return 0x22; + case 0xD3: return 0x22; + case 0xD4: return 0x27; + case 0xD5: return 0x27; + case 0xD6: return '-'; // use dash instead of slash + case 0xD7: return ' '; + case 0xD8: return 'y'; + case 0xD9: return 'Y'; + case 0xDA: return '-'; // use dash instead of slash + case 0xDB: return ' '; + case 0xDC: return '<'; + case 0xDD: return '>'; + case 0xDE: return ' '; + case 0xDF: return ' '; + case 0xE0: return ' '; + case 0xE1: return ' '; + case 0xE2: return ','; + case 0xE3: return ','; + case 0xE4: return ' '; + case 0xE5: return 'A'; + case 0xE6: return 'E'; + case 0xE7: return 'A'; + case 0xE8: return 'E'; + case 0xE9: return 'E'; + case 0xEA: return 'I'; + case 0xEB: return 'I'; + case 0xEC: return 'I'; + case 0xED: return 'I'; + case 0xEE: return 'O'; + case 0xEF: return 'O'; + case 0xF0: return ' '; + case 0xF1: return 'O'; + case 0xF2: return 'U'; + case 0xF3: return 'U'; + case 0xF4: return 'U'; + case 0xF5: return '|'; + case 0xF6: return ' '; + case 0xF7: return ' '; + case 0xF8: return ' '; + case 0xF9: return ' '; + case 0xFA: return '.'; + case 0xFB: return ' '; + case 0xFC: return ' '; + case 0xFD: return 0x22; + case 0xFE: return ' '; + case 0xFF: return ' '; + } + return c; +} + +// String should match ndof for manufacturer based search to work +static void sanitizeString( char* inCStr ) +{ + char* charIt = inCStr; + while ( *charIt ) + { + *charIt = mapChar( *charIt ); + charIt++; + } +} + +struct HidDevice +{ + long mAxis; + long mLocalID; + char mProduct[256]; + char mManufacturer[256]; + long mUsage; + long mUsagePage; +}; + +static void populate_device_info( io_object_t io_obj_p, CFDictionaryRef device_dic, HidDevice* devicep ) +{ + CFMutableDictionaryRef io_properties = nil; + io_registry_entry_t entry1; + io_registry_entry_t entry2; + kern_return_t rc; + + // Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also + // get dictionary for usb properties: step up two levels and get CF dictionary for USB properties + // try to get parent1 + rc = IORegistryEntryGetParentEntry( io_obj_p, kIOServicePlane, &entry1 ); + if ( KERN_SUCCESS == rc ) + { + rc = IORegistryEntryGetParentEntry( entry1, kIOServicePlane, &entry2 ); + + IOObjectRelease( entry1 ); + + if ( KERN_SUCCESS == rc ) + { + rc = IORegistryEntryCreateCFProperties( entry2, &io_properties, kCFAllocatorDefault, kNilOptions ); + // either way, release parent2 + IOObjectRelease( entry2 ); + } + } + if ( KERN_SUCCESS == rc ) + { + // IORegistryEntryCreateCFProperties() succeeded + if ( io_properties != nil ) + { + CFTypeRef dict_element = 0; + // get device info + // try hid dictionary first, if fail then go to usb dictionary + + + dict_element = CFDictionaryGetValue( device_dic, CFSTR(kIOHIDProductKey) ); + if ( !dict_element ) + { + dict_element = CFDictionaryGetValue( io_properties, CFSTR( "USB Product Name" ) ); + } + if ( dict_element ) + { + bool res = CFStringGetCString((CFStringRef)dict_element, devicep->mProduct, 256, kCFStringEncodingUTF8); + sanitizeString(devicep->mProduct); + if ( !res ) + { + LL_WARNS("Joystick") << "Failed to populate mProduct" << LL_ENDL; + } + } + + dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDManufacturerKey ) ); + if ( !dict_element ) + { + dict_element = CFDictionaryGetValue( io_properties, CFSTR( "USB Vendor Name" ) ); + } + if ( dict_element ) + { + bool res = CFStringGetCString( (CFStringRef)dict_element, devicep->mManufacturer, 256, kCFStringEncodingUTF8 ); + sanitizeString(devicep->mManufacturer); + if ( !res ) + { + LL_WARNS("Joystick") << "Failed to populate mManufacturer" << LL_ENDL; + } + } + + dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDLocationIDKey ) ); + if ( !dict_element ) + { + dict_element = CFDictionaryGetValue( io_properties, CFSTR( "locationID" ) ); + } + if ( dict_element ) + { + bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mLocalID ); + if ( !res ) + { + LL_WARNS("Joystick") << "Failed to populate mLocalID" << LL_ENDL; + } + } + + dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDPrimaryUsagePageKey ) ); + if ( dict_element ) + { + bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mUsagePage ); + if ( !res ) + { + LL_WARNS("Joystick") << "Failed to populate mUsagePage" << LL_ENDL; + } + dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDPrimaryUsageKey ) ); + if ( dict_element ) + { + if ( !CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mUsage ) ) + { + LL_WARNS("Joystick") << "Failed to populate mUsage" << LL_ENDL; + } + } + } + + //Add axis, because ndof lib checks sutability by axises as well as other elements + devicep->mAxis = 0; + CFTypeRef hid_elements = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDElementKey ) ); + if ( hid_elements && CFGetTypeID( hid_elements ) == CFArrayGetTypeID( ) ) + { + long count = CFArrayGetCount( (CFArrayRef) hid_elements ); + for (int i = 0; i < count; ++i) + { + CFTypeRef element = CFArrayGetValueAtIndex((CFArrayRef) hid_elements, i); + if (element && CFGetTypeID( element ) == CFDictionaryGetTypeID( )) + { + long type = 0, usage_page = 0, usage = 0; + + CFTypeRef ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementTypeKey ) ); + if ( ref_value ) + { + CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &type ); + } + + ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementUsagePageKey ) ); + if ( ref_value ) + { + CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &usage_page ); + } + + ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementUsageKey ) ); + if ( ref_value ) + { + CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &usage ); + } + if ( type != 0 + && type != kIOHIDElementTypeCollection + && usage_page == kHIDPage_GenericDesktop) + { + switch( usage ) + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + devicep->mAxis++; + break; + default: + break; + } + } + } + } + } + + CFRelease(io_properties); + } + else + { + LL_WARNS("Joystick") << "Failed to populate fields" << LL_ENDL; + } + } +} + +HidDevice populate_device( io_object_t io_obj ) +{ + void* interfacep = nullptr; + HidDevice device; + memset( &device, 0, sizeof( HidDevice ) ); + CFMutableDictionaryRef device_dic = 0; + kern_return_t result = IORegistryEntryCreateCFProperties( io_obj, &device_dic, kCFAllocatorDefault, kNilOptions ); + + if ( KERN_SUCCESS == result + && device_dic ) + { + IOReturn io_result = kIOReturnSuccess; + HRESULT query_result = S_OK; + SInt32 the_score = 0; + IOCFPlugInInterface **the_interface = NULL; + + + io_result = IOCreatePlugInInterfaceForService( io_obj, kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &the_interface, &the_score ); + if ( io_result == kIOReturnSuccess ) + { + query_result = ( *the_interface )->QueryInterface( the_interface, CFUUIDGetUUIDBytes( kIOHIDDeviceInterfaceID ), ( LPVOID * ) & ( interfacep ) ); + if ( query_result != S_OK ) + { + LL_WARNS("Joystick") << "QueryInterface failed" << LL_ENDL; + } + IODestroyPlugInInterface( the_interface ); + } + else + { + LL_WARNS("Joystick") << "IOCreatePlugInInterfaceForService failed" << LL_ENDL; + } + + if ( interfacep ) + { + result = ( *( IOHIDDeviceInterface** )interfacep )->open( interfacep, 0 ); + + if ( result != kIOReturnSuccess) + { + LL_WARNS("Joystick") << "open failed" << LL_ENDL; + } + } + // extract needed fields + populate_device_info( io_obj, device_dic, &device ); + + // Release interface + if ( interfacep ) + { + ( *( IOHIDDeviceInterface** ) interfacep )->close( interfacep ); + + ( *( IOHIDDeviceInterface** ) interfacep )->Release( interfacep ); + + interfacep = NULL; + } + + CFRelease( device_dic ); + } + else + { + LL_WARNS("Joystick") << "populate_device failed" << LL_ENDL; + } + + return device; +} + +static void get_devices(std::list<HidDevice> &list_of_devices, + io_iterator_t inIODeviceIterator) +{ + IOReturn result = kIOReturnSuccess; // assume success( optimist! ) + io_object_t io_obj = 0; + + while ( 0 != (io_obj = IOIteratorNext( inIODeviceIterator ) ) ) + { + HidDevice device = populate_device( io_obj ); + + // Should match ndof + if (device.mAxis >= 3 + || (device.mUsagePage == kHIDPage_GenericDesktop + && (device.mUsage == kHIDUsage_GD_MultiAxisController + || device.mUsage == kHIDUsage_GD_GamePad + || device.mUsage == kHIDUsage_GD_Joystick)) + || (device.mUsagePage == kHIDPage_Game + && device.mUsage == kHIDUsage_Game_3DGameController) + || strstr(device.mManufacturer, "3Dconnexion")) + { + list_of_devices.push_back(device); + } + else + { + LL_DEBUGS("Joystick"); + list_of_devices.push_back(device); + LL_CONT << "Device axes: " << (S32)device.mAxis + << " Device HIDUsepage: " << (S32)device.mUsagePage + << " Device HIDUsage: " << (S32)device.mUsage; + LL_ENDL; + } + + + // release the device object, it is no longer needed + result = IOObjectRelease( io_obj ); + if ( KERN_SUCCESS != result ) + { + LL_WARNS("Joystick") << "IOObjectRelease failed" << LL_ENDL; + } + } +} + +bool LLWindowMacOSX::getInputDevices(U32 device_type_filter, + std::function<bool(std::string&, LLSD&, void*)> osx_callback, + void* win_callback, + void* userdata) +{ + bool return_value = false; + CFMutableDictionaryRef device_dict_ref; + IOReturn result = kIOReturnSuccess; // assume success( optimist! ) + + // Set up matching dictionary to search the I/O Registry for HID devices we are interested in. Dictionary reference is NULL if error. + + // A dictionary to match devices to? + device_dict_ref = IOServiceMatching( kIOHIDDeviceKey ); + + // BUG FIX! one reference is consumed by IOServiceGetMatchingServices + CFRetain( device_dict_ref ); + io_iterator_t io_iter = 0; + + // create an IO object iterator + result = IOServiceGetMatchingServices( kIOMasterPortDefault, device_dict_ref, &io_iter ); + if ( kIOReturnSuccess != result ) + { + LL_WARNS("Joystick") << "IOServiceGetMatchingServices failed" << LL_ENDL; + } + + if ( io_iter ) + { + // add all existing devices + std::list<HidDevice> device_list; + + get_devices(device_list, io_iter); + + std::list<HidDevice>::iterator iter; + + for (iter = device_list.begin(); iter != device_list.end(); ++iter) + { + std::string label(iter->mProduct); + LLSD data; + data["manufacturer"] = std::string(iter->mManufacturer); + data["product"] = label; + + if (osx_callback(label, data, userdata)) + { + break; //found device + } + } + return_value = true; + } + + CFRelease( device_dict_ref ); + return return_value; } LLSD LLWindowMacOSX::getNativeKeyData() { - LLSD result = LLSD::emptyMap(); + LLSD result = LLSD::emptyMap(); - if(mRawKeyEvent) - { + 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; + LL_DEBUGS() << "native key data is: " << result << LL_ENDL; - return result; + return result; } BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b) { - BOOL retval = FALSE; - OSErr error = noErr; - NColorPickerInfo info; - - memset(&info, 0, sizeof(info)); - info.theColor.color.rgb.red = (UInt16)(*r * 65535.f); - info.theColor.color.rgb.green = (UInt16)(*g * 65535.f); - info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f); - info.placeWhere = kCenterOnMainScreen; - - error = NPickColor(&info); - - if (error == noErr) - { - retval = info.newColorChosen; - if (info.newColorChosen) - { - *r = ((float) info.theColor.color.rgb.red) / 65535.0; - *g = ((float) info.theColor.color.rgb.green) / 65535.0; - *b = ((float) info.theColor.color.rgb.blue) / 65535.0; - } - } - - return (retval); + BOOL retval = FALSE; + OSErr error = noErr; + NColorPickerInfo info; + + memset(&info, 0, sizeof(info)); + info.theColor.color.rgb.red = (UInt16)(*r * 65535.f); + info.theColor.color.rgb.green = (UInt16)(*g * 65535.f); + info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f); + info.placeWhere = kCenterOnMainScreen; + + error = NPickColor(&info); + + if (error == noErr) + { + retval = info.newColorChosen; + if (info.newColorChosen) + { + *r = ((float) info.theColor.color.rgb.red) / 65535.0; + *g = ((float) info.theColor.color.rgb.green) / 65535.0; + *b = ((float) info.theColor.color.rgb.blue) / 65535.0; + } + } + + return (retval); } void *LLWindowMacOSX::getPlatformWindow() { - // NOTE: this will be NULL in fullscreen mode. Plan accordingly. - return (void*)mWindow; + // NOTE: this will be NULL in fullscreen mode. Plan accordingly. + return (void*)mWindow; } // get a double value from a dictionary /* static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) { - double double_value; - CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); - if (!number_value) // if can't get a number for the dictionary - return -1; // fail - if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it - return -1; // fail - return double_value; // otherwise return the long value + double double_value; + CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); + if (!number_value) // if can't get a number for the dictionary + return -1; // fail + if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it + return -1; // fail + return double_value; // otherwise return the long value }*/ // get a long value from a dictionary static long getDictLong (CFDictionaryRef refDict, CFStringRef key) { - long int_value; - CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); - if (!number_value) // if can't get a number for the dictionary - return -1; // fail - if (!CFNumberGetValue(number_value, kCFNumberLongType, &int_value)) // or if cant convert it - return -1; // fail - return int_value; // otherwise return the long value + long int_value; + CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); + if (!number_value) // if can't get a number for the dictionary + return -1; // fail + if (!CFNumberGetValue(number_value, kCFNumberLongType, &int_value)) // or if cant convert it + return -1; // fail + return int_value; // otherwise return the long value } void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { - if (preeditor != mPreeditor && !b) - { - // This condition may occur by a call to - // setEnabled(BOOL) against LLTextEditor or LLLineEditor - // when the control is not focused. - // We need to silently ignore the case so that - // the language input status of the focused control - // is not disturbed. - return; - } - - // Take care of old and new preeditors. - if (preeditor != mPreeditor || !b) - { - // We need to interrupt before updating mPreeditor, - // so that the fix string from input method goes to - // the old preeditor. - if (mLanguageTextInputAllowed) - { - interruptLanguageTextInput(); - } - mPreeditor = (b ? preeditor : NULL); - } - - if (b == mLanguageTextInputAllowed) - { - return; - } - mLanguageTextInputAllowed = b; + if (preeditor != mPreeditor && !b) + { + // This condition may occur by a call to + // setEnabled(BOOL) against LLTextEditor or LLLineEditor + // when the control is not focused. + // We need to silently ignore the case so that + // the language input status of the focused control + // is not disturbed. + return; + } + + // Take care of old and new preeditors. + if (preeditor != mPreeditor || !b) + { + // We need to interrupt before updating mPreeditor, + // so that the fix string from input method goes to + // the old preeditor. + if (mLanguageTextInputAllowed) + { + interruptLanguageTextInput(); + } + mPreeditor = (b ? preeditor : NULL); + } + + if (b == mLanguageTextInputAllowed) + { + return; + } + mLanguageTextInputAllowed = b; allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit } -class sharedContext +class sharedContext { public: CGLContextObj mContext; @@ -1963,7 +2453,7 @@ void* LLWindowMacOSX::createSharedContext() { sharedContext* sc = new sharedContext(); CGLCreateContext(mPixelFormat, mContext, &(sc->mContext)); - + if (sUseMultGL) { CGLEnable(mContext, kCGLCEMPEngine); @@ -1977,23 +2467,23 @@ void LLWindowMacOSX::makeContextCurrent(void* context) CGLSetCurrentContext(((sharedContext*)context)->mContext); //enable multi-threaded OpenGL - if (sUseMultGL) - { - CGLError cgl_err; - CGLContextObj ctx = CGLGetCurrentContext(); - - cgl_err = CGLEnable( ctx, kCGLCEMPEngine); - - if (cgl_err != kCGLNoError ) - { - LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; - } - else - { + if (sUseMultGL) + { + CGLError cgl_err; + CGLContextObj ctx = CGLGetCurrentContext(); + + cgl_err = CGLEnable( ctx, kCGLCEMPEngine); + + if (cgl_err != kCGLNoError ) + { + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + } + else + { LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; - } - } - + } + } + } void LLWindowMacOSX::destroySharedContext(void* context) @@ -2016,166 +2506,166 @@ void LLWindowMacOSX::toggleVSync(bool enable_vsync) { frames_per_swap = 1; } - + CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap); } void LLWindowMacOSX::interruptLanguageTextInput() { - commitCurrentPreedit(mGLView); + commitCurrentPreedit(mGLView); } std::vector<std::string> LLWindowMacOSX::getDisplaysResolutionList() { - std::vector<std::string> resolution_list; - - CGDirectDisplayID display_ids[10]; - uint32_t found_displays = 0; - CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays); - - if (kCGErrorSuccess != err) - { - LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL; - return std::vector<std::string>(); - } - - for (uint32_t i = 0; i < found_displays; i++) - { - S32 monitor_width = CGDisplayPixelsWide(display_ids[i]); - S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]); - - std::ostringstream sstream; - sstream << monitor_width << "x" << monitor_height;; - std::string res = sstream.str(); - - resolution_list.push_back(res); - } - - return resolution_list; + std::vector<std::string> resolution_list; + + CGDirectDisplayID display_ids[10]; + uint32_t found_displays = 0; + CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays); + + if (kCGErrorSuccess != err) + { + LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL; + return std::vector<std::string>(); + } + + for (uint32_t i = 0; i < found_displays; i++) + { + S32 monitor_width = CGDisplayPixelsWide(display_ids[i]); + S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]); + + std::ostringstream sstream; + sstream << monitor_width << "x" << monitor_height;; + std::string res = sstream.str(); + + resolution_list.push_back(res); + } + + return resolution_list; } //static std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList() { - // Fonts previously in getFontListSans() have moved to fonts.xml. - return std::vector<std::string>(); + // Fonts previously in getFontListSans() have moved to fonts.xml. + return std::vector<std::string>(); } // static MASK LLWindowMacOSX::modifiersToMask(S16 modifiers) { - MASK mask = 0; - if(modifiers & MAC_SHIFT_KEY) { mask |= MASK_SHIFT; } - if(modifiers & (MAC_CMD_KEY | MAC_CTRL_KEY)) { mask |= MASK_CONTROL; } - if(modifiers & MAC_ALT_KEY) { mask |= MASK_ALT; } - return mask; + MASK mask = 0; + if(modifiers & MAC_SHIFT_KEY) { mask |= MASK_SHIFT; } + if(modifiers & (MAC_CMD_KEY | MAC_CTRL_KEY)) { mask |= MASK_CONTROL; } + if(modifiers & MAC_ALT_KEY) { mask |= MASK_ALT; } + return mask; } F32 LLWindowMacOSX::getSystemUISize() { - return gHiDPISupport ? ::getDeviceUnitSize(mGLView) : LLWindow::getSystemUISize(); + return gHiDPISupport ? ::getDeviceUnitSize(mGLView) : LLWindow::getSystemUISize(); } #if LL_OS_DRAGDROP_ENABLED /* S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, - void * handlerRefCon, DragRef drag) + void * handlerRefCon, DragRef drag) { - S16 result = 0; - LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; + S16 result = 0; + LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; - LL_DEBUGS() << "drag tracking handler, message = " << message << LL_ENDL; + LL_DEBUGS() << "drag tracking handler, message = " << message << LL_ENDL; - switch(message) - { - case kDragTrackingInWindow: - result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_TRACK); - break; + switch(message) + { + case kDragTrackingInWindow: + result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_TRACK); + break; - case kDragTrackingEnterHandler: - result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_START_TRACKING); - break; + case kDragTrackingEnterHandler: + result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_START_TRACKING); + break; - case kDragTrackingLeaveHandler: - result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_STOP_TRACKING); - break; + case kDragTrackingLeaveHandler: + result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_STOP_TRACKING); + break; - default: - break; - } + default: + break; + } - return result; + return result; } OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, - DragRef drag) + DragRef drag) { - LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; - return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED); + LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; + return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED); } */ void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action) { - MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers()); - - float mouse_point[2]; - // This will return the mouse point in window coords - getCursorPos(mWindow, mouse_point); - LLCoordWindow window_coords(mouse_point[0], mouse_point[1]); - LLCoordGL gl_pos; - convertCoords(window_coords, &gl_pos); - - if(!url.empty()) - { - LLWindowCallbacks::DragNDropResult res = - mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); - - switch (res) { - case LLWindowCallbacks::DND_NONE: // No drop allowed - if (action == LLWindowCallbacks::DNDA_TRACK) - { - mDragOverrideCursor = 0; - } - else { - mDragOverrideCursor = -1; - } - break; - case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation - mDragOverrideCursor = UI_CURSOR_NO; - break; - case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation - mDragOverrideCursor = UI_CURSOR_ARROWCOPY; - break; - default: - mDragOverrideCursor = -1; - break; - } - // This overrides the cursor being set by setCursor. - // This is a bit of a hack workaround because lots of areas - // within the viewer just blindly set the cursor. - if (mDragOverrideCursor == -1) - { - // Restore the cursor - ECursorType temp_cursor = mCurrentCursor; - // get around the "setting the same cursor" code in setCursor() - mCurrentCursor = UI_CURSOR_COUNT; - setCursor(temp_cursor); - } - else { - // Override the cursor - switch (mDragOverrideCursor) { - case 0: - setArrowCursor(); - break; - case UI_CURSOR_NO: - setNotAllowedCursor(); - case UI_CURSOR_ARROWCOPY: - setCopyCursor(); - default: - break; - }; - } - } + MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers()); + + float mouse_point[2]; + // This will return the mouse point in window coords + getCursorPos(mWindow, mouse_point); + LLCoordWindow window_coords(mouse_point[0], mouse_point[1]); + LLCoordGL gl_pos; + convertCoords(window_coords, &gl_pos); + + if(!url.empty()) + { + LLWindowCallbacks::DragNDropResult res = + mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); + + switch (res) { + case LLWindowCallbacks::DND_NONE: // No drop allowed + if (action == LLWindowCallbacks::DNDA_TRACK) + { + mDragOverrideCursor = 0; + } + else { + mDragOverrideCursor = -1; + } + break; + case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation + mDragOverrideCursor = UI_CURSOR_NO; + break; + case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation + mDragOverrideCursor = UI_CURSOR_ARROWCOPY; + break; + default: + mDragOverrideCursor = -1; + break; + } + // This overrides the cursor being set by setCursor. + // This is a bit of a hack workaround because lots of areas + // within the viewer just blindly set the cursor. + if (mDragOverrideCursor == -1) + { + // Restore the cursor + ECursorType temp_cursor = mCurrentCursor; + // get around the "setting the same cursor" code in setCursor() + mCurrentCursor = UI_CURSOR_COUNT; + setCursor(temp_cursor); + } + else { + // Override the cursor + switch (mDragOverrideCursor) { + case 0: + setArrowCursor(); + break; + case UI_CURSOR_NO: + setNotAllowedCursor(); + case UI_CURSOR_ARROWCOPY: + setCopyCursor(); + default: + break; + }; + } + } } #endif // LL_OS_DRAGDROP_ENABLED diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 7614167213..5e09e58a99 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindowmacosx.h * @brief Mac implementation of LLWindow class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,94 +44,99 @@ class LLWindowMacOSX : public LLWindow { public: - 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; - ECursorType getCursor() const override; - void captureMouse() override; - void releaseMouse() override; - void setMouseClipping( BOOL b ) override; - BOOL isClipboardTextAvailable() override; - BOOL pasteTextFromClipboard(LLWString &dst) override; - BOOL copyTextToClipboard(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 fsaa_samples) override; - BOOL restoreGamma() override; // Restore original gamma table (before updating gamma) - ESwapMethod getSwapMethod() override { return mSwapMethod; } - void gatherInput() override; - void delayInputProcessing() override {}; - void swapBuffers() override; - - // handy coordinate space conversion routines - 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; - void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } - - // query VRAM usage + 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; + ECursorType getCursor() const override; + void captureMouse() override; + void releaseMouse() override; + void setMouseClipping( BOOL b ) override; + BOOL isClipboardTextAvailable() override; + BOOL pasteTextFromClipboard(LLWString &dst) override; + BOOL copyTextToClipboard(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 fsaa_samples) override; + BOOL restoreGamma() override; // Restore original gamma table (before updating gamma) + ESwapMethod getSwapMethod() override { return mSwapMethod; } + void gatherInput() override; + void delayInputProcessing() override {}; + void swapBuffers() override; + + // handy coordinate space conversion routines + 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; + void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } + + // query VRAM usage /*virtual*/ U32 getAvailableVRAMMegabytes() override; - void beforeDialog() override; - void afterDialog() override; - - BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override; - - void *getPlatformWindow() override; - void bringToFront() override {}; - - void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) override; - void interruptLanguageTextInput() override; - void spawnWebBrowser(const std::string& escaped_url, bool async) override; - F32 getSystemUISize() override; - - static std::vector<std::string> getDisplaysResolutionList(); - - static std::vector<std::string> getDynamicFallbackFontList(); - - // Provide native key event data - LLSD getNativeKeyData() override; - - void* getWindow() { return mWindow; } - LLWindowCallbacks* getCallbacks() { return mCallbacks; } - LLPreeditor* getPreeditor() { return mPreeditor; } - - void updateMouseDeltas(float* deltas); - void getMouseDeltas(float* delta); - - void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action); - + void beforeDialog() override; + void afterDialog() override; + + BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override; + + void *getPlatformWindow() override; + void bringToFront() override {}; + + void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) override; + void interruptLanguageTextInput() override; + void spawnWebBrowser(const std::string& escaped_url, bool async) override; + F32 getSystemUISize() override; + + bool getInputDevices(U32 device_type_filter, + std::function<bool(std::string&, LLSD&, void*)> osx_callback, + void* win_callback, + void* userdata) override; + + static std::vector<std::string> getDisplaysResolutionList(); + + static std::vector<std::string> getDynamicFallbackFontList(); + + // Provide native key event data + LLSD getNativeKeyData() override; + + void* getWindow() { return mWindow; } + LLWindowCallbacks* getCallbacks() { return mCallbacks; } + LLPreeditor* getPreeditor() { return mPreeditor; } + + void updateMouseDeltas(float* deltas); + void getMouseDeltas(float* delta); + + void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action); + bool allowsLanguageInput() { return mLanguageTextInputAllowed; } //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread @@ -146,29 +151,29 @@ public: void toggleVSync(bool enable_vsync) override; protected: - LLWindowMacOSX(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); - ~LLWindowMacOSX(); + LLWindowMacOSX(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); + ~LLWindowMacOSX(); - void initCursors(); - BOOL isValid() override; - void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); + void initCursors(); + BOOL isValid() override; + 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); + // Changes display resolution. Returns true if successful + BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); - // Go back to last fullscreen display resolution. - BOOL setFullscreenResolution(); + // Go back to last fullscreen display resolution. + BOOL setFullscreenResolution(); - // Restore the display resolution to its value before we ran the app. - BOOL resetDisplayResolution(); + // Restore the display resolution to its value before we ran the app. + BOOL resetDisplayResolution(); + + BOOL shouldPostQuit() { return mPostQuit; } - BOOL shouldPostQuit() { return mPostQuit; } - //Satisfy MAINT-3135 and MAINT-3288 with a flag. /*virtual */ void setOldResize(bool oldresize) override {setResizeMode(oldresize, mGLView); } @@ -176,81 +181,81 @@ private: void restoreGLContext(); protected: - // - // Platform specific methods - // - - // 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 enable_vsync); - void destroyContext(); - void setupFailure(const std::string& text, const std::string& caption, U32 type); - void adjustCursorDecouple(bool warpingMouse = false); - static MASK modifiersToMask(S16 modifiers); - + // + // Platform specific methods + // + + // 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 enable_vsync); + void destroyContext(); + void setupFailure(const std::string& text, const std::string& caption, U32 type); + void adjustCursorDecouple(bool warpingMouse = false); + static MASK modifiersToMask(S16 modifiers); + #if LL_OS_DRAGDROP_ENABLED - - //static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag); - //static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag); - - + + //static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag); + //static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag); + + #endif // LL_OS_DRAGDROP_ENABLED - - // - // Platform specific variables - // - - // Use generic pointers here. This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise. - NSWindowRef mWindow; - GLViewRef mGLView; - CGLContextObj mContext; - CGLPixelFormatObj mPixelFormat; - CGDirectDisplayID mDisplay; - - LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse() - std::string mWindowTitle; - double mOriginalAspectRatio; - BOOL mSimulatedRightClick; - U32 mLastModifiers; - BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing. - // Used to allow event processing when putting up dialogs in fullscreen mode. - BOOL mCursorDecoupled; - S32 mCursorLastEventDeltaX; - S32 mCursorLastEventDeltaY; - BOOL mCursorIgnoreNextDelta; - BOOL mNeedsResize; // Constructor figured out the window is too big, it needs a resize. - LLCoordScreen mNeedsResizeSize; - F32 mOverrideAspectRatio; - BOOL mMaximized; - BOOL mMinimized; - U32 mFSAASamples; - BOOL mForceRebuild; - - S32 mDragOverrideCursor; - - // Input method management through Text Service Manager. - BOOL mLanguageTextInputAllowed; - LLPreeditor* mPreeditor; - + + // + // Platform specific variables + // + + // Use generic pointers here. This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise. + NSWindowRef mWindow; + GLViewRef mGLView; + CGLContextObj mContext; + CGLPixelFormatObj mPixelFormat; + CGDirectDisplayID mDisplay; + + LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse() + std::string mWindowTitle; + double mOriginalAspectRatio; + BOOL mSimulatedRightClick; + U32 mLastModifiers; + BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing. + // Used to allow event processing when putting up dialogs in fullscreen mode. + BOOL mCursorDecoupled; + S32 mCursorLastEventDeltaX; + S32 mCursorLastEventDeltaY; + BOOL mCursorIgnoreNextDelta; + BOOL mNeedsResize; // Constructor figured out the window is too big, it needs a resize. + LLCoordScreen mNeedsResizeSize; + F32 mOverrideAspectRatio; + BOOL mMaximized; + BOOL mMinimized; + U32 mFSAASamples; + BOOL mForceRebuild; + + S32 mDragOverrideCursor; + + // Input method management through Text Service Manager. + BOOL mLanguageTextInputAllowed; + LLPreeditor* mPreeditor; + public: - static BOOL sUseMultGL; + static BOOL sUseMultGL; + + friend class LLWindowManager; - friend class LLWindowManager; - }; class LLSplashScreenMacOSX : public LLSplashScreen { public: - LLSplashScreenMacOSX(); - virtual ~LLSplashScreenMacOSX(); + LLSplashScreenMacOSX(); + virtual ~LLSplashScreenMacOSX(); - void showImpl(); - void updateImpl(const std::string& mesg); - void hideImpl(); + void showImpl(); + void updateImpl(const std::string& mesg); + void hideImpl(); private: - WindowRef mWindow; + WindowRef mWindow; }; S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp index 4b01f7a979..58f8f80d2d 100644 --- a/indra/llwindow/llwindowmesaheadless.cpp +++ b/indra/llwindow/llwindowmesaheadless.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llwindowmesaheadless.cpp * @brief Platform-dependent implementation of llwindow * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,39 +40,39 @@ U16 *gMesaBuffer = NULL; // LLWindowMesaHeadless::LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, - U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) - : LLWindow(callbacks, fullscreen, flags) + U32 flags, BOOL fullscreen, BOOL clearBg, + BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) + : LLWindow(callbacks, fullscreen, flags) { - if (use_gl) - { - LL_INFOS() << "MESA Init" << LL_ENDL; - mMesaContext = OSMesaCreateContextExt( GL_RGBA, 32, 0, 0, NULL ); + if (use_gl) + { + LL_INFOS() << "MESA Init" << LL_ENDL; + mMesaContext = OSMesaCreateContextExt( GL_RGBA, 32, 0, 0, NULL ); - /* Allocate the image buffer */ - mMesaBuffer = new unsigned char [width * height * 4 * MESA_CHANNEL_SIZE]; - llassert(mMesaBuffer); + /* Allocate the image buffer */ + mMesaBuffer = new unsigned char [width * height * 4 * MESA_CHANNEL_SIZE]; + llassert(mMesaBuffer); - gMesaBuffer = (U16*)mMesaBuffer; + gMesaBuffer = (U16*)mMesaBuffer; - /* Bind the buffer to the context and make it current */ - if (!OSMesaMakeCurrent( mMesaContext, mMesaBuffer, MESA_CHANNEL_TYPE, width, height )) - { - LL_ERRS() << "MESA: OSMesaMakeCurrent failed!" << LL_ENDL; - } + /* Bind the buffer to the context and make it current */ + if (!OSMesaMakeCurrent( mMesaContext, mMesaBuffer, MESA_CHANNEL_TYPE, width, height )) + { + LL_ERRS() << "MESA: OSMesaMakeCurrent failed!" << LL_ENDL; + } - llverify(gGLManager.initGL()); - } + llverify(gGLManager.initGL()); + } } LLWindowMesaHeadless::~LLWindowMesaHeadless() { - delete mMesaBuffer; - OSMesaDestroyContext( mMesaContext ); + delete mMesaBuffer; + OSMesaDestroyContext( mMesaContext ); } void LLWindowMesaHeadless::swapBuffers() { - glFinish(); + glFinish(); } diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index 00e42240e6..9aa376a6db 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindowmesaheadless.h * @brief Windows implementation of LLWindow class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,85 +36,85 @@ class LLWindowMesaHeadless : public LLWindow { public: - /*virtual*/ void show() {}; - /*virtual*/ void hide() {}; - /*virtual*/ void close() {}; - /*virtual*/ BOOL getVisible() {return FALSE;}; - /*virtual*/ BOOL getMinimized() {return FALSE;}; - /*virtual*/ BOOL getMaximized() {return FALSE;}; - /*virtual*/ BOOL maximize() {return FALSE;}; - /*virtual*/ void minimize() {}; - /*virtual*/ void restore() {}; - /*virtual*/ BOOL getFullscreen() {return FALSE;}; - /*virtual*/ BOOL getPosition(LLCoordScreen *position) {return FALSE;}; - /*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;}; - /*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;}; - /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; - /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; - /*virtual*/ void showCursor() {}; - /*virtual*/ void hideCursor() {}; - /*virtual*/ void showCursorFromMouseMove() {}; - /*virtual*/ void hideCursorUntilMouseMove() {}; - /*virtual*/ BOOL isCursorHidden() {return FALSE;}; - /*virtual*/ void updateCursor() {}; - //virtual ECursorType getCursor() { return mCurrentCursor; }; - /*virtual*/ void captureMouse() {}; - /*virtual*/ void releaseMouse() {}; - /*virtual*/ void setMouseClipping( BOOL b ) {}; - /*virtual*/ BOOL isClipboardTextAvailable() {return FALSE; }; - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) {return FALSE; }; - /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) {return FALSE; }; - /*virtual*/ void flashIcon(F32 seconds) {}; - /*virtual*/ F32 getGamma() {return 1.0f; }; - /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma - /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) - /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ } - /*virtual*/ U32 getFSAASamples() { return 0; } - //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void gatherInput() {}; - /*virtual*/ void delayInputProcessing() {}; - /*virtual*/ void swapBuffers(); - /*virtual*/ void restoreGLContext() {}; + /*virtual*/ void show() {}; + /*virtual*/ void hide() {}; + /*virtual*/ void close() {}; + /*virtual*/ BOOL getVisible() {return FALSE;}; + /*virtual*/ BOOL getMinimized() {return FALSE;}; + /*virtual*/ BOOL getMaximized() {return FALSE;}; + /*virtual*/ BOOL maximize() {return FALSE;}; + /*virtual*/ void minimize() {}; + /*virtual*/ void restore() {}; + /*virtual*/ BOOL getFullscreen() {return FALSE;}; + /*virtual*/ BOOL getPosition(LLCoordScreen *position) {return FALSE;}; + /*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;}; + /*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;}; + /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; + /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; + /*virtual*/ void showCursor() {}; + /*virtual*/ void hideCursor() {}; + /*virtual*/ void showCursorFromMouseMove() {}; + /*virtual*/ void hideCursorUntilMouseMove() {}; + /*virtual*/ BOOL isCursorHidden() {return FALSE;}; + /*virtual*/ void updateCursor() {}; + //virtual ECursorType getCursor() { return mCurrentCursor; }; + /*virtual*/ void captureMouse() {}; + /*virtual*/ void releaseMouse() {}; + /*virtual*/ void setMouseClipping( BOOL b ) {}; + /*virtual*/ BOOL isClipboardTextAvailable() {return FALSE; }; + /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) {return FALSE; }; + /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) {return FALSE; }; + /*virtual*/ void flashIcon(F32 seconds) {}; + /*virtual*/ F32 getGamma() {return 1.0f; }; + /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma + /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) + /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ } + /*virtual*/ U32 getFSAASamples() { return 0; } + //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } + /*virtual*/ void gatherInput() {}; + /*virtual*/ void delayInputProcessing() {}; + /*virtual*/ void swapBuffers(); + /*virtual*/ void restoreGLContext() {}; + + // handy coordinate space conversion routines + /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) { return FALSE; }; + /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) { return FALSE; }; + /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) { return FALSE; }; + /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) { return FALSE; }; + /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) { return FALSE; }; + /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) { return FALSE; }; - // handy coordinate space conversion routines - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) { return FALSE; }; + /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; }; + /*virtual*/ F32 getNativeAspectRatio() { return 1.0f; }; + /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; }; + /*virtual*/ void setNativeAspectRatio(F32 ratio) {} - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; }; - /*virtual*/ F32 getNativeAspectRatio() { return 1.0f; }; - /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; }; - /*virtual*/ void setNativeAspectRatio(F32 ratio) {} + /*virtual*/ void *getPlatformWindow() { return 0; }; + /*virtual*/ void bringToFront() {}; - /*virtual*/ void *getPlatformWindow() { return 0; }; - /*virtual*/ void bringToFront() {}; - - LLWindowMesaHeadless(LLWindowCallbacks* callbacks, + LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, - U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); - ~LLWindowMesaHeadless(); + U32 flags, BOOL fullscreen, BOOL clearBg, + BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); + ~LLWindowMesaHeadless(); private: - OSMesaContext mMesaContext; - unsigned char * mMesaBuffer; + OSMesaContext mMesaContext; + unsigned char * mMesaBuffer; }; class LLSplashScreenMesaHeadless : public LLSplashScreen { public: - LLSplashScreenMesaHeadless() {}; - virtual ~LLSplashScreenMesaHeadless() {}; + LLSplashScreenMesaHeadless() {}; + virtual ~LLSplashScreenMesaHeadless() {}; - /*virtual*/ void showImpl() {}; - /*virtual*/ void updateImpl(const std::string& mesg) {}; - /*virtual*/ void hideImpl() {}; + /*virtual*/ void showImpl() {}; + /*virtual*/ void updateImpl(const std::string& mesg) {}; + /*virtual*/ void hideImpl() {}; }; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index de09003e0e..5c0be53673 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llwindowsdl.cpp * @brief SDL implementation of LLWindow class * @author This module has many fathers, and it shows. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -66,7 +66,7 @@ extern BOOL gDebugWindowProc; const S32 MAX_NUM_RESOLUTIONS = 200; // static variable for ATI mouse cursor crash work-around: -static bool ATIbug = false; +static bool ATIbug = false; #if LL_DARWIN @@ -120,17 +120,17 @@ static LLWindowSDL *gWindowImplementation = NULL; void maybe_lock_display(void) { - if (gWindowImplementation && gWindowImplementation->Lock_Display) { - gWindowImplementation->Lock_Display(); - } + if (gWindowImplementation && gWindowImplementation->Lock_Display) { + gWindowImplementation->Lock_Display(); + } } void maybe_unlock_display(void) { - if (gWindowImplementation && gWindowImplementation->Unlock_Display) { - gWindowImplementation->Unlock_Display(); - } + if (gWindowImplementation && gWindowImplementation->Unlock_Display) { + gWindowImplementation->Unlock_Display(); + } } @@ -139,63 +139,63 @@ void maybe_unlock_display(void) // 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; + 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 (!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; #ifndef LL_USESYSTEMLIBS - if (!g_thread_supported ()) g_thread_init (NULL); + if (!g_thread_supported ()) g_thread_init (NULL); #endif - 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; - } + 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; - } + 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; - } + done_gtk_diag = TRUE; + } - return gtk_is_good; + return gtk_is_good; } #endif // LL_GTK @@ -204,106 +204,106 @@ bool LLWindowSDL::ll_try_gtk_init(void) // static Window LLWindowSDL::get_SDL_XWindowID(void) { - if (gWindowImplementation) { - return gWindowImplementation->mSDL_XWindowID; - } - return None; + if (gWindowImplementation) { + return gWindowImplementation->mSDL_XWindowID; + } + return None; } //static Display* LLWindowSDL::get_SDL_Display(void) { - if (gWindowImplementation) { - return gWindowImplementation->mSDL_Display; - } - return NULL; + if (gWindowImplementation) { + return gWindowImplementation->mSDL_Display; + } + return NULL; } #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) -{ - // 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 - - // Ignore use_gl for now, only used for drones on PC - mWindow = NULL; - mNeedsResize = FALSE; - mOverrideAspectRatio = 0.f; - mGrabbyKeyFlags = 0; - mReallyCapturedCount = 0; - mHaveInputFocus = -1; - mIsMinimized = -1; - mFSAASamples = fsaa_samples; + 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) +{ + // 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 + + // Ignore use_gl for now, only used for drones on PC + mWindow = NULL; + mNeedsResize = FALSE; + mOverrideAspectRatio = 0.f; + mGrabbyKeyFlags = 0; + mReallyCapturedCount = 0; + mHaveInputFocus = -1; + mIsMinimized = -1; + mFSAASamples = fsaa_samples; #if LL_X11 - mSDL_XWindowID = None; - mSDL_Display = NULL; + mSDL_XWindowID = None; + mSDL_Display = NULL; #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(); + // 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; + // Assume 4:3 aspect ratio until we know better + mOriginalAspectRatio = 1024.0 / 768.0; - if (title.empty()) - mWindowTitle = "SDL Window"; // *FIX: (?) - else - mWindowTitle = title; + if (title.empty()) + mWindowTitle = "SDL Window"; // *FIX: (?) + 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)) - { - gGLManager.initGL(); + // Create the GL context and set it up for windowed or fullscreen, as appropriate. + if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + { + gGLManager.initGL(); - //start with arrow cursor - initCursors(); - setCursor( UI_CURSOR_ARROW ); - } + //start with arrow cursor + initCursors(); + setCursor( UI_CURSOR_ARROW ); + } - stop_glerror(); + stop_glerror(); - // Stash an object pointer for OSMessageBox() - gWindowImplementation = this; + // Stash an object pointer for OSMessageBox() + gWindowImplementation = this; #if LL_X11 - mFlashing = FALSE; + mFlashing = FALSE; #endif // LL_X11 - mKeyScanCode = 0; - mKeyVirtualKey = 0; - mKeyModifiers = KMOD_NONE; + mKeyScanCode = 0; + mKeyVirtualKey = 0; + mKeyModifiers = KMOD_NONE; } static SDL_Surface *Load_BMP_Resource(const char *basename) { - const int PATH_BUFFER_SIZE=1000; - char path_buffer[PATH_BUFFER_SIZE]; /* Flawfinder: ignore */ - - // 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); - path_buffer[PATH_BUFFER_SIZE-1] = '\0'; - - return SDL_LoadBMP(path_buffer); + const int PATH_BUFFER_SIZE=1000; + char path_buffer[PATH_BUFFER_SIZE]; /* Flawfinder: ignore */ + + // 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); + path_buffer[PATH_BUFFER_SIZE-1] = '\0'; + + return SDL_LoadBMP(path_buffer); } #if 0 @@ -313,562 +313,559 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) // '?' 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' + 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' } static int x11_detect_VRAM_kb() { - 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'; - } + 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. + // *TODO: we could be smarter and see which of Xorg/XFree86 has the + // freshest time-stamp. - // Try Xorg log first - fname = x_log_location; - fname += "Xorg."; - 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, ": Video RAM: "); - 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; - // 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; - } - } - return rtn; + // Try Xorg log first + fname = x_log_location; + fname += "Xorg."; + 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, ": Video RAM: "); + 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; + // 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; + } + } + return rtn; } #endif // LL_X11 BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) { - //bool glneedsinit = false; + //bool glneedsinit = false; - LL_INFOS() << "createContext, fullscreen=" << fullscreen << - " size=" << width << "x" << height << LL_ENDL; + LL_INFOS() << "createContext, fullscreen=" << fullscreen << + " 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; - } + // captures don't survive contexts + mGrabbyKeyFlags = 0; + mReallyCapturedCount = 0; - 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; - - SDL_DisplayMode display_mode; - if (SDL_GetDesktopDisplayMode(0, &display_mode) < 0) - { - LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; - setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); - return FALSE; - } + 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; + } - if (display_mode.h > 0) - { - mOriginalAspectRatio = (float)display_mode.w / (float)display_mode.h; - LL_INFOS() << "Original aspect ratio was " << display_mode.w << ":" << display_mode.h << "=" << mOriginalAspectRatio << LL_ENDL; - } + 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; + + SDL_DisplayMode display_mode; + if (SDL_GetDesktopDisplayMode(0, &display_mode) < 0) + { + LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; + setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); + return FALSE; + } - // 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); + if (display_mode.h > 0) + { + mOriginalAspectRatio = (float)display_mode.w / (float)display_mode.h; + LL_INFOS() << "Original aspect ratio was " << display_mode.w << ":" << display_mode.h << "=" << mOriginalAspectRatio << LL_ENDL; + } + + // 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); + // 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? - mFullscreen = fullscreen; + mFullscreen = fullscreen; - int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;// | SDL_ANYFORMAT; + int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;// | SDL_ANYFORMAT; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); #if LL_DARWIN - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); #else - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); #endif - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (mFSAASamples > 0) - { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); - } - - mSDLFlags = sdlflags; + if (mFSAASamples > 0) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); + } - if (mFullscreen) - { - LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; + mSDLFlags = sdlflags; - // 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; - - LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; - - for(i=0; i < resolutionCount; i++) - { - 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))) - { - 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; - } - } + if (mFullscreen) + { + LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; - if((width == 0) || (height == 0)) - { - // Mode search failed for some reason. Use the old-school default. - width = 1024; - height = 768; - } + // 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); - mWindow = SDL_CreateWindow(mWindowTitle.c_str(), - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - width, height, sdlflags | SDL_WINDOW_FULLSCREEN); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_CreateWindow(mWindowTitle.c_str(), - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - width, height, sdlflags | SDL_WINDOW_FULLSCREEN); - } + if(resolutionList != NULL) + { + F32 closestAspect = 0; + U32 closestHeight = 0; + U32 closestWidth = 0; + int i; - if (mWindow) - { - SDL_GL_CreateContext(mWindow); - mFullscreen = TRUE; - SDL_GetWindowSize(mWindow, - &mFullscreenWidth, &mFullscreenHeight); - //mFullscreenBits = mWindow->format->BitsPerPixel; - mFullscreenRefresh = -1; - - LL_INFOS() << "Running at " << mFullscreenWidth - << "x" << mFullscreenHeight - << "x" << mFullscreenBits - << " @ " << mFullscreenRefresh - << LL_ENDL; - } - else - { - LL_WARNS() << "createContext: fullscreen creation failure. SDL: " << SDL_GetError() << LL_ENDL; - // No fullscreen support - 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); - } - } + LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; - if(!mFullscreen && (mWindow == NULL)) - { - if (width == 0) - width = 1024; - if (height == 0) - width = 768; - - LL_INFOS() << "createContext: creating window " << width << "x" << height << "x" << bits << LL_ENDL; - mWindow = SDL_CreateWindow(mWindowTitle.c_str(), - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - width, height, sdlflags); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_CreateWindow(mWindowTitle.c_str(), - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - width, height, sdlflags); - } + for(i=0; i < resolutionCount; i++) + { + F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; - if (!mWindow) - { - LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; - setupFailure("Window creation error", "Error", OSMB_OK); - return FALSE; - } - SDL_GL_CreateContext(mWindow); - } else if (!mFullscreen && (mWindow != NULL)) - { - LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; - } + LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; - //SDL_EnableUNICODE(1); - SDL_SetWindowTitle(mWindow, mWindowTitle.c_str()); + if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && + (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio))) + { + LL_INFOS() << " (new closest mode) " << LL_ENDL; - // 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_TRUE, - SDL_MapRGB(bmpsurface->format, 0,0,0) ); - SDL_SetWindowIcon(mWindow, bmpsurface); - // The SDL examples cheerfully avoid freeing the icon - // surface, but I'm betting that's leaky. - SDL_FreeSurface(bmpsurface); - bmpsurface = NULL; - } - - // Detect video memory size. + // This is the closest mode we've seen yet. + closestWidth = resolutionList[i].mWidth; + closestHeight = resolutionList[i].mHeight; + closestAspect = aspect; + } + } + + width = closestWidth; + height = closestHeight; + } + } + + if((width == 0) || (height == 0)) + { + // Mode search failed for some reason. Use the old-school default. + width = 1024; + height = 768; + } + + mWindow = SDL_CreateWindow(mWindowTitle.c_str(), + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, sdlflags | SDL_WINDOW_FULLSCREEN); + if (!mWindow && bits > 16) + { + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + mWindow = SDL_CreateWindow(mWindowTitle.c_str(), + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, sdlflags | SDL_WINDOW_FULLSCREEN); + } + + if (mWindow) + { + SDL_GL_CreateContext(mWindow); + mFullscreen = TRUE; + SDL_GetWindowSize(mWindow, &mFullscreenWidth, &mFullscreenHeight); + //mFullscreenBits = mWindow->format->BitsPerPixel; + mFullscreenRefresh = -1; + + LL_INFOS() << "Running at " << mFullscreenWidth + << "x" << mFullscreenHeight + << "x" << mFullscreenBits + << " @ " << mFullscreenRefresh + << LL_ENDL; + } + else + { + LL_WARNS() << "createContext: fullscreen creation failure. SDL: " << SDL_GetError() << LL_ENDL; + // No fullscreen support + 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); + } + } + + if(!mFullscreen && (mWindow == NULL)) + { + if (width == 0) + width = 1024; + if (height == 0) + width = 768; + + LL_INFOS() << "createContext: creating window " << width << "x" << height << "x" << bits << LL_ENDL; + mWindow = SDL_CreateWindow(mWindowTitle.c_str(), + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, sdlflags); + if (!mWindow && bits > 16) + { + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + mWindow = SDL_CreateWindow(mWindowTitle.c_str(), + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, sdlflags); + } + + if (!mWindow) + { + LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; + setupFailure("Window creation error", "Error", OSMB_OK); + return FALSE; + } + SDL_GL_CreateContext(mWindow); + } else if (!mFullscreen && (mWindow != NULL)) + { + LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; + } + + //SDL_EnableUNICODE(1); + SDL_SetWindowTitle(mWindow, mWindowTitle.c_str()); + + // 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_TRUE, + SDL_MapRGB(bmpsurface->format, 0,0,0) ); + SDL_SetWindowIcon(mWindow, bmpsurface); + // The SDL examples cheerfully avoid freeing the icon + // surface, but I'm betting that's leaky. + SDL_FreeSurface(bmpsurface); + bmpsurface = NULL; + } + + // Detect video memory size. #if 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; + 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; #else - 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; - } + 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; + gGLManager.mVRAM = vram_megabytes; # endif // LL_DARWIN - if (gGLManager.mVRAM) - LL_INFOS() << "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); - - LL_INFOS() << "GL buffer:" << LL_ENDL; + if (gGLManager.mVRAM) + LL_INFOS() << "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); + + 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; - - GLint colorBits = redBits + greenBits + blueBits + alphaBits; - // fixme: actually, it's REALLY important for picking that we get at - // least 8 bits each of red,green,blue. Alpha we can be a bit more - // relaxed about if we have to. - if (colorBits < 32) - { + 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 + // least 8 bits each of red,green,blue. Alpha we can be a bit more + // relaxed about if we have to. + if (colorBits < 32) + { #if LL_LINUX - 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); - return FALSE; + 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); + return FALSE; #endif // LL_LINUX - } + } #if 0 // *FIX: we're going to brave it for now... - if (alphaBits < 8) - { - 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; - } + if (alphaBits < 8) + { + 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; + } #endif #if LL_X11 - /* Grab the window manager specific information */ - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - 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.window; - /* - Lock_Display = info.info.x11.lock_func; - Unlock_Display = info.info.x11.unlock_func; - */ - } - else - { - LL_WARNS() << "We're not running under X11? Wild." - << LL_ENDL; - } - } - else - { - LL_WARNS() << "We're not running under any known WM. Wild." - << LL_ENDL; - } + /* Grab the window manager specific information */ + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + 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; + */ + } + else + { + LL_WARNS() << "We're not running under X11? Wild." + << LL_ENDL; + } + } + else + { + LL_WARNS() << "We're not running under any known WM. Wild." + << LL_ENDL; + } #endif // LL_X11 - //make sure multisampling is disabled by default + //make sure multisampling is disabled by default #if GL_VERSION_1_3 - glDisable(GL_MULTISAMPLE_ARB); + glDisable(GL_MULTISAMPLE_ARB); #endif - - // 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; - */ - // Don't need to get the current gamma, since there's a call that restores it to the system defaults. - return TRUE; + // 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; + */ + + // Don't need to get the current gamma, since there's a call that restores it to the system defaults. + return TRUE; } // 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) { - const BOOL needsRebuild = TRUE; // Just nuke the context and start over. - BOOL result = true; + const BOOL needsRebuild = TRUE; // Just nuke the context and start over. + BOOL result = true; - LL_INFOS() << "switchContext, fullscreen=" << fullscreen << LL_ENDL; - stop_glerror(); - if(needsRebuild) - { - destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); - if (result) - { - gGLManager.initGL(); + LL_INFOS() << "switchContext, fullscreen=" << fullscreen << LL_ENDL; + stop_glerror(); + if(needsRebuild) + { + destroyContext(); + result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); + if (result) + { + gGLManager.initGL(); - //start with arrow cursor - initCursors(); - setCursor( UI_CURSOR_ARROW ); - } - } + //start with arrow cursor + initCursors(); + setCursor( UI_CURSOR_ARROW ); + } + } - stop_glerror(); + stop_glerror(); - return result; + return result; } void LLWindowSDL::destroyContext() { - LL_INFOS() << "destroyContext begins" << LL_ENDL; + LL_INFOS() << "destroyContext begins" << LL_ENDL; #if LL_X11 - mSDL_Display = NULL; - mSDL_XWindowID = None; - Lock_Display = NULL; - Unlock_Display = NULL; + mSDL_Display = NULL; + mSDL_XWindowID = None; + Lock_Display = NULL; + 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() << "SDL_QuitSS/VID begins" << LL_ENDL; - SDL_QuitSubSystem(SDL_INIT_VIDEO); // *FIX: this might be risky... + // Clean up remaining GL state before blowing away window + LL_INFOS() << "shutdownGL begins" << LL_ENDL; + gGLManager.shutdownGL(); + LL_INFOS() << "SDL_QuitSS/VID begins" << LL_ENDL; + SDL_QuitSubSystem(SDL_INIT_VIDEO); // *FIX: this might be risky... - mWindow = NULL; + mWindow = NULL; } LLWindowSDL::~LLWindowSDL() { - quitCursors(); - destroyContext(); + quitCursors(); + destroyContext(); - if(mSupportedResolutions != NULL) - { - delete []mSupportedResolutions; - } + if(mSupportedResolutions != NULL) + { + delete []mSupportedResolutions; + } - gWindowImplementation = NULL; + gWindowImplementation = NULL; } @@ -899,77 +896,77 @@ void LLWindowSDL::restore() // Usually called from LLWindowManager::destroyWindow() void LLWindowSDL::close() { - // Is window is already closed? - // if (!mWindow) - // { - // return; - // } + // Is window is already closed? + // if (!mWindow) + // { + // return; + // } - // Make sure cursor is visible and we haven't mangled the clipping state. - setMouseClipping(FALSE); - showCursor(); + // Make sure cursor is visible and we haven't mangled the clipping state. + setMouseClipping(FALSE); + showCursor(); - destroyContext(); + destroyContext(); } BOOL LLWindowSDL::isValid() { - return (mWindow != NULL); + return (mWindow != NULL); } BOOL LLWindowSDL::getVisible() { - BOOL result = FALSE; + BOOL result = FALSE; // *FIX: This isn't really right... - // Then what is? - if (mWindow) - { - result = TRUE; - } + // Then what is? + if (mWindow) + { + result = TRUE; + } - return(result); + return(result); } BOOL LLWindowSDL::getMinimized() { - BOOL result = FALSE; + BOOL result = FALSE; - if (mWindow && (1 == mIsMinimized)) - { - result = TRUE; - } - return(result); + if (mWindow && (1 == mIsMinimized)) + { + result = TRUE; + } + return(result); } BOOL LLWindowSDL::getMaximized() { - BOOL result = FALSE; + BOOL result = FALSE; - if (mWindow) - { - // TODO - } + if (mWindow) + { + // TODO + } - return(result); + return(result); } BOOL LLWindowSDL::maximize() { - // TODO - return FALSE; + // TODO + return FALSE; } BOOL LLWindowSDL::getFullscreen() { - return mFullscreen; + return mFullscreen; } BOOL LLWindowSDL::getPosition(LLCoordScreen *position) { // *FIX: can anything be done with this? - position->mX = 0; - position->mY = 0; + position->mX = 0; + position->mY = 0; return TRUE; } @@ -978,7 +975,7 @@ BOOL LLWindowSDL::getSize(LLCoordScreen *size) if (mWindow) { SDL_GetWindowSize(mWindow, &size->mX, &size->mY); - return (TRUE); + return (TRUE); } return (FALSE); @@ -989,7 +986,7 @@ BOOL LLWindowSDL::getSize(LLCoordWindow *size) if (mWindow) { SDL_GetWindowSize(mWindow, &size->mX, &size->mY); - return (TRUE); + return (TRUE); } return (FALSE); @@ -997,100 +994,100 @@ BOOL LLWindowSDL::getSize(LLCoordWindow *size) BOOL LLWindowSDL::setPosition(const LLCoordScreen position) { - if(mWindow) - { + if(mWindow) + { // *FIX: (?) - //MacMoveWindow(mWindow, position.mX, position.mY, false); - } + //MacMoveWindow(mWindow, position.mX, position.mY, false); + } - return TRUE; + return TRUE; } 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_WINDOWEVENT; - event.window.event = SDL_WINDOWEVENT_RESIZED; - event.window.data1 = size.mX; - event.window.data2 = size.mY; - SDL_PushEvent(&event); // copied into queue - - return TRUE; - } - - return FALSE; + 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_WINDOWEVENT; + event.window.event = SDL_WINDOWEVENT_RESIZED; + event.window.data1 = size.mX; + event.window.data2 = size.mY; + SDL_PushEvent(&event); // copied into queue + + return TRUE; + } + + return FALSE; } BOOL LLWindowSDL::setSizeImpl(const LLCoordWindow size) { - if(mWindow) - { - // Push a resize event onto SDL's queue - we'll handle it - // when it comes out again. - SDL_Event event; - event.type = SDL_WINDOWEVENT; - event.window.event = SDL_WINDOWEVENT_RESIZED; - event.window.data1 = size.mX; - event.window.data2 = size.mY; - SDL_PushEvent(&event); // copied into queue - - return TRUE; - } + 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_WINDOWEVENT; + event.window.event = SDL_WINDOWEVENT_RESIZED; + event.window.data1 = size.mX; + event.window.data2 = size.mY; + SDL_PushEvent(&event); // copied into queue + + return TRUE; + } - return FALSE; + return FALSE; } void LLWindowSDL::swapBuffers() { - if (mWindow) - { - SDL_GL_SwapWindow(mWindow); - } + if (mWindow) + { + SDL_GL_SwapWindow(mWindow); + } } U32 LLWindowSDL::getFSAASamples() { - return mFSAASamples; + return mFSAASamples; } void LLWindowSDL::setFSAASamples(const U32 samples) { - mFSAASamples = samples; + mFSAASamples = samples; } F32 LLWindowSDL::getGamma() { - return 1/mGamma; + return 1/mGamma; } BOOL LLWindowSDL::restoreGamma() { - //CGDisplayRestoreColorSyncSettings(); - Uint16 ramp; - SDL_CalculateGammaRamp(1.0f, &ramp); - SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); - return true; + //CGDisplayRestoreColorSyncSettings(); + Uint16 ramp; + SDL_CalculateGammaRamp(1.0f, &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; - Uint16 ramp; - SDL_CalculateGammaRamp(mGamma, &ramp); - SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); - return true; + mGamma = gamma; + if (mGamma == 0) mGamma = 0.1f; + mGamma = 1/mGamma; + Uint16 ramp; + SDL_CalculateGammaRamp(mGamma, &ramp); + SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); + return true; } BOOL LLWindowSDL::isCursorHidden() { - return mCursorHidden; + return mCursorHidden; } @@ -1104,19 +1101,19 @@ void LLWindowSDL::setMouseClipping( BOOL b ) // virtual void LLWindowSDL::setMinSize(U32 min_width, U32 min_height, bool enforce_immediately) { - LLWindow::setMinSize(min_width, min_height, enforce_immediately); + LLWindow::setMinSize(min_width, min_height, enforce_immediately); #if LL_X11 - // Set the minimum size limits for X11 window - // so the window manager doesn't allow resizing below those limits. - XSizeHints* hints = XAllocSizeHints(); - hints->flags |= PMinSize; - hints->min_width = mMinWindowWidth; - hints->min_height = mMinWindowHeight; + // 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); + XSetWMNormalHints(mSDL_Display, mSDL_XWindowID, hints); - XFree(hints); + XFree(hints); #endif } @@ -1143,95 +1140,95 @@ void LLWindowSDL::toggleVSync(bool enable_vsync) BOOL LLWindowSDL::setCursorPosition(const LLCoordWindow position) { - BOOL result = TRUE; - LLCoordScreen screen_pos; + BOOL result = TRUE; + LLCoordScreen screen_pos; - if (!convertCoords(position, &screen_pos)) - { - return FALSE; - } + if (!convertCoords(position, &screen_pos)) + { + return FALSE; + } - //LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL; + //LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL; - // do the actual forced cursor move. - if (mFullscreen) - SDL_WarpMouseGlobal(screen_pos.mX, screen_pos.mY); - else - 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; + // do the actual forced cursor move. + if (mFullscreen) + SDL_WarpMouseGlobal(screen_pos.mX, screen_pos.mY); + else + SDL_WarpMouseInWindow(mWindow, screen_pos.mX, screen_pos.mY); - return result; + //LL_INFOS() << llformat("llcw %d,%d -> scr %d,%d", position.mX, position.mY, screen_pos.mX, screen_pos.mY) << LL_ENDL; + + return result; } BOOL LLWindowSDL::getCursorPosition(LLCoordWindow *position) { - //Point cursor_point; - LLCoordScreen screen_pos; + //Point cursor_point; + LLCoordScreen screen_pos; - //GetMouse(&cursor_point); + //GetMouse(&cursor_point); int x, y; SDL_GetMouseState(&x, &y); - screen_pos.mX = x; - screen_pos.mY = y; + screen_pos.mX = x; + screen_pos.mY = y; - return convertCoords(screen_pos, position); + return convertCoords(screen_pos, position); } 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); + // 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 + 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. + // 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. - // New assumptions: - // - pixels are square (the only reasonable choice, really) - // - The user runs their display at a native resolution, so the resolution of the display - // when the app is launched has an aspect ratio that matches the monitor. + // New assumptions: + // - pixels are square (the only reasonable choice, really) + // - The user runs their display at a native resolution, so the resolution of the display + // when the app is launched has an aspect ratio that matches the monitor. - //RN: actually, the assumption that there are no ridiculous resolutions (above the display's native capabilities) has - // been born out in my experience. - // Pixels are often not square (just ask the people who run their LCDs at 1024x768 or 800x600 when running fullscreen, like me) - // The ordering of display list is a blind assumption though, so we should check for max values - // Things might be different on the Mac though, so I'll defer to MBW + //RN: actually, the assumption that there are no ridiculous resolutions (above the display's native capabilities) has + // been born out in my experience. + // Pixels are often not square (just ask the people who run their LCDs at 1024x768 or 800x600 when running fullscreen, like me) + // The ordering of display list is a blind assumption though, so we should check for max values + // Things might be different on the Mac though, so I'll defer to MBW - // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution - // switching, and stashes it in mOriginalAspectRatio. Here, we just return it. + // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution + // switching, and stashes it in mOriginalAspectRatio. Here, we just return it. - if (mOverrideAspectRatio > 0.f) - { - return mOverrideAspectRatio; - } + if (mOverrideAspectRatio > 0.f) + { + return mOverrideAspectRatio; + } - return mOriginalAspectRatio; + return mOriginalAspectRatio; } F32 LLWindowSDL::getPixelAspectRatio() { - F32 pixel_aspect = 1.f; - if (getFullscreen()) - { - LLCoordScreen screen_size; - if (getSize(&screen_size)) - { - pixel_aspect = getNativeAspectRatio() * (F32)screen_size.mY / (F32)screen_size.mX; - } - } + F32 pixel_aspect = 1.f; + if (getFullscreen()) + { + LLCoordScreen screen_size; + if (getSize(&screen_size)) + { + pixel_aspect = getNativeAspectRatio() * (F32)screen_size.mY / (F32)screen_size.mX; + } + } - return pixel_aspect; + return pixel_aspect; } U32 LLWindowSDL::getAvailableVRAMMegabytes() @@ -1245,67 +1242,67 @@ U32 LLWindowSDL::getAvailableVRAMMegabytes() // dialogs are still usable in fullscreen. void LLWindowSDL::beforeDialog() { - bool running_x11 = false; + bool running_x11 = false; #if LL_X11 - running_x11 = (mSDL_XWindowID != None); + running_x11 = (mSDL_XWindowID != None); #endif //LL_X11 - LL_INFOS() << "LLWindowSDL::beforeDialog()" << LL_ENDL; + LL_INFOS() << "LLWindowSDL::beforeDialog()" << LL_ENDL; - if (SDLReallyCaptureInput(FALSE)) // must ungrab input so popup works! - { - if (mFullscreen) - { - // need to temporarily go non-fullscreen; bless SDL - // for providing a SDL_WM_ToggleFullScreen() - though - // it only works in X11 - if (running_x11 && mWindow) - { - SDL_SetWindowFullscreen(mWindow, SDL_WINDOW_FULLSCREEN); - } - } - } + if (SDLReallyCaptureInput(FALSE)) // must ungrab input so popup works! + { + if (mFullscreen) + { + // need to temporarily go non-fullscreen; bless SDL + // for providing a SDL_WM_ToggleFullScreen() - though + // it only works in X11 + if (running_x11 && mWindow) + { + SDL_SetWindowFullscreen(mWindow, SDL_WINDOW_FULLSCREEN); + } + } + } #if LL_X11 - if (mSDL_Display) - { - // Everything that we/SDL asked for should happen before we - // potentially hand control over to GTK. - maybe_lock_display(); - XSync(mSDL_Display, False); - maybe_unlock_display(); - } + if (mSDL_Display) + { + // Everything that we/SDL asked for should happen before we + // potentially hand control over to GTK. + maybe_lock_display(); + XSync(mSDL_Display, False); + maybe_unlock_display(); + } #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(); + // 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(); + maybe_lock_display(); } void LLWindowSDL::afterDialog() { - bool running_x11 = false; + bool running_x11 = false; #if LL_X11 - running_x11 = (mSDL_XWindowID != None); + running_x11 = (mSDL_XWindowID != None); #endif //LL_X11 - LL_INFOS() << "LLWindowSDL::afterDialog()" << LL_ENDL; + LL_INFOS() << "LLWindowSDL::afterDialog()" << LL_ENDL; - maybe_unlock_display(); + maybe_unlock_display(); - if (mFullscreen) - { - // need to restore fullscreen mode after dialog - only works - // in X11 - if (running_x11 && mWindow) - { - SDL_SetWindowFullscreen(mWindow, SDL_WINDOW_FULLSCREEN); - } - } + if (mFullscreen) + { + // need to restore fullscreen mode after dialog - only works + // in X11 + if (running_x11 && mWindow) + { + SDL_SetWindowFullscreen(mWindow, SDL_WINDOW_FULLSCREEN); + } + } } @@ -1313,45 +1310,45 @@ void LLWindowSDL::afterDialog() // 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(); - } + 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; - - F32 remaining_time = mFlashTimer.getRemainingTimeF32(); - if (remaining_time < seconds) - remaining_time = seconds; - mFlashTimer.reset(); - mFlashTimer.setTimerExpirySec(remaining_time); - - x11_set_urgent(TRUE); - mFlashing = TRUE; + LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; +#else + LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; + + F32 remaining_time = mFlashTimer.getRemainingTimeF32(); + if (remaining_time < seconds) + remaining_time = seconds; + mFlashTimer.reset(); + mFlashTimer.setTimerExpirySec(remaining_time); + + x11_set_urgent(TRUE); + mFlashing = TRUE; #endif // LL_X11 } @@ -1359,136 +1356,136 @@ void LLWindowSDL::flashIcon(F32 seconds) #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 + 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 } BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &text) { - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - gchar * const data = gtk_clipboard_wait_for_text(clipboard); - if (data) - { - text = LLWString(utf8str_to_wstring(data)); - g_free(data); - return TRUE; - } - } - return FALSE; // failure + if (ll_try_gtk_init()) + { + GtkClipboard * const clipboard = + gtk_clipboard_get(GDK_NONE); + gchar * const data = gtk_clipboard_wait_for_text(clipboard); + if (data) + { + text = LLWString(utf8str_to_wstring(data)); + g_free(data); + return TRUE; + } + } + return FALSE; // failure } 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 + 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 } 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 + 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 } BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &text) { - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gchar * const data = gtk_clipboard_wait_for_text(clipboard); - if (data) - { - text = LLWString(utf8str_to_wstring(data)); - g_free(data); - return TRUE; - } - } - return FALSE; // failure + if (ll_try_gtk_init()) + { + GtkClipboard * const clipboard = + gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gchar * const data = gtk_clipboard_wait_for_text(clipboard); + if (data) + { + text = LLWString(utf8str_to_wstring(data)); + g_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 + 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 SDL_HasClipboardText(); + return SDL_HasClipboardText(); } BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) { - auto data = SDL_GetClipboardText(); - if (data) - { - dst = LLWString(utf8str_to_wstring(data)); - SDL_free(data); - return TRUE; - } - return FALSE; + auto data = SDL_GetClipboardText(); + if (data) + { + dst = LLWString(utf8str_to_wstring(data)); + SDL_free(data); + return TRUE; + } + return FALSE; } BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) { - return !SDL_SetClipboardText(wstring_to_utf8str(s).c_str()); + return !SDL_SetClipboardText(wstring_to_utf8str(s).c_str()); } BOOL LLWindowSDL::isPrimaryTextAvailable() { - return FALSE; // unsupported + return FALSE; // unsupported } BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &dst) { - return FALSE; // unsupported + return FALSE; // unsupported } BOOL LLWindowSDL::copyTextToPrimary(const LLWString &s) { - return FALSE; // unsupported + return FALSE; // unsupported } #endif // LL_GTK LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) { - if (!mSupportedResolutions) - { - mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; - mNumSupportedResolutions = 0; + if (!mSupportedResolutions) + { + mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; + mNumSupportedResolutions = 0; /* SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); @@ -1527,10 +1524,10 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso } } //} - } + } - num_resolutions = mNumSupportedResolutions; - return mSupportedResolutions; + num_resolutions = mNumSupportedResolutions; + return mSupportedResolutions; } BOOL LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to) @@ -1543,7 +1540,7 @@ BOOL LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to) SDL_GetWindowSize(mWindow, nullptr, &h); to->mY = h - from.mY - 1; - return TRUE; + return TRUE; } BOOL LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to) @@ -1556,43 +1553,43 @@ BOOL LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to) SDL_GetWindowSize(mWindow, nullptr, &h); to->mY = h - from.mY - 1; - return TRUE; + return TRUE; } BOOL LLWindowSDL::convertCoords(LLCoordScreen from, LLCoordWindow* to) { if (!to) - return FALSE; + return FALSE; - // In the fullscreen case, window and screen coordinates are the same. - to->mX = from.mX; - to->mY = from.mY; + // In the fullscreen case, window and screen coordinates are the same. + to->mX = from.mX; + to->mY = from.mY; return (TRUE); } BOOL LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordScreen *to) { if (!to) - return FALSE; + return FALSE; - // In the fullscreen case, window and screen coordinates are the same. - to->mX = from.mX; - to->mY = from.mY; + // In the fullscreen case, window and screen coordinates are the same. + to->mX = from.mX; + to->mY = from.mY; return (TRUE); } BOOL LLWindowSDL::convertCoords(LLCoordScreen from, LLCoordGL *to) { - LLCoordWindow window_coord; + LLCoordWindow window_coord; - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); } BOOL LLWindowSDL::convertCoords(LLCoordGL from, LLCoordScreen *to) { - LLCoordWindow window_coord; + LLCoordWindow window_coord; - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); } @@ -1600,226 +1597,226 @@ BOOL LLWindowSDL::convertCoords(LLCoordGL from, LLCoordScreen *to) void LLWindowSDL::setupFailure(const std::string& text, const std::string& caption, U32 type) { - destroyContext(); + destroyContext(); - OSMessageBox(text, caption, type); + OSMessageBox(text, caption, type); } BOOL LLWindowSDL::SDLReallyCaptureInput(BOOL capture) { - // note: this used to be safe to call nestedly, but in the - // end that's not really a wise usage pattern, so don't. + // note: this used to be safe to call nestedly, but in the + // end that's not really a wise usage pattern, so don't. - if (capture) - mReallyCapturedCount = 1; - else - mReallyCapturedCount = 0; - - SDL_bool wantmode, newmode; - if (mReallyCapturedCount <= 0) // uncapture - { - wantmode = SDL_FALSE; - } else // capture - { - wantmode = SDL_TRUE; - } - - if (mReallyCapturedCount < 0) // yuck, imbalance. - { - mReallyCapturedCount = 0; - LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL; - } + if (capture) + mReallyCapturedCount = 1; + else + mReallyCapturedCount = 0; - if (!mFullscreen) /* only bother if we're windowed anyway */ - { + SDL_bool wantmode, newmode; + if (mReallyCapturedCount <= 0) // uncapture + { + wantmode = SDL_FALSE; + } else // capture + { + wantmode = SDL_TRUE; + } + + if (mReallyCapturedCount < 0) // yuck, imbalance. + { + mReallyCapturedCount = 0; + LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL; + } + + if (!mFullscreen) /* only bother if we're windowed anyway */ + { #if LL_X11 - if (mSDL_Display) - { - /* 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_TRUE) - { - //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_TRUE; - else - newmode = SDL_FALSE; - } else if (wantmode == SDL_FALSE) - { - //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; - newmode = SDL_FALSE; - //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; + if (mSDL_Display) + { + /* 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_TRUE) + { + //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_TRUE; + else + newmode = SDL_FALSE; + } else if (wantmode == SDL_FALSE) + { + //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; + newmode = SDL_FALSE; + //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; - } - - // return boolean success for whether we ended up in the desired state - return (capture && SDL_TRUE==newmode) || - (!capture && SDL_FALSE==newmode); + } else { + // pretend we got what we wanted, when really we don't care. + newmode = wantmode; + } + + // return boolean success for whether we ended up in the desired state + return (capture && SDL_TRUE==newmode) || + (!capture && SDL_FALSE==newmode); } U32 LLWindowSDL::SDLCheckGrabbyKeys(SDL_Keycode 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 - spoil their day by acquiring the exclusive X11 mouse lock for as - long as ALT is held down, so the window manager can't easily - see what's happening. Tested successfully with Metacity. - And... do the same with CTRL, for other darn WMs. We don't - care about other metakeys as SL doesn't use them with dragging - (for now). */ - - /* We maintain a bitmap of critical keys which are up and down - instead of simply key-counting, because SDL sometimes reports - misbalanced keyup/keydown event pairs to us for whatever reason. */ - - 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; - } + /* part of the fix for SL-13243: Some popular window managers like + to totally eat alt-drag for the purposes of moving windows. We + spoil their day by acquiring the exclusive X11 mouse lock for as + long as ALT is held down, so the window manager can't easily + see what's happening. Tested successfully with Metacity. + And... do the same with CTRL, for other darn WMs. We don't + care about other metakeys as SL doesn't use them with dragging + (for now). */ + + /* We maintain a bitmap of critical keys which are up and down + instead of simply key-counting, because SDL sometimes reports + misbalanced keyup/keydown event pairs to us for whatever reason. */ + + 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; + } - if (gain) - mGrabbyKeyFlags |= mask; - else - mGrabbyKeyFlags &= ~mask; + if (gain) + mGrabbyKeyFlags |= mask; + else + mGrabbyKeyFlags &= ~mask; - //LL_INFOS() << "mGrabbyKeyFlags=" << mGrabbyKeyFlags << LL_ENDL; + //LL_INFOS() << "mGrabbyKeyFlags=" << mGrabbyKeyFlags << LL_ENDL; - /* 0 means we don't need to mousegrab, otherwise grab. */ - return mGrabbyKeyFlags; + /* 0 means we don't need to mousegrab, otherwise grab. */ + return mGrabbyKeyFlags; } void check_vm_bloat() { #if LL_LINUX - // watch our own VM and RSS sizes, warn if we bloated rapidly - static const std::string STATS_FILE = "/proc/self/stat"; - FILE *fp = fopen(STATS_FILE.c_str(), "r"); - if (fp) - { - static long long last_vm_size = 0; - static long long last_rss_size = 0; - const long long significant_vm_difference = 250 * 1024*1024; - const long long significant_rss_difference = 50 * 1024*1024; - long long this_vm_size = 0; - long long this_rss_size = 0; - - ssize_t res; - size_t dummy; - char *ptr = NULL; - for (int i=0; i<22; ++i) // parse past the values we don't want - { - res = getdelim(&ptr, &dummy, ' ', fp); - if (-1 == res) - { - LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; - goto finally; - } - free(ptr); - ptr = NULL; - } - // 23rd space-delimited entry is vsize - res = getdelim(&ptr, &dummy, ' ', fp); - llassert(ptr); - if (-1 == res) - { - LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; - goto finally; - } - this_vm_size = atoll(ptr); - free(ptr); - ptr = NULL; - // 24th space-delimited entry is RSS - res = getdelim(&ptr, &dummy, ' ', fp); - llassert(ptr); - if (-1 == res) - { - LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; - goto finally; - } - this_rss_size = getpagesize() * atoll(ptr); - free(ptr); - ptr = NULL; + // watch our own VM and RSS sizes, warn if we bloated rapidly + static const std::string STATS_FILE = "/proc/self/stat"; + FILE *fp = fopen(STATS_FILE.c_str(), "r"); + if (fp) + { + static long long last_vm_size = 0; + static long long last_rss_size = 0; + const long long significant_vm_difference = 250 * 1024*1024; + const long long significant_rss_difference = 50 * 1024*1024; + long long this_vm_size = 0; + long long this_rss_size = 0; + + ssize_t res; + size_t dummy; + char *ptr = NULL; + for (int i=0; i<22; ++i) // parse past the values we don't want + { + res = getdelim(&ptr, &dummy, ' ', fp); + if (-1 == res) + { + LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; + goto finally; + } + free(ptr); + ptr = NULL; + } + // 23rd space-delimited entry is vsize + res = getdelim(&ptr, &dummy, ' ', fp); + llassert(ptr); + if (-1 == res) + { + LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; + goto finally; + } + this_vm_size = atoll(ptr); + free(ptr); + ptr = NULL; + // 24th space-delimited entry is RSS + res = getdelim(&ptr, &dummy, ' ', fp); + llassert(ptr); + if (-1 == res) + { + LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; + goto finally; + } + this_rss_size = getpagesize() * atoll(ptr); + free(ptr); + ptr = NULL; - LL_INFOS() << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << LL_ENDL; + LL_INFOS() << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << LL_ENDL; - if (llabs(last_vm_size - this_vm_size) > - significant_vm_difference) - { - if (this_vm_size > last_vm_size) - { - LL_WARNS() << "VM size grew by " << (this_vm_size - last_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; - } - else - { - LL_INFOS() << "VM size shrank by " << (last_vm_size - this_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; - } - } + if (llabs(last_vm_size - this_vm_size) > + significant_vm_difference) + { + if (this_vm_size > last_vm_size) + { + LL_WARNS() << "VM size grew by " << (this_vm_size - last_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + else + { + LL_INFOS() << "VM size shrank by " << (last_vm_size - this_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + } - if (llabs(last_rss_size - this_rss_size) > - significant_rss_difference) - { - if (this_rss_size > last_rss_size) - { - LL_WARNS() << "RSS size grew by " << (this_rss_size - last_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; - } - else - { - LL_INFOS() << "RSS size shrank by " << (last_rss_size - this_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; - } - } + if (llabs(last_rss_size - this_rss_size) > + significant_rss_difference) + { + if (this_rss_size > last_rss_size) + { + LL_WARNS() << "RSS size grew by " << (this_rss_size - last_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + else + { + LL_INFOS() << "RSS size shrank by " << (last_rss_size - this_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + } - last_rss_size = this_rss_size; - last_vm_size = this_vm_size; + last_rss_size = this_rss_size; + last_vm_size = this_vm_size; finally: - if (NULL != ptr) - { - free(ptr); - ptr = NULL; - } - fclose(fp); - } + if (NULL != ptr) + { + free(ptr); + ptr = NULL; + } + fclose(fp); + } #endif // LL_LINUX } @@ -1828,37 +1825,37 @@ finally: 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 + // 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() ); + // 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 // hack - doesn't belong here - but this is just for debugging if (getenv("LL_DEBUG_BLOAT")) { - check_vm_bloat(); + check_vm_bloat(); } } @@ -1881,25 +1878,25 @@ void LLWindowSDL::gatherInput() LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(TRUE); - mCallbacks->handleMouseMove(this, openGlCoord, mask); + MASK mask = gKeyboard->currentMask(TRUE); + mCallbacks->handleMouseMove(this, openGlCoord, mask); break; } case SDL_KEYDOWN: - mKeyScanCode = event.key.keysym.scancode; - mKeyModifiers = event.key.keysym.mod; - - 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); - - if (event.key.keysym.sym < SDLK_SPACE) - { - handleUnicodeUTF16(event.key.keysym.sym, - gKeyboard->currentMask(FALSE)); - } + mKeyScanCode = event.key.keysym.scancode; + mKeyModifiers = event.key.keysym.mod; + + 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); + + if (event.key.keysym.sym < SDLK_SPACE) + { + handleUnicodeUTF16(event.key.keysym.sym, + gKeyboard->currentMask(FALSE)); + } break; case SDL_TEXTINPUT: @@ -1911,14 +1908,14 @@ void LLWindowSDL::gatherInput() break; case SDL_KEYUP: - mKeyScanCode = event.key.keysym.scancode; - mKeyModifiers = event.key.keysym.mod; + mKeyScanCode = event.key.keysym.scancode; + mKeyModifiers = event.key.keysym.mod; - if (SDLCheckGrabbyKeys(event.key.keysym.sym, FALSE) == 0) - SDLReallyCaptureInput(FALSE); // part of the fix for SL-13243 + if (SDLCheckGrabbyKeys(event.key.keysym.sym, FALSE) == 0) + SDLReallyCaptureInput(FALSE); // part of the fix for SL-13243 - gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod); - break; + gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod); + break; case SDL_MOUSEBUTTONDOWN: { @@ -1926,7 +1923,7 @@ void LLWindowSDL::gatherInput() LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(TRUE); + MASK mask = gKeyboard->currentMask(TRUE); if (event.button.button == SDL_BUTTON_LEFT) // SDL doesn't manage double clicking... { @@ -1938,7 +1935,7 @@ void LLWindowSDL::gatherInput() if (++leftClick >= 2) { leftClick = 0; - isDoubleClick = true; + isDoubleClick = true; } } lastLeftDown = now; @@ -1953,7 +1950,7 @@ void LLWindowSDL::gatherInput() if (++rightClick >= 2) { rightClick = 0; - isDoubleClick = true; + isDoubleClick = true; } } lastRightDown = now; @@ -1962,20 +1959,20 @@ void LLWindowSDL::gatherInput() if (event.button.button == SDL_BUTTON_LEFT) // left { if (isDoubleClick) - mCallbacks->handleDoubleClick(this, openGlCoord, mask); + mCallbacks->handleDoubleClick(this, openGlCoord, mask); else - mCallbacks->handleMouseDown(this, openGlCoord, mask); + 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); - } + { + mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask); + } break; } @@ -1992,14 +1989,14 @@ void LLWindowSDL::gatherInput() LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(TRUE); + 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); + mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); // don't handle mousewheel here... break; @@ -2007,353 +2004,352 @@ void LLWindowSDL::gatherInput() case SDL_WINDOWEVENT: { - if (event.window.event == SDL_WINDOWEVENT_EXPOSED) { // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing! - int w, h; - SDL_GetWindowSize(mWindow, &w, &h); - mCallbacks->handlePaint(this, 0, 0, w, h); + if (event.window.event == SDL_WINDOWEVENT_EXPOSED) { // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing! + int w, h; + SDL_GetWindowSize(mWindow, &w, &h); + mCallbacks->handlePaint(this, 0, 0, w, h); } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - LL_INFOS() << "Handling a resize event: " << event.window.data1 << - "x" << event.window.data2 << LL_ENDL; + 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); + S32 width = llmax(event.window.data1, (S32)mMinWindowWidth); + S32 height = llmax(event.window.data2, (S32)mMinWindowHeight); - // *FIX: handle this? - // *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 - } + // *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 + } break; - } - */ + } + */ - mCallbacks->handleResize(this, width, height); - } + 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); - } + // 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) - { - mIsMinimized = (!event.active.gain); - - 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; - } + // Change in iconification/minimization state. + if ((!event.active.gain) != mIsMinimized) + { + mIsMinimized = (!event.active.gain); + + 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; + } } break; */ case SDL_QUIT: - if(mCallbacks->handleCloseRequest(this)) - { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL - } + if(mCallbacks->handleCloseRequest(this)) + { + // Get the app to initiate cleanup. + mCallbacks->handleQuit(this); + // 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(); + + 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); - mFlashing = FALSE; + x11_set_urgent(FALSE); + mFlashing = FALSE; } #endif // LL_X11 } static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty) { - SDL_Cursor *sdlcursor = NULL; - SDL_Surface *bmpsurface; + SDL_Cursor *sdlcursor = NULL; + SDL_Surface *bmpsurface; - // Load cursor pixel data from BMP file - bmpsurface = Load_BMP_Resource(filename); - if (bmpsurface && bmpsurface->w%8==0) - { - SDL_Surface *cursurface; - LL_DEBUGS() << "Loaded cursor file " << filename << " " - << 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)); - 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)) - { - // n.b. we already checked that width is a multiple of 8. - const int bitmap_bytes = (cursurface->w * cursurface->h) / 8; - unsigned char *cursor_data = new unsigned char[bitmap_bytes]; - unsigned char *cursor_mask = new unsigned char[bitmap_bytes]; - memset(cursor_data, 0, bitmap_bytes); - memset(cursor_mask, 0, bitmap_bytes); - int i,j; - // Walk the RGBA cursor pixel data, extracting both data and - // mask to build SDL-friendly cursor bitmaps from. The mask - // is inferred by color-keying against 200,200,200 - 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 srcred = pixelp[0]; - U8 srcgreen = pixelp[1]; - U8 srcblue = pixelp[2]; - BOOL mask_bit = (srcred != 200) - || (srcgreen != 200) - || (srcblue != 200); - BOOL data_bit = mask_bit && (srcgreen <= 80);//not 0x80 - unsigned char bit_offset = (cursurface->w/8) * i - + 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); - delete[] cursor_data; - delete[] cursor_mask; - } else { - LL_WARNS() << "CURSOR BLIT FAILURE, cursurface: " << cursurface << LL_ENDL; - } - SDL_FreeSurface(cursurface); - SDL_FreeSurface(bmpsurface); - } else { - LL_WARNS() << "CURSOR LOAD FAILURE " << filename << LL_ENDL; - } + // Load cursor pixel data from BMP file + bmpsurface = Load_BMP_Resource(filename); + if (bmpsurface && bmpsurface->w%8==0) + { + SDL_Surface *cursurface; + LL_DEBUGS() << "Loaded cursor file " << filename << " " + << 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)); + 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)) + { + // n.b. we already checked that width is a multiple of 8. + const int bitmap_bytes = (cursurface->w * cursurface->h) / 8; + unsigned char *cursor_data = new unsigned char[bitmap_bytes]; + unsigned char *cursor_mask = new unsigned char[bitmap_bytes]; + memset(cursor_data, 0, bitmap_bytes); + memset(cursor_mask, 0, bitmap_bytes); + int i,j; + // Walk the RGBA cursor pixel data, extracting both data and + // mask to build SDL-friendly cursor bitmaps from. The mask + // is inferred by color-keying against 200,200,200 + 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 srcred = pixelp[0]; + U8 srcgreen = pixelp[1]; + U8 srcblue = pixelp[2]; + BOOL mask_bit = (srcred != 200) + || (srcgreen != 200) + || (srcblue != 200); + BOOL data_bit = mask_bit && (srcgreen <= 80);//not 0x80 + unsigned char bit_offset = (cursurface->w/8) * i + + 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); + delete[] cursor_data; + delete[] cursor_mask; + } else { + LL_WARNS() << "CURSOR BLIT FAILURE, cursurface: " << cursurface << LL_ENDL; + } + SDL_FreeSurface(cursurface); + SDL_FreeSurface(bmpsurface); + } else { + LL_WARNS() << "CURSOR LOAD FAILURE " << filename << LL_ENDL; + } - return sdlcursor; + return sdlcursor; } void LLWindowSDL::updateCursor() { - if (ATIbug) { - // cursor-updating is very flaky when this bug is - // present; do nothing. - return; - } + if (ATIbug) { + // cursor-updating is very flaky when this bug is + // present; do nothing. + return; + } - if (mCurrentCursor != mNextCursor) - { - if (mNextCursor < UI_CURSOR_COUNT) - { - SDL_Cursor *sdlcursor = mSDLCursors[mNextCursor]; - // Try to default to the arrow for any cursors that - // did not load correctly. - if (!sdlcursor && mSDLCursors[UI_CURSOR_ARROW]) - sdlcursor = mSDLCursors[UI_CURSOR_ARROW]; - if (sdlcursor) - SDL_SetCursor(sdlcursor); - } else { - LL_WARNS() << "Tried to set invalid cursor number " << mNextCursor << LL_ENDL; - } - mCurrentCursor = mNextCursor; - } + if (mCurrentCursor != mNextCursor) + { + if (mNextCursor < UI_CURSOR_COUNT) + { + SDL_Cursor *sdlcursor = mSDLCursors[mNextCursor]; + // Try to default to the arrow for any cursors that + // did not load correctly. + if (!sdlcursor && mSDLCursors[UI_CURSOR_ARROW]) + sdlcursor = mSDLCursors[UI_CURSOR_ARROW]; + if (sdlcursor) + SDL_SetCursor(sdlcursor); + } else { + LL_WARNS() << "Tried to set invalid cursor number " << mNextCursor << LL_ENDL; + } + mCurrentCursor = mNextCursor; + } } void LLWindowSDL::initCursors() { - int i; - // Blank the cursor pointer array for those we may miss. - for (i=0; i<UI_CURSOR_COUNT; ++i) - { - mSDLCursors[i] = NULL; - } - // 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); + int i; + // Blank the cursor pointer array for those we may miss. + for (i=0; i<UI_CURSOR_COUNT; ++i) + { + mSDLCursors[i] = NULL; + } + // 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_TOOLGRAB] = makeSDLCursorFromBMP("lltoolgrab.BMP",2,13); - mSDLCursors[UI_CURSOR_TOOLLAND] = makeSDLCursorFromBMP("lltoolland.BMP",1,6); - mSDLCursors[UI_CURSOR_TOOLFOCUS] = makeSDLCursorFromBMP("lltoolfocus.BMP",8,5); - mSDLCursors[UI_CURSOR_TOOLCREATE] = makeSDLCursorFromBMP("lltoolcreate.BMP",7,7); - mSDLCursors[UI_CURSOR_ARROWDRAG] = makeSDLCursorFromBMP("arrowdrag.BMP",0,0); - mSDLCursors[UI_CURSOR_ARROWCOPY] = makeSDLCursorFromBMP("arrowcop.BMP",0,0); - mSDLCursors[UI_CURSOR_ARROWDRAGMULTI] = makeSDLCursorFromBMP("llarrowdragmulti.BMP",0,0); - mSDLCursors[UI_CURSOR_ARROWCOPYMULTI] = makeSDLCursorFromBMP("arrowcopmulti.BMP",0,0); - mSDLCursors[UI_CURSOR_NOLOCKED] = makeSDLCursorFromBMP("llnolocked.BMP",8,8); - mSDLCursors[UI_CURSOR_ARROWLOCKED] = makeSDLCursorFromBMP("llarrowlocked.BMP",0,0); - mSDLCursors[UI_CURSOR_GRABLOCKED] = makeSDLCursorFromBMP("llgrablocked.BMP",2,13); - mSDLCursors[UI_CURSOR_TOOLTRANSLATE] = makeSDLCursorFromBMP("lltooltranslate.BMP",0,0); - mSDLCursors[UI_CURSOR_TOOLROTATE] = makeSDLCursorFromBMP("lltoolrotate.BMP",0,0); - mSDLCursors[UI_CURSOR_TOOLSCALE] = makeSDLCursorFromBMP("lltoolscale.BMP",0,0); - mSDLCursors[UI_CURSOR_TOOLCAMERA] = makeSDLCursorFromBMP("lltoolcamera.BMP",7,5); - mSDLCursors[UI_CURSOR_TOOLPAN] = makeSDLCursorFromBMP("lltoolpan.BMP",7,5); - mSDLCursors[UI_CURSOR_TOOLZOOMIN] = makeSDLCursorFromBMP("lltoolzoomin.BMP",7,5); + mSDLCursors[UI_CURSOR_NO] = makeSDLCursorFromBMP("llno.BMP",8,8); + mSDLCursors[UI_CURSOR_WORKING] = makeSDLCursorFromBMP("working.BMP",12,15); + 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); + mSDLCursors[UI_CURSOR_TOOLCREATE] = makeSDLCursorFromBMP("lltoolcreate.BMP",7,7); + mSDLCursors[UI_CURSOR_ARROWDRAG] = makeSDLCursorFromBMP("arrowdrag.BMP",0,0); + mSDLCursors[UI_CURSOR_ARROWCOPY] = makeSDLCursorFromBMP("arrowcop.BMP",0,0); + mSDLCursors[UI_CURSOR_ARROWDRAGMULTI] = makeSDLCursorFromBMP("llarrowdragmulti.BMP",0,0); + mSDLCursors[UI_CURSOR_ARROWCOPYMULTI] = makeSDLCursorFromBMP("arrowcopmulti.BMP",0,0); + mSDLCursors[UI_CURSOR_NOLOCKED] = makeSDLCursorFromBMP("llnolocked.BMP",8,8); + mSDLCursors[UI_CURSOR_ARROWLOCKED] = makeSDLCursorFromBMP("llarrowlocked.BMP",0,0); + mSDLCursors[UI_CURSOR_GRABLOCKED] = makeSDLCursorFromBMP("llgrablocked.BMP",2,13); + mSDLCursors[UI_CURSOR_TOOLTRANSLATE] = makeSDLCursorFromBMP("lltooltranslate.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLROTATE] = makeSDLCursorFromBMP("lltoolrotate.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLSCALE] = makeSDLCursorFromBMP("lltoolscale.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLCAMERA] = makeSDLCursorFromBMP("lltoolcamera.BMP",7,5); + mSDLCursors[UI_CURSOR_TOOLPAN] = makeSDLCursorFromBMP("lltoolpan.BMP",7,5); + mSDLCursors[UI_CURSOR_TOOLZOOMIN] = makeSDLCursorFromBMP("lltoolzoomin.BMP",7,5); mSDLCursors[UI_CURSOR_TOOLZOOMOUT] = makeSDLCursorFromBMP("lltoolzoomout.BMP", 7, 5); - mSDLCursors[UI_CURSOR_TOOLPICKOBJECT3] = makeSDLCursorFromBMP("toolpickobject3.BMP",0,0); - mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP("toolplay.BMP",0,0); - mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0); - mSDLCursors[UI_CURSOR_TOOLMEDIAOPEN] = makeSDLCursorFromBMP("toolmediaopen.BMP",0,0); - mSDLCursors[UI_CURSOR_PIPETTE] = makeSDLCursorFromBMP("lltoolpipette.BMP",2,28); - mSDLCursors[UI_CURSOR_TOOLSIT] = makeSDLCursorFromBMP("toolsit.BMP",20,15); - mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",20,15); - mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",20,15); - mSDLCursors[UI_CURSOR_TOOLPATHFINDING] = makeSDLCursorFromBMP("lltoolpathfinding.BMP", 16, 16); - mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START] = makeSDLCursorFromBMP("lltoolpathfindingpathstart.BMP", 16, 16); - mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathstartadd.BMP", 16, 16); - mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END] = makeSDLCursorFromBMP("lltoolpathfindingpathend.BMP", 16, 16); - mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathendadd.BMP", 16, 16); - mSDLCursors[UI_CURSOR_TOOLNO] = makeSDLCursorFromBMP("llno.BMP",8,8); - - if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) { - LL_INFOS() << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << LL_ENDL; - ATIbug = true; - } + mSDLCursors[UI_CURSOR_TOOLPICKOBJECT3] = makeSDLCursorFromBMP("toolpickobject3.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP("toolplay.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLMEDIAOPEN] = makeSDLCursorFromBMP("toolmediaopen.BMP",0,0); + mSDLCursors[UI_CURSOR_PIPETTE] = makeSDLCursorFromBMP("lltoolpipette.BMP",2,28); + mSDLCursors[UI_CURSOR_TOOLSIT] = makeSDLCursorFromBMP("toolsit.BMP",20,15); + mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",20,15); + mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",20,15); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING] = makeSDLCursorFromBMP("lltoolpathfinding.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START] = makeSDLCursorFromBMP("lltoolpathfindingpathstart.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathstartadd.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END] = makeSDLCursorFromBMP("lltoolpathfindingpathend.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathendadd.BMP", 16, 16); + mSDLCursors[UI_CURSOR_TOOLNO] = makeSDLCursorFromBMP("llno.BMP",8,8); + + if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) { + LL_INFOS() << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << LL_ENDL; + ATIbug = true; + } } void LLWindowSDL::quitCursors() { - int i; - if (mWindow) - { - for (i=0; i<UI_CURSOR_COUNT; ++i) - { - if (mSDLCursors[i]) - { - SDL_FreeCursor(mSDLCursors[i]); - mSDLCursors[i] = NULL; - } - } - } else { - // SDL doesn't refcount cursors, so if the window has - // already been destroyed then the cursors have gone with it. - LL_INFOS() << "Skipping quitCursors: mWindow already gone." << LL_ENDL; - for (i=0; i<UI_CURSOR_COUNT; ++i) - mSDLCursors[i] = NULL; - } + int i; + if (mWindow) + { + for (i=0; i<UI_CURSOR_COUNT; ++i) + { + if (mSDLCursors[i]) + { + SDL_FreeCursor(mSDLCursors[i]); + mSDLCursors[i] = NULL; + } + } + } else { + // SDL doesn't refcount cursors, so if the window has + // already been destroyed then the cursors have gone with it. + LL_INFOS() << "Skipping quitCursors: mWindow already gone." << LL_ENDL; + for (i=0; i<UI_CURSOR_COUNT; ++i) + mSDLCursors[i] = NULL; + } } void LLWindowSDL::captureMouse() { - // SDL already enforces the semantics that captureMouse is - // used for, i.e. that we continue to get mouse events as long - // as a button is down regardless of whether we left the - // window, and in a less obnoxious way than SDL_WM_GrabInput - // which would confine the cursor to the window too. + // SDL already enforces the semantics that captureMouse is + // used for, i.e. that we continue to get mouse events as long + // as a button is down regardless of whether we left the + // window, and in a less obnoxious way than SDL_WM_GrabInput + // which would confine the cursor to the window too. - LL_DEBUGS() << "LLWindowSDL::captureMouse" << LL_ENDL; + LL_DEBUGS() << "LLWindowSDL::captureMouse" << LL_ENDL; } void LLWindowSDL::releaseMouse() { - // see LWindowSDL::captureMouse() - - LL_DEBUGS() << "LLWindowSDL::releaseMouse" << LL_ENDL; + // see LWindowSDL::captureMouse() + + LL_DEBUGS() << "LLWindowSDL::releaseMouse" << LL_ENDL; } void LLWindowSDL::hideCursor() { - if(!mCursorHidden) - { - // LL_INFOS() << "hideCursor: hiding" << LL_ENDL; - mCursorHidden = TRUE; - mHideCursorPermanent = TRUE; - SDL_ShowCursor(0); - } - else - { - // LL_INFOS() << "hideCursor: already hidden" << LL_ENDL; - } + if(!mCursorHidden) + { + // LL_INFOS() << "hideCursor: hiding" << LL_ENDL; + mCursorHidden = TRUE; + mHideCursorPermanent = TRUE; + SDL_ShowCursor(0); + } + else + { + // LL_INFOS() << "hideCursor: already hidden" << LL_ENDL; + } } void LLWindowSDL::showCursor() { - if(mCursorHidden) - { - // LL_INFOS() << "showCursor: showing" << LL_ENDL; - mCursorHidden = FALSE; - mHideCursorPermanent = FALSE; - SDL_ShowCursor(1); - } - else - { - // LL_INFOS() << "showCursor: already visible" << LL_ENDL; - } + if(mCursorHidden) + { + // LL_INFOS() << "showCursor: showing" << LL_ENDL; + mCursorHidden = FALSE; + mHideCursorPermanent = FALSE; + SDL_ShowCursor(1); + } + else + { + // LL_INFOS() << "showCursor: already visible" << LL_ENDL; + } } void LLWindowSDL::showCursorFromMouseMove() { - if (!mHideCursorPermanent) - { - showCursor(); - } + if (!mHideCursorPermanent) + { + showCursor(); + } } void LLWindowSDL::hideCursorUntilMouseMove() { - if (!mHideCursorPermanent) - { - hideCursor(); - mHideCursorPermanent = FALSE; - } + if (!mHideCursorPermanent) + { + hideCursor(); + mHideCursorPermanent = FALSE; + } } @@ -2386,119 +2382,119 @@ void LLSplashScreenSDL::hideImpl() #if LL_GTK static void response_callback (GtkDialog *dialog, - gint arg1, - gpointer user_data) + gint arg1, + gpointer user_data) { - gint *response = (gint*)user_data; - *response = arg1; - gtk_widget_destroy(GTK_WIDGET(dialog)); - gtk_main_quit(); + 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; + S32 rtn = OSBTN_CANCEL; - if(gWindowImplementation != NULL) - gWindowImplementation->beforeDialog(); + if(gWindowImplementation != NULL) + gWindowImplementation->beforeDialog(); - if (LLWindowSDL::ll_try_gtk_init()) - { - 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; - break; - case OSMB_OKCANCEL: - messagetype = GTK_MESSAGE_QUESTION; - buttons = GTK_BUTTONS_OK_CANCEL; - break; - case OSMB_YESNO: - messagetype = GTK_MESSAGE_QUESTION; - buttons = GTK_BUTTONS_YES_NO; - break; - } - win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, "%s", - text.c_str()); + if (LLWindowSDL::ll_try_gtk_init()) + { + 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; + break; + case OSMB_OKCANCEL: + messagetype = GTK_MESSAGE_QUESTION; + buttons = GTK_BUTTONS_OK_CANCEL; + break; + case OSMB_YESNO: + messagetype = GTK_MESSAGE_QUESTION; + buttons = GTK_BUTTONS_YES_NO; + 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); - } + // 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_position(GTK_WINDOW(win), + GTK_WIN_POS_CENTER_ON_PARENT); - gtk_window_set_type_hint(GTK_WINDOW(win), - GDK_WINDOW_TYPE_HINT_DIALOG); + 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()); + 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); + 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(); + // 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; - } + //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(); + if(gWindowImplementation != NULL) + gWindowImplementation->afterDialog(); - return rtn; + return rtn; } static void color_changed_callback(GtkWidget *widget, - gpointer user_data) + gpointer user_data) { - GtkColorSelection *colorsel = GTK_COLOR_SELECTION(widget); - GdkColor *colorp = (GdkColor*)user_data; - - gtk_color_selection_get_current_color(colorsel, colorp); + GtkColorSelection *colorsel = GTK_COLOR_SELECTION(widget); + GdkColor *colorp = (GdkColor*)user_data; + + gtk_color_selection_get_current_color(colorsel, colorp); } @@ -2510,25 +2506,25 @@ LLSD LLWindowSDL::getNativeKeyData() { LLSD result = LLSD::emptyMap(); - U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave! - - // we go through so many levels of device abstraction that I can't really guess - // what a plugin under GDK under Qt under SL under SDL under X11 considers - // a 'native' modifier mask. this has been sort of reverse-engineered... they *appear* - // to match GDK consts, but that may be co-incidence. - modifiers |= (mKeyModifiers & KMOD_LSHIFT) ? 0x0001 : 0; - modifiers |= (mKeyModifiers & KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift - modifiers |= (mKeyModifiers & KMOD_CAPS) ? 0x0002 : 0; - modifiers |= (mKeyModifiers & KMOD_LCTRL) ? 0x0004 : 0; - modifiers |= (mKeyModifiers & KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl - modifiers |= (mKeyModifiers & KMOD_LALT) ? 0x0008 : 0;// untested - modifiers |= (mKeyModifiers & KMOD_RALT) ? 0x0008 : 0;// untested - // *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). + U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave! + + // we go through so many levels of device abstraction that I can't really guess + // what a plugin under GDK under Qt under SL under SDL under X11 considers + // a 'native' modifier mask. this has been sort of reverse-engineered... they *appear* + // to match GDK consts, but that may be co-incidence. + modifiers |= (mKeyModifiers & KMOD_LSHIFT) ? 0x0001 : 0; + modifiers |= (mKeyModifiers & KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift + modifiers |= (mKeyModifiers & KMOD_CAPS) ? 0x0002 : 0; + modifiers |= (mKeyModifiers & KMOD_LCTRL) ? 0x0004 : 0; + modifiers |= (mKeyModifiers & KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl + modifiers |= (mKeyModifiers & KMOD_LALT) ? 0x0008 : 0;// untested + modifiers |= (mKeyModifiers & KMOD_RALT) ? 0x0008 : 0;// untested + // *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["modifiers"] = (S32)modifiers; + result["modifiers"] = (S32)modifiers; return result; } @@ -2536,85 +2532,85 @@ LLSD LLWindowSDL::getNativeKeyData() BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) { - BOOL rtn = FALSE; + BOOL rtn = FALSE; - beforeDialog(); + beforeDialog(); - if (ll_try_gtk_init()) - { - GtkWidget *win = NULL; + if (ll_try_gtk_init()) + { + GtkWidget *win = NULL; - win = gtk_color_selection_dialog_new(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); - } + // 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; - } - } + 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(); + afterDialog(); - return rtn; + return rtn; } #else S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type) { - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - return 0; + LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; + return 0; } BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) { - return (FALSE); + return (FALSE); } #if LL_DARWIN @@ -2669,31 +2665,31 @@ LLSD LLWindowSDL::getNativeKeyData() // 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; - } - } + 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; + } + } } #endif @@ -2701,48 +2697,48 @@ void exec_cmd(const std::string& cmd, const std::string& arg) // Must begin with protocol identifier. void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) { - bool found = false; - S32 i; - for (i = 0; i < gURLProtocolWhitelistCount; i++) - { - if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos) - { - found = true; - break; - } - } + bool found = false; + S32 i; + for (i = 0; i < gURLProtocolWhitelistCount; i++) + { + if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos) + { + found = true; + break; + } + } - if (!found) - { - LL_WARNS() << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << LL_ENDL; - return; - } + if (!found) + { + LL_WARNS() << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << LL_ENDL; + return; + } + + LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; - LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; - #if LL_LINUX || LL_FREEBSD # if LL_X11 - if (mSDL_Display) - { - maybe_lock_display(); - // Just in case - before forking. - XSync(mSDL_Display, False); - maybe_unlock_display(); - } + if (mSDL_Display) + { + maybe_lock_display(); + // Just in case - before forking. + XSync(mSDL_Display, False); + maybe_unlock_display(); + } # endif // LL_X11 - std::string cmd, arg; + std::string cmd, arg; #ifdef LL_USESYSTEMLIBS - cmd = gDirUtilp->getExecutableDir(); + cmd = gDirUtilp->getExecutableDir(); #else - cmd = gDirUtilp->getAppRODataDir(); - cmd += gDirUtilp->getDirDelimiter(); - cmd += "etc"; + cmd = gDirUtilp->getAppRODataDir(); + cmd += gDirUtilp->getDirDelimiter(); + cmd += "etc"; #endif - cmd += gDirUtilp->getDirDelimiter(); - cmd += "launch_url.sh"; - arg = escaped_url; - exec_cmd(cmd, arg); + cmd += gDirUtilp->getDirDelimiter(); + cmd += "launch_url.sh"; + arg = escaped_url; + exec_cmd(cmd, arg); #elif LL_DARWIN @@ -2781,152 +2777,152 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) #endif // LL_LINUX - LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; + 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; - } + 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; + // Unixoid mozilla really needs GTK. + return NULL; } void LLWindowSDL::bringToFront() { - // This is currently used when we are 'launched' to a specific - // map position externally. - LL_INFOS() << "bringToFront" << LL_ENDL; + // 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) - { - maybe_lock_display(); - XRaiseWindow(mSDL_Display, mSDL_XWindowID); - XSync(mSDL_Display, False); - maybe_unlock_display(); - } + if (mSDL_Display && !mFullscreen) + { + maybe_lock_display(); + XRaiseWindow(mSDL_Display, mSDL_XWindowID); + XSync(mSDL_Display, False); + maybe_unlock_display(); + } #endif // LL_X11 } //static std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() { - // Use libfontconfig to find us a nice ordered list of fallback fonts - // specific to this system. - std::string final_fallback("/usr/share/fonts/truetype/kochi/kochi-gothic.ttf"); - const int max_font_count_cutoff = 40; // fonts are expensive in the current system, don't enumerate an arbitrary number of them - // Our 'ideal' font properties which define the sorting results. - // slant=0 means Roman, index=0 means the first face in a font file - // (the one we actually use), weight=80 means medium weight, - // spacing=0 means proportional spacing. - std::string sort_order("slant=0:index=0:weight=80:spacing=0"); - // elide_unicode_coverage removes fonts from the list whose unicode - // range is covered by fonts earlier in the list. This usually - // removes ~90% of the fonts as redundant (which is great because - // the font list can be huge), but might unnecessarily reduce the - // renderable range if for some reason our FreeType actually fails - // to use some of the fonts we want it to. - const bool elide_unicode_coverage = true; - std::vector<std::string> rtns; - FcFontSet *fs = NULL; - FcPattern *sortpat = NULL; - - LL_INFOS() << "Getting system font list from FontConfig..." << LL_ENDL; - - // If the user has a system-wide language preference, then favor - // fonts from that language group. This doesn't affect the types - // of languages that can be displayed, but ensures that their - // preferred language is rendered from a single consistent font where - // possible. - FL_Locale *locale = NULL; - FL_Success success = FL_FindLocale(&locale, FL_MESSAGES); - if (success != 0) - { - if (success >= 2 && locale->lang) // confident! - { - LL_INFOS("AppInit") << "Language " << locale->lang << LL_ENDL; - LL_INFOS("AppInit") << "Location " << locale->country << LL_ENDL; - LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL; - - LL_INFOS() << "Preferring fonts of language: " - << locale->lang - << LL_ENDL; - sort_order = "lang=" + std::string(locale->lang) + ":" - + sort_order; - } - } - FL_FreeLocale(&locale); + // Use libfontconfig to find us a nice ordered list of fallback fonts + // specific to this system. + std::string final_fallback("/usr/share/fonts/truetype/kochi/kochi-gothic.ttf"); + const int max_font_count_cutoff = 40; // fonts are expensive in the current system, don't enumerate an arbitrary number of them + // Our 'ideal' font properties which define the sorting results. + // slant=0 means Roman, index=0 means the first face in a font file + // (the one we actually use), weight=80 means medium weight, + // spacing=0 means proportional spacing. + std::string sort_order("slant=0:index=0:weight=80:spacing=0"); + // elide_unicode_coverage removes fonts from the list whose unicode + // range is covered by fonts earlier in the list. This usually + // removes ~90% of the fonts as redundant (which is great because + // the font list can be huge), but might unnecessarily reduce the + // renderable range if for some reason our FreeType actually fails + // to use some of the fonts we want it to. + const bool elide_unicode_coverage = true; + std::vector<std::string> rtns; + FcFontSet *fs = NULL; + FcPattern *sortpat = NULL; + + LL_INFOS() << "Getting system font list from FontConfig..." << LL_ENDL; + + // If the user has a system-wide language preference, then favor + // fonts from that language group. This doesn't affect the types + // of languages that can be displayed, but ensures that their + // preferred language is rendered from a single consistent font where + // possible. + FL_Locale *locale = NULL; + FL_Success success = FL_FindLocale(&locale, FL_MESSAGES); + if (success != 0) + { + if (success >= 2 && locale->lang) // confident! + { + LL_INFOS("AppInit") << "Language " << locale->lang << LL_ENDL; + LL_INFOS("AppInit") << "Location " << locale->country << LL_ENDL; + LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL; + + LL_INFOS() << "Preferring fonts of language: " + << locale->lang + << LL_ENDL; + sort_order = "lang=" + std::string(locale->lang) + ":" + + sort_order; + } + } + FL_FreeLocale(&locale); - if (!FcInit()) - { - LL_WARNS() << "FontConfig failed to initialize." << LL_ENDL; - rtns.push_back(final_fallback); - return rtns; - } + if (!FcInit()) + { + LL_WARNS() << "FontConfig failed to initialize." << LL_ENDL; + rtns.push_back(final_fallback); + return rtns; + } - sortpat = FcNameParse((FcChar8*) sort_order.c_str()); - if (sortpat) - { - // Sort the list of system fonts from most-to-least-desirable. - FcResult result; - fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, - NULL, &result); - FcPatternDestroy(sortpat); - } + sortpat = FcNameParse((FcChar8*) sort_order.c_str()); + if (sortpat) + { + // Sort the list of system fonts from most-to-least-desirable. + FcResult result; + fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, + NULL, &result); + FcPatternDestroy(sortpat); + } - int found_font_count = 0; - if (fs) - { - // Get the full pathnames to the fonts, where available, - // which is what we really want. - found_font_count = fs->nfont; - for (int i=0; i<fs->nfont; ++i) - { - FcChar8 *filename; - if (FcResultMatch == FcPatternGetString(fs->fonts[i], - FC_FILE, 0, - &filename) - && filename) - { - rtns.push_back(std::string((const char*)filename)); - if (rtns.size() >= max_font_count_cutoff) - break; // hit limit - } - } - FcFontSetDestroy (fs); - } + int found_font_count = 0; + if (fs) + { + // Get the full pathnames to the fonts, where available, + // which is what we really want. + found_font_count = fs->nfont; + for (int i=0; i<fs->nfont; ++i) + { + FcChar8 *filename; + if (FcResultMatch == FcPatternGetString(fs->fonts[i], + FC_FILE, 0, + &filename) + && filename) + { + rtns.push_back(std::string((const char*)filename)); + if (rtns.size() >= max_font_count_cutoff) + break; // hit limit + } + } + FcFontSetDestroy (fs); + } - LL_DEBUGS() << "Using font list: " << LL_ENDL; - for (std::vector<std::string>::iterator it = rtns.begin(); - it != rtns.end(); - ++it) - { - LL_DEBUGS() << " file: " << *it << LL_ENDL; - } - LL_INFOS() << "Using " << rtns.size() << "/" << found_font_count << " system fonts." << LL_ENDL; + LL_DEBUGS() << "Using font list: " << LL_ENDL; + for (std::vector<std::string>::iterator it = rtns.begin(); + it != rtns.end(); + ++it) + { + LL_DEBUGS() << " file: " << *it << LL_ENDL; + } + LL_INFOS() << "Using " << rtns.size() << "/" << found_font_count << " system fonts." << LL_ENDL; - rtns.push_back(final_fallback); - return rtns; + rtns.push_back(final_fallback); + return rtns; } #endif // LL_SDL diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 17bdc16bf6..0dbd94b1fe 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindowsdl.h * @brief SDL implementation of LLWindow class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,191 +52,191 @@ class LLWindowSDL : public LLWindow { public: - 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; - /*virtual*/ 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; - void* createSharedContext() override; - void makeContextCurrent(void* context) override; - void destroySharedContext(void* context) override; - void toggleVSync(bool enable_vsync) 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; - U32 getFSAASamples() override; - void setFSAASamples(const U32 fsaa_samples) override; - BOOL restoreGamma() override; - ESwapMethod getSwapMethod() override { return mSwapMethod; } - void processMiscNativeEvents() override; - void gatherInput() override; - void swapBuffers() override; - /*virtual*/ void restoreGLContext() {}; - - void delayInputProcessing() override {}; - - // handy coordinate space conversion routines - 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; - void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } - - U32 getAvailableVRAMMegabytes() override; - - void beforeDialog() override; - void afterDialog() override; - - BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override; - - void *getPlatformWindow() override; - void bringToFront() override; - - void spawnWebBrowser(const std::string& escaped_url, bool async) override; - - static std::vector<std::string> getDynamicFallbackFontList(); - - // Not great that these are public, but they have to be accessible - // by non-class code and it's better than making them global. + 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; + /*virtual*/ 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 disable_vsync, const LLCoordScreen * const posp = NULL) override; + void* createSharedContext() override; + void makeContextCurrent(void* context) override; + void destroySharedContext(void* context) override; + void toggleVSync(bool enable_vsync) 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; + /*virtual*/ void restoreGLContext() {}; + + void delayInputProcessing() override { }; + + // handy coordinate space conversion routines + 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; + void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } + + U32 getAvailableVRAMMegabytes() override; + + void beforeDialog() override; + void afterDialog() override; + + BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override; + + void *getPlatformWindow() override; + void bringToFront() override; + + /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async) override; + + static std::vector<std::string> getDynamicFallbackFontList(); + + // Not great that these are public, but they have to be accessible + // by non-class code and it's better than making them global. #if LL_X11 - Window mSDL_XWindowID; - Display *mSDL_Display; + Window mSDL_XWindowID; + Display *mSDL_Display; #endif - void (*Lock_Display)(void); - void (*Unlock_Display)(void); + 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); + // Lazily initialize and check the runtime GTK version for goodness. + static bool ll_try_gtk_init(void); #endif // LL_GTK #if LL_X11 - static Window get_SDL_XWindowID(void); - static Display* get_SDL_Display(void); -#endif // LL_X11 + static Window get_SDL_XWindowID(void); + static Display* get_SDL_Display(void); +#endif // LL_X11 #if LL_DARWIN static BOOL sUseMultGL; #endif 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(); + 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(); - BOOL isValid() override; - LLSD getNativeKeyData() override; + BOOL isValid() override; + LLSD getNativeKeyData() override; - void initCursors(); - void quitCursors(); - void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); + void initCursors(); + void quitCursors(); + 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); + // Changes display resolution. Returns true if successful + BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); - // Go back to last fullscreen display resolution. - BOOL setFullscreenResolution(); + // Go back to last fullscreen display resolution. + BOOL setFullscreenResolution(); - BOOL shouldPostQuit() { return mPostQuit; } + BOOL shouldPostQuit() { return mPostQuit; } protected: - // - // Platform specific methods - // - - // 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); - void destroyContext(); - void setupFailure(const std::string& text, const std::string& caption, U32 type); - void fixWindowSize(void); - U32 SDLCheckGrabbyKeys(SDL_Keycode keysym, BOOL gain); - BOOL SDLReallyCaptureInput(BOOL capture); - - // - // Platform specific variables - // - U32 mGrabbyKeyFlags; - int mReallyCapturedCount; - SDL_Window * mWindow; - 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; - - int mSDLFlags; - - SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT]; - int mHaveInputFocus; /* 0=no, 1=yes, else unknown */ - int mIsMinimized; /* 0=no, 1=yes, else unknown */ - - friend class LLWindowManager; + // + // Platform specific methods + // + + // 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); + void destroyContext(); + void setupFailure(const std::string& text, const std::string& caption, U32 type); + void fixWindowSize(void); + U32 SDLCheckGrabbyKeys(SDL_Keycode keysym, BOOL gain); + BOOL SDLReallyCaptureInput(BOOL capture); + + // + // Platform specific variables + // + U32 mGrabbyKeyFlags; + int mReallyCapturedCount; + SDL_Window * mWindow; + 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; + + int mSDLFlags; + + SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT]; + 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; + void x11_set_urgent(BOOL urgent); + BOOL mFlashing; + LLTimer mFlashTimer; #endif //LL_X11 - - U32 mKeyScanCode; + + U32 mKeyScanCode; U32 mKeyVirtualKey; - Uint16 mKeyModifiers; + Uint16 mKeyModifiers; }; class LLSplashScreenSDL : public LLSplashScreen { public: - LLSplashScreenSDL(); - virtual ~LLSplashScreenSDL(); + LLSplashScreenSDL(); + virtual ~LLSplashScreenSDL(); - /*virtual*/ void showImpl(); - /*virtual*/ void updateImpl(const std::string& mesg); - /*virtual*/ void hideImpl(); + /*virtual*/ void showImpl(); + /*virtual*/ void updateImpl(const std::string& mesg); + /*virtual*/ 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 54e5f43e87..d6b93b93d9 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llwindowwin32.cpp * @brief Platform-dependent implementation of llwindow * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -53,7 +53,7 @@ #include <commdlg.h> #include <WinUser.h> #include <mapi.h> -#include <process.h> // for _spawn +#include <process.h> // for _spawn #include <shellapi.h> #include <fstream> #include <Imm.h> @@ -75,10 +75,10 @@ #pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems #pragma comment(lib, "dinput8") -const S32 MAX_MESSAGE_PER_UPDATE = 20; -const S32 BITS_PER_PIXEL = 32; -const S32 MAX_NUM_RESOLUTIONS = 32; -const F32 ICON_FLASH_TIME = 0.5f; +const S32 MAX_MESSAGE_PER_UPDATE = 20; +const S32 BITS_PER_PIXEL = 32; +const S32 MAX_NUM_RESOLUTIONS = 32; +const F32 ICON_FLASH_TIME = 0.5f; #ifndef WM_DPICHANGED #define WM_DPICHANGED 0x02E0 @@ -114,16 +114,16 @@ LLW32MsgCallback gAsyncMsgCallback = NULL; #ifndef DPI_ENUMS_DECLARED typedef enum PROCESS_DPI_AWARENESS { - PROCESS_DPI_UNAWARE = 0, - PROCESS_SYSTEM_DPI_AWARE = 1, - PROCESS_PER_MONITOR_DPI_AWARE = 2 + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; typedef enum MONITOR_DPI_TYPE { - MDT_EFFECTIVE_DPI = 0, - MDT_ANGULAR_DPI = 1, - MDT_RAW_DPI = 2, - MDT_DEFAULT = MDT_EFFECTIVE_DPI + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; #endif @@ -131,14 +131,14 @@ typedef enum MONITOR_DPI_TYPE { typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value); typedef HRESULT(STDAPICALLTYPE *GetProcessDpiAwarenessType)( - _In_ HANDLE hprocess, - _Out_ PROCESS_DPI_AWARENESS *value); + _In_ HANDLE hprocess, + _Out_ PROCESS_DPI_AWARENESS *value); typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( - _In_ HMONITOR hmonitor, - _In_ MONITOR_DPI_TYPE dpiType, - _Out_ UINT *dpiX, - _Out_ UINT *dpiY); + _In_ HMONITOR hmonitor, + _In_ MONITOR_DPI_TYPE dpiType, + _Out_ UINT *dpiX, + _Out_ UINT *dpiY); // // LLWindowWin32 @@ -146,19 +146,19 @@ typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( void show_window_creation_error(const std::string& title) { - LL_WARNS("Window") << title << LL_ENDL; + LL_WARNS("Window") << title << LL_ENDL; } HGLRC SafeCreateContext(HDC &hdc) { - __try - { - return wglCreateContext(hdc); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - return NULL; - } + __try + { + return wglCreateContext(hdc); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + return NULL; + } } GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) @@ -180,11 +180,11 @@ GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) //static BOOL LLWindowWin32::sIsClassRegistered = FALSE; -BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; -BOOL LLWindowWin32::sWinIMEOpened = FALSE; -HKL LLWindowWin32::sWinInputLocale = 0; -DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE; -DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC; +BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; +BOOL LLWindowWin32::sWinIMEOpened = FALSE; +HKL LLWindowWin32::sWinInputLocale = 0; +DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE; +DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC; LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1); // The following class LLWinImm delegates Windows IMM APIs. @@ -196,110 +196,110 @@ LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1); class LLWinImm { public: - static bool isAvailable() { return true; } + static bool isAvailable() { return true; } public: - // Wrappers for IMM API. - static BOOL isIME(HKL hkl); - static HIMC getContext(HWND hwnd); - static BOOL releaseContext(HWND hwnd, HIMC himc); - static BOOL getOpenStatus(HIMC himc); - static BOOL setOpenStatus(HIMC himc, BOOL status); - static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence); - static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence); - static BOOL getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form); - static BOOL setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form); - static LONG getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length); - static BOOL setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength); - static BOOL setCompositionFont(HIMC himc, LPLOGFONTW logfont); - static BOOL setCandidateWindow(HIMC himc, LPCANDIDATEFORM candidate_form); - static BOOL notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value); + // Wrappers for IMM API. + static BOOL isIME(HKL hkl); + static HIMC getContext(HWND hwnd); + static BOOL releaseContext(HWND hwnd, HIMC himc); + static BOOL getOpenStatus(HIMC himc); + static BOOL setOpenStatus(HIMC himc, BOOL status); + static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence); + static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence); + static BOOL getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form); + static BOOL setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form); + static LONG getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length); + static BOOL setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength); + static BOOL setCompositionFont(HIMC himc, LPLOGFONTW logfont); + static BOOL setCandidateWindow(HIMC himc, LPCANDIDATEFORM candidate_form); + static BOOL notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value); }; -// static -BOOL LLWinImm::isIME(HKL hkl) -{ - return ImmIsIME(hkl); +// static +BOOL LLWinImm::isIME(HKL hkl) +{ + return ImmIsIME(hkl); } -// static -HIMC LLWinImm::getContext(HWND hwnd) +// static +HIMC LLWinImm::getContext(HWND hwnd) { - return ImmGetContext(hwnd); + return ImmGetContext(hwnd); } -//static -BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc) -{ - return ImmReleaseContext(hwnd, himc); +//static +BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc) +{ + return ImmReleaseContext(hwnd, himc); } -// static -BOOL LLWinImm::getOpenStatus(HIMC himc) -{ - return ImmGetOpenStatus(himc); +// static +BOOL LLWinImm::getOpenStatus(HIMC himc) +{ + return ImmGetOpenStatus(himc); } -// static -BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) -{ - return ImmSetOpenStatus(himc, status); +// static +BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) +{ + return ImmSetOpenStatus(himc, status); } -// static -BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) -{ - return ImmGetConversionStatus(himc, conversion, sentence); +// static +BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) +{ + return ImmGetConversionStatus(himc, conversion, sentence); } -// static -BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) -{ - return ImmSetConversionStatus(himc, conversion, sentence); +// static +BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) +{ + return ImmSetConversionStatus(himc, conversion, sentence); } -// static -BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) -{ - return ImmGetCompositionWindow(himc, form); +// static +BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) +{ + return ImmGetCompositionWindow(himc, form); } -// static -BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) -{ - return ImmSetCompositionWindow(himc, form); +// static +BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) +{ + return ImmSetCompositionWindow(himc, form); } -// static -LONG LLWinImm::getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length) -{ - return ImmGetCompositionString(himc, index, data, length); +// static +LONG LLWinImm::getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length) +{ + return ImmGetCompositionString(himc, index, data, length); } -// static -BOOL LLWinImm::setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength) -{ - return ImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength); +// static +BOOL LLWinImm::setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength) +{ + return ImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength); } -// static -BOOL LLWinImm::setCompositionFont(HIMC himc, LPLOGFONTW pFont) -{ - return ImmSetCompositionFont(himc, pFont); +// static +BOOL LLWinImm::setCompositionFont(HIMC himc, LPLOGFONTW pFont) +{ + return ImmSetCompositionFont(himc, pFont); } -// static -BOOL LLWinImm::setCandidateWindow(HIMC himc, LPCANDIDATEFORM form) -{ - return ImmSetCandidateWindow(himc, form); +// static +BOOL LLWinImm::setCandidateWindow(HIMC himc, LPCANDIDATEFORM form) +{ + return ImmSetCandidateWindow(himc, form); } -// static -BOOL LLWinImm::notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value) -{ - return ImmNotifyIME(himc, action, index, value); +// static +BOOL LLWinImm::notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value) +{ + return ImmNotifyIME(himc, action, index, value); } @@ -308,31 +308,31 @@ class LLMonitorInfo { public: - std::vector<std::string> getResolutionsList() { return mResList; } + std::vector<std::string> getResolutionsList() { return mResList; } - LLMonitorInfo() - { - EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); - } + LLMonitorInfo() + { + EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); + } private: - static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData) - { - int monitor_width = lprcMonitor->right - lprcMonitor->left; - int monitor_height = lprcMonitor->bottom - lprcMonitor->top; - - std::ostringstream sstream; - sstream << monitor_width << "x" << monitor_height;; - std::string res = sstream.str(); + static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData) + { + int monitor_width = lprcMonitor->right - lprcMonitor->left; + int monitor_height = lprcMonitor->bottom - lprcMonitor->top; + + std::ostringstream sstream; + sstream << monitor_width << "x" << monitor_height;; + std::string res = sstream.str(); - LLMonitorInfo* pThis = reinterpret_cast<LLMonitorInfo*>(pData); - pThis->mResList.push_back(res); + LLMonitorInfo* pThis = reinterpret_cast<LLMonitorInfo*>(pData); + pThis->mResList.push_back(res); - return TRUE; - } + return TRUE; + } - std::vector<std::string> mResList; + std::vector<std::string> mResList; }; static LLMonitorInfo sMonitorInfo; @@ -363,7 +363,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool // initialzie DXGI adapter (for querying available VRAM) void initDX(); - + // initialize D3D (if DXGI cannot be used) void initD3D(); @@ -437,28 +437,28 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, - 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, + 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, U32 max_cores, U32 max_vram, F32 max_gl_version) - : - LLWindow(callbacks, fullscreen, flags), - mMaxGLVersion(max_gl_version), + : + LLWindow(callbacks, fullscreen, flags), + mMaxGLVersion(max_gl_version), mMaxCores(max_cores) { sMainThreadId = LLThread::currentID(); mWindowThread = new LLWindowWin32Thread(); mWindowThread->mMaxVRAM = max_vram; - //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways - LoadLibrary(L"opengl32.dll"); - - + //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways + LoadLibrary(L"opengl32.dll"); + + if (mMaxCores != 0) { HANDLE hProcess = GetCurrentProcess(); @@ -530,76 +530,76 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, #endif - mFSAASamples = fsaa_samples; - mIconResource = gIconResource; - mOverrideAspectRatio = 0.f; - mNativeAspectRatio = 0.f; - mInputProcessingPaused = FALSE; - mPreeditor = NULL; - mKeyCharCode = 0; - mKeyScanCode = 0; - mKeyVirtualKey = 0; - mhDC = NULL; - mhRC = NULL; - memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp)); - memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp)); - mCustomGammaSet = FALSE; - mWindowHandle = NULL; + mFSAASamples = fsaa_samples; + mIconResource = gIconResource; + mOverrideAspectRatio = 0.f; + mNativeAspectRatio = 0.f; + mInputProcessingPaused = FALSE; + mPreeditor = NULL; + mKeyCharCode = 0; + mKeyScanCode = 0; + mKeyVirtualKey = 0; + mhDC = NULL; + mhRC = NULL; + memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp)); + memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp)); + mCustomGammaSet = FALSE; + mWindowHandle = NULL; mRect = {0, 0, 0, 0}; mClientRect = {0, 0, 0, 0}; - - if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0)) - { - mMouseVanish = TRUE; - } - - // Initialize the keyboard - gKeyboard = new LLKeyboardWin32(); - gKeyboard->setCallbacks(callbacks); - - // Initialize the Drag and Drop functionality - mDragDrop = new LLDragDropWin32; - - // Initialize (boot strap) the Language text input management, - // based on the system's (user's) default settings. - allowLanguageTextInput(mPreeditor, FALSE); - - WNDCLASS wc; - RECT window_rect; - - // Set the window title - if (title.empty()) - { - mWindowTitle = new WCHAR[50]; - wsprintf(mWindowTitle, L"OpenGL Window"); - } - else - { - mWindowTitle = new WCHAR[256]; // Assume title length < 255 chars. - mbstowcs(mWindowTitle, title.c_str(), 255); - mWindowTitle[255] = 0; - } - - // Set the window class name - if (name.empty()) - { - mWindowClassName = new WCHAR[50]; - wsprintf(mWindowClassName, L"OpenGL Window"); - } - else - { - mWindowClassName = new WCHAR[256]; // Assume title length < 255 chars. - mbstowcs(mWindowClassName, name.c_str(), 255); - mWindowClassName[255] = 0; - } - - - // We're not clipping yet - SetRect( &mOldMouseClip, 0, 0, 0, 0 ); - - // Make an instance of our window then define the window class - mhInstance = GetModuleHandle(NULL); + + if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0)) + { + mMouseVanish = TRUE; + } + + // Initialize the keyboard + gKeyboard = new LLKeyboardWin32(); + gKeyboard->setCallbacks(callbacks); + + // Initialize the Drag and Drop functionality + mDragDrop = new LLDragDropWin32; + + // Initialize (boot strap) the Language text input management, + // based on the system's (user's) default settings. + allowLanguageTextInput(mPreeditor, FALSE); + + WNDCLASS wc; + RECT window_rect; + + // Set the window title + if (title.empty()) + { + mWindowTitle = new WCHAR[50]; + wsprintf(mWindowTitle, L"OpenGL Window"); + } + else + { + mWindowTitle = new WCHAR[256]; // Assume title length < 255 chars. + mbstowcs(mWindowTitle, title.c_str(), 255); + mWindowTitle[255] = 0; + } + + // Set the window class name + if (name.empty()) + { + mWindowClassName = new WCHAR[50]; + wsprintf(mWindowClassName, L"OpenGL Window"); + } + else + { + mWindowClassName = new WCHAR[256]; // Assume title length < 255 chars. + mbstowcs(mWindowClassName, name.c_str(), 255); + mWindowClassName[255] = 0; + } + + + // We're not clipping yet + SetRect( &mOldMouseClip, 0, 0, 0, 0 ); + + // Make an instance of our window then define the window class + mhInstance = GetModuleHandle(NULL); // Init Direct Input - needed for joystick / Spacemouse @@ -616,199 +616,199 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, gDirectInput8 = di8_interface; } - mSwapMethod = SWAP_METHOD_UNDEFINED; - - // No WPARAM yet. - mLastSizeWParam = 0; - - // Windows GDI rects don't include rightmost pixel - window_rect.left = (long) 0; - window_rect.right = (long) width; - window_rect.top = (long) 0; - window_rect.bottom = (long) height; - - // Grab screen size to sanitize the window - S32 window_border_y = GetSystemMetrics(SM_CYBORDER); - S32 virtual_screen_x = GetSystemMetrics(SM_XVIRTUALSCREEN); - S32 virtual_screen_y = GetSystemMetrics(SM_YVIRTUALSCREEN); - S32 virtual_screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN); - S32 virtual_screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN); - - if (x < virtual_screen_x) x = virtual_screen_x; - if (y < virtual_screen_y - window_border_y) y = virtual_screen_y - window_border_y; - - if (x + width > virtual_screen_x + virtual_screen_width) x = virtual_screen_x + virtual_screen_width - width; - if (y + height > virtual_screen_y + virtual_screen_height) y = virtual_screen_y + virtual_screen_height - height; - - if (!sIsClassRegistered) - { - // Force redraw when resized and create a private device context - - // Makes double click messages. - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; - - // Set message handler function - wc.lpfnWndProc = (WNDPROC) mainWindowProc; - - // unused - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - - wc.hInstance = mhInstance; - wc.hIcon = LoadIcon(mhInstance, mIconResource); - - // We will set the cursor ourselves - wc.hCursor = NULL; - - // background color is not used - if (clearBg) - { - wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - } - else - { - wc.hbrBackground = (HBRUSH) NULL; - } - - // we don't use windows menus - wc.lpszMenuName = NULL; - - wc.lpszClassName = mWindowClassName; - - if (!RegisterClass(&wc)) - { - OSMessageBox(mCallbacks->translateString("MBRegClassFailed"), - mCallbacks->translateString("MBError"), OSMB_OK); - return; - } - sIsClassRegistered = TRUE; - } - - //----------------------------------------------------------------------- - // Get the current refresh rate - //----------------------------------------------------------------------- - - DEVMODE dev_mode; - ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); - dev_mode.dmSize = sizeof(DEVMODE); - DWORD current_refresh; - if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) - { - current_refresh = dev_mode.dmDisplayFrequency; - mNativeAspectRatio = ((F32)dev_mode.dmPelsWidth) / ((F32)dev_mode.dmPelsHeight); - } - else - { - current_refresh = 60; - } + mSwapMethod = SWAP_METHOD_UNDEFINED; + + // No WPARAM yet. + mLastSizeWParam = 0; + + // Windows GDI rects don't include rightmost pixel + window_rect.left = (long) 0; + window_rect.right = (long) width; + window_rect.top = (long) 0; + window_rect.bottom = (long) height; + + // Grab screen size to sanitize the window + S32 window_border_y = GetSystemMetrics(SM_CYBORDER); + S32 virtual_screen_x = GetSystemMetrics(SM_XVIRTUALSCREEN); + S32 virtual_screen_y = GetSystemMetrics(SM_YVIRTUALSCREEN); + S32 virtual_screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN); + S32 virtual_screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN); + + if (x < virtual_screen_x) x = virtual_screen_x; + if (y < virtual_screen_y - window_border_y) y = virtual_screen_y - window_border_y; + + if (x + width > virtual_screen_x + virtual_screen_width) x = virtual_screen_x + virtual_screen_width - width; + if (y + height > virtual_screen_y + virtual_screen_height) y = virtual_screen_y + virtual_screen_height - height; + + if (!sIsClassRegistered) + { + // Force redraw when resized and create a private device context + + // Makes double click messages. + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; + + // Set message handler function + wc.lpfnWndProc = (WNDPROC) mainWindowProc; + + // unused + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + + wc.hInstance = mhInstance; + wc.hIcon = LoadIcon(mhInstance, mIconResource); + + // We will set the cursor ourselves + wc.hCursor = NULL; + + // background color is not used + if (clearBg) + { + wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + } + else + { + wc.hbrBackground = (HBRUSH) NULL; + } + + // we don't use windows menus + wc.lpszMenuName = NULL; + + wc.lpszClassName = mWindowClassName; + + if (!RegisterClass(&wc)) + { + OSMessageBox(mCallbacks->translateString("MBRegClassFailed"), + mCallbacks->translateString("MBError"), OSMB_OK); + return; + } + sIsClassRegistered = TRUE; + } + + //----------------------------------------------------------------------- + // Get the current refresh rate + //----------------------------------------------------------------------- + + DEVMODE dev_mode; + ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); + dev_mode.dmSize = sizeof(DEVMODE); + DWORD current_refresh; + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) + { + current_refresh = dev_mode.dmDisplayFrequency; + mNativeAspectRatio = ((F32)dev_mode.dmPelsWidth) / ((F32)dev_mode.dmPelsHeight); + } + else + { + current_refresh = 60; + } mRefreshRate = current_refresh; - //----------------------------------------------------------------------- - // Drop resolution and go fullscreen - // use a display mode with our desired size and depth, with a refresh - // rate as close at possible to the users' default - //----------------------------------------------------------------------- - if (mFullscreen) - { - BOOL success = FALSE; - DWORD closest_refresh = 0; - - for (S32 mode_num = 0;; mode_num++) - { - if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) - { - break; - } - - if (dev_mode.dmPelsWidth == width && - dev_mode.dmPelsHeight == height && - dev_mode.dmBitsPerPel == BITS_PER_PIXEL) - { - success = TRUE; - if ((dev_mode.dmDisplayFrequency - current_refresh) - < (closest_refresh - current_refresh)) - { - closest_refresh = dev_mode.dmDisplayFrequency; - } - } - } - - if (closest_refresh == 0) - { - LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; - //success = FALSE; - - if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) - { - success = FALSE; - } - else - { - if (dev_mode.dmBitsPerPel == BITS_PER_PIXEL) - { - LL_WARNS("Window") << "Current BBP is OK falling back to that" << LL_ENDL; - window_rect.right=width=dev_mode.dmPelsWidth; - window_rect.bottom=height=dev_mode.dmPelsHeight; - success = TRUE; - } - else - { - LL_WARNS("Window") << "Current BBP is BAD" << LL_ENDL; - success = FALSE; - } - } - } - - // If we found a good resolution, use it. - if (success) - { - success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); - } - - // Keep a copy of the actual current device mode in case we minimize - // and change the screen resolution. JC - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); - - // If it failed, we don't want to run fullscreen - if (success) - { - mFullscreen = TRUE; - mFullscreenWidth = dev_mode.dmPelsWidth; - mFullscreenHeight = dev_mode.dmPelsHeight; - mFullscreenBits = dev_mode.dmBitsPerPel; - mFullscreenRefresh = dev_mode.dmDisplayFrequency; - - LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth - << "x" << dev_mode.dmPelsHeight - << "x" << dev_mode.dmBitsPerPel - << " @ " << dev_mode.dmDisplayFrequency - << LL_ENDL; - } - else - { - mFullscreen = FALSE; - mFullscreenWidth = -1; - mFullscreenHeight = -1; - mFullscreenBits = -1; - mFullscreenRefresh = -1; - - std::map<std::string,std::string> args; - args["[WIDTH]"] = llformat("%d", width); - args["[HEIGHT]"] = llformat ("%d", height); - OSMessageBox(mCallbacks->translateString("MBFullScreenErr", args), - mCallbacks->translateString("MBError"), OSMB_OK); - } - } - - // TODO: add this after resolving _WIN32_WINNT issue - // if (!fullscreen) - // { - // TRACKMOUSEEVENT track_mouse_event; - // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); - // track_mouse_event.dwFlags = TME_LEAVE; - // track_mouse_event.hwndTrack = mWindowHandle; - // track_mouse_event.dwHoverTime = HOVER_DEFAULT; - // TrackMouseEvent( &track_mouse_event ); - // } + //----------------------------------------------------------------------- + // Drop resolution and go fullscreen + // use a display mode with our desired size and depth, with a refresh + // rate as close at possible to the users' default + //----------------------------------------------------------------------- + if (mFullscreen) + { + BOOL success = FALSE; + DWORD closest_refresh = 0; + + for (S32 mode_num = 0;; mode_num++) + { + if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) + { + break; + } + + if (dev_mode.dmPelsWidth == width && + dev_mode.dmPelsHeight == height && + dev_mode.dmBitsPerPel == BITS_PER_PIXEL) + { + success = TRUE; + if ((dev_mode.dmDisplayFrequency - current_refresh) + < (closest_refresh - current_refresh)) + { + closest_refresh = dev_mode.dmDisplayFrequency; + } + } + } + + if (closest_refresh == 0) + { + LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; + //success = FALSE; + + if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) + { + success = FALSE; + } + else + { + if (dev_mode.dmBitsPerPel == BITS_PER_PIXEL) + { + LL_WARNS("Window") << "Current BBP is OK falling back to that" << LL_ENDL; + window_rect.right=width=dev_mode.dmPelsWidth; + window_rect.bottom=height=dev_mode.dmPelsHeight; + success = TRUE; + } + else + { + LL_WARNS("Window") << "Current BBP is BAD" << LL_ENDL; + success = FALSE; + } + } + } + + // If we found a good resolution, use it. + if (success) + { + success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); + } + + // Keep a copy of the actual current device mode in case we minimize + // and change the screen resolution. JC + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); + + // If it failed, we don't want to run fullscreen + if (success) + { + mFullscreen = TRUE; + mFullscreenWidth = dev_mode.dmPelsWidth; + mFullscreenHeight = dev_mode.dmPelsHeight; + mFullscreenBits = dev_mode.dmBitsPerPel; + mFullscreenRefresh = dev_mode.dmDisplayFrequency; + + LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth + << "x" << dev_mode.dmPelsHeight + << "x" << dev_mode.dmBitsPerPel + << " @ " << dev_mode.dmDisplayFrequency + << LL_ENDL; + } + else + { + mFullscreen = FALSE; + mFullscreenWidth = -1; + mFullscreenHeight = -1; + mFullscreenBits = -1; + mFullscreenRefresh = -1; + + std::map<std::string,std::string> args; + args["[WIDTH]"] = llformat("%d", width); + args["[HEIGHT]"] = llformat ("%d", height); + OSMessageBox(mCallbacks->translateString("MBFullScreenErr", args), + mCallbacks->translateString("MBError"), OSMB_OK); + } + } + + // TODO: add this after resolving _WIN32_WINNT issue + // if (!fullscreen) + // { + // TRACKMOUSEEVENT track_mouse_event; + // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); + // track_mouse_event.dwFlags = TME_LEAVE; + // track_mouse_event.hwndTrack = mWindowHandle; + // track_mouse_event.dwHoverTime = HOVER_DEFAULT; + // TrackMouseEvent( &track_mouse_event ); + // } // SL-12971 dual GPU display DISPLAY_DEVICEA display_device; @@ -842,20 +842,20 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, LL_INFOS("Window") << "Total Display Devices: " << display_index << LL_ENDL; - //----------------------------------------------------------------------- - // Create GL drawing context - //----------------------------------------------------------------------- - LLCoordScreen windowPos(x,y); - LLCoordScreen windowSize(window_rect.right - window_rect.left, - window_rect.bottom - window_rect.top); - if (!switchContext(mFullscreen, windowSize, enable_vsync, &windowPos)) - { - return; - } - - //start with arrow cursor - initCursors(); - setCursor( UI_CURSOR_ARROW ); + //----------------------------------------------------------------------- + // Create GL drawing context + //----------------------------------------------------------------------- + LLCoordScreen windowPos(x,y); + LLCoordScreen windowSize(window_rect.right - window_rect.left, + window_rect.bottom - window_rect.top); + if (!switchContext(mFullscreen, windowSize, enable_vsync, &windowPos)) + { + return; + } + + //start with arrow cursor + initCursors(); + setCursor( UI_CURSOR_ARROW ); mRawMouse.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC mRawMouse.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE @@ -864,56 +864,56 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, RegisterRawInputDevices(&mRawMouse, 1, sizeof(mRawMouse)); - // Initialize (boot strap) the Language text input management, - // based on the system's (or user's) default settings. - allowLanguageTextInput(NULL, FALSE); + // Initialize (boot strap) the Language text input management, + // based on the system's (or user's) default settings. + allowLanguageTextInput(NULL, FALSE); } LLWindowWin32::~LLWindowWin32() { - delete mDragDrop; + delete mDragDrop; + + delete [] mWindowTitle; + mWindowTitle = NULL; - delete [] mWindowTitle; - mWindowTitle = NULL; + delete [] mSupportedResolutions; + mSupportedResolutions = NULL; - delete [] mSupportedResolutions; - mSupportedResolutions = NULL; + delete [] mWindowClassName; + mWindowClassName = NULL; - delete [] mWindowClassName; - mWindowClassName = NULL; - delete mWindowThread; } void LLWindowWin32::show() { LL_DEBUGS("Window") << "Setting window to show" << LL_ENDL; - ShowWindow(mWindowHandle, SW_SHOW); - SetForegroundWindow(mWindowHandle); - SetFocus(mWindowHandle); + ShowWindow(mWindowHandle, SW_SHOW); + SetForegroundWindow(mWindowHandle); + SetFocus(mWindowHandle); } void LLWindowWin32::hide() { - setMouseClipping(FALSE); - ShowWindow(mWindowHandle, SW_HIDE); + setMouseClipping(FALSE); + ShowWindow(mWindowHandle, SW_HIDE); } //virtual void LLWindowWin32::minimize() { - setMouseClipping(FALSE); - showCursor(); - ShowWindow(mWindowHandle, SW_MINIMIZE); + setMouseClipping(FALSE); + showCursor(); + ShowWindow(mWindowHandle, SW_MINIMIZE); } //virtual void LLWindowWin32::restore() { - ShowWindow(mWindowHandle, SW_RESTORE); - SetForegroundWindow(mWindowHandle); - SetFocus(mWindowHandle); + ShowWindow(mWindowHandle, SW_RESTORE); + SetForegroundWindow(mWindowHandle); + SetFocus(mWindowHandle); } // See SL-12170 @@ -942,88 +942,88 @@ bool destroy_window_handler(HWND hWnd) // Usually called from LLWindowManager::destroyWindow() void LLWindowWin32::close() { - LL_DEBUGS("Window") << "Closing LLWindowWin32" << LL_ENDL; - // Is window is already closed? - if (!mWindowHandle) - { - return; - } - - mDragDrop->reset(); - - - // Go back to screen mode written in the registry. - if (mFullscreen) - { - resetDisplayResolution(); - } - - // Make sure cursor is visible and we haven't mangled the clipping state. - showCursor(); - setMouseClipping(FALSE); - if (gKeyboard) - { - gKeyboard->resetKeys(); - } - - // Clean up remaining GL state - if (gGLManager.mInited) - { - LL_INFOS("Window") << "Cleaning up GL" << LL_ENDL; - gGLManager.shutdownGL(); - } - - LL_DEBUGS("Window") << "Releasing Context" << LL_ENDL; - if (mhRC) - { - if (!wglMakeCurrent(NULL, NULL)) - { - LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL; - } - - if (!wglDeleteContext(mhRC)) - { - LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL; - } - - mhRC = NULL; - } - - // Restore gamma to the system values. - restoreGamma(); - - LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; + LL_DEBUGS("Window") << "Closing LLWindowWin32" << LL_ENDL; + // Is window is already closed? + if (!mWindowHandle) + { + return; + } + + mDragDrop->reset(); + + + // Go back to screen mode written in the registry. + if (mFullscreen) + { + resetDisplayResolution(); + } + + // Make sure cursor is visible and we haven't mangled the clipping state. + showCursor(); + setMouseClipping(FALSE); + if (gKeyboard) + { + gKeyboard->resetKeys(); + } + + // Clean up remaining GL state + if (gGLManager.mInited) + { + LL_INFOS("Window") << "Cleaning up GL" << LL_ENDL; + gGLManager.shutdownGL(); + } + + LL_DEBUGS("Window") << "Releasing Context" << LL_ENDL; + if (mhRC) + { + if (!wglMakeCurrent(NULL, NULL)) + { + LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL; + } + + if (!wglDeleteContext(mhRC)) + { + LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL; + } + + mhRC = NULL; + } + + // Restore gamma to the system values. + restoreGamma(); + + LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; mhDC = NULL; mWindowHandle = NULL; - + mWindowThread->wakeAndDestroy(); } BOOL LLWindowWin32::isValid() { - return (mWindowHandle != NULL); + return (mWindowHandle != NULL); } BOOL LLWindowWin32::getVisible() { - return (mWindowHandle && IsWindowVisible(mWindowHandle)); + return (mWindowHandle && IsWindowVisible(mWindowHandle)); } BOOL LLWindowWin32::getMinimized() { - return (mWindowHandle && IsIconic(mWindowHandle)); + return (mWindowHandle && IsIconic(mWindowHandle)); } BOOL LLWindowWin32::getMaximized() { - return (mWindowHandle && IsZoomed(mWindowHandle)); + return (mWindowHandle && IsZoomed(mWindowHandle)); } BOOL LLWindowWin32::maximize() { - BOOL success = FALSE; - if (!mWindowHandle) return success; + BOOL success = FALSE; + if (!mWindowHandle) return success; mWindowThread->post([=] { @@ -1042,52 +1042,52 @@ BOOL LLWindowWin32::maximize() BOOL LLWindowWin32::getFullscreen() { - return mFullscreen; + return mFullscreen; } BOOL LLWindowWin32::getPosition(LLCoordScreen *position) { position->mX = mRect.left; - position->mY = mRect.top; - return TRUE; + position->mY = mRect.top; + return TRUE; } BOOL LLWindowWin32::getSize(LLCoordScreen *size) { - size->mX = mRect.right - mRect.left; - size->mY = mRect.bottom - mRect.top; - return TRUE; + size->mX = mRect.right - mRect.left; + size->mY = mRect.bottom - mRect.top; + return TRUE; } BOOL LLWindowWin32::getSize(LLCoordWindow *size) { - size->mX = mClientRect.right - mClientRect.left; - size->mY = mClientRect.bottom - mClientRect.top; - return TRUE; + size->mX = mClientRect.right - mClientRect.left; + size->mY = mClientRect.bottom - mClientRect.top; + return TRUE; } BOOL LLWindowWin32::setPosition(const LLCoordScreen position) { - LLCoordScreen size; + LLCoordScreen size; - if (!mWindowHandle) - { - return FALSE; - } - getSize(&size); - moveWindow(position, size); - return TRUE; + if (!mWindowHandle) + { + return FALSE; + } + getSize(&size); + moveWindow(position, size); + return TRUE; } BOOL LLWindowWin32::setSizeImpl(const LLCoordScreen size) { - LLCoordScreen position; + LLCoordScreen position; - getPosition(&position); - if (!mWindowHandle) - { - return FALSE; - } + getPosition(&position); + if (!mWindowHandle) + { + return FALSE; + } mWindowThread->post([=]() { @@ -1101,33 +1101,33 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordScreen size) } }); - moveWindow(position, size); - return TRUE; + moveWindow(position, size); + return TRUE; } BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) { - RECT window_rect = {0, 0, size.mX, size.mY }; - DWORD dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; - DWORD dw_style = WS_OVERLAPPEDWINDOW; + RECT window_rect = {0, 0, size.mX, size.mY }; + DWORD dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + DWORD dw_style = WS_OVERLAPPEDWINDOW; AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); - return setSizeImpl(LLCoordScreen(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top)); + return setSizeImpl(LLCoordScreen(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top)); } // changing fullscreen resolution BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BOOL enable_vsync, const LLCoordScreen* const posp) { //called from main thread - GLuint pixel_format; + GLuint pixel_format; DEVMODE dev_mode; ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); dev_mode.dmSize = sizeof(DEVMODE); - DWORD current_refresh; - DWORD dw_ex_style; - DWORD dw_style; - RECT window_rect = { 0, 0, 0, 0 }; + DWORD current_refresh; + DWORD dw_ex_style; + DWORD dw_style; + RECT window_rect = { 0, 0, 0, 0 }; S32 width = size.mX; S32 height = size.mY; BOOL auto_show = FALSE; @@ -1203,7 +1203,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); } - // Keep a copy of the actual current device mode in case we minimize + // Keep a copy of the actual current device mode in case we minimize // and change the screen resolution. JC EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); @@ -1222,7 +1222,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO << LL_ENDL; window_rect.left = (long)0; - window_rect.right = (long)width; // Windows GDI rects don't include rightmost pixel + window_rect.right = (long)width; // Windows GDI rects don't include rightmost pixel window_rect.top = (long)0; window_rect.bottom = (long)height; dw_ex_style = WS_EX_APPWINDOW; @@ -1249,7 +1249,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO { mFullscreen = FALSE; window_rect.left = (long)(posp ? posp->mX : 0); - window_rect.right = (long)width + window_rect.left; // Windows GDI rects don't include rightmost pixel + window_rect.right = (long)width + window_rect.left; // Windows GDI rects don't include rightmost pixel window_rect.top = (long)(posp ? posp->mY : 0); window_rect.bottom = (long)height + window_rect.top; // Window with an edge @@ -1270,318 +1270,318 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO << " Fullscreen: " << mFullscreen << LL_ENDL; - recreateWindow(window_rect, dw_ex_style, dw_style); - - if (mWindowHandle) - { - LL_INFOS("Window") << "window is created." << LL_ENDL ; - } - else - { - LL_WARNS("Window") << "Window creation failed, code: " << GetLastError() << LL_ENDL; - } - - //----------------------------------------------------------------------- - // Create GL drawing context - //----------------------------------------------------------------------- - static PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - BITS_PER_PIXEL, - 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused - 8, // alpha bits - 0, // alpha shift - 0, // accum bits - 0, 0, 0, 0, // accum RGBA - 24, // depth bits - 8, // stencil bits, avi added for stencil test - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - if (!mhDC) - { - close(); - OSMessageBox(mCallbacks->translateString("MBDevContextErr"), - mCallbacks->translateString("MBError"), OSMB_OK); - return FALSE; - } - - LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; + recreateWindow(window_rect, dw_ex_style, dw_style); + + if (mWindowHandle) + { + LL_INFOS("Window") << "window is created." << LL_ENDL ; + } + else + { + LL_WARNS("Window") << "Window creation failed, code: " << GetLastError() << LL_ENDL; + } + + //----------------------------------------------------------------------- + // Create GL drawing context + //----------------------------------------------------------------------- + static PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + BITS_PER_PIXEL, + 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused + 8, // alpha bits + 0, // alpha shift + 0, // accum bits + 0, 0, 0, 0, // accum RGBA + 24, // depth bits + 8, // stencil bits, avi added for stencil test + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + if (!mhDC) + { + close(); + OSMessageBox(mCallbacks->translateString("MBDevContextErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + return FALSE; + } + + LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; try { // Looks like ChoosePixelFormat can crash in case of faulty driver if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd))) - { + { LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), mCallbacks->translateString("MBError"), OSMB_OK); - close(); + close(); return FALSE; } } catch (...) { LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); - OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } + return FALSE; + } - LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; + LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; - // Verify what pixel format we actually received. - if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + // Verify what pixel format we actually received. + if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), + &pfd)) + { + OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), + mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } - - // (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash - LL_INFOS("Window") << "--- begin pixel format dump ---" << LL_ENDL ; - LL_INFOS("Window") << "pixel_format is " << pixel_format << LL_ENDL ; - LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << LL_ENDL ; - LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << LL_ENDL ; - LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << LL_ENDL ; - LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << LL_ENDL ; - LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << LL_ENDL ; - LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << LL_ENDL ; - LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << LL_ENDL ; - LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << LL_ENDL ; - LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << LL_ENDL ; - LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << LL_ENDL ; - LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << LL_ENDL ; - LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << LL_ENDL ; - LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << LL_ENDL ; - LL_INFOS("Window") << "--- end pixel format dump ---" << LL_ENDL ; - - if (!SetPixelFormat(mhDC, pixel_format, &pfd)) - { - OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + return FALSE; + } + + // (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash + LL_INFOS("Window") << "--- begin pixel format dump ---" << LL_ENDL ; + LL_INFOS("Window") << "pixel_format is " << pixel_format << LL_ENDL ; + LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << LL_ENDL ; + LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << LL_ENDL ; + LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << LL_ENDL ; + LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << LL_ENDL ; + LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << LL_ENDL ; + LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << LL_ENDL ; + LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << LL_ENDL ; + LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << LL_ENDL ; + LL_INFOS("Window") << "--- end pixel format dump ---" << LL_ENDL ; + + if (!SetPixelFormat(mhDC, pixel_format, &pfd)) + { + OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), + mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } + return FALSE; + } - if (!(mhRC = SafeCreateContext(mhDC))) - { - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + if (!(mhRC = SafeCreateContext(mhDC))) + { + OSMessageBox(mCallbacks->translateString("MBGLContextErr"), + mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } - - if (!wglMakeCurrent(mhDC, mhRC)) - { - OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + return FALSE; + } + + if (!wglMakeCurrent(mhDC, mhRC)) + { + OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), + mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } - - LL_INFOS("Window") << "Drawing context is created." << LL_ENDL ; - - gGLManager.initWGL(); - - if (wglChoosePixelFormatARB) - { - // OK, at this point, use the ARB wglChoosePixelFormatsARB function to see if we - // can get exactly what we want. - GLint attrib_list[256]; - S32 cur_attrib = 0; - - attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB; - attrib_list[cur_attrib++] = 24; - - //attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB; //stencil buffer is deprecated (performance penalty) - //attrib_list[cur_attrib++] = 8; - - attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_ACCELERATION_ARB; - attrib_list[cur_attrib++] = WGL_FULL_ACCELERATION_ARB; - - attrib_list[cur_attrib++] = WGL_SUPPORT_OPENGL_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_DOUBLE_BUFFER_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB; - attrib_list[cur_attrib++] = 24; - - attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; - attrib_list[cur_attrib++] = 0; - - U32 end_attrib = 0; - if (mFSAASamples > 0) - { - end_attrib = cur_attrib; - attrib_list[cur_attrib++] = WGL_SAMPLE_BUFFERS_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_SAMPLES_ARB; - attrib_list[cur_attrib++] = mFSAASamples; - } - - // End the list - attrib_list[cur_attrib++] = 0; - - GLint pixel_formats[256]; - U32 num_formats = 0; - - // First we try and get a 32 bit depth pixel format - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - - while(!result && mFSAASamples > 0) - { - LL_WARNS() << "FSAASamples: " << mFSAASamples << " not supported." << LL_ENDL ; - - mFSAASamples /= 2 ; //try to decrease sample pixel number until to disable anti-aliasing - if(mFSAASamples < 2) - { - mFSAASamples = 0 ; - } - - if (mFSAASamples > 0) - { - attrib_list[end_attrib + 3] = mFSAASamples; - } - else - { - cur_attrib = end_attrib ; - end_attrib = 0 ; - attrib_list[cur_attrib++] = 0 ; //end - } - result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - - if(result) - { - LL_WARNS() << "Only support FSAASamples: " << mFSAASamples << LL_ENDL ; - } - } - - if (!result) - { - LL_WARNS() << "mFSAASamples: " << mFSAASamples << LL_ENDL ; - - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit"); - return FALSE; - } - - if (!num_formats) - { - if (end_attrib > 0) - { - LL_INFOS("Window") << "No valid pixel format for " << mFSAASamples << "x anti-aliasing." << LL_ENDL; - attrib_list[end_attrib] = 0; - - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result) - { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit no AA"); - return FALSE; - } - } - - if (!num_formats) - { - LL_INFOS("Window") << "No 32 bit z-buffer, trying 24 bits instead" << LL_ENDL; - // Try 24-bit format - attrib_list[1] = 24; - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result) - { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit"); - return FALSE; - } - - if (!num_formats) - { - LL_WARNS("Window") << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << LL_ENDL; - attrib_list[1] = 16; - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result || !num_formats) - { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit"); - return FALSE; - } - } - } - - LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL; - } - - LL_INFOS("Window") << "pixel formats done." << LL_ENDL ; - - S32 swap_method = 0; - S32 cur_format = 0; -const S32 max_format = (S32)num_formats - 1; - GLint swap_query = WGL_SWAP_METHOD_ARB; - - // SL-14705 Fix name tags showing in front of objects with AMD GPUs. - // On AMD hardware we need to iterate from the first pixel format to the end. - // Spec: - // https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt - while (wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method)) - { - if (swap_method == WGL_SWAP_UNDEFINED_ARB) - { - break; - } - else if (cur_format >= max_format) - { - cur_format = 0; - break; - } - - ++cur_format; - } - - pixel_format = pixel_formats[cur_format]; - - if (mhDC != 0) // Does The Window Have A Device Context? - { - wglMakeCurrent(mhDC, 0); // Set The Current Active Rendering Context To Zero - if (mhRC != 0) // Does The Window Have A Rendering Context? - { - wglDeleteContext (mhRC); // Release The Rendering Context - mhRC = 0; // Zero The Rendering Context - } - } + return FALSE; + } + + LL_INFOS("Window") << "Drawing context is created." << LL_ENDL ; + + gGLManager.initWGL(); + + if (wglChoosePixelFormatARB) + { + // OK, at this point, use the ARB wglChoosePixelFormatsARB function to see if we + // can get exactly what we want. + GLint attrib_list[256]; + S32 cur_attrib = 0; + + attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB; + attrib_list[cur_attrib++] = 24; + + //attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB; //stencil buffer is deprecated (performance penalty) + //attrib_list[cur_attrib++] = 8; + + attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB; + attrib_list[cur_attrib++] = GL_TRUE; + + attrib_list[cur_attrib++] = WGL_ACCELERATION_ARB; + attrib_list[cur_attrib++] = WGL_FULL_ACCELERATION_ARB; + + attrib_list[cur_attrib++] = WGL_SUPPORT_OPENGL_ARB; + attrib_list[cur_attrib++] = GL_TRUE; + + attrib_list[cur_attrib++] = WGL_DOUBLE_BUFFER_ARB; + attrib_list[cur_attrib++] = GL_TRUE; + + attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB; + attrib_list[cur_attrib++] = 24; + + attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; + attrib_list[cur_attrib++] = 0; + + U32 end_attrib = 0; + if (mFSAASamples > 0) + { + end_attrib = cur_attrib; + attrib_list[cur_attrib++] = WGL_SAMPLE_BUFFERS_ARB; + attrib_list[cur_attrib++] = GL_TRUE; + + attrib_list[cur_attrib++] = WGL_SAMPLES_ARB; + attrib_list[cur_attrib++] = mFSAASamples; + } + + // End the list + attrib_list[cur_attrib++] = 0; + + GLint pixel_formats[256]; + U32 num_formats = 0; + + // First we try and get a 32 bit depth pixel format + BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + + while(!result && mFSAASamples > 0) + { + LL_WARNS() << "FSAASamples: " << mFSAASamples << " not supported." << LL_ENDL ; + + mFSAASamples /= 2 ; //try to decrease sample pixel number until to disable anti-aliasing + if(mFSAASamples < 2) + { + mFSAASamples = 0 ; + } + + if (mFSAASamples > 0) + { + attrib_list[end_attrib + 3] = mFSAASamples; + } + else + { + cur_attrib = end_attrib ; + end_attrib = 0 ; + attrib_list[cur_attrib++] = 0 ; //end + } + result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + + if(result) + { + LL_WARNS() << "Only support FSAASamples: " << mFSAASamples << LL_ENDL ; + } + } + + if (!result) + { + LL_WARNS() << "mFSAASamples: " << mFSAASamples << LL_ENDL ; + + close(); + show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit"); + return FALSE; + } + + if (!num_formats) + { + if (end_attrib > 0) + { + LL_INFOS("Window") << "No valid pixel format for " << mFSAASamples << "x anti-aliasing." << LL_ENDL; + attrib_list[end_attrib] = 0; + + BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + if (!result) + { + close(); + show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit no AA"); + return FALSE; + } + } + + if (!num_formats) + { + LL_INFOS("Window") << "No 32 bit z-buffer, trying 24 bits instead" << LL_ENDL; + // Try 24-bit format + attrib_list[1] = 24; + BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + if (!result) + { + close(); + show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit"); + return FALSE; + } + + if (!num_formats) + { + LL_WARNS("Window") << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << LL_ENDL; + attrib_list[1] = 16; + BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + if (!result || !num_formats) + { + close(); + show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit"); + return FALSE; + } + } + } + + LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL; + } + + LL_INFOS("Window") << "pixel formats done." << LL_ENDL ; + + S32 swap_method = 0; + S32 cur_format = 0; +const S32 max_format = (S32)num_formats - 1; + GLint swap_query = WGL_SWAP_METHOD_ARB; + + // SL-14705 Fix name tags showing in front of objects with AMD GPUs. + // On AMD hardware we need to iterate from the first pixel format to the end. + // Spec: + // https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt + while (wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method)) + { + if (swap_method == WGL_SWAP_UNDEFINED_ARB) + { + break; + } + else if (cur_format >= max_format) + { + cur_format = 0; + break; + } + + ++cur_format; + } + + pixel_format = pixel_formats[cur_format]; + + if (mhDC != 0) // Does The Window Have A Device Context? + { + wglMakeCurrent(mhDC, 0); // Set The Current Active Rendering Context To Zero + if (mhRC != 0) // Does The Window Have A Rendering Context? + { + wglDeleteContext (mhRC); // Release The Rendering Context + mhRC = 0; // Zero The Rendering Context + } + } // will release and recreate mhDC, mWindowHandle - recreateWindow(window_rect, dw_ex_style, dw_style); - + recreateWindow(window_rect, dw_ex_style, dw_style); + RECT rect; RECT client_rect; //initialize immediately on main thread @@ -1592,112 +1592,114 @@ const S32 max_format = (S32)num_formats - 1; mClientRect = client_rect; }; - if (mWindowHandle) - { - LL_INFOS("Window") << "recreate window done." << LL_ENDL ; - } - else - { - // Note: if value is NULL GetDC retrieves the DC for the entire screen. - LL_WARNS("Window") << "Window recreation failed, code: " << GetLastError() << LL_ENDL; - } - - if (!mhDC) - { - OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); - close(); - return FALSE; - } - - if (!SetPixelFormat(mhDC, pixel_format, &pfd)) - { - OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), - mCallbacks->translateString("MBError"), OSMB_OK); - close(); - return FALSE; - } - - if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method)) - { - switch (swap_method) - { - case WGL_SWAP_EXCHANGE_ARB: - mSwapMethod = SWAP_METHOD_EXCHANGE; - LL_DEBUGS("Window") << "Swap Method: Exchange" << LL_ENDL; - break; - case WGL_SWAP_COPY_ARB: - mSwapMethod = SWAP_METHOD_COPY; - LL_DEBUGS("Window") << "Swap Method: Copy" << LL_ENDL; - break; - case WGL_SWAP_UNDEFINED_ARB: - mSwapMethod = SWAP_METHOD_UNDEFINED; - LL_DEBUGS("Window") << "Swap Method: Undefined" << LL_ENDL; - break; - default: - mSwapMethod = SWAP_METHOD_UNDEFINED; - LL_DEBUGS("Window") << "Swap Method: Unknown" << LL_ENDL; - break; - } - } - } - else - { - LL_WARNS("Window") << "No wgl_ARB_pixel_format extension, using default ChoosePixelFormat!" << LL_ENDL; - } - - // Verify what pixel format we actually received. - if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); - close(); - return FALSE; - } - - LL_INFOS("Window") << "GL buffer: Color Bits " << S32(pfd.cColorBits) - << " Alpha Bits " << S32(pfd.cAlphaBits) - << " Depth Bits " << S32(pfd.cDepthBits) - << LL_ENDL; - - mhRC = 0; - if (wglCreateContextAttribsARB) - { //attempt to create a specific versioned context + if (mWindowHandle) + { + LL_INFOS("Window") << "recreate window done." << LL_ENDL ; + } + else + { + // Note: if value is NULL GetDC retrieves the DC for the entire screen. + LL_WARNS("Window") << "Window recreation failed, code: " << GetLastError() << LL_ENDL; + } + + if (!mhDC) + { + OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } + + if (!SetPixelFormat(mhDC, pixel_format, &pfd)) + { + OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } + + if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method)) + { + switch (swap_method) + { + case WGL_SWAP_EXCHANGE_ARB: + mSwapMethod = SWAP_METHOD_EXCHANGE; + LL_DEBUGS("Window") << "Swap Method: Exchange" << LL_ENDL; + break; + case WGL_SWAP_COPY_ARB: + mSwapMethod = SWAP_METHOD_COPY; + LL_DEBUGS("Window") << "Swap Method: Copy" << LL_ENDL; + break; + case WGL_SWAP_UNDEFINED_ARB: + mSwapMethod = SWAP_METHOD_UNDEFINED; + LL_DEBUGS("Window") << "Swap Method: Undefined" << LL_ENDL; + break; + default: + mSwapMethod = SWAP_METHOD_UNDEFINED; + LL_DEBUGS("Window") << "Swap Method: Unknown" << LL_ENDL; + break; + } + } + } + else + { + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr")); + // mWindowHandle is 0, going to crash either way + LL_ERRS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL; + } + + // Verify what pixel format we actually received. + if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), + &pfd)) + { + OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } + + LL_INFOS("Window") << "GL buffer: Color Bits " << S32(pfd.cColorBits) + << " Alpha Bits " << S32(pfd.cAlphaBits) + << " Depth Bits " << S32(pfd.cDepthBits) + << LL_ENDL; + + mhRC = 0; + if (wglCreateContextAttribsARB) + { //attempt to create a specific versioned context mhRC = (HGLRC) createSharedContext(); if (!mhRC) { return FALSE; } - } + } - if (!wglMakeCurrent(mhDC, mhRC)) - { - OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); + if (!wglMakeCurrent(mhDC, mhRC)) + { + OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } + return FALSE; + } - if (!gGLManager.initGL()) - { - OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); + if (!gGLManager.initGL()) + { + OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); close(); - return FALSE; - } - - // Disable vertical sync for swap + return FALSE; + } + + // Disable vertical sync for swap toggleVSync(enable_vsync); - SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); + SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); - // register this window as handling drag/drop events from the OS - DragAcceptFiles( mWindowHandle, TRUE ); + // register this window as handling drag/drop events from the OS + DragAcceptFiles( mWindowHandle, TRUE ); - mDragDrop->init( mWindowHandle ); - - //register joystick timer callback - SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer + mDragDrop->init( mWindowHandle ); - // ok to post quit messages now - mPostQuit = TRUE; + //register joystick timer callback + SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer + + // ok to post quit messages now + mPostQuit = TRUE; // *HACK: Attempt to prevent startup crashes by deferring memory accounting // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18 @@ -1706,17 +1708,17 @@ const S32 max_format = (S32)num_formats - 1; mWindowThread->glReady(); }); - if (auto_show) - { - show(); - glClearColor(0.0f, 0.0f, 0.0f, 0.f); - glClear(GL_COLOR_BUFFER_BIT); - swapBuffers(); - } + if (auto_show) + { + show(); + glClearColor(0.0f, 0.0f, 0.0f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + swapBuffers(); + } LL_PROFILER_GPU_CONTEXT; - return TRUE; + return TRUE; } void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style) @@ -1771,10 +1773,10 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw windowClassName, windowTitle, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, - window_rect.left, // x pos - window_rect.top, // y pos - window_rect.right - window_rect.left, // width - window_rect.bottom - window_rect.top, // height + window_rect.left, // x pos + window_rect.top, // y pos + window_rect.right - window_rect.left, // width + window_rect.bottom - window_rect.top, // height NULL, NULL, hInstance, @@ -1793,7 +1795,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw self->mWindowHandleThrd = handle; self->mhDCThrd = GetDC(handle); } - + updateWindowRect(); // It's important to wake up the future either way. @@ -1895,12 +1897,16 @@ void LLWindowWin32::destroySharedContext(void* contextPtr) void LLWindowWin32::toggleVSync(bool enable_vsync) { - if (!enable_vsync && wglSwapIntervalEXT) + if (wglSwapIntervalEXT == nullptr) + { + LL_INFOS("Window") << "VSync: wglSwapIntervalEXT not initialized" << LL_ENDL; + } + else if (!enable_vsync) { LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; wglSwapIntervalEXT(0); } - else if (wglSwapIntervalEXT) + else { LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL; wglSwapIntervalEXT(1); @@ -1909,22 +1915,22 @@ void LLWindowWin32::toggleVSync(bool enable_vsync) void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScreen& size ) { - if( mIsMouseClipping ) - { - RECT client_rect_in_screen_space; - if( getClientRectInScreenSpace( &client_rect_in_screen_space ) ) - { - ClipCursor( &client_rect_in_screen_space ); - } - } - - // if the window was already maximized, MoveWindow seems to still set the maximized flag even if - // the window is smaller than maximized. - // So we're going to do a restore first (which is a ShowWindow call) (SL-44655). - - // THIS CAUSES DEV-15484 and DEV-15949 - //ShowWindow(mWindowHandle, SW_RESTORE); - // NOW we can call MoveWindow + if( mIsMouseClipping ) + { + RECT client_rect_in_screen_space; + if( getClientRectInScreenSpace( &client_rect_in_screen_space ) ) + { + ClipCursor( &client_rect_in_screen_space ); + } + } + + // if the window was already maximized, MoveWindow seems to still set the maximized flag even if + // the window is smaller than maximized. + // So we're going to do a restore first (which is a ShowWindow call) (SL-44655). + + // THIS CAUSES DEV-15484 and DEV-15949 + //ShowWindow(mWindowHandle, SW_RESTORE); + // NOW we can call MoveWindow mWindowThread->post([=]() { MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE); @@ -1979,7 +1985,7 @@ BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position) } *position = mCursorPosition; - return TRUE; + return TRUE; } BOOL LLWindowWin32::getCursorDelta(LLCoordCommon* delta) @@ -2006,8 +2012,8 @@ void LLWindowWin32::hideCursor() } }); - mCursorHidden = TRUE; - mHideCursorPermanent = TRUE; + mCursorHidden = TRUE; + mHideCursorPermanent = TRUE; } void LLWindowWin32::showCursor() @@ -2015,7 +2021,7 @@ void LLWindowWin32::showCursor() LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; ASSERT_MAIN_THREAD(); - + mWindowThread->post([=]() { // makes sure the cursor shows up @@ -2025,103 +2031,103 @@ void LLWindowWin32::showCursor() } }); - mCursorHidden = FALSE; - mHideCursorPermanent = FALSE; + mCursorHidden = FALSE; + mHideCursorPermanent = FALSE; } void LLWindowWin32::showCursorFromMouseMove() { - if (!mHideCursorPermanent) - { - showCursor(); - } + if (!mHideCursorPermanent) + { + showCursor(); + } } void LLWindowWin32::hideCursorUntilMouseMove() { - if (!mHideCursorPermanent && mMouseVanish) - { - hideCursor(); - mHideCursorPermanent = FALSE; - } + if (!mHideCursorPermanent && mMouseVanish) + { + hideCursor(); + mHideCursorPermanent = FALSE; + } } BOOL LLWindowWin32::isCursorHidden() { - return mCursorHidden; + return mCursorHidden; } HCURSOR LLWindowWin32::loadColorCursor(LPCTSTR name) { - return (HCURSOR)LoadImage(mhInstance, - name, - IMAGE_CURSOR, - 0, // default width - 0, // default height - LR_DEFAULTCOLOR); + return (HCURSOR)LoadImage(mhInstance, + name, + IMAGE_CURSOR, + 0, // default width + 0, // default height + LR_DEFAULTCOLOR); } void LLWindowWin32::initCursors() { - mCursor[ UI_CURSOR_ARROW ] = LoadCursor(NULL, IDC_ARROW); - mCursor[ UI_CURSOR_WAIT ] = LoadCursor(NULL, IDC_WAIT); - mCursor[ UI_CURSOR_HAND ] = LoadCursor(NULL, IDC_HAND); - mCursor[ UI_CURSOR_IBEAM ] = LoadCursor(NULL, IDC_IBEAM); - mCursor[ UI_CURSOR_CROSS ] = LoadCursor(NULL, IDC_CROSS); - mCursor[ UI_CURSOR_SIZENWSE ] = LoadCursor(NULL, IDC_SIZENWSE); - mCursor[ UI_CURSOR_SIZENESW ] = LoadCursor(NULL, IDC_SIZENESW); - mCursor[ UI_CURSOR_SIZEWE ] = LoadCursor(NULL, IDC_SIZEWE); - mCursor[ UI_CURSOR_SIZENS ] = LoadCursor(NULL, IDC_SIZENS); - mCursor[ UI_CURSOR_SIZEALL ] = LoadCursor(NULL, IDC_SIZEALL); - mCursor[ UI_CURSOR_NO ] = LoadCursor(NULL, IDC_NO); - mCursor[ UI_CURSOR_WORKING ] = LoadCursor(NULL, IDC_APPSTARTING); - - HMODULE module = GetModuleHandle(NULL); - mCursor[ UI_CURSOR_TOOLGRAB ] = LoadCursor(module, TEXT("TOOLGRAB")); - mCursor[ UI_CURSOR_TOOLLAND ] = LoadCursor(module, TEXT("TOOLLAND")); - mCursor[ UI_CURSOR_TOOLFOCUS ] = LoadCursor(module, TEXT("TOOLFOCUS")); - mCursor[ UI_CURSOR_TOOLCREATE ] = LoadCursor(module, TEXT("TOOLCREATE")); - mCursor[ UI_CURSOR_ARROWDRAG ] = LoadCursor(module, TEXT("ARROWDRAG")); - mCursor[ UI_CURSOR_ARROWCOPY ] = LoadCursor(module, TEXT("ARROWCOPY")); - mCursor[ UI_CURSOR_ARROWDRAGMULTI ] = LoadCursor(module, TEXT("ARROWDRAGMULTI")); - mCursor[ UI_CURSOR_ARROWCOPYMULTI ] = LoadCursor(module, TEXT("ARROWCOPYMULTI")); - mCursor[ UI_CURSOR_NOLOCKED ] = LoadCursor(module, TEXT("NOLOCKED")); - mCursor[ UI_CURSOR_ARROWLOCKED ]= LoadCursor(module, TEXT("ARROWLOCKED")); - mCursor[ UI_CURSOR_GRABLOCKED ] = LoadCursor(module, TEXT("GRABLOCKED")); - mCursor[ UI_CURSOR_TOOLTRANSLATE ] = LoadCursor(module, TEXT("TOOLTRANSLATE")); - mCursor[ UI_CURSOR_TOOLROTATE ] = LoadCursor(module, TEXT("TOOLROTATE")); - mCursor[ UI_CURSOR_TOOLSCALE ] = LoadCursor(module, TEXT("TOOLSCALE")); - mCursor[ UI_CURSOR_TOOLCAMERA ] = LoadCursor(module, TEXT("TOOLCAMERA")); - mCursor[ UI_CURSOR_TOOLPAN ] = LoadCursor(module, TEXT("TOOLPAN")); - mCursor[ UI_CURSOR_TOOLZOOMIN ] = LoadCursor(module, TEXT("TOOLZOOMIN")); - mCursor[ UI_CURSOR_TOOLZOOMOUT ] = LoadCursor(module, TEXT("TOOLZOOMOUT")); - mCursor[ UI_CURSOR_TOOLPICKOBJECT3 ] = LoadCursor(module, TEXT("TOOLPICKOBJECT3")); - mCursor[ UI_CURSOR_PIPETTE ] = LoadCursor(module, TEXT("TOOLPIPETTE")); - mCursor[ UI_CURSOR_TOOLSIT ] = LoadCursor(module, TEXT("TOOLSIT")); - mCursor[ UI_CURSOR_TOOLBUY ] = LoadCursor(module, TEXT("TOOLBUY")); - mCursor[ UI_CURSOR_TOOLOPEN ] = LoadCursor(module, TEXT("TOOLOPEN")); - mCursor[ UI_CURSOR_TOOLPATHFINDING ] = LoadCursor(module, TEXT("TOOLPATHFINDING")); - mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTARTADD")); - mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTART")); - mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHEND")); - mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHENDADD")); - mCursor[ UI_CURSOR_TOOLNO ] = LoadCursor(module, TEXT("TOOLNO")); - - // Color cursors - mCursor[ UI_CURSOR_TOOLPLAY ] = loadColorCursor(TEXT("TOOLPLAY")); - mCursor[ UI_CURSOR_TOOLPAUSE ] = loadColorCursor(TEXT("TOOLPAUSE")); - mCursor[ UI_CURSOR_TOOLMEDIAOPEN ] = loadColorCursor(TEXT("TOOLMEDIAOPEN")); - - // Note: custom cursors that are not found make LoadCursor() return NULL. - for( S32 i = 0; i < UI_CURSOR_COUNT; i++ ) - { - if( !mCursor[i] ) - { - mCursor[i] = LoadCursor(NULL, IDC_ARROW); - } - } + mCursor[ UI_CURSOR_ARROW ] = LoadCursor(NULL, IDC_ARROW); + mCursor[ UI_CURSOR_WAIT ] = LoadCursor(NULL, IDC_WAIT); + mCursor[ UI_CURSOR_HAND ] = LoadCursor(NULL, IDC_HAND); + mCursor[ UI_CURSOR_IBEAM ] = LoadCursor(NULL, IDC_IBEAM); + mCursor[ UI_CURSOR_CROSS ] = LoadCursor(NULL, IDC_CROSS); + mCursor[ UI_CURSOR_SIZENWSE ] = LoadCursor(NULL, IDC_SIZENWSE); + mCursor[ UI_CURSOR_SIZENESW ] = LoadCursor(NULL, IDC_SIZENESW); + mCursor[ UI_CURSOR_SIZEWE ] = LoadCursor(NULL, IDC_SIZEWE); + mCursor[ UI_CURSOR_SIZENS ] = LoadCursor(NULL, IDC_SIZENS); + mCursor[ UI_CURSOR_SIZEALL ] = LoadCursor(NULL, IDC_SIZEALL); + mCursor[ UI_CURSOR_NO ] = LoadCursor(NULL, IDC_NO); + mCursor[ UI_CURSOR_WORKING ] = LoadCursor(NULL, IDC_APPSTARTING); + + HMODULE module = GetModuleHandle(NULL); + mCursor[ UI_CURSOR_TOOLGRAB ] = LoadCursor(module, TEXT("TOOLGRAB")); + mCursor[ UI_CURSOR_TOOLLAND ] = LoadCursor(module, TEXT("TOOLLAND")); + mCursor[ UI_CURSOR_TOOLFOCUS ] = LoadCursor(module, TEXT("TOOLFOCUS")); + mCursor[ UI_CURSOR_TOOLCREATE ] = LoadCursor(module, TEXT("TOOLCREATE")); + mCursor[ UI_CURSOR_ARROWDRAG ] = LoadCursor(module, TEXT("ARROWDRAG")); + mCursor[ UI_CURSOR_ARROWCOPY ] = LoadCursor(module, TEXT("ARROWCOPY")); + mCursor[ UI_CURSOR_ARROWDRAGMULTI ] = LoadCursor(module, TEXT("ARROWDRAGMULTI")); + mCursor[ UI_CURSOR_ARROWCOPYMULTI ] = LoadCursor(module, TEXT("ARROWCOPYMULTI")); + mCursor[ UI_CURSOR_NOLOCKED ] = LoadCursor(module, TEXT("NOLOCKED")); + mCursor[ UI_CURSOR_ARROWLOCKED ]= LoadCursor(module, TEXT("ARROWLOCKED")); + mCursor[ UI_CURSOR_GRABLOCKED ] = LoadCursor(module, TEXT("GRABLOCKED")); + mCursor[ UI_CURSOR_TOOLTRANSLATE ] = LoadCursor(module, TEXT("TOOLTRANSLATE")); + mCursor[ UI_CURSOR_TOOLROTATE ] = LoadCursor(module, TEXT("TOOLROTATE")); + mCursor[ UI_CURSOR_TOOLSCALE ] = LoadCursor(module, TEXT("TOOLSCALE")); + mCursor[ UI_CURSOR_TOOLCAMERA ] = LoadCursor(module, TEXT("TOOLCAMERA")); + mCursor[ UI_CURSOR_TOOLPAN ] = LoadCursor(module, TEXT("TOOLPAN")); + mCursor[ UI_CURSOR_TOOLZOOMIN ] = LoadCursor(module, TEXT("TOOLZOOMIN")); + mCursor[ UI_CURSOR_TOOLZOOMOUT ] = LoadCursor(module, TEXT("TOOLZOOMOUT")); + mCursor[ UI_CURSOR_TOOLPICKOBJECT3 ] = LoadCursor(module, TEXT("TOOLPICKOBJECT3")); + mCursor[ UI_CURSOR_PIPETTE ] = LoadCursor(module, TEXT("TOOLPIPETTE")); + mCursor[ UI_CURSOR_TOOLSIT ] = LoadCursor(module, TEXT("TOOLSIT")); + mCursor[ UI_CURSOR_TOOLBUY ] = LoadCursor(module, TEXT("TOOLBUY")); + mCursor[ UI_CURSOR_TOOLOPEN ] = LoadCursor(module, TEXT("TOOLOPEN")); + mCursor[ UI_CURSOR_TOOLPATHFINDING ] = LoadCursor(module, TEXT("TOOLPATHFINDING")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTARTADD")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTART")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHEND")); + mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHENDADD")); + mCursor[ UI_CURSOR_TOOLNO ] = LoadCursor(module, TEXT("TOOLNO")); + + // Color cursors + mCursor[ UI_CURSOR_TOOLPLAY ] = loadColorCursor(TEXT("TOOLPLAY")); + mCursor[ UI_CURSOR_TOOLPAUSE ] = loadColorCursor(TEXT("TOOLPAUSE")); + mCursor[ UI_CURSOR_TOOLMEDIAOPEN ] = loadColorCursor(TEXT("TOOLMEDIAOPEN")); + + // Note: custom cursors that are not found make LoadCursor() return NULL. + for( S32 i = 0; i < UI_CURSOR_COUNT; i++ ) + { + if( !mCursor[i] ) + { + mCursor[i] = LoadCursor(NULL, IDC_ARROW); + } + } } @@ -2130,43 +2136,43 @@ void LLWindowWin32::updateCursor() { ASSERT_MAIN_THREAD(); LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32 - if (mNextCursor == UI_CURSOR_ARROW - && mBusyCount > 0) - { - mNextCursor = UI_CURSOR_WORKING; - } - - if( mCurrentCursor != mNextCursor ) - { - mCurrentCursor = mNextCursor; + if (mNextCursor == UI_CURSOR_ARROW + && mBusyCount > 0) + { + mNextCursor = UI_CURSOR_WORKING; + } + + if( mCurrentCursor != mNextCursor ) + { + mCurrentCursor = mNextCursor; auto nextCursor = mCursor[mNextCursor]; mWindowThread->post([=]() { SetCursor(nextCursor); }); - } + } } ECursorType LLWindowWin32::getCursor() const { - return mCurrentCursor; + return mCurrentCursor; } void LLWindowWin32::captureMouse() { - SetCapture(mWindowHandle); + SetCapture(mWindowHandle); } void LLWindowWin32::releaseMouse() { LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; - ReleaseCapture(); + ReleaseCapture(); } void LLWindowWin32::delayInputProcessing() { - mInputProcessingPaused = TRUE; + mInputProcessingPaused = TRUE; } @@ -2190,7 +2196,7 @@ void LLWindowWin32::gatherInput() LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - PostMessage"); kickWindowThread(); } - + while (mWindowThread->mMessageQueue.tryPopBack(msg)) { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - message queue"); @@ -2234,7 +2240,7 @@ void LLWindowWin32::gatherInput() LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - mouse move"); mCallbacks->handleMouseMove(this, mCursorPosition.convert(), mMouseMask); } - + mLastCursorPosition = mCursorPosition; { @@ -2247,9 +2253,9 @@ void LLWindowWin32::gatherInput() } } - mInputProcessingPaused = FALSE; + mInputProcessingPaused = FALSE; - updateCursor(); + updateCursor(); } static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard"); @@ -2296,9 +2302,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ switch (u_msg) { - RECT update_rect; - S32 update_width; - S32 update_height; + RECT update_rect; + S32 update_width; + S32 update_height; case WM_TIMER: { @@ -2313,7 +2319,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL) { WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp)); - + return TRUE; } break; @@ -2374,7 +2380,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ if (window_imp->mFullscreen) { - // When we run fullscreen, restoring or minimizing the app needs + // When we run fullscreen, restoring or minimizing the app needs // to switch the screen resolution if (activating) { @@ -2410,7 +2416,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ window_imp->interruptLanguageTextInput(); } }); - + break; } @@ -2488,7 +2494,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ gKeyboard->handleKeyDown(w_param, mask); }); - if (eat_keystroke) return 0; // skip DefWindowProc() handling if we're consuming the keypress + if (eat_keystroke) return 0; // skip DefWindowProc() handling if we're consuming the keypress break; } case WM_SYSKEYUP: @@ -2510,7 +2516,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ gKeyboard->handleKeyUp(w_param, mask); } }); - if (eat_keystroke) return 0; // skip DefWindowProc() handling if we're consuming the keypress + if (eat_keystroke) return 0; // skip DefWindowProc() handling if we're consuming the keypress break; } case WM_IME_SETCONTEXT: @@ -2583,7 +2589,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // it is worth trying. The good old WM_CHAR works just fine even for supplementary // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's // by ourselves. It is not that tough. -- Alissa Sabre @ SL - + // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE, // we *did* processed the event, so I believe we should not pass it to DefWindowProc... window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE)); @@ -2611,12 +2617,12 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ window_imp->postMouseButtonEvent([=]() { sHandleLeftMouseUp = true; - + if (LLWinImm::isAvailable() && window_imp->mPreeditor) { window_imp->interruptLanguageTextInput(); } - + MASK mask = gKeyboard->currentMask(TRUE); auto gl_coord = window_imp->mCursorPosition.convert(); window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); @@ -2663,7 +2669,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } sHandleDoubleClick = true; - + MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates window_imp->mCursorPosition = window_coord; @@ -2711,7 +2717,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ break; case WM_MBUTTONDOWN: - // case WM_MBUTTONDBLCLK: + // case WM_MBUTTONDBLCLK: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MBUTTONDOWN"); { @@ -2759,7 +2765,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 window_imp->mCallbacks->handleOtherMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); }); - + } break; @@ -2784,7 +2790,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEWHEEL"); static short z_delta = 0; - RECT client_rect; + RECT client_rect; // eat scroll events that occur outside our window, since we use mouse position to direct scroll // instead of keyboard focus @@ -2827,12 +2833,12 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { window_imp->mCallbacks->handleMouseLeave(window_imp); - // TRACKMOUSEEVENT track_mouse_event; - // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); - // track_mouse_event.dwFlags = TME_LEAVE; - // track_mouse_event.hwndTrack = h_wnd; - // track_mouse_event.dwHoverTime = HOVER_DEFAULT; - // TrackMouseEvent( &track_mouse_event ); + // TRACKMOUSEEVENT track_mouse_event; + // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); + // track_mouse_event.dwFlags = TME_LEAVE; + // track_mouse_event.hwndTrack = h_wnd; + // track_mouse_event.dwHoverTime = HOVER_DEFAULT; + // TrackMouseEvent( &track_mouse_event ); return 0; } */ @@ -2841,7 +2847,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEHWHEEL"); static short h_delta = 0; - RECT client_rect; + RECT client_rect; // eat scroll events that occur outside our window, since we use mouse position to direct scroll // instead of keyboard focus @@ -2876,7 +2882,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_MOUSEMOVE: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEMOVE"); - // DO NOT use mouse event queue for move events to ensure cursor position is updated + // DO NOT use mouse event queue for move events to ensure cursor position is updated // when button events are handled WINDOW_IMP_POST( { @@ -2908,12 +2914,12 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SIZE"); window_imp->updateWindowRect(); - // There's an odd behavior with WM_SIZE that I would call a bug. If + // There's an odd behavior with WM_SIZE that I would call a bug. If // the window is maximized, and you call MoveWindow() with a size smaller - // than a maximized window, it ends up sending WM_SIZE with w_param set + // than a maximized window, it ends up sending WM_SIZE with w_param set // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work. - // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see - // LLWindowWin32::moveWindow in this file). + // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see + // LLWindowWin32::moveWindow in this file). // If we are now restored, but we weren't before, this // means that the window was un-minimized. @@ -2957,7 +2963,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ S32 new_width = lprc_new_scale->right - lprc_new_scale->left; S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; WINDOW_IMP_POST(window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height)); - + SetWindowPos(h_wnd, HWND_TOP, lprc_new_scale->left, @@ -2965,7 +2971,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ new_width, new_height, SWP_NOZORDER | SWP_NOACTIVATE); - + return 0; } @@ -3015,17 +3021,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } } break; - + case WM_INPUT: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("MWP - WM_INPUT"); - + UINT dwSize = 0; GetRawInputData((HRAWINPUT)l_param, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); llassert(dwSize < 1024); U8 lpb[1024]; - + if (GetRawInputData((HRAWINPUT)l_param, RID_INPUT, (void*)lpb, &dwSize, sizeof(RAWINPUTHEADER)) == dwSize) { RAWINPUT* raw = (RAWINPUT*)lpb; @@ -3121,175 +3127,175 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordWindow *to) { - S32 client_height; - RECT client_rect; - LLCoordWindow window_position; + S32 client_height; + RECT client_rect; + LLCoordWindow window_position; - if (!mWindowHandle || - !GetClientRect(mWindowHandle, &client_rect) || - NULL == to) - { - return FALSE; - } + if (!mWindowHandle || + !GetClientRect(mWindowHandle, &client_rect) || + NULL == to) + { + return FALSE; + } - to->mX = from.mX; - client_height = client_rect.bottom - client_rect.top; - to->mY = client_height - from.mY - 1; + to->mX = from.mX; + client_height = client_rect.bottom - client_rect.top; + to->mY = client_height - from.mY - 1; - return TRUE; + return TRUE; } BOOL LLWindowWin32::convertCoords(LLCoordWindow from, LLCoordGL* to) { - S32 client_height; - RECT client_rect; + S32 client_height; + RECT client_rect; - if (!mWindowHandle || - !GetClientRect(mWindowHandle, &client_rect) || - NULL == to) - { - return FALSE; - } + if (!mWindowHandle || + !GetClientRect(mWindowHandle, &client_rect) || + NULL == to) + { + return FALSE; + } - to->mX = from.mX; - client_height = client_rect.bottom - client_rect.top; - to->mY = client_height - from.mY - 1; + to->mX = from.mX; + client_height = client_rect.bottom - client_rect.top; + to->mY = client_height - from.mY - 1; - return TRUE; + return TRUE; } BOOL LLWindowWin32::convertCoords(LLCoordScreen from, LLCoordWindow* to) -{ - POINT mouse_point; +{ + POINT mouse_point; - mouse_point.x = from.mX; - mouse_point.y = from.mY; - BOOL result = ScreenToClient(mWindowHandle, &mouse_point); + mouse_point.x = from.mX; + mouse_point.y = from.mY; + BOOL result = ScreenToClient(mWindowHandle, &mouse_point); - if (result) - { - to->mX = mouse_point.x; - to->mY = mouse_point.y; - } + if (result) + { + to->mX = mouse_point.x; + to->mY = mouse_point.y; + } - return result; + return result; } BOOL LLWindowWin32::convertCoords(LLCoordWindow from, LLCoordScreen *to) { - POINT mouse_point; + POINT mouse_point; - mouse_point.x = from.mX; - mouse_point.y = from.mY; - BOOL result = ClientToScreen(mWindowHandle, &mouse_point); + mouse_point.x = from.mX; + mouse_point.y = from.mY; + BOOL result = ClientToScreen(mWindowHandle, &mouse_point); - if (result) - { - to->mX = mouse_point.x; - to->mY = mouse_point.y; - } + if (result) + { + to->mX = mouse_point.x; + to->mY = mouse_point.y; + } - return result; + return result; } BOOL LLWindowWin32::convertCoords(LLCoordScreen from, LLCoordGL *to) { - LLCoordWindow window_coord; + LLCoordWindow window_coord; - if (!mWindowHandle || (NULL == to)) - { - return FALSE; - } + if (!mWindowHandle || (NULL == to)) + { + return FALSE; + } - convertCoords(from, &window_coord); - convertCoords(window_coord, to); - return TRUE; + convertCoords(from, &window_coord); + convertCoords(window_coord, to); + return TRUE; } BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordScreen *to) { - LLCoordWindow window_coord; + LLCoordWindow window_coord; - if (!mWindowHandle || (NULL == to)) - { - return FALSE; - } + if (!mWindowHandle || (NULL == to)) + { + return FALSE; + } - convertCoords(from, &window_coord); - convertCoords(window_coord, to); - return TRUE; + convertCoords(from, &window_coord); + convertCoords(window_coord, to); + return TRUE; } BOOL LLWindowWin32::isClipboardTextAvailable() { - return IsClipboardFormatAvailable(CF_UNICODETEXT); + return IsClipboardFormatAvailable(CF_UNICODETEXT); } BOOL LLWindowWin32::pasteTextFromClipboard(LLWString &dst) { - BOOL success = FALSE; + BOOL success = FALSE; - if (IsClipboardFormatAvailable(CF_UNICODETEXT)) - { - if (OpenClipboard(mWindowHandle)) - { - HGLOBAL h_data = GetClipboardData(CF_UNICODETEXT); - if (h_data) - { - WCHAR *utf16str = (WCHAR*) GlobalLock(h_data); - if (utf16str) - { - dst = utf16str_to_wstring(utf16str); - LLWStringUtil::removeWindowsCR(dst); - GlobalUnlock(h_data); - success = TRUE; - } - } - CloseClipboard(); - } - } + if (IsClipboardFormatAvailable(CF_UNICODETEXT)) + { + if (OpenClipboard(mWindowHandle)) + { + HGLOBAL h_data = GetClipboardData(CF_UNICODETEXT); + if (h_data) + { + WCHAR *utf16str = (WCHAR*) GlobalLock(h_data); + if (utf16str) + { + dst = utf16str_to_wstring(utf16str); + LLWStringUtil::removeWindowsCR(dst); + GlobalUnlock(h_data); + success = TRUE; + } + } + CloseClipboard(); + } + } - return success; + return success; } BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr) { - BOOL success = FALSE; + BOOL success = FALSE; - if (OpenClipboard(mWindowHandle)) - { - EmptyClipboard(); + if (OpenClipboard(mWindowHandle)) + { + EmptyClipboard(); - // Provide a copy of the data in Unicode format. - LLWString sanitized_string(wstr); - LLWStringUtil::addCRLF(sanitized_string); - llutf16string out_utf16 = wstring_to_utf16str(sanitized_string); - const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(WCHAR); + // Provide a copy of the data in Unicode format. + LLWString sanitized_string(wstr); + LLWStringUtil::addCRLF(sanitized_string); + llutf16string out_utf16 = wstring_to_utf16str(sanitized_string); + const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(WCHAR); - // Memory is allocated and then ownership of it is transfered to the system. - HGLOBAL hglobal_copy_utf16 = GlobalAlloc(GMEM_MOVEABLE, size_utf16); - if (hglobal_copy_utf16) - { - WCHAR* copy_utf16 = (WCHAR*) GlobalLock(hglobal_copy_utf16); - if (copy_utf16) - { - memcpy(copy_utf16, out_utf16.c_str(), size_utf16); /* Flawfinder: ignore */ - GlobalUnlock(hglobal_copy_utf16); + // Memory is allocated and then ownership of it is transfered to the system. + HGLOBAL hglobal_copy_utf16 = GlobalAlloc(GMEM_MOVEABLE, size_utf16); + if (hglobal_copy_utf16) + { + WCHAR* copy_utf16 = (WCHAR*) GlobalLock(hglobal_copy_utf16); + if (copy_utf16) + { + memcpy(copy_utf16, out_utf16.c_str(), size_utf16); /* Flawfinder: ignore */ + GlobalUnlock(hglobal_copy_utf16); - if (SetClipboardData(CF_UNICODETEXT, hglobal_copy_utf16)) - { - success = TRUE; - } - } - } + if (SetClipboardData(CF_UNICODETEXT, hglobal_copy_utf16)) + { + success = TRUE; + } + } + } - CloseClipboard(); - } + CloseClipboard(); + } - return success; + return success; } // Constrains the mouse to the window. @@ -3297,32 +3303,32 @@ void LLWindowWin32::setMouseClipping( BOOL b ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; ASSERT_MAIN_THREAD(); - if( b != mIsMouseClipping ) - { - BOOL success = FALSE; - - if( b ) - { - GetClipCursor( &mOldMouseClip ); - - RECT client_rect_in_screen_space; - if( getClientRectInScreenSpace( &client_rect_in_screen_space ) ) - { - success = ClipCursor( &client_rect_in_screen_space ); - } - } - else - { - // Must restore the old mouse clip, which may be set by another window. - success = ClipCursor( &mOldMouseClip ); - SetRect( &mOldMouseClip, 0, 0, 0, 0 ); - } - - if( success ) - { - mIsMouseClipping = b; - } - } + if( b != mIsMouseClipping ) + { + BOOL success = FALSE; + + if( b ) + { + GetClipCursor( &mOldMouseClip ); + + RECT client_rect_in_screen_space; + if( getClientRectInScreenSpace( &client_rect_in_screen_space ) ) + { + success = ClipCursor( &client_rect_in_screen_space ); + } + } + else + { + // Must restore the old mouse clip, which may be set by another window. + success = ClipCursor( &mOldMouseClip ); + SetRect( &mOldMouseClip, 0, 0, 0, 0 ); + } + + if( success ) + { + mIsMouseClipping = b; + } + } } BOOL LLWindowWin32::getClientRectInScreenSpace( RECT* rectp ) @@ -3371,29 +3377,29 @@ void LLWindowWin32::flashIcon(F32 seconds) F32 LLWindowWin32::getGamma() { - return mCurrentGamma; + return mCurrentGamma; } BOOL LLWindowWin32::restoreGamma() { ASSERT_MAIN_THREAD(); - if (mCustomGammaSet != FALSE) - { + if (mCustomGammaSet != FALSE) + { LL_DEBUGS("Window") << "Restoring gamma" << LL_ENDL; - mCustomGammaSet = FALSE; - return SetDeviceGammaRamp(mhDC, mPrevGammaRamp); - } - return TRUE; + mCustomGammaSet = FALSE; + return SetDeviceGammaRamp(mhDC, mPrevGammaRamp); + } + return TRUE; } BOOL LLWindowWin32::setGamma(const F32 gamma) { ASSERT_MAIN_THREAD(); - mCurrentGamma = gamma; + mCurrentGamma = gamma; - //Get the previous gamma ramp to restore later. - if (mCustomGammaSet == FALSE) - { + //Get the previous gamma ramp to restore later. + if (mCustomGammaSet == FALSE) + { if (!gGLManager.mIsIntel) // skip for Intel GPUs (see SL-11341) { LL_DEBUGS("Window") << "Getting the previous gamma ramp to restore later" << LL_ENDL; @@ -3403,192 +3409,192 @@ BOOL LLWindowWin32::setGamma(const F32 gamma) return FALSE; } } - mCustomGammaSet = TRUE; - } + mCustomGammaSet = TRUE; + } - LL_DEBUGS("Window") << "Setting gamma to " << gamma << LL_ENDL; + LL_DEBUGS("Window") << "Setting gamma to " << gamma << LL_ENDL; - for ( int i = 0; i < 256; ++i ) - { - int mult = 256 - ( int ) ( ( gamma - 1.0f ) * 128.0f ); + for ( int i = 0; i < 256; ++i ) + { + int mult = 256 - ( int ) ( ( gamma - 1.0f ) * 128.0f ); - int value = mult * i; + int value = mult * i; - if ( value > 0xffff ) - value = 0xffff; + if ( value > 0xffff ) + value = 0xffff; - mCurrentGammaRamp[0][i] = - mCurrentGammaRamp[1][i] = - mCurrentGammaRamp[2][i] = (WORD) value; - }; + mCurrentGammaRamp[0][i] = + mCurrentGammaRamp[1][i] = + mCurrentGammaRamp[2][i] = (WORD) value; + }; - return SetDeviceGammaRamp ( mhDC, mCurrentGammaRamp ); + return SetDeviceGammaRamp ( mhDC, mCurrentGammaRamp ); } void LLWindowWin32::setFSAASamples(const U32 fsaa_samples) { ASSERT_MAIN_THREAD(); - mFSAASamples = fsaa_samples; + mFSAASamples = fsaa_samples; } U32 LLWindowWin32::getFSAASamples() { - return mFSAASamples; + return mFSAASamples; } LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) { ASSERT_MAIN_THREAD(); - if (!mSupportedResolutions) - { - mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; - DEVMODE dev_mode; - ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); - dev_mode.dmSize = sizeof(DEVMODE); - - mNumSupportedResolutions = 0; - for (S32 mode_num = 0; mNumSupportedResolutions < MAX_NUM_RESOLUTIONS; mode_num++) - { - if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) - { - break; - } - - if (dev_mode.dmBitsPerPel == BITS_PER_PIXEL && - dev_mode.dmPelsWidth >= 800 && - dev_mode.dmPelsHeight >= 600) - { - BOOL resolution_exists = FALSE; - for(S32 i = 0; i < mNumSupportedResolutions; i++) - { - if (mSupportedResolutions[i].mWidth == dev_mode.dmPelsWidth && - mSupportedResolutions[i].mHeight == dev_mode.dmPelsHeight) - { - resolution_exists = TRUE; - } - } - if (!resolution_exists) - { - mSupportedResolutions[mNumSupportedResolutions].mWidth = dev_mode.dmPelsWidth; - mSupportedResolutions[mNumSupportedResolutions].mHeight = dev_mode.dmPelsHeight; - mNumSupportedResolutions++; - } - } - } - } - - num_resolutions = mNumSupportedResolutions; - return mSupportedResolutions; + if (!mSupportedResolutions) + { + mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; + DEVMODE dev_mode; + ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); + dev_mode.dmSize = sizeof(DEVMODE); + + mNumSupportedResolutions = 0; + for (S32 mode_num = 0; mNumSupportedResolutions < MAX_NUM_RESOLUTIONS; mode_num++) + { + if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) + { + break; + } + + if (dev_mode.dmBitsPerPel == BITS_PER_PIXEL && + dev_mode.dmPelsWidth >= 800 && + dev_mode.dmPelsHeight >= 600) + { + BOOL resolution_exists = FALSE; + for(S32 i = 0; i < mNumSupportedResolutions; i++) + { + if (mSupportedResolutions[i].mWidth == dev_mode.dmPelsWidth && + mSupportedResolutions[i].mHeight == dev_mode.dmPelsHeight) + { + resolution_exists = TRUE; + } + } + if (!resolution_exists) + { + mSupportedResolutions[mNumSupportedResolutions].mWidth = dev_mode.dmPelsWidth; + mSupportedResolutions[mNumSupportedResolutions].mHeight = dev_mode.dmPelsHeight; + mNumSupportedResolutions++; + } + } + } + } + + num_resolutions = mNumSupportedResolutions; + return mSupportedResolutions; } F32 LLWindowWin32::getNativeAspectRatio() { - if (mOverrideAspectRatio > 0.f) - { - return mOverrideAspectRatio; - } - else if (mNativeAspectRatio > 0.f) - { - // we grabbed this value at startup, based on the user's desktop settings - return mNativeAspectRatio; - } - // 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); + if (mOverrideAspectRatio > 0.f) + { + return mOverrideAspectRatio; + } + else if (mNativeAspectRatio > 0.f) + { + // we grabbed this value at startup, based on the user's desktop settings + return mNativeAspectRatio; + } + // 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); + return ((F32)resolutions[num_resolutions - 1].mWidth / (F32)resolutions[num_resolutions - 1].mHeight); } F32 LLWindowWin32::getPixelAspectRatio() { - F32 pixel_aspect = 1.f; - if (getFullscreen()) - { - LLCoordScreen screen_size; - getSize(&screen_size); - pixel_aspect = getNativeAspectRatio() * (F32)screen_size.mY / (F32)screen_size.mX; - } + F32 pixel_aspect = 1.f; + if (getFullscreen()) + { + LLCoordScreen screen_size; + getSize(&screen_size); + pixel_aspect = getNativeAspectRatio() * (F32)screen_size.mY / (F32)screen_size.mX; + } - return pixel_aspect; + return pixel_aspect; } // Change display resolution. Returns true if successful. // protected BOOL LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh) { - DEVMODE dev_mode; - ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); - dev_mode.dmSize = sizeof(DEVMODE); - BOOL success = FALSE; - - // Don't change anything if we don't have to - if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) - { - if (dev_mode.dmPelsWidth == width && - dev_mode.dmPelsHeight == height && - dev_mode.dmBitsPerPel == bits && - dev_mode.dmDisplayFrequency == refresh ) - { - // ...display mode identical, do nothing - return TRUE; - } - } - - memset(&dev_mode, 0, sizeof(dev_mode)); - dev_mode.dmSize = sizeof(dev_mode); - dev_mode.dmPelsWidth = width; - dev_mode.dmPelsHeight = height; - dev_mode.dmBitsPerPel = bits; - dev_mode.dmDisplayFrequency = refresh; - dev_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; - - // CDS_FULLSCREEN indicates that this is a temporary change to the device mode. - LONG cds_result = ChangeDisplaySettings(&dev_mode, CDS_FULLSCREEN); - - success = (DISP_CHANGE_SUCCESSFUL == cds_result); - - if (!success) - { - LL_WARNS("Window") << "setDisplayResolution failed, " - << width << "x" << height << "x" << bits << " @ " << refresh << LL_ENDL; - } - - return success; + DEVMODE dev_mode; + ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); + dev_mode.dmSize = sizeof(DEVMODE); + BOOL success = FALSE; + + // Don't change anything if we don't have to + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) + { + if (dev_mode.dmPelsWidth == width && + dev_mode.dmPelsHeight == height && + dev_mode.dmBitsPerPel == bits && + dev_mode.dmDisplayFrequency == refresh ) + { + // ...display mode identical, do nothing + return TRUE; + } + } + + memset(&dev_mode, 0, sizeof(dev_mode)); + dev_mode.dmSize = sizeof(dev_mode); + dev_mode.dmPelsWidth = width; + dev_mode.dmPelsHeight = height; + dev_mode.dmBitsPerPel = bits; + dev_mode.dmDisplayFrequency = refresh; + dev_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + + // CDS_FULLSCREEN indicates that this is a temporary change to the device mode. + LONG cds_result = ChangeDisplaySettings(&dev_mode, CDS_FULLSCREEN); + + success = (DISP_CHANGE_SUCCESSFUL == cds_result); + + if (!success) + { + LL_WARNS("Window") << "setDisplayResolution failed, " + << width << "x" << height << "x" << bits << " @ " << refresh << LL_ENDL; + } + + return success; } // protected BOOL LLWindowWin32::setFullscreenResolution() { - if (mFullscreen) - { - return setDisplayResolution( mFullscreenWidth, mFullscreenHeight, mFullscreenBits, mFullscreenRefresh); - } - else - { - return FALSE; - } + if (mFullscreen) + { + return setDisplayResolution( mFullscreenWidth, mFullscreenHeight, mFullscreenBits, mFullscreenRefresh); + } + else + { + return FALSE; + } } // protected BOOL LLWindowWin32::resetDisplayResolution() { - LL_DEBUGS("Window") << "resetDisplayResolution START" << LL_ENDL; + LL_DEBUGS("Window") << "resetDisplayResolution START" << LL_ENDL; - LONG cds_result = ChangeDisplaySettings(NULL, 0); + LONG cds_result = ChangeDisplaySettings(NULL, 0); - BOOL success = (DISP_CHANGE_SUCCESSFUL == cds_result); + BOOL success = (DISP_CHANGE_SUCCESSFUL == cds_result); - if (!success) - { - LL_WARNS("Window") << "resetDisplayResolution failed" << LL_ENDL; - } + if (!success) + { + LL_WARNS("Window") << "resetDisplayResolution failed" << LL_ENDL; + } - LL_DEBUGS("Window") << "resetDisplayResolution END" << LL_ENDL; + LL_DEBUGS("Window") << "resetDisplayResolution END" << LL_ENDL; - return success; + return success; } void LLWindowWin32::swapBuffers() @@ -3609,7 +3615,7 @@ void LLWindowWin32::swapBuffers() // LLSplashScreenImp // LLSplashScreenWin32::LLSplashScreenWin32() -: mWindow(NULL) +: mWindow(NULL) { } @@ -3619,14 +3625,14 @@ LLSplashScreenWin32::~LLSplashScreenWin32() void LLSplashScreenWin32::showImpl() { - // This appears to work. ??? - HINSTANCE hinst = GetModuleHandle(NULL); + // This appears to work. ??? + HINSTANCE hinst = GetModuleHandle(NULL); - mWindow = CreateDialog(hinst, - TEXT("SPLASHSCREEN"), - NULL, // no parent - (DLGPROC) LLSplashScreenWin32::windowProc); - ShowWindow(mWindow, SW_SHOW); + mWindow = CreateDialog(hinst, + TEXT("SPLASHSCREEN"), + NULL, // no parent + (DLGPROC) LLSplashScreenWin32::windowProc); + ShowWindow(mWindow, SW_SHOW); // Should set taskbar text without creating a header for the window (caption) SetWindowTextA(mWindow, "Second Life"); @@ -3635,46 +3641,46 @@ void LLSplashScreenWin32::showImpl() void LLSplashScreenWin32::updateImpl(const std::string& mesg) { - if (!mWindow) return; + if (!mWindow) return; - int output_str_len = MultiByteToWideChar(CP_UTF8, 0, mesg.c_str(), mesg.length(), NULL, 0); - if( output_str_len>1024 ) - return; + int output_str_len = MultiByteToWideChar(CP_UTF8, 0, mesg.c_str(), mesg.length(), NULL, 0); + if( output_str_len>1024 ) + return; - WCHAR w_mesg[1025];//big enought to keep null terminatos + WCHAR w_mesg[1025];//big enought to keep null terminatos - MultiByteToWideChar (CP_UTF8, 0, mesg.c_str(), mesg.length(), w_mesg, output_str_len); + MultiByteToWideChar (CP_UTF8, 0, mesg.c_str(), mesg.length(), w_mesg, output_str_len); - //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858 - w_mesg[output_str_len] = 0; + //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858 + w_mesg[output_str_len] = 0; - SendDlgItemMessage(mWindow, - 666, // HACK: text id - WM_SETTEXT, - FALSE, - (LPARAM)w_mesg); + SendDlgItemMessage(mWindow, + 666, // HACK: text id + WM_SETTEXT, + FALSE, + (LPARAM)w_mesg); } void LLSplashScreenWin32::hideImpl() { - if (mWindow) - { + if (mWindow) + { if (!destroy_window_handler(mWindow)) { LL_WARNS("Window") << "Failed to properly close splash screen window!" << LL_ENDL; } - mWindow = NULL; - } + mWindow = NULL; + } } // static LRESULT CALLBACK LLSplashScreenWin32::windowProc(HWND h_wnd, UINT u_msg, - WPARAM w_param, LPARAM l_param) + WPARAM w_param, LPARAM l_param) { - // Just give it to windows - return DefWindowProc(h_wnd, u_msg, w_param, l_param); + // Just give it to windows + return DefWindowProc(h_wnd, u_msg, w_param, l_param); } // @@ -3683,148 +3689,148 @@ LRESULT CALLBACK LLSplashScreenWin32::windowProc(HWND h_wnd, UINT u_msg, S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type) { - UINT uType; - - switch(type) - { - case OSMB_OK: - uType = MB_OK; - break; - case OSMB_OKCANCEL: - uType = MB_OKCANCEL; - break; - case OSMB_YESNO: - uType = MB_YESNO; - break; - default: - uType = MB_OK; - break; - } - - int retval_win = MessageBoxW(NULL, // HWND - ll_convert_string_to_wide(text).c_str(), - ll_convert_string_to_wide(caption).c_str(), - uType); - S32 retval; - - switch(retval_win) - { - case IDYES: - retval = OSBTN_YES; - break; - case IDNO: - retval = OSBTN_NO; - break; - case IDOK: - retval = OSBTN_OK; - break; - case IDCANCEL: - retval = OSBTN_CANCEL; - break; - default: - retval = OSBTN_CANCEL; - break; - } - - return retval; + UINT uType; + + switch(type) + { + case OSMB_OK: + uType = MB_OK; + break; + case OSMB_OKCANCEL: + uType = MB_OKCANCEL; + break; + case OSMB_YESNO: + uType = MB_YESNO; + break; + default: + uType = MB_OK; + break; + } + + int retval_win = MessageBoxW(NULL, // HWND + ll_convert_string_to_wide(text).c_str(), + ll_convert_string_to_wide(caption).c_str(), + uType); + S32 retval; + + switch(retval_win) + { + case IDYES: + retval = OSBTN_YES; + break; + case IDNO: + retval = OSBTN_NO; + break; + case IDOK: + retval = OSBTN_OK; + break; + case IDCANCEL: + retval = OSBTN_CANCEL; + break; + default: + retval = OSBTN_CANCEL; + break; + } + + return retval; } void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async) { - bool found = false; - S32 i; - for (i = 0; i < gURLProtocolWhitelistCount; i++) - { - if (escaped_url.find(gURLProtocolWhitelist[i]) == 0) - { - found = true; - break; - } - } - - if (!found) - { - LL_WARNS("Window") << "spawn_web_browser() called for url with protocol not on whitelist: " << escaped_url << LL_ENDL; - return; - } - - LL_INFOS("Window") << "Opening URL " << escaped_url << LL_ENDL; - - // replaced ShellExecute code with ShellExecuteEx since ShellExecute doesn't work - // reliablly on Vista. - - // this is madness.. no, this is.. - LLWString url_wstring = utf8str_to_wstring( escaped_url ); - llutf16string url_utf16 = wstring_to_utf16str( url_wstring ); - - // let the OS decide what to use to open the URL - SHELLEXECUTEINFO sei = { sizeof( sei ) }; - // NOTE: this assumes that SL will stick around long enough to complete the DDE message exchange - // necessary for ShellExecuteEx to complete - if (async) - { - sei.fMask = SEE_MASK_ASYNCOK; - } - sei.nShow = SW_SHOWNORMAL; - sei.lpVerb = L"open"; - sei.lpFile = url_utf16.c_str(); - ShellExecuteEx( &sei ); + bool found = false; + S32 i; + for (i = 0; i < gURLProtocolWhitelistCount; i++) + { + if (escaped_url.find(gURLProtocolWhitelist[i]) == 0) + { + found = true; + break; + } + } + + if (!found) + { + LL_WARNS("Window") << "spawn_web_browser() called for url with protocol not on whitelist: " << escaped_url << LL_ENDL; + return; + } + + LL_INFOS("Window") << "Opening URL " << escaped_url << LL_ENDL; + + // replaced ShellExecute code with ShellExecuteEx since ShellExecute doesn't work + // reliablly on Vista. + + // this is madness.. no, this is.. + LLWString url_wstring = utf8str_to_wstring( escaped_url ); + llutf16string url_utf16 = wstring_to_utf16str( url_wstring ); + + // let the OS decide what to use to open the URL + SHELLEXECUTEINFO sei = { sizeof( sei ) }; + // NOTE: this assumes that SL will stick around long enough to complete the DDE message exchange + // necessary for ShellExecuteEx to complete + if (async) + { + sei.fMask = SEE_MASK_ASYNCOK; + } + sei.nShow = SW_SHOWNORMAL; + sei.lpVerb = L"open"; + sei.lpFile = url_utf16.c_str(); + ShellExecuteEx( &sei ); } /* - 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 + 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 LLWindowWin32::getNativeKeyData() { - LLSD result = LLSD::emptyMap(); + LLSD result = LLSD::emptyMap(); - result["scan_code"] = (S32)mKeyScanCode; - result["virtual_key"] = (S32)mKeyVirtualKey; - result["msg"] = ll_sd_from_U32(mRawMsg); - result["w_param"] = ll_sd_from_U32(mRawWParam); - result["l_param"] = ll_sd_from_U32(mRawLParam); + result["scan_code"] = (S32)mKeyScanCode; + result["virtual_key"] = (S32)mKeyVirtualKey; + result["msg"] = ll_sd_from_U32(mRawMsg); + result["w_param"] = ll_sd_from_U32(mRawWParam); + result["l_param"] = ll_sd_from_U32(mRawLParam); - return result; + return result; } BOOL LLWindowWin32::dialogColorPicker( F32 *r, F32 *g, F32 *b ) { - BOOL retval = FALSE; - - static CHOOSECOLOR cc; - static COLORREF crCustColors[16]; - cc.lStructSize = sizeof(CHOOSECOLOR); - cc.hwndOwner = mWindowHandle; - cc.hInstance = NULL; - cc.rgbResult = RGB ((*r * 255.f),(*g *255.f),(*b * 255.f)); - //cc.rgbResult = RGB (0x80,0x80,0x80); - cc.lpCustColors = crCustColors; - cc.Flags = CC_RGBINIT | CC_FULLOPEN; - cc.lCustData = 0; - cc.lpfnHook = NULL; - cc.lpTemplateName = NULL; - - // This call is modal, so pause agent - //send_agent_pause(); // this is in newview and we don't want to set up a dependency - { - retval = ChooseColor(&cc); - } - //send_agent_resume(); // this is in newview and we don't want to set up a dependency - - *b = ((F32)((cc.rgbResult >> 16) & 0xff)) / 255.f; - - *g = ((F32)((cc.rgbResult >> 8) & 0xff)) / 255.f; - - *r = ((F32)(cc.rgbResult & 0xff)) / 255.f; - - return (retval); + BOOL retval = FALSE; + + static CHOOSECOLOR cc; + static COLORREF crCustColors[16]; + cc.lStructSize = sizeof(CHOOSECOLOR); + cc.hwndOwner = mWindowHandle; + cc.hInstance = NULL; + cc.rgbResult = RGB ((*r * 255.f),(*g *255.f),(*b * 255.f)); + //cc.rgbResult = RGB (0x80,0x80,0x80); + cc.lpCustColors = crCustColors; + cc.Flags = CC_RGBINIT | CC_FULLOPEN; + cc.lCustData = 0; + cc.lpfnHook = NULL; + cc.lpTemplateName = NULL; + + // This call is modal, so pause agent + //send_agent_pause(); // this is in newview and we don't want to set up a dependency + { + retval = ChooseColor(&cc); + } + //send_agent_resume(); // this is in newview and we don't want to set up a dependency + + *b = ((F32)((cc.rgbResult >> 16) & 0xff)) / 255.f; + + *g = ((F32)((cc.rgbResult >> 8) & 0xff)) / 255.f; + + *r = ((F32)(cc.rgbResult & 0xff)) / 255.f; + + return (retval); } void *LLWindowWin32::getPlatformWindow() { - return (void*)mWindowHandle; + return (void*)mWindowHandle; } void LLWindowWin32::bringToFront() @@ -3846,40 +3852,40 @@ void LLWindowWin32::focusClient() void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { - if (b == sLanguageTextInputAllowed || !LLWinImm::isAvailable()) - { - return; - } - - if (preeditor != mPreeditor && !b) - { - // This condition may occur with a call to - // setEnabled(BOOL) from LLTextEditor or LLLineEditor - // when the control is not focused. - // We need to silently ignore the case so that - // the language input status of the focused control - // is not disturbed. - return; - } - - // Take care of old and new preeditors. - if (preeditor != mPreeditor || !b) - { - if (sLanguageTextInputAllowed) - { - interruptLanguageTextInput(); - } - mPreeditor = (b ? preeditor : NULL); - } - - sLanguageTextInputAllowed = b; + if (b == sLanguageTextInputAllowed || !LLWinImm::isAvailable()) + { + return; + } + + if (preeditor != mPreeditor && !b) + { + // This condition may occur with a call to + // setEnabled(BOOL) from LLTextEditor or LLLineEditor + // when the control is not focused. + // We need to silently ignore the case so that + // the language input status of the focused control + // is not disturbed. + return; + } + + // Take care of old and new preeditors. + if (preeditor != mPreeditor || !b) + { + if (sLanguageTextInputAllowed) + { + interruptLanguageTextInput(); + } + mPreeditor = (b ? preeditor : NULL); + } + + sLanguageTextInputAllowed = b; if (sLanguageTextInputAllowed) { mWindowThread->post([=]() { - // Allowing: Restore the previous IME status, so that the user has a feeling that the previous - // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps + // Allowing: Restore the previous IME status, so that the user has a feeling that the previous + // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps // using same Input Locale (aka Keyboard Layout). if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) { @@ -3907,7 +3913,7 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); - // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's + // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's // keyboard hooking, because Some IME reacts only on the former and some other on the latter... LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); LLWinImm::setOpenStatus(himc, FALSE); @@ -3918,194 +3924,194 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) } } -void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, - CANDIDATEFORM *form) +void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, + CANDIDATEFORM *form) { - LLCoordWindow caret_coord, top_left, bottom_right; - convertCoords(caret, &caret_coord); - convertCoords(LLCoordGL(bounds.mLeft, bounds.mTop), &top_left); - convertCoords(LLCoordGL(bounds.mRight, bounds.mBottom), &bottom_right); + LLCoordWindow caret_coord, top_left, bottom_right; + convertCoords(caret, &caret_coord); + convertCoords(LLCoordGL(bounds.mLeft, bounds.mTop), &top_left); + convertCoords(LLCoordGL(bounds.mRight, bounds.mBottom), &bottom_right); - memset(form, 0, sizeof(CANDIDATEFORM)); - form->dwStyle = CFS_EXCLUDE; - form->ptCurrentPos.x = caret_coord.mX; - form->ptCurrentPos.y = caret_coord.mY; - form->rcArea.left = top_left.mX; - form->rcArea.top = top_left.mY; - form->rcArea.right = bottom_right.mX; - form->rcArea.bottom = bottom_right.mY; + memset(form, 0, sizeof(CANDIDATEFORM)); + form->dwStyle = CFS_EXCLUDE; + form->ptCurrentPos.x = caret_coord.mX; + form->ptCurrentPos.y = caret_coord.mY; + form->rcArea.left = top_left.mX; + form->rcArea.top = top_left.mY; + form->rcArea.right = bottom_right.mX; + form->rcArea.bottom = bottom_right.mY; } // Put the IME window at the right place (near current text input). Point coordinates should be the top of the current text line. void LLWindowWin32::setLanguageTextInput( const LLCoordGL & position ) { - if (sLanguageTextInputAllowed && LLWinImm::isAvailable()) - { - HIMC himc = LLWinImm::getContext(mWindowHandle); + if (sLanguageTextInputAllowed && LLWinImm::isAvailable()) + { + HIMC himc = LLWinImm::getContext(mWindowHandle); - LLCoordWindow win_pos; - convertCoords( position, &win_pos ); + LLCoordWindow win_pos; + convertCoords( position, &win_pos ); - if ( win_pos.mX >= 0 && win_pos.mY >= 0 && - (win_pos.mX != sWinIMEWindowPosition.mX) || (win_pos.mY != sWinIMEWindowPosition.mY) ) - { - COMPOSITIONFORM ime_form; - memset( &ime_form, 0, sizeof(ime_form) ); - ime_form.dwStyle = CFS_POINT; - ime_form.ptCurrentPos.x = win_pos.mX; - ime_form.ptCurrentPos.y = win_pos.mY; + if ( win_pos.mX >= 0 && win_pos.mY >= 0 && + (win_pos.mX != sWinIMEWindowPosition.mX) || (win_pos.mY != sWinIMEWindowPosition.mY) ) + { + COMPOSITIONFORM ime_form; + memset( &ime_form, 0, sizeof(ime_form) ); + ime_form.dwStyle = CFS_POINT; + ime_form.ptCurrentPos.x = win_pos.mX; + ime_form.ptCurrentPos.y = win_pos.mY; - LLWinImm::setCompositionWindow( himc, &ime_form ); + LLWinImm::setCompositionWindow( himc, &ime_form ); - sWinIMEWindowPosition = win_pos; - } + sWinIMEWindowPosition = win_pos; + } - LLWinImm::releaseContext(mWindowHandle, himc); - } + LLWinImm::releaseContext(mWindowHandle, himc); + } } void LLWindowWin32::fillCharPosition(const LLCoordGL& caret, const LLRect& bounds, const LLRect& control, - IMECHARPOSITION *char_position) + IMECHARPOSITION *char_position) { - LLCoordScreen caret_coord, top_left, bottom_right; - convertCoords(caret, &caret_coord); - convertCoords(LLCoordGL(bounds.mLeft, bounds.mTop), &top_left); - convertCoords(LLCoordGL(bounds.mRight, bounds.mBottom), &bottom_right); + LLCoordScreen caret_coord, top_left, bottom_right; + convertCoords(caret, &caret_coord); + convertCoords(LLCoordGL(bounds.mLeft, bounds.mTop), &top_left); + convertCoords(LLCoordGL(bounds.mRight, bounds.mBottom), &bottom_right); - char_position->pt.x = caret_coord.mX; - char_position->pt.y = top_left.mY; // Windows wants the coordinate of upper left corner of a character... - char_position->cLineHeight = bottom_right.mY - top_left.mY; - char_position->rcDocument.left = top_left.mX; - char_position->rcDocument.top = top_left.mY; - char_position->rcDocument.right = bottom_right.mX; - char_position->rcDocument.bottom = bottom_right.mY; + char_position->pt.x = caret_coord.mX; + char_position->pt.y = top_left.mY; // Windows wants the coordinate of upper left corner of a character... + char_position->cLineHeight = bottom_right.mY - top_left.mY; + char_position->rcDocument.left = top_left.mX; + char_position->rcDocument.top = top_left.mY; + char_position->rcDocument.right = bottom_right.mX; + char_position->rcDocument.bottom = bottom_right.mY; } void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont) { - // Our font is a list of FreeType recognized font files that may - // not have a corresponding ones in Windows' fonts. Hence, we - // can't simply tell Windows which font we are using. We will - // notify a _standard_ font for a current input locale instead. - // We use a hard-coded knowledge about the Windows' standard - // configuration to do so... - - memset(logfont, 0, sizeof(LOGFONT)); - - const WORD lang_id = LOWORD(GetKeyboardLayout(0)); - switch (PRIMARYLANGID(lang_id)) - { - case LANG_CHINESE: - // We need to identify one of two Chinese fonts. - switch (SUBLANGID(lang_id)) - { - case SUBLANG_CHINESE_SIMPLIFIED: - case SUBLANG_CHINESE_SINGAPORE: - logfont->lfCharSet = GB2312_CHARSET; - lstrcpy(logfont->lfFaceName, TEXT("SimHei")); - break; - case SUBLANG_CHINESE_TRADITIONAL: - case SUBLANG_CHINESE_HONGKONG: - case SUBLANG_CHINESE_MACAU: - default: - logfont->lfCharSet = CHINESEBIG5_CHARSET; - lstrcpy(logfont->lfFaceName, TEXT("MingLiU")); - break; - } - break; - case LANG_JAPANESE: - logfont->lfCharSet = SHIFTJIS_CHARSET; - lstrcpy(logfont->lfFaceName, TEXT("MS Gothic")); - break; - case LANG_KOREAN: - logfont->lfCharSet = HANGUL_CHARSET; - lstrcpy(logfont->lfFaceName, TEXT("Gulim")); - break; - default: - logfont->lfCharSet = ANSI_CHARSET; - lstrcpy(logfont->lfFaceName, TEXT("Tahoma")); - break; - } - - logfont->lfHeight = mPreeditor->getPreeditFontSize(); - logfont->lfWeight = FW_NORMAL; -} + // Our font is a list of FreeType recognized font files that may + // not have a corresponding ones in Windows' fonts. Hence, we + // can't simply tell Windows which font we are using. We will + // notify a _standard_ font for a current input locale instead. + // We use a hard-coded knowledge about the Windows' standard + // configuration to do so... -U32 LLWindowWin32::fillReconvertString(const LLWString &text, - S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string) -{ - const llutf16string text_utf16 = wstring_to_utf16str(text); - const DWORD required_size = sizeof(RECONVERTSTRING) + (text_utf16.length() + 1) * sizeof(WCHAR); - if (reconvert_string && reconvert_string->dwSize >= required_size) - { - const DWORD focus_utf16_at = wstring_utf16_length(text, 0, focus); - const DWORD focus_utf16_length = wstring_utf16_length(text, focus, focus_length); + memset(logfont, 0, sizeof(LOGFONT)); - reconvert_string->dwVersion = 0; - reconvert_string->dwStrLen = text_utf16.length(); - reconvert_string->dwStrOffset = sizeof(RECONVERTSTRING); - reconvert_string->dwCompStrLen = focus_utf16_length; - reconvert_string->dwCompStrOffset = focus_utf16_at * sizeof(WCHAR); - reconvert_string->dwTargetStrLen = 0; - reconvert_string->dwTargetStrOffset = focus_utf16_at * sizeof(WCHAR); + const WORD lang_id = LOWORD(GetKeyboardLayout(0)); + switch (PRIMARYLANGID(lang_id)) + { + case LANG_CHINESE: + // We need to identify one of two Chinese fonts. + switch (SUBLANGID(lang_id)) + { + case SUBLANG_CHINESE_SIMPLIFIED: + case SUBLANG_CHINESE_SINGAPORE: + logfont->lfCharSet = GB2312_CHARSET; + lstrcpy(logfont->lfFaceName, TEXT("SimHei")); + break; + case SUBLANG_CHINESE_TRADITIONAL: + case SUBLANG_CHINESE_HONGKONG: + case SUBLANG_CHINESE_MACAU: + default: + logfont->lfCharSet = CHINESEBIG5_CHARSET; + lstrcpy(logfont->lfFaceName, TEXT("MingLiU")); + break; + } + break; + case LANG_JAPANESE: + logfont->lfCharSet = SHIFTJIS_CHARSET; + lstrcpy(logfont->lfFaceName, TEXT("MS Gothic")); + break; + case LANG_KOREAN: + logfont->lfCharSet = HANGUL_CHARSET; + lstrcpy(logfont->lfFaceName, TEXT("Gulim")); + break; + default: + logfont->lfCharSet = ANSI_CHARSET; + lstrcpy(logfont->lfFaceName, TEXT("Tahoma")); + break; + } - const LPWSTR text = (LPWSTR)((BYTE *)reconvert_string + sizeof(RECONVERTSTRING)); - memcpy(text, text_utf16.c_str(), (text_utf16.length() + 1) * sizeof(WCHAR)); - } - return required_size; + logfont->lfHeight = mPreeditor->getPreeditFontSize(); + logfont->lfWeight = FW_NORMAL; +} + +U32 LLWindowWin32::fillReconvertString(const LLWString &text, + S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string) +{ + const llutf16string text_utf16 = wstring_to_utf16str(text); + const DWORD required_size = sizeof(RECONVERTSTRING) + (text_utf16.length() + 1) * sizeof(WCHAR); + if (reconvert_string && reconvert_string->dwSize >= required_size) + { + const DWORD focus_utf16_at = wstring_utf16_length(text, 0, focus); + const DWORD focus_utf16_length = wstring_utf16_length(text, focus, focus_length); + + reconvert_string->dwVersion = 0; + reconvert_string->dwStrLen = text_utf16.length(); + reconvert_string->dwStrOffset = sizeof(RECONVERTSTRING); + reconvert_string->dwCompStrLen = focus_utf16_length; + reconvert_string->dwCompStrOffset = focus_utf16_at * sizeof(WCHAR); + reconvert_string->dwTargetStrLen = 0; + reconvert_string->dwTargetStrOffset = focus_utf16_at * sizeof(WCHAR); + + const LPWSTR text = (LPWSTR)((BYTE *)reconvert_string + sizeof(RECONVERTSTRING)); + memcpy(text, text_utf16.c_str(), (text_utf16.length() + 1) * sizeof(WCHAR)); + } + return required_size; } void LLWindowWin32::updateLanguageTextInputArea() { - if (!mPreeditor || !LLWinImm::isAvailable()) - { - return; - } - - LLCoordGL caret_coord; - LLRect preedit_bounds; - if (mPreeditor->getPreeditLocation(-1, &caret_coord, &preedit_bounds, NULL)) - { - mLanguageTextInputPointGL = caret_coord; - mLanguageTextInputAreaGL = preedit_bounds; - - CANDIDATEFORM candidate_form; - fillCandidateForm(caret_coord, preedit_bounds, &candidate_form); - - HIMC himc = LLWinImm::getContext(mWindowHandle); - // Win32 document says there may be up to 4 candidate windows. - // This magic number 4 appears only in the document, and - // there are no constant/macro for the value... - for (int i = 3; i >= 0; --i) - { - candidate_form.dwIndex = i; - LLWinImm::setCandidateWindow(himc, &candidate_form); - } - LLWinImm::releaseContext(mWindowHandle, himc); - } + if (!mPreeditor || !LLWinImm::isAvailable()) + { + return; + } + + LLCoordGL caret_coord; + LLRect preedit_bounds; + if (mPreeditor->getPreeditLocation(-1, &caret_coord, &preedit_bounds, NULL)) + { + mLanguageTextInputPointGL = caret_coord; + mLanguageTextInputAreaGL = preedit_bounds; + + CANDIDATEFORM candidate_form; + fillCandidateForm(caret_coord, preedit_bounds, &candidate_form); + + HIMC himc = LLWinImm::getContext(mWindowHandle); + // Win32 document says there may be up to 4 candidate windows. + // This magic number 4 appears only in the document, and + // there are no constant/macro for the value... + for (int i = 3; i >= 0; --i) + { + candidate_form.dwIndex = i; + LLWinImm::setCandidateWindow(himc, &candidate_form); + } + LLWinImm::releaseContext(mWindowHandle, himc); + } } void LLWindowWin32::interruptLanguageTextInput() { ASSERT_MAIN_THREAD(); - if (mPreeditor && LLWinImm::isAvailable()) - { - HIMC himc = LLWinImm::getContext(mWindowHandle); - LLWinImm::notifyIME(himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); - LLWinImm::releaseContext(mWindowHandle, himc); - } + if (mPreeditor && LLWinImm::isAvailable()) + { + HIMC himc = LLWinImm::getContext(mWindowHandle); + LLWinImm::notifyIME(himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); + LLWinImm::releaseContext(mWindowHandle, himc); + } } void LLWindowWin32::handleStartCompositionMessage() { - // Let IME know the font to use in feedback UI. - LOGFONT logfont; - fillCompositionLogfont(&logfont); - HIMC himc = LLWinImm::getContext(mWindowHandle); - LLWinImm::setCompositionFont(himc, &logfont); - LLWinImm::releaseContext(mWindowHandle, himc); + // Let IME know the font to use in feedback UI. + LOGFONT logfont; + fillCompositionLogfont(&logfont); + HIMC himc = LLWinImm::getContext(mWindowHandle); + LLWinImm::setCompositionFont(himc, &logfont); + LLWinImm::releaseContext(mWindowHandle, himc); } // Handle WM_IME_COMPOSITION message. @@ -4116,156 +4122,156 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) { return; } - BOOL needs_update = FALSE; - LLWString result_string; - LLWString preedit_string; - S32 preedit_string_utf16_length = 0; - LLPreeditor::segment_lengths_t preedit_segment_lengths; - LLPreeditor::standouts_t preedit_standouts; - - // Step I: Receive details of preedits from IME. - - HIMC himc = LLWinImm::getContext(mWindowHandle); - - if (indexes & GCS_RESULTSTR) - { - LONG size = LLWinImm::getCompositionString(himc, GCS_RESULTSTR, NULL, 0); - if (size >= 0) - { - const LPWSTR data = new WCHAR[size / sizeof(WCHAR) + 1]; - size = LLWinImm::getCompositionString(himc, GCS_RESULTSTR, data, size); - if (size > 0) - { - result_string = utf16str_to_wstring(llutf16string(data, size / sizeof(WCHAR))); - } - delete[] data; - needs_update = TRUE; - } - } - - if (indexes & GCS_COMPSTR) - { - LONG size = LLWinImm::getCompositionString(himc, GCS_COMPSTR, NULL, 0); - if (size >= 0) - { - const LPWSTR data = new WCHAR[size / sizeof(WCHAR) + 1]; - size = LLWinImm::getCompositionString(himc, GCS_COMPSTR, data, size); - if (size > 0) - { - preedit_string_utf16_length = size / sizeof(WCHAR); - preedit_string = utf16str_to_wstring(llutf16string(data, size / sizeof(WCHAR))); - } - delete[] data; - needs_update = TRUE; - } - } - - if ((indexes & GCS_COMPCLAUSE) && preedit_string.length() > 0) - { - LONG size = LLWinImm::getCompositionString(himc, GCS_COMPCLAUSE, NULL, 0); - if (size > 0) - { - const LPDWORD data = new DWORD[size / sizeof(DWORD)]; - size = LLWinImm::getCompositionString(himc, GCS_COMPCLAUSE, data, size); - if (size >= sizeof(DWORD) * 2 - && data[0] == 0 && data[size / sizeof(DWORD) - 1] == preedit_string_utf16_length) - { - preedit_segment_lengths.resize(size / sizeof(DWORD) - 1); - S32 offset = 0; - for (U32 i = 0; i < preedit_segment_lengths.size(); i++) - { - const S32 length = wstring_wstring_length_from_utf16_length(preedit_string, offset, data[i + 1] - data[i]); - preedit_segment_lengths[i] = length; - offset += length; - } - } - delete[] data; - } - } - - if ((indexes & GCS_COMPATTR) && preedit_segment_lengths.size() > 1) - { - LONG size = LLWinImm::getCompositionString(himc, GCS_COMPATTR, NULL, 0); - if (size > 0) - { - const LPBYTE data = new BYTE[size / sizeof(BYTE)]; - size = LLWinImm::getCompositionString(himc, GCS_COMPATTR, data, size); - if (size == preedit_string_utf16_length) - { - preedit_standouts.assign(preedit_segment_lengths.size(), FALSE); - S32 offset = 0; - for (U32 i = 0; i < preedit_segment_lengths.size(); i++) - { - if (ATTR_TARGET_CONVERTED == data[offset] || ATTR_TARGET_NOTCONVERTED == data[offset]) - { - preedit_standouts[i] = TRUE; - } - offset += wstring_utf16_length(preedit_string, offset, preedit_segment_lengths[i]); - } - } - delete[] data; - } - } - - S32 caret_position = preedit_string.length(); - if (indexes & GCS_CURSORPOS) - { - const S32 caret_position_utf16 = LLWinImm::getCompositionString(himc, GCS_CURSORPOS, NULL, 0); - if (caret_position_utf16 >= 0 && caret_position <= preedit_string_utf16_length) - { - caret_position = wstring_wstring_length_from_utf16_length(preedit_string, 0, caret_position_utf16); - } - } - - if (indexes == 0) - { - // I'm not sure this condition really happens, but - // Windows SDK document says it is an indication - // of "reset everything." - needs_update = TRUE; - } - - LLWinImm::releaseContext(mWindowHandle, himc); - - // Step II: Update the active preeditor. - - if (needs_update) - { + BOOL needs_update = FALSE; + LLWString result_string; + LLWString preedit_string; + S32 preedit_string_utf16_length = 0; + LLPreeditor::segment_lengths_t preedit_segment_lengths; + LLPreeditor::standouts_t preedit_standouts; + + // Step I: Receive details of preedits from IME. + + HIMC himc = LLWinImm::getContext(mWindowHandle); + + if (indexes & GCS_RESULTSTR) + { + LONG size = LLWinImm::getCompositionString(himc, GCS_RESULTSTR, NULL, 0); + if (size >= 0) + { + const LPWSTR data = new WCHAR[size / sizeof(WCHAR) + 1]; + size = LLWinImm::getCompositionString(himc, GCS_RESULTSTR, data, size); + if (size > 0) + { + result_string = utf16str_to_wstring(llutf16string(data, size / sizeof(WCHAR))); + } + delete[] data; + needs_update = TRUE; + } + } + + if (indexes & GCS_COMPSTR) + { + LONG size = LLWinImm::getCompositionString(himc, GCS_COMPSTR, NULL, 0); + if (size >= 0) + { + const LPWSTR data = new WCHAR[size / sizeof(WCHAR) + 1]; + size = LLWinImm::getCompositionString(himc, GCS_COMPSTR, data, size); + if (size > 0) + { + preedit_string_utf16_length = size / sizeof(WCHAR); + preedit_string = utf16str_to_wstring(llutf16string(data, size / sizeof(WCHAR))); + } + delete[] data; + needs_update = TRUE; + } + } + + if ((indexes & GCS_COMPCLAUSE) && preedit_string.length() > 0) + { + LONG size = LLWinImm::getCompositionString(himc, GCS_COMPCLAUSE, NULL, 0); + if (size > 0) + { + const LPDWORD data = new DWORD[size / sizeof(DWORD)]; + size = LLWinImm::getCompositionString(himc, GCS_COMPCLAUSE, data, size); + if (size >= sizeof(DWORD) * 2 + && data[0] == 0 && data[size / sizeof(DWORD) - 1] == preedit_string_utf16_length) + { + preedit_segment_lengths.resize(size / sizeof(DWORD) - 1); + S32 offset = 0; + for (U32 i = 0; i < preedit_segment_lengths.size(); i++) + { + const S32 length = wstring_wstring_length_from_utf16_length(preedit_string, offset, data[i + 1] - data[i]); + preedit_segment_lengths[i] = length; + offset += length; + } + } + delete[] data; + } + } + + if ((indexes & GCS_COMPATTR) && preedit_segment_lengths.size() > 1) + { + LONG size = LLWinImm::getCompositionString(himc, GCS_COMPATTR, NULL, 0); + if (size > 0) + { + const LPBYTE data = new BYTE[size / sizeof(BYTE)]; + size = LLWinImm::getCompositionString(himc, GCS_COMPATTR, data, size); + if (size == preedit_string_utf16_length) + { + preedit_standouts.assign(preedit_segment_lengths.size(), FALSE); + S32 offset = 0; + for (U32 i = 0; i < preedit_segment_lengths.size(); i++) + { + if (ATTR_TARGET_CONVERTED == data[offset] || ATTR_TARGET_NOTCONVERTED == data[offset]) + { + preedit_standouts[i] = TRUE; + } + offset += wstring_utf16_length(preedit_string, offset, preedit_segment_lengths[i]); + } + } + delete[] data; + } + } + + S32 caret_position = preedit_string.length(); + if (indexes & GCS_CURSORPOS) + { + const S32 caret_position_utf16 = LLWinImm::getCompositionString(himc, GCS_CURSORPOS, NULL, 0); + if (caret_position_utf16 >= 0 && caret_position <= preedit_string_utf16_length) + { + caret_position = wstring_wstring_length_from_utf16_length(preedit_string, 0, caret_position_utf16); + } + } + + if (indexes == 0) + { + // I'm not sure this condition really happens, but + // Windows SDK document says it is an indication + // of "reset everything." + needs_update = TRUE; + } + + LLWinImm::releaseContext(mWindowHandle, himc); + + // Step II: Update the active preeditor. + + if (needs_update) + { if (preedit_string.length() != 0 || result_string.length() != 0) { mPreeditor->resetPreedit(); } - if (result_string.length() > 0) - { - for (LLWString::const_iterator i = result_string.begin(); i != result_string.end(); i++) - { - mPreeditor->handleUnicodeCharHere(*i); - } - } - - if (preedit_string.length() == 0) - { - preedit_segment_lengths.clear(); - preedit_standouts.clear(); - } - else - { - if (preedit_segment_lengths.size() == 0) - { - preedit_segment_lengths.assign(1, preedit_string.length()); - } - if (preedit_standouts.size() == 0) - { - preedit_standouts.assign(preedit_segment_lengths.size(), FALSE); - } - } - mPreeditor->updatePreedit(preedit_string, preedit_segment_lengths, preedit_standouts, caret_position); - - // Some IME doesn't query char position after WM_IME_COMPOSITION, - // so we need to update them actively. - updateLanguageTextInputArea(); - } + if (result_string.length() > 0) + { + for (LLWString::const_iterator i = result_string.begin(); i != result_string.end(); i++) + { + mPreeditor->handleUnicodeCharHere(*i); + } + } + + if (preedit_string.length() == 0) + { + preedit_segment_lengths.clear(); + preedit_standouts.clear(); + } + else + { + if (preedit_segment_lengths.size() == 0) + { + preedit_segment_lengths.assign(1, preedit_string.length()); + } + if (preedit_standouts.size() == 0) + { + preedit_standouts.assign(preedit_segment_lengths.size(), FALSE); + } + } + mPreeditor->updatePreedit(preedit_string, preedit_segment_lengths, preedit_standouts, caret_position); + + // Some IME doesn't query char position after WM_IME_COMPOSITION, + // so we need to update them actively. + updateLanguageTextInputArea(); + } } // Given a text and a focus range, find_context finds and returns a @@ -4275,24 +4281,24 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_length, S32 *offset) { - static const S32 CONTEXT_EXCESS = 30; // This value is by experiences. + static const S32 CONTEXT_EXCESS = 30; // This value is by experiences. - const S32 e = llmin((S32) wtext.length(), focus + focus_length + CONTEXT_EXCESS); - S32 end = focus + focus_length; - while (end < e && '\n' != wtext[end]) - { - end++; - } + const S32 e = llmin((S32) wtext.length(), focus + focus_length + CONTEXT_EXCESS); + S32 end = focus + focus_length; + while (end < e && '\n' != wtext[end]) + { + end++; + } - const S32 s = llmax(0, focus - CONTEXT_EXCESS); - S32 start = focus; - while (start > s && '\n' != wtext[start - 1]) - { - --start; - } + const S32 s = llmax(0, focus - CONTEXT_EXCESS); + S32 start = focus; + while (start > s && '\n' != wtext[start - 1]) + { + --start; + } - *offset = start; - return wtext.substr(start, end - start); + *offset = start; + return wtext.substr(start, end - start); } // final stage of handling drop requests - both from WM_DROPFILES message @@ -4300,7 +4306,7 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ) { ASSERT_MAIN_THREAD(); - return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url ); + return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url ); } // Handle WM_IME_REQUEST message. @@ -4310,153 +4316,153 @@ LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( cons BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *result) { - if ( mPreeditor ) - { - switch (request) - { - case IMR_CANDIDATEWINDOW: // http://msdn2.microsoft.com/en-us/library/ms776080.aspx - { - LLCoordGL caret_coord; - LLRect preedit_bounds; - mPreeditor->getPreeditLocation(-1, &caret_coord, &preedit_bounds, NULL); - - CANDIDATEFORM *const form = (CANDIDATEFORM *)param; - DWORD const dwIndex = form->dwIndex; - fillCandidateForm(caret_coord, preedit_bounds, form); - form->dwIndex = dwIndex; - - *result = 1; - return TRUE; - } - case IMR_QUERYCHARPOSITION: - { - IMECHARPOSITION *const char_position = (IMECHARPOSITION *)param; - - // char_position->dwCharPos counts in number of - // WCHARs, i.e., UTF-16 encoding units, so we can't simply pass the - // number to getPreeditLocation. - - const LLWString & wtext = mPreeditor->getPreeditString(); - S32 preedit, preedit_length; - mPreeditor->getPreeditRange(&preedit, &preedit_length); - LLCoordGL caret_coord; - LLRect preedit_bounds, text_control; - const S32 position = wstring_wstring_length_from_utf16_length(wtext, preedit, char_position->dwCharPos); - - if (!mPreeditor->getPreeditLocation(position, &caret_coord, &preedit_bounds, &text_control)) - { - LL_WARNS("Window") << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << LL_ENDL; - return FALSE; - } - - fillCharPosition(caret_coord, preedit_bounds, text_control, char_position); - - *result = 1; - return TRUE; - } - case IMR_COMPOSITIONFONT: - { - fillCompositionLogfont((LOGFONT *)param); - - *result = 1; - return TRUE; - } - case IMR_RECONVERTSTRING: - { - mPreeditor->resetPreedit(); - const LLWString & wtext = mPreeditor->getPreeditString(); - S32 select, select_length; - mPreeditor->getSelectionRange(&select, &select_length); - - S32 context_offset; - const LLWString context = find_context(wtext, select, select_length, &context_offset); - - RECONVERTSTRING * const reconvert_string = (RECONVERTSTRING *)param; - const U32 size = fillReconvertString(context, select - context_offset, select_length, reconvert_string); - if (reconvert_string) - { - if (select_length == 0) - { - // Let the IME to decide the reconversion range, and - // adjust the reconvert_string structure accordingly. - HIMC himc = LLWinImm::getContext(mWindowHandle); - const BOOL adjusted = LLWinImm::setCompositionString(himc, - SCS_QUERYRECONVERTSTRING, reconvert_string, size, NULL, 0); - LLWinImm::releaseContext(mWindowHandle, himc); - if (adjusted) - { - const llutf16string & text_utf16 = wstring_to_utf16str(context); - const S32 new_preedit_start = reconvert_string->dwCompStrOffset / sizeof(WCHAR); - const S32 new_preedit_end = new_preedit_start + reconvert_string->dwCompStrLen; - select = utf16str_wstring_length(text_utf16, new_preedit_start); - select_length = utf16str_wstring_length(text_utf16, new_preedit_end) - select; - select += context_offset; - } - } - mPreeditor->markAsPreedit(select, select_length); - } - - *result = size; - return TRUE; - } - case IMR_CONFIRMRECONVERTSTRING: - { - *result = FALSE; - return TRUE; - } - case IMR_DOCUMENTFEED: - { - const LLWString & wtext = mPreeditor->getPreeditString(); - S32 preedit, preedit_length; - mPreeditor->getPreeditRange(&preedit, &preedit_length); - - S32 context_offset; - LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); - preedit -= context_offset; - preedit_length = llmin(preedit_length, (S32)context.length() - preedit); - if (preedit_length > 0 && preedit >= 0) - { - // IMR_DOCUMENTFEED may be called when we have an active preedit. - // We should pass the context string *excluding* the preedit string. - // Otherwise, some IME are confused. - context.erase(preedit, preedit_length); - } - - RECONVERTSTRING *reconvert_string = (RECONVERTSTRING *)param; - *result = fillReconvertString(context, preedit, 0, reconvert_string); - return TRUE; - } - default: - return FALSE; - } - } - - return FALSE; + if ( mPreeditor ) + { + switch (request) + { + case IMR_CANDIDATEWINDOW: // http://msdn2.microsoft.com/en-us/library/ms776080.aspx + { + LLCoordGL caret_coord; + LLRect preedit_bounds; + mPreeditor->getPreeditLocation(-1, &caret_coord, &preedit_bounds, NULL); + + CANDIDATEFORM *const form = (CANDIDATEFORM *)param; + DWORD const dwIndex = form->dwIndex; + fillCandidateForm(caret_coord, preedit_bounds, form); + form->dwIndex = dwIndex; + + *result = 1; + return TRUE; + } + case IMR_QUERYCHARPOSITION: + { + IMECHARPOSITION *const char_position = (IMECHARPOSITION *)param; + + // char_position->dwCharPos counts in number of + // WCHARs, i.e., UTF-16 encoding units, so we can't simply pass the + // number to getPreeditLocation. + + const LLWString & wtext = mPreeditor->getPreeditString(); + S32 preedit, preedit_length; + mPreeditor->getPreeditRange(&preedit, &preedit_length); + LLCoordGL caret_coord; + LLRect preedit_bounds, text_control; + const S32 position = wstring_wstring_length_from_utf16_length(wtext, preedit, char_position->dwCharPos); + + if (!mPreeditor->getPreeditLocation(position, &caret_coord, &preedit_bounds, &text_control)) + { + LL_WARNS("Window") << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << LL_ENDL; + return FALSE; + } + + fillCharPosition(caret_coord, preedit_bounds, text_control, char_position); + + *result = 1; + return TRUE; + } + case IMR_COMPOSITIONFONT: + { + fillCompositionLogfont((LOGFONT *)param); + + *result = 1; + return TRUE; + } + case IMR_RECONVERTSTRING: + { + mPreeditor->resetPreedit(); + const LLWString & wtext = mPreeditor->getPreeditString(); + S32 select, select_length; + mPreeditor->getSelectionRange(&select, &select_length); + + S32 context_offset; + const LLWString context = find_context(wtext, select, select_length, &context_offset); + + RECONVERTSTRING * const reconvert_string = (RECONVERTSTRING *)param; + const U32 size = fillReconvertString(context, select - context_offset, select_length, reconvert_string); + if (reconvert_string) + { + if (select_length == 0) + { + // Let the IME to decide the reconversion range, and + // adjust the reconvert_string structure accordingly. + HIMC himc = LLWinImm::getContext(mWindowHandle); + const BOOL adjusted = LLWinImm::setCompositionString(himc, + SCS_QUERYRECONVERTSTRING, reconvert_string, size, NULL, 0); + LLWinImm::releaseContext(mWindowHandle, himc); + if (adjusted) + { + const llutf16string & text_utf16 = wstring_to_utf16str(context); + const S32 new_preedit_start = reconvert_string->dwCompStrOffset / sizeof(WCHAR); + const S32 new_preedit_end = new_preedit_start + reconvert_string->dwCompStrLen; + select = utf16str_wstring_length(text_utf16, new_preedit_start); + select_length = utf16str_wstring_length(text_utf16, new_preedit_end) - select; + select += context_offset; + } + } + mPreeditor->markAsPreedit(select, select_length); + } + + *result = size; + return TRUE; + } + case IMR_CONFIRMRECONVERTSTRING: + { + *result = FALSE; + return TRUE; + } + case IMR_DOCUMENTFEED: + { + const LLWString & wtext = mPreeditor->getPreeditString(); + S32 preedit, preedit_length; + mPreeditor->getPreeditRange(&preedit, &preedit_length); + + S32 context_offset; + LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); + preedit -= context_offset; + preedit_length = llmin(preedit_length, (S32)context.length() - preedit); + if (preedit_length > 0 && preedit >= 0) + { + // IMR_DOCUMENTFEED may be called when we have an active preedit. + // We should pass the context string *excluding* the preedit string. + // Otherwise, some IME are confused. + context.erase(preedit, preedit_length); + } + + RECONVERTSTRING *reconvert_string = (RECONVERTSTRING *)param; + *result = fillReconvertString(context, preedit, 0, reconvert_string); + return TRUE; + } + default: + return FALSE; + } + } + + return FALSE; } //static void LLWindowWin32::setDPIAwareness() { - HMODULE hShcore = LoadLibrary(L"shcore.dll"); - if (hShcore != NULL) - { - SetProcessDpiAwarenessType pSPDA; - pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); - if (pSPDA) - { - - HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); - if (hr != S_OK) - { - LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; - } - } - FreeLibrary(hShcore); - } - else - { - LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; - } + HMODULE hShcore = LoadLibrary(L"shcore.dll"); + if (hShcore != NULL) + { + SetProcessDpiAwarenessType pSPDA; + pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); + if (pSPDA) + { + + HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); + if (hr != S_OK) + { + LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } + } + FreeLibrary(hShcore); + } + else + { + LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } } void* LLWindowWin32::getDirectInput8() @@ -4464,7 +4470,10 @@ void* LLWindowWin32::getDirectInput8() return &gDirectInput8; } -bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata) +bool LLWindowWin32::getInputDevices(U32 device_type_filter, + std::function<bool(std::string&, LLSD&, void*)> osx_callback, + void * di8_devices_callback, + void* userdata) { if (gDirectInput8 != NULL) { @@ -4483,76 +4492,76 @@ bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_c F32 LLWindowWin32::getSystemUISize() { - F32 scale_value = 1.f; - HWND hWnd = (HWND)getPlatformWindow(); - HDC hdc = GetDC(hWnd); - HMONITOR hMonitor; - HANDLE hProcess = GetCurrentProcess(); - PROCESS_DPI_AWARENESS dpi_awareness; - - HMODULE hShcore = LoadLibrary(L"shcore.dll"); - - if (hShcore != NULL) - { - GetProcessDpiAwarenessType pGPDA; - pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness"); - GetDpiForMonitorType pGDFM; - pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor"); - if (pGPDA != NULL && pGDFM != NULL) - { - pGPDA(hProcess, &dpi_awareness); - if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE) - { - POINT pt; - UINT dpix = 0, dpiy = 0; - HRESULT hr = E_FAIL; - RECT rect; - - GetWindowRect(hWnd, &rect); - // Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor - pt.x = (rect.left + rect.right) / 2; - pt.y = (rect.top + rect.bottom) / 2; - hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); - if (hr == S_OK) - { - scale_value = F32(dpix) / F32(USER_DEFAULT_SCREEN_DPI); - } - else - { - LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; - scale_value = 1.0f; - } - } - else - { - LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; - scale_value = 1.0f; - } - } - FreeLibrary(hShcore); - } - else - { - LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; - scale_value = F32(GetDeviceCaps(hdc, LOGPIXELSX)) / F32(USER_DEFAULT_SCREEN_DPI); - } - - ReleaseDC(hWnd, hdc); - return scale_value; + F32 scale_value = 1.f; + HWND hWnd = (HWND)getPlatformWindow(); + HDC hdc = GetDC(hWnd); + HMONITOR hMonitor; + HANDLE hProcess = GetCurrentProcess(); + PROCESS_DPI_AWARENESS dpi_awareness; + + HMODULE hShcore = LoadLibrary(L"shcore.dll"); + + if (hShcore != NULL) + { + GetProcessDpiAwarenessType pGPDA; + pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness"); + GetDpiForMonitorType pGDFM; + pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor"); + if (pGPDA != NULL && pGDFM != NULL) + { + pGPDA(hProcess, &dpi_awareness); + if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE) + { + POINT pt; + UINT dpix = 0, dpiy = 0; + HRESULT hr = E_FAIL; + RECT rect; + + GetWindowRect(hWnd, &rect); + // Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor + pt.x = (rect.left + rect.right) / 2; + pt.y = (rect.top + rect.bottom) / 2; + hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); + if (hr == S_OK) + { + scale_value = F32(dpix) / F32(USER_DEFAULT_SCREEN_DPI); + } + else + { + LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } + } + else + { + LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } + } + FreeLibrary(hShcore); + } + else + { + LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; + scale_value = F32(GetDeviceCaps(hdc, LOGPIXELSX)) / F32(USER_DEFAULT_SCREEN_DPI); + } + + ReleaseDC(hWnd, hdc); + return scale_value; } //static std::vector<std::string> LLWindowWin32::getDisplaysResolutionList() -{ - return sMonitorInfo.getResolutionsList(); +{ + return sMonitorInfo.getResolutionsList(); } //static std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList() { - // Fonts previously in getFontListSans() have moved to fonts.xml. - return std::vector<std::string>(); + // Fonts previously in getFontListSans() have moved to fonts.xml. + return std::vector<std::string>(); } U32 LLWindowWin32::getAvailableVRAMMegabytes() @@ -4736,7 +4745,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D() if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandleThrd != 0) { mD3D = Direct3DCreate9(D3D_SDK_VERSION); - + D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); @@ -4744,7 +4753,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D() d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandleThrd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); - + if (FAILED(res)) { LL_WARNS() << "(fallback) CreateDevice failed: 0x" << std::hex << res << LL_ENDL; @@ -4801,7 +4810,7 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() U32 afr_mb = info.AvailableForReservation / 1024 / 1024; // correct for systems that misreport budget if (budget_mb == 0) - { + { // fall back to available for reservation clamped between 512MB and 2GB budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048); } @@ -4822,7 +4831,7 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() } U32 target_mb = budget_mb; - if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free + if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free { target_mb -= 2048; } @@ -4834,7 +4843,7 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0; #if 0 - + F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb; LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024 << "\nBudget: " << info.Budget / 1024 / 1024 @@ -4908,7 +4917,7 @@ void LLWindowWin32::LLWindowWin32Thread::run() //process any pending functions getQueue().runPending(); } - + // update available vram once every 3 seconds static LLFrameTimer vramTimer; if (vramTimer.getElapsedTimeF32() > 3.f) @@ -5064,11 +5073,11 @@ void LLWindowWin32::updateWindowRect() //called from window thread RECT rect; RECT client_rect; - + if (GetWindowRect(mWindowHandle, &rect) && GetClientRect(mWindowHandle, &client_rect)) { - post([=] + post([=] { mRect = rect; mClientRect = client_rect; diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index ff287a140e..33fa67ba50 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -1,25 +1,25 @@ -/** +/** * @file llwindowwin32.h * @brief Windows implementation of LLWindow class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,158 +45,161 @@ typedef void (*LLW32MsgCallback)(const MSG &msg); class LLWindowWin32 : 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 enable_vsync, const LLCoordScreen * const posp = NULL); + /*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 enable_vsync, const LLCoordScreen * const posp = NULL); /*virtual*/ void setTitle(const std::string title); void* createSharedContext() override; void makeContextCurrent(void* context) override; void destroySharedContext(void* context) override; /*virtual*/ void toggleVSync(bool enable_vsync); - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); + /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); + /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta); - /*virtual*/ void showCursor(); - /*virtual*/ void hideCursor(); - /*virtual*/ void showCursorFromMouseMove(); - /*virtual*/ void hideCursorUntilMouseMove(); - /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void updateCursor(); - /*virtual*/ ECursorType getCursor() const; - /*virtual*/ void captureMouse(); - /*virtual*/ void releaseMouse(); - /*virtual*/ void setMouseClipping( BOOL b ); - /*virtual*/ BOOL isClipboardTextAvailable(); - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); - /*virtual*/ BOOL copyTextToClipboard(const LLWString &src); - /*virtual*/ void flashIcon(F32 seconds); - /*virtual*/ F32 getGamma(); - /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma - /*virtual*/ void setFSAASamples(const U32 fsaa_samples); - /*virtual*/ U32 getFSAASamples(); - /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) - /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void gatherInput(); - /*virtual*/ void delayInputProcessing(); - /*virtual*/ void swapBuffers(); - /*virtual*/ void restoreGLContext() {}; - - // 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); - - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); - /*virtual*/ F32 getNativeAspectRatio(); - /*virtual*/ F32 getPixelAspectRatio(); - /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } + /*virtual*/ void showCursor(); + /*virtual*/ void hideCursor(); + /*virtual*/ void showCursorFromMouseMove(); + /*virtual*/ void hideCursorUntilMouseMove(); + /*virtual*/ BOOL isCursorHidden(); + /*virtual*/ void updateCursor(); + /*virtual*/ ECursorType getCursor() const; + /*virtual*/ void captureMouse(); + /*virtual*/ void releaseMouse(); + /*virtual*/ void setMouseClipping( BOOL b ); + /*virtual*/ BOOL isClipboardTextAvailable(); + /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); + /*virtual*/ BOOL copyTextToClipboard(const LLWString &src); + /*virtual*/ void flashIcon(F32 seconds); + /*virtual*/ F32 getGamma(); + /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma + /*virtual*/ void setFSAASamples(const U32 fsaa_samples); + /*virtual*/ U32 getFSAASamples(); + /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) + /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } + /*virtual*/ void gatherInput(); + /*virtual*/ void delayInputProcessing(); + /*virtual*/ void swapBuffers(); + /*virtual*/ void restoreGLContext() {}; + + // 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); + + /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); + /*virtual*/ F32 getNativeAspectRatio(); + /*virtual*/ F32 getPixelAspectRatio(); + /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } U32 getAvailableVRAMMegabytes() override; - - /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b ); - /*virtual*/ void *getPlatformWindow(); - /*virtual*/ void bringToFront(); - /*virtual*/ void focusClient(); + /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b ); + + /*virtual*/ void *getPlatformWindow(); + /*virtual*/ void bringToFront(); + /*virtual*/ void focusClient(); - /*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b); - /*virtual*/ void setLanguageTextInput( const LLCoordGL & pos ); - /*virtual*/ void updateLanguageTextInputArea(); - /*virtual*/ void interruptLanguageTextInput(); - /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); + /*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b); + /*virtual*/ void setLanguageTextInput( const LLCoordGL & pos ); + /*virtual*/ void updateLanguageTextInputArea(); + /*virtual*/ void interruptLanguageTextInput(); + /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); - /*virtual*/ F32 getSystemUISize(); + /*virtual*/ F32 getSystemUISize(); - LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); + LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); - static std::vector<std::string> getDisplaysResolutionList(); - static std::vector<std::string> getDynamicFallbackFontList(); - static void setDPIAwareness(); + static std::vector<std::string> getDisplaysResolutionList(); + static std::vector<std::string> getDynamicFallbackFontList(); + static void setDPIAwareness(); /*virtual*/ void* getDirectInput8(); - /*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata); + /*virtual*/ bool getInputDevices(U32 device_type_filter, + std::function<bool(std::string&, LLSD&, void*)> osx_callback, + void* win_callback, + void* userdata); U32 getRawWParam() { return mRawWParam; } protected: - LLWindowWin32(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, U32 max_cores, U32 max_vram, F32 max_gl_version); - ~LLWindowWin32(); - - void initCursors(); - void initInputDevices(); - HCURSOR loadColorCursor(LPCTSTR name); - BOOL isValid(); - void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); - virtual LLSD getNativeKeyData(); - - // Changes display resolution. Returns true if successful - BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); - - // Go back to last fullscreen display resolution. - BOOL setFullscreenResolution(); - - // Restore the display resolution to its value before we ran the app. - BOOL resetDisplayResolution(); - - BOOL shouldPostQuit() { return mPostQuit; } - - void fillCompositionForm(const LLRect& bounds, COMPOSITIONFORM *form); - void fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, CANDIDATEFORM *form); - void fillCharPosition(const LLCoordGL& caret, const LLRect& bounds, const LLRect& control, IMECHARPOSITION *char_position); - void fillCompositionLogfont(LOGFONT *logfont); - U32 fillReconvertString(const LLWString &text, S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string); - void handleStartCompositionMessage(); - void handleCompositionMessage(U32 indexes); - BOOL handleImeRequests(WPARAM request, LPARAM param, LRESULT *result); + LLWindowWin32(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, U32 max_cores, U32 max_vram, F32 max_gl_version); + ~LLWindowWin32(); + + void initCursors(); + void initInputDevices(); + HCURSOR loadColorCursor(LPCTSTR name); + BOOL isValid(); + void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); + virtual LLSD getNativeKeyData(); + + // Changes display resolution. Returns true if successful + BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); + + // Go back to last fullscreen display resolution. + BOOL setFullscreenResolution(); + + // Restore the display resolution to its value before we ran the app. + BOOL resetDisplayResolution(); + + BOOL shouldPostQuit() { return mPostQuit; } + + void fillCompositionForm(const LLRect& bounds, COMPOSITIONFORM *form); + void fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, CANDIDATEFORM *form); + void fillCharPosition(const LLCoordGL& caret, const LLRect& bounds, const LLRect& control, IMECHARPOSITION *char_position); + void fillCompositionLogfont(LOGFONT *logfont); + U32 fillReconvertString(const LLWString &text, S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string); + void handleStartCompositionMessage(); + void handleCompositionMessage(U32 indexes); + BOOL handleImeRequests(WPARAM request, LPARAM param, LRESULT *result); protected: - // - // Platform specific methods - // + // + // Platform specific methods + // - BOOL getClientRectInScreenSpace(RECT* rectp); - void updateJoystick( ); + BOOL getClientRectInScreenSpace(RECT* rectp); + void updateJoystick( ); - static LRESULT CALLBACK mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param); - static BOOL CALLBACK enumChildWindows(HWND h_wnd, LPARAM l_param); + static LRESULT CALLBACK mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param); + static BOOL CALLBACK enumChildWindows(HWND h_wnd, LPARAM l_param); - // - // Platform specific variables - // - WCHAR *mWindowTitle; - WCHAR *mWindowClassName; + // + // Platform specific variables + // + WCHAR *mWindowTitle; + WCHAR *mWindowClassName; - HWND mWindowHandle = 0; // window handle - HGLRC mhRC = 0; // OpenGL rendering context - HDC mhDC = 0; // Windows Device context handle - HINSTANCE mhInstance; // handle to application instance - RECT mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse() - WPARAM mLastSizeWParam; - F32 mOverrideAspectRatio; - F32 mNativeAspectRatio; + HWND mWindowHandle = 0; // window handle + HGLRC mhRC = 0; // OpenGL rendering context + HDC mhDC = 0; // Windows Device context handle + HINSTANCE mhInstance; // handle to application instance + RECT mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse() + WPARAM mLastSizeWParam; + F32 mOverrideAspectRatio; + F32 mNativeAspectRatio; - HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors + HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors LLCoordWindow mCursorPosition; // mouse cursor position, should only be mutated on main thread LLMutex mRawMouseMutex; RAWINPUTDEVICE mRawMouse; @@ -206,86 +209,86 @@ protected: MASK mMouseMask; - static BOOL sIsClassRegistered; // has the window class been registered? + static BOOL sIsClassRegistered; // has the window class been registered? - F32 mCurrentGamma; - U32 mFSAASamples; + F32 mCurrentGamma; + U32 mFSAASamples; U32 mMaxCores; // for debugging only -- maximum number of CPU cores to use, or 0 for no limit F32 mMaxGLVersion; // maximum OpenGL version to attempt to use (clamps to 3.2 - 4.6) - WORD mPrevGammaRamp[3][256]; - WORD mCurrentGammaRamp[3][256]; - BOOL mCustomGammaSet; - - LPWSTR mIconResource; - BOOL mInputProcessingPaused; - - // The following variables are for Language Text Input control. - // They are all static, since one context is shared by all LLWindowWin32 - // instances. - static BOOL sLanguageTextInputAllowed; - static BOOL sWinIMEOpened; - static HKL sWinInputLocale; - static DWORD sWinIMEConversionMode; - static DWORD sWinIMESentenceMode; - static LLCoordWindow sWinIMEWindowPosition; - LLCoordGL mLanguageTextInputPointGL; - LLRect mLanguageTextInputAreaGL; - - LLPreeditor *mPreeditor; - - LLDragDropWin32* mDragDrop; - - U32 mKeyCharCode; - U32 mKeyScanCode; - U32 mKeyVirtualKey; - U32 mRawMsg; - U32 mRawWParam; - U32 mRawLParam; - - BOOL mMouseVanish; + WORD mPrevGammaRamp[3][256]; + WORD mCurrentGammaRamp[3][256]; + BOOL mCustomGammaSet; + + LPWSTR mIconResource; + BOOL mInputProcessingPaused; + + // The following variables are for Language Text Input control. + // They are all static, since one context is shared by all LLWindowWin32 + // instances. + static BOOL sLanguageTextInputAllowed; + static BOOL sWinIMEOpened; + static HKL sWinInputLocale; + static DWORD sWinIMEConversionMode; + static DWORD sWinIMESentenceMode; + static LLCoordWindow sWinIMEWindowPosition; + LLCoordGL mLanguageTextInputPointGL; + LLRect mLanguageTextInputAreaGL; + + LLPreeditor *mPreeditor; + + LLDragDropWin32* mDragDrop; + + U32 mKeyCharCode; + U32 mKeyScanCode; + U32 mKeyVirtualKey; + U32 mRawMsg; + U32 mRawWParam; + U32 mRawLParam; + + BOOL mMouseVanish; // Cached values of GetWindowRect and GetClientRect to be used by app thread void updateWindowRect(); - RECT mRect; + RECT mRect; RECT mClientRect; - struct LLWindowWin32Thread; - LLWindowWin32Thread* mWindowThread = nullptr; - LLThreadSafeQueue<std::function<void()>> mFunctionQueue; - LLThreadSafeQueue<std::function<void()>> mMouseQueue; - void post(const std::function<void()>& func); - void postMouseButtonEvent(const std::function<void()>& func); - void recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style); - void kickWindowThread(HWND windowHandle=0); + struct LLWindowWin32Thread; + LLWindowWin32Thread* mWindowThread = nullptr; + LLThreadSafeQueue<std::function<void()>> mFunctionQueue; + LLThreadSafeQueue<std::function<void()>> mMouseQueue; + void post(const std::function<void()>& func); + void postMouseButtonEvent(const std::function<void()>& func); + void recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style); + void kickWindowThread(HWND windowHandle=0); - friend class LLWindowManager; + friend class LLWindowManager; }; class LLSplashScreenWin32 : public LLSplashScreen { public: - LLSplashScreenWin32(); - virtual ~LLSplashScreenWin32(); + LLSplashScreenWin32(); + virtual ~LLSplashScreenWin32(); - /*virtual*/ void showImpl(); - /*virtual*/ void updateImpl(const std::string& mesg); - /*virtual*/ void hideImpl(); + /*virtual*/ void showImpl(); + /*virtual*/ void updateImpl(const std::string& mesg); + /*virtual*/ void hideImpl(); #if LL_WINDOWS - static LRESULT CALLBACK windowProc(HWND h_wnd, UINT u_msg, - WPARAM w_param, LPARAM l_param); + static LRESULT CALLBACK windowProc(HWND h_wnd, UINT u_msg, + WPARAM w_param, LPARAM l_param); #endif private: #if LL_WINDOWS - HWND mWindow; + HWND mWindow; #endif }; extern LLW32MsgCallback gAsyncMsgCallback; extern LPWSTR gIconResource; -static void handleMessage( const MSG& msg ); +static void handleMessage( const MSG& msg ); S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type); |