aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llwindow/llwindowwin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llwindow/llwindowwin32.cpp1074
1 files changed, 310 insertions, 764 deletions
diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp
index f6beb79..b14df5e 100644
--- a/linden/indra/llwindow/llwindowwin32.cpp
+++ b/linden/indra/llwindow/llwindowwin32.cpp
@@ -1,4 +1,4 @@
1/** 1/**
2 * @file llwindowwin32.cpp 2 * @file llwindowwin32.cpp
3 * @brief Platform-dependent implementation of llwindow 3 * @brief Platform-dependent implementation of llwindow
4 * 4 *
@@ -46,7 +46,7 @@
46#define DIRECTINPUT_VERSION 0x0800 46#define DIRECTINPUT_VERSION 0x0800
47 47
48#include <dinput.h> 48#include <dinput.h>
49 49#include <Dbt.h.>
50 50
51#include "llkeyboardwin32.h" 51#include "llkeyboardwin32.h"
52#include "llerror.h" 52#include "llerror.h"
@@ -103,7 +103,7 @@ LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1);
103// as a default, and we can't link against imm32.lib statically. 103// as a default, and we can't link against imm32.lib statically.
104// I believe DLL loading of this type is best suited to do 104// I believe DLL loading of this type is best suited to do
105// in a static initialization of a class. What I'm not sure is 105// in a static initialization of a class. What I'm not sure is
106// whether it follows the Linden Conding Standard... 106// whether it follows the Linden Conding Standard...
107// See http://wiki.secondlife.com/wiki/Coding_standards#Static_Members 107// See http://wiki.secondlife.com/wiki/Coding_standards#Static_Members
108 108
109class LLWinImm 109class LLWinImm
@@ -113,16 +113,16 @@ public:
113 113
114public: 114public:
115 // Wrappers for IMM API. 115 // Wrappers for IMM API.
116 static BOOL isIME(HKL hkl); 116 static BOOL isIME(HKL hkl);
117 static HWND getDefaultIMEWnd(HWND hwnd); 117 static HWND getDefaultIMEWnd(HWND hwnd);
118 static HIMC getContext(HWND hwnd); 118 static HIMC getContext(HWND hwnd);
119 static BOOL releaseContext(HWND hwnd, HIMC himc); 119 static BOOL releaseContext(HWND hwnd, HIMC himc);
120 static BOOL getOpenStatus(HIMC himc); 120 static BOOL getOpenStatus(HIMC himc);
121 static BOOL setOpenStatus(HIMC himc, BOOL status); 121 static BOOL setOpenStatus(HIMC himc, BOOL status);
122 static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence); 122 static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence);
123 static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence); 123 static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence);
124 static BOOL getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form); 124 static BOOL getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);
125 static BOOL setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form); 125 static BOOL setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);
126 static LONG getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length); 126 static LONG getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length);
127 static BOOL setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength); 127 static BOOL setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength);
128 static BOOL setCompositionFont(HIMC himc, LPLOGFONTW logfont); 128 static BOOL setCompositionFont(HIMC himc, LPLOGFONTW logfont);
@@ -160,10 +160,10 @@ LLWinImm LLWinImm::sTheInstance;
160 160
161LLWinImm::LLWinImm() : mHImmDll(NULL) 161LLWinImm::LLWinImm() : mHImmDll(NULL)
162{ 162{
163 // Check system metrics 163 // Check system metrics
164 if ( !GetSystemMetrics( SM_DBCSENABLED ) ) 164 if ( !GetSystemMetrics( SM_DBCSENABLED ) )
165 return; 165 return;
166 166
167 167
168 mHImmDll = LoadLibraryA("Imm32"); 168 mHImmDll = LoadLibraryA("Imm32");
169 if (mHImmDll != NULL) 169 if (mHImmDll != NULL)
@@ -200,13 +200,13 @@ LLWinImm::LLWinImm() : mHImmDll(NULL)
200 mImmSetCandidateWindow == NULL || 200 mImmSetCandidateWindow == NULL ||
201 mImmNotifyIME == NULL) 201 mImmNotifyIME == NULL)
202 { 202 {
203 // If any of the above API entires are not found, we can't use IMM API. 203 // If any of the above API entires are not found, we can't use IMM API.
204 // So, turn off the IMM support. We should log some warning message in 204 // So, turn off the IMM support. We should log some warning message in
205 // the case, since it is very unusual; these APIs are available from 205 // the case, since it is very unusual; these APIs are available from
206 // the beginning, and all versions of IMM32.DLL should have them all. 206 // the beginning, and all versions of IMM32.DLL should have them all.
207 // Unfortunately, this code may be executed before initialization of 207 // Unfortunately, this code may be executed before initialization of
208 // the logging channel (llwarns), and we can't do it here... Yes, this 208 // the logging channel (llwarns), and we can't do it here... Yes, this
209 // is one of disadvantages to use static constraction to DLL loading. 209 // is one of disadvantages to use static constraction to DLL loading.
210 FreeLibrary(mHImmDll); 210 FreeLibrary(mHImmDll);
211 mHImmDll = NULL; 211 mHImmDll = NULL;
212 212
@@ -231,117 +231,117 @@ LLWinImm::LLWinImm() : mHImmDll(NULL)
231} 231}
232 232
233 233
234// static 234// static
235BOOL LLWinImm::isIME(HKL hkl) 235BOOL LLWinImm::isIME(HKL hkl)
236{ 236{
237 if ( sTheInstance.mImmIsIME ) 237 if ( sTheInstance.mImmIsIME )
238 return sTheInstance.mImmIsIME(hkl); 238 return sTheInstance.mImmIsIME(hkl);
239 return FALSE; 239 return FALSE;
240} 240}
241 241
242// static 242// static
243HIMC LLWinImm::getContext(HWND hwnd) 243HIMC LLWinImm::getContext(HWND hwnd)
244{ 244{
245 if ( sTheInstance.mImmGetContext ) 245 if ( sTheInstance.mImmGetContext )
246 return sTheInstance.mImmGetContext(hwnd); 246 return sTheInstance.mImmGetContext(hwnd);
247 return 0; 247 return 0;
248} 248}
249 249
250//static 250//static
251BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc) 251BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc)
252{ 252{
253 if ( sTheInstance.mImmIsIME ) 253 if ( sTheInstance.mImmIsIME )
254 return sTheInstance.mImmReleaseContext(hwnd, himc); 254 return sTheInstance.mImmReleaseContext(hwnd, himc);
255 return FALSE; 255 return FALSE;
256} 256}
257 257
258// static 258// static
259BOOL LLWinImm::getOpenStatus(HIMC himc) 259BOOL LLWinImm::getOpenStatus(HIMC himc)
260{ 260{
261 if ( sTheInstance.mImmGetOpenStatus ) 261 if ( sTheInstance.mImmGetOpenStatus )
262 return sTheInstance.mImmGetOpenStatus(himc); 262 return sTheInstance.mImmGetOpenStatus(himc);
263 return FALSE; 263 return FALSE;
264} 264}
265 265
266// static 266// static
267BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) 267BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
268{ 268{
269 if ( sTheInstance.mImmSetOpenStatus ) 269 if ( sTheInstance.mImmSetOpenStatus )
270 return sTheInstance.mImmSetOpenStatus(himc, status); 270 return sTheInstance.mImmSetOpenStatus(himc, status);
271 return FALSE; 271 return FALSE;
272} 272}
273 273
274// static 274// static
275BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) 275BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence)
276{ 276{
277 if ( sTheInstance.mImmGetConversionStatus ) 277 if ( sTheInstance.mImmGetConversionStatus )
278 return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); 278 return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence);
279 return FALSE; 279 return FALSE;
280} 280}
281 281
282// static 282// static
283BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) 283BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence)
284{ 284{
285 if ( sTheInstance.mImmSetConversionStatus ) 285 if ( sTheInstance.mImmSetConversionStatus )
286 return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); 286 return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence);
287 return FALSE; 287 return FALSE;
288} 288}
289 289
290// static 290// static
291BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) 291BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
292{ 292{
293 if ( sTheInstance.mImmGetCompostitionWindow ) 293 if ( sTheInstance.mImmGetCompostitionWindow )
294 return sTheInstance.mImmGetCompostitionWindow(himc, form); 294 return sTheInstance.mImmGetCompostitionWindow(himc, form);
295 return FALSE; 295 return FALSE;
296} 296}
297 297
298// static 298// static
299BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) 299BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
300{ 300{
301 if ( sTheInstance.mImmSetCompostitionWindow ) 301 if ( sTheInstance.mImmSetCompostitionWindow )
302 return sTheInstance.mImmSetCompostitionWindow(himc, form); 302 return sTheInstance.mImmSetCompostitionWindow(himc, form);
303 return FALSE; 303 return FALSE;
304} 304}
305 305
306 306
307// static 307// static
308LONG LLWinImm::getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length) 308LONG LLWinImm::getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length)
309{ 309{
310 if ( sTheInstance.mImmGetCompositionString ) 310 if ( sTheInstance.mImmGetCompositionString )
311 return sTheInstance.mImmGetCompositionString(himc, index, data, length); 311 return sTheInstance.mImmGetCompositionString(himc, index, data, length);
312 return FALSE; 312 return FALSE;
313} 313}
314 314
315 315
316// static 316// static
317BOOL LLWinImm::setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength) 317BOOL LLWinImm::setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength)
318{ 318{
319 if ( sTheInstance.mImmSetCompositionString ) 319 if ( sTheInstance.mImmSetCompositionString )
320 return sTheInstance.mImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength); 320 return sTheInstance.mImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength);
321 return FALSE; 321 return FALSE;
322} 322}
323 323
324// static 324// static
325BOOL LLWinImm::setCompositionFont(HIMC himc, LPLOGFONTW pFont) 325BOOL LLWinImm::setCompositionFont(HIMC himc, LPLOGFONTW pFont)
326{ 326{
327 if ( sTheInstance.mImmSetCompositionFont ) 327 if ( sTheInstance.mImmSetCompositionFont )
328 return sTheInstance.mImmSetCompositionFont(himc, pFont); 328 return sTheInstance.mImmSetCompositionFont(himc, pFont);
329 return FALSE; 329 return FALSE;
330} 330}
331 331
332// static 332// static
333BOOL LLWinImm::setCandidateWindow(HIMC himc, LPCANDIDATEFORM form) 333BOOL LLWinImm::setCandidateWindow(HIMC himc, LPCANDIDATEFORM form)
334{ 334{
335 if ( sTheInstance.mImmSetCandidateWindow ) 335 if ( sTheInstance.mImmSetCandidateWindow )
336 return sTheInstance.mImmSetCandidateWindow(himc, form); 336 return sTheInstance.mImmSetCandidateWindow(himc, form);
337 return FALSE; 337 return FALSE;
338} 338}
339 339
340// static 340// static
341BOOL LLWinImm::notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value) 341BOOL LLWinImm::notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value)
342{ 342{
343 if ( sTheInstance.mImmNotifyIME ) 343 if ( sTheInstance.mImmNotifyIME )
344 return sTheInstance.mImmNotifyIME(himc, action, index, value); 344 return sTheInstance.mImmNotifyIME(himc, action, index, value);
345 return FALSE; 345 return FALSE;
346} 346}
347 347
@@ -359,22 +359,15 @@ LLWinImm::~LLWinImm()
359} 359}
360 360
361 361
362LPDIRECTINPUT8 g_pDI = NULL;
363LPDIRECTINPUTDEVICE8 g_pJoystick = NULL;
364BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
365 VOID* pContext );
366BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
367 VOID* pContext );
368
369
370LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, 362LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
371 S32 height, U32 flags, 363 S32 height, U32 flags,
372 BOOL fullscreen, BOOL clearBg, 364 BOOL fullscreen, BOOL clearBg,
373 BOOL disable_vsync, BOOL use_gl, 365 BOOL disable_vsync, BOOL use_gl,
374 BOOL ignore_pixel_depth) 366 BOOL ignore_pixel_depth,
367 U32 fsaa_samples)
375 : LLWindow(fullscreen, flags) 368 : LLWindow(fullscreen, flags)
376{ 369{
377 S32 i = 0; 370 mFSAASamples = fsaa_samples;
378 mIconResource = gIconResource; 371 mIconResource = gIconResource;
379 mOverrideAspectRatio = 0.f; 372 mOverrideAspectRatio = 0.f;
380 mNativeAspectRatio = 0.f; 373 mNativeAspectRatio = 0.f;
@@ -389,10 +382,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
389 // based on the system's (user's) default settings. 382 // based on the system's (user's) default settings.
390 allowLanguageTextInput(mPreeditor, FALSE); 383 allowLanguageTextInput(mPreeditor, FALSE);
391 384
392 GLuint pixel_format;
393 WNDCLASS wc; 385 WNDCLASS wc;
394 DWORD dw_ex_style;
395 DWORD dw_style;
396 RECT window_rect; 386 RECT window_rect;
397 387
398 // Set the window title 388 // Set the window title
@@ -442,8 +432,8 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
442 432
443 // Grab screen size to sanitize the window 433 // Grab screen size to sanitize the window
444 S32 window_border_y = GetSystemMetrics(SM_CYBORDER); 434 S32 window_border_y = GetSystemMetrics(SM_CYBORDER);
445 S32 virtual_screen_x = GetSystemMetrics(SM_XVIRTUALSCREEN); 435 S32 virtual_screen_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
446 S32 virtual_screen_y = GetSystemMetrics(SM_YVIRTUALSCREEN); 436 S32 virtual_screen_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
447 S32 virtual_screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN); 437 S32 virtual_screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
448 S32 virtual_screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN); 438 S32 virtual_screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
449 439
@@ -554,7 +544,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
554 success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); 544 success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh);
555 } 545 }
556 546
557 // Keep a copy of the actual current device mode in case we minimize 547 // Keep a copy of the actual current device mode in case we minimize
558 // and change the screen resolution. JC 548 // and change the screen resolution. JC
559 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); 549 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode);
560 550
@@ -586,49 +576,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
586 OSMessageBox(error, "Error", OSMB_OK); 576 OSMessageBox(error, "Error", OSMB_OK);
587 } 577 }
588 } 578 }
589 579
590 //-----------------------------------------------------------------------
591 // Resize window to account for borders
592 //-----------------------------------------------------------------------
593 if (mFullscreen)
594 {
595 dw_ex_style = WS_EX_APPWINDOW;
596 dw_style = WS_POPUP;
597
598 // Move window borders out not to cover window contents
599 AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
600 }
601 else
602 {
603 // Window with an edge
604 dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
605 dw_style = WS_OVERLAPPEDWINDOW;
606 }
607
608 //-----------------------------------------------------------------------
609 // Create the window
610 // Microsoft help indicates that GL windows must be created with
611 // WS_CLIPSIBLINGS and WS_CLIPCHILDREN, but not CS_PARENTDC
612 //-----------------------------------------------------------------------
613 mWindowHandle = CreateWindowEx(dw_ex_style,
614 mWindowClassName,
615 mWindowTitle,
616 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
617 x, // x pos
618 y, // y pos
619 window_rect.right - window_rect.left, // width
620 window_rect.bottom - window_rect.top, // height
621 NULL,
622 NULL,
623 mhInstance,
624 NULL);
625
626 if (!mWindowHandle)
627 {
628 OSMessageBox("Window creation error", "Error", OSMB_OK);
629 return;
630 }
631
632 // TODO: add this after resolving _WIN32_WINNT issue 580 // TODO: add this after resolving _WIN32_WINNT issue
633 // if (!fullscreen) 581 // if (!fullscreen)
634 // { 582 // {
@@ -637,380 +585,21 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
637 // track_mouse_event.dwFlags = TME_LEAVE; 585 // track_mouse_event.dwFlags = TME_LEAVE;
638 // track_mouse_event.hwndTrack = mWindowHandle; 586 // track_mouse_event.hwndTrack = mWindowHandle;
639 // track_mouse_event.dwHoverTime = HOVER_DEFAULT; 587 // track_mouse_event.dwHoverTime = HOVER_DEFAULT;
640 // TrackMouseEvent( &track_mouse_event ); 588 // TrackMouseEvent( &track_mouse_event );
641 // } 589 // }
642 590
643 591
644
645 S32 pfdflags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
646 if (use_gl)
647 {
648 pfdflags |= PFD_SUPPORT_OPENGL;
649 }
650
651 //----------------------------------------------------------------------- 592 //-----------------------------------------------------------------------
652 // Create GL drawing context 593 // Create GL drawing context
653 //----------------------------------------------------------------------- 594 //-----------------------------------------------------------------------
654 PIXELFORMATDESCRIPTOR pfd = 595 LLCoordScreen windowPos(x,y);
596 LLCoordScreen windowSize(window_rect.right - window_rect.left,
597 window_rect.bottom - window_rect.top);
598 if (!switchContext(mFullscreen, windowSize, TRUE, &windowPos))
655 { 599 {
656 sizeof(PIXELFORMATDESCRIPTOR),
657 1,
658 pfdflags,
659 PFD_TYPE_RGBA,
660 BITS_PER_PIXEL,
661 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused
662 8, // alpha bits
663 0, // alpha shift
664 0, // accum bits
665 0, 0, 0, 0, // accum RGBA
666 24, // depth bits
667 8, // stencil bits, avi added for stencil test
668 0,
669 PFD_MAIN_PLANE,
670 0,
671 0, 0, 0
672 };
673
674 if (!(mhDC = GetDC(mWindowHandle)))
675 {
676 close();
677 OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
678 return; 600 return;
679 } 601 }
680 602
681 if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
682 {
683 close();
684 OSMessageBox("Can't find suitable pixel format", "Error", OSMB_OK);
685 return;
686 }
687
688 // Verify what pixel format we actually received.
689 if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
690 &pfd))
691 {
692 close();
693 OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
694 return;
695 }
696
697 // sanity check pfd returned by Windows
698 if (!ignore_pixel_depth && (pfd.cColorBits < 32))
699 {
700 close();
701 OSMessageBox(
702 "Second Life requires True Color (32-bit) to run in a window.\n"
703 "Please go to Control Panels -> Display -> Settings and\n"
704 "set the screen to 32-bit color.\n"
705 "Alternately, if you choose to run fullscreen, Second Life\n"
706 "will automatically adjust the screen each time it runs.",
707 "Error",
708 OSMB_OK);
709 return;
710 }
711
712 if (!ignore_pixel_depth && (pfd.cAlphaBits < 8))
713 {
714 close();
715 OSMessageBox(
716 "Second Life is unable to run because it can't get an 8 bit alpha\n"
717 "channel. Usually this is due to video card driver issues.\n"
718 "Please make sure you have the latest video card drivers installed.\n"
719 "Also be sure your monitor is set to True Color (32-bit) in\n"
720 "Control Panels -> Display -> Settings.\n"
721 "If you continue to receive this message, contact customer service.",
722 "Error",
723 OSMB_OK);
724 return;
725 }
726
727 if (!SetPixelFormat(mhDC, pixel_format, &pfd))
728 {
729 close();
730 OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
731 return;
732 }
733
734 if (use_gl)
735 {
736 if (!(mhRC = wglCreateContext(mhDC)))
737 {
738 close();
739 OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
740 return;
741 }
742
743 if (!wglMakeCurrent(mhDC, mhRC))
744 {
745 close();
746 OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
747 return;
748 }
749
750 gGLManager.initWGL();
751
752 if (gGLManager.mHasWGLARBPixelFormat && (wglChoosePixelFormatARB != NULL))
753 {
754 // OK, at this point, use the ARB wglChoosePixelFormatsARB function to see if we
755 // can get exactly what we want.
756 GLint attrib_list[256];
757 S32 cur_attrib = 0;
758
759 attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB;
760 attrib_list[cur_attrib++] = 24;
761
762 attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB;
763 attrib_list[cur_attrib++] = 8;
764
765 attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB;
766 attrib_list[cur_attrib++] = GL_TRUE;
767
768 attrib_list[cur_attrib++] = WGL_ACCELERATION_ARB;
769 attrib_list[cur_attrib++] = WGL_FULL_ACCELERATION_ARB;
770
771 attrib_list[cur_attrib++] = WGL_SUPPORT_OPENGL_ARB;
772 attrib_list[cur_attrib++] = GL_TRUE;
773
774 attrib_list[cur_attrib++] = WGL_DOUBLE_BUFFER_ARB;
775 attrib_list[cur_attrib++] = GL_TRUE;
776
777 attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB;
778 attrib_list[cur_attrib++] = 32;
779
780 attrib_list[cur_attrib++] = WGL_RED_BITS_ARB;
781 attrib_list[cur_attrib++] = 8;
782
783 attrib_list[cur_attrib++] = WGL_GREEN_BITS_ARB;
784 attrib_list[cur_attrib++] = 8;
785
786 attrib_list[cur_attrib++] = WGL_BLUE_BITS_ARB;
787 attrib_list[cur_attrib++] = 8;
788
789 attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB;
790 attrib_list[cur_attrib++] = 8;
791
792 // End the list
793 attrib_list[cur_attrib++] = 0;
794
795 GLint pixel_formats[256];
796 U32 num_formats = 0;
797
798 // First we try and get a 32 bit depth pixel format
799 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
800 if (!result)
801 {
802 close();
803 show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit");
804 return;
805 }
806
807 if (!num_formats)
808 {
809 llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl;
810 // Try 24-bit format
811 attrib_list[1] = 24;
812 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
813 if (!result)
814 {
815 close();
816 show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit");
817 return;
818 }
819
820 if (!num_formats)
821 {
822 llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl;
823 attrib_list[1] = 16;
824 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
825 if (!result || !num_formats)
826 {
827 close();
828 show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit");
829 return;
830 }
831 }
832
833 llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl;
834
835 pixel_format = pixel_formats[0];
836 }
837
838 DestroyWindow(mWindowHandle);
839
840 mWindowHandle = CreateWindowEx(dw_ex_style,
841 mWindowClassName,
842 mWindowTitle,
843 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
844 x, // x pos
845 y, // y pos
846 window_rect.right - window_rect.left, // width
847 window_rect.bottom - window_rect.top, // height
848 NULL,
849 NULL,
850 mhInstance,
851 NULL);
852
853 if (!(mhDC = GetDC(mWindowHandle)))
854 {
855 close();
856 OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
857 return;
858 }
859
860 if (!SetPixelFormat(mhDC, pixel_format, &pfd))
861 {
862 close();
863 OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
864 return;
865 }
866
867 int swap_method = 0;
868 GLint swap_query = WGL_SWAP_METHOD_ARB;
869
870 if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
871 {
872 switch (swap_method)
873 {
874 case WGL_SWAP_EXCHANGE_ARB:
875 mSwapMethod = SWAP_METHOD_EXCHANGE;
876 llinfos << "Swap Method: Exchange" << llendl;
877 break;
878 case WGL_SWAP_COPY_ARB:
879 mSwapMethod = SWAP_METHOD_COPY;
880 llinfos << "Swap Method: Copy" << llendl;
881 break;
882 case WGL_SWAP_UNDEFINED_ARB:
883 mSwapMethod = SWAP_METHOD_UNDEFINED;
884 llinfos << "Swap Method: Undefined" << llendl;
885 break;
886 default:
887 mSwapMethod = SWAP_METHOD_UNDEFINED;
888 llinfos << "Swap Method: Unknown" << llendl;
889 break;
890 }
891 }
892 }
893 else
894 {
895 llwarns << "No wgl_ARB_pixel_format extension, using default ChoosePixelFormat!" << llendl;
896 }
897
898 // Verify what pixel format we actually received.
899 if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
900 &pfd))
901 {
902 close();
903 OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
904 return;
905 }
906 llinfos << "GL buffer: Color Bits " << S32(pfd.cColorBits)
907 << " Alpha Bits " << S32(pfd.cAlphaBits)
908 << " Depth Bits " << S32(pfd.cDepthBits)
909 << llendl;
910
911 if (pfd.cColorBits < 32)
912 {
913 close();
914 OSMessageBox(
915 "Second Life requires True Color (32-bit) to run in a window.\n"
916 "Please go to Control Panels -> Display -> Settings and\n"
917 "set the screen to 32-bit color.\n"
918 "Alternately, if you choose to run fullscreen, Second Life\n"
919 "will automatically adjust the screen each time it runs.",
920 "Error",
921 OSMB_OK);
922 return;
923 }
924
925 if (pfd.cAlphaBits < 8)
926 {
927 close();
928 OSMessageBox(
929 "Second Life is unable to run because it can't get an 8 bit alpha\n"
930 "channel. Usually this is due to video card driver issues.\n"
931 "Please make sure you have the latest video card drivers installed.\n"
932 "Also be sure your monitor is set to True Color (32-bit) in\n"
933 "Control Panels -> Display -> Settings.\n"
934 "If you continue to receive this message, contact customer service.",
935 "Error",
936 OSMB_OK);
937 return;
938 }
939
940 if (!(mhRC = wglCreateContext(mhDC)))
941 {
942 close();
943 OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
944 return;
945 }
946
947 if (!wglMakeCurrent(mhDC, mhRC))
948 {
949 close();
950 OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
951 return;
952 }
953
954 if (!gGLManager.initGL())
955 {
956 close();
957 OSMessageBox(
958 "Second Life is unable to run because your video card drivers\n"
959 "are out of date or unsupported. Please make sure you have\n"
960 "the latest video card drivers installed.\n\n"
961 "If you continue to receive this message, contact customer service.",
962 "Error",
963 OSMB_OK);
964 return;
965 }
966
967 // Disable vertical sync for swap
968 if (disable_vsync && wglSwapIntervalEXT)
969 {
970 llinfos << "Disabling vertical sync" << llendl;
971 wglSwapIntervalEXT(0);
972 }
973 else
974 {
975 llinfos << "Keeping vertical sync" << llendl;
976 }
977
978
979 // OK, let's get the current gamma information and store it off.
980 mCurrentGamma = 0.f; // Not set, default;
981 if (!GetDeviceGammaRamp(mhDC, mPrevGammaRamp))
982 {
983 llwarns << "Unable to get device gamma ramp" << llendl;
984 }
985
986 // Calculate what the current gamma is. From a posting by Garrett T. Bass, Get/SetDeviceGammaRamp Demystified
987 // http://apollo.iwt.uni-bielefeld.de/~ml_robot/OpenGL-04-2000/0058.html
988
989 // We're going to assume that gamma's the same for all 3 channels, because I don't feel like doing it otherwise.
990 // Using the red channel.
991
992 F32 Csum = 0.0;
993 S32 Ccount = 0;
994 for (i = 0; i < 256; i++)
995 {
996 if (i != 0 && mPrevGammaRamp[i] != 0 && mPrevGammaRamp[i] != 65536)
997 {
998 F64 B = (i % 256) / 256.0;
999 F64 A = mPrevGammaRamp[i] / 65536.0;
1000 F32 C = (F32) ( log(A) / log(B) );
1001 Csum += C;
1002 Ccount++;
1003 }
1004 }
1005 mCurrentGamma = Csum / Ccount;
1006
1007 llinfos << "Previous gamma: " << mCurrentGamma << llendl;
1008 }
1009
1010
1011 //store this pointer for wndProc callback
1012 SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this);
1013
1014 //start with arrow cursor 603 //start with arrow cursor
1015 initCursors(); 604 initCursors();
1016 setCursor( UI_CURSOR_ARROW ); 605 setCursor( UI_CURSOR_ARROW );
@@ -1019,40 +608,6 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
1019 // based on the system's (or user's) default settings. 608 // based on the system's (or user's) default settings.
1020 allowLanguageTextInput(NULL, FALSE); 609 allowLanguageTextInput(NULL, FALSE);
1021 610
1022 initInputDevices();
1023}
1024
1025void LLWindowWin32::initInputDevices()
1026{
1027 // Direct Input
1028 HRESULT hr;
1029
1030 if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
1031 IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
1032 {
1033 llwarns << "Direct8InputCreate failed!" << llendl;
1034 }
1035 else
1036 {
1037 while(1)
1038 {
1039 // Look for a simple joystick we can use for this sample program.
1040 if (FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
1041 EnumJoysticksCallback,
1042 NULL, DIEDFL_ATTACHEDONLY ) ) )
1043 break;
1044 if (!g_pJoystick)
1045 break;
1046 if( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick ) ) )
1047 break;
1048 if( FAILED( hr = g_pJoystick->EnumObjects( EnumObjectsCallback,
1049 (VOID*)mWindowHandle, DIDFT_ALL ) ) )
1050 break;
1051 g_pJoystick->Acquire();
1052 break;
1053 }
1054 }
1055
1056 SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer 611 SetTimer( mWindowHandle, 0, 1000 / 30, NULL ); // 30 fps timer
1057} 612}
1058 613
@@ -1149,7 +704,7 @@ void LLWindowWin32::close()
1149 } 704 }
1150 705
1151 llinfos << "Destroying Window" << llendl; 706 llinfos << "Destroying Window" << llendl;
1152 707
1153 // Don't process events in our mainWindowProc any longer. 708 // Don't process events in our mainWindowProc any longer.
1154 SetWindowLong(mWindowHandle, GWL_USERDATA, NULL); 709 SetWindowLong(mWindowHandle, GWL_USERDATA, NULL);
1155 710
@@ -1283,7 +838,7 @@ BOOL LLWindowWin32::setSize(const LLCoordScreen size)
1283} 838}
1284 839
1285// changing fullscreen resolution 840// changing fullscreen resolution
1286BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync) 841BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
1287{ 842{
1288 GLuint pixel_format; 843 GLuint pixel_format;
1289 DEVMODE dev_mode; 844 DEVMODE dev_mode;
@@ -1360,7 +915,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1360 success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); 915 success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh);
1361 } 916 }
1362 917
1363 // Keep a copy of the actual current device mode in case we minimize 918 // Keep a copy of the actual current device mode in case we minimize
1364 // and change the screen resolution. JC 919 // and change the screen resolution. JC
1365 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); 920 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode);
1366 921
@@ -1405,10 +960,10 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1405 else 960 else
1406 { 961 {
1407 mFullscreen = FALSE; 962 mFullscreen = FALSE;
1408 window_rect.left = (long) 0; 963 window_rect.left = (long) (posp ? posp->mX : 0);
1409 window_rect.right = (long) width; // Windows GDI rects don't include rightmost pixel 964 window_rect.right = (long) width + window_rect.left; // Windows GDI rects don't include rightmost pixel
1410 window_rect.top = (long) 0; 965 window_rect.top = (long) (posp ? posp->mY : 0);
1411 window_rect.bottom = (long) height; 966 window_rect.bottom = (long) height + window_rect.top;
1412 // Window with an edge 967 // Window with an edge
1413 dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; 968 dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
1414 dw_style = WS_OVERLAPPEDWINDOW; 969 dw_style = WS_OVERLAPPEDWINDOW;
@@ -1437,9 +992,9 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1437 //----------------------------------------------------------------------- 992 //-----------------------------------------------------------------------
1438 static PIXELFORMATDESCRIPTOR pfd = 993 static PIXELFORMATDESCRIPTOR pfd =
1439 { 994 {
1440 sizeof(PIXELFORMATDESCRIPTOR), 995 sizeof(PIXELFORMATDESCRIPTOR),
1441 1, 996 1,
1442 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 997 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1443 PFD_TYPE_RGBA, 998 PFD_TYPE_RGBA,
1444 BITS_PER_PIXEL, 999 BITS_PER_PIXEL,
1445 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused 1000 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused
@@ -1558,17 +1113,19 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1558 attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB; 1113 attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB;
1559 attrib_list[cur_attrib++] = 24; 1114 attrib_list[cur_attrib++] = 24;
1560 1115
1561 attrib_list[cur_attrib++] = WGL_RED_BITS_ARB; 1116 attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB;
1562 attrib_list[cur_attrib++] = 8;
1563
1564 attrib_list[cur_attrib++] = WGL_GREEN_BITS_ARB;
1565 attrib_list[cur_attrib++] = 8; 1117 attrib_list[cur_attrib++] = 8;
1566 1118
1567 attrib_list[cur_attrib++] = WGL_BLUE_BITS_ARB; 1119 U32 end_attrib = 0;
1568 attrib_list[cur_attrib++] = 8; 1120 if (mFSAASamples > 0)
1121 {
1122 end_attrib = cur_attrib;
1123 attrib_list[cur_attrib++] = WGL_SAMPLE_BUFFERS_ARB;
1124 attrib_list[cur_attrib++] = GL_TRUE;
1569 1125
1570 attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; 1126 attrib_list[cur_attrib++] = WGL_SAMPLES_ARB;
1571 attrib_list[cur_attrib++] = 8; 1127 attrib_list[cur_attrib++] = mFSAASamples;
1128 }
1572 1129
1573 // End the list 1130 // End the list
1574 attrib_list[cur_attrib++] = 0; 1131 attrib_list[cur_attrib++] = 0;
@@ -1587,36 +1144,67 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1587 1144
1588 if (!num_formats) 1145 if (!num_formats)
1589 { 1146 {
1590 llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl; 1147 if (end_attrib > 0)
1591 // Try 24-bit format
1592 attrib_list[1] = 24;
1593 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
1594 if (!result)
1595 { 1148 {
1596 close(); 1149 llinfos << "No valid pixel format for " << mFSAASamples << "x anti-aliasing." << llendl;
1597 show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit"); 1150 attrib_list[end_attrib] = 0;
1598 return FALSE; 1151
1152 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
1153 if (!result)
1154 {
1155 close();
1156 show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit no AA");
1157 return FALSE;
1158 }
1599 } 1159 }
1600 1160
1601 if (!num_formats) 1161 if (!num_formats)
1602 { 1162 {
1603 llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl; 1163 llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl;
1604 attrib_list[1] = 16; 1164 // Try 24-bit format
1165 attrib_list[1] = 24;
1605 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); 1166 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
1606 if (!result || !num_formats) 1167 if (!result)
1607 { 1168 {
1608 close(); 1169 close();
1609 show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit"); 1170 show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit");
1610 return FALSE; 1171 return FALSE;
1611 } 1172 }
1173
1174 if (!num_formats)
1175 {
1176 llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl;
1177 attrib_list[1] = 16;
1178 BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
1179 if (!result || !num_formats)
1180 {
1181 close();
1182 show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit");
1183 return FALSE;
1184 }
1185 }
1612 } 1186 }
1613 1187
1614 llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl; 1188 llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl;
1189 }
1190
1191 pixel_format = pixel_formats[0];
1615 1192
1616 pixel_format = pixel_formats[0]; 1193 if (mhDC != 0) // Does The Window Have A Device Context?
1194 {
1195 wglMakeCurrent(mhDC, 0); // Set The Current Active Rendering Context To Zero
1196 if (mhRC != 0) // Does The Window Have A Rendering Context?
1197 {
1198 wglDeleteContext (mhRC); // Release The Rendering Context
1199 mhRC = 0; // Zero The Rendering Context
1200
1201 }
1202 ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
1203 mhDC = 0; // Zero The Device Context
1617 } 1204 }
1205 DestroyWindow (mWindowHandle); // Destroy The Window
1206
1618 1207
1619 DestroyWindow(mWindowHandle);
1620 mWindowHandle = CreateWindowEx(dw_ex_style, 1208 mWindowHandle = CreateWindowEx(dw_ex_style,
1621 mWindowClassName, 1209 mWindowClassName,
1622 mWindowTitle, 1210 mWindowTitle,
@@ -1668,7 +1256,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1668 llinfos << "Swap Method: Unknown" << llendl; 1256 llinfos << "Swap Method: Unknown" << llendl;
1669 break; 1257 break;
1670 } 1258 }
1671 } 1259 }
1672 } 1260 }
1673 else 1261 else
1674 { 1262 {
@@ -1684,12 +1272,13 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1684 return FALSE; 1272 return FALSE;
1685 } 1273 }
1686 1274
1687 llinfos << "GL buffer: Color Bits " << S32(pfd.cColorBits) 1275 llinfos << "GL buffer: Color Bits " << S32(pfd.cColorBits)
1688 << " Alpha Bits " << S32(pfd.cAlphaBits) 1276 << " Alpha Bits " << S32(pfd.cAlphaBits)
1689 << " Depth Bits " << S32(pfd.cDepthBits) 1277 << " Depth Bits " << S32(pfd.cDepthBits)
1690 << llendl; 1278 << llendl;
1691 1279
1692 if (pfd.cColorBits < 32) 1280 // make sure we have 32 bits per pixel
1281 if (pfd.cColorBits < 32 || GetDeviceCaps(mhDC, BITSPIXEL) < 32)
1693 { 1282 {
1694 close(); 1283 close();
1695 OSMessageBox( 1284 OSMessageBox(
@@ -1759,7 +1348,9 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa
1759 SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this); 1348 SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this);
1760 show(); 1349 show();
1761 1350
1762 initInputDevices(); 1351 //make sure multi sampling is disabled by default
1352 glDisable(GL_MULTISAMPLE_ARB);
1353
1763 1354
1764 // ok to post quit messages now 1355 // ok to post quit messages now
1765 mPostQuit = TRUE; 1356 mPostQuit = TRUE;
@@ -1884,10 +1475,10 @@ void LLWindowWin32::initCursors()
1884 mCursor[ UI_CURSOR_CROSS ] = LoadCursor(NULL, IDC_CROSS); 1475 mCursor[ UI_CURSOR_CROSS ] = LoadCursor(NULL, IDC_CROSS);
1885 mCursor[ UI_CURSOR_SIZENWSE ] = LoadCursor(NULL, IDC_SIZENWSE); 1476 mCursor[ UI_CURSOR_SIZENWSE ] = LoadCursor(NULL, IDC_SIZENWSE);
1886 mCursor[ UI_CURSOR_SIZENESW ] = LoadCursor(NULL, IDC_SIZENESW); 1477 mCursor[ UI_CURSOR_SIZENESW ] = LoadCursor(NULL, IDC_SIZENESW);
1887 mCursor[ UI_CURSOR_SIZEWE ] = LoadCursor(NULL, IDC_SIZEWE); 1478 mCursor[ UI_CURSOR_SIZEWE ] = LoadCursor(NULL, IDC_SIZEWE);
1888 mCursor[ UI_CURSOR_SIZENS ] = LoadCursor(NULL, IDC_SIZENS); 1479 mCursor[ UI_CURSOR_SIZENS ] = LoadCursor(NULL, IDC_SIZENS);
1889 mCursor[ UI_CURSOR_NO ] = LoadCursor(NULL, IDC_NO); 1480 mCursor[ UI_CURSOR_NO ] = LoadCursor(NULL, IDC_NO);
1890 mCursor[ UI_CURSOR_WORKING ] = LoadCursor(NULL, IDC_APPSTARTING); 1481 mCursor[ UI_CURSOR_WORKING ] = LoadCursor(NULL, IDC_APPSTARTING);
1891 1482
1892 HMODULE module = GetModuleHandle(NULL); 1483 HMODULE module = GetModuleHandle(NULL);
1893 mCursor[ UI_CURSOR_TOOLGRAB ] = LoadCursor(module, TEXT("TOOLGRAB")); 1484 mCursor[ UI_CURSOR_TOOLGRAB ] = LoadCursor(module, TEXT("TOOLGRAB"));
@@ -1902,7 +1493,7 @@ void LLWindowWin32::initCursors()
1902 mCursor[ UI_CURSOR_ARROWLOCKED ]= LoadCursor(module, TEXT("ARROWLOCKED")); 1493 mCursor[ UI_CURSOR_ARROWLOCKED ]= LoadCursor(module, TEXT("ARROWLOCKED"));
1903 mCursor[ UI_CURSOR_GRABLOCKED ] = LoadCursor(module, TEXT("GRABLOCKED")); 1494 mCursor[ UI_CURSOR_GRABLOCKED ] = LoadCursor(module, TEXT("GRABLOCKED"));
1904 mCursor[ UI_CURSOR_TOOLTRANSLATE ] = LoadCursor(module, TEXT("TOOLTRANSLATE")); 1495 mCursor[ UI_CURSOR_TOOLTRANSLATE ] = LoadCursor(module, TEXT("TOOLTRANSLATE"));
1905 mCursor[ UI_CURSOR_TOOLROTATE ] = LoadCursor(module, TEXT("TOOLROTATE")); 1496 mCursor[ UI_CURSOR_TOOLROTATE ] = LoadCursor(module, TEXT("TOOLROTATE"));
1906 mCursor[ UI_CURSOR_TOOLSCALE ] = LoadCursor(module, TEXT("TOOLSCALE")); 1497 mCursor[ UI_CURSOR_TOOLSCALE ] = LoadCursor(module, TEXT("TOOLSCALE"));
1907 mCursor[ UI_CURSOR_TOOLCAMERA ] = LoadCursor(module, TEXT("TOOLCAMERA")); 1498 mCursor[ UI_CURSOR_TOOLCAMERA ] = LoadCursor(module, TEXT("TOOLCAMERA"));
1908 mCursor[ UI_CURSOR_TOOLPAN ] = LoadCursor(module, TEXT("TOOLPAN")); 1499 mCursor[ UI_CURSOR_TOOLPAN ] = LoadCursor(module, TEXT("TOOLPAN"));
@@ -2051,7 +1642,22 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2051 S32 update_height; 1642 S32 update_height;
2052 1643
2053 case WM_TIMER: 1644 case WM_TIMER:
2054 window_imp->updateJoystick( ); 1645 window_imp->mCallbacks->handleTimerEvent(window_imp);
1646 break;
1647
1648 case WM_DEVICECHANGE:
1649 if (gDebugWindowProc)
1650 {
1651 llinfos << " WM_DEVICECHANGE: wParam=" << w_param
1652 << "; lParam=" << l_param << llendl;
1653 }
1654 if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
1655 {
1656 if (window_imp->mCallbacks->handleDeviceChange(window_imp))
1657 {
1658 return 0;
1659 }
1660 }
2055 break; 1661 break;
2056 1662
2057 case WM_PAINT: 1663 case WM_PAINT:
@@ -2103,7 +1709,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2103 1709
2104 if (window_imp->mFullscreen) 1710 if (window_imp->mFullscreen)
2105 { 1711 {
2106 // When we run fullscreen, restoring or minimizing the app needs 1712 // When we run fullscreen, restoring or minimizing the app needs
2107 // to switch the screen resolution 1713 // to switch the screen resolution
2108 if (activating) 1714 if (activating)
2109 { 1715 {
@@ -2116,6 +1722,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2116 window_imp->resetDisplayResolution(); 1722 window_imp->resetDisplayResolution();
2117 } 1723 }
2118 } 1724 }
1725
1726 window_imp->mCallbacks->handleActivateApp(window_imp, activating);
1727
2119 break; 1728 break;
2120 } 1729 }
2121 1730
@@ -2131,13 +1740,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2131 window_imp->interruptLanguageTextInput(); 1740 window_imp->interruptLanguageTextInput();
2132 } 1741 }
2133 1742
2134 // JC - I'm not sure why, but if we don't report that we handled the 1743 // JC - I'm not sure why, but if we don't report that we handled the
2135 // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work 1744 // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work
2136 // properly when we run fullscreen. 1745 // properly when we run fullscreen.
2137 if (gDebugWindowProc) 1746 if (gDebugWindowProc)
2138 { 1747 {
2139 llinfos << "WINDOWPROC Activate " 1748 llinfos << "WINDOWPROC Activate "
2140 << " activating " << S32(activating) 1749 << " activating " << S32(activating)
2141 << " minimized " << S32(minimized) 1750 << " minimized " << S32(minimized)
2142 << llendl; 1751 << llendl;
2143 } 1752 }
@@ -2153,9 +1762,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2153 case WM_SYSCOMMAND: 1762 case WM_SYSCOMMAND:
2154 switch(w_param) 1763 switch(w_param)
2155 { 1764 {
2156 case SC_KEYMENU: 1765 case SC_KEYMENU:
2157 // Disallow the ALT key from triggering the default system menu. 1766 // Disallow the ALT key from triggering the default system menu.
2158 return 0; 1767 return 0;
2159 1768
2160 case SC_SCREENSAVE: 1769 case SC_SCREENSAVE:
2161 case SC_MONITORPOWER: 1770 case SC_MONITORPOWER:
@@ -2196,7 +1805,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2196 if (gDebugWindowProc) 1805 if (gDebugWindowProc)
2197 { 1806 {
2198 llinfos << "Debug WindowProc WM_KEYDOWN " 1807 llinfos << "Debug WindowProc WM_KEYDOWN "
2199 << " key " << S32(w_param) 1808 << " key " << S32(w_param)
2200 << llendl; 1809 << llendl;
2201 } 1810 }
2202 if(gKeyboard->handleKeyDown(w_param, mask) && eat_keystroke) 1811 if(gKeyboard->handleKeyDown(w_param, mask) && eat_keystroke)
@@ -2215,7 +1824,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2215 if (gDebugWindowProc) 1824 if (gDebugWindowProc)
2216 { 1825 {
2217 llinfos << "Debug WindowProc WM_KEYUP " 1826 llinfos << "Debug WindowProc WM_KEYUP "
2218 << " key " << S32(w_param) 1827 << " key " << S32(w_param)
2219 << llendl; 1828 << llendl;
2220 } 1829 }
2221 if (gKeyboard->handleKeyUp(w_param, mask) && eat_keystroke) 1830 if (gKeyboard->handleKeyUp(w_param, mask) && eat_keystroke)
@@ -2284,7 +1893,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2284 if (gDebugWindowProc) 1893 if (gDebugWindowProc)
2285 { 1894 {
2286 llinfos << "Debug WindowProc WM_CHAR " 1895 llinfos << "Debug WindowProc WM_CHAR "
2287 << " key " << S32(w_param) 1896 << " key " << S32(w_param)
2288 << llendl; 1897 << llendl;
2289 } 1898 }
2290 // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE, 1899 // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
@@ -2527,7 +2136,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2527 // track_mouse_event.dwFlags = TME_LEAVE; 2136 // track_mouse_event.dwFlags = TME_LEAVE;
2528 // track_mouse_event.hwndTrack = h_wnd; 2137 // track_mouse_event.hwndTrack = h_wnd;
2529 // track_mouse_event.dwHoverTime = HOVER_DEFAULT; 2138 // track_mouse_event.dwHoverTime = HOVER_DEFAULT;
2530 // TrackMouseEvent( &track_mouse_event ); 2139 // TrackMouseEvent( &track_mouse_event );
2531 return 0; 2140 return 0;
2532 } 2141 }
2533 */ 2142 */
@@ -2559,12 +2168,12 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2559 << llendl; 2168 << llendl;
2560 } 2169 }
2561 2170
2562 // There's an odd behavior with WM_SIZE that I would call a bug. If 2171 // There's an odd behavior with WM_SIZE that I would call a bug. If
2563 // the window is maximized, and you call MoveWindow() with a size smaller 2172 // the window is maximized, and you call MoveWindow() with a size smaller
2564 // than a maximized window, it ends up sending WM_SIZE with w_param set 2173 // than a maximized window, it ends up sending WM_SIZE with w_param set
2565 // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work. 2174 // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work.
2566 // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see 2175 // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see
2567 // LLWindowWin32::moveWindow in this file). 2176 // LLWindowWin32::moveWindow in this file).
2568 2177
2569 // If we are now restored, but we weren't before, this 2178 // If we are now restored, but we weren't before, this
2570 // means that the window was un-minimized. 2179 // means that the window was un-minimized.
@@ -2589,8 +2198,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2589 if (w_param != SIZE_MINIMIZED) 2198 if (w_param != SIZE_MINIMIZED)
2590 { 2199 {
2591 // Ignore updates for minimizing and minimized "windows" 2200 // Ignore updates for minimizing and minimized "windows"
2592 window_imp->mCallbacks->handleResize( window_imp, 2201 window_imp->mCallbacks->handleResize( window_imp,
2593 LOWORD(l_param), 2202 LOWORD(l_param),
2594 HIWORD(l_param) ); 2203 HIWORD(l_param) );
2595 } 2204 }
2596 2205
@@ -2619,7 +2228,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2619 // received a URL 2228 // received a URL
2620 PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param; 2229 PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param;
2621 window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData); 2230 window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData);
2622 return 0; 2231 return 0;
2623 } 2232 }
2624 } 2233 }
2625 2234
@@ -2667,7 +2276,7 @@ BOOL LLWindowWin32::convertCoords(LLCoordWindow from, LLCoordGL* to)
2667} 2276}
2668 2277
2669BOOL LLWindowWin32::convertCoords(LLCoordScreen from, LLCoordWindow* to) 2278BOOL LLWindowWin32::convertCoords(LLCoordScreen from, LLCoordWindow* to)
2670{ 2279{
2671 POINT mouse_point; 2280 POINT mouse_point;
2672 2281
2673 mouse_point.x = from.mX; 2282 mouse_point.x = from.mX;
@@ -2778,7 +2387,7 @@ BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr)
2778 const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(WCHAR); 2387 const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(WCHAR);
2779 2388
2780 // Memory is allocated and then ownership of it is transfered to the system. 2389 // Memory is allocated and then ownership of it is transfered to the system.
2781 HGLOBAL hglobal_copy_utf16 = GlobalAlloc(GMEM_MOVEABLE, size_utf16); 2390 HGLOBAL hglobal_copy_utf16 = GlobalAlloc(GMEM_MOVEABLE, size_utf16);
2782 if (hglobal_copy_utf16) 2391 if (hglobal_copy_utf16)
2783 { 2392 {
2784 WCHAR* copy_utf16 = (WCHAR*) GlobalLock(hglobal_copy_utf16); 2393 WCHAR* copy_utf16 = (WCHAR*) GlobalLock(hglobal_copy_utf16);
@@ -2841,12 +2450,12 @@ BOOL LLWindowWin32::getClientRectInScreenSpace( RECT* rectp )
2841 POINT top_left; 2450 POINT top_left;
2842 top_left.x = client_rect.left; 2451 top_left.x = client_rect.left;
2843 top_left.y = client_rect.top; 2452 top_left.y = client_rect.top;
2844 ClientToScreen(mWindowHandle, &top_left); 2453 ClientToScreen(mWindowHandle, &top_left);
2845 2454
2846 POINT bottom_right; 2455 POINT bottom_right;
2847 bottom_right.x = client_rect.right; 2456 bottom_right.x = client_rect.right;
2848 bottom_right.y = client_rect.bottom; 2457 bottom_right.y = client_rect.bottom;
2849 ClientToScreen(mWindowHandle, &bottom_right); 2458 ClientToScreen(mWindowHandle, &bottom_right);
2850 2459
2851 SetRect( rectp, 2460 SetRect( rectp,
2852 top_left.x, 2461 top_left.x,
@@ -2977,14 +2586,24 @@ BOOL LLWindowWin32::setGamma(const F32 gamma)
2977 if ( value > 0xffff ) 2586 if ( value > 0xffff )
2978 value = 0xffff; 2587 value = 0xffff;
2979 2588
2980 mCurrentGammaRamp [ 0 * 256 + i ] = 2589 mCurrentGammaRamp [ 0 * 256 + i ] =
2981 mCurrentGammaRamp [ 1 * 256 + i ] = 2590 mCurrentGammaRamp [ 1 * 256 + i ] =
2982 mCurrentGammaRamp [ 2 * 256 + i ] = ( WORD )value; 2591 mCurrentGammaRamp [ 2 * 256 + i ] = ( WORD )value;
2983 }; 2592 };
2984 2593
2985 return SetDeviceGammaRamp ( mhDC, mCurrentGammaRamp ); 2594 return SetDeviceGammaRamp ( mhDC, mCurrentGammaRamp );
2986} 2595}
2987 2596
2597void LLWindowWin32::setFSAASamples(const U32 fsaa_samples)
2598{
2599 mFSAASamples = fsaa_samples;
2600}
2601
2602U32 LLWindowWin32::getFSAASamples()
2603{
2604 return mFSAASamples;
2605}
2606
2988LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) 2607LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions)
2989{ 2608{
2990 if (!mSupportedResolutions) 2609 if (!mSupportedResolutions)
@@ -3142,81 +2761,6 @@ void LLWindowWin32::swapBuffers()
3142} 2761}
3143 2762
3144 2763
3145BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
3146 VOID* pContext )
3147{
3148 HRESULT hr;
3149
3150 // Obtain an interface to the enumerated joystick.
3151 hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
3152
3153 // If it failed, then we can't use this joystick. (Maybe the user unplugged
3154 // it while we were in the middle of enumerating it.)
3155 if( FAILED(hr) )
3156 return DIENUM_CONTINUE;
3157
3158 // Stop enumeration. Note: we're just taking the first joystick we get. You
3159 // could store all the enumerated joysticks and let the user pick.
3160 return DIENUM_STOP;
3161}
3162
3163BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
3164 VOID* pContext )
3165{
3166 if( pdidoi->dwType & DIDFT_AXIS )
3167 {
3168 DIPROPRANGE diprg;
3169 diprg.diph.dwSize = sizeof(DIPROPRANGE);
3170 diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
3171 diprg.diph.dwHow = DIPH_BYID;
3172 diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
3173 diprg.lMin = -1000;
3174 diprg.lMax = +1000;
3175
3176 // Set the range for the axis
3177 if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
3178 return DIENUM_STOP;
3179
3180 }
3181 return DIENUM_CONTINUE;
3182}
3183
3184void LLWindowWin32::updateJoystick( )
3185{
3186 HRESULT hr;
3187 DIJOYSTATE js; // DInput joystick state
3188
3189 if (!g_pJoystick)
3190 return;
3191 hr = g_pJoystick->Poll();
3192 if ( hr == DIERR_INPUTLOST )
3193 {
3194 hr = g_pJoystick->Acquire();
3195 return;
3196 }
3197 else if ( FAILED(hr) )
3198 return;
3199
3200 // Get the input's device state
3201 if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js ) ) )
3202 return; // The device should have been acquired during the Poll()
3203
3204 mJoyAxis[0] = js.lX/1000.f;
3205 mJoyAxis[1] = js.lY/1000.f;
3206 mJoyAxis[2] = js.lZ/1000.f;
3207 mJoyAxis[3] = js.lRx/1000.f;
3208 mJoyAxis[4] = js.lRy/1000.f;
3209 mJoyAxis[5] = js.lRz/1000.f;
3210 mJoyAxis[6] = js.rglSlider[0]/1000.f;
3211 mJoyAxis[7] = js.rglSlider[1]/1000.f;
3212
3213 for (U32 i = 0; i < 16; i++)
3214 {
3215 mJoyButtonState[i] = js.rgbButtons[i];
3216 }
3217}
3218
3219
3220// 2764//
3221// LLSplashScreenImp 2765// LLSplashScreenImp
3222// 2766//
@@ -3234,10 +2778,10 @@ void LLSplashScreenWin32::showImpl()
3234 // This appears to work. ??? 2778 // This appears to work. ???
3235 HINSTANCE hinst = GetModuleHandle(NULL); 2779 HINSTANCE hinst = GetModuleHandle(NULL);
3236 2780
3237 mWindow = CreateDialog(hinst, 2781 mWindow = CreateDialog(hinst,
3238 TEXT("SPLASHSCREEN"), 2782 TEXT("SPLASHSCREEN"),
3239 NULL, // no parent 2783 NULL, // no parent
3240 (DLGPROC) LLSplashScreenWin32::windowProc); 2784 (DLGPROC) LLSplashScreenWin32::windowProc);
3241 ShowWindow(mWindow, SW_SHOW); 2785 ShowWindow(mWindow, SW_SHOW);
3242} 2786}
3243 2787
@@ -3262,7 +2806,7 @@ void LLSplashScreenWin32::hideImpl()
3262 if (mWindow) 2806 if (mWindow)
3263 { 2807 {
3264 DestroyWindow(mWindow); 2808 DestroyWindow(mWindow);
3265 mWindow = NULL; 2809 mWindow = NULL;
3266 } 2810 }
3267} 2811}
3268 2812
@@ -3364,77 +2908,79 @@ void spawn_web_browser(const char* escaped_url )
3364 sei.lpFile = url_utf16.c_str(); 2908 sei.lpFile = url_utf16.c_str();
3365 ShellExecuteEx( &sei ); 2909 ShellExecuteEx( &sei );
3366 2910
3367 ////// TODO: LEAVING OLD CODE HERE SO I DON'T BONE OTHER MERGES 2911 //// TODO: LEAVING OLD CODE HERE SO I DON'T BONE OTHER MERGES
3368 ////// DELETE THIS ONCE THE MERGES ARE DONE 2912 //// DELETE THIS ONCE THE MERGES ARE DONE
3369 2913
3370 //// Figure out the user's default web browser 2914 // Figure out the user's default web browser
3371 //// HKEY_CLASSES_ROOT\http\shell\open\command 2915 // HKEY_CLASSES_ROOT\http\shell\open\command
3372 //char reg_path_str[256]; /* Flawfinder: ignore */ 2916 /*
3373 //snprintf(reg_path_str, sizeof(reg_path_str), "%s\\shell\\open\\command", gURLProtocolWhitelistHandler[i]); /* Flawfinder: ignore */ 2917 char reg_path_str[256]; // Flawfinder: ignore
3374 //WCHAR reg_path_wstr[256]; 2918 snprintf(reg_path_str, sizeof(reg_path_str), "%s\\shell\\open\\command", gURLProtocolWhitelistHandler[i]); // Flawfinder: ignore
3375 //mbstowcs(reg_path_wstr, reg_path_str, sizeof(reg_path_wstr)/sizeof(reg_path_wstr[0])); 2919 WCHAR reg_path_wstr[256];
3376 2920 mbstowcs(reg_path_wstr, reg_path_str, sizeof(reg_path_wstr)/sizeof(reg_path_wstr[0]));
3377 //HKEY key; 2921
3378 //WCHAR browser_open_wstr[1024]; 2922 HKEY key;
3379 //DWORD buffer_length = 1024; 2923 WCHAR browser_open_wstr[1024];
3380 //RegOpenKeyEx(HKEY_CLASSES_ROOT, reg_path_wstr, 0, KEY_QUERY_VALUE, &key); 2924 DWORD buffer_length = 1024;
3381 //RegQueryValueEx(key, NULL, NULL, NULL, (LPBYTE)browser_open_wstr, &buffer_length); 2925 RegOpenKeyEx(HKEY_CLASSES_ROOT, reg_path_wstr, 0, KEY_QUERY_VALUE, &key);
3382 //RegCloseKey(key); 2926 RegQueryValueEx(key, NULL, NULL, NULL, (LPBYTE)browser_open_wstr, &buffer_length);
3383 2927 RegCloseKey(key);
3384 //// Convert to STL string 2928
3385 //LLWString browser_open_wstring = utf16str_to_wstring(browser_open_wstr); 2929 // Convert to STL string
3386 2930 LLWString browser_open_wstring = utf16str_to_wstring(browser_open_wstr);
3387 //if (browser_open_wstring.length() < 2) 2931
3388 //{ 2932 if (browser_open_wstring.length() < 2)
3389 // llwarns << "Invalid browser executable in registry " << browser_open_wstring << llendl; 2933 {
3390 // return; 2934 llwarns << "Invalid browser executable in registry " << browser_open_wstring << llendl;
3391 //} 2935 return;
3392 2936 }
3393 //// Extract the process that's supposed to be launched 2937
3394 //LLWString browser_executable; 2938 // Extract the process that's supposed to be launched
3395 //if (browser_open_wstring[0] == '"') 2939 LLWString browser_executable;
3396 //{ 2940 if (browser_open_wstring[0] == '"')
3397 // // executable is quoted, find the matching quote 2941 {
3398 // size_t quote_pos = browser_open_wstring.find('"', 1); 2942 // executable is quoted, find the matching quote
3399 // // copy out the string including both quotes 2943 size_t quote_pos = browser_open_wstring.find('"', 1);
3400 // browser_executable = browser_open_wstring.substr(0, quote_pos+1); 2944 // copy out the string including both quotes
3401 //} 2945 browser_executable = browser_open_wstring.substr(0, quote_pos+1);
3402 //else 2946 }
3403 //{ 2947 else
3404 // // executable not quoted, find a space 2948 {
3405 // size_t space_pos = browser_open_wstring.find(' ', 1); 2949 // executable not quoted, find a space
3406 // browser_executable = browser_open_wstring.substr(0, space_pos); 2950 size_t space_pos = browser_open_wstring.find(' ', 1);
3407 //} 2951 browser_executable = browser_open_wstring.substr(0, space_pos);
3408 2952 }
3409 //llinfos << "Browser reg key: " << wstring_to_utf8str(browser_open_wstring) << llendl; 2953
3410 //llinfos << "Browser executable: " << wstring_to_utf8str(browser_executable) << llendl; 2954 llinfos << "Browser reg key: " << wstring_to_utf8str(browser_open_wstring) << llendl;
3411 2955 llinfos << "Browser executable: " << wstring_to_utf8str(browser_executable) << llendl;
3412 //// Convert URL to wide string for Windows API 2956
3413 //// Assume URL is UTF8, as can come from scripts 2957 // Convert URL to wide string for Windows API
3414 //LLWString url_wstring = utf8str_to_wstring(escaped_url); 2958 // Assume URL is UTF8, as can come from scripts
3415 //llutf16string url_utf16 = wstring_to_utf16str(url_wstring); 2959 LLWString url_wstring = utf8str_to_wstring(escaped_url);
3416 2960 llutf16string url_utf16 = wstring_to_utf16str(url_wstring);
3417 //// Convert executable and path to wide string for Windows API 2961
3418 //llutf16string browser_exec_utf16 = wstring_to_utf16str(browser_executable); 2962 // Convert executable and path to wide string for Windows API
3419 2963 llutf16string browser_exec_utf16 = wstring_to_utf16str(browser_executable);
3420 //// ShellExecute returns HINSTANCE for backwards compatiblity. 2964
3421 //// MS docs say to cast to int and compare to 32. 2965 // ShellExecute returns HINSTANCE for backwards compatiblity.
3422 //HWND our_window = NULL; 2966 // MS docs say to cast to int and compare to 32.
3423 //LPCWSTR directory_wstr = NULL; 2967 HWND our_window = NULL;
3424 //int retval = (int) ShellExecute(our_window, /* Flawfinder: ignore */ 2968 LPCWSTR directory_wstr = NULL;
3425 // L"open", 2969 int retval = (int) ShellExecute(our_window, // Flawfinder: ignore
3426 // browser_exec_utf16.c_str(), 2970 L"open",
3427 // url_utf16.c_str(), 2971 browser_exec_utf16.c_str(),
3428 // directory_wstr, 2972 url_utf16.c_str(),
3429 // SW_SHOWNORMAL); 2973 directory_wstr,
3430 //if (retval > 32) 2974 SW_SHOWNORMAL);
3431 //{ 2975 if (retval > 32)
3432 // llinfos << "load_url success with " << retval << llendl; 2976 {
3433 //} 2977 llinfos << "load_url success with " << retval << llendl;
3434 //else 2978 }
3435 //{ 2979 else
3436 // llinfos << "load_url failure with " << retval << llendl; 2980 {
3437 //} 2981 llinfos << "load_url failure with " << retval << llendl;
2982 }
2983 */
3438} 2984}
3439 2985
3440 2986
@@ -3448,13 +2994,13 @@ BOOL LLWindowWin32::dialog_color_picker ( F32 *r, F32 *g, F32 *b )
3448 cc.hwndOwner = mWindowHandle; 2994 cc.hwndOwner = mWindowHandle;
3449 cc.hInstance = NULL; 2995 cc.hInstance = NULL;
3450 cc.rgbResult = RGB ((*r * 255.f),(*g *255.f),(*b * 255.f)); 2996 cc.rgbResult = RGB ((*r * 255.f),(*g *255.f),(*b * 255.f));
3451 //cc.rgbResult = RGB (0x80,0x80,0x80); 2997 //cc.rgbResult = RGB (0x80,0x80,0x80);
3452 cc.lpCustColors = crCustColors; 2998 cc.lpCustColors = crCustColors;
3453 cc.Flags = CC_RGBINIT | CC_FULLOPEN; 2999 cc.Flags = CC_RGBINIT | CC_FULLOPEN;
3454 cc.lCustData = 0; 3000 cc.lCustData = 0;
3455 cc.lpfnHook = NULL; 3001 cc.lpfnHook = NULL;
3456 cc.lpTemplateName = NULL; 3002 cc.lpTemplateName = NULL;
3457 3003
3458 // This call is modal, so pause agent 3004 // This call is modal, so pause agent
3459 //send_agent_pause(); // this is in newview and we don't want to set up a dependency 3005 //send_agent_pause(); // this is in newview and we don't want to set up a dependency
3460 { 3006 {
@@ -3465,7 +3011,7 @@ BOOL LLWindowWin32::dialog_color_picker ( F32 *r, F32 *g, F32 *b )
3465 *b = ((F32)((cc.rgbResult >> 16) & 0xff)) / 255.f; 3011 *b = ((F32)((cc.rgbResult >> 16) & 0xff)) / 255.f;
3466 3012
3467 *g = ((F32)((cc.rgbResult >> 8) & 0xff)) / 255.f; 3013 *g = ((F32)((cc.rgbResult >> 8) & 0xff)) / 255.f;
3468 3014
3469 *r = ((F32)(cc.rgbResult & 0xff)) / 255.f; 3015 *r = ((F32)(cc.rgbResult & 0xff)) / 255.f;
3470 3016
3471 return (retval); 3017 return (retval);
@@ -3519,8 +3065,8 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
3519 3065
3520 if ( sLanguageTextInputAllowed ) 3066 if ( sLanguageTextInputAllowed )
3521 { 3067 {
3522 // Allowing: Restore the previous IME status, so that the user has a feeling that the previous 3068 // Allowing: Restore the previous IME status, so that the user has a feeling that the previous
3523 // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps 3069 // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
3524 // using same Input Locale (aka Keyboard Layout). 3070 // using same Input Locale (aka Keyboard Layout).
3525 if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) 3071 if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
3526 { 3072 {
@@ -3545,7 +3091,7 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
3545 { 3091 {
3546 LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); 3092 LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
3547 3093
3548 // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's 3094 // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
3549 // keyboard hooking, because Some IME reacts only on the former and some other on the latter... 3095 // keyboard hooking, because Some IME reacts only on the former and some other on the latter...
3550 LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); 3096 LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
3551 LLWinImm::setOpenStatus(himc, FALSE); 3097 LLWinImm::setOpenStatus(himc, FALSE);
@@ -3555,7 +3101,7 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
3555 } 3101 }
3556} 3102}
3557 3103
3558void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, 3104void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds,
3559 CANDIDATEFORM *form) 3105 CANDIDATEFORM *form)
3560{ 3106{
3561 LLCoordWindow caret_coord, top_left, bottom_right; 3107 LLCoordWindow caret_coord, top_left, bottom_right;
@@ -3584,7 +3130,7 @@ void LLWindowWin32::setLanguageTextInput( const LLCoordGL & position )
3584 LLCoordWindow win_pos; 3130 LLCoordWindow win_pos;
3585 convertCoords( position, &win_pos ); 3131 convertCoords( position, &win_pos );
3586 3132
3587 if ( win_pos.mX >= 0 && win_pos.mY >= 0 && 3133 if ( win_pos.mX >= 0 && win_pos.mY >= 0 &&
3588 (win_pos.mX != sWinIMEWindowPosition.mX) || (win_pos.mY != sWinIMEWindowPosition.mY) ) 3134 (win_pos.mX != sWinIMEWindowPosition.mX) || (win_pos.mY != sWinIMEWindowPosition.mY) )
3589 { 3135 {
3590 COMPOSITIONFORM ime_form; 3136 COMPOSITIONFORM ime_form;
@@ -3649,13 +3195,13 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont)
3649 default: 3195 default:
3650 logfont->lfCharSet = CHINESEBIG5_CHARSET; 3196 logfont->lfCharSet = CHINESEBIG5_CHARSET;
3651 lstrcpy(logfont->lfFaceName, TEXT("MingLiU")); 3197 lstrcpy(logfont->lfFaceName, TEXT("MingLiU"));
3652 break; 3198 break;
3653 } 3199 }
3654 break; 3200 break;
3655 case LANG_JAPANESE: 3201 case LANG_JAPANESE:
3656 logfont->lfCharSet = SHIFTJIS_CHARSET; 3202 logfont->lfCharSet = SHIFTJIS_CHARSET;
3657 lstrcpy(logfont->lfFaceName, TEXT("MS Gothic")); 3203 lstrcpy(logfont->lfFaceName, TEXT("MS Gothic"));
3658 break; 3204 break;
3659 case LANG_KOREAN: 3205 case LANG_KOREAN:
3660 logfont->lfCharSet = HANGUL_CHARSET; 3206 logfont->lfCharSet = HANGUL_CHARSET;
3661 lstrcpy(logfont->lfFaceName, TEXT("Gulim")); 3207 lstrcpy(logfont->lfFaceName, TEXT("Gulim"));
@@ -3665,10 +3211,10 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont)
3665 lstrcpy(logfont->lfFaceName, TEXT("Tahoma")); 3211 lstrcpy(logfont->lfFaceName, TEXT("Tahoma"));
3666 break; 3212 break;
3667 } 3213 }
3668 3214
3669 logfont->lfHeight = mPreeditor->getPreeditFontSize(); 3215 logfont->lfHeight = mPreeditor->getPreeditFontSize();
3670 logfont->lfWeight = FW_NORMAL; 3216 logfont->lfWeight = FW_NORMAL;
3671} 3217}
3672 3218
3673U32 LLWindowWin32::fillReconvertString(const LLWString &text, 3219U32 LLWindowWin32::fillReconvertString(const LLWString &text,
3674 S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string) 3220 S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string)
@@ -3782,7 +3328,7 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
3782 needs_update = TRUE; 3328 needs_update = TRUE;
3783 } 3329 }
3784 } 3330 }
3785 3331
3786 if (indexes & GCS_COMPSTR) 3332 if (indexes & GCS_COMPSTR)
3787 { 3333 {
3788 LONG size = LLWinImm::getCompositionString(himc, GCS_COMPSTR, NULL, 0); 3334 LONG size = LLWinImm::getCompositionString(himc, GCS_COMPSTR, NULL, 0);
@@ -3877,7 +3423,7 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
3877 { 3423 {
3878 for (LLWString::const_iterator i = result_string.begin(); i != result_string.end(); i++) 3424 for (LLWString::const_iterator i = result_string.begin(); i != result_string.end(); i++)
3879 { 3425 {
3880 mPreeditor->handleUnicodeCharHere(*i, FALSE); 3426 mPreeditor->handleUnicodeCharHere(*i);
3881 } 3427 }
3882 } 3428 }
3883 3429
@@ -3948,7 +3494,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
3948 LLCoordGL caret_coord; 3494 LLCoordGL caret_coord;
3949 LLRect preedit_bounds; 3495 LLRect preedit_bounds;
3950 mPreeditor->getPreeditLocation(-1, &caret_coord, &preedit_bounds, NULL); 3496 mPreeditor->getPreeditLocation(-1, &caret_coord, &preedit_bounds, NULL);
3951 3497
3952 CANDIDATEFORM *const form = (CANDIDATEFORM *)param; 3498 CANDIDATEFORM *const form = (CANDIDATEFORM *)param;
3953 DWORD const dwIndex = form->dwIndex; 3499 DWORD const dwIndex = form->dwIndex;
3954 fillCandidateForm(caret_coord, preedit_bounds, form); 3500 fillCandidateForm(caret_coord, preedit_bounds, form);
@@ -3963,7 +3509,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
3963 3509
3964 // char_position->dwCharPos counts in number of 3510 // char_position->dwCharPos counts in number of
3965 // WCHARs, i.e., UTF-16 encoding units, so we can't simply pass the 3511 // WCHARs, i.e., UTF-16 encoding units, so we can't simply pass the
3966 // number to getPreeditLocation. 3512 // number to getPreeditLocation.
3967 3513
3968 const LLWString & wtext = mPreeditor->getWText(); 3514 const LLWString & wtext = mPreeditor->getWText();
3969 S32 preedit, preedit_length; 3515 S32 preedit, preedit_length;
@@ -4037,7 +3583,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
4037 const LLWString & wtext = mPreeditor->getWText(); 3583 const LLWString & wtext = mPreeditor->getWText();
4038 S32 preedit, preedit_length; 3584 S32 preedit, preedit_length;
4039 mPreeditor->getPreeditRange(&preedit, &preedit_length); 3585 mPreeditor->getPreeditRange(&preedit, &preedit_length);
4040 3586
4041 S32 context_offset; 3587 S32 context_offset;
4042 LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); 3588 LLWString context = find_context(wtext, preedit, preedit_length, &context_offset);
4043 preedit -= context_offset; 3589 preedit -= context_offset;
@@ -4048,7 +3594,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
4048 // Otherwise, some IME are confused. 3594 // Otherwise, some IME are confused.
4049 context.erase(preedit, preedit_length); 3595 context.erase(preedit, preedit_length);
4050 } 3596 }
4051 3597
4052 RECONVERTSTRING *reconvert_string = (RECONVERTSTRING *)param; 3598 RECONVERTSTRING *reconvert_string = (RECONVERTSTRING *)param;
4053 *result = fillReconvertString(context, preedit, 0, reconvert_string); 3599 *result = fillReconvertString(context, preedit, 0, reconvert_string);
4054 return TRUE; 3600 return TRUE;