summaryrefslogtreecommitdiff
path: root/indra/llwindow/llwindowwin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llwindow/llwindowwin32.cpp')
-rw-r--r--indra/llwindow/llwindowwin32.cpp1407
1 files changed, 508 insertions, 899 deletions
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index a5367aac8a..87075c7318 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -2,30 +2,25 @@
* @file llwindowwin32.cpp
* @brief Platform-dependent implementation of llwindow
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* 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://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * 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://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * 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.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,31 +30,34 @@
#include "llwindowwin32.h"
+// LLWindow library includes
+#include "llkeyboardwin32.h"
+#include "lldragdropwin32.h"
+#include "llpreeditor.h"
+#include "llwindowcallbacks.h"
+
+// Linden library includes
+#include "llerror.h"
+#include "llgl.h"
+#include "llstring.h"
+#include "lldir.h"
+
+// System includes
#include <commdlg.h>
#include <WinUser.h>
#include <mapi.h>
#include <process.h> // for _spawn
#include <shellapi.h>
+#include <fstream>
#include <Imm.h>
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
+#include <Dbt.h.>
-
-#include "llkeyboardwin32.h"
-#include "llerror.h"
-#include "llgl.h"
-#include "llstring.h"
-#include "lldir.h"
-
-#include "llglheaders.h"
-
-#include "indra_constants.h"
-
-#include "llpreeditor.h"
-
+#include "llmemtype.h"
// culled from winuser.h
#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */
const S32 WM_MOUSEWHEEL = 0x020A;
@@ -82,9 +80,9 @@ LLW32MsgCallback gAsyncMsgCallback = NULL;
// LLWindowWin32
//
-void show_window_creation_error(const char* title)
+void show_window_creation_error(const std::string& title)
{
- llwarns << title << llendl;
+ LL_WARNS("Window") << title << LL_ENDL;
}
//static
@@ -359,44 +357,44 @@ LLWinImm::~LLWinImm()
}
-LPDIRECTINPUT8 g_pDI = NULL;
-LPDIRECTINPUTDEVICE8 g_pJoystick = NULL;
-BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
- VOID* pContext );
-BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
- VOID* pContext );
-
-
-LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
+LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl,
- BOOL ignore_pixel_depth)
- : LLWindow(fullscreen, flags)
+ BOOL ignore_pixel_depth,
+ U32 fsaa_samples)
+ : LLWindow(callbacks, fullscreen, flags)
{
- S32 i = 0;
+ mFSAASamples = fsaa_samples;
mIconResource = gIconResource;
mOverrideAspectRatio = 0.f;
mNativeAspectRatio = 0.f;
mMousePositionModified = FALSE;
mInputProcessingPaused = FALSE;
mPreeditor = NULL;
+ mKeyCharCode = 0;
+ mKeyScanCode = 0;
+ mKeyVirtualKey = 0;
+ mhDC = NULL;
+ mhRC = NULL;
// Initialize the keyboard
gKeyboard = new LLKeyboardWin32();
+ gKeyboard->setCallbacks(callbacks);
+
+ // Initialize the Drag and Drop functionality
+ mDragDrop = new LLDragDropWin32;
// Initialize (boot strap) the Language text input management,
// based on the system's (user's) default settings.
allowLanguageTextInput(mPreeditor, FALSE);
- GLuint pixel_format;
WNDCLASS wc;
- DWORD dw_ex_style;
- DWORD dw_style;
RECT window_rect;
// Set the window title
- if (!title)
+ if (title.empty())
{
mWindowTitle = new WCHAR[50];
wsprintf(mWindowTitle, L"OpenGL Window");
@@ -404,12 +402,12 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
else
{
mWindowTitle = new WCHAR[256]; // Assume title length < 255 chars.
- mbstowcs(mWindowTitle, title, 255);
+ mbstowcs(mWindowTitle, title.c_str(), 255);
mWindowTitle[255] = 0;
}
// Set the window class name
- if (!name)
+ if (name.empty())
{
mWindowClassName = new WCHAR[50];
wsprintf(mWindowClassName, L"OpenGL Window");
@@ -417,7 +415,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
else
{
mWindowClassName = new WCHAR[256]; // Assume title length < 255 chars.
- mbstowcs(mWindowClassName, name, 255);
+ mbstowcs(mWindowClassName, name.c_str(), 255);
mWindowClassName[255] = 0;
}
@@ -429,7 +427,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
mhInstance = GetModuleHandle(NULL);
mWndProc = NULL;
- mSwapMethod = SWAP_METHOD_EXCHANGE;
+ mSwapMethod = SWAP_METHOD_UNDEFINED;
// No WPARAM yet.
mLastSizeWParam = 0;
@@ -490,7 +488,8 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
if (!RegisterClass(&wc))
{
- OSMessageBox("RegisterClass failed", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBRegClassFailed"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return;
}
sIsClassRegistered = TRUE;
@@ -544,7 +543,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
if (closest_refresh == 0)
{
- llwarns << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << llendl;
+ LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL;
success = FALSE;
}
@@ -567,11 +566,11 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
mFullscreenBits = dev_mode.dmBitsPerPel;
mFullscreenRefresh = dev_mode.dmDisplayFrequency;
- llinfos << "Running at " << dev_mode.dmPelsWidth
+ LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth
<< "x" << dev_mode.dmPelsHeight
<< "x" << dev_mode.dmBitsPerPel
<< " @ " << dev_mode.dmDisplayFrequency
- << llendl;
+ << LL_ENDL;
}
else
{
@@ -581,54 +580,14 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
mFullscreenBits = -1;
mFullscreenRefresh = -1;
- char error[256]; /* Flawfinder: ignore */
- snprintf(error, sizeof(error), "Unable to run fullscreen at %d x %d.\nRunning in window.", width, height); /* Flawfinder: ignore */
- OSMessageBox(error, "Error", OSMB_OK);
+ std::map<std::string,std::string> args;
+ args["[WIDTH]"] = llformat("%d", width);
+ args["[HEIGHT]"] = llformat ("%d", height);
+ OSMessageBox(mCallbacks->translateString("MBFullScreenErr", args),
+ mCallbacks->translateString("MBError"), OSMB_OK);
}
}
- //-----------------------------------------------------------------------
- // Resize window to account for borders
- //-----------------------------------------------------------------------
- if (mFullscreen)
- {
- dw_ex_style = WS_EX_APPWINDOW;
- dw_style = WS_POPUP;
-
- // Move window borders out not to cover window contents
- AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
- }
- else
- {
- // Window with an edge
- dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
- dw_style = WS_OVERLAPPEDWINDOW;
- }
-
- //-----------------------------------------------------------------------
- // Create the window
- // Microsoft help indicates that GL windows must be created with
- // WS_CLIPSIBLINGS and WS_CLIPCHILDREN, but not CS_PARENTDC
- //-----------------------------------------------------------------------
- mWindowHandle = CreateWindowEx(dw_ex_style,
- mWindowClassName,
- mWindowTitle,
- WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
- x, // x pos
- y, // y pos
- window_rect.right - window_rect.left, // width
- window_rect.bottom - window_rect.top, // height
- NULL,
- NULL,
- mhInstance,
- NULL);
-
- if (!mWindowHandle)
- {
- OSMessageBox("Window creation error", "Error", OSMB_OK);
- return;
- }
-
// TODO: add this after resolving _WIN32_WINNT issue
// if (!fullscreen)
// {
@@ -641,376 +600,17 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
// }
-
- S32 pfdflags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
- if (use_gl)
- {
- pfdflags |= PFD_SUPPORT_OPENGL;
- }
-
//-----------------------------------------------------------------------
// Create GL drawing context
//-----------------------------------------------------------------------
- PIXELFORMATDESCRIPTOR pfd =
+ LLCoordScreen windowPos(x,y);
+ LLCoordScreen windowSize(window_rect.right - window_rect.left,
+ window_rect.bottom - window_rect.top);
+ if (!switchContext(mFullscreen, windowSize, TRUE, &windowPos))
{
- sizeof(PIXELFORMATDESCRIPTOR),
- 1,
- pfdflags,
- PFD_TYPE_RGBA,
- BITS_PER_PIXEL,
- 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused
- 8, // alpha bits
- 0, // alpha shift
- 0, // accum bits
- 0, 0, 0, 0, // accum RGBA
- 24, // depth bits
- 8, // stencil bits, avi added for stencil test
- 0,
- PFD_MAIN_PLANE,
- 0,
- 0, 0, 0
- };
-
- if (!(mhDC = GetDC(mWindowHandle)))
- {
- close();
- OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
return;
}
-
- if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
- {
- close();
- OSMessageBox("Can't find suitable pixel format", "Error", OSMB_OK);
- return;
- }
-
- // Verify what pixel format we actually received.
- if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
- &pfd))
- {
- close();
- OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
- return;
- }
-
- // sanity check pfd returned by Windows
- if (!ignore_pixel_depth && (pfd.cColorBits < 32))
- {
- close();
- OSMessageBox(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
- return;
- }
-
- if (!ignore_pixel_depth && (pfd.cAlphaBits < 8))
- {
- close();
- OSMessageBox(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
- return;
- }
-
- if (!SetPixelFormat(mhDC, pixel_format, &pfd))
- {
- close();
- OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
- return;
- }
-
- if (use_gl)
- {
- if (!(mhRC = wglCreateContext(mhDC)))
- {
- close();
- OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
- return;
- }
-
- if (!wglMakeCurrent(mhDC, mhRC))
- {
- close();
- OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
- return;
- }
-
- gGLManager.initWGL();
-
- if (gGLManager.mHasWGLARBPixelFormat && (wglChoosePixelFormatARB != NULL))
- {
- // OK, at this point, use the ARB wglChoosePixelFormatsARB function to see if we
- // can get exactly what we want.
- GLint attrib_list[256];
- S32 cur_attrib = 0;
-
- attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB;
- attrib_list[cur_attrib++] = 24;
-
- attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
-
- attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB;
- attrib_list[cur_attrib++] = GL_TRUE;
-
- attrib_list[cur_attrib++] = WGL_ACCELERATION_ARB;
- attrib_list[cur_attrib++] = WGL_FULL_ACCELERATION_ARB;
-
- attrib_list[cur_attrib++] = WGL_SUPPORT_OPENGL_ARB;
- attrib_list[cur_attrib++] = GL_TRUE;
-
- attrib_list[cur_attrib++] = WGL_DOUBLE_BUFFER_ARB;
- attrib_list[cur_attrib++] = GL_TRUE;
-
- attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB;
- attrib_list[cur_attrib++] = 32;
-
- attrib_list[cur_attrib++] = WGL_RED_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
-
- attrib_list[cur_attrib++] = WGL_GREEN_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
-
- attrib_list[cur_attrib++] = WGL_BLUE_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
-
- attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
-
- // End the list
- attrib_list[cur_attrib++] = 0;
-
- GLint pixel_formats[256];
- U32 num_formats = 0;
-
- // First we try and get a 32 bit depth pixel format
- BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
- if (!result)
- {
- close();
- show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit");
- return;
- }
-
- if (!num_formats)
- {
- llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl;
- // Try 24-bit format
- attrib_list[1] = 24;
- BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
- if (!result)
- {
- close();
- show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit");
- return;
- }
-
- if (!num_formats)
- {
- llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl;
- attrib_list[1] = 16;
- BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
- if (!result || !num_formats)
- {
- close();
- show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit");
- return;
- }
- }
-
- llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl;
-
- pixel_format = pixel_formats[0];
- }
-
- DestroyWindow(mWindowHandle);
-
- mWindowHandle = CreateWindowEx(dw_ex_style,
- mWindowClassName,
- mWindowTitle,
- WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
- x, // x pos
- y, // y pos
- window_rect.right - window_rect.left, // width
- window_rect.bottom - window_rect.top, // height
- NULL,
- NULL,
- mhInstance,
- NULL);
-
- if (!(mhDC = GetDC(mWindowHandle)))
- {
- close();
- OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
- return;
- }
-
- if (!SetPixelFormat(mhDC, pixel_format, &pfd))
- {
- close();
- OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
- return;
- }
-
- int swap_method = 0;
- GLint swap_query = WGL_SWAP_METHOD_ARB;
-
- if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
- {
- switch (swap_method)
- {
- case WGL_SWAP_EXCHANGE_ARB:
- mSwapMethod = SWAP_METHOD_EXCHANGE;
- llinfos << "Swap Method: Exchange" << llendl;
- break;
- case WGL_SWAP_COPY_ARB:
- mSwapMethod = SWAP_METHOD_COPY;
- llinfos << "Swap Method: Copy" << llendl;
- break;
- case WGL_SWAP_UNDEFINED_ARB:
- mSwapMethod = SWAP_METHOD_UNDEFINED;
- llinfos << "Swap Method: Undefined" << llendl;
- break;
- default:
- mSwapMethod = SWAP_METHOD_UNDEFINED;
- llinfos << "Swap Method: Unknown" << llendl;
- break;
- }
- }
- }
- else
- {
- llwarns << "No wgl_ARB_pixel_format extension, using default ChoosePixelFormat!" << llendl;
- }
-
- // Verify what pixel format we actually received.
- if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
- &pfd))
- {
- close();
- OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
- return;
- }
- llinfos << "GL buffer: Color Bits " << S32(pfd.cColorBits)
- << " Alpha Bits " << S32(pfd.cAlphaBits)
- << " Depth Bits " << S32(pfd.cDepthBits)
- << llendl;
-
- if (pfd.cColorBits < 32)
- {
- close();
- OSMessageBox(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
- return;
- }
-
- if (pfd.cAlphaBits < 8)
- {
- close();
- OSMessageBox(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
- return;
- }
-
- if (!(mhRC = wglCreateContext(mhDC)))
- {
- close();
- OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
- return;
- }
-
- if (!wglMakeCurrent(mhDC, mhRC))
- {
- close();
- OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
- return;
- }
-
- if (!gGLManager.initGL())
- {
- close();
- OSMessageBox(
- "Second Life is unable to run because your video card drivers\n"
- "are out of date or unsupported. Please make sure you have\n"
- "the latest video card drivers installed.\n\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
- return;
- }
-
- // Disable vertical sync for swap
- if (disable_vsync && wglSwapIntervalEXT)
- {
- llinfos << "Disabling vertical sync" << llendl;
- wglSwapIntervalEXT(0);
- }
- else
- {
- llinfos << "Keeping vertical sync" << llendl;
- }
-
-
- // OK, let's get the current gamma information and store it off.
- mCurrentGamma = 0.f; // Not set, default;
- if (!GetDeviceGammaRamp(mhDC, mPrevGammaRamp))
- {
- llwarns << "Unable to get device gamma ramp" << llendl;
- }
-
- // Calculate what the current gamma is. From a posting by Garrett T. Bass, Get/SetDeviceGammaRamp Demystified
- // http://apollo.iwt.uni-bielefeld.de/~ml_robot/OpenGL-04-2000/0058.html
-
- // We're going to assume that gamma's the same for all 3 channels, because I don't feel like doing it otherwise.
- // Using the red channel.
-
- F32 Csum = 0.0;
- S32 Ccount = 0;
- for (i = 0; i < 256; i++)
- {
- if (i != 0 && mPrevGammaRamp[i] != 0 && mPrevGammaRamp[i] != 65536)
- {
- F64 B = (i % 256) / 256.0;
- F64 A = mPrevGammaRamp[i] / 65536.0;
- F32 C = (F32) ( log(A) / log(B) );
- Csum += C;
- Ccount++;
- }
- }
- mCurrentGamma = Csum / Ccount;
-
- llinfos << "Previous gamma: " << mCurrentGamma << llendl;
- }
-
-
- //store this pointer for wndProc callback
- SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this);
-
+
//start with arrow cursor
initCursors();
setCursor( UI_CURSOR_ARROW );
@@ -1018,47 +618,13 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
// Initialize (boot strap) the Language text input management,
// based on the system's (or user's) default settings.
allowLanguageTextInput(NULL, FALSE);
-
- initInputDevices();
-}
-
-void LLWindowWin32::initInputDevices()
-{
- // Direct Input
- HRESULT hr;
-
- if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
- IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
- {
- llwarns << "Direct8InputCreate failed!" << llendl;
- }
- else
- {
- while(1)
- {
- // Look for a simple joystick we can use for this sample program.
- if (FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
- EnumJoysticksCallback,
- NULL, DIEDFL_ATTACHEDONLY ) ) )
- break;
- if (!g_pJoystick)
- break;
- if( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick ) ) )
- break;
- if( FAILED( hr = g_pJoystick->EnumObjects( EnumObjectsCallback,
- (VOID*)mWindowHandle, DIDFT_ALL ) ) )
- break;
- g_pJoystick->Acquire();
- break;
- }
- }
-
- SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer
}
LLWindowWin32::~LLWindowWin32()
{
+ delete mDragDrop;
+
delete [] mWindowTitle;
mWindowTitle = NULL;
@@ -1082,6 +648,7 @@ void LLWindowWin32::hide()
ShowWindow(mWindowHandle, SW_HIDE);
}
+//virtual
void LLWindowWin32::minimize()
{
setMouseClipping(FALSE);
@@ -1089,7 +656,7 @@ void LLWindowWin32::minimize()
ShowWindow(mWindowHandle, SW_MINIMIZE);
}
-
+//virtual
void LLWindowWin32::restore()
{
ShowWindow(mWindowHandle, SW_RESTORE);
@@ -1102,13 +669,15 @@ void LLWindowWin32::restore()
// Usually called from LLWindowManager::destroyWindow()
void LLWindowWin32::close()
{
- llinfos << "Closing LLWindowWin32" << llendl;
+ LL_DEBUGS("Window") << "Closing LLWindowWin32" << LL_ENDL;
// Is window is already closed?
if (!mWindowHandle)
{
return;
}
+ mDragDrop->reset();
+
// Make sure cursor is visible and we haven't mangled the clipping state.
setMouseClipping(FALSE);
showCursor();
@@ -1120,20 +689,20 @@ void LLWindowWin32::close()
}
// Clean up remaining GL state
- llinfos << "Shutting down GL" << llendl;
+ LL_DEBUGS("Window") << "Shutting down GL" << LL_ENDL;
gGLManager.shutdownGL();
- llinfos << "Releasing Context" << llendl;
+ LL_DEBUGS("Window") << "Releasing Context" << LL_ENDL;
if (mhRC)
{
if (!wglMakeCurrent(NULL, NULL))
{
- llwarns << "Release of DC and RC failed" << llendl;
+ LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL;
}
if (!wglDeleteContext(mhRC))
{
- llwarns << "Release of rendering context failed" << llendl;
+ LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL;
}
mhRC = NULL;
@@ -1144,11 +713,11 @@ void LLWindowWin32::close()
if (mhDC && !ReleaseDC(mWindowHandle, mhDC))
{
- llwarns << "Release of ghDC failed" << llendl;
+ LL_WARNS("Window") << "Release of ghDC failed" << LL_ENDL;
mhDC = NULL;
}
- llinfos << "Destroying Window" << llendl;
+ LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
// Don't process events in our mainWindowProc any longer.
SetWindowLong(mWindowHandle, GWL_USERDATA, NULL);
@@ -1159,7 +728,9 @@ void LLWindowWin32::close()
// This causes WM_DESTROY to be sent *immediately*
if (!DestroyWindow(mWindowHandle))
{
- OSMessageBox("DestroyWindow(mWindowHandle) failed", "Shutdown Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
+ mCallbacks->translateString("MBShutdownErr"),
+ OSMB_OK);
}
mWindowHandle = NULL;
@@ -1283,7 +854,7 @@ BOOL LLWindowWin32::setSize(const LLCoordScreen size)
}
// changing fullscreen resolution
-BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync)
+BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
{
GLuint pixel_format;
DEVMODE dev_mode;
@@ -1293,8 +864,13 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
RECT window_rect;
S32 width = size.mX;
S32 height = size.mY;
+ BOOL auto_show = FALSE;
- resetDisplayResolution();
+ if (mhRC)
+ {
+ auto_show = TRUE;
+ resetDisplayResolution();
+ }
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
{
@@ -1311,12 +887,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
{
if (!wglMakeCurrent(NULL, NULL))
{
- llwarns << "Release of DC and RC failed" << llendl;
+ LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL;
}
if (!wglDeleteContext(mhRC))
{
- llwarns << "Release of rendering context failed" << llendl;
+ LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL;
}
mhRC = NULL;
@@ -1350,7 +926,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
if (closest_refresh == 0)
{
- llwarns << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << llendl;
+ LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL;
return FALSE;
}
@@ -1372,11 +948,11 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
mFullscreenBits = dev_mode.dmBitsPerPel;
mFullscreenRefresh = dev_mode.dmDisplayFrequency;
- llinfos << "Running at " << dev_mode.dmPelsWidth
+ LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth
<< "x" << dev_mode.dmPelsHeight
<< "x" << dev_mode.dmBitsPerPel
<< " @ " << dev_mode.dmDisplayFrequency
- << llendl;
+ << LL_ENDL;
window_rect.left = (long) 0;
window_rect.right = (long) width; // Windows GDI rects don't include rightmost pixel
@@ -1397,18 +973,17 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
mFullscreenBits = -1;
mFullscreenRefresh = -1;
- llinfos << "Unable to run fullscreen at " << width << "x" << height << llendl;
- llinfos << "Running in window." << llendl;
+ LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL;
return FALSE;
}
}
else
{
mFullscreen = FALSE;
- window_rect.left = (long) 0;
- window_rect.right = (long) width; // Windows GDI rects don't include rightmost pixel
- window_rect.top = (long) 0;
- window_rect.bottom = (long) height;
+ window_rect.left = (long) (posp ? posp->mX : 0);
+ window_rect.right = (long) width + window_rect.left; // Windows GDI rects don't include rightmost pixel
+ window_rect.top = (long) (posp ? posp->mY : 0);
+ window_rect.bottom = (long) height + window_rect.top;
// Window with an edge
dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dw_style = WS_OVERLAPPEDWINDOW;
@@ -1458,14 +1033,16 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
if (!(mhDC = GetDC(mWindowHandle)))
{
close();
- OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBDevContextErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
{
close();
- OSMessageBox("Can't find suitable pixel format", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1474,57 +1051,48 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
&pfd))
{
close();
- OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (pfd.cColorBits < 32)
{
close();
- OSMessageBox(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBTrueColorWindow"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (pfd.cAlphaBits < 8)
{
close();
- OSMessageBox(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBAlpha"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!SetPixelFormat(mhDC, pixel_format, &pfd))
{
close();
- OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!(mhRC = wglCreateContext(mhDC)))
{
close();
- OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!wglMakeCurrent(mhDC, mhRC))
{
close();
- OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextActErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1558,17 +1126,19 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB;
attrib_list[cur_attrib++] = 24;
- attrib_list[cur_attrib++] = WGL_RED_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
-
- attrib_list[cur_attrib++] = WGL_GREEN_BITS_ARB;
+ attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB;
attrib_list[cur_attrib++] = 8;
- attrib_list[cur_attrib++] = WGL_BLUE_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
+ U32 end_attrib = 0;
+ if (mFSAASamples > 0)
+ {
+ end_attrib = cur_attrib;
+ attrib_list[cur_attrib++] = WGL_SAMPLE_BUFFERS_ARB;
+ attrib_list[cur_attrib++] = GL_TRUE;
- attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
+ attrib_list[cur_attrib++] = WGL_SAMPLES_ARB;
+ attrib_list[cur_attrib++] = mFSAASamples;
+ }
// End the list
attrib_list[cur_attrib++] = 0;
@@ -1587,36 +1157,87 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
if (!num_formats)
{
- llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl;
- // Try 24-bit format
- attrib_list[1] = 24;
- BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
- if (!result)
- {
- close();
- show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit");
- return FALSE;
+ if (end_attrib > 0)
+ {
+ LL_INFOS("Window") << "No valid pixel format for " << mFSAASamples << "x anti-aliasing." << LL_ENDL;
+ attrib_list[end_attrib] = 0;
+
+ BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
+ if (!result)
+ {
+ close();
+ show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit no AA");
+ return FALSE;
+ }
}
if (!num_formats)
{
- llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl;
- attrib_list[1] = 16;
+ LL_INFOS("Window") << "No 32 bit z-buffer, trying 24 bits instead" << LL_ENDL;
+ // Try 24-bit format
+ attrib_list[1] = 24;
BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
- if (!result || !num_formats)
+ if (!result)
{
close();
- show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit");
+ show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit");
return FALSE;
}
+
+ if (!num_formats)
+ {
+ LL_WARNS("Window") << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << LL_ENDL;
+ attrib_list[1] = 16;
+ BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
+ if (!result || !num_formats)
+ {
+ close();
+ show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit");
+ return FALSE;
+ }
+ }
}
- llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl;
+ LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL;
+ }
+
+
+
+ S32 swap_method = 0;
+ S32 cur_format = num_formats-1;
+ GLint swap_query = WGL_SWAP_METHOD_ARB;
+
+ BOOL found_format = FALSE;
+
+ while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
+ {
+ if (swap_method == WGL_SWAP_UNDEFINED_ARB || cur_format <= 0)
+ {
+ found_format = TRUE;
+ }
+ else
+ {
+ --cur_format;
+ }
+ }
+
+ pixel_format = pixel_formats[cur_format];
+
+ if (mhDC != 0) // Does The Window Have A Device Context?
+ {
+ wglMakeCurrent(mhDC, 0); // Set The Current Active Rendering Context To Zero
+ if (mhRC != 0) // Does The Window Have A Rendering Context?
+ {
+ wglDeleteContext (mhRC); // Release The Rendering Context
+ mhRC = 0; // Zero The Rendering Context
- pixel_format = pixel_formats[0];
+ }
+ ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
+ mhDC = 0; // Zero The Device Context
}
+ DestroyWindow (mWindowHandle); // Destroy The Window
+
- DestroyWindow(mWindowHandle);
mWindowHandle = CreateWindowEx(dw_ex_style,
mWindowClassName,
mWindowTitle,
@@ -1633,46 +1254,44 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
if (!(mhDC = GetDC(mWindowHandle)))
{
close();
- OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!SetPixelFormat(mhDC, pixel_format, &pfd))
{
close();
- OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
- int swap_method = 0;
- GLint swap_query = WGL_SWAP_METHOD_ARB;
-
if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
{
switch (swap_method)
{
case WGL_SWAP_EXCHANGE_ARB:
mSwapMethod = SWAP_METHOD_EXCHANGE;
- llinfos << "Swap Method: Exchange" << llendl;
+ LL_DEBUGS("Window") << "Swap Method: Exchange" << LL_ENDL;
break;
case WGL_SWAP_COPY_ARB:
mSwapMethod = SWAP_METHOD_COPY;
- llinfos << "Swap Method: Copy" << llendl;
+ LL_DEBUGS("Window") << "Swap Method: Copy" << LL_ENDL;
break;
case WGL_SWAP_UNDEFINED_ARB:
mSwapMethod = SWAP_METHOD_UNDEFINED;
- llinfos << "Swap Method: Undefined" << llendl;
+ LL_DEBUGS("Window") << "Swap Method: Undefined" << LL_ENDL;
break;
default:
mSwapMethod = SWAP_METHOD_UNDEFINED;
- llinfos << "Swap Method: Unknown" << llendl;
+ LL_DEBUGS("Window") << "Swap Method: Unknown" << LL_ENDL;
break;
}
}
}
else
{
- llwarns << "No wgl_ARB_pixel_format extension, using default ChoosePixelFormat!" << llendl;
+ LL_WARNS("Window") << "No wgl_ARB_pixel_format extension, using default ChoosePixelFormat!" << LL_ENDL;
}
// Verify what pixel format we actually received.
@@ -1680,89 +1299,83 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
&pfd))
{
close();
- OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
- llinfos << "GL buffer: Color Bits " << S32(pfd.cColorBits)
+ LL_INFOS("Window") << "GL buffer: Color Bits " << S32(pfd.cColorBits)
<< " Alpha Bits " << S32(pfd.cAlphaBits)
<< " Depth Bits " << S32(pfd.cDepthBits)
- << llendl;
+ << LL_ENDL;
- if (pfd.cColorBits < 32)
+ // make sure we have 32 bits per pixel
+ if (pfd.cColorBits < 32 || GetDeviceCaps(mhDC, BITSPIXEL) < 32)
{
close();
- OSMessageBox(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBTrueColorWindow"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (pfd.cAlphaBits < 8)
{
close();
- OSMessageBox(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBAlpha"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!(mhRC = wglCreateContext(mhDC)))
{
close();
- OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!wglMakeCurrent(mhDC, mhRC))
{
close();
- OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!gGLManager.initGL())
{
close();
- OSMessageBox(
- "Second Life is unable to run because your video card drivers\n"
- "are out of date or unsupported. Please make sure you have\n"
- "the latest video card drivers installed.\n\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
// Disable vertical sync for swap
if (disable_vsync && wglSwapIntervalEXT)
{
- llinfos << "Disabling vertical sync" << llendl;
+ LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL;
wglSwapIntervalEXT(0);
}
else
{
- llinfos << "Keeping vertical sync" << llendl;
+ LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL;
}
SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this);
- show();
- initInputDevices();
+ // register this window as handling drag/drop events from the OS
+ DragAcceptFiles( mWindowHandle, TRUE );
+
+ mDragDrop->init( mWindowHandle );
+
+ //register joystick timer callback
+ SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer
// ok to post quit messages now
mPostQuit = TRUE;
+
+ if (auto_show)
+ {
+ show();
+ glClearColor(0.0f, 0.0f, 0.0f, 0.f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ swapBuffers();
+ }
+
return TRUE;
}
@@ -1780,7 +1393,9 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre
// if the window was already maximized, MoveWindow seems to still set the maximized flag even if
// the window is smaller than maximized.
// So we're going to do a restore first (which is a ShowWindow call) (SL-44655).
- ShowWindow(mWindowHandle, SW_RESTORE);
+
+ // THIS CAUSES DEV-15484 and DEV-15949
+ //ShowWindow(mWindowHandle, SW_RESTORE);
// NOW we can call MoveWindow
MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE);
}
@@ -1800,6 +1415,20 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)
return FALSE;
}
+ // Inform the application of the new mouse position (needed for per-frame
+ // hover/picking to function).
+ LLCoordGL gl_pos;
+ convertCoords(position, &gl_pos);
+ mCallbacks->handleMouseMove(this, gl_pos, (MASK)0);
+
+ // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking.
+ // Because we have preemptively notified the application of the new
+ // mouse position via handleMouseMove() above, we need to clear out
+ // any stale mouse move events. RN/JC
+ MSG msg;
+ while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
+ { }
+
return SetCursorPos(screen_pos.mX, screen_pos.mY);
}
@@ -1909,15 +1538,14 @@ void LLWindowWin32::initCursors()
mCursor[ UI_CURSOR_TOOLZOOMIN ] = LoadCursor(module, TEXT("TOOLZOOMIN"));
mCursor[ UI_CURSOR_TOOLPICKOBJECT3 ] = LoadCursor(module, TEXT("TOOLPICKOBJECT3"));
mCursor[ UI_CURSOR_PIPETTE ] = LoadCursor(module, TEXT("TOOLPIPETTE"));
+ mCursor[ UI_CURSOR_TOOLSIT ] = LoadCursor(module, TEXT("TOOLSIT"));
+ mCursor[ UI_CURSOR_TOOLBUY ] = LoadCursor(module, TEXT("TOOLBUY"));
+ mCursor[ UI_CURSOR_TOOLOPEN ] = LoadCursor(module, TEXT("TOOLOPEN"));
// Color cursors
- mCursor[UI_CURSOR_TOOLSIT] = loadColorCursor(TEXT("TOOLSIT"));
- mCursor[UI_CURSOR_TOOLBUY] = loadColorCursor(TEXT("TOOLBUY"));
- mCursor[UI_CURSOR_TOOLPAY] = loadColorCursor(TEXT("TOOLPAY"));
- mCursor[UI_CURSOR_TOOLOPEN] = loadColorCursor(TEXT("TOOLOPEN"));
- mCursor[UI_CURSOR_TOOLPLAY] = loadColorCursor(TEXT("TOOLPLAY"));
- mCursor[UI_CURSOR_TOOLPAUSE] = loadColorCursor(TEXT("TOOLPAUSE"));
- mCursor[UI_CURSOR_TOOLMEDIAOPEN] = loadColorCursor(TEXT("TOOLMEDIAOPEN"));
+ mCursor[ UI_CURSOR_TOOLPLAY ] = loadColorCursor(TEXT("TOOLPLAY"));
+ mCursor[ UI_CURSOR_TOOLPAUSE ] = loadColorCursor(TEXT("TOOLPAUSE"));
+ mCursor[ UI_CURSOR_TOOLMEDIAOPEN ] = loadColorCursor(TEXT("TOOLMEDIAOPEN"));
// Note: custom cursors that are not found make LoadCursor() return NULL.
for( S32 i = 0; i < UI_CURSOR_COUNT; i++ )
@@ -1958,7 +1586,13 @@ void LLWindowWin32::captureMouse()
void LLWindowWin32::releaseMouse()
{
+ // *NOTE:Mani ReleaseCapture will spawn new windows messages...
+ // which will in turn call our MainWindowProc. It therefore requires
+ // pausing *and more importantly resumption* of the mainlooptimeout...
+ // just like DispatchMessage below.
+ mCallbacks->handlePauseWatchdog(this);
ReleaseCapture();
+ mCallbacks->handleResumeWatchdog(this);
}
@@ -1972,10 +1606,17 @@ void LLWindowWin32::gatherInput()
MSG msg;
int msg_count = 0;
+ LLMemType m1(LLMemType::MTYPE_GATHER_INPUT);
+
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && msg_count < MAX_MESSAGE_PER_UPDATE)
{
+ mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput");
TranslateMessage(&msg);
+
+ // turn watchdog off in here to not fail if windows is doing something wacky
+ mCallbacks->handlePauseWatchdog(this);
DispatchMessage(&msg);
+ mCallbacks->handleResumeWatchdog(this);
msg_count++;
if ( mInputProcessingPaused )
@@ -2001,7 +1642,7 @@ void LLWindowWin32::gatherInput()
}
}
*/
-
+ mCallbacks->handlePingWatchdog(this, "Main:AsyncCallbackGatherInput");
// For async host by name support. Really hacky.
if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message))
{
@@ -2016,12 +1657,18 @@ void LLWindowWin32::gatherInput()
mMousePositionModified = FALSE;
}
+static LLFastTimer::DeclareTimer FTM_KEYHANDLER("Handle Keyboard");
+static LLFastTimer::DeclareTimer FTM_MOUSEHANDLER("Handle Mouse");
+
LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param)
{
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA);
+
if (NULL != window_imp)
{
+ window_imp->mCallbacks->handleResumeWatchdog(window_imp);
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:StartWndProc");
// Has user provided their own window callback?
if (NULL != window_imp->mWndProc)
{
@@ -2032,6 +1679,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
}
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:PreSwitchWndProc");
+
// Juggle to make sure we can get negative positions for when
// mouse is outside window.
LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param));
@@ -2051,10 +1700,28 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
S32 update_height;
case WM_TIMER:
- window_imp->updateJoystick( );
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_TIMER");
+ window_imp->mCallbacks->handleTimerEvent(window_imp);
+ break;
+
+ case WM_DEVICECHANGE:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DEVICECHANGE");
+ if (gDebugWindowProc)
+ {
+ llinfos << " WM_DEVICECHANGE: wParam=" << w_param
+ << "; lParam=" << l_param << llendl;
+ }
+ if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
+ {
+ if (window_imp->mCallbacks->handleDeviceChange(window_imp))
+ {
+ return 0;
+ }
+ }
break;
case WM_PAINT:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PAINT");
GetUpdateRect(window_imp->mWindowHandle, &update_rect, FALSE);
update_width = update_rect.right - update_rect.left + 1;
update_height = update_rect.bottom - update_rect.top + 1;
@@ -2062,6 +1729,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
update_width, update_height);
break;
case WM_PARENTNOTIFY:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PARENTNOTIFY");
u_msg = u_msg;
break;
@@ -2071,6 +1739,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// Only take control of cursor over client region of window
// This allows Windows(tm) to handle resize cursors, etc.
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETCURSOR");
if (LOWORD(l_param) == HTCLIENT)
{
SetCursor(window_imp->mCursor[ window_imp->mCurrentCursor] );
@@ -2079,14 +1748,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_ENTERMENULOOP:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ENTERMENULOOP");
window_imp->mCallbacks->handleWindowBlock(window_imp);
break;
case WM_EXITMENULOOP:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_EXITMENULOOP");
window_imp->mCallbacks->handleWindowUnblock(window_imp);
break;
case WM_ACTIVATEAPP:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATEAPP");
{
// This message should be sent whenever the app gains or loses focus.
BOOL activating = (BOOL) w_param;
@@ -2094,11 +1766,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
if (gDebugWindowProc)
{
- llinfos << "WINDOWPROC ActivateApp "
+ LL_INFOS("Window") << "WINDOWPROC ActivateApp "
<< " activating " << S32(activating)
<< " minimized " << S32(minimized)
<< " fullscreen " << S32(window_imp->mFullscreen)
- << llendl;
+ << LL_ENDL;
}
if (window_imp->mFullscreen)
@@ -2116,10 +1788,14 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->resetDisplayResolution();
}
}
+
+ window_imp->mCallbacks->handleActivateApp(window_imp, activating);
+
break;
}
case WM_ACTIVATE:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATE");
{
// Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE
BOOL activating = (LOWORD(w_param) != WA_INACTIVE);
@@ -2136,10 +1812,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// properly when we run fullscreen.
if (gDebugWindowProc)
{
- llinfos << "WINDOWPROC Activate "
+ LL_INFOS("Window") << "WINDOWPROC Activate "
<< " activating " << S32(activating)
<< " minimized " << S32(minimized)
- << llendl;
+ << LL_ENDL;
}
// Don't handle this.
@@ -2151,6 +1827,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_SYSCOMMAND:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSCOMMAND");
switch(w_param)
{
case SC_KEYMENU:
@@ -2165,6 +1842,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_CLOSE:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CLOSE");
// Will the app allow the window to close?
if (window_imp->mCallbacks->handleCloseRequest(window_imp))
{
@@ -2175,6 +1853,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
case WM_DESTROY:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DESTROY");
if (window_imp->shouldPostQuit())
{
PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0
@@ -2182,6 +1861,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
case WM_COMMAND:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COMMAND");
if (!HIWORD(w_param)) // this message is from a menu
{
window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param));
@@ -2189,15 +1869,21 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_SYSKEYDOWN:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSKEYDOWN");
// allow system keys, such as ALT-F4 to be processed by Windows
eat_keystroke = FALSE;
case WM_KEYDOWN:
+ window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next
+ window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
+ window_imp->mKeyVirtualKey = w_param;
+
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN");
{
if (gDebugWindowProc)
{
- llinfos << "Debug WindowProc WM_KEYDOWN "
+ LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
<< " key " << S32(w_param)
- << llendl;
+ << LL_ENDL;
}
if(gKeyboard->handleKeyDown(w_param, mask) && eat_keystroke)
{
@@ -2210,13 +1896,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
eat_keystroke = FALSE;
case WM_KEYUP:
{
- LLFastTimer t2(LLFastTimer::FTM_KEYHANDLER);
+ window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
+ window_imp->mKeyVirtualKey = w_param;
+
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
+ LLFastTimer t2(FTM_KEYHANDLER);
if (gDebugWindowProc)
{
- llinfos << "Debug WindowProc WM_KEYUP "
+ LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
<< " key " << S32(w_param)
- << llendl;
+ << LL_ENDL;
}
if (gKeyboard->handleKeyUp(w_param, mask) && eat_keystroke)
{
@@ -2227,6 +1917,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
}
case WM_IME_SETCONTEXT:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_SETCONTEXT");
+ if (gDebugWindowProc)
+ {
+ llinfos << "WM_IME_SETCONTEXT" << llendl;
+ }
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW;
@@ -2235,6 +1930,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_IME_STARTCOMPOSITION:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_STARTCOMPOSITION");
+ if (gDebugWindowProc)
+ {
+ llinfos << "WM_IME_STARTCOMPOSITION" << llendl;
+ }
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->handleStartCompositionMessage();
@@ -2243,6 +1943,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_IME_ENDCOMPOSITION:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_ENDCOMPOSITION");
+ if (gDebugWindowProc)
+ {
+ llinfos << "WM_IME_ENDCOMPOSITION" << llendl;
+ }
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
return 0;
@@ -2250,6 +1955,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_IME_COMPOSITION:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_COMPOSITION");
+ if (gDebugWindowProc)
+ {
+ llinfos << "WM_IME_COMPOSITION" << llendl;
+ }
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->handleCompositionMessage(l_param);
@@ -2258,6 +1968,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_IME_REQUEST:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_REQUEST");
+ if (gDebugWindowProc)
+ {
+ llinfos << "WM_IME_REQUEST" << llendl;
+ }
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
LRESULT result = 0;
@@ -2269,6 +1984,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
case WM_CHAR:
+ window_imp->mKeyCharCode = w_param;
+
// Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
// to figure out how that works. - Doug
//
@@ -2279,13 +1996,12 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// it is worth trying. The good old WM_CHAR works just fine even for supplementary
// characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
// by ourselves. It is not that tough. -- Alissa Sabre @ SL
- //
- // llinfos << "WM_CHAR: " << w_param << llendl;
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CHAR");
if (gDebugWindowProc)
{
- llinfos << "Debug WindowProc WM_CHAR "
+ LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
<< " key " << S32(w_param)
- << llendl;
+ << LL_ENDL;
}
// Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
// we *did* processed the event, so I believe we should not pass it to DefWindowProc...
@@ -2294,7 +2010,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_LBUTTONDOWN:
{
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN");
+ LLFastTimer t2(FTM_MOUSEHANDLER);
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
@@ -2316,6 +2033,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask))
{
return 0;
@@ -2327,6 +2046,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
//RN: ignore right button double clicks for now
//case WM_RBUTTONDBLCLK:
{
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK");
// Because we move the cursor position in the app, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the
@@ -2343,6 +2063,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask) )
{
return 0;
@@ -2352,10 +2074,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_LBUTTONUP:
{
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP");
+ LLFastTimer t2(FTM_MOUSEHANDLER);
//if (gDebugClicks)
//{
- // llinfos << "WndProc left button up" << llendl;
+ // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL;
//}
// Because we move the cursor position in the app, we need to query
// to find out where the cursor at the time the event is handled.
@@ -2373,6 +2096,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleMouseUp(window_imp, gl_coord, mask))
{
return 0;
@@ -2383,13 +2108,14 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_RBUTTONDBLCLK:
case WM_RBUTTONDOWN:
{
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONDOWN");
+ LLFastTimer t2(FTM_MOUSEHANDLER);
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
}
- // Because we move the cursor position in tllviewerhe app, we need to query
+ // Because we move the cursor position in the llviewerapp, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the
// first click changes the cursor position, all subsequent clicks
@@ -2405,6 +2131,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask))
{
return 0;
@@ -2414,7 +2142,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_RBUTTONUP:
{
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONUP");
+ LLFastTimer t2(FTM_MOUSEHANDLER);
// Because we move the cursor position in the app, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the
@@ -2431,6 +2160,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask))
{
return 0;
@@ -2441,7 +2172,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_MBUTTONDOWN:
// case WM_MBUTTONDBLCLK:
{
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN");
+ LLFastTimer t2(FTM_MOUSEHANDLER);
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
@@ -2463,6 +2195,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask))
{
return 0;
@@ -2472,8 +2206,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_MBUTTONUP:
{
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
- // Because we move the cursor position in tllviewerhe app, we need to query
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP");
+ LLFastTimer t2(FTM_MOUSEHANDLER);
+ // Because we move the cursor position in the llviewer app, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the
// first click changes the cursor position, all subsequent clicks
@@ -2489,6 +2224,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->convertCoords(window_coord, &gl_coord);
}
MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask))
{
return 0;
@@ -2498,9 +2235,30 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_MOUSEWHEEL:
{
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEWHEEL");
static short z_delta = 0;
- z_delta += HIWORD(w_param);
+ RECT client_rect;
+
+ // eat scroll events that occur outside our window, since we use mouse position to direct scroll
+ // instead of keyboard focus
+ // NOTE: mouse_coord is in *window* coordinates for scroll events
+ POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)};
+
+ if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
+ && GetClientRect(window_imp->mWindowHandle, &client_rect))
+ {
+ // we have a valid mouse point and client rect
+ if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
+ || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
+ {
+ // mouse is outside of client rect, so don't do anything
+ return 0;
+ }
+ }
+
+ S16 incoming_z_delta = HIWORD(w_param);
+ z_delta += incoming_z_delta;
// cout << "z_delta " << z_delta << endl;
// current mouse wheels report changes in increments of zDelta (+120, -120)
@@ -2534,6 +2292,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// Handle mouse movement within the window
case WM_MOUSEMOVE:
{
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEMOVE");
window_imp->convertCoords(window_coord, &gl_coord);
MASK mask = gKeyboard->currentMask(TRUE);
window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
@@ -2542,6 +2301,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_SIZE:
{
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SIZE");
S32 width = S32( LOWORD(l_param) );
S32 height = S32( HIWORD(l_param) );
@@ -2551,12 +2311,12 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
BOOL restored = ( w_param == SIZE_RESTORED );
BOOL minimized = ( w_param == SIZE_MINIMIZED );
- llinfos << "WINDOWPROC Size "
+ LL_INFOS("Window") << "WINDOWPROC Size "
<< width << "x" << height
<< " max " << S32(maximized)
<< " min " << S32(minimized)
<< " rest " << S32(restored)
- << llendl;
+ << LL_ENDL;
}
// There's an odd behavior with WM_SIZE that I would call a bug. If
@@ -2600,29 +2360,39 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
case WM_SETFOCUS:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS");
if (gDebugWindowProc)
{
- llinfos << "WINDOWPROC SetFocus" << llendl;
+ LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
}
window_imp->mCallbacks->handleFocus(window_imp);
return 0;
case WM_KILLFOCUS:
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KILLFOCUS");
if (gDebugWindowProc)
{
- llinfos << "WINDOWPROC KillFocus" << llendl;
+ LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
}
window_imp->mCallbacks->handleFocusLost(window_imp);
return 0;
case WM_COPYDATA:
- // received a URL
- PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param;
- window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData);
+ {
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COPYDATA");
+ // received a URL
+ PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param;
+ window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData);
+ };
return 0;
+
+ break;
}
+
+ window_imp->mCallbacks->handlePauseWatchdog(window_imp);
}
+
// pass unhandled messages down to Windows
return DefWindowProc(h_wnd, u_msg, w_param, l_param);
}
@@ -2750,7 +2520,7 @@ BOOL LLWindowWin32::pasteTextFromClipboard(LLWString &dst)
if (utf16str)
{
dst = utf16str_to_wstring(utf16str);
- LLWString::removeCRLF(dst);
+ LLWStringUtil::removeCRLF(dst);
GlobalUnlock(h_data);
success = TRUE;
}
@@ -2773,7 +2543,7 @@ BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr)
// Provide a copy of the data in Unicode format.
LLWString sanitized_string(wstr);
- LLWString::addCRLF(sanitized_string);
+ LLWStringUtil::addCRLF(sanitized_string);
llutf16string out_utf16 = wstring_to_utf16str(sanitized_string);
const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(WCHAR);
@@ -2860,86 +2630,6 @@ BOOL LLWindowWin32::getClientRectInScreenSpace( RECT* rectp )
return success;
}
-
-BOOL LLWindowWin32::sendEmail(const char* address, const char* subject, const char* body_text,
- const char* attachment, const char* attachment_displayed_name )
-{
- // Based on "A SendMail() DLL" by Greg Turner, Windows Developer Magazine, Nov. 1997.
- // See article for use of GetProcAddress
- // No restrictions on use.
-
- enum SendResult
- {
- LL_EMAIL_SUCCESS,
- LL_EMAIL_MAPI_NOT_INSTALLED, // No MAPI Server (eg Microsoft Exchange) installed
- LL_EMAIL_MAPILOAD_FAILED, // Load of MAPI32.DLL failed
- LL_EMAIL_SEND_FAILED // The message send itself failed
- };
-
- SendResult result = LL_EMAIL_SUCCESS;
-
- U32 mapi_installed = GetProfileInt(L"Mail", L"MAPI", 0);
- if( !mapi_installed)
- {
- result = LL_EMAIL_MAPI_NOT_INSTALLED;
- }
- else
- {
- HINSTANCE hMAPIInst = LoadLibrary(L"MAPI32.DLL"); /* Flawfinder: ignore */
- if(!hMAPIInst)
- {
- result = LL_EMAIL_MAPILOAD_FAILED;
- }
- else
- {
- LPMAPISENDMAIL pMAPISendMail = (LPMAPISENDMAIL) GetProcAddress(hMAPIInst, "MAPISendMail");
-
- // Send the message
- MapiRecipDesc recipients[1];
- recipients[0].ulReserved = 0;
- recipients[0].ulRecipClass = MAPI_TO;
- recipients[0].lpszName = (char*)address;
- recipients[0].lpszAddress = (char*)address;
- recipients[0].ulEIDSize = 0;
- recipients[0].lpEntryID = 0;
-
- MapiFileDesc files[1];
- files[0].ulReserved = 0;
- files[0].flFlags = 0; // non-OLE file
- files[0].nPosition = -1; // Leave file location in email unspecified.
- files[0].lpszPathName = (char*)attachment; // Must be fully qualified name, including drive letter.
- files[0].lpszFileName = (char*)attachment_displayed_name; // If NULL, uses attachment as displayed name.
- files[0].lpFileType = NULL; // Recipient will have to figure out what kind of file this is.
-
- MapiMessage msg;
- memset(&msg, 0, sizeof(msg));
- msg.lpszSubject = (char*)subject; // may be NULL
- msg.lpszNoteText = (char*)body_text;
- msg.nRecipCount = address ? 1 : 0;
- msg.lpRecips = address ? recipients : NULL;
- msg.nFileCount = attachment ? 1 : 0;
- msg.lpFiles = attachment ? files : NULL;
-
- U32 success = pMAPISendMail(0, (U32) mWindowHandle, &msg, MAPI_DIALOG|MAPI_LOGON_UI|MAPI_NEW_SESSION, 0);
- if(success != SUCCESS_SUCCESS)
- {
- result = LL_EMAIL_SEND_FAILED;
- }
-
- FreeLibrary(hMAPIInst);
- }
- }
-
- return result == LL_EMAIL_SUCCESS;
-}
-
-
-S32 LLWindowWin32::stat(const char* file_name, struct stat* stat_info)
-{
- llassert( sizeof(struct stat) == sizeof(struct _stat) ); // They are defined identically in sys/stat.h, but I'm paranoid.
- return LLFile::stat( file_name, (struct _stat*) stat_info );
-}
-
void LLWindowWin32::flashIcon(F32 seconds)
{
FLASHWINFO flash_info;
@@ -2966,7 +2656,7 @@ BOOL LLWindowWin32::setGamma(const F32 gamma)
{
mCurrentGamma = gamma;
- llinfos << "Setting gamma to " << gamma << llendl;
+ LL_DEBUGS("Window") << "Setting gamma to " << gamma << LL_ENDL;
for ( int i = 0; i < 256; ++i )
{
@@ -2985,6 +2675,16 @@ BOOL LLWindowWin32::setGamma(const F32 gamma)
return SetDeviceGammaRamp ( mhDC, mCurrentGammaRamp );
}
+void LLWindowWin32::setFSAASamples(const U32 fsaa_samples)
+{
+ mFSAASamples = fsaa_samples;
+}
+
+U32 LLWindowWin32::getFSAASamples()
+{
+ return mFSAASamples;
+}
+
LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions)
{
if (!mSupportedResolutions)
@@ -3097,8 +2797,8 @@ BOOL LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 bits, S32 re
if (!success)
{
- llwarns << "setDisplayResolution failed, "
- << width << "x" << height << "x" << bits << " @ " << refresh << llendl;
+ LL_WARNS("Window") << "setDisplayResolution failed, "
+ << width << "x" << height << "x" << bits << " @ " << refresh << LL_ENDL;
}
return success;
@@ -3120,7 +2820,7 @@ BOOL LLWindowWin32::setFullscreenResolution()
// protected
BOOL LLWindowWin32::resetDisplayResolution()
{
- llinfos << "resetDisplayResolution START" << llendl;
+ LL_DEBUGS("Window") << "resetDisplayResolution START" << LL_ENDL;
LONG cds_result = ChangeDisplaySettings(NULL, 0);
@@ -3128,10 +2828,10 @@ BOOL LLWindowWin32::resetDisplayResolution()
if (!success)
{
- llwarns << "resetDisplayResolution failed" << llendl;
+ LL_WARNS("Window") << "resetDisplayResolution failed" << LL_ENDL;
}
- llinfos << "resetDisplayResolution END" << llendl;
+ LL_DEBUGS("Window") << "resetDisplayResolution END" << LL_ENDL;
return success;
}
@@ -3142,81 +2842,6 @@ void LLWindowWin32::swapBuffers()
}
-BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
- VOID* pContext )
-{
- HRESULT hr;
-
- // Obtain an interface to the enumerated joystick.
- hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
-
- // If it failed, then we can't use this joystick. (Maybe the user unplugged
- // it while we were in the middle of enumerating it.)
- if( FAILED(hr) )
- return DIENUM_CONTINUE;
-
- // Stop enumeration. Note: we're just taking the first joystick we get. You
- // could store all the enumerated joysticks and let the user pick.
- return DIENUM_STOP;
-}
-
-BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
- VOID* pContext )
-{
- if( pdidoi->dwType & DIDFT_AXIS )
- {
- DIPROPRANGE diprg;
- diprg.diph.dwSize = sizeof(DIPROPRANGE);
- diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
- diprg.diph.dwHow = DIPH_BYID;
- diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
- diprg.lMin = -1000;
- diprg.lMax = +1000;
-
- // Set the range for the axis
- if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
- return DIENUM_STOP;
-
- }
- return DIENUM_CONTINUE;
-}
-
-void LLWindowWin32::updateJoystick( )
-{
- HRESULT hr;
- DIJOYSTATE js; // DInput joystick state
-
- if (!g_pJoystick)
- return;
- hr = g_pJoystick->Poll();
- if ( hr == DIERR_INPUTLOST )
- {
- hr = g_pJoystick->Acquire();
- return;
- }
- else if ( FAILED(hr) )
- return;
-
- // Get the input's device state
- if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js ) ) )
- return; // The device should have been acquired during the Poll()
-
- mJoyAxis[0] = js.lX/1000.f;
- mJoyAxis[1] = js.lY/1000.f;
- mJoyAxis[2] = js.lZ/1000.f;
- mJoyAxis[3] = js.lRx/1000.f;
- mJoyAxis[4] = js.lRy/1000.f;
- mJoyAxis[5] = js.lRz/1000.f;
- mJoyAxis[6] = js.rglSlider[0]/1000.f;
- mJoyAxis[7] = js.rglSlider[1]/1000.f;
-
- for (U32 i = 0; i < 16; i++)
- {
- mJoyButtonState[i] = js.rgbButtons[i];
- }
-}
-
-
//
// LLSplashScreenImp
//
@@ -3242,12 +2867,20 @@ void LLSplashScreenWin32::showImpl()
}
-void LLSplashScreenWin32::updateImpl(const char *mesg)
+void LLSplashScreenWin32::updateImpl(const std::string& mesg)
{
if (!mWindow) return;
- WCHAR w_mesg[1024];
- mbstowcs(w_mesg, mesg, 1024);
+ int output_str_len = MultiByteToWideChar(CP_UTF8, 0, mesg.c_str(), mesg.length(), NULL, 0);
+ if( output_str_len>1024 )
+ return;
+
+ WCHAR w_mesg[1025];//big enought to keep null terminatos
+
+ MultiByteToWideChar (CP_UTF8, 0, mesg.c_str(), mesg.length(), w_mesg, output_str_len);
+
+ //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858
+ w_mesg[output_str_len] = 0;
SendDlgItemMessage(mWindow,
666, // HACK: text id
@@ -3279,7 +2912,7 @@ LRESULT CALLBACK LLSplashScreenWin32::windowProc(HWND h_wnd, UINT u_msg,
// Helper Funcs
//
-S32 OSMessageBoxWin32(const char* text, const char* caption, U32 type)
+S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type)
{
UINT uType;
@@ -3300,7 +2933,7 @@ S32 OSMessageBoxWin32(const char* text, const char* caption, U32 type)
}
// HACK! Doesn't properly handle wide strings!
- int retval_win = MessageBoxA(NULL, text, caption, uType);
+ int retval_win = MessageBoxA(NULL, text.c_str(), caption.c_str(), uType);
S32 retval;
switch(retval_win)
@@ -3326,15 +2959,13 @@ S32 OSMessageBoxWin32(const char* text, const char* caption, U32 type)
}
-void spawn_web_browser(const char* escaped_url )
+void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async)
{
bool found = false;
S32 i;
for (i = 0; i < gURLProtocolWhitelistCount; i++)
{
- S32 len = strlen(gURLProtocolWhitelist[i]); /* Flawfinder: ignore */
- if (!strncmp(escaped_url, gURLProtocolWhitelist[i], len)
- && escaped_url[len] == ':')
+ if (escaped_url.find(gURLProtocolWhitelist[i]) == 0)
{
found = true;
break;
@@ -3343,84 +2974,48 @@ void spawn_web_browser(const char* escaped_url )
if (!found)
{
- llwarns << "spawn_web_browser() called for url with protocol not on whitelist: " << escaped_url << llendl;
+ LL_WARNS("Window") << "spawn_web_browser() called for url with protocol not on whitelist: " << escaped_url << LL_ENDL;
return;
}
- llinfos << "Opening URL " << escaped_url << llendl;
+ LL_INFOS("Window") << "Opening URL " << escaped_url << LL_ENDL;
- // Figure out the user's default web browser
- // HKEY_CLASSES_ROOT\http\shell\open\command
- char reg_path_str[256]; /* Flawfinder: ignore */
- snprintf(reg_path_str, sizeof(reg_path_str), "%s\\shell\\open\\command", gURLProtocolWhitelistHandler[i]); /* Flawfinder: ignore */
- WCHAR reg_path_wstr[256];
- mbstowcs(reg_path_wstr, reg_path_str, sizeof(reg_path_wstr)/sizeof(reg_path_wstr[0]));
+ // replaced ShellExecute code with ShellExecuteEx since ShellExecute doesn't work
+ // reliablly on Vista.
- HKEY key;
- WCHAR browser_open_wstr[1024];
- DWORD buffer_length = 1024;
- RegOpenKeyEx(HKEY_CLASSES_ROOT, reg_path_wstr, 0, KEY_QUERY_VALUE, &key);
- RegQueryValueEx(key, NULL, NULL, NULL, (LPBYTE)browser_open_wstr, &buffer_length);
- RegCloseKey(key);
+ // this is madness.. no, this is..
+ LLWString url_wstring = utf8str_to_wstring( escaped_url );
+ llutf16string url_utf16 = wstring_to_utf16str( url_wstring );
- // Convert to STL string
- LLWString browser_open_wstring = utf16str_to_wstring(browser_open_wstr);
-
- if (browser_open_wstring.length() < 2)
+ // let the OS decide what to use to open the URL
+ SHELLEXECUTEINFO sei = { sizeof( sei ) };
+ // NOTE: this assumes that SL will stick around long enough to complete the DDE message exchange
+ // necessary for ShellExecuteEx to complete
+ if (async)
{
- llwarns << "Invalid browser executable in registry " << browser_open_wstring << llendl;
- return;
+ sei.fMask = SEE_MASK_ASYNCOK;
}
+ sei.nShow = SW_SHOWNORMAL;
+ sei.lpVerb = L"open";
+ sei.lpFile = url_utf16.c_str();
+ ShellExecuteEx( &sei );
+}
- // Extract the process that's supposed to be launched
- LLWString browser_executable;
- if (browser_open_wstring[0] == '"')
- {
- // executable is quoted, find the matching quote
- size_t quote_pos = browser_open_wstring.find('"', 1);
- // copy out the string including both quotes
- browser_executable = browser_open_wstring.substr(0, quote_pos+1);
- }
- else
- {
- // executable not quoted, find a space
- size_t space_pos = browser_open_wstring.find(' ', 1);
- browser_executable = browser_open_wstring.substr(0, space_pos);
- }
-
- llinfos << "Browser reg key: " << wstring_to_utf8str(browser_open_wstring) << llendl;
- llinfos << "Browser executable: " << wstring_to_utf8str(browser_executable) << llendl;
-
- // Convert URL to wide string for Windows API
- // Assume URL is UTF8, as can come from scripts
- LLWString url_wstring = utf8str_to_wstring(escaped_url);
- llutf16string url_utf16 = wstring_to_utf16str(url_wstring);
+/*
+ Make the raw keyboard data available - used to poke through to LLQtWebKit so
+ that Qt/Webkit has access to the virtual keycodes etc. that it needs
+*/
+LLSD LLWindowWin32::getNativeKeyData()
+{
+ LLSD result = LLSD::emptyMap();
- // Convert executable and path to wide string for Windows API
- llutf16string browser_exec_utf16 = wstring_to_utf16str(browser_executable);
+ result["scan_code"] = (S32)mKeyScanCode;
+ result["virtual_key"] = (S32)mKeyVirtualKey;
- // ShellExecute returns HINSTANCE for backwards compatiblity.
- // MS docs say to cast to int and compare to 32.
- HWND our_window = NULL;
- LPCWSTR directory_wstr = NULL;
- int retval = (int) ShellExecute(our_window, /* Flawfinder: ignore */
- L"open",
- browser_exec_utf16.c_str(),
- url_utf16.c_str(),
- directory_wstr,
- SW_SHOWNORMAL);
- if (retval > 32)
- {
- llinfos << "load_url success with " << retval << llendl;
- }
- else
- {
- llinfos << "load_url failure with " << retval << llendl;
- }
+ return result;
}
-
-BOOL LLWindowWin32::dialog_color_picker ( F32 *r, F32 *g, F32 *b )
+BOOL LLWindowWin32::dialogColorPicker( F32 *r, F32 *g, F32 *b )
{
BOOL retval = FALSE;
@@ -3859,7 +3454,7 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
{
for (LLWString::const_iterator i = result_string.begin(); i != result_string.end(); i++)
{
- mPreeditor->handleUnicodeCharHere(*i, FALSE);
+ mPreeditor->handleUnicodeCharHere(*i);
}
}
@@ -3914,6 +3509,13 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng
return wtext.substr(start, end - start);
}
+// final stage of handling drop requests - both from WM_DROPFILES message
+// for files and via IDropTarget interface requests.
+LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url )
+{
+ return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url );
+}
+
// Handle WM_IME_REQUEST message.
// If it handled the message, returns TRUE. Otherwise, FALSE.
// When it handled the message, the value to be returned from
@@ -3947,7 +3549,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
// WCHARs, i.e., UTF-16 encoding units, so we can't simply pass the
// number to getPreeditLocation.
- const LLWString & wtext = mPreeditor->getWText();
+ const LLWString & wtext = mPreeditor->getPreeditString();
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
LLCoordGL caret_coord;
@@ -3956,7 +3558,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
if (!mPreeditor->getPreeditLocation(position, &caret_coord, &preedit_bounds, &text_control))
{
- llwarns << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << llendl;
+ LL_WARNS("Window") << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << LL_ENDL;
return FALSE;
}
fillCharPosition(caret_coord, preedit_bounds, text_control, char_position);
@@ -3974,7 +3576,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
case IMR_RECONVERTSTRING:
{
mPreeditor->resetPreedit();
- const LLWString & wtext = mPreeditor->getWText();
+ const LLWString & wtext = mPreeditor->getPreeditString();
S32 select, select_length;
mPreeditor->getSelectionRange(&select, &select_length);
@@ -4016,7 +3618,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
}
case IMR_DOCUMENTFEED:
{
- const LLWString & wtext = mPreeditor->getWText();
+ const LLWString & wtext = mPreeditor->getPreeditString();
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
@@ -4043,5 +3645,12 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
return FALSE;
}
+//static
+std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
+{
+ // Fonts previously in getFontListSans() have moved to fonts.xml.
+ return std::vector<std::string>();
+}
+
#endif // LL_WINDOWS