diff options
Diffstat (limited to 'indra/llwindow')
30 files changed, 4873 insertions, 4873 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 34720ff64e..b3dcac6222 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 U16 os_key, KEY *out_key) { - std::map<U16, KEY>::iterator iter; - - // Only translate keys in the map, ignore all other keys for now - iter = mTranslateKeyMap.find(os_key); - 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<U16, 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; + } } U16 LLKeyboard::inverseTranslateKey(const KEY translated_key) { - std::map<KEY, U16>::iterator iter; - iter = mInvTranslateKeyMap.find(translated_key); - if (iter == mInvTranslateKeyMap.end()) - { - return 0; - } - else - { - return iter->second; - } + std::map<KEY, U16>::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 dad150e3c1..2618f9f022 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 U16 os_key, KEY *translated_key); + U16 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 U16 os_key, KEY *translated_key); - U16 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 U16 key, MASK mask) = 0; + virtual BOOL handleKeyDown(const U16 key, MASK mask) = 0; - virtual BOOL handleKeyUp(const U16 key, MASK mask) = 0; - virtual BOOL handleKeyDown(const U16 key, MASK mask) = 0; - #ifdef LL_DARWIN - // 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<U16, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs - std::map<KEY, U16> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys - 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<U16, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs + std::map<KEY, U16> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys + 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 a1b6b294e0..01ac26261b 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 8ed28ace90..8e067e6108 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 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*/ 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(); #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 7c9aa1d340..3ee10f70cd 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,291 +33,291 @@ 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... - U16 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_KP4] = KEY_PAD_LEFT; - //mTranslateKeyMap[SDLK_KP6] = KEY_PAD_RIGHT; - //mTranslateKeyMap[SDLK_KP8] = KEY_PAD_UP; - //mTranslateKeyMap[SDLK_KP2] = KEY_PAD_DOWN; - //mTranslateKeyMap[SDLK_KP_PERIOD] = KEY_DELETE; - //mTranslateKeyMap[SDLK_KP7] = KEY_HOME; - //mTranslateKeyMap[SDLK_KP1] = KEY_END; - //mTranslateKeyMap[SDLK_KP9] = KEY_PAGE_UP; - //mTranslateKeyMap[SDLK_KP3] = KEY_PAGE_DOWN; - //mTranslateKeyMap[SDLK_KP0] = 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<U16, KEY>::iterator iter; - for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) - { - mInvTranslateKeyMap[iter->second] = iter->first; - } - - // numpad map - mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS; - mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END; - mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN; - mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN; - mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT; - mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER; - mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT; - mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME; - mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP; - mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP; - mTranslateNumpadMap[SDLK_KP_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... + U16 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_KP4] = KEY_PAD_LEFT; + //mTranslateKeyMap[SDLK_KP6] = KEY_PAD_RIGHT; + //mTranslateKeyMap[SDLK_KP8] = KEY_PAD_UP; + //mTranslateKeyMap[SDLK_KP2] = KEY_PAD_DOWN; + //mTranslateKeyMap[SDLK_KP_PERIOD] = KEY_DELETE; + //mTranslateKeyMap[SDLK_KP7] = KEY_HOME; + //mTranslateKeyMap[SDLK_KP1] = KEY_END; + //mTranslateKeyMap[SDLK_KP9] = KEY_PAGE_UP; + //mTranslateKeyMap[SDLK_KP3] = KEY_PAGE_DOWN; + //mTranslateKeyMap[SDLK_KP0] = 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<U16, KEY>::iterator iter; + for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) + { + mInvTranslateKeyMap[iter->second] = iter->first; + } + + // numpad map + mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS; + mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END; + mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN; + mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN; + mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT; + mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER; + mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT; + mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME; + mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP; + mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP; + mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL; + + // build inverse numpad map + for (iter = mTranslateNumpadMap.begin(); + iter != mTranslateNumpadMap.end(); + iter++) + { + mInvTranslateNumpadMap[iter->second] = iter->first; + } } void LLKeyboardSDL::resetMaskKeys() { - SDLMod 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? - - if(mask & KMOD_SHIFT) - { - mKeyLevel[KEY_SHIFT] = TRUE; - } - - if(mask & KMOD_CTRL) - { - mKeyLevel[KEY_CONTROL] = TRUE; - } - - if(mask & KMOD_ALT) - { - mKeyLevel[KEY_ALT] = TRUE; - } + SDLMod 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? + + if(mask & KMOD_SHIFT) + { + mKeyLevel[KEY_SHIFT] = TRUE; + } + + if(mask & KMOD_CTRL) + { + 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) - { - out_mask |= MASK_CONTROL; - } + if(mask & KMOD_CTRL) + { + 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 U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask) { - // SDL doesn't automatically adjust the keysym according to - // whether NUMLOCK is engaged, so we massage the keysym manually. - U16 rtn = key; - if (!(mask & KMOD_NUM)) - { - switch (key) - { - case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; - case SDLK_KP0: rtn = SDLK_INSERT; break; - case SDLK_KP1: rtn = SDLK_END; break; - case SDLK_KP2: rtn = SDLK_DOWN; break; - case SDLK_KP3: rtn = SDLK_PAGEDOWN; break; - case SDLK_KP4: rtn = SDLK_LEFT; break; - case SDLK_KP6: rtn = SDLK_RIGHT; break; - case SDLK_KP7: rtn = SDLK_HOME; break; - case SDLK_KP8: rtn = SDLK_UP; break; - case SDLK_KP9: rtn = SDLK_PAGEUP; break; - } - } - return rtn; + // SDL doesn't automatically adjust the keysym according to + // whether NUMLOCK is engaged, so we massage the keysym manually. + U16 rtn = key; + if (!(mask & KMOD_NUM)) + { + switch (key) + { + case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; + case SDLK_KP0: rtn = SDLK_INSERT; break; + case SDLK_KP1: rtn = SDLK_END; break; + case SDLK_KP2: rtn = SDLK_DOWN; break; + case SDLK_KP3: rtn = SDLK_PAGEDOWN; break; + case SDLK_KP4: rtn = SDLK_LEFT; break; + case SDLK_KP6: rtn = SDLK_RIGHT; break; + case SDLK_KP7: rtn = SDLK_HOME; break; + case SDLK_KP8: rtn = SDLK_UP; break; + case SDLK_KP9: rtn = SDLK_PAGEUP; break; + } + } + return rtn; } BOOL LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) { - U16 adjusted_nativekey; - KEY translated_key = 0; - U32 translated_mask = MASK_NONE; - BOOL handled = FALSE; + U16 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 U16 key, const U32 mask) { - U16 adjusted_nativekey; - KEY translated_key = 0; - U32 translated_mask = MASK_NONE; - BOOL handled = FALSE; + U16 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; - SDLMod mask = SDL_GetModState(); + MASK result = MASK_NONE; + SDLMod mask = SDL_GetModState(); - if (mask & KMOD_SHIFT) result |= MASK_SHIFT; - if (mask & KMOD_CTRL) result |= MASK_CONTROL; - if (mask & KMOD_ALT) result |= MASK_ALT; + if (mask & KMOD_SHIFT) result |= MASK_SHIFT; + if (mask & KMOD_CTRL) result |= MASK_CONTROL; + if (mask & KMOD_ALT) result |= MASK_ALT; - // For keyboard events, consider Meta keys equivalent to Control - if (!for_mouse_event) - { - if (mask & KMOD_META) result |= MASK_CONTROL; - } + // For keyboard events, consider Meta keys equivalent to Control + if (!for_mouse_event) + { + if (mask & KMOD_META) 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 U16 os_key, KEY *translated_key) { - return translateKey(os_key, translated_key); + return translateKey(os_key, translated_key); } U16 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 02a71425f1..620f83e9b4 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$ */ @@ -33,23 +33,23 @@ class LLKeyboardSDL : public LLKeyboard { public: - LLKeyboardSDL(); - /*virtual*/ ~LLKeyboardSDL() {}; + LLKeyboardSDL(); + /*virtual*/ ~LLKeyboardSDL() {}; - /*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*/ 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(); 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/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 9e281dfc99..9cc11091b6 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$ */ @@ -53,43 +53,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_WINDOWS - result = OSMessageBoxWin32(text, caption, type); + result = OSMessageBoxWin32(text, caption, type); #elif LL_DARWIN - result = OSMessageBoxMacOSX(text, caption, type); + result = OSMessageBoxMacOSX(text, caption, type); #elif LL_SDL - result = OSMessageBoxSDL(text, caption, type); + result = OSMessageBoxSDL(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; } @@ -98,27 +98,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) { } @@ -129,13 +129,13 @@ LLWindow::~LLWindow() //virtual BOOL LLWindow::isValid() { - return TRUE; + return TRUE; } //virtual BOOL LLWindow::canDelete() { - return TRUE; + return TRUE; } //virtual @@ -147,126 +147,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_WINDOWS - return LLWindowWin32::getDynamicFallbackFontList(); + return LLWindowWin32::getDynamicFallbackFontList(); #elif LL_DARWIN - return LLWindowMacOSX::getDynamicFallbackFontList(); + return LLWindowMacOSX::getDynamicFallbackFontList(); #elif LL_SDL - return LLWindowSDL::getDynamicFallbackFontList(); + return LLWindowSDL::getDynamicFallbackFontList(); #else - return std::vector<std::string>(); + return std::vector<std::string>(); #endif } @@ -274,11 +274,11 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList() std::vector<std::string> LLWindow::getDisplaysResolutionList() { #if LL_WINDOWS - return LLWindowWin32::getDisplaysResolutionList(); + return LLWindowWin32::getDisplaysResolutionList(); #elif LL_DARWIN - return LLWindowMacOSX::getDisplaysResolutionList(); + return LLWindowMacOSX::getDisplaysResolutionList(); #else - return std::vector<std::string>(); + return std::vector<std::string>(); #endif } @@ -288,45 +288,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); + } + } } // @@ -336,18 +336,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 @@ -357,39 +357,39 @@ LLSplashScreen *LLSplashScreen::create() //static void LLSplashScreen::show() { - if (!gSplashScreenp) - { + if (!gSplashScreenp) + { #if LL_WINDOWS && !LL_MESA_HEADLESS - gSplashScreenp = new LLSplashScreenWin32; + gSplashScreenp = new LLSplashScreenWin32; #elif LL_DARWIN - gSplashScreenp = new LLSplashScreenMacOSX; + gSplashScreenp = new LLSplashScreenMacOSX; #endif - 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; } // @@ -400,111 +400,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; + LLWindow* new_window; - 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/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index be61e1e16c..a43d281d4c 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,29 +49,29 @@ 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::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) @@ -80,22 +80,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) @@ -110,12 +110,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) @@ -140,7 +140,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) @@ -151,15 +151,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) @@ -176,27 +176,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) @@ -221,7 +221,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 3b18648138..d5681400a1 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,68 +32,68 @@ 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 ~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 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/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 7ea87f5884..df8b2ba5ab 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$ */ @@ -64,7 +64,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; // // LLWindowSDL @@ -83,17 +83,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(); + } } @@ -102,61 +102,61 @@ 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; - - if (!done_setlocale) - { - LL_INFOS() << "Starting GTK Initialization." << LL_ENDL; - maybe_lock_display(); - gtk_disable_setlocale(); - maybe_unlock_display(); - done_setlocale = TRUE; - } - - if (!tried_gtk_init) - { - tried_gtk_init = TRUE; - if (!g_thread_supported ()) g_thread_init (NULL); - maybe_lock_display(); - gtk_is_good = gtk_init_check(NULL, NULL); - maybe_unlock_display(); - if (!gtk_is_good) - LL_WARNS() << "GTK Initialization failed." << LL_ENDL; - } - - if (gtk_is_good && !done_gtk_diag) - { - LL_INFOS() << "GTK Initialized." << LL_ENDL; - LL_INFOS() << "- Compiled against GTK version " - << GTK_MAJOR_VERSION << "." - << GTK_MINOR_VERSION << "." - << GTK_MICRO_VERSION << LL_ENDL; - LL_INFOS() << "- Running against GTK version " - << gtk_major_version << "." - << gtk_minor_version << "." - << gtk_micro_version << LL_ENDL; - maybe_lock_display(); - const gchar* gtk_warning = gtk_check_version( - GTK_MAJOR_VERSION, - GTK_MINOR_VERSION, - GTK_MICRO_VERSION); - maybe_unlock_display(); - if (gtk_warning) - { - LL_WARNS() << "- GTK COMPATIBILITY WARNING: " << - gtk_warning << LL_ENDL; - gtk_is_good = FALSE; - } else { - LL_INFOS() << "- GTK version is good." << LL_ENDL; - } - - done_gtk_diag = TRUE; - } - - return gtk_is_good; + static BOOL done_gtk_diag = FALSE; + static BOOL gtk_is_good = FALSE; + static BOOL done_setlocale = FALSE; + static BOOL tried_gtk_init = FALSE; + + if (!done_setlocale) + { + LL_INFOS() << "Starting GTK Initialization." << LL_ENDL; + maybe_lock_display(); + gtk_disable_setlocale(); + maybe_unlock_display(); + done_setlocale = TRUE; + } + + if (!tried_gtk_init) + { + tried_gtk_init = TRUE; + if (!g_thread_supported ()) g_thread_init (NULL); + maybe_lock_display(); + gtk_is_good = gtk_init_check(NULL, NULL); + maybe_unlock_display(); + if (!gtk_is_good) + LL_WARNS() << "GTK Initialization failed." << LL_ENDL; + } + + if (gtk_is_good && !done_gtk_diag) + { + LL_INFOS() << "GTK Initialized." << LL_ENDL; + LL_INFOS() << "- Compiled against GTK version " + << GTK_MAJOR_VERSION << "." + << GTK_MINOR_VERSION << "." + << GTK_MICRO_VERSION << LL_ENDL; + LL_INFOS() << "- Running against GTK version " + << gtk_major_version << "." + << gtk_minor_version << "." + << gtk_micro_version << LL_ENDL; + maybe_lock_display(); + const gchar* gtk_warning = gtk_check_version( + GTK_MAJOR_VERSION, + GTK_MINOR_VERSION, + GTK_MICRO_VERSION); + maybe_unlock_display(); + if (gtk_warning) + { + LL_WARNS() << "- GTK COMPATIBILITY WARNING: " << + gtk_warning << LL_ENDL; + gtk_is_good = FALSE; + } else { + LL_INFOS() << "- GTK version is good." << LL_ENDL; + } + + done_gtk_diag = TRUE; + } + + return gtk_is_good; } #endif // LL_GTK @@ -165,106 +165,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 LL_X11 @@ -274,520 +274,520 @@ 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'; - } - - // *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; + 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. + + // 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; - - 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; - } - - SDL_version c_sdl_version; - SDL_VERSION(&c_sdl_version); - LL_INFOS() << "Compiled against SDL " - << int(c_sdl_version.major) << "." - << int(c_sdl_version.minor) << "." - << int(c_sdl_version.patch) << LL_ENDL; - const SDL_version *r_sdl_version; - r_sdl_version = SDL_Linked_Version(); - LL_INFOS() << " Running against SDL " - << int(r_sdl_version->major) << "." - << int(r_sdl_version->minor) << "." - << int(r_sdl_version->patch) << LL_ENDL; - - const SDL_VideoInfo *video_info = SDL_GetVideoInfo( ); - if (!video_info) - { - LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; - setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); - return FALSE; - } - - if (video_info->current_h > 0) - { - mOriginalAspectRatio = (float)video_info->current_w / (float)video_info->current_h; - LL_INFOS() << "Original aspect ratio was " << video_info->current_w << ":" << video_info->current_h << "=" << mOriginalAspectRatio << LL_ENDL; - } - - SDL_EnableUNICODE(1); - SDL_WM_SetCaption(mWindowTitle.c_str(), 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_SRCCOLORKEY, - SDL_MapRGB(bmpsurface->format, 0,0,0) ); - SDL_WM_SetIcon(bmpsurface, NULL); - // The SDL examples cheerfully avoid freeing the icon - // surface, but I'm betting that's leaky. - SDL_FreeSurface(bmpsurface); - bmpsurface = NULL; - } - - // note: these SetAttributes make Tom's 9600-on-AMD64 fail to - // get a visual, but it's broken anyway when it does, and without - // these SetAttributes we might easily get an avoidable substandard - // visual to work with on most other machines. - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + //bool glneedsinit = false; + + 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; + } + + SDL_version c_sdl_version; + SDL_VERSION(&c_sdl_version); + LL_INFOS() << "Compiled against SDL " + << int(c_sdl_version.major) << "." + << int(c_sdl_version.minor) << "." + << int(c_sdl_version.patch) << LL_ENDL; + const SDL_version *r_sdl_version; + r_sdl_version = SDL_Linked_Version(); + LL_INFOS() << " Running against SDL " + << int(r_sdl_version->major) << "." + << int(r_sdl_version->minor) << "." + << int(r_sdl_version->patch) << LL_ENDL; + + const SDL_VideoInfo *video_info = SDL_GetVideoInfo( ); + if (!video_info) + { + LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; + setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); + return FALSE; + } + + if (video_info->current_h > 0) + { + mOriginalAspectRatio = (float)video_info->current_w / (float)video_info->current_h; + LL_INFOS() << "Original aspect ratio was " << video_info->current_w << ":" << video_info->current_h << "=" << mOriginalAspectRatio << LL_ENDL; + } + + SDL_EnableUNICODE(1); + SDL_WM_SetCaption(mWindowTitle.c_str(), 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_SRCCOLORKEY, + SDL_MapRGB(bmpsurface->format, 0,0,0) ); + SDL_WM_SetIcon(bmpsurface, NULL); + // The SDL examples cheerfully avoid freeing the icon + // surface, but I'm betting that's leaky. + SDL_FreeSurface(bmpsurface); + bmpsurface = NULL; + } + + // note: these SetAttributes make Tom's 9600-on-AMD64 fail to + // get a visual, but it's broken anyway when it does, and without + // these SetAttributes we might easily get an avoidable substandard + // visual to work with on most other machines. + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24); - // We need stencil support for a few (minor) things. - if (!getenv("LL_GL_NO_STENCIL")) - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + // 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; - - int sdlflags = SDL_OPENGL | SDL_RESIZABLE | SDL_ANYFORMAT; - - 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 (mFullscreen) - { - LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; - - // If the requested width or height is 0, find the best default for the monitor. - if((width == 0) || (height == 0)) - { - // Scan through the list of modes, looking for one which has: - // height between 700 and 800 - // aspect ratio closest to the user's original mode - S32 resolutionCount = 0; - LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); - - if(resolutionList != NULL) - { - F32 closestAspect = 0; - U32 closestHeight = 0; - U32 closestWidth = 0; - int i; - - 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((width == 0) || (height == 0)) - { - // Mode search failed for some reason. Use the old-school default. - width = 1024; - height = 768; - } - - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); - } - - if (mWindow) - { - mFullscreen = TRUE; - mFullscreenWidth = mWindow->w; - mFullscreenHeight = mWindow->h; - 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_SetVideoMode(width, height, bits, sdlflags); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); - } - - if (!mWindow) - { - LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; - setupFailure("Window creation error", "Error", OSMB_OK); - return FALSE; - } - } else if (!mFullscreen && (mWindow != NULL)) - { - LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; - } - - // Detect video memory size. + mFullscreen = fullscreen; + + int sdlflags = SDL_OPENGL | SDL_RESIZABLE | SDL_ANYFORMAT; + + 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 (mFullscreen) + { + LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; + + // If the requested width or height is 0, find the best default for the monitor. + if((width == 0) || (height == 0)) + { + // Scan through the list of modes, looking for one which has: + // height between 700 and 800 + // aspect ratio closest to the user's original mode + S32 resolutionCount = 0; + LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); + + if(resolutionList != NULL) + { + F32 closestAspect = 0; + U32 closestHeight = 0; + U32 closestWidth = 0; + int i; + + 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((width == 0) || (height == 0)) + { + // Mode search failed for some reason. Use the old-school default. + width = 1024; + height = 768; + } + + mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); + if (!mWindow && bits > 16) + { + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); + } + + if (mWindow) + { + mFullscreen = TRUE; + mFullscreenWidth = mWindow->w; + mFullscreenHeight = mWindow->h; + 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_SetVideoMode(width, height, bits, sdlflags); + if (!mWindow && bits > 16) + { + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); + } + + if (!mWindow) + { + LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; + setupFailure("Window creation error", "Error", OSMB_OK); + return FALSE; + } + } else if (!mFullscreen && (mWindow != NULL)) + { + LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; + } + + // Detect video memory size. # if LL_X11 - gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; - if (gGLManager.mVRAM != 0) - { - LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; - } else + gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; + if (gGLManager.mVRAM != 0) + { + LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; + } else # endif // LL_X11 - { - // fallback to letting SDL detect VRAM. - // note: I've not seen SDL's detection ever actually find - // VRAM != 0, but if SDL *does* detect it then that's a bonus. - gGLManager.mVRAM = video_info->video_mem / 1024; - if (gGLManager.mVRAM != 0) - { - LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; - } - } - // If VRAM is not detected, that is handled later - - // *TODO: Now would be an appropriate time to check for some - // explicitly unsupported cards. - //const char* RENDERER = (const char*) glGetString(GL_RENDERER); - - GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; - - glGetIntegerv(GL_RED_BITS, &redBits); - glGetIntegerv(GL_GREEN_BITS, &greenBits); - glGetIntegerv(GL_BLUE_BITS, &blueBits); - glGetIntegerv(GL_ALPHA_BITS, &alphaBits); - glGetIntegerv(GL_DEPTH_BITS, &depthBits); - glGetIntegerv(GL_STENCIL_BITS, &stencilBits); - - LL_INFOS() << "GL buffer:" << LL_ENDL; + { + // fallback to letting SDL detect VRAM. + // note: I've not seen SDL's detection ever actually find + // VRAM != 0, but if SDL *does* detect it then that's a bonus. + gGLManager.mVRAM = video_info->video_mem / 1024; + if (gGLManager.mVRAM != 0) + { + LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; + } + } + // If VRAM is not detected, that is handled later + + // *TODO: Now would be an appropriate time to check for some + // explicitly unsupported cards. + //const char* RENDERER = (const char*) glGetString(GL_RENDERER); + + GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; + + glGetIntegerv(GL_RED_BITS, &redBits); + glGetIntegerv(GL_GREEN_BITS, &greenBits); + glGetIntegerv(GL_BLUE_BITS, &blueBits); + glGetIntegerv(GL_ALPHA_BITS, &alphaBits); + glGetIntegerv(GL_DEPTH_BITS, &depthBits); + glGetIntegerv(GL_STENCIL_BITS, &stencilBits); + + 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) - { - 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; - } + 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) + { + 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; + } #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_GetWMInfo(&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; - } + /* Grab the window manager specific information */ + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if ( SDL_GetWMInfo(&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 - glDisable(GL_MULTISAMPLE_ARB); - - // We need to do this here, once video is init'd - if (-1 == SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, - SDL_DEFAULT_REPEAT_INTERVAL)) - LL_WARNS() << "Couldn't enable key-repeat: " << SDL_GetError() <<LL_ENDL; + //make sure multisampling is disabled by default + glDisable(GL_MULTISAMPLE_ARB); - // 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; } @@ -818,77 +818,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; } @@ -898,7 +898,7 @@ BOOL LLWindowSDL::getSize(LLCoordScreen *size) { size->mX = mWindow->w; size->mY = mWindow->h; - return (TRUE); + return (TRUE); } return (FALSE); @@ -910,7 +910,7 @@ BOOL LLWindowSDL::getSize(LLCoordWindow *size) { size->mX = mWindow->w; size->mY = mWindow->h; - return (TRUE); + return (TRUE); } return (FALSE); @@ -918,94 +918,94 @@ 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_VIDEORESIZE; - event.resize.w = size.mX; - event.resize.h = size.mY; - SDL_PushEvent(&event); // copied into queue + if(mWindow) + { + // Push a resize event onto SDL's queue - we'll handle it + // when it comes out again. + SDL_Event event; + event.type = SDL_VIDEORESIZE; + event.resize.w = size.mX; + event.resize.h = size.mY; + SDL_PushEvent(&event); // copied into queue + + return TRUE; + } - return TRUE; - } - - return FALSE; + return FALSE; } BOOL LLWindowSDL::setSizeImpl(const LLCoordWindow size) { - if(mWindow) - { - // Push a resize event onto SDL's queue - we'll handle it - // when it comes out again. - SDL_Event event; - event.type = SDL_VIDEORESIZE; - event.resize.w = size.mX; - event.resize.h = size.mY; - SDL_PushEvent(&event); // copied into queue - - return TRUE; - } + if(mWindow) + { + // Push a resize event onto SDL's queue - we'll handle it + // when it comes out again. + SDL_Event event; + event.type = SDL_VIDEORESIZE; + event.resize.w = size.mX; + event.resize.h = size.mY; + SDL_PushEvent(&event); // copied into queue + + return TRUE; + } - return FALSE; + return FALSE; } void LLWindowSDL::swapBuffers() { - if (mWindow) - { - SDL_GL_SwapBuffers(); - } + if (mWindow) + { + SDL_GL_SwapBuffers(); + } } 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(); + //CGDisplayRestoreColorSyncSettings(); SDL_SetGamma(1.0f, 1.0f, 1.0f); - return true; + return true; } BOOL LLWindowSDL::setGamma(const F32 gamma) { - mGamma = gamma; - if (mGamma == 0) mGamma = 0.1f; - mGamma = 1/mGamma; - SDL_SetGamma(mGamma, mGamma, mGamma); - return true; + mGamma = gamma; + if (mGamma == 0) mGamma = 0.1f; + mGamma = 1/mGamma; + SDL_SetGamma(mGamma, mGamma, mGamma); + return true; } BOOL LLWindowSDL::isCursorHidden() { - return mCursorHidden; + return mCursorHidden; } @@ -1019,110 +1019,110 @@ 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 } 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. - SDL_WarpMouse(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. + SDL_WarpMouse(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; } @@ -1130,67 +1130,67 @@ F32 LLWindowSDL::getPixelAspectRatio() // 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; - - 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_WM_ToggleFullScreen(mWindow); - } - } - } + 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_WM_ToggleFullScreen(mWindow); + } + } + } #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_WM_ToggleFullScreen(mWindow); - } - } + if (mFullscreen) + { + // need to restore fullscreen mode after dialog - only works + // in X11 + if (running_x11 && mWindow) + { + SDL_WM_ToggleFullScreen(mWindow); + } + } } @@ -1198,45 +1198,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; + 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(); + 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; + 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(); - } + 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 } @@ -1244,129 +1244,129 @@ 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 FALSE; // unsupported + return FALSE; // unsupported } BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) { - return FALSE; // unsupported + return FALSE; // unsupported } BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) { - return FALSE; // unsupported + return FALSE; // unsupported } 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); if ( (modes != NULL) && (modes != ((SDL_Rect **) -1)) ) @@ -1398,10 +1398,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) @@ -1409,10 +1409,10 @@ BOOL LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to) if (!to) return FALSE; - to->mX = from.mX; - to->mY = mWindow->h - from.mY - 1; + to->mX = from.mX; + to->mY = mWindow->h - from.mY - 1; - return TRUE; + return TRUE; } BOOL LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to) @@ -1420,46 +1420,46 @@ BOOL LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to) if (!to) return FALSE; - to->mX = from.mX; - to->mY = mWindow->h - from.mY - 1; + to->mX = from.mX; + to->mY = mWindow->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)); } @@ -1467,226 +1467,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. - - if (capture) - mReallyCapturedCount = 1; - else - mReallyCapturedCount = 0; - - SDL_GrabMode wantmode, newmode; - if (mReallyCapturedCount <= 0) // uncapture - { - wantmode = SDL_GRAB_OFF; - } else // capture - { - wantmode = SDL_GRAB_ON; - } - - if (mReallyCapturedCount < 0) // yuck, imbalance. - { - mReallyCapturedCount = 0; - LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL; - } - - if (!mFullscreen) /* only bother if we're windowed anyway */ - { + // 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_GrabMode wantmode, newmode; + if (mReallyCapturedCount <= 0) // uncapture + { + wantmode = SDL_GRAB_OFF; + } else // capture + { + wantmode = SDL_GRAB_ON; + } + + 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_GRAB_ON) - { - //LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL; - //newmode = SDL_WM_GrabInput(wantmode); - maybe_lock_display(); - result = XGrabPointer(mSDL_Display, mSDL_XWindowID, - True, 0, GrabModeAsync, - GrabModeAsync, - None, None, CurrentTime); - maybe_unlock_display(); - if (GrabSuccess == result) - newmode = SDL_GRAB_ON; - else - newmode = SDL_GRAB_OFF; - } else if (wantmode == SDL_GRAB_OFF) - { - //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; - newmode = SDL_GRAB_OFF; - //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF); - - maybe_lock_display(); - XUngrabPointer(mSDL_Display, CurrentTime); - // Make sure the ungrab happens RIGHT NOW. - XSync(mSDL_Display, False); - maybe_unlock_display(); - } else - { - newmode = SDL_GRAB_QUERY; // neutral - } - } else // not actually running on X11, for some reason - newmode = wantmode; + 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_GRAB_ON) + { + //LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL; + //newmode = SDL_WM_GrabInput(wantmode); + maybe_lock_display(); + result = XGrabPointer(mSDL_Display, mSDL_XWindowID, + True, 0, GrabModeAsync, + GrabModeAsync, + None, None, CurrentTime); + maybe_unlock_display(); + if (GrabSuccess == result) + newmode = SDL_GRAB_ON; + else + newmode = SDL_GRAB_OFF; + } else if (wantmode == SDL_GRAB_OFF) + { + //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; + newmode = SDL_GRAB_OFF; + //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF); + + maybe_lock_display(); + XUngrabPointer(mSDL_Display, CurrentTime); + // Make sure the ungrab happens RIGHT NOW. + XSync(mSDL_Display, False); + maybe_unlock_display(); + } else + { + newmode = SDL_GRAB_QUERY; // neutral + } + } else // not actually running on X11, for some reason + newmode = wantmode; #endif // LL_X11 - } else { - // pretend we got what we wanted, when really we don't care. - newmode = wantmode; - } - - // return boolean success for whether we ended up in the desired state - return (capture && SDL_GRAB_ON==newmode) || - (!capture && SDL_GRAB_OFF==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_GRAB_ON==newmode) || + (!capture && SDL_GRAB_OFF==newmode); } U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey 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; - } - - if (gain) - mGrabbyKeyFlags |= mask; - else - mGrabbyKeyFlags &= ~mask; - - //LL_INFOS() << "mGrabbyKeyFlags=" << mGrabbyKeyFlags << LL_ENDL; - - /* 0 means we don't need to mousegrab, otherwise grab. */ - return mGrabbyKeyFlags; + /* 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; + + //LL_INFOS() << "mGrabbyKeyFlags=" << mGrabbyKeyFlags << LL_ENDL; + + /* 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; - - 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_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; + // 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; + + 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; + } + } + + 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 } @@ -1695,37 +1695,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(); } } @@ -1748,38 +1748,38 @@ 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; - mKeyVirtualKey = event.key.keysym.unicode; - 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.unicode) - { - handleUnicodeUTF16(event.key.keysym.unicode, - gKeyboard->currentMask(FALSE)); - } + mKeyScanCode = event.key.keysym.scancode; + mKeyVirtualKey = event.key.keysym.unicode; + 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.unicode) + { + handleUnicodeUTF16(event.key.keysym.unicode, + gKeyboard->currentMask(FALSE)); + } break; case SDL_KEYUP: - mKeyScanCode = event.key.keysym.scancode; - mKeyVirtualKey = event.key.keysym.unicode; - mKeyModifiers = event.key.keysym.mod; + mKeyScanCode = event.key.keysym.scancode; + mKeyVirtualKey = event.key.keysym.unicode; + 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: { @@ -1787,7 +1787,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... { @@ -1799,7 +1799,7 @@ void LLWindowSDL::gatherInput() if (++leftClick >= 2) { leftClick = 0; - isDoubleClick = true; + isDoubleClick = true; } } lastLeftDown = now; @@ -1814,7 +1814,7 @@ void LLWindowSDL::gatherInput() if (++rightClick >= 2) { rightClick = 0; - isDoubleClick = true; + isDoubleClick = true; } } lastRightDown = now; @@ -1823,24 +1823,24 @@ 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); + } else if (event.button.button == 4) // mousewheel up...thanks to X11 for making SDL consider these "buttons". - mCallbacks->handleScrollWheel(this, -1); + mCallbacks->handleScrollWheel(this, -1); else if (event.button.button == 5) // mousewheel down...thanks to X11 for making SDL consider these "buttons". - mCallbacks->handleScrollWheel(this, 1); + mCallbacks->handleScrollWheel(this, 1); break; } @@ -1850,361 +1850,361 @@ 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; } case SDL_VIDEOEXPOSE: // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing! - mCallbacks->handlePaint(this, 0, 0, mWindow->w, mWindow->h); + mCallbacks->handlePaint(this, 0, 0, mWindow->w, mWindow->h); break; case SDL_VIDEORESIZE: // *FIX: handle this? { - LL_INFOS() << "Handling a resize event: " << event.resize.w << - "x" << event.resize.h << LL_ENDL; - - S32 width = llmax(event.resize.w, (S32)mMinWindowWidth); - S32 height = llmax(event.resize.h, (S32)mMinWindowHeight); - - // *FIX: I'm not sure this is necessary! - mWindow = SDL_SetVideoMode(width, height, 32, mSDLFlags); - if (!mWindow) - { - // *FIX: More informative dialog? - LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; - if(mCallbacks->handleCloseRequest(this)) - { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL - } + LL_INFOS() << "Handling a resize event: " << event.resize.w << + "x" << event.resize.h << LL_ENDL; + + S32 width = llmax(event.resize.w, (S32)mMinWindowWidth); + S32 height = llmax(event.resize.h, (S32)mMinWindowHeight); + + // *FIX: I'm not sure this is necessary! + mWindow = SDL_SetVideoMode(width, height, 32, mSDLFlags); + if (!mWindow) + { + // *FIX: More informative dialog? + LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; + if(mCallbacks->handleCloseRequest(this)) + { + // Get the app to initiate cleanup. + mCallbacks->handleQuit(this); + // The app is responsible for calling destroyWindow when done with GL + } 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; - - // 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; + 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; + } + + return sdlcursor; } void LLWindowSDL::updateCursor() { - if (ATIbug) { - // cursor-updating is very flaky when this bug is - // present; do nothing. - return; - } - - if (mCurrentCursor != mNextCursor) - { - if (mNextCursor < UI_CURSOR_COUNT) - { - 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 (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; + } } 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; + } } @@ -2237,119 +2237,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; - - 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()); + S32 rtn = OSBTN_CANCEL; + + 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 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_type_hint(GTK_WINDOW(win), - GDK_WINDOW_TYPE_HINT_DIALOG); - - if (!caption.empty()) - gtk_window_set_title(GTK_WINDOW(win), caption.c_str()); - - gint response = GTK_RESPONSE_NONE; - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); - - // we should be able to use a gtk_dialog_run(), but it's - // apparently not written to exist in a world without a higher - // gtk_main(), so we manage its signal/destruction outselves. - gtk_widget_show_all (win); - gtk_main(); - - //LL_INFOS() << "response: " << response << LL_ENDL; - switch (response) - { - case GTK_RESPONSE_OK: rtn = OSBTN_OK; break; - case GTK_RESPONSE_YES: rtn = OSBTN_YES; break; - case GTK_RESPONSE_NO: rtn = OSBTN_NO; break; - case GTK_RESPONSE_APPLY: rtn = OSBTN_OK; break; - case GTK_RESPONSE_NONE: - case GTK_RESPONSE_CANCEL: - case GTK_RESPONSE_CLOSE: - case GTK_RESPONSE_DELETE_EVENT: - default: rtn = OSBTN_CANCEL; - } - } - else - { - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - LL_INFOS() << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << LL_ENDL; - rtn = OSBTN_OK; - } - - if(gWindowImplementation != NULL) - gWindowImplementation->afterDialog(); - - return rtn; + gtk_window_set_position(GTK_WINDOW(win), + GTK_WIN_POS_CENTER_ON_PARENT); + + gtk_window_set_type_hint(GTK_WINDOW(win), + GDK_WINDOW_TYPE_HINT_DIALOG); + + if (!caption.empty()) + gtk_window_set_title(GTK_WINDOW(win), caption.c_str()); + + gint response = GTK_RESPONSE_NONE; + g_signal_connect (win, + "response", + G_CALLBACK (response_callback), + &response); + + // we should be able to use a gtk_dialog_run(), but it's + // apparently not written to exist in a world without a higher + // gtk_main(), so we manage its signal/destruction outselves. + gtk_widget_show_all (win); + gtk_main(); + + //LL_INFOS() << "response: " << response << LL_ENDL; + switch (response) + { + case GTK_RESPONSE_OK: rtn = OSBTN_OK; break; + case GTK_RESPONSE_YES: rtn = OSBTN_YES; break; + case GTK_RESPONSE_NO: rtn = OSBTN_NO; break; + case GTK_RESPONSE_APPLY: rtn = OSBTN_OK; break; + case GTK_RESPONSE_NONE: + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_CLOSE: + case GTK_RESPONSE_DELETE_EVENT: + default: rtn = OSBTN_CANCEL; + } + } + else + { + LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; + LL_INFOS() << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << LL_ENDL; + rtn = OSBTN_OK; + } + + if(gWindowImplementation != NULL) + gWindowImplementation->afterDialog(); + + 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); } @@ -2361,25 +2361,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; } @@ -2387,85 +2387,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; - } - } - - afterDialog(); - - return rtn; + GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel); + + GdkColor color, orig_color; + orig_color.pixel = 0; + orig_color.red = guint16(65535 * *r); + orig_color.green= guint16(65535 * *g); + orig_color.blue = guint16(65535 * *b); + color = orig_color; + + gtk_color_selection_set_previous_color (colorsel, &color); + gtk_color_selection_set_current_color (colorsel, &color); + gtk_color_selection_set_has_palette (colorsel, TRUE); + gtk_color_selection_set_has_opacity_control(colorsel, FALSE); + + gint response = GTK_RESPONSE_NONE; + g_signal_connect (win, + "response", + G_CALLBACK (response_callback), + &response); + + g_signal_connect (G_OBJECT (colorsel), "color_changed", + G_CALLBACK (color_changed_callback), + &color); + + gtk_window_set_modal(GTK_WINDOW(win), TRUE); + gtk_widget_show_all(win); + // hide the help button - we don't service it. + gtk_widget_hide(GTK_COLOR_SELECTION_DIALOG(win)->help_button); + gtk_main(); + + if (response == GTK_RESPONSE_OK && + (orig_color.red != color.red + || orig_color.green != color.green + || orig_color.blue != color.blue) ) + { + *r = color.red / 65535.0f; + *g = color.green / 65535.0f; + *b = color.blue / 65535.0f; + rtn = TRUE; + } + } + + afterDialog(); + + return rtn; } #else S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type) { - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - return 0; + LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; + return 0; } BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) { - return (FALSE); + return (FALSE); } #endif // LL_GTK @@ -2474,31 +2474,31 @@ BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) // 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 @@ -2506,192 +2506,192 @@ void exec_cmd(const std::string& cmd, const std::string& arg) // Must begin with protocol identifier. void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) { - bool found = false; - S32 i; - for (i = 0; i < gURLProtocolWhitelistCount; i++) - { - if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos) - { - found = true; - break; - } - } - - if (!found) - { - 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; - + 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; + } + + LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; + #if LL_LINUX # 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; - cmd = gDirUtilp->getAppRODataDir(); - cmd += gDirUtilp->getDirDelimiter(); - cmd += "etc"; - cmd += gDirUtilp->getDirDelimiter(); - cmd += "launch_url.sh"; - arg = escaped_url; - exec_cmd(cmd, arg); + std::string cmd, arg; + cmd = gDirUtilp->getAppRODataDir(); + cmd += gDirUtilp->getDirDelimiter(); + cmd += "etc"; + cmd += gDirUtilp->getDirDelimiter(); + cmd += "launch_url.sh"; + arg = escaped_url; + exec_cmd(cmd, arg); #endif // LL_LINUX - LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; + 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); - - 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); - } - - 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; - - rtns.push_back(final_fallback); - return rtns; + // 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; + } + + 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); + } + + 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; } #endif // LL_SDL diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 7193e6f45a..e96fce92f5 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$ */ @@ -49,181 +49,181 @@ class LLWindowSDL : public LLWindow { public: - /*virtual*/ void show(); - /*virtual*/ void hide(); - /*virtual*/ void close(); - /*virtual*/ BOOL getVisible(); - /*virtual*/ BOOL getMinimized(); - /*virtual*/ BOOL getMaximized(); - /*virtual*/ BOOL maximize(); - /*virtual*/ void minimize(); - /*virtual*/ void restore(); - /*virtual*/ BOOL getFullscreen(); - /*virtual*/ BOOL getPosition(LLCoordScreen *position); - /*virtual*/ BOOL getSize(LLCoordScreen *size); - /*virtual*/ BOOL getSize(LLCoordWindow *size); - /*virtual*/ BOOL setPosition(LLCoordScreen position); - /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); - /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); - /*virtual*/ void showCursor(); - /*virtual*/ void hideCursor(); - /*virtual*/ void showCursorFromMouseMove(); - /*virtual*/ void hideCursorUntilMouseMove(); - /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void updateCursor(); - /*virtual*/ void captureMouse(); - /*virtual*/ void releaseMouse(); - /*virtual*/ void setMouseClipping( BOOL b ); - /*virtual*/ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - - /*virtual*/ BOOL isClipboardTextAvailable(); - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); - /*virtual*/ BOOL copyTextToClipboard(const LLWString & src); - - /*virtual*/ BOOL isPrimaryTextAvailable(); - /*virtual*/ BOOL pasteTextFromPrimary(LLWString &dst); - /*virtual*/ BOOL copyTextToPrimary(const LLWString & src); - - /*virtual*/ void flashIcon(F32 seconds); - /*virtual*/ F32 getGamma(); - /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma - /*virtual*/ U32 getFSAASamples(); - /*virtual*/ void setFSAASamples(const U32 samples); - /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) - /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void processMiscNativeEvents(); - /*virtual*/ void gatherInput(); - /*virtual*/ void swapBuffers(); - /*virtual*/ void restoreGLContext() {}; - - /*virtual*/ void delayInputProcessing() { }; - - // 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 beforeDialog(); - /*virtual*/ void afterDialog(); - - /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b); - - /*virtual*/ void *getPlatformWindow(); - /*virtual*/ void bringToFront(); - - /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); - - 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. + /*virtual*/ void show(); + /*virtual*/ void hide(); + /*virtual*/ void close(); + /*virtual*/ BOOL getVisible(); + /*virtual*/ BOOL getMinimized(); + /*virtual*/ BOOL getMaximized(); + /*virtual*/ BOOL maximize(); + /*virtual*/ void minimize(); + /*virtual*/ void restore(); + /*virtual*/ BOOL getFullscreen(); + /*virtual*/ BOOL getPosition(LLCoordScreen *position); + /*virtual*/ BOOL getSize(LLCoordScreen *size); + /*virtual*/ BOOL getSize(LLCoordWindow *size); + /*virtual*/ BOOL setPosition(LLCoordScreen position); + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); + /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); + /*virtual*/ void showCursor(); + /*virtual*/ void hideCursor(); + /*virtual*/ void showCursorFromMouseMove(); + /*virtual*/ void hideCursorUntilMouseMove(); + /*virtual*/ BOOL isCursorHidden(); + /*virtual*/ void updateCursor(); + /*virtual*/ void captureMouse(); + /*virtual*/ void releaseMouse(); + /*virtual*/ void setMouseClipping( BOOL b ); + /*virtual*/ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); + + /*virtual*/ BOOL isClipboardTextAvailable(); + /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); + /*virtual*/ BOOL copyTextToClipboard(const LLWString & src); + + /*virtual*/ BOOL isPrimaryTextAvailable(); + /*virtual*/ BOOL pasteTextFromPrimary(LLWString &dst); + /*virtual*/ BOOL copyTextToPrimary(const LLWString & src); + + /*virtual*/ void flashIcon(F32 seconds); + /*virtual*/ F32 getGamma(); + /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma + /*virtual*/ U32 getFSAASamples(); + /*virtual*/ void setFSAASamples(const U32 samples); + /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) + /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } + /*virtual*/ void processMiscNativeEvents(); + /*virtual*/ void gatherInput(); + /*virtual*/ void swapBuffers(); + /*virtual*/ void restoreGLContext() {}; + + /*virtual*/ void delayInputProcessing() { }; + + // 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 beforeDialog(); + /*virtual*/ void afterDialog(); + + /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b); + + /*virtual*/ void *getPlatformWindow(); + /*virtual*/ void bringToFront(); + + /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); + + 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 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(); - /*virtual*/ BOOL isValid(); - /*virtual*/ LLSD getNativeKeyData(); + /*virtual*/ BOOL isValid(); + /*virtual*/ LLSD getNativeKeyData(); - 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(SDLKey keysym, BOOL gain); - BOOL SDLReallyCaptureInput(BOOL capture); - - // - // Platform specific variables - // - U32 mGrabbyKeyFlags; - int mReallyCapturedCount; - SDL_Surface * 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(SDLKey keysym, BOOL gain); + BOOL SDLReallyCaptureInput(BOOL capture); + + // + // Platform specific variables + // + U32 mGrabbyKeyFlags; + int mReallyCapturedCount; + SDL_Surface * 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; - SDLMod mKeyModifiers; + SDLMod 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); |