12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #define _JNI_IMPLEMENTATION_ 27 28 #include "awt.h" 29 #include <signal.h> 30 #include <windowsx.h> 31 #include <process.h> 32 33 #include "awt_DrawingSurface.h" 34 #include "awt_AWTEvent.h" 35 #include "awt_Component.h" 36 #include "awt_Canvas.h" 37 #include "awt_Clipboard.h" 38 #include "awt_Frame.h" 39 #include "awt_Dialog.h" 40 #include "awt_Font.h" 41 #include "awt_Cursor.h" 42 #include "awt_InputEvent.h" 43 #include "awt_KeyEvent.h" 44 #include "awt_List.h" 45 #include "awt_Palette.h" 46 #include "awt_PopupMenu.h" 47 #include "awt_Toolkit.h" 48 #include "awt_DesktopProperties.h" 49 #include "awt_FileDialog.h" 50 #include "CmdIDList.h" 51 #include "awt_new.h" 275 jmethodID AwtToolkit::insetsMID; 276 277 /************************************************************************ 278 * AwtToolkit methods 279 */ 280 281 AwtToolkit::AwtToolkit() { 282 m_localPump = FALSE; 283 m_mainThreadId = 0; 284 m_toolkitHWnd = NULL; 285 m_inputMethodHWnd = NULL; 286 m_verbose = FALSE; 287 m_isActive = TRUE; 288 m_isDisposed = FALSE; 289 290 m_vmSignalled = FALSE; 291 292 m_isDynamicLayoutSet = FALSE; 293 m_areExtraMouseButtonsEnabled = TRUE; 294 295 m_verifyComponents = FALSE; 296 m_breakOnError = FALSE; 297 298 m_breakMessageLoop = FALSE; 299 m_messageLoopResult = 0; 300 301 m_lastMouseOver = NULL; 302 m_mouseDown = FALSE; 303 304 m_hGetMessageHook = 0; 305 m_hMouseLLHook = 0; 306 m_lastWindowUnderMouse = NULL; 307 m_timer = 0; 308 309 m_cmdIDs = new AwtCmdIDList(); 310 m_pModalDialog = NULL; 311 m_peer = NULL; 312 m_dllHandle = NULL; 313 314 m_displayChanged = FALSE; 328 /* 329 * The code has been moved to AwtToolkit::Dispose() method. 330 */ 331 } 332 333 HWND AwtToolkit::CreateToolkitWnd(LPCTSTR name) 334 { 335 HWND hwnd = CreateWindow( 336 szAwtToolkitClassName, 337 (LPCTSTR)name, /* window name */ 338 WS_DISABLED, /* window style */ 339 -1, -1, /* position of window */ 340 0, 0, /* width and height */ 341 NULL, NULL, /* hWndParent and hWndMenu */ 342 GetModuleHandle(), 343 NULL); /* lpParam */ 344 DASSERT(hwnd != NULL); 345 return hwnd; 346 } 347 348 349 struct ToolkitThreadProc_Data { 350 bool result; 351 HANDLE hCompleted; 352 353 jobject thread; 354 jobject threadGroup; 355 }; 356 357 void ToolkitThreadProc(void *param) 358 { 359 ToolkitThreadProc_Data *data = (ToolkitThreadProc_Data *)param; 360 361 bool bNotified = false; 362 363 JNIEnv *env; 364 JavaVMAttachArgs attachArgs; 365 attachArgs.version = JNI_VERSION_1_2; 366 attachArgs.name = "AWT-Windows"; 367 attachArgs.group = data->threadGroup; 486 tk.m_localPump = localPump; 487 tk.m_mainThreadId = ::GetCurrentThreadId(); 488 489 /* 490 * Create the one-and-only toolkit window. This window isn't 491 * displayed, but is used to route messages to this thread. 492 */ 493 tk.m_toolkitHWnd = tk.CreateToolkitWnd(TEXT("theAwtToolkitWindow")); 494 DASSERT(tk.m_toolkitHWnd != NULL); 495 496 /* 497 * Setup a GetMessage filter to watch all messages coming out of our 498 * queue from PreProcessMsg(). 499 */ 500 tk.m_hGetMessageHook = ::SetWindowsHookEx(WH_GETMESSAGE, 501 (HOOKPROC)GetMessageFilter, 502 0, tk.m_mainThreadId); 503 504 awt_dnd_initialize(); 505 506 return TRUE; 507 } 508 509 BOOL AwtToolkit::Dispose() { 510 DTRACE_PRINTLN("In AwtToolkit::Dispose()"); 511 512 AwtToolkit& tk = AwtToolkit::GetInstance(); 513 514 if (!tk.m_isActive || tk.m_mainThreadId != ::GetCurrentThreadId()) { 515 return FALSE; 516 } 517 518 tk.m_isActive = FALSE; 519 520 // dispose Direct3D-related resources. This should be done 521 // before AwtObjectList::Cleanup() as the d3d will attempt to 522 // shutdown when the last of its windows is disposed of 523 D3DInitializer::GetInstance().Clean(); 524 525 AwtObjectList::Cleanup(); 526 527 awt_dnd_uninitialize(); 528 awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); 529 530 if (tk.m_inputMethodHWnd != NULL) { 531 ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); 532 } 533 tk.m_inputMethodHWnd = NULL; 534 535 // wait for any messages to be processed, in particular, 536 // all WM_AWT_DELETEOBJECT messages that delete components; no 537 // new messages will appear as all the windows except toolkit 538 // window are unsubclassed and destroyed 539 MSG msg; 540 while (::GetMessage(&msg, NULL, 0, 0)) { 541 ::TranslateMessage(&msg); 542 ::DispatchMessage(&msg); 543 } 544 545 AwtFont::Cleanup(); 546 547 HWND toolkitHWndToDestroy = tk.m_toolkitHWnd; 548 tk.m_toolkitHWnd = 0; 549 VERIFY(::DestroyWindow(toolkitHWndToDestroy) != NULL); 2641 2642 if (IS_WIN2000) { 2643 if (IS_WINXP) { 2644 if (IS_WINVISTA) { 2645 swprintf(szVer + l, 128, L" (Windows Vista)"); 2646 } else { 2647 swprintf(szVer + l, 128, L" (Windows XP)"); 2648 } 2649 } else { 2650 swprintf(szVer + l, 128, L" (Windows 2000)"); 2651 } 2652 } else { 2653 swprintf(szVer + l, 128, L" (Unknown)"); 2654 } 2655 2656 return JNU_NewStringPlatform(env, szVer); 2657 2658 CATCH_BAD_ALLOC_RET(NULL); 2659 } 2660 2661 JNIEXPORT jboolean JNICALL 2662 Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout) 2663 { 2664 AwtToolkit & tk = AwtToolkit::GetInstance(); 2665 DWORD eventNumber = tk.eventNumber; 2666 tk.PostMessage(WM_SYNC_WAIT, 0, 0); 2667 ::WaitForSingleObject(tk.m_waitEvent, INFINITE); 2668 DWORD newEventNumber = tk.eventNumber; 2669 return (newEventNumber - eventNumber) > 2; 2670 } 2671 2672 } /* extern "C" */ 2673 2674 /* Convert a Windows desktop color index into an RGB value. */ 2675 COLORREF DesktopColor2RGB(int colorIndex) { 2676 DWORD sysColor = ::GetSysColor(colorIndex); 2677 return ((GetRValue(sysColor)<<16) | (GetGValue(sysColor)<<8) | 2678 (GetBValue(sysColor)) | 0xff000000); 2679 } 2680 2713 */ 2714 extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseButtonsEnabledNative 2715 (JNIEnv *env, jclass self, jboolean enable){ 2716 TRY; 2717 AwtToolkit::GetInstance().setExtraMouseButtonsEnabled(enable); 2718 CATCH_BAD_ALLOC; 2719 } 2720 2721 void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) { 2722 m_areExtraMouseButtonsEnabled = enable; 2723 } 2724 2725 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl 2726 (JNIEnv *, jobject self) { 2727 return AwtToolkit::GetNumberOfButtons(); 2728 } 2729 2730 UINT AwtToolkit::GetNumberOfButtons() { 2731 return MOUSE_BUTTONS_WINDOWS_SUPPORTED; 2732 } | 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #define _JNI_IMPLEMENTATION_ 27 28 #include "awt.h" 29 #include <signal.h> 30 #include <windowsx.h> 31 #include <process.h> 32 #include <shellapi.h> 33 #include <shlwapi.h> 34 35 #include "awt_DrawingSurface.h" 36 #include "awt_AWTEvent.h" 37 #include "awt_Component.h" 38 #include "awt_Canvas.h" 39 #include "awt_Clipboard.h" 40 #include "awt_Frame.h" 41 #include "awt_Dialog.h" 42 #include "awt_Font.h" 43 #include "awt_Cursor.h" 44 #include "awt_InputEvent.h" 45 #include "awt_KeyEvent.h" 46 #include "awt_List.h" 47 #include "awt_Palette.h" 48 #include "awt_PopupMenu.h" 49 #include "awt_Toolkit.h" 50 #include "awt_DesktopProperties.h" 51 #include "awt_FileDialog.h" 52 #include "CmdIDList.h" 53 #include "awt_new.h" 277 jmethodID AwtToolkit::insetsMID; 278 279 /************************************************************************ 280 * AwtToolkit methods 281 */ 282 283 AwtToolkit::AwtToolkit() { 284 m_localPump = FALSE; 285 m_mainThreadId = 0; 286 m_toolkitHWnd = NULL; 287 m_inputMethodHWnd = NULL; 288 m_verbose = FALSE; 289 m_isActive = TRUE; 290 m_isDisposed = FALSE; 291 292 m_vmSignalled = FALSE; 293 294 m_isDynamicLayoutSet = FALSE; 295 m_areExtraMouseButtonsEnabled = TRUE; 296 297 m_isWin8OrLater = FALSE; 298 m_touchKbrdAutoShowIsEnabled = FALSE; 299 m_touchKbrdExeFilePath = NULL; 300 m_pRegisterTouchWindow = NULL; 301 m_pGetTouchInputInfo = NULL; 302 m_pCloseTouchInputHandle = NULL; 303 304 m_verifyComponents = FALSE; 305 m_breakOnError = FALSE; 306 307 m_breakMessageLoop = FALSE; 308 m_messageLoopResult = 0; 309 310 m_lastMouseOver = NULL; 311 m_mouseDown = FALSE; 312 313 m_hGetMessageHook = 0; 314 m_hMouseLLHook = 0; 315 m_lastWindowUnderMouse = NULL; 316 m_timer = 0; 317 318 m_cmdIDs = new AwtCmdIDList(); 319 m_pModalDialog = NULL; 320 m_peer = NULL; 321 m_dllHandle = NULL; 322 323 m_displayChanged = FALSE; 337 /* 338 * The code has been moved to AwtToolkit::Dispose() method. 339 */ 340 } 341 342 HWND AwtToolkit::CreateToolkitWnd(LPCTSTR name) 343 { 344 HWND hwnd = CreateWindow( 345 szAwtToolkitClassName, 346 (LPCTSTR)name, /* window name */ 347 WS_DISABLED, /* window style */ 348 -1, -1, /* position of window */ 349 0, 0, /* width and height */ 350 NULL, NULL, /* hWndParent and hWndMenu */ 351 GetModuleHandle(), 352 NULL); /* lpParam */ 353 DASSERT(hwnd != NULL); 354 return hwnd; 355 } 356 357 void AwtToolkit::InitTouchKeyboardExeFilePath() { 358 enum RegistryView { WOW64_32BIT, WOW64_64BIT }; 359 const TCHAR tabTipCoKeyName[] = _T("SOFTWARE\\Classes\\CLSID\\") 360 _T("{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32"); 361 HKEY hTabTipCoKey = NULL; 362 RegistryView regViewWithTabTipCoKey = WOW64_32BIT; 363 364 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0, 365 KEY_READ | KEY_WOW64_32KEY, &hTabTipCoKey) != ERROR_SUCCESS) { 366 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0, 367 KEY_READ | KEY_WOW64_64KEY, &hTabTipCoKey) != ERROR_SUCCESS) { 368 return; 369 } else { 370 regViewWithTabTipCoKey = WOW64_64BIT; 371 } 372 } 373 374 DWORD keyValType = 0; 375 DWORD bytesCopied = 0; 376 if ((::RegQueryValueEx(hTabTipCoKey, NULL, NULL, &keyValType, NULL, 377 &bytesCopied) != ERROR_SUCCESS) || 378 ((keyValType != REG_EXPAND_SZ) && (keyValType != REG_SZ))) { 379 if (hTabTipCoKey != NULL) { 380 ::RegCloseKey(hTabTipCoKey); 381 } 382 return; 383 } 384 385 // Increase the buffer size for 1 additional null-terminating character. 386 bytesCopied += sizeof(TCHAR); 387 TCHAR* tabTipFilePath = new TCHAR[bytesCopied / sizeof(TCHAR)]; 388 ::memset(tabTipFilePath, 0, bytesCopied); 389 390 DWORD oldBytesCopied = bytesCopied; 391 if (::RegQueryValueEx(hTabTipCoKey, NULL, NULL, NULL, 392 (LPBYTE)tabTipFilePath, &bytesCopied) == ERROR_SUCCESS) { 393 const TCHAR searchedStr[] = _T("%CommonProgramFiles%"); 394 const size_t searchedStrLen = ::_tcslen(searchedStr); 395 int searchedStrStartIndex = -1; 396 397 TCHAR* commonFilesDirPath = NULL; 398 DWORD commonFilesDirPathLen = 0; 399 400 // Check, if '%CommonProgramFiles%' string is present in the defined 401 // path of the touch keyboard executable. 402 TCHAR* const searchedStrStart = ::_tcsstr(tabTipFilePath, searchedStr); 403 if (searchedStrStart != NULL) { 404 searchedStrStartIndex = searchedStrStart - tabTipFilePath; 405 406 // Get value of 'CommonProgramFiles' environment variable, if the 407 // file path of the touch keyboard executable was found in 32-bit 408 // registry view, otherwise get value of 'CommonProgramW6432'. 409 const TCHAR envVar32BitName[] = _T("CommonProgramFiles"); 410 const TCHAR envVar64BitName[] = _T("CommonProgramW6432"); 411 const TCHAR* envVarName = (regViewWithTabTipCoKey == WOW64_32BIT ? 412 envVar32BitName : envVar64BitName); 413 414 DWORD charsStored = ::GetEnvironmentVariable(envVarName, NULL, 0); 415 if (charsStored > 0) { 416 commonFilesDirPath = new TCHAR[charsStored]; 417 ::memset(commonFilesDirPath, 0, charsStored * sizeof(TCHAR)); 418 419 DWORD oldCharsStored = charsStored; 420 if (((charsStored = ::GetEnvironmentVariable(envVarName, 421 commonFilesDirPath, charsStored)) > 0) && 422 (charsStored <= oldCharsStored)) { 423 commonFilesDirPathLen = charsStored; 424 } else { 425 delete[] commonFilesDirPath; 426 commonFilesDirPath = NULL; 427 } 428 } 429 } 430 431 // Calculate 'm_touchKbrdExeFilePath' length in characters including 432 // the null-terminating character. 433 DWORD exeFilePathLen = oldBytesCopied / sizeof(TCHAR); 434 if (commonFilesDirPathLen > 0) { 435 exeFilePathLen = exeFilePathLen - searchedStrLen + 436 commonFilesDirPathLen; 437 } 438 439 if (m_touchKbrdExeFilePath != NULL) { 440 delete[] m_touchKbrdExeFilePath; 441 m_touchKbrdExeFilePath = NULL; 442 } 443 m_touchKbrdExeFilePath = new TCHAR[exeFilePathLen]; 444 ::memset(m_touchKbrdExeFilePath, 0, exeFilePathLen * sizeof(TCHAR)); 445 446 if (commonFilesDirPathLen > 0) { 447 ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath, 448 searchedStrStartIndex); 449 DWORD charsCopied = searchedStrStartIndex; 450 451 ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied, 452 exeFilePathLen - charsCopied, commonFilesDirPath, 453 commonFilesDirPathLen); 454 charsCopied += commonFilesDirPathLen; 455 456 ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied, 457 exeFilePathLen - charsCopied, searchedStrStart + searchedStrLen, 458 bytesCopied / sizeof(TCHAR) - 459 (searchedStrStartIndex + searchedStrLen)); 460 } else { 461 ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath, 462 bytesCopied / sizeof(TCHAR)); 463 } 464 465 // Remove leading and trailing quotation marks. 466 ::StrTrim(m_touchKbrdExeFilePath, _T("\"")); 467 468 // Verify that a file with the path 'm_touchKbrdExeFilePath' exists. 469 DWORD fileAttrs = ::GetFileAttributes(m_touchKbrdExeFilePath); 470 DWORD err = ::GetLastError(); 471 if ((fileAttrs == INVALID_FILE_ATTRIBUTES) || 472 (fileAttrs & FILE_ATTRIBUTE_DIRECTORY)) { 473 delete[] m_touchKbrdExeFilePath; 474 m_touchKbrdExeFilePath = NULL; 475 } 476 477 if (commonFilesDirPath != NULL) { 478 delete[] commonFilesDirPath; 479 } 480 } 481 482 if (tabTipFilePath != NULL) { 483 delete[] tabTipFilePath; 484 } 485 if (hTabTipCoKey != NULL) { 486 ::RegCloseKey(hTabTipCoKey); 487 } 488 } 489 490 HWND AwtToolkit::GetTouchKeyboardWindow() { 491 const TCHAR wndClassName[] = _T("IPTip_Main_Window"); 492 HWND hwnd = ::FindWindow(wndClassName, NULL); 493 if ((hwnd != NULL) && ::IsWindow(hwnd) && ::IsWindowEnabled(hwnd) && 494 ::IsWindowVisible(hwnd)) { 495 return hwnd; 496 } 497 return NULL; 498 } 499 500 501 struct ToolkitThreadProc_Data { 502 bool result; 503 HANDLE hCompleted; 504 505 jobject thread; 506 jobject threadGroup; 507 }; 508 509 void ToolkitThreadProc(void *param) 510 { 511 ToolkitThreadProc_Data *data = (ToolkitThreadProc_Data *)param; 512 513 bool bNotified = false; 514 515 JNIEnv *env; 516 JavaVMAttachArgs attachArgs; 517 attachArgs.version = JNI_VERSION_1_2; 518 attachArgs.name = "AWT-Windows"; 519 attachArgs.group = data->threadGroup; 638 tk.m_localPump = localPump; 639 tk.m_mainThreadId = ::GetCurrentThreadId(); 640 641 /* 642 * Create the one-and-only toolkit window. This window isn't 643 * displayed, but is used to route messages to this thread. 644 */ 645 tk.m_toolkitHWnd = tk.CreateToolkitWnd(TEXT("theAwtToolkitWindow")); 646 DASSERT(tk.m_toolkitHWnd != NULL); 647 648 /* 649 * Setup a GetMessage filter to watch all messages coming out of our 650 * queue from PreProcessMsg(). 651 */ 652 tk.m_hGetMessageHook = ::SetWindowsHookEx(WH_GETMESSAGE, 653 (HOOKPROC)GetMessageFilter, 654 0, tk.m_mainThreadId); 655 656 awt_dnd_initialize(); 657 658 /* 659 * Initialization of the touch keyboard related variables. 660 */ 661 tk.m_isWin8OrLater = IS_WIN8; 662 663 TRY; 664 665 JNIEnv* env = AwtToolkit::GetEnv(); 666 jclass sunToolkitCls = env->FindClass("sun/awt/SunToolkit"); 667 DASSERT(sunToolkitCls != 0); 668 CHECK_NULL_RETURN(sunToolkitCls, FALSE); 669 670 jmethodID isTouchKeyboardAutoShowEnabledMID = env->GetStaticMethodID( 671 sunToolkitCls, "isTouchKeyboardAutoShowEnabled", "()Z"); 672 DASSERT(isTouchKeyboardAutoShowEnabledMID != 0); 673 CHECK_NULL_RETURN(isTouchKeyboardAutoShowEnabledMID, FALSE); 674 675 tk.m_touchKbrdAutoShowIsEnabled = env->CallStaticBooleanMethod( 676 sunToolkitCls, isTouchKeyboardAutoShowEnabledMID); 677 678 CATCH_BAD_ALLOC_RET(FALSE); 679 680 if (tk.m_isWin8OrLater && tk.m_touchKbrdAutoShowIsEnabled) { 681 tk.InitTouchKeyboardExeFilePath(); 682 HMODULE hUser32Dll = ::LoadLibrary(_T("user32.dll")); 683 if (hUser32Dll != NULL) { 684 tk.m_pRegisterTouchWindow = (RegisterTouchWindowFunc) 685 ::GetProcAddress(hUser32Dll, "RegisterTouchWindow"); 686 tk.m_pGetTouchInputInfo = (GetTouchInputInfoFunc) 687 ::GetProcAddress(hUser32Dll, "GetTouchInputInfo"); 688 tk.m_pCloseTouchInputHandle = (CloseTouchInputHandleFunc) 689 ::GetProcAddress(hUser32Dll, "CloseTouchInputHandle"); 690 } 691 692 if ((tk.m_pRegisterTouchWindow == NULL) || 693 (tk.m_pGetTouchInputInfo == NULL) || 694 (tk.m_pCloseTouchInputHandle == NULL)) { 695 tk.m_pRegisterTouchWindow = NULL; 696 tk.m_pGetTouchInputInfo = NULL; 697 tk.m_pCloseTouchInputHandle = NULL; 698 } 699 } 700 /* 701 * End of the touch keyboard related initialization code. 702 */ 703 704 return TRUE; 705 } 706 707 BOOL AwtToolkit::Dispose() { 708 DTRACE_PRINTLN("In AwtToolkit::Dispose()"); 709 710 AwtToolkit& tk = AwtToolkit::GetInstance(); 711 712 if (!tk.m_isActive || tk.m_mainThreadId != ::GetCurrentThreadId()) { 713 return FALSE; 714 } 715 716 tk.m_isActive = FALSE; 717 718 // dispose Direct3D-related resources. This should be done 719 // before AwtObjectList::Cleanup() as the d3d will attempt to 720 // shutdown when the last of its windows is disposed of 721 D3DInitializer::GetInstance().Clean(); 722 723 AwtObjectList::Cleanup(); 724 725 awt_dnd_uninitialize(); 726 awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); 727 728 if (tk.m_touchKbrdExeFilePath != NULL) { 729 delete[] tk.m_touchKbrdExeFilePath; 730 tk.m_touchKbrdExeFilePath = NULL; 731 } 732 tk.m_pRegisterTouchWindow = NULL; 733 tk.m_pGetTouchInputInfo = NULL; 734 tk.m_pCloseTouchInputHandle = NULL; 735 736 if (tk.m_inputMethodHWnd != NULL) { 737 ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); 738 } 739 tk.m_inputMethodHWnd = NULL; 740 741 // wait for any messages to be processed, in particular, 742 // all WM_AWT_DELETEOBJECT messages that delete components; no 743 // new messages will appear as all the windows except toolkit 744 // window are unsubclassed and destroyed 745 MSG msg; 746 while (::GetMessage(&msg, NULL, 0, 0)) { 747 ::TranslateMessage(&msg); 748 ::DispatchMessage(&msg); 749 } 750 751 AwtFont::Cleanup(); 752 753 HWND toolkitHWndToDestroy = tk.m_toolkitHWnd; 754 tk.m_toolkitHWnd = 0; 755 VERIFY(::DestroyWindow(toolkitHWndToDestroy) != NULL); 2847 2848 if (IS_WIN2000) { 2849 if (IS_WINXP) { 2850 if (IS_WINVISTA) { 2851 swprintf(szVer + l, 128, L" (Windows Vista)"); 2852 } else { 2853 swprintf(szVer + l, 128, L" (Windows XP)"); 2854 } 2855 } else { 2856 swprintf(szVer + l, 128, L" (Windows 2000)"); 2857 } 2858 } else { 2859 swprintf(szVer + l, 128, L" (Unknown)"); 2860 } 2861 2862 return JNU_NewStringPlatform(env, szVer); 2863 2864 CATCH_BAD_ALLOC_RET(NULL); 2865 } 2866 2867 JNIEXPORT void JNICALL 2868 Java_sun_awt_windows_WToolkit_showTouchKeyboard(JNIEnv *env, jobject self, 2869 jboolean causedByTouchEvent) 2870 { 2871 AwtToolkit& tk = AwtToolkit::GetInstance(); 2872 if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { 2873 return; 2874 } 2875 2876 if (causedByTouchEvent || 2877 (tk.IsTouchKeyboardAutoShowSystemEnabled() && 2878 !tk.IsAnyKeyboardAttached())) { 2879 tk.ShowTouchKeyboard(); 2880 } 2881 } 2882 2883 JNIEXPORT void JNICALL 2884 Java_sun_awt_windows_WToolkit_hideTouchKeyboard(JNIEnv *env, jobject self) 2885 { 2886 AwtToolkit& tk = AwtToolkit::GetInstance(); 2887 if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { 2888 return; 2889 } 2890 tk.HideTouchKeyboard(); 2891 } 2892 2893 JNIEXPORT jboolean JNICALL 2894 Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout) 2895 { 2896 AwtToolkit & tk = AwtToolkit::GetInstance(); 2897 DWORD eventNumber = tk.eventNumber; 2898 tk.PostMessage(WM_SYNC_WAIT, 0, 0); 2899 ::WaitForSingleObject(tk.m_waitEvent, INFINITE); 2900 DWORD newEventNumber = tk.eventNumber; 2901 return (newEventNumber - eventNumber) > 2; 2902 } 2903 2904 } /* extern "C" */ 2905 2906 /* Convert a Windows desktop color index into an RGB value. */ 2907 COLORREF DesktopColor2RGB(int colorIndex) { 2908 DWORD sysColor = ::GetSysColor(colorIndex); 2909 return ((GetRValue(sysColor)<<16) | (GetGValue(sysColor)<<8) | 2910 (GetBValue(sysColor)) | 0xff000000); 2911 } 2912 2945 */ 2946 extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseButtonsEnabledNative 2947 (JNIEnv *env, jclass self, jboolean enable){ 2948 TRY; 2949 AwtToolkit::GetInstance().setExtraMouseButtonsEnabled(enable); 2950 CATCH_BAD_ALLOC; 2951 } 2952 2953 void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) { 2954 m_areExtraMouseButtonsEnabled = enable; 2955 } 2956 2957 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl 2958 (JNIEnv *, jobject self) { 2959 return AwtToolkit::GetNumberOfButtons(); 2960 } 2961 2962 UINT AwtToolkit::GetNumberOfButtons() { 2963 return MOUSE_BUTTONS_WINDOWS_SUPPORTED; 2964 } 2965 2966 bool AwtToolkit::IsWin8OrLater() { 2967 return m_isWin8OrLater; 2968 } 2969 2970 bool AwtToolkit::IsTouchKeyboardAutoShowEnabled() { 2971 return m_touchKbrdAutoShowIsEnabled; 2972 } 2973 2974 bool AwtToolkit::IsAnyKeyboardAttached() { 2975 UINT numDevs = 0; 2976 UINT numDevsRet = 0; 2977 const UINT devListTypeSize = sizeof(RAWINPUTDEVICELIST); 2978 if ((::GetRawInputDeviceList(NULL, &numDevs, devListTypeSize) != 0) || 2979 (numDevs == 0)) { 2980 return false; 2981 } 2982 2983 RAWINPUTDEVICELIST* pDevList = new RAWINPUTDEVICELIST[numDevs]; 2984 while (((numDevsRet = ::GetRawInputDeviceList(pDevList, &numDevs, 2985 devListTypeSize)) == (UINT)-1) && 2986 (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 2987 if (pDevList != NULL) { 2988 delete[] pDevList; 2989 } 2990 pDevList = new RAWINPUTDEVICELIST[numDevs]; 2991 } 2992 2993 bool keyboardIsAttached = false; 2994 if (numDevsRet != (UINT)-1) { 2995 for (UINT i = 0; i < numDevsRet; i++) { 2996 if (pDevList[i].dwType == RIM_TYPEKEYBOARD) { 2997 keyboardIsAttached = true; 2998 break; 2999 } 3000 } 3001 } 3002 3003 if (pDevList != NULL) { 3004 delete[] pDevList; 3005 } 3006 return keyboardIsAttached; 3007 } 3008 3009 bool AwtToolkit::IsTouchKeyboardAutoShowSystemEnabled() { 3010 const TCHAR tabTipKeyName[] = _T("SOFTWARE\\Microsoft\\TabletTip\\1.7"); 3011 HKEY hTabTipKey = NULL; 3012 if (::RegOpenKeyEx(HKEY_CURRENT_USER, tabTipKeyName, 0, KEY_READ, 3013 &hTabTipKey) != ERROR_SUCCESS) { 3014 return false; 3015 } 3016 3017 const TCHAR enableAutoInvokeValName[] = _T("EnableDesktopModeAutoInvoke"); 3018 DWORD keyValType = 0; 3019 bool autoShowIsEnabled = false; 3020 if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL, 3021 &keyValType, NULL, NULL) == ERROR_SUCCESS) { 3022 if (keyValType == REG_DWORD) { 3023 DWORD enableAutoInvokeVal = 0; 3024 DWORD bytesCopied = sizeof(DWORD); 3025 if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL, 3026 NULL, (LPBYTE)(DWORD*)&enableAutoInvokeVal, 3027 &bytesCopied) == ERROR_SUCCESS) { 3028 autoShowIsEnabled = (enableAutoInvokeVal == 0 ? false : true); 3029 } 3030 } 3031 } 3032 3033 if (hTabTipKey != NULL) { 3034 ::RegCloseKey(hTabTipKey); 3035 } 3036 return autoShowIsEnabled; 3037 } 3038 3039 void AwtToolkit::ShowTouchKeyboard() { 3040 if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled && 3041 (m_touchKbrdExeFilePath != NULL)) { 3042 HINSTANCE retVal = ::ShellExecute(NULL, _T("open"), 3043 m_touchKbrdExeFilePath, NULL, NULL, SW_SHOW); 3044 if ((int)retVal <= 32) { 3045 DTRACE_PRINTLN1("AwtToolkit::ShowTouchKeyboard: Failed" 3046 ", retVal='%d'", (int)retVal); 3047 } 3048 } 3049 } 3050 3051 void AwtToolkit::HideTouchKeyboard() { 3052 if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled) { 3053 HWND hwnd = GetTouchKeyboardWindow(); 3054 if (hwnd != NULL) { 3055 ::PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0); 3056 } 3057 } 3058 } 3059 3060 BOOL AwtToolkit::TIRegisterTouchWindow(HWND hWnd, ULONG ulFlags) { 3061 if (m_pRegisterTouchWindow == NULL) { 3062 return FALSE; 3063 } 3064 return m_pRegisterTouchWindow(hWnd, ulFlags); 3065 } 3066 3067 BOOL AwtToolkit::TIGetTouchInputInfo(HTOUCHINPUT hTouchInput, 3068 UINT cInputs, PTOUCHINPUT pInputs, int cbSize) { 3069 if (m_pGetTouchInputInfo == NULL) { 3070 return FALSE; 3071 } 3072 return m_pGetTouchInputInfo(hTouchInput, cInputs, pInputs, cbSize); 3073 } 3074 3075 BOOL AwtToolkit::TICloseTouchInputHandle(HTOUCHINPUT hTouchInput) { 3076 if (m_pCloseTouchInputHandle == NULL) { 3077 return FALSE; 3078 } 3079 return m_pCloseTouchInputHandle(hTouchInput); 3080 } |