Imported existing code
This commit is contained in:
161
indra/llwindow/CMakeLists.txt
Normal file
161
indra/llwindow/CMakeLists.txt
Normal file
@@ -0,0 +1,161 @@
|
||||
# -*- cmake -*-
|
||||
#
|
||||
# Compared to other libraries, compiling this one is a mess. The
|
||||
# reason is that we have several source files that have two different
|
||||
# sets of behaviour, depending on whether they're intended to be part
|
||||
# of the viewer or the map server.
|
||||
#
|
||||
# Unfortunately, the affected code is a rat's nest of #ifdefs, so it's
|
||||
# easier to play compilation tricks than to actually fix the problem.
|
||||
|
||||
project(llwindow)
|
||||
|
||||
include(00-Common)
|
||||
include(DirectX)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLMath)
|
||||
include(LLRender)
|
||||
include(LLVFS)
|
||||
include(LLWindow)
|
||||
include(LLXML)
|
||||
include(UI)
|
||||
|
||||
include_directories(
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLIMAGE_INCLUDE_DIRS}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLRENDER_INCLUDE_DIRS}
|
||||
${LLVFS_INCLUDE_DIRS}
|
||||
${LLWINDOW_INCLUDE_DIRS}
|
||||
${LLXML_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(llwindow_SOURCE_FILES
|
||||
llkeyboard.cpp
|
||||
llwindowheadless.cpp
|
||||
)
|
||||
|
||||
set(llwindows_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
llkeyboard.h
|
||||
llwindowheadless.h
|
||||
)
|
||||
|
||||
set(viewer_SOURCE_FILES
|
||||
llwindow.cpp
|
||||
)
|
||||
|
||||
set(viewer_HEADER_FILES
|
||||
llwindow.h
|
||||
llpreeditor.h
|
||||
llmousehandler.h
|
||||
)
|
||||
|
||||
# Libraries on which this library depends, needed for Linux builds
|
||||
# Sort by high-level to low-level
|
||||
set(llwindow_LINK_LIBRARIES
|
||||
${UI_LIBRARIES} # for GTK
|
||||
${SDL_LIBRARY}
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
list(APPEND llwindow_SOURCE_FILES
|
||||
llkeyboardmacosx.cpp
|
||||
llwindowmacosx.cpp
|
||||
llwindowmacosx-objc.mm
|
||||
)
|
||||
list(APPEND llwindow_HEADER_FILES
|
||||
llkeyboardmacosx.h
|
||||
llwindowmacosx.h
|
||||
llwindowmacosx-objc.h
|
||||
)
|
||||
|
||||
# We use a bunch of deprecated system APIs.
|
||||
set_source_files_properties(
|
||||
llkeyboardmacosx.cpp
|
||||
llwindowmacosx.cpp
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-Wno-deprecated-declarations -fpascal-strings"
|
||||
)
|
||||
endif (DARWIN)
|
||||
|
||||
if (LINUX)
|
||||
list(APPEND viewer_SOURCE_FILES
|
||||
llkeyboardsdl.cpp
|
||||
llwindowsdl.cpp
|
||||
)
|
||||
list(APPEND viewer_HEADER_FILES
|
||||
llkeyboardsdl.h
|
||||
llwindowsdl.h
|
||||
)
|
||||
endif (LINUX)
|
||||
|
||||
if (WINDOWS)
|
||||
list(APPEND llwindow_SOURCE_FILES
|
||||
llwindowwin32.cpp
|
||||
lldxhardware.cpp
|
||||
llkeyboardwin32.cpp
|
||||
)
|
||||
list(APPEND llwindow_HEADER_FILES
|
||||
llwindowwin32.h
|
||||
lldxhardware.h
|
||||
llkeyboardwin32.h
|
||||
)
|
||||
list(APPEND llwindow_LINK_LIBRARIES
|
||||
comdlg32 # Common Dialogs for ChooseColor
|
||||
)
|
||||
endif (WINDOWS)
|
||||
|
||||
if (SOLARIS)
|
||||
list(APPEND llwindow_SOURCE_FILES
|
||||
llwindowsolaris.cpp
|
||||
)
|
||||
list(APPEND llwindow_HEADER_FILES
|
||||
llwindowsolaris.h
|
||||
)
|
||||
endif (SOLARIS)
|
||||
|
||||
set_source_files_properties(${llwindow_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
if (SERVER AND NOT WINDOWS AND NOT DARWIN)
|
||||
set(server_SOURCE_FILES
|
||||
llwindowmesaheadless.cpp
|
||||
)
|
||||
set(server_HEADER_FILES
|
||||
llwindowmesaheadless.h
|
||||
)
|
||||
copy_server_sources(
|
||||
llwindow
|
||||
)
|
||||
|
||||
|
||||
set_source_files_properties(
|
||||
${server_SOURCE_FILES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
|
||||
)
|
||||
add_library (llwindowheadless
|
||||
${llwindow_SOURCE_FILES}
|
||||
${server_SOURCE_FILES}
|
||||
)
|
||||
add_dependencies(llwindowheadless prepare)
|
||||
# *TODO: This should probably have target_link_libraries
|
||||
endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
|
||||
|
||||
if (llwindow_HEADER_FILES)
|
||||
list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})
|
||||
endif (llwindow_HEADER_FILES)
|
||||
list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
|
||||
|
||||
if (VIEWER)
|
||||
add_library (llwindow
|
||||
${llwindow_SOURCE_FILES}
|
||||
${viewer_SOURCE_FILES}
|
||||
)
|
||||
add_dependencies(llwindow prepare)
|
||||
target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
|
||||
endif (VIEWER)
|
||||
|
||||
207
indra/llwindow/GL/glh_extensions.h
Normal file
207
indra/llwindow/GL/glh_extensions.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* glh_extensions.h
|
||||
* From nVidia Corporation, downloaded 2006-12-18 from:
|
||||
* http://developer.nvidia.com/attach/8196
|
||||
* ("NVParse Library with Source (.zip) (2390 KB)")
|
||||
*
|
||||
* License (quoted from license_info.txt in aforementioned file):
|
||||
* "The files bison.exe, bison.simple, and flex.exe are covered by
|
||||
* the GPL. All other files in this distribution can be used however
|
||||
* you want."
|
||||
*/
|
||||
|
||||
#ifndef GLH_EXTENSIONS
|
||||
#define GLH_EXTENSIONS
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include "GL/wglext.h"
|
||||
#endif
|
||||
|
||||
#define CHECK_MEMORY(ptr) \
|
||||
if (NULL == ptr) { \
|
||||
printf("Error allocating memory in file %s, line %d\n", __FILE__, __LINE__); \
|
||||
exit(-1); \
|
||||
}
|
||||
|
||||
#ifdef GLH_EXT_SINGLE_FILE
|
||||
# define GLH_EXTENSIONS_SINGLE_FILE // have to do this because glh_genext.h unsets GLH_EXT_SINGLE_FILE
|
||||
#endif
|
||||
|
||||
#include "glh_genext.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef GLH_EXTENSIONS_SINGLE_FILE
|
||||
|
||||
class GLHExts
|
||||
{
|
||||
public:
|
||||
GLHExts()
|
||||
{
|
||||
mSysExts = NULL;
|
||||
// mUnsupportedExts = NULL;
|
||||
}
|
||||
~GLHExts()
|
||||
{
|
||||
if (mSysExts)
|
||||
{
|
||||
free(mSysExts);
|
||||
}
|
||||
// if (mUnsupportedExts)
|
||||
// {
|
||||
// free(mUnsupportedExts);
|
||||
// }
|
||||
}
|
||||
char *mSysExts;
|
||||
// char *mUnsupportedExts;
|
||||
};
|
||||
|
||||
GLHExts gGLHExts;
|
||||
|
||||
static int ExtensionExists(const char* extName, const char* sysExts)
|
||||
{
|
||||
char *padExtName = (char*)malloc(strlen(extName) + 2);
|
||||
strcat(strcpy(padExtName, extName), " ");
|
||||
|
||||
if (0 == strcmp(extName, "GL_VERSION_1_2")) {
|
||||
const char *version = (const char*)glGetString(GL_VERSION);
|
||||
if (strstr(version, "1.0") == version || strstr(version, "1.1") == version) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (strstr(sysExts, padExtName)) {
|
||||
free(padExtName);
|
||||
return TRUE;
|
||||
} else {
|
||||
free(padExtName);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* EatWhiteSpace(const char *str)
|
||||
{
|
||||
for (; *str && (' ' == *str || '\t' == *str || '\n' == *str); str++);
|
||||
return str;
|
||||
}
|
||||
|
||||
static const char* EatNonWhiteSpace(const char *str)
|
||||
{
|
||||
for (; *str && (' ' != *str && '\t' != *str && '\n' != *str); str++);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
int glh_init_extensions(const char *origReqExts)
|
||||
{
|
||||
// Length of requested extensions string
|
||||
unsigned reqExtsLen;
|
||||
char *reqExts;
|
||||
// Ptr for individual extensions within reqExts
|
||||
char *reqExt;
|
||||
int success = TRUE;
|
||||
|
||||
// build space-padded extension string
|
||||
if (NULL == gGLHExts.mSysExts) {
|
||||
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
int sysExtsLen = (int)strlen(extensions);
|
||||
const char *winsys_extensions = 0;
|
||||
int winsysExtsLen = 0;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
|
||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if(wglGetExtensionsStringARB)
|
||||
{
|
||||
winsys_extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
|
||||
winsysExtsLen = (S32)strlen(winsys_extensions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Add 2 bytes, one for padding space, one for terminating NULL
|
||||
gGLHExts.mSysExts = (char*)malloc(sysExtsLen + winsysExtsLen + 3);
|
||||
CHECK_MEMORY(gGLHExts.mSysExts);
|
||||
strcpy(gGLHExts.mSysExts, extensions);
|
||||
gGLHExts.mSysExts[sysExtsLen] = ' ';
|
||||
gGLHExts.mSysExts[sysExtsLen + 1] = 0;
|
||||
if (winsysExtsLen)
|
||||
{
|
||||
strcat(gGLHExts.mSysExts, winsys_extensions);
|
||||
}
|
||||
gGLHExts.mSysExts[sysExtsLen + 1 + winsysExtsLen] = ' ';
|
||||
gGLHExts.mSysExts[sysExtsLen + 1 + winsysExtsLen + 1] = 0;
|
||||
}
|
||||
|
||||
if (NULL == origReqExts)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
reqExts = strdup(origReqExts);
|
||||
reqExtsLen = (S32)strlen(reqExts);
|
||||
/*
|
||||
if (NULL == gGLHExts.mUnsupportedExts)
|
||||
{
|
||||
gGLHExts.mUnsupportedExts = (char*)malloc(reqExtsLen + 1);
|
||||
}
|
||||
else if (reqExtsLen > strlen(gGLHExts.mUnsupportedExts))
|
||||
{
|
||||
gGLHExts.mUnsupportedExts = (char*)realloc(gGLHExts.mUnsupportedExts, reqExtsLen + 1);
|
||||
}
|
||||
CHECK_MEMORY(gGLHExts.mUnsupportedExts);
|
||||
*gGLHExts.mUnsupportedExts = 0;
|
||||
*/
|
||||
|
||||
// Parse requested extension list
|
||||
for (reqExt = reqExts;
|
||||
(reqExt = (char*)EatWhiteSpace(reqExt)) && *reqExt;
|
||||
reqExt = (char*)EatNonWhiteSpace(reqExt))
|
||||
{
|
||||
char *extEnd = (char*)EatNonWhiteSpace(reqExt);
|
||||
char saveChar = *extEnd;
|
||||
*extEnd = (char)0;
|
||||
|
||||
if (!ExtensionExists(reqExt, gGLHExts.mSysExts) ||
|
||||
!glh_init_extension(reqExt)) {
|
||||
/*
|
||||
// add reqExt to end of unsupportedExts
|
||||
strcat(gGLHExts.mUnsupportedExts, reqExt);
|
||||
strcat(gGLHExts.mUnsupportedExts, " ");
|
||||
*/
|
||||
success = FALSE;
|
||||
}
|
||||
*extEnd = saveChar;
|
||||
}
|
||||
free(reqExts);
|
||||
return success;
|
||||
}
|
||||
|
||||
const char* glh_get_unsupported_extensions()
|
||||
{
|
||||
return "";
|
||||
// return (const char*)gGLHExts.mUnsupportedExts;
|
||||
}
|
||||
|
||||
#else
|
||||
int glh_init_extensions(const char *origReqExts);
|
||||
const char* glh_get_unsupported_extensions();
|
||||
#endif /* GLH_EXT_SINGLE_FILE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GLH_EXTENSIONS */
|
||||
1671
indra/llwindow/GL/glh_genext.h
Normal file
1671
indra/llwindow/GL/glh_genext.h
Normal file
File diff suppressed because it is too large
Load Diff
1621
indra/llwindow/glh/glh_linear.h
Executable file
1621
indra/llwindow/glh/glh_linear.h
Executable file
File diff suppressed because it is too large
Load Diff
675
indra/llwindow/lldxhardware.cpp
Normal file
675
indra/llwindow/lldxhardware.cpp
Normal file
@@ -0,0 +1,675 @@
|
||||
/**
|
||||
* @file lldxhardware.cpp
|
||||
* @brief LLDXHardware implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
|
||||
// Culled from some Microsoft sample code
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#define INITGUID
|
||||
#include <dxdiag.h>
|
||||
#undef INITGUID
|
||||
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#include "lldxhardware.h"
|
||||
#include "llerror.h"
|
||||
|
||||
#include "llstring.h"
|
||||
#include "llstl.h"
|
||||
|
||||
void (*gWriteDebug)(const char* msg) = NULL;
|
||||
LLDXHardware gDXHardware;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines, and constants
|
||||
//-----------------------------------------------------------------------------
|
||||
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
||||
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName)
|
||||
{
|
||||
HRESULT hr;
|
||||
VARIANT var;
|
||||
WCHAR wszPropValue[256];
|
||||
|
||||
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, 255 ); /* Flawfinder: ignore */
|
||||
wszPropValue[255] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Clear the variant (this is needed to free BSTR memory)
|
||||
VariantClear( &var );
|
||||
|
||||
return utf16str_to_utf8str(wszPropValue);
|
||||
}
|
||||
|
||||
|
||||
LLVersion::LLVersion()
|
||||
{
|
||||
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)
|
||||
{
|
||||
//llwarns << "Potentially bogus version string!" << version_string << llendl;
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
llinfos << mFilepath << llendl;
|
||||
llinfos << mName << llendl;
|
||||
llinfos << mVersionString << llendl;
|
||||
llinfos << mDateString << llendl;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
LLDXDevice::~LLDXDevice()
|
||||
{
|
||||
for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer());
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
llinfos << llendl;
|
||||
llinfos << "DeviceName:" << mName << llendl;
|
||||
llinfos << "PCIString:" << mPCIString << llendl;
|
||||
llinfos << "Drivers" << llendl;
|
||||
llinfos << "-------" << llendl;
|
||||
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;
|
||||
}
|
||||
|
||||
LLDXHardware::LLDXHardware()
|
||||
{
|
||||
mVRAM = 0;
|
||||
gWriteDebug = NULL;
|
||||
}
|
||||
|
||||
void LLDXHardware::cleanup()
|
||||
{
|
||||
// for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer());
|
||||
}
|
||||
|
||||
/*
|
||||
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 "";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
||||
BOOL LLDXHardware::getInfo(BOOL vram_only)
|
||||
{
|
||||
LLTimer hw_timer;
|
||||
BOOL ok = FALSE;
|
||||
HRESULT hr;
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
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;
|
||||
|
||||
// CoCreate a IDxDiagProvider*
|
||||
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 (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.
|
||||
DXDIAG_INIT_PARAMS dx_diag_init_params;
|
||||
ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS));
|
||||
|
||||
dx_diag_init_params.dwSize = sizeof(DXDIAG_INIT_PARAMS);
|
||||
dx_diag_init_params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
|
||||
dx_diag_init_params.bAllowWHQLChecks = TRUE;
|
||||
dx_diag_init_params.pReserved = NULL;
|
||||
|
||||
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;
|
||||
hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp );
|
||||
if(FAILED(hr) || !dx_diag_rootp)
|
||||
{
|
||||
goto LCleanup;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
goto LCleanup;
|
||||
}
|
||||
|
||||
// Get device 0
|
||||
LL_DEBUGS("AppInit") << "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");
|
||||
|
||||
// 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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// 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);
|
||||
SAFE_RELEASE(dx_diag_rootp);
|
||||
SAFE_RELEASE(dx_diag_providerp);
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
LLSD LLDXHardware::getDisplayInfo()
|
||||
{
|
||||
LLTimer hw_timer;
|
||||
HRESULT hr;
|
||||
LLSD ret;
|
||||
CoInitialize(NULL);
|
||||
|
||||
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;
|
||||
|
||||
// CoCreate a IDxDiagProvider*
|
||||
llinfos << "CoCreateInstance IID_IDxDiagProvider" << llendl;
|
||||
hr = CoCreateInstance(CLSID_DxDiagProvider,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IDxDiagProvider,
|
||||
(LPVOID*) &dx_diag_providerp);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
llwarns << "No DXDiag provider found! DirectX 9 not installed!" << llendl;
|
||||
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.
|
||||
DXDIAG_INIT_PARAMS dx_diag_init_params;
|
||||
ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS));
|
||||
|
||||
dx_diag_init_params.dwSize = sizeof(DXDIAG_INIT_PARAMS);
|
||||
dx_diag_init_params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
|
||||
dx_diag_init_params.bAllowWHQLChecks = TRUE;
|
||||
dx_diag_init_params.pReserved = NULL;
|
||||
|
||||
llinfos << "dx_diag_providerp->Initialize" << llendl;
|
||||
hr = dx_diag_providerp->Initialize(&dx_diag_init_params);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto LCleanup;
|
||||
}
|
||||
|
||||
llinfos << "dx_diag_providerp->GetRootContainer" << llendl;
|
||||
hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp );
|
||||
if(FAILED(hr) || !dx_diag_rootp)
|
||||
{
|
||||
goto LCleanup;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
// Get display driver information
|
||||
llinfos << "dx_diag_rootp->GetChildContainer" << llendl;
|
||||
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
|
||||
if(FAILED(hr) || !devices_containerp)
|
||||
{
|
||||
goto LCleanup;
|
||||
}
|
||||
|
||||
// Get device 0
|
||||
llinfos << "devices_containerp->GetChildContainer" << llendl;
|
||||
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;
|
||||
|
||||
// ATI has a slightly different version string
|
||||
if(device_name.length() >= 4 && device_name.substr(0,4) == "ATI ")
|
||||
{
|
||||
// get the key
|
||||
HKEY hKey;
|
||||
const DWORD RV_SIZE = 100;
|
||||
WCHAR release_version[RV_SIZE];
|
||||
|
||||
// Hard coded registry entry. Using this since it's simpler for now.
|
||||
// And using EnumDisplayDevices to get a registry key also requires
|
||||
// a hard coded Query value.
|
||||
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\ATI Technologies\\CBT"), &hKey))
|
||||
{
|
||||
// get the value
|
||||
DWORD dwType = REG_SZ;
|
||||
DWORD dwSize = sizeof(WCHAR) * RV_SIZE;
|
||||
if(ERROR_SUCCESS == RegQueryValueEx(hKey, TEXT("ReleaseVersion"),
|
||||
NULL, &dwType, (LPBYTE)release_version, &dwSize))
|
||||
{
|
||||
// print the value
|
||||
// windows doesn't guarantee to be null terminated
|
||||
release_version[RV_SIZE - 1] = NULL;
|
||||
ret["DriverVersion"] = utf16str_to_utf8str(release_version);
|
||||
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LCleanup:
|
||||
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;
|
||||
}
|
||||
|
||||
void LLDXHardware::setWriteDebugFunc(void (*func)(const char*))
|
||||
{
|
||||
gWriteDebug = func;
|
||||
}
|
||||
|
||||
#endif
|
||||
118
indra/llwindow/lldxhardware.h
Normal file
118
indra/llwindow/lldxhardware.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @file lldxhardware.h
|
||||
* @brief LLDXHardware definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLDXHARDWARE_H
|
||||
#define LL_LLDXHARDWARE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llstring.h"
|
||||
#include "llsd.h"
|
||||
|
||||
class LLVersion
|
||||
{
|
||||
public:
|
||||
LLVersion();
|
||||
BOOL set(const std::string &version_string);
|
||||
S32 getField(const S32 field_num);
|
||||
protected:
|
||||
std::string mVersionString;
|
||||
S32 mFields[4];
|
||||
BOOL mValid;
|
||||
};
|
||||
|
||||
class LLDXDriverFile
|
||||
{
|
||||
public:
|
||||
std::string dump();
|
||||
|
||||
public:
|
||||
std::string mFilepath;
|
||||
std::string mName;
|
||||
std::string mVersionString;
|
||||
LLVersion mVersion;
|
||||
std::string mDateString;
|
||||
};
|
||||
|
||||
class LLDXDevice
|
||||
{
|
||||
public:
|
||||
~LLDXDevice();
|
||||
std::string dump();
|
||||
|
||||
LLDXDriverFile *findDriver(const std::string &driver);
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
class LLDXHardware
|
||||
{
|
||||
public:
|
||||
LLDXHardware();
|
||||
|
||||
void setWriteDebugFunc(void (*func)(const char*));
|
||||
void cleanup();
|
||||
|
||||
// Returns TRUE on success.
|
||||
// vram_only TRUE does a "light" probe.
|
||||
BOOL getInfo(BOOL vram_only);
|
||||
|
||||
S32 getVRAM() const { return mVRAM; }
|
||||
|
||||
LLSD getDisplayInfo();
|
||||
|
||||
// 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();
|
||||
public:
|
||||
typedef std::map<std::string, LLDXDevice *> device_map_t;
|
||||
// device_map_t mDevices;
|
||||
protected:
|
||||
S32 mVRAM;
|
||||
};
|
||||
|
||||
extern void (*gWriteDebug)(const char* msg);
|
||||
extern LLDXHardware gDXHardware;
|
||||
|
||||
#endif // LL_LLDXHARDWARE_H
|
||||
398
indra/llwindow/llkeyboard.cpp
Normal file
398
indra/llwindow/llkeyboard.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
/**
|
||||
* @file llkeyboard.cpp
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "indra_constants.h"
|
||||
#include "llkeyboard.h"
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
LLKeyboard *gKeyboard = NULL;
|
||||
|
||||
//static
|
||||
std::map<KEY,std::string> LLKeyboard::sKeysToNames;
|
||||
std::map<std::string,KEY> LLKeyboard::sNamesToKeys;
|
||||
|
||||
//
|
||||
// Class Implementation
|
||||
//
|
||||
|
||||
LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
void LLKeyboard::addKeyName(KEY key, const std::string& name)
|
||||
{
|
||||
sKeysToNames[key] = name;
|
||||
std::string nameuc = name;
|
||||
LLStringUtil::toUpper(nameuc);
|
||||
sNamesToKeys[nameuc] = key;
|
||||
}
|
||||
|
||||
// BUG this has to be called when an OS dialog is shown, otherwise modifier key state
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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())
|
||||
{
|
||||
//llwarns << "Unknown virtual key " << os_key << llendl;
|
||||
*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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
lldebugst(LLERR_USER_INPUT) << "keyup -" << translated_key << "-" << llendl;
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
void LLKeyboard::toggleInsertMode()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
// Returns time in frames since key was pressed.
|
||||
S32 LLKeyboard::getKeyElapsedFrameCount(KEY 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;
|
||||
}
|
||||
llwarns << "keyFromString failed: " << str << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
std::string LLKeyboard::stringFromKey(KEY key)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//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;
|
||||
}
|
||||
}
|
||||
149
indra/llwindow/llkeyboard.h
Normal file
149
indra/llwindow/llkeyboard.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @file llkeyboard.h
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLKEYBOARD_H
|
||||
#define LL_LLKEYBOARD_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "string_table.h"
|
||||
#include "lltimer.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
enum EKeystate
|
||||
{
|
||||
KEYSTATE_DOWN,
|
||||
KEYSTATE_LEVEL,
|
||||
KEYSTATE_UP
|
||||
};
|
||||
|
||||
typedef void (*LLKeyFunc)(EKeystate keystate);
|
||||
|
||||
enum EKeyboardInsertMode
|
||||
{
|
||||
LL_KIM_INSERT,
|
||||
LL_KIM_OVERWRITE
|
||||
};
|
||||
|
||||
class LLKeyBinding
|
||||
{
|
||||
public:
|
||||
KEY mKey;
|
||||
MASK mMask;
|
||||
// const char *mName; // unused
|
||||
LLKeyFunc mFunction;
|
||||
};
|
||||
|
||||
class LLWindowCallbacks;
|
||||
|
||||
class LLKeyboard
|
||||
{
|
||||
public:
|
||||
typedef enum e_numpad_distinct
|
||||
{
|
||||
ND_NEVER,
|
||||
ND_NUMLOCK_OFF,
|
||||
ND_NUMLOCK_ON
|
||||
} ENumpadDistinct;
|
||||
|
||||
public:
|
||||
LLKeyboard();
|
||||
virtual ~LLKeyboard();
|
||||
|
||||
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]; }
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; }
|
||||
void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; }
|
||||
|
||||
void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
|
||||
F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed.
|
||||
S32 getKeyElapsedFrameCount( KEY key ); // Returns time in frames since key was pressed.
|
||||
|
||||
protected:
|
||||
void addKeyName(KEY key, const std::string& name);
|
||||
|
||||
protected:
|
||||
std::map<U16, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs
|
||||
std::map<KEY, U16> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys
|
||||
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()
|
||||
|
||||
e_numpad_distinct mNumpadDistinct;
|
||||
|
||||
EKeyboardInsertMode mInsertMode;
|
||||
|
||||
static std::map<KEY,std::string> sKeysToNames;
|
||||
static std::map<std::string,KEY> sNamesToKeys;
|
||||
};
|
||||
|
||||
extern LLKeyboard *gKeyboard;
|
||||
|
||||
#endif
|
||||
333
indra/llwindow/llkeyboardmacosx.cpp
Normal file
333
indra/llwindow/llkeyboardmacosx.cpp
Normal file
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
* @file llkeyboardmacosx.cpp
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if LL_DARWIN
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llkeyboardmacosx.h"
|
||||
#include "llwindow.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void LLKeyboardMacOSX::resetMaskKeys()
|
||||
{
|
||||
U32 mask = GetCurrentEventKeyModifiers();
|
||||
|
||||
// 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 & shiftKey)
|
||||
{
|
||||
mKeyLevel[KEY_SHIFT] = TRUE;
|
||||
}
|
||||
|
||||
if(mask & (controlKey))
|
||||
{
|
||||
mKeyLevel[KEY_CONTROL] = TRUE;
|
||||
}
|
||||
|
||||
if(mask & optionKey)
|
||||
{
|
||||
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];
|
||||
|
||||
|
||||
return(outKey != 0);
|
||||
}
|
||||
*/
|
||||
|
||||
MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
|
||||
{
|
||||
// translate the mask
|
||||
MASK out_mask = 0;
|
||||
|
||||
if(mask & shiftKey)
|
||||
{
|
||||
out_mask |= MASK_SHIFT;
|
||||
}
|
||||
|
||||
if(mask & (controlKey | cmdKey))
|
||||
{
|
||||
out_mask |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
if(mask & optionKey)
|
||||
{
|
||||
out_mask |= MASK_ALT;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLKeyboardMacOSX::handleKeyUp(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 = handleTranslatedKeyUp(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
|
||||
{
|
||||
MASK result = MASK_NONE;
|
||||
U32 mask = GetCurrentEventKeyModifiers();
|
||||
|
||||
if (mask & shiftKey) result |= MASK_SHIFT;
|
||||
if (mask & controlKey) result |= MASK_CONTROL;
|
||||
if (mask & optionKey) result |= MASK_ALT;
|
||||
|
||||
// For keyboard events, consider Command equivalent to Control
|
||||
if (!for_mouse_event)
|
||||
{
|
||||
if (mask & cmdKey) 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]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key )
|
||||
{
|
||||
if(mNumpadDistinct == ND_NUMLOCK_ON)
|
||||
{
|
||||
std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
|
||||
if(iter != mTranslateNumpadMap.end())
|
||||
{
|
||||
*translated_key = iter->second;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return translateKey(os_key, translated_key);
|
||||
}
|
||||
|
||||
U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key)
|
||||
{
|
||||
if(mNumpadDistinct == ND_NUMLOCK_ON)
|
||||
{
|
||||
std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
|
||||
if(iter != mInvTranslateNumpadMap.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
return inverseTranslateKey(translated_key);
|
||||
}
|
||||
|
||||
#endif // LL_DARWIN
|
||||
60
indra/llwindow/llkeyboardmacosx.h
Normal file
60
indra/llwindow/llkeyboardmacosx.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file llkeyboardmacosx.h
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLKEYBOARDMACOSX_H
|
||||
#define LL_LLKEYBOARDMACOSX_H
|
||||
|
||||
#include "llkeyboard.h"
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
private:
|
||||
std::map<U16, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys
|
||||
std::map<KEY, U16> mInvTranslateNumpadMap; // inverse of the above
|
||||
};
|
||||
|
||||
#endif
|
||||
348
indra/llwindow/llkeyboardsdl.cpp
Normal file
348
indra/llwindow/llkeyboardsdl.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
/**
|
||||
* @file llkeyboardsdl.cpp
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if LL_SDL
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llkeyboardsdl.h"
|
||||
#include "llwindow.h"
|
||||
#include "SDL/SDL.h"
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MASK LLKeyboardSDL::updateModifiers(const U32 mask)
|
||||
{
|
||||
// translate the mask
|
||||
MASK out_mask = MASK_NONE;
|
||||
|
||||
if(mask & KMOD_SHIFT)
|
||||
{
|
||||
out_mask |= MASK_SHIFT;
|
||||
}
|
||||
|
||||
if(mask & KMOD_CTRL)
|
||||
{
|
||||
out_mask |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
if(mask & KMOD_ALT)
|
||||
{
|
||||
out_mask |= MASK_ALT;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask)
|
||||
{
|
||||
U16 adjusted_nativekey;
|
||||
KEY translated_key = 0;
|
||||
U32 translated_mask = MASK_NONE;
|
||||
BOOL handled = FALSE;
|
||||
|
||||
adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
|
||||
|
||||
translated_mask = updateModifiers(mask);
|
||||
|
||||
if(translateNumpadKey(adjusted_nativekey, &translated_key))
|
||||
{
|
||||
handled = handleTranslatedKeyDown(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
|
||||
|
||||
translated_mask = updateModifiers(mask);
|
||||
|
||||
if(translateNumpadKey(adjusted_nativekey, &translated_key))
|
||||
{
|
||||
handled = handleTranslatedKeyUp(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
MASK LLKeyboardSDL::currentMask(BOOL for_mouse_event)
|
||||
{
|
||||
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;
|
||||
|
||||
// For keyboard events, consider Meta keys equivalent to Control
|
||||
if (!for_mouse_event)
|
||||
{
|
||||
if (mask & KMOD_META) result |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
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]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
|
||||
{
|
||||
if(mNumpadDistinct == ND_NUMLOCK_ON)
|
||||
{
|
||||
std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
|
||||
if(iter != mTranslateNumpadMap.end())
|
||||
{
|
||||
*translated_key = iter->second;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
BOOL success = translateKey(os_key, translated_key);
|
||||
return success;
|
||||
}
|
||||
|
||||
U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
|
||||
{
|
||||
if(mNumpadDistinct == ND_NUMLOCK_ON)
|
||||
{
|
||||
std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
|
||||
if(iter != mInvTranslateNumpadMap.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
return inverseTranslateKey(translated_key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
61
indra/llwindow/llkeyboardsdl.h
Normal file
61
indra/llwindow/llkeyboardsdl.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @file llkeyboardsdl.h
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLKEYBOARDSDL_H
|
||||
#define LL_LLKEYBOARDSDL_H
|
||||
|
||||
#include "llkeyboard.h"
|
||||
#include "SDL/SDL.h"
|
||||
|
||||
class LLKeyboardSDL : public LLKeyboard
|
||||
{
|
||||
public:
|
||||
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();
|
||||
|
||||
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);
|
||||
private:
|
||||
std::map<U16, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys
|
||||
std::map<KEY, U16> mInvTranslateNumpadMap; // inverse of the above
|
||||
};
|
||||
|
||||
#endif
|
||||
409
indra/llwindow/llkeyboardwin32.cpp
Normal file
409
indra/llwindow/llkeyboardwin32.cpp
Normal file
@@ -0,0 +1,409 @@
|
||||
/**
|
||||
* @file llkeyboardwin32.cpp
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llkeyboardwin32.h"
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
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' + (0x60 - cur_char));
|
||||
}
|
||||
|
||||
|
||||
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] = KEY_PAD_DIVIDE;
|
||||
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
|
||||
// appropriate states.
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void LLKeyboardWin32::setModifierKeyLevel( KEY key, BOOL new_state )
|
||||
//{
|
||||
// if( mKeyLevel[key] != new_state )
|
||||
// {
|
||||
// mKeyLevelFrameCount[key] = 0;
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
translated_mask = updateModifiers();
|
||||
|
||||
if (translateExtendedKey(key, mask, &translated_key))
|
||||
{
|
||||
handled = handleTranslatedKeyDown(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
translated_mask = updateModifiers();
|
||||
|
||||
if (translateExtendedKey(key, mask, &translated_key))
|
||||
{
|
||||
handled = handleTranslatedKeyUp(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
MASK LLKeyboardWin32::currentMask(BOOL)
|
||||
{
|
||||
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;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
void LLKeyboardWin32::scanKeyboard()
|
||||
{
|
||||
S32 key;
|
||||
MSG msg;
|
||||
BOOL pending_key_events = PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD);
|
||||
for (key = 0; key < KEY_COUNT; key++)
|
||||
{
|
||||
// On Windows, verify key down state. JC
|
||||
// RN: only do this if we don't have further key events in the queue
|
||||
// as otherwise there might be key repeat events still waiting for this key we are now dumping
|
||||
if (!pending_key_events && mKeyLevel[key])
|
||||
{
|
||||
// *TODO: I KNOW there must be a better way of
|
||||
// interrogating the key state than this, using async key
|
||||
// state can cause ALL kinds of bugs - Doug
|
||||
if (key < KEY_BUTTON0)
|
||||
{
|
||||
// ...under windows make sure the key actually still is down.
|
||||
// ...translate back to windows key
|
||||
U16 virtual_key = inverseTranslateExtendedKey(key);
|
||||
// keydown in highest bit
|
||||
if (!pending_key_events && !(GetAsyncKeyState(virtual_key) & 0x8000))
|
||||
{
|
||||
//llinfos << "Key up event missed, resetting" << llendl;
|
||||
mKeyLevel[key] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
if(mNumpadDistinct == ND_NUMLOCK_ON)
|
||||
{
|
||||
std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key);
|
||||
if (iter != mTranslateNumpadMap.end())
|
||||
{
|
||||
*translated_key = iter->second;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL success = translateKey(os_key, translated_key);
|
||||
if(mNumpadDistinct != ND_NEVER) {
|
||||
if(!success) return success;
|
||||
if(mask & MASK_EXTENDED)
|
||||
{
|
||||
// this is where we'd create new keycodes for extended keys
|
||||
// the set of extended keys includes the 'normal' arrow keys and
|
||||
// the pgup/dn/insert/home/end/delete cluster above the arrow keys
|
||||
// see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx
|
||||
|
||||
// only process the return key if numlock is off
|
||||
if(((mNumpadDistinct == ND_NUMLOCK_OFF &&
|
||||
!(GetKeyState(VK_NUMLOCK) & 1))
|
||||
|| mNumpadDistinct == ND_NUMLOCK_ON) &&
|
||||
*translated_key == KEY_RETURN) {
|
||||
*translated_key = KEY_PAD_RETURN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the non-extended keys, those are in the numpad
|
||||
switch (*translated_key)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
*translated_key = KEY_PAD_LEFT; break;
|
||||
case KEY_RIGHT:
|
||||
*translated_key = KEY_PAD_RIGHT; break;
|
||||
case KEY_UP:
|
||||
*translated_key = KEY_PAD_UP; break;
|
||||
case KEY_DOWN:
|
||||
*translated_key = KEY_PAD_DOWN; break;
|
||||
case KEY_HOME:
|
||||
*translated_key = KEY_PAD_HOME; break;
|
||||
case KEY_END:
|
||||
*translated_key = KEY_PAD_END; break;
|
||||
case KEY_PAGE_UP:
|
||||
*translated_key = KEY_PAD_PGUP; break;
|
||||
case KEY_PAGE_DOWN:
|
||||
*translated_key = KEY_PAD_PGDN; break;
|
||||
case KEY_INSERT:
|
||||
*translated_key = KEY_PAD_INS; break;
|
||||
case KEY_DELETE:
|
||||
*translated_key = KEY_PAD_DEL; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key)
|
||||
{
|
||||
// if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number
|
||||
if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1))
|
||||
{
|
||||
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
|
||||
64
indra/llwindow/llkeyboardwin32.h
Normal file
64
indra/llwindow/llkeyboardwin32.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file llkeyboardwin32.h
|
||||
* @brief Handler for assignable key bindings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLKEYBOARDWIN32_H
|
||||
#define LL_LLKEYBOARDWIN32_H
|
||||
|
||||
#include "llkeyboard.h"
|
||||
|
||||
// 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() {};
|
||||
|
||||
/*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 );
|
||||
private:
|
||||
std::map<U16, KEY> mTranslateNumpadMap;
|
||||
std::map<KEY, U16> mInvTranslateNumpadMap;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
indra/llwindow/llmousehandler.h
Normal file
74
indra/llwindow/llmousehandler.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @file llmousehandler.h
|
||||
* @brief LLMouseHandler class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_MOUSEHANDLER_H
|
||||
#define LL_MOUSEHANDLER_H
|
||||
|
||||
#include "llstring.h"
|
||||
|
||||
// Abstract interface.
|
||||
// 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() {}
|
||||
typedef enum {
|
||||
SHOW_NEVER,
|
||||
SHOW_IF_NOT_BLOCKED,
|
||||
SHOW_ALWAYS,
|
||||
} EShowToolTip;
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0;
|
||||
virtual BOOL handleMouseUp(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 handleDoubleClick(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 handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) = 0;
|
||||
virtual EShowToolTip getShowToolTip() { return SHOW_IF_NOT_BLOCKED; };
|
||||
virtual const std::string& getName() const = 0;
|
||||
|
||||
virtual void onMouseCaptureLost() = 0;
|
||||
|
||||
// Hack to support LLFocusMgr
|
||||
virtual BOOL isView() 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;
|
||||
};
|
||||
|
||||
#endif
|
||||
107
indra/llwindow/llpreeditor.h
Normal file
107
indra/llwindow/llpreeditor.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* @file llpreeditor.h
|
||||
* @brief I believe this is used for languages like Japanese that require
|
||||
* an "input method editor" to type Kanji.
|
||||
* @author Open source patch, incorporated by Dave Simmons
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2007-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_PREEDITOR
|
||||
#define LL_PREEDITOR
|
||||
|
||||
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() {};
|
||||
|
||||
// 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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
virtual const LLWString & getWText() 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.
|
||||
|
||||
virtual BOOL handleUnicodeCharHere(llwchar uni_char) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
550
indra/llwindow/llwindow.cpp
Normal file
550
indra/llwindow/llwindow.cpp
Normal file
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
* @file llwindow.cpp
|
||||
* @brief Basic graphical window class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llwindowheadless.h"
|
||||
|
||||
#if LL_MESA_HEADLESS
|
||||
#include "llwindowmesaheadless.h"
|
||||
#elif LL_SDL
|
||||
#include "llwindowsdl.h"
|
||||
#elif LL_WINDOWS
|
||||
#include "llwindowwin32.h"
|
||||
#elif LL_DARWIN
|
||||
#include "llwindowmacosx.h"
|
||||
#endif
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "linked_lists.h"
|
||||
|
||||
//static instance for default callbacks
|
||||
LLWindowCallbacks LLWindow::sDefaultCallbacks;
|
||||
|
||||
//
|
||||
// LLWindowCallbacks
|
||||
//
|
||||
|
||||
LLSplashScreen *gSplashScreenp = NULL;
|
||||
BOOL gDebugClicks = FALSE;
|
||||
BOOL gDebugWindowProc = FALSE;
|
||||
|
||||
const S32 gURLProtocolWhitelistCount = 3;
|
||||
const std::string gURLProtocolWhitelist[] = { "file:", "http:", "https:" };
|
||||
|
||||
// CP: added a handler list - this is what's used to open the protocol and is based on registry entry
|
||||
// only meaningful difference currently is that file: protocols are opened using http:
|
||||
// since no protocol handler exists in registry for file:
|
||||
// Important - these lists should match - protocol to handler
|
||||
const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" };
|
||||
|
||||
BOOL LLWindowCallbacks::handleTranslatedKeyDown(const KEY key, const MASK mask, BOOL repeated)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLWindowCallbacks::handleTranslatedKeyUp(const KEY key, const MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleMouseLeave(LLWindow *window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleCloseRequest(LLWindow *window)
|
||||
{
|
||||
//allow the window to close
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleQuit(LLWindow *window)
|
||||
{
|
||||
if(LLWindowManager::destroyWindow(window) == FALSE)
|
||||
{
|
||||
llerrs << "LLWindowCallbacks::handleQuit() : Couldn't destroy window" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleRightMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleMiddleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleMiddleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleActivateApp(LLWindow *window, BOOL activating)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleFocus(LLWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleFocusLost(LLWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleDoubleClick(LLWindow *window, const LLCoordGL pos, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleWindowBlock(LLWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleWindowUnblock(LLWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleTimerEvent(LLWindow *window)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handlePauseWatchdog(LLWindow *window)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLWindowCallbacks::handleResumeWatchdog(LLWindow *window)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
S32 result = 0;
|
||||
#if LL_MESA_HEADLESS // !!! *FIX: (???)
|
||||
llwarns << "OSMessageBox: " << text << llendl;
|
||||
return OSBTN_OK;
|
||||
#elif LL_WINDOWS
|
||||
result = OSMessageBoxWin32(text, caption, type);
|
||||
#elif LL_DARWIN
|
||||
result = OSMessageBoxMacOSX(text, caption, type);
|
||||
#elif LL_SDL
|
||||
result = OSMessageBoxSDL(text, caption, type);
|
||||
#else
|
||||
#error("OSMessageBox not implemented for this platform!")
|
||||
#endif
|
||||
|
||||
if (was_visible)
|
||||
{
|
||||
LLSplashScreen::show();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLWindow
|
||||
//
|
||||
|
||||
LLWindow::LLWindow(BOOL fullscreen, U32 flags)
|
||||
: mCallbacks(&sDefaultCallbacks),
|
||||
mPostQuit(TRUE),
|
||||
mFullscreen(fullscreen),
|
||||
mFullscreenWidth(0),
|
||||
mFullscreenHeight(0),
|
||||
mFullscreenBits(0),
|
||||
mFullscreenRefresh(0),
|
||||
mSupportedResolutions(NULL),
|
||||
mNumSupportedResolutions(0),
|
||||
mCurrentCursor(UI_CURSOR_ARROW),
|
||||
mCursorHidden(FALSE),
|
||||
mBusyCount(0),
|
||||
mIsMouseClipping(FALSE),
|
||||
mSwapMethod(SWAP_METHOD_UNDEFINED),
|
||||
mHideCursorPermanent(FALSE),
|
||||
mFlags(flags),
|
||||
mHighSurrogate(0)
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLWindow::incBusyCount()
|
||||
{
|
||||
++mBusyCount;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLWindow::decBusyCount()
|
||||
{
|
||||
if (mBusyCount > 0)
|
||||
{
|
||||
--mBusyCount;
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindow::setCallbacks(LLWindowCallbacks *callbacks)
|
||||
{
|
||||
mCallbacks = callbacks;
|
||||
if (gKeyboard)
|
||||
{
|
||||
gKeyboard->setCallbacks(callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
void *LLWindow::getMediaWindow()
|
||||
{
|
||||
// Default to returning the platform window.
|
||||
return getPlatformWindow();
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLWindow::processMiscNativeEvents()
|
||||
{
|
||||
// do nothing unless subclassed
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLWindow::isPrimaryTextAvailable()
|
||||
{
|
||||
return FALSE; // no
|
||||
}
|
||||
//virtual
|
||||
BOOL LLWindow::pasteTextFromPrimary(LLWString &dst)
|
||||
{
|
||||
return FALSE; // fail
|
||||
}
|
||||
// virtual
|
||||
BOOL LLWindow::copyTextToPrimary(const LLWString &src)
|
||||
{
|
||||
return FALSE; // fail
|
||||
}
|
||||
|
||||
// static
|
||||
std::vector<std::string> LLWindow::getDynamicFallbackFontList()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
return LLWindowWin32::getDynamicFallbackFontList();
|
||||
#elif LL_DARWIN
|
||||
return LLWindowMacOSX::getDynamicFallbackFontList();
|
||||
#elif LL_SDL
|
||||
return LLWindowSDL::getDynamicFallbackFontList();
|
||||
#else
|
||||
return std::vector<std::string>();
|
||||
#endif
|
||||
}
|
||||
|
||||
#define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
|
||||
#define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400)
|
||||
#define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LLSplashScreen
|
||||
//
|
||||
|
||||
// static
|
||||
bool LLSplashScreen::isVisible()
|
||||
{
|
||||
return gSplashScreenp ? true: false;
|
||||
}
|
||||
|
||||
// static
|
||||
LLSplashScreen *LLSplashScreen::create()
|
||||
{
|
||||
#if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (???)
|
||||
return 0;
|
||||
#elif LL_WINDOWS
|
||||
return new LLSplashScreenWin32;
|
||||
#elif LL_DARWIN
|
||||
return new LLSplashScreenMacOSX;
|
||||
#else
|
||||
#error("LLSplashScreen not implemented on this platform!")
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void LLSplashScreen::show()
|
||||
{
|
||||
if (!gSplashScreenp)
|
||||
{
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
gSplashScreenp = new LLSplashScreenWin32;
|
||||
#elif LL_DARWIN
|
||||
gSplashScreenp = new LLSplashScreenMacOSX;
|
||||
#endif
|
||||
if (gSplashScreenp)
|
||||
{
|
||||
gSplashScreenp->showImpl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLSplashScreen::update(const std::string& str)
|
||||
{
|
||||
LLSplashScreen::show();
|
||||
if (gSplashScreenp)
|
||||
{
|
||||
gSplashScreenp->updateImpl(str);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLSplashScreen::hide()
|
||||
{
|
||||
if (gSplashScreenp)
|
||||
{
|
||||
gSplashScreenp->hideImpl();
|
||||
}
|
||||
delete gSplashScreenp;
|
||||
gSplashScreenp = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// LLWindowManager
|
||||
//
|
||||
|
||||
// TODO: replace with std::set
|
||||
static std::set<LLWindow*> sWindowList;
|
||||
|
||||
LLWindow* LLWindowManager::createWindow(
|
||||
const std::string& title,
|
||||
const std::string& name,
|
||||
LLCoordScreen upper_left,
|
||||
LLCoordScreen size,
|
||||
U32 flags,
|
||||
BOOL fullscreen,
|
||||
BOOL clearBg,
|
||||
BOOL disable_vsync,
|
||||
BOOL use_gl,
|
||||
BOOL ignore_pixel_depth)
|
||||
{
|
||||
return createWindow(
|
||||
title, name, upper_left.mX, upper_left.mY, size.mX, size.mY, flags,
|
||||
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
|
||||
}
|
||||
|
||||
LLWindow* LLWindowManager::createWindow(
|
||||
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,
|
||||
U32 fsaa_samples)
|
||||
{
|
||||
LLWindow* new_window;
|
||||
|
||||
if (use_gl)
|
||||
{
|
||||
#if LL_MESA_HEADLESS
|
||||
new_window = new LLWindowMesaHeadless(
|
||||
title, name, x, y, width, height, flags,
|
||||
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
|
||||
#elif LL_SDL
|
||||
new_window = new LLWindowSDL(
|
||||
title, x, y, width, height, flags,
|
||||
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
|
||||
#elif LL_WINDOWS
|
||||
new_window = new LLWindowWin32(
|
||||
title, name, x, y, width, height, flags,
|
||||
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
|
||||
#elif LL_DARWIN
|
||||
new_window = new LLWindowMacOSX(
|
||||
title, name, x, y, width, height, flags,
|
||||
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
new_window = new LLWindowHeadless(
|
||||
title, name, x, y, width, height, flags,
|
||||
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
|
||||
}
|
||||
|
||||
if (FALSE == new_window->isValid())
|
||||
{
|
||||
delete new_window;
|
||||
llwarns << "LLWindowManager::create() : Error creating window." << llendl;
|
||||
return NULL;
|
||||
}
|
||||
sWindowList.insert(new_window);
|
||||
return new_window;
|
||||
}
|
||||
|
||||
BOOL LLWindowManager::destroyWindow(LLWindow* window)
|
||||
{
|
||||
if (sWindowList.find(window) == sWindowList.end())
|
||||
{
|
||||
llerrs << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!"
|
||||
<< llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
window->close();
|
||||
|
||||
sWindowList.erase(window);
|
||||
|
||||
delete window;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLWindowManager::isWindowValid(LLWindow *window)
|
||||
{
|
||||
return sWindowList.find(window) != sWindowList.end();
|
||||
}
|
||||
332
indra/llwindow/llwindow.h
Normal file
332
indra/llwindow/llwindow.h
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @file llwindow.h
|
||||
* @brief Basic graphical window class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWINDOW_H
|
||||
#define LL_LLWINDOW_H
|
||||
|
||||
#include "llrect.h"
|
||||
#include "llcoord.h"
|
||||
#include "llstring.h"
|
||||
#include "llcursortypes.h"
|
||||
|
||||
class LLSplashScreen;
|
||||
|
||||
class LLWindow;
|
||||
|
||||
class LLPreeditor;
|
||||
|
||||
class LLWindowCallbacks
|
||||
{
|
||||
public:
|
||||
virtual ~LLWindowCallbacks() {}
|
||||
virtual BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated);
|
||||
virtual BOOL handleTranslatedKeyUp(KEY key, MASK mask);
|
||||
virtual void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
|
||||
virtual BOOL handleUnicodeChar(llwchar uni_char, MASK mask);
|
||||
|
||||
virtual BOOL 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 handleActivate(LLWindow *window, BOOL activated);
|
||||
virtual BOOL handleActivateApp(LLWindow *window, BOOL activating);
|
||||
virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
|
||||
virtual void handleScrollWheel(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 void handlePingWatchdog(LLWindow *window, const char * msg);
|
||||
virtual void handlePauseWatchdog(LLWindow *window);
|
||||
virtual void handleResumeWatchdog(LLWindow *window);
|
||||
|
||||
};
|
||||
|
||||
// Refer to llwindow_test in test/common/llwindow for usage example
|
||||
|
||||
class LLWindow
|
||||
{
|
||||
public:
|
||||
struct LLWindowResolution
|
||||
{
|
||||
S32 mWidth;
|
||||
S32 mHeight;
|
||||
};
|
||||
enum ESwapMethod
|
||||
{
|
||||
SWAP_METHOD_UNDEFINED,
|
||||
SWAP_METHOD_EXCHANGE,
|
||||
SWAP_METHOD_COPY
|
||||
};
|
||||
enum EFlags
|
||||
{
|
||||
// currently unused
|
||||
};
|
||||
public:
|
||||
virtual void show() = 0;
|
||||
virtual void hide() = 0;
|
||||
virtual void close() = 0;
|
||||
virtual BOOL getVisible() = 0;
|
||||
virtual BOOL getMinimized() = 0;
|
||||
virtual BOOL getMaximized() = 0;
|
||||
virtual BOOL maximize() = 0;
|
||||
BOOL getFullscreen() { return mFullscreen; };
|
||||
virtual BOOL getPosition(LLCoordScreen *position) = 0;
|
||||
virtual BOOL getSize(LLCoordScreen *size) = 0;
|
||||
virtual BOOL getSize(LLCoordWindow *size) = 0;
|
||||
virtual BOOL setPosition(LLCoordScreen position) = 0;
|
||||
virtual BOOL setSize(LLCoordScreen size) = 0;
|
||||
virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0;
|
||||
virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
|
||||
virtual BOOL getCursorPosition(LLCoordWindow *position) = 0;
|
||||
virtual void showCursor() = 0;
|
||||
virtual void hideCursor() = 0;
|
||||
virtual BOOL isCursorHidden() = 0;
|
||||
virtual void showCursorFromMouseMove() = 0;
|
||||
virtual void hideCursorUntilMouseMove() = 0;
|
||||
|
||||
// These two functions create a way to make a busy cursor instead
|
||||
// of an arrow when someone's busy doing something. Draw an
|
||||
// arrow/hour if busycount > 0.
|
||||
virtual void incBusyCount();
|
||||
virtual void decBusyCount();
|
||||
virtual void resetBusyCount() { mBusyCount = 0; }
|
||||
virtual S32 getBusyCount() const { return mBusyCount; }
|
||||
|
||||
// Sets cursor, may set to arrow+hourglass
|
||||
virtual void setCursor(ECursorType cursor) = 0;
|
||||
virtual ECursorType getCursor() const { return mCurrentCursor; }
|
||||
|
||||
virtual void captureMouse() = 0;
|
||||
virtual void releaseMouse() = 0;
|
||||
virtual void setMouseClipping( BOOL b ) = 0;
|
||||
virtual BOOL isClipboardTextAvailable() = 0;
|
||||
virtual BOOL pasteTextFromClipboard(LLWString &dst) = 0;
|
||||
virtual BOOL copyTextToClipboard(const LLWString &src) = 0;
|
||||
|
||||
virtual BOOL isPrimaryTextAvailable();
|
||||
virtual BOOL pasteTextFromPrimary(LLWString &dst);
|
||||
virtual BOOL copyTextToPrimary(const LLWString &src);
|
||||
|
||||
virtual void flashIcon(F32 seconds) = 0;
|
||||
virtual F32 getGamma() = 0;
|
||||
virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma
|
||||
virtual void setFSAASamples(const U32 fsaa_samples) = 0; //set number of FSAA samples
|
||||
virtual U32 getFSAASamples() = 0;
|
||||
virtual BOOL restoreGamma() = 0; // Restore original gamma table (before updating gamma)
|
||||
virtual ESwapMethod getSwapMethod() { return mSwapMethod; }
|
||||
virtual void processMiscNativeEvents();
|
||||
virtual void gatherInput() = 0;
|
||||
virtual void delayInputProcessing() = 0;
|
||||
virtual void swapBuffers() = 0;
|
||||
virtual void bringToFront() = 0;
|
||||
virtual void focusClient() { }; // this may not have meaning or be required on other platforms, therefore, it's not abstract
|
||||
|
||||
// handy coordinate space conversion routines
|
||||
// NB: screen to window and vice verse won't work on width/height coordinate pairs,
|
||||
// as the conversion must take into account left AND right border widths, etc.
|
||||
virtual BOOL convertCoords( LLCoordScreen from, LLCoordWindow *to) = 0;
|
||||
virtual BOOL convertCoords( LLCoordWindow from, LLCoordScreen *to) = 0;
|
||||
virtual BOOL convertCoords( LLCoordWindow from, LLCoordGL *to) = 0;
|
||||
virtual BOOL convertCoords( LLCoordGL from, LLCoordWindow *to) = 0;
|
||||
virtual BOOL convertCoords( LLCoordScreen from, LLCoordGL *to) = 0;
|
||||
virtual BOOL convertCoords( LLCoordGL from, LLCoordScreen *to) = 0;
|
||||
|
||||
// query supported resolutions
|
||||
virtual LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) = 0;
|
||||
virtual F32 getNativeAspectRatio() = 0;
|
||||
virtual F32 getPixelAspectRatio() = 0;
|
||||
virtual void setNativeAspectRatio(F32 aspect) = 0;
|
||||
|
||||
void setCallbacks(LLWindowCallbacks *callbacks);
|
||||
|
||||
virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode)
|
||||
virtual void afterDialog() {}; // undo whatever was done in beforeDialog()
|
||||
|
||||
// opens system default color picker
|
||||
virtual BOOL dialog_color_picker (F32 *r, F32 *g, F32 *b) { return FALSE; };
|
||||
|
||||
// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
|
||||
virtual void *getPlatformWindow() = 0;
|
||||
|
||||
// return the platform-specific window reference we use to initialize llmozlib (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
|
||||
virtual void *getMediaWindow();
|
||||
|
||||
// control platform's Language Text Input mechanisms.
|
||||
virtual void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) {}
|
||||
virtual void setLanguageTextInput( const LLCoordGL & pos ) {};
|
||||
virtual void updateLanguageTextInputArea() {}
|
||||
virtual void interruptLanguageTextInput() {}
|
||||
virtual void spawnWebBrowser(const std::string& escaped_url) {};
|
||||
|
||||
static std::vector<std::string> getDynamicFallbackFontList();
|
||||
|
||||
protected:
|
||||
LLWindow(BOOL fullscreen, U32 flags);
|
||||
virtual ~LLWindow() {}
|
||||
virtual BOOL isValid() {return TRUE;}
|
||||
virtual BOOL canDelete() {return TRUE;}
|
||||
protected:
|
||||
static LLWindowCallbacks sDefaultCallbacks;
|
||||
|
||||
protected:
|
||||
LLWindowCallbacks* mCallbacks;
|
||||
|
||||
BOOL mPostQuit; // should this window post a quit message when destroyed?
|
||||
BOOL mFullscreen;
|
||||
S32 mFullscreenWidth;
|
||||
S32 mFullscreenHeight;
|
||||
S32 mFullscreenBits;
|
||||
S32 mFullscreenRefresh;
|
||||
LLWindowResolution* mSupportedResolutions;
|
||||
S32 mNumSupportedResolutions;
|
||||
ECursorType mCurrentCursor;
|
||||
BOOL mCursorHidden;
|
||||
S32 mBusyCount; // how deep is the "cursor busy" stack?
|
||||
BOOL mIsMouseClipping; // Is this window currently clipping the mouse
|
||||
ESwapMethod mSwapMethod;
|
||||
BOOL mHideCursorPermanent;
|
||||
U32 mFlags;
|
||||
U16 mHighSurrogate;
|
||||
|
||||
// Handle a UTF-16 encoding unit received from keyboard.
|
||||
// Converting the series of UTF-16 encoding units to UTF-32 data,
|
||||
// this method passes the resulting UTF-32 data to mCallback's
|
||||
// handleUnicodeChar. The mask should be that to be passed to the
|
||||
// callback. This method uses mHighSurrogate as a dedicated work
|
||||
// variable.
|
||||
void handleUnicodeUTF16(U16 utf16, MASK mask);
|
||||
|
||||
friend class LLWindowManager;
|
||||
};
|
||||
|
||||
|
||||
// LLSplashScreen
|
||||
// A simple, OS-specific splash screen that we can display
|
||||
// while initializing the application and before creating a GL
|
||||
// window
|
||||
|
||||
|
||||
class LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreen() { };
|
||||
virtual ~LLSplashScreen() { };
|
||||
|
||||
|
||||
// Call to display the window.
|
||||
static LLSplashScreen * create();
|
||||
static void show();
|
||||
static void hide();
|
||||
static void update(const std::string& string);
|
||||
|
||||
static bool isVisible();
|
||||
protected:
|
||||
// These are overridden by the platform implementation
|
||||
virtual void showImpl() = 0;
|
||||
virtual void updateImpl(const std::string& string) = 0;
|
||||
virtual void hideImpl() = 0;
|
||||
|
||||
static BOOL sVisible;
|
||||
|
||||
};
|
||||
|
||||
// Platform-neutral for accessing the platform specific message box
|
||||
S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type);
|
||||
const U32 OSMB_OK = 0;
|
||||
const U32 OSMB_OKCANCEL = 1;
|
||||
const U32 OSMB_YESNO = 2;
|
||||
|
||||
const S32 OSBTN_YES = 0;
|
||||
const S32 OSBTN_NO = 1;
|
||||
const S32 OSBTN_OK = 2;
|
||||
const S32 OSBTN_CANCEL = 3;
|
||||
|
||||
//
|
||||
// LLWindowManager
|
||||
// Manages window creation and error checking
|
||||
|
||||
class LLWindowManager
|
||||
{
|
||||
public:
|
||||
static LLWindow* createWindow(
|
||||
const std::string& title,
|
||||
const std::string& name,
|
||||
LLCoordScreen upper_left = LLCoordScreen(10, 10),
|
||||
LLCoordScreen size = LLCoordScreen(320, 240),
|
||||
U32 flags = 0,
|
||||
BOOL fullscreen = FALSE,
|
||||
BOOL clearBg = FALSE,
|
||||
BOOL disable_vsync = TRUE,
|
||||
BOOL use_gl = TRUE,
|
||||
BOOL ignore_pixel_depth = FALSE);
|
||||
static LLWindow *createWindow(
|
||||
const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
|
||||
U32 flags = 0,
|
||||
BOOL fullscreen = FALSE,
|
||||
BOOL clearBg = FALSE,
|
||||
BOOL disable_vsync = TRUE,
|
||||
BOOL use_gl = TRUE,
|
||||
BOOL ignore_pixel_depth = FALSE,
|
||||
U32 fsaa_samples = 0);
|
||||
static BOOL destroyWindow(LLWindow* window);
|
||||
static BOOL isWindowValid(LLWindow *window);
|
||||
};
|
||||
|
||||
//
|
||||
// helper funcs
|
||||
//
|
||||
extern BOOL gDebugWindowProc;
|
||||
|
||||
// Protocols, like "http" and "https" we support in URLs
|
||||
extern const S32 gURLProtocolWhitelistCount;
|
||||
extern const std::string gURLProtocolWhitelist[];
|
||||
extern const std::string gURLProtocolWhitelistHandler[];
|
||||
|
||||
void simpleEscapeString ( std::string& stringIn );
|
||||
|
||||
#endif // _LL_window_h_
|
||||
56
indra/llwindow/llwindowheadless.cpp
Normal file
56
indra/llwindow/llwindowheadless.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file llwindowheadless.cpp
|
||||
* @brief Headless implementation of LLWindow class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
#include "llwindowheadless.h"
|
||||
|
||||
//
|
||||
// LLWindowHeadless
|
||||
//
|
||||
LLWindowHeadless::LLWindowHeadless(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(fullscreen, flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLWindowHeadless::~LLWindowHeadless()
|
||||
{
|
||||
}
|
||||
|
||||
void LLWindowHeadless::swapBuffers()
|
||||
{
|
||||
}
|
||||
|
||||
118
indra/llwindow/llwindowheadless.h
Normal file
118
indra/llwindow/llwindowheadless.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @file llwindowheadless.h
|
||||
* @brief Headless definition of LLWindow class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWINDOWHEADLESS_H
|
||||
#define LL_LLWINDOWHEADLESS_H
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
class LLWindowHeadless : 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*/ 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 setSize(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 setCursor(ECursorType cursor) {};
|
||||
//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*/ void setFSAASamples(const U32 fsaa_samples) { }
|
||||
/*virtual*/ U32 getFSAASamples() { return 0; }
|
||||
/*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma)
|
||||
//virtual ESwapMethod getSwapMethod() { return mSwapMethod; }
|
||||
/*virtual*/ void gatherInput() {};
|
||||
/*virtual*/ void delayInputProcessing() {};
|
||||
/*virtual*/ void swapBuffers();
|
||||
|
||||
// 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*/ void *getPlatformWindow() { return 0; };
|
||||
/*virtual*/ void bringToFront() {};
|
||||
|
||||
LLWindowHeadless(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);
|
||||
virtual ~LLWindowHeadless();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class LLSplashScreenHeadless : public LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreenHeadless() {};
|
||||
virtual ~LLSplashScreenHeadless() {};
|
||||
|
||||
/*virtual*/ void showImpl() {};
|
||||
/*virtual*/ void updateImpl(const std::string& mesg) {};
|
||||
/*virtual*/ void hideImpl() {};
|
||||
|
||||
};
|
||||
|
||||
#endif //LL_LLWINDOWHEADLESS_H
|
||||
|
||||
43
indra/llwindow/llwindowmacosx-objc.h
Normal file
43
indra/llwindow/llwindowmacosx-objc.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file llwindowmacosx-objc.h
|
||||
* @brief Prototypes for functions shared between llwindowmacosx.cpp
|
||||
* and llwindowmacosx-objc.mm.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
// This will actually hold an NSCursor*, but that type is only available in objective C.
|
||||
typedef void *CursorRef;
|
||||
|
||||
/* Defined in llwindowmacosx-objc.mm: */
|
||||
void setupCocoa();
|
||||
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
|
||||
OSErr releaseImageCursor(CursorRef ref);
|
||||
OSErr setImageCursor(CursorRef ref);
|
||||
|
||||
119
indra/llwindow/llwindowmacosx-objc.mm
Normal file
119
indra/llwindow/llwindowmacosx-objc.mm
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @file llwindowmacosx-objc.mm
|
||||
* @brief Definition of functions shared between llwindowmacosx.cpp
|
||||
* and llwindowmacosx-objc.mm.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
/*
|
||||
* These functions are broken out into a separate file because the
|
||||
* objective-C typedef for 'BOOL' conflicts with the one in
|
||||
* llcommon/stdtypes.h. This makes it impossible to use the standard
|
||||
* linden headers with any objective-C++ source.
|
||||
*/
|
||||
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
void setupCocoa()
|
||||
{
|
||||
static bool inited = false;
|
||||
|
||||
if(!inited)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
|
||||
// http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
|
||||
|
||||
// Needed for Carbon based applications which call into Cocoa
|
||||
NSApplicationLoad();
|
||||
|
||||
// Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
|
||||
[[[NSWindow alloc] init] release];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
}
|
||||
|
||||
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
|
||||
NSCursor *cursor =
|
||||
[[[NSCursor alloc]
|
||||
initWithImage:
|
||||
[[[NSImage alloc] initWithContentsOfFile:
|
||||
[NSString stringWithFormat:@"%s", fullpath]
|
||||
]autorelease]
|
||||
hotSpot:NSMakePoint(hotspotX, hotspotY)
|
||||
]retain];
|
||||
|
||||
[pool release];
|
||||
|
||||
return (CursorRef)cursor;
|
||||
}
|
||||
|
||||
// This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness.
|
||||
OSErr releaseImageCursor(CursorRef ref)
|
||||
{
|
||||
if( ref != NULL )
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSCursor *cursor = (NSCursor*)ref;
|
||||
[cursor release];
|
||||
[pool release];
|
||||
}
|
||||
else
|
||||
{
|
||||
return paramErr;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSErr setImageCursor(CursorRef ref)
|
||||
{
|
||||
if( ref != NULL )
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSCursor *cursor = (NSCursor*)ref;
|
||||
[cursor set];
|
||||
[pool release];
|
||||
}
|
||||
else
|
||||
{
|
||||
return paramErr;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
3366
indra/llwindow/llwindowmacosx.cpp
Normal file
3366
indra/llwindow/llwindowmacosx.cpp
Normal file
File diff suppressed because it is too large
Load Diff
232
indra/llwindow/llwindowmacosx.h
Normal file
232
indra/llwindow/llwindowmacosx.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* @file llwindowmacosx.h
|
||||
* @brief Mac implementation of LLWindow class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWINDOWMACOSX_H
|
||||
#define LL_LLWINDOWMACOSX_H
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AGL/agl.h>
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
#undef verify
|
||||
#undef check
|
||||
#undef require
|
||||
|
||||
|
||||
class LLWindowMacOSX : 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*/ BOOL getFullscreen();
|
||||
/*virtual*/ BOOL getPosition(LLCoordScreen *position);
|
||||
/*virtual*/ BOOL getSize(LLCoordScreen *size);
|
||||
/*virtual*/ BOOL getSize(LLCoordWindow *size);
|
||||
/*virtual*/ BOOL setPosition(LLCoordScreen position);
|
||||
/*virtual*/ BOOL setSize(LLCoordScreen 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 setCursor(ECursorType cursor);
|
||||
/*virtual*/ ECursorType getCursor() const;
|
||||
/*virtual*/ void captureMouse();
|
||||
/*virtual*/ void releaseMouse();
|
||||
/*virtual*/ void setMouseClipping( BOOL b );
|
||||
/*virtual*/ BOOL isClipboardTextAvailable();
|
||||
/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst);
|
||||
/*virtual*/ BOOL copyTextToClipboard(const LLWString & src);
|
||||
/*virtual*/ void flashIcon(F32 seconds);
|
||||
/*virtual*/ F32 getGamma();
|
||||
/*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma
|
||||
/*virtual*/ U32 getFSAASamples();
|
||||
/*virtual*/ void setFSAASamples(const U32 fsaa_samples);
|
||||
/*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma)
|
||||
/*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; }
|
||||
/*virtual*/ void gatherInput();
|
||||
/*virtual*/ void delayInputProcessing() {};
|
||||
/*virtual*/ void swapBuffers();
|
||||
|
||||
// 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 dialog_color_picker(F32 *r, F32 *g, F32 *b);
|
||||
|
||||
/*virtual*/ void *getPlatformWindow();
|
||||
/*virtual*/ void *getMediaWindow();
|
||||
/*virtual*/ void bringToFront() {};
|
||||
|
||||
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
|
||||
/*virtual*/ void interruptLanguageTextInput();
|
||||
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url);
|
||||
|
||||
static std::vector<std::string> getDynamicFallbackFontList();
|
||||
|
||||
protected:
|
||||
LLWindowMacOSX(
|
||||
const std::string& title, const std::string& name, 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);
|
||||
~LLWindowMacOSX();
|
||||
|
||||
void initCursors();
|
||||
BOOL isValid();
|
||||
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);
|
||||
|
||||
// Go back to last fullscreen display resolution.
|
||||
BOOL setFullscreenResolution();
|
||||
|
||||
// Restore the display resolution to its value before we ran the app.
|
||||
BOOL resetDisplayResolution();
|
||||
|
||||
void minimize();
|
||||
void restore();
|
||||
|
||||
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);
|
||||
static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
|
||||
static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
|
||||
OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
|
||||
void adjustCursorDecouple(bool warpingMouse = false);
|
||||
void fixWindowSize(void);
|
||||
void stopDockTileBounce();
|
||||
|
||||
|
||||
//
|
||||
// Platform specific variables
|
||||
//
|
||||
WindowRef mWindow;
|
||||
AGLContext mContext;
|
||||
AGLPixelFormat mPixelFormat;
|
||||
CGDirectDisplayID mDisplay;
|
||||
CFDictionaryRef mOldDisplayMode;
|
||||
EventLoopTimerRef mTimer;
|
||||
EventHandlerUPP mEventHandlerUPP;
|
||||
EventHandlerRef mGlobalHandlerRef;
|
||||
EventHandlerRef mWindowHandlerRef;
|
||||
EventComparatorUPP mMoveEventCampartorUPP;
|
||||
|
||||
Rect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
|
||||
Str255 mWindowTitle;
|
||||
double mOriginalAspectRatio;
|
||||
BOOL mSimulatedRightClick;
|
||||
UInt32 mLastModifiers;
|
||||
BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing.
|
||||
// Used to allow event processing when putting up dialogs in fullscreen mode.
|
||||
BOOL mCursorDecoupled;
|
||||
S32 mCursorLastEventDeltaX;
|
||||
S32 mCursorLastEventDeltaY;
|
||||
BOOL mCursorIgnoreNextDelta;
|
||||
BOOL mNeedsResize; // Constructor figured out the window is too big, it needs a resize.
|
||||
LLCoordScreen mNeedsResizeSize;
|
||||
F32 mOverrideAspectRatio;
|
||||
BOOL mMinimized;
|
||||
U32 mFSAASamples;
|
||||
BOOL mForceRebuild;
|
||||
|
||||
F32 mBounceTime;
|
||||
NMRec mBounceRec;
|
||||
LLTimer mBounceTimer;
|
||||
|
||||
// Imput method management through Text Service Manager.
|
||||
TSMDocumentID mTSMDocument;
|
||||
BOOL mLanguageTextInputAllowed;
|
||||
ScriptCode mTSMScriptCode;
|
||||
LangCode mTSMLangCode;
|
||||
LLPreeditor* mPreeditor;
|
||||
|
||||
static BOOL sUseMultGL;
|
||||
|
||||
friend class LLWindowManager;
|
||||
static WindowRef sMediaWindow;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLSplashScreenMacOSX : public LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreenMacOSX();
|
||||
virtual ~LLSplashScreenMacOSX();
|
||||
|
||||
/*virtual*/ void showImpl();
|
||||
/*virtual*/ void updateImpl(const std::string& mesg);
|
||||
/*virtual*/ void hideImpl();
|
||||
|
||||
private:
|
||||
WindowRef mWindow;
|
||||
};
|
||||
|
||||
S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type);
|
||||
|
||||
void load_url_external(const char* url);
|
||||
|
||||
#endif //LL_LLWINDOWMACOSX_H
|
||||
83
indra/llwindow/llwindowmesaheadless.cpp
Normal file
83
indra/llwindow/llwindowmesaheadless.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file llwindowmesaheadless.cpp
|
||||
* @brief Platform-dependent implementation of llwindow
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
#include "llwindowmesaheadless.h"
|
||||
#include "llgl.h"
|
||||
|
||||
#define MESA_CHANNEL_TYPE GL_UNSIGNED_SHORT
|
||||
#define MESA_CHANNEL_SIZE 2
|
||||
|
||||
U16 *gMesaBuffer = NULL;
|
||||
|
||||
//
|
||||
// LLWindowMesaHeadless
|
||||
//
|
||||
LLWindowMesaHeadless::LLWindowMesaHeadless(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(fullscreen, flags)
|
||||
{
|
||||
if (use_gl)
|
||||
{
|
||||
llinfos << "MESA Init" << llendl;
|
||||
mMesaContext = OSMesaCreateContextExt( GL_RGBA, 32, 0, 0, NULL );
|
||||
|
||||
/* Allocate the image buffer */
|
||||
mMesaBuffer = new unsigned char [width * height * 4 * MESA_CHANNEL_SIZE];
|
||||
llassert(mMesaBuffer);
|
||||
|
||||
gMesaBuffer = (U16*)mMesaBuffer;
|
||||
|
||||
/* Bind the buffer to the context and make it current */
|
||||
if (!OSMesaMakeCurrent( mMesaContext, mMesaBuffer, MESA_CHANNEL_TYPE, width, height ))
|
||||
{
|
||||
llerrs << "MESA: OSMesaMakeCurrent failed!" << llendl;
|
||||
}
|
||||
|
||||
llverify(gGLManager.initGL());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLWindowMesaHeadless::~LLWindowMesaHeadless()
|
||||
{
|
||||
delete mMesaBuffer;
|
||||
OSMesaDestroyContext( mMesaContext );
|
||||
}
|
||||
|
||||
void LLWindowMesaHeadless::swapBuffers()
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
125
indra/llwindow/llwindowmesaheadless.h
Normal file
125
indra/llwindow/llwindowmesaheadless.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @file llwindowmesaheadless.h
|
||||
* @brief Windows implementation of LLWindow class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWINDOWMESAHEADLESS_H
|
||||
#define LL_LLWINDOWMESAHEADLESS_H
|
||||
|
||||
#if LL_MESA_HEADLESS
|
||||
|
||||
#include "llwindow.h"
|
||||
#include "GL/glu.h"
|
||||
#include "GL/osmesa.h"
|
||||
|
||||
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*/ 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 setSize(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 setCursor(ECursorType cursor) {};
|
||||
//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();
|
||||
|
||||
// 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*/ void *getPlatformWindow() { return 0; };
|
||||
/*virtual*/ void bringToFront() {};
|
||||
|
||||
LLWindowMesaHeadless(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();
|
||||
|
||||
private:
|
||||
OSMesaContext mMesaContext;
|
||||
unsigned char * mMesaBuffer;
|
||||
};
|
||||
|
||||
class LLSplashScreenMesaHeadless : public LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreenMesaHeadless() {};
|
||||
virtual ~LLSplashScreenMesaHeadless() {};
|
||||
|
||||
/*virtual*/ void showImpl() {};
|
||||
/*virtual*/ void updateImpl(const std::string& mesg) {};
|
||||
/*virtual*/ void hideImpl() {};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif //LL_LLWINDOWMESAHEADLESS_H
|
||||
2463
indra/llwindow/llwindowsdl.cpp
Normal file
2463
indra/llwindow/llwindowsdl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
224
indra/llwindow/llwindowsdl.h
Normal file
224
indra/llwindow/llwindowsdl.h
Normal file
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @file llwindowsdl.h
|
||||
* @brief SDL implementation of LLWindow class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWINDOWSDL_H
|
||||
#define LL_LLWINDOWSDL_H
|
||||
|
||||
// Simple Directmedia Layer (http://libsdl.org/) implementation of LLWindow class
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
#include "SDL/SDL_endian.h"
|
||||
|
||||
#if LL_X11
|
||||
// get X11-specific headers for use in low-level stuff like copy-and-paste support
|
||||
#include "SDL/SDL_syswm.h"
|
||||
#endif
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
#undef verify
|
||||
#undef check
|
||||
#undef require
|
||||
|
||||
|
||||
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*/ BOOL getFullscreen();
|
||||
/*virtual*/ BOOL getPosition(LLCoordScreen *position);
|
||||
/*virtual*/ BOOL getSize(LLCoordScreen *size);
|
||||
/*virtual*/ BOOL getSize(LLCoordWindow *size);
|
||||
/*virtual*/ BOOL setPosition(LLCoordScreen position);
|
||||
/*virtual*/ BOOL setSize(LLCoordScreen 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 setCursor(ECursorType cursor);
|
||||
/*virtual*/ ECursorType getCursor();
|
||||
/*virtual*/ void captureMouse();
|
||||
/*virtual*/ void releaseMouse();
|
||||
/*virtual*/ void setMouseClipping( BOOL b );
|
||||
/*virtual*/ BOOL isClipboardTextAvailable();
|
||||
/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst);
|
||||
/*virtual*/ BOOL copyTextToClipboard(const LLWString & src);
|
||||
/*virtual*/ void flashIcon(F32 seconds);
|
||||
/*virtual*/ F32 getGamma();
|
||||
/*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma
|
||||
/*virtual*/ 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 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 dialog_color_picker(F32 *r, F32 *g, F32 *b);
|
||||
|
||||
/*virtual*/ void *getPlatformWindow();
|
||||
/*virtual*/ void bringToFront();
|
||||
|
||||
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url);
|
||||
|
||||
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;
|
||||
#endif
|
||||
void (*Lock_Display)(void);
|
||||
void (*Unlock_Display)(void);
|
||||
|
||||
#if LL_GTK
|
||||
// Lazily initialize and check the runtime GTK version for goodness.
|
||||
static bool ll_try_gtk_init(void);
|
||||
#endif // LL_GTK
|
||||
|
||||
#if LL_X11
|
||||
static Window get_SDL_XWindowID(void);
|
||||
static Display* get_SDL_Display(void);
|
||||
#endif // LL_X11
|
||||
|
||||
protected:
|
||||
LLWindowSDL(
|
||||
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();
|
||||
|
||||
void initCursors();
|
||||
void quitCursors();
|
||||
BOOL isValid();
|
||||
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);
|
||||
|
||||
// Go back to last fullscreen display resolution.
|
||||
BOOL setFullscreenResolution();
|
||||
|
||||
void minimize();
|
||||
void restore();
|
||||
|
||||
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;
|
||||
|
||||
#if LL_X11
|
||||
private:
|
||||
void x11_set_urgent(BOOL urgent);
|
||||
BOOL mFlashing;
|
||||
LLTimer mFlashTimer;
|
||||
#endif //LL_X11
|
||||
};
|
||||
|
||||
|
||||
class LLSplashScreenSDL : public LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreenSDL();
|
||||
virtual ~LLSplashScreenSDL();
|
||||
|
||||
/*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);
|
||||
|
||||
#endif //LL_LLWINDOWSDL_H
|
||||
3664
indra/llwindow/llwindowwin32.cpp
Normal file
3664
indra/llwindow/llwindowwin32.cpp
Normal file
File diff suppressed because it is too large
Load Diff
240
indra/llwindow/llwindowwin32.h
Normal file
240
indra/llwindow/llwindowwin32.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* @file llwindowwin32.h
|
||||
* @brief Windows implementation of LLWindow class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLWINDOWWIN32_H
|
||||
#define LL_LLWINDOWWIN32_H
|
||||
|
||||
// Limit Windows API to small and manageable set.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
// Hack for async host by name
|
||||
#define LL_WM_HOST_RESOLVED (WM_APP + 1)
|
||||
typedef void (*LLW32MsgCallback)(const MSG &msg);
|
||||
|
||||
class LLWindowWin32 : public LLWindow
|
||||
{
|
||||
public:
|
||||
/*virtual*/ void show();
|
||||
/*virtual*/ void hide();
|
||||
/*virtual*/ void close();
|
||||
/*virtual*/ BOOL getVisible();
|
||||
/*virtual*/ BOOL getMinimized();
|
||||
/*virtual*/ BOOL getMaximized();
|
||||
/*virtual*/ BOOL maximize();
|
||||
/*virtual*/ BOOL getFullscreen();
|
||||
/*virtual*/ BOOL getPosition(LLCoordScreen *position);
|
||||
/*virtual*/ BOOL getSize(LLCoordScreen *size);
|
||||
/*virtual*/ BOOL getSize(LLCoordWindow *size);
|
||||
/*virtual*/ BOOL setPosition(LLCoordScreen position);
|
||||
/*virtual*/ BOOL setSize(LLCoordScreen 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 setCursor(ECursorType cursor);
|
||||
/*virtual*/ ECursorType getCursor() const;
|
||||
/*virtual*/ void captureMouse();
|
||||
/*virtual*/ void releaseMouse();
|
||||
/*virtual*/ void setMouseClipping( BOOL b );
|
||||
/*virtual*/ BOOL isClipboardTextAvailable();
|
||||
/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst);
|
||||
/*virtual*/ BOOL copyTextToClipboard(const LLWString &src);
|
||||
/*virtual*/ void flashIcon(F32 seconds);
|
||||
/*virtual*/ F32 getGamma();
|
||||
/*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma
|
||||
/*virtual*/ void setFSAASamples(const U32 fsaa_samples);
|
||||
/*virtual*/ U32 getFSAASamples();
|
||||
/*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma)
|
||||
/*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; }
|
||||
/*virtual*/ void gatherInput();
|
||||
/*virtual*/ void delayInputProcessing();
|
||||
/*virtual*/ void swapBuffers();
|
||||
|
||||
// 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*/ BOOL dialog_color_picker (F32 *r, F32 *g, F32 *b );
|
||||
|
||||
/*virtual*/ void *getPlatformWindow();
|
||||
/*virtual*/ void bringToFront();
|
||||
/*virtual*/ void focusClient();
|
||||
|
||||
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
|
||||
/*virtual*/ void setLanguageTextInput( const LLCoordGL & pos );
|
||||
/*virtual*/ void updateLanguageTextInputArea();
|
||||
/*virtual*/ void interruptLanguageTextInput();
|
||||
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url);
|
||||
|
||||
static std::vector<std::string> getDynamicFallbackFontList();
|
||||
|
||||
protected:
|
||||
LLWindowWin32(
|
||||
const std::string& title, const std::string& name, 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);
|
||||
~LLWindowWin32();
|
||||
|
||||
void initCursors();
|
||||
void initInputDevices();
|
||||
HCURSOR loadColorCursor(LPCTSTR name);
|
||||
BOOL isValid();
|
||||
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);
|
||||
|
||||
// Go back to last fullscreen display resolution.
|
||||
BOOL setFullscreenResolution();
|
||||
|
||||
// Restore the display resolution to its value before we ran the app.
|
||||
BOOL resetDisplayResolution();
|
||||
|
||||
void minimize();
|
||||
void restore();
|
||||
|
||||
BOOL shouldPostQuit() { return mPostQuit; }
|
||||
|
||||
void fillCompositionForm(const LLRect& bounds, COMPOSITIONFORM *form);
|
||||
void fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, CANDIDATEFORM *form);
|
||||
void fillCharPosition(const LLCoordGL& caret, const LLRect& bounds, const LLRect& control, IMECHARPOSITION *char_position);
|
||||
void fillCompositionLogfont(LOGFONT *logfont);
|
||||
U32 fillReconvertString(const LLWString &text, S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string);
|
||||
void handleStartCompositionMessage();
|
||||
void handleCompositionMessage(U32 indexes);
|
||||
BOOL handleImeRequests(U32 request, U32 param, LRESULT *result);
|
||||
|
||||
protected:
|
||||
//
|
||||
// Platform specific methods
|
||||
//
|
||||
|
||||
BOOL getClientRectInScreenSpace(RECT* rectp);
|
||||
void updateJoystick( );
|
||||
|
||||
static LRESULT CALLBACK mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param);
|
||||
static BOOL CALLBACK enumChildWindows(HWND h_wnd, LPARAM l_param);
|
||||
|
||||
|
||||
//
|
||||
// Platform specific variables
|
||||
//
|
||||
WCHAR *mWindowTitle;
|
||||
WCHAR *mWindowClassName;
|
||||
|
||||
HWND mWindowHandle; // window handle
|
||||
HGLRC mhRC; // OpenGL rendering context
|
||||
HDC mhDC; // Windows Device context handle
|
||||
HINSTANCE mhInstance; // handle to application instance
|
||||
WNDPROC mWndProc; // user-installable window proc
|
||||
RECT mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
|
||||
WPARAM mLastSizeWParam;
|
||||
F32 mOverrideAspectRatio;
|
||||
F32 mNativeAspectRatio;
|
||||
|
||||
HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors
|
||||
|
||||
static BOOL sIsClassRegistered; // has the window class been registered?
|
||||
|
||||
F32 mCurrentGamma;
|
||||
U32 mFSAASamples;
|
||||
WORD mPrevGammaRamp[256*3];
|
||||
WORD mCurrentGammaRamp[256*3];
|
||||
|
||||
LPWSTR mIconResource;
|
||||
BOOL mMousePositionModified;
|
||||
BOOL mInputProcessingPaused;
|
||||
|
||||
// The following variables are for Language Text Input control.
|
||||
// They are all static, since one context is shared by all LLWindowWin32
|
||||
// instances.
|
||||
static BOOL sLanguageTextInputAllowed;
|
||||
static BOOL sWinIMEOpened;
|
||||
static HKL sWinInputLocale;
|
||||
static DWORD sWinIMEConversionMode;
|
||||
static DWORD sWinIMESentenceMode;
|
||||
static LLCoordWindow sWinIMEWindowPosition;
|
||||
LLCoordGL mLanguageTextInputPointGL;
|
||||
LLRect mLanguageTextInputAreaGL;
|
||||
|
||||
LLPreeditor *mPreeditor;
|
||||
|
||||
friend class LLWindowManager;
|
||||
};
|
||||
|
||||
class LLSplashScreenWin32 : public LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreenWin32();
|
||||
virtual ~LLSplashScreenWin32();
|
||||
|
||||
/*virtual*/ void showImpl();
|
||||
/*virtual*/ void updateImpl(const std::string& mesg);
|
||||
/*virtual*/ void hideImpl();
|
||||
|
||||
#if LL_WINDOWS
|
||||
static LRESULT CALLBACK windowProc(HWND h_wnd, UINT u_msg,
|
||||
WPARAM w_param, LPARAM l_param);
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if LL_WINDOWS
|
||||
HWND mWindow;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern LLW32MsgCallback gAsyncMsgCallback;
|
||||
extern LPWSTR gIconResource;
|
||||
|
||||
static void handleMessage( const MSG& msg );
|
||||
|
||||
S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type);
|
||||
|
||||
#endif //LL_LLWINDOWWIN32_H
|
||||
Reference in New Issue
Block a user