Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View 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)

View 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 */

File diff suppressed because it is too large Load Diff

1621
indra/llwindow/glh/glh_linear.h Executable file

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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
View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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
View 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
View 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_

View 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()
{
}

View 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

View 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);

View 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;
}

File diff suppressed because it is too large Load Diff

View 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

View 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();
}

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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