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" 288 jmethodID AwtToolkit::insetsMID; 289 290 /************************************************************************ 291 * AwtToolkit methods 292 */ 293 294 AwtToolkit::AwtToolkit() { 295 m_localPump = FALSE; 296 m_mainThreadId = 0; 297 m_toolkitHWnd = NULL; 298 m_inputMethodHWnd = NULL; 299 m_verbose = FALSE; 300 m_isActive = TRUE; 301 m_isDisposed = FALSE; 302 303 m_vmSignalled = FALSE; 304 305 m_isDynamicLayoutSet = FALSE; 306 m_areExtraMouseButtonsEnabled = TRUE; 307 308 m_verifyComponents = FALSE; 309 m_breakOnError = FALSE; 310 311 m_breakMessageLoop = FALSE; 312 m_messageLoopResult = 0; 313 314 m_lastMouseOver = NULL; 315 m_mouseDown = FALSE; 316 317 m_hGetMessageHook = 0; 318 m_hMouseLLHook = 0; 319 m_lastWindowUnderMouse = NULL; 320 m_timer = 0; 321 322 m_cmdIDs = new AwtCmdIDList(); 323 m_pModalDialog = NULL; 324 m_peer = NULL; 325 m_dllHandle = NULL; 326 327 m_displayChanged = FALSE; 342 /* 343 * The code has been moved to AwtToolkit::Dispose() method. 344 */ 345 } 346 347 HWND AwtToolkit::CreateToolkitWnd(LPCTSTR name) 348 { 349 HWND hwnd = CreateWindow( 350 szAwtToolkitClassName, 351 (LPCTSTR)name, /* window name */ 352 WS_DISABLED, /* window style */ 353 -1, -1, /* position of window */ 354 0, 0, /* width and height */ 355 NULL, NULL, /* hWndParent and hWndMenu */ 356 GetModuleHandle(), 357 NULL); /* lpParam */ 358 DASSERT(hwnd != NULL); 359 return hwnd; 360 } 361 362 363 struct ToolkitThreadProc_Data { 364 bool result; 365 HANDLE hCompleted; 366 367 jobject thread; 368 jobject threadGroup; 369 }; 370 371 void ToolkitThreadProc(void *param) 372 { 373 ToolkitThreadProc_Data *data = (ToolkitThreadProc_Data *)param; 374 375 bool bNotified = false; 376 377 JNIEnv *env; 378 JavaVMAttachArgs attachArgs; 379 attachArgs.version = JNI_VERSION_1_2; 380 attachArgs.name = "AWT-Windows"; 381 attachArgs.group = data->threadGroup; 500 tk.m_localPump = localPump; 501 tk.m_mainThreadId = ::GetCurrentThreadId(); 502 503 /* 504 * Create the one-and-only toolkit window. This window isn't 505 * displayed, but is used to route messages to this thread. 506 */ 507 tk.m_toolkitHWnd = tk.CreateToolkitWnd(TEXT("theAwtToolkitWindow")); 508 DASSERT(tk.m_toolkitHWnd != NULL); 509 510 /* 511 * Setup a GetMessage filter to watch all messages coming out of our 512 * queue from PreProcessMsg(). 513 */ 514 tk.m_hGetMessageHook = ::SetWindowsHookEx(WH_GETMESSAGE, 515 (HOOKPROC)GetMessageFilter, 516 0, tk.m_mainThreadId); 517 518 awt_dnd_initialize(); 519 520 return TRUE; 521 } 522 523 BOOL AwtToolkit::Dispose() { 524 DTRACE_PRINTLN("In AwtToolkit::Dispose()"); 525 526 AwtToolkit& tk = AwtToolkit::GetInstance(); 527 528 if (!tk.m_isActive || tk.m_mainThreadId != ::GetCurrentThreadId()) { 529 return FALSE; 530 } 531 532 tk.m_isActive = FALSE; 533 534 // dispose Direct3D-related resources. This should be done 535 // before AwtObjectList::Cleanup() as the d3d will attempt to 536 // shutdown when the last of its windows is disposed of 537 D3DInitializer::GetInstance().Clean(); 538 539 AwtObjectList::Cleanup(); 540 541 awt_dnd_uninitialize(); 542 awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); 543 544 if (tk.m_inputMethodHWnd != NULL) { 545 ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); 546 } 547 tk.m_inputMethodHWnd = NULL; 548 549 // wait for any messages to be processed, in particular, 550 // all WM_AWT_DELETEOBJECT messages that delete components; no 551 // new messages will appear as all the windows except toolkit 552 // window are unsubclassed and destroyed 553 MSG msg; 554 while (::GetMessage(&msg, NULL, 0, 0)) { 555 ::TranslateMessage(&msg); 556 ::DispatchMessage(&msg); 557 } 558 559 AwtFont::Cleanup(); 560 561 HWND toolkitHWndToDestroy = tk.m_toolkitHWnd; 562 tk.m_toolkitHWnd = 0; 563 VERIFY(::DestroyWindow(toolkitHWndToDestroy) != NULL); 2730 2731 if (IS_WIN2000) { 2732 if (IS_WINXP) { 2733 if (IS_WINVISTA) { 2734 swprintf(szVer + l, 128, L" (Windows Vista)"); 2735 } else { 2736 swprintf(szVer + l, 128, L" (Windows XP)"); 2737 } 2738 } else { 2739 swprintf(szVer + l, 128, L" (Windows 2000)"); 2740 } 2741 } else { 2742 swprintf(szVer + l, 128, L" (Unknown)"); 2743 } 2744 2745 return JNU_NewStringPlatform(env, szVer); 2746 2747 CATCH_BAD_ALLOC_RET(NULL); 2748 } 2749 2750 JNIEXPORT jboolean JNICALL 2751 Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout) 2752 { 2753 AwtToolkit & tk = AwtToolkit::GetInstance(); 2754 DWORD eventNumber = tk.eventNumber; 2755 tk.PostMessage(WM_SYNC_WAIT, 0, 0); 2756 for(long t = 2; t < timeout && 2757 WAIT_TIMEOUT == ::WaitForSingleObject(tk.m_waitEvent, 2); t+=2) { 2758 if (tk.isInDoDragDropLoop) { 2759 break; 2760 } 2761 } 2762 DWORD newEventNumber = tk.eventNumber; 2763 return (newEventNumber - eventNumber) > 2; 2764 } 2765 2766 } /* extern "C" */ 2767 2768 /* Convert a Windows desktop color index into an RGB value. */ 2769 COLORREF DesktopColor2RGB(int colorIndex) { 2807 */ 2808 extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseButtonsEnabledNative 2809 (JNIEnv *env, jclass self, jboolean enable){ 2810 TRY; 2811 AwtToolkit::GetInstance().setExtraMouseButtonsEnabled(enable); 2812 CATCH_BAD_ALLOC; 2813 } 2814 2815 void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) { 2816 m_areExtraMouseButtonsEnabled = enable; 2817 } 2818 2819 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl 2820 (JNIEnv *, jobject self) { 2821 return AwtToolkit::GetNumberOfButtons(); 2822 } 2823 2824 UINT AwtToolkit::GetNumberOfButtons() { 2825 return MOUSE_BUTTONS_WINDOWS_SUPPORTED; 2826 } | 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" 290 jmethodID AwtToolkit::insetsMID; 291 292 /************************************************************************ 293 * AwtToolkit methods 294 */ 295 296 AwtToolkit::AwtToolkit() { 297 m_localPump = FALSE; 298 m_mainThreadId = 0; 299 m_toolkitHWnd = NULL; 300 m_inputMethodHWnd = NULL; 301 m_verbose = FALSE; 302 m_isActive = TRUE; 303 m_isDisposed = FALSE; 304 305 m_vmSignalled = FALSE; 306 307 m_isDynamicLayoutSet = FALSE; 308 m_areExtraMouseButtonsEnabled = TRUE; 309 310 m_isWin8OrLater = FALSE; 311 m_touchKbrdAutoShowIsEnabled = FALSE; 312 m_touchKbrdExeFilePath = NULL; 313 m_pRegisterTouchWindow = NULL; 314 m_pGetTouchInputInfo = NULL; 315 m_pCloseTouchInputHandle = NULL; 316 317 m_verifyComponents = FALSE; 318 m_breakOnError = FALSE; 319 320 m_breakMessageLoop = FALSE; 321 m_messageLoopResult = 0; 322 323 m_lastMouseOver = NULL; 324 m_mouseDown = FALSE; 325 326 m_hGetMessageHook = 0; 327 m_hMouseLLHook = 0; 328 m_lastWindowUnderMouse = NULL; 329 m_timer = 0; 330 331 m_cmdIDs = new AwtCmdIDList(); 332 m_pModalDialog = NULL; 333 m_peer = NULL; 334 m_dllHandle = NULL; 335 336 m_displayChanged = FALSE; 351 /* 352 * The code has been moved to AwtToolkit::Dispose() method. 353 */ 354 } 355 356 HWND AwtToolkit::CreateToolkitWnd(LPCTSTR name) 357 { 358 HWND hwnd = CreateWindow( 359 szAwtToolkitClassName, 360 (LPCTSTR)name, /* window name */ 361 WS_DISABLED, /* window style */ 362 -1, -1, /* position of window */ 363 0, 0, /* width and height */ 364 NULL, NULL, /* hWndParent and hWndMenu */ 365 GetModuleHandle(), 366 NULL); /* lpParam */ 367 DASSERT(hwnd != NULL); 368 return hwnd; 369 } 370 371 void AwtToolkit::InitTouchKeyboardExeFilePath() { 372 enum RegistryView { WOW64_32BIT, WOW64_64BIT }; 373 const TCHAR tabTipCoKeyName[] = _T("SOFTWARE\\Classes\\CLSID\\") 374 _T("{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32"); 375 HKEY hTabTipCoKey = NULL; 376 RegistryView regViewWithTabTipCoKey = WOW64_32BIT; 377 378 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0, 379 KEY_READ | KEY_WOW64_32KEY, &hTabTipCoKey) != ERROR_SUCCESS) { 380 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0, 381 KEY_READ | KEY_WOW64_64KEY, &hTabTipCoKey) != ERROR_SUCCESS) { 382 return; 383 } else { 384 regViewWithTabTipCoKey = WOW64_64BIT; 385 } 386 } 387 388 DWORD keyValType = 0; 389 DWORD bytesCopied = 0; 390 if ((::RegQueryValueEx(hTabTipCoKey, NULL, NULL, &keyValType, NULL, 391 &bytesCopied) != ERROR_SUCCESS) || 392 ((keyValType != REG_EXPAND_SZ) && (keyValType != REG_SZ))) { 393 if (hTabTipCoKey != NULL) { 394 ::RegCloseKey(hTabTipCoKey); 395 } 396 return; 397 } 398 399 // Increase the buffer size for 1 additional null-terminating character. 400 bytesCopied += sizeof(TCHAR); 401 TCHAR* tabTipFilePath = new TCHAR[bytesCopied / sizeof(TCHAR)]; 402 ::memset(tabTipFilePath, 0, bytesCopied); 403 404 DWORD oldBytesCopied = bytesCopied; 405 if (::RegQueryValueEx(hTabTipCoKey, NULL, NULL, NULL, 406 (LPBYTE)tabTipFilePath, &bytesCopied) == ERROR_SUCCESS) { 407 const TCHAR searchedStr[] = _T("%CommonProgramFiles%"); 408 const size_t searchedStrLen = ::_tcslen(searchedStr); 409 int searchedStrStartIndex = -1; 410 411 TCHAR* commonFilesDirPath = NULL; 412 DWORD commonFilesDirPathLen = 0; 413 414 // Check, if '%CommonProgramFiles%' string is present in the defined 415 // path of the touch keyboard executable. 416 TCHAR* const searchedStrStart = ::_tcsstr(tabTipFilePath, searchedStr); 417 if (searchedStrStart != NULL) { 418 searchedStrStartIndex = searchedStrStart - tabTipFilePath; 419 420 // Get value of 'CommonProgramFiles' environment variable, if the 421 // file path of the touch keyboard executable was found in 32-bit 422 // registry view, otherwise get value of 'CommonProgramW6432'. 423 const TCHAR envVar32BitName[] = _T("CommonProgramFiles"); 424 const TCHAR envVar64BitName[] = _T("CommonProgramW6432"); 425 const TCHAR* envVarName = (regViewWithTabTipCoKey == WOW64_32BIT ? 426 envVar32BitName : envVar64BitName); 427 428 DWORD charsStored = ::GetEnvironmentVariable(envVarName, NULL, 0); 429 if (charsStored > 0) { 430 commonFilesDirPath = new TCHAR[charsStored]; 431 ::memset(commonFilesDirPath, 0, charsStored * sizeof(TCHAR)); 432 433 DWORD oldCharsStored = charsStored; 434 if (((charsStored = ::GetEnvironmentVariable(envVarName, 435 commonFilesDirPath, charsStored)) > 0) && 436 (charsStored <= oldCharsStored)) { 437 commonFilesDirPathLen = charsStored; 438 } else { 439 delete[] commonFilesDirPath; 440 commonFilesDirPath = NULL; 441 } 442 } 443 } 444 445 // Calculate 'm_touchKbrdExeFilePath' length in characters including 446 // the null-terminating character. 447 DWORD exeFilePathLen = oldBytesCopied / sizeof(TCHAR); 448 if (commonFilesDirPathLen > 0) { 449 exeFilePathLen = exeFilePathLen - searchedStrLen + 450 commonFilesDirPathLen; 451 } 452 453 if (m_touchKbrdExeFilePath != NULL) { 454 delete[] m_touchKbrdExeFilePath; 455 m_touchKbrdExeFilePath = NULL; 456 } 457 m_touchKbrdExeFilePath = new TCHAR[exeFilePathLen]; 458 ::memset(m_touchKbrdExeFilePath, 0, exeFilePathLen * sizeof(TCHAR)); 459 460 if (commonFilesDirPathLen > 0) { 461 ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath, 462 searchedStrStartIndex); 463 DWORD charsCopied = searchedStrStartIndex; 464 465 ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied, 466 exeFilePathLen - charsCopied, commonFilesDirPath, 467 commonFilesDirPathLen); 468 charsCopied += commonFilesDirPathLen; 469 470 ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied, 471 exeFilePathLen - charsCopied, searchedStrStart + searchedStrLen, 472 bytesCopied / sizeof(TCHAR) - 473 (searchedStrStartIndex + searchedStrLen)); 474 } else { 475 ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath, 476 bytesCopied / sizeof(TCHAR)); 477 } 478 479 // Remove leading and trailing quotation marks. 480 ::StrTrim(m_touchKbrdExeFilePath, _T("\"")); 481 482 // Verify that a file with the path 'm_touchKbrdExeFilePath' exists. 483 DWORD fileAttrs = ::GetFileAttributes(m_touchKbrdExeFilePath); 484 DWORD err = ::GetLastError(); 485 if ((fileAttrs == INVALID_FILE_ATTRIBUTES) || 486 (fileAttrs & FILE_ATTRIBUTE_DIRECTORY)) { 487 delete[] m_touchKbrdExeFilePath; 488 m_touchKbrdExeFilePath = NULL; 489 } 490 491 if (commonFilesDirPath != NULL) { 492 delete[] commonFilesDirPath; 493 } 494 } 495 496 if (tabTipFilePath != NULL) { 497 delete[] tabTipFilePath; 498 } 499 if (hTabTipCoKey != NULL) { 500 ::RegCloseKey(hTabTipCoKey); 501 } 502 } 503 504 HWND AwtToolkit::GetTouchKeyboardWindow() { 505 const TCHAR wndClassName[] = _T("IPTip_Main_Window"); 506 HWND hwnd = ::FindWindow(wndClassName, NULL); 507 if ((hwnd != NULL) && ::IsWindow(hwnd) && ::IsWindowEnabled(hwnd) && 508 ::IsWindowVisible(hwnd)) { 509 return hwnd; 510 } 511 return NULL; 512 } 513 514 515 struct ToolkitThreadProc_Data { 516 bool result; 517 HANDLE hCompleted; 518 519 jobject thread; 520 jobject threadGroup; 521 }; 522 523 void ToolkitThreadProc(void *param) 524 { 525 ToolkitThreadProc_Data *data = (ToolkitThreadProc_Data *)param; 526 527 bool bNotified = false; 528 529 JNIEnv *env; 530 JavaVMAttachArgs attachArgs; 531 attachArgs.version = JNI_VERSION_1_2; 532 attachArgs.name = "AWT-Windows"; 533 attachArgs.group = data->threadGroup; 652 tk.m_localPump = localPump; 653 tk.m_mainThreadId = ::GetCurrentThreadId(); 654 655 /* 656 * Create the one-and-only toolkit window. This window isn't 657 * displayed, but is used to route messages to this thread. 658 */ 659 tk.m_toolkitHWnd = tk.CreateToolkitWnd(TEXT("theAwtToolkitWindow")); 660 DASSERT(tk.m_toolkitHWnd != NULL); 661 662 /* 663 * Setup a GetMessage filter to watch all messages coming out of our 664 * queue from PreProcessMsg(). 665 */ 666 tk.m_hGetMessageHook = ::SetWindowsHookEx(WH_GETMESSAGE, 667 (HOOKPROC)GetMessageFilter, 668 0, tk.m_mainThreadId); 669 670 awt_dnd_initialize(); 671 672 /* 673 * Initialization of the touch keyboard related variables. 674 */ 675 tk.m_isWin8OrLater = IS_WIN8; 676 677 TRY; 678 679 JNIEnv* env = AwtToolkit::GetEnv(); 680 jclass sunToolkitCls = env->FindClass("sun/awt/SunToolkit"); 681 DASSERT(sunToolkitCls != 0); 682 CHECK_NULL_RETURN(sunToolkitCls, FALSE); 683 684 jmethodID isTouchKeyboardAutoShowEnabledMID = env->GetStaticMethodID( 685 sunToolkitCls, "isTouchKeyboardAutoShowEnabled", "()Z"); 686 DASSERT(isTouchKeyboardAutoShowEnabledMID != 0); 687 CHECK_NULL_RETURN(isTouchKeyboardAutoShowEnabledMID, FALSE); 688 689 tk.m_touchKbrdAutoShowIsEnabled = env->CallStaticBooleanMethod( 690 sunToolkitCls, isTouchKeyboardAutoShowEnabledMID); 691 692 CATCH_BAD_ALLOC_RET(FALSE); 693 694 if (tk.m_isWin8OrLater && tk.m_touchKbrdAutoShowIsEnabled) { 695 tk.InitTouchKeyboardExeFilePath(); 696 HMODULE hUser32Dll = ::LoadLibrary(_T("user32.dll")); 697 if (hUser32Dll != NULL) { 698 tk.m_pRegisterTouchWindow = (RegisterTouchWindowFunc) 699 ::GetProcAddress(hUser32Dll, "RegisterTouchWindow"); 700 tk.m_pGetTouchInputInfo = (GetTouchInputInfoFunc) 701 ::GetProcAddress(hUser32Dll, "GetTouchInputInfo"); 702 tk.m_pCloseTouchInputHandle = (CloseTouchInputHandleFunc) 703 ::GetProcAddress(hUser32Dll, "CloseTouchInputHandle"); 704 } 705 706 if ((tk.m_pRegisterTouchWindow == NULL) || 707 (tk.m_pGetTouchInputInfo == NULL) || 708 (tk.m_pCloseTouchInputHandle == NULL)) { 709 tk.m_pRegisterTouchWindow = NULL; 710 tk.m_pGetTouchInputInfo = NULL; 711 tk.m_pCloseTouchInputHandle = NULL; 712 } 713 } 714 /* 715 * End of the touch keyboard related initialization code. 716 */ 717 718 return TRUE; 719 } 720 721 BOOL AwtToolkit::Dispose() { 722 DTRACE_PRINTLN("In AwtToolkit::Dispose()"); 723 724 AwtToolkit& tk = AwtToolkit::GetInstance(); 725 726 if (!tk.m_isActive || tk.m_mainThreadId != ::GetCurrentThreadId()) { 727 return FALSE; 728 } 729 730 tk.m_isActive = FALSE; 731 732 // dispose Direct3D-related resources. This should be done 733 // before AwtObjectList::Cleanup() as the d3d will attempt to 734 // shutdown when the last of its windows is disposed of 735 D3DInitializer::GetInstance().Clean(); 736 737 AwtObjectList::Cleanup(); 738 739 awt_dnd_uninitialize(); 740 awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); 741 742 if (tk.m_touchKbrdExeFilePath != NULL) { 743 delete[] tk.m_touchKbrdExeFilePath; 744 tk.m_touchKbrdExeFilePath = NULL; 745 } 746 tk.m_pRegisterTouchWindow = NULL; 747 tk.m_pGetTouchInputInfo = NULL; 748 tk.m_pCloseTouchInputHandle = NULL; 749 750 if (tk.m_inputMethodHWnd != NULL) { 751 ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); 752 } 753 tk.m_inputMethodHWnd = NULL; 754 755 // wait for any messages to be processed, in particular, 756 // all WM_AWT_DELETEOBJECT messages that delete components; no 757 // new messages will appear as all the windows except toolkit 758 // window are unsubclassed and destroyed 759 MSG msg; 760 while (::GetMessage(&msg, NULL, 0, 0)) { 761 ::TranslateMessage(&msg); 762 ::DispatchMessage(&msg); 763 } 764 765 AwtFont::Cleanup(); 766 767 HWND toolkitHWndToDestroy = tk.m_toolkitHWnd; 768 tk.m_toolkitHWnd = 0; 769 VERIFY(::DestroyWindow(toolkitHWndToDestroy) != NULL); 2936 2937 if (IS_WIN2000) { 2938 if (IS_WINXP) { 2939 if (IS_WINVISTA) { 2940 swprintf(szVer + l, 128, L" (Windows Vista)"); 2941 } else { 2942 swprintf(szVer + l, 128, L" (Windows XP)"); 2943 } 2944 } else { 2945 swprintf(szVer + l, 128, L" (Windows 2000)"); 2946 } 2947 } else { 2948 swprintf(szVer + l, 128, L" (Unknown)"); 2949 } 2950 2951 return JNU_NewStringPlatform(env, szVer); 2952 2953 CATCH_BAD_ALLOC_RET(NULL); 2954 } 2955 2956 JNIEXPORT void JNICALL 2957 Java_sun_awt_windows_WToolkit_showTouchKeyboard(JNIEnv *env, jobject self, 2958 jboolean causedByTouchEvent) 2959 { 2960 AwtToolkit& tk = AwtToolkit::GetInstance(); 2961 if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { 2962 return; 2963 } 2964 2965 if (causedByTouchEvent || 2966 (tk.IsTouchKeyboardAutoShowSystemEnabled() && 2967 !tk.IsAnyKeyboardAttached())) { 2968 tk.ShowTouchKeyboard(); 2969 } 2970 } 2971 2972 JNIEXPORT void JNICALL 2973 Java_sun_awt_windows_WToolkit_hideTouchKeyboard(JNIEnv *env, jobject self) 2974 { 2975 AwtToolkit& tk = AwtToolkit::GetInstance(); 2976 if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { 2977 return; 2978 } 2979 tk.HideTouchKeyboard(); 2980 } 2981 2982 JNIEXPORT jboolean JNICALL 2983 Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout) 2984 { 2985 AwtToolkit & tk = AwtToolkit::GetInstance(); 2986 DWORD eventNumber = tk.eventNumber; 2987 tk.PostMessage(WM_SYNC_WAIT, 0, 0); 2988 for(long t = 2; t < timeout && 2989 WAIT_TIMEOUT == ::WaitForSingleObject(tk.m_waitEvent, 2); t+=2) { 2990 if (tk.isInDoDragDropLoop) { 2991 break; 2992 } 2993 } 2994 DWORD newEventNumber = tk.eventNumber; 2995 return (newEventNumber - eventNumber) > 2; 2996 } 2997 2998 } /* extern "C" */ 2999 3000 /* Convert a Windows desktop color index into an RGB value. */ 3001 COLORREF DesktopColor2RGB(int colorIndex) { 3039 */ 3040 extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseButtonsEnabledNative 3041 (JNIEnv *env, jclass self, jboolean enable){ 3042 TRY; 3043 AwtToolkit::GetInstance().setExtraMouseButtonsEnabled(enable); 3044 CATCH_BAD_ALLOC; 3045 } 3046 3047 void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) { 3048 m_areExtraMouseButtonsEnabled = enable; 3049 } 3050 3051 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl 3052 (JNIEnv *, jobject self) { 3053 return AwtToolkit::GetNumberOfButtons(); 3054 } 3055 3056 UINT AwtToolkit::GetNumberOfButtons() { 3057 return MOUSE_BUTTONS_WINDOWS_SUPPORTED; 3058 } 3059 3060 bool AwtToolkit::IsWin8OrLater() { 3061 return m_isWin8OrLater; 3062 } 3063 3064 bool AwtToolkit::IsTouchKeyboardAutoShowEnabled() { 3065 return m_touchKbrdAutoShowIsEnabled; 3066 } 3067 3068 bool AwtToolkit::IsAnyKeyboardAttached() { 3069 UINT numDevs = 0; 3070 UINT numDevsRet = 0; 3071 const UINT devListTypeSize = sizeof(RAWINPUTDEVICELIST); 3072 if ((::GetRawInputDeviceList(NULL, &numDevs, devListTypeSize) != 0) || 3073 (numDevs == 0)) { 3074 return false; 3075 } 3076 3077 RAWINPUTDEVICELIST* pDevList = new RAWINPUTDEVICELIST[numDevs]; 3078 while (((numDevsRet = ::GetRawInputDeviceList(pDevList, &numDevs, 3079 devListTypeSize)) == (UINT)-1) && 3080 (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 3081 if (pDevList != NULL) { 3082 delete[] pDevList; 3083 } 3084 pDevList = new RAWINPUTDEVICELIST[numDevs]; 3085 } 3086 3087 bool keyboardIsAttached = false; 3088 if (numDevsRet != (UINT)-1) { 3089 for (UINT i = 0; i < numDevsRet; i++) { 3090 if (pDevList[i].dwType == RIM_TYPEKEYBOARD) { 3091 keyboardIsAttached = true; 3092 break; 3093 } 3094 } 3095 } 3096 3097 if (pDevList != NULL) { 3098 delete[] pDevList; 3099 } 3100 return keyboardIsAttached; 3101 } 3102 3103 bool AwtToolkit::IsTouchKeyboardAutoShowSystemEnabled() { 3104 const TCHAR tabTipKeyName[] = _T("SOFTWARE\\Microsoft\\TabletTip\\1.7"); 3105 HKEY hTabTipKey = NULL; 3106 if (::RegOpenKeyEx(HKEY_CURRENT_USER, tabTipKeyName, 0, KEY_READ, 3107 &hTabTipKey) != ERROR_SUCCESS) { 3108 return false; 3109 } 3110 3111 const TCHAR enableAutoInvokeValName[] = _T("EnableDesktopModeAutoInvoke"); 3112 DWORD keyValType = 0; 3113 bool autoShowIsEnabled = false; 3114 if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL, 3115 &keyValType, NULL, NULL) == ERROR_SUCCESS) { 3116 if (keyValType == REG_DWORD) { 3117 DWORD enableAutoInvokeVal = 0; 3118 DWORD bytesCopied = sizeof(DWORD); 3119 if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL, 3120 NULL, (LPBYTE)(DWORD*)&enableAutoInvokeVal, 3121 &bytesCopied) == ERROR_SUCCESS) { 3122 autoShowIsEnabled = (enableAutoInvokeVal == 0 ? false : true); 3123 } 3124 } 3125 } 3126 3127 if (hTabTipKey != NULL) { 3128 ::RegCloseKey(hTabTipKey); 3129 } 3130 return autoShowIsEnabled; 3131 } 3132 3133 void AwtToolkit::ShowTouchKeyboard() { 3134 if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled && 3135 (m_touchKbrdExeFilePath != NULL)) { 3136 HINSTANCE retVal = ::ShellExecute(NULL, _T("open"), 3137 m_touchKbrdExeFilePath, NULL, NULL, SW_SHOW); 3138 if ((int)retVal <= 32) { 3139 // Verify that a file with the path 'm_touchKbrdExeFilePath' exists. 3140 DWORD fileAttrs = ::GetFileAttributes(m_touchKbrdExeFilePath); 3141 if ((fileAttrs == INVALID_FILE_ATTRIBUTES) || 3142 (fileAttrs & FILE_ATTRIBUTE_DIRECTORY)) { 3143 delete[] m_touchKbrdExeFilePath; 3144 m_touchKbrdExeFilePath = NULL; 3145 } 3146 } 3147 } 3148 } 3149 3150 void AwtToolkit::HideTouchKeyboard() { 3151 if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled) { 3152 HWND hwnd = GetTouchKeyboardWindow(); 3153 if (hwnd != NULL) { 3154 ::PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0); 3155 } 3156 } 3157 } 3158 3159 BOOL AwtToolkit::TIRegisterTouchWindow(HWND hWnd, ULONG ulFlags) { 3160 if (m_pRegisterTouchWindow == NULL) { 3161 return FALSE; 3162 } 3163 return m_pRegisterTouchWindow(hWnd, ulFlags); 3164 } 3165 3166 BOOL AwtToolkit::TIGetTouchInputInfo(HTOUCHINPUT hTouchInput, 3167 UINT cInputs, PTOUCHINPUT pInputs, int cbSize) { 3168 if (m_pGetTouchInputInfo == NULL) { 3169 return FALSE; 3170 } 3171 return m_pGetTouchInputInfo(hTouchInput, cInputs, pInputs, cbSize); 3172 } 3173 3174 BOOL AwtToolkit::TICloseTouchInputHandle(HTOUCHINPUT hTouchInput) { 3175 if (m_pCloseTouchInputHandle == NULL) { 3176 return FALSE; 3177 } 3178 return m_pCloseTouchInputHandle(hTouchInput); 3179 } |