1 /* 2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 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 #include "awt.h" 27 28 #include <windowsx.h> 29 #include <zmouse.h> 30 31 #include "jlong.h" 32 #include "awt_AWTEvent.h" 33 #include "awt_BitmapUtil.h" 34 #include "awt_Component.h" 35 #include "awt_Cursor.h" 36 #include "awt_Dimension.h" 37 #include "awt_Frame.h" 38 #include "awt_InputEvent.h" 39 #include "awt_InputTextInfor.h" 40 #include "awt_Insets.h" 41 #include "awt_KeyEvent.h" 42 #include "awt_MenuItem.h" 43 #include "awt_MouseEvent.h" 44 #include "awt_Palette.h" 45 #include "awt_Toolkit.h" 46 #include "awt_Window.h" 47 #include "awt_Win32GraphicsDevice.h" 48 #include "Hashtable.h" 49 #include "ComCtl32Util.h" 50 51 #include <Region.h> 52 53 #include <jawt.h> 54 55 #include <java_awt_Toolkit.h> 56 #include <java_awt_FontMetrics.h> 57 #include <java_awt_Color.h> 58 #include <java_awt_Event.h> 59 #include <java_awt_event_KeyEvent.h> 60 #include <java_awt_Insets.h> 61 #include <sun_awt_windows_WPanelPeer.h> 62 #include <java_awt_event_InputEvent.h> 63 #include <java_awt_event_InputMethodEvent.h> 64 #include <sun_awt_windows_WInputMethod.h> 65 #include <java_awt_event_MouseEvent.h> 66 #include <java_awt_event_MouseWheelEvent.h> 67 68 // Begin -- Win32 SDK include files 69 #include <imm.h> 70 #include <ime.h> 71 // End -- Win32 SDK include files 72 73 #include <awt_DnDDT.h> 74 75 LPCTSTR szAwtComponentClassName = TEXT("SunAwtComponent"); 76 // register a message that no other window in the process (even in a plugin 77 // scenario) will be using 78 const UINT AwtComponent::WmAwtIsComponent = 79 ::RegisterWindowMessage(szAwtComponentClassName); 80 81 static HWND g_hwndDown = NULL; 82 static DCList activeDCList; 83 static DCList passiveDCList; 84 85 extern void CheckFontSmoothingSettings(HWND); 86 87 extern "C" { 88 // Remember the input language has changed by some user's action 89 // (Alt+Shift or through the language icon on the Taskbar) to control the 90 // race condition between the toolkit thread and the AWT event thread. 91 // This flag remains TRUE until the next WInputMethod.getNativeLocale() is 92 // issued. 93 BOOL g_bUserHasChangedInputLang = FALSE; 94 } 95 96 BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE; 97 BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE; 98 HWND AwtComponent::sm_focusOwner = NULL; 99 HWND AwtComponent::sm_focusedWindow = NULL; 100 BOOL AwtComponent::sm_bMenuLoop = FALSE; 101 BOOL AwtComponent::sm_inSynthesizeFocus = FALSE; 102 103 /************************************************************************/ 104 // Struct for _Reshape() and ReshapeNoCheck() methods 105 struct ReshapeStruct { 106 jobject component; 107 jint x, y; 108 jint w, h; 109 }; 110 // Struct for _NativeHandleEvent() method 111 struct NativeHandleEventStruct { 112 jobject component; 113 jobject event; 114 }; 115 // Struct for _SetForeground() and _SetBackground() methods 116 struct SetColorStruct { 117 jobject component; 118 jint rgb; 119 }; 120 // Struct for _SetFont() method 121 struct SetFontStruct { 122 jobject component; 123 jobject font; 124 }; 125 // Struct for _CreatePrintedPixels() method 126 struct CreatePrintedPixelsStruct { 127 jobject component; 128 int srcx, srcy; 129 int srcw, srch; 130 jint alpha; 131 }; 132 // Struct for _SetRectangularShape() method 133 struct SetRectangularShapeStruct { 134 jobject component; 135 jint x1, x2, y1, y2; 136 jobject region; 137 }; 138 // Struct for _GetInsets function 139 struct GetInsetsStruct { 140 jobject window; 141 RECT *insets; 142 }; 143 // Struct for _SetZOrder function 144 struct SetZOrderStruct { 145 jobject component; 146 jlong above; 147 }; 148 // Struct for _SetFocus function 149 struct SetFocusStruct { 150 jobject component; 151 jboolean doSetFocus; 152 }; 153 // Struct for _SetParent function 154 struct SetParentStruct { 155 jobject component; 156 jobject parentComp; 157 }; 158 /************************************************************************/ 159 160 ////////////////////////////////////////////////////////////////////////// 161 162 /************************************************************************* 163 * AwtComponent fields 164 */ 165 166 167 jfieldID AwtComponent::peerID; 168 jfieldID AwtComponent::xID; 169 jfieldID AwtComponent::yID; 170 jfieldID AwtComponent::widthID; 171 jfieldID AwtComponent::heightID; 172 jfieldID AwtComponent::visibleID; 173 jfieldID AwtComponent::backgroundID; 174 jfieldID AwtComponent::foregroundID; 175 jfieldID AwtComponent::enabledID; 176 jfieldID AwtComponent::parentID; 177 jfieldID AwtComponent::graphicsConfigID; 178 jfieldID AwtComponent::peerGCID; 179 jfieldID AwtComponent::focusableID; 180 jfieldID AwtComponent::appContextID; 181 jfieldID AwtComponent::cursorID; 182 jfieldID AwtComponent::hwndID; 183 184 jmethodID AwtComponent::getFontMID; 185 jmethodID AwtComponent::getToolkitMID; 186 jmethodID AwtComponent::isEnabledMID; 187 jmethodID AwtComponent::getLocationOnScreenMID; 188 jmethodID AwtComponent::replaceSurfaceDataMID; 189 jmethodID AwtComponent::replaceSurfaceDataLaterMID; 190 jmethodID AwtComponent::disposeLaterMID; 191 192 HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0); 193 LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0)); 194 UINT AwtComponent::m_CodePage 195 = AwtComponent::LangToCodePage(m_idLang); 196 197 jint *AwtComponent::masks; 198 199 static BOOL bLeftShiftIsDown = false; 200 static BOOL bRightShiftIsDown = false; 201 static UINT lastShiftKeyPressed = 0; // init to safe value 202 203 // Added by waleed to initialize the RTL Flags 204 BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC || 205 PRIMARYLANGID(GetInputLanguage()) == LANG_HEBREW; 206 BOOL AwtComponent::sm_rtlReadingOrder = 207 PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC; 208 209 BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE; 210 211 HWND AwtComponent::sm_cursorOn; 212 BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE; 213 214 CriticalSection windowMoveLock; 215 BOOL windowMoveLockHeld = FALSE; 216 217 /************************************************************************ 218 * AwtComponent methods 219 */ 220 221 AwtComponent::AwtComponent() 222 { 223 m_mouseButtonClickAllowed = 0; 224 m_touchDownOccurred = FALSE; 225 m_touchUpOccurred = FALSE; 226 m_touchDownPoint.x = m_touchDownPoint.y = 0; 227 m_touchUpPoint.x = m_touchUpPoint.y = 0; 228 m_callbacksEnabled = FALSE; 229 m_hwnd = NULL; 230 231 m_colorForeground = 0; 232 m_colorBackground = 0; 233 m_backgroundColorSet = FALSE; 234 m_penForeground = NULL; 235 m_brushBackground = NULL; 236 m_DefWindowProc = NULL; 237 m_nextControlID = 1; 238 m_childList = NULL; 239 m_myControlID = 0; 240 m_hdwp = NULL; 241 m_validationNestCount = 0; 242 243 m_dropTarget = NULL; 244 245 m_InputMethod = NULL; 246 m_useNativeCompWindow = TRUE; 247 m_PendingLeadByte = 0; 248 m_bitsCandType = 0; 249 250 windowMoveLockPosX = 0; 251 windowMoveLockPosY = 0; 252 windowMoveLockPosCX = 0; 253 windowMoveLockPosCY = 0; 254 255 m_hCursorCache = NULL; 256 257 m_bSubclassed = FALSE; 258 m_bPauseDestroy = FALSE; 259 260 m_MessagesProcessing = 0; 261 m_wheelRotationAmount = 0; 262 if (!sm_PrimaryDynamicTableBuilt) { 263 // do it once. 264 AwtComponent::BuildPrimaryDynamicTable(); 265 sm_PrimaryDynamicTableBuilt = TRUE; 266 } 267 268 deadKeyActive = FALSE; 269 } 270 271 AwtComponent::~AwtComponent() 272 { 273 DASSERT(AwtToolkit::IsMainThread()); 274 275 /* 276 * All the messages for this component are processed, native 277 * resources are freed, and Java object is not connected to 278 * the native one anymore. So we can safely destroy component's 279 * handle. 280 */ 281 DestroyHWnd(); 282 } 283 284 void AwtComponent::Dispose() 285 { 286 DASSERT(AwtToolkit::IsMainThread()); 287 288 // NOTE: in case the component/toplevel was focused, Java should 289 // have already taken care of proper transferring it or clearing. 290 291 if (m_hdwp != NULL) { 292 // end any deferred window positioning, regardless 293 // of m_validationNestCount 294 ::EndDeferWindowPos(m_hdwp); 295 } 296 297 // Send final message to release all DCs associated with this component 298 SendMessage(WM_AWT_RELEASE_ALL_DCS); 299 300 /* Stop message filtering. */ 301 UnsubclassHWND(); 302 303 /* Release global ref to input method */ 304 SetInputMethod(NULL, TRUE); 305 306 if (m_childList != NULL) { 307 delete m_childList; 308 m_childList = NULL; 309 } 310 311 DestroyDropTarget(); 312 ReleaseDragCapture(0); 313 314 if (m_myControlID != 0) { 315 AwtComponent* parent = GetParent(); 316 if (parent != NULL) 317 parent->RemoveChild(m_myControlID); 318 } 319 320 ::RemoveProp(GetHWnd(), DrawingStateProp); 321 322 /* Release any allocated resources. */ 323 if (m_penForeground != NULL) { 324 m_penForeground->Release(); 325 m_penForeground = NULL; 326 } 327 if (m_brushBackground != NULL) { 328 m_brushBackground->Release(); 329 m_brushBackground = NULL; 330 } 331 332 /* Disconnect all links. */ 333 UnlinkObjects(); 334 335 if (m_bPauseDestroy) { 336 // AwtComponent::WmNcDestroy could be released now 337 m_bPauseDestroy = FALSE; 338 m_hwnd = NULL; 339 } 340 341 // The component instance is deleted using AwtObject::Dispose() method 342 AwtObject::Dispose(); 343 } 344 345 /* store component pointer in window extra bytes */ 346 void AwtComponent::SetComponentInHWND() { 347 DASSERT(::GetWindowLongPtr(GetHWnd(), GWLP_USERDATA) == NULL); 348 ::SetWindowLongPtr(GetHWnd(), GWLP_USERDATA, (LONG_PTR)this); 349 } 350 351 /* 352 * static function to get AwtComponent pointer from hWnd -- 353 * you don't want to call this from inside a wndproc to avoid 354 * infinite recursion 355 */ 356 AwtComponent* AwtComponent::GetComponent(HWND hWnd) { 357 // Requests for Toolkit hwnd resolution happen pretty often. Check first. 358 if (hWnd == AwtToolkit::GetInstance().GetHWnd()) { 359 return NULL; 360 } 361 362 // check that it's an AWT component from the same toolkit as the caller 363 if (::IsWindow(hWnd) && 364 AwtToolkit::MainThread() == ::GetWindowThreadProcessId(hWnd, NULL)) 365 { 366 DASSERT(WmAwtIsComponent != 0); 367 if (::SendMessage(hWnd, WmAwtIsComponent, 0, 0L)) { 368 return GetComponentImpl(hWnd); 369 } 370 } 371 return NULL; 372 } 373 374 /* 375 * static function to get AwtComponent pointer from hWnd-- 376 * different from GetComponent because caller knows the 377 * hwnd is an AWT component hwnd 378 */ 379 AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) { 380 AwtComponent *component = 381 (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA); 382 DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) ); 383 DASSERT(!component || component->GetHWnd() == hWnd ); 384 return component; 385 } 386 387 /* 388 * Single window proc for all the components. Delegates real work to 389 * the component's WindowProc() member function. 390 */ 391 LRESULT CALLBACK AwtComponent::WndProc(HWND hWnd, UINT message, 392 WPARAM wParam, LPARAM lParam) 393 { 394 TRY; 395 396 AwtComponent * self = AwtComponent::GetComponentImpl(hWnd); 397 if (self == NULL || self->GetHWnd() != hWnd || 398 message == WM_UNDOCUMENTED_CLIENTSHUTDOWN) // handle log-off gracefully 399 { 400 return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam); 401 } else { 402 return self->WindowProc(message, wParam, lParam); 403 } 404 405 CATCH_BAD_ALLOC_RET(0); 406 } 407 408 BOOL AwtComponent::IsFocusable() { 409 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 410 jobject peer = GetPeer(env); 411 jobject target = env->GetObjectField(peer, AwtObject::targetID); 412 BOOL res = env->GetBooleanField(target, focusableID); 413 AwtWindow *pCont = GetContainer(); 414 if (pCont) { 415 res &= pCont->IsFocusableWindow(); 416 } 417 env->DeleteLocalRef(target); 418 return res; 419 } 420 421 /************************************************************************ 422 * AwtComponent dynamic methods 423 * 424 * Window class registration routines 425 */ 426 427 /* 428 * Fix for 4964237: Win XP: Changing theme changes java dialogs title icon 429 */ 430 void AwtComponent::FillClassInfo(WNDCLASSEX *lpwc) 431 { 432 lpwc->cbSize = sizeof(WNDCLASSEX); 433 lpwc->style = 0L;//CS_OWNDC; 434 lpwc->lpfnWndProc = (WNDPROC)::DefWindowProc; 435 lpwc->cbClsExtra = 0; 436 lpwc->cbWndExtra = 0; 437 lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(), 438 lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon(); 439 lpwc->hCursor = NULL; 440 lpwc->hbrBackground = NULL; 441 lpwc->lpszMenuName = NULL; 442 lpwc->lpszClassName = GetClassName(); 443 //Fixed 6233560: PIT: Java Cup Logo on the title bar of top-level windows look blurred, Win32 444 lpwc->hIconSm = AwtToolkit::GetInstance().GetAwtIconSm(); 445 } 446 447 void AwtComponent::RegisterClass() 448 { 449 WNDCLASSEX wc; 450 if (!::GetClassInfoEx(AwtToolkit::GetInstance().GetModuleHandle(), GetClassName(), &wc)) { 451 FillClassInfo(&wc); 452 ATOM ret = ::RegisterClassEx(&wc); 453 DASSERT(ret != 0); 454 } 455 } 456 457 void AwtComponent::UnregisterClass() 458 { 459 ::UnregisterClass(GetClassName(), AwtToolkit::GetInstance().GetModuleHandle()); 460 } 461 462 /* 463 * Copy the graphicsConfig reference from Component into WComponentPeer 464 */ 465 void AwtComponent::InitPeerGraphicsConfig(JNIEnv *env, jobject peer) 466 { 467 jobject target = env->GetObjectField(peer, AwtObject::targetID); 468 //Get graphicsConfig object ref from Component 469 jobject compGC = env->GetObjectField(target, 470 AwtComponent::graphicsConfigID); 471 472 //Set peer's graphicsConfig to Component's graphicsConfig 473 if (compGC != NULL) { 474 jclass win32GCCls = env->FindClass("sun/awt/Win32GraphicsConfig"); 475 DASSERT(win32GCCls != NULL); 476 DASSERT(env->IsInstanceOf(compGC, win32GCCls)); 477 if (win32GCCls == NULL) { 478 throw std::bad_alloc(); 479 } 480 env->SetObjectField(peer, AwtComponent::peerGCID, compGC); 481 } 482 } 483 484 void 485 AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, 486 DWORD windowStyle, 487 DWORD windowExStyle, 488 int x, int y, int w, int h, 489 HWND hWndParent, HMENU hMenu, 490 COLORREF colorForeground, 491 COLORREF colorBackground, 492 jobject peer) 493 { 494 if (env->EnsureLocalCapacity(2) < 0) { 495 return; 496 } 497 498 /* 499 * The window class of multifont label must be "BUTTON" because 500 * "STATIC" class can't get WM_DRAWITEM message, and m_peerObject 501 * member is referred in the GetClassName method of AwtLabel class. 502 * So m_peerObject member must be set here. 503 */ 504 if (m_peerObject == NULL) { 505 m_peerObject = env->NewGlobalRef(peer); 506 } else { 507 assert(env->IsSameObject(m_peerObject, peer)); 508 } 509 510 RegisterClass(); 511 512 jobject target = env->GetObjectField(peer, AwtObject::targetID); 513 jboolean visible = env->GetBooleanField(target, AwtComponent::visibleID); 514 m_visible = visible; 515 516 if (visible) { 517 windowStyle |= WS_VISIBLE; 518 } else { 519 windowStyle &= ~WS_VISIBLE; 520 } 521 522 InitPeerGraphicsConfig(env, peer); 523 524 SetLastError(0); 525 HWND hwnd = ::CreateWindowEx(windowExStyle, 526 GetClassName(), 527 title, 528 windowStyle, 529 x, y, w, h, 530 hWndParent, 531 hMenu, 532 AwtToolkit::GetInstance().GetModuleHandle(), 533 NULL); 534 535 // fix for 5088782 536 // check if CreateWindowsEx() returns not null value and if it does - 537 // create an InternalError or OutOfMemoryError based on GetLastError(). 538 // This error is set to createError field of WObjectPeer and then 539 // checked and thrown in WComponentPeer constructor. We can't throw an 540 // error here because this code is invoked on Toolkit thread 541 if (hwnd == NULL) 542 { 543 DWORD dw = ::GetLastError(); 544 jobject createError = NULL; 545 if (dw == ERROR_OUTOFMEMORY) 546 { 547 jstring errorMsg = JNU_NewStringPlatform(env, L"too many window handles"); 548 if (errorMsg == NULL || env->ExceptionCheck()) { 549 env->ExceptionClear(); 550 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", "()V"); 551 } else { 552 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", 553 "(Ljava/lang/String;)V", 554 errorMsg); 555 env->DeleteLocalRef(errorMsg); 556 } 557 } 558 else 559 { 560 TCHAR *buf; 561 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 562 NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 563 (LPTSTR)&buf, 0, NULL); 564 jstring s = JNU_NewStringPlatform(env, buf); 565 if (s == NULL || env->ExceptionCheck()) { 566 env->ExceptionClear(); 567 createError = JNU_NewObjectByName(env, "java/lang/InternalError", "()V"); 568 } else { 569 createError = JNU_NewObjectByName(env, "java/lang/InternalError", 570 "(Ljava/lang/String;)V", s); 571 env->DeleteLocalRef(s); 572 } 573 LocalFree(buf); 574 } 575 if (createError != NULL) { 576 env->SetObjectField(peer, AwtObject::createErrorID, createError); 577 env->DeleteLocalRef(createError); 578 } 579 env->DeleteLocalRef(target); 580 return; 581 } 582 583 m_hwnd = hwnd; 584 585 ::ImmAssociateContext(m_hwnd, NULL); 586 587 SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | 588 (jint)JAWT_LOCK_BOUNDS_CHANGED | 589 (jint)JAWT_LOCK_CLIP_CHANGED); 590 591 LinkObjects(env, peer); 592 593 /* Subclass the window now so that we can snoop on its messages */ 594 SubclassHWND(); 595 596 AwtToolkit& tk = AwtToolkit::GetInstance(); 597 if (tk.IsWin8OrLater() && tk.IsTouchKeyboardAutoShowEnabled()) { 598 tk.TIRegisterTouchWindow(GetHWnd(), TWF_WANTPALM); 599 } 600 601 /* 602 * Fix for 4046446. 603 */ 604 SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE); 605 606 /* Set default colors. */ 607 m_colorForeground = colorForeground; 608 m_colorBackground = colorBackground; 609 610 /* 611 * Only set background color if the color is actually set on the 612 * target -- this avoids inheriting a parent's color unnecessarily, 613 * and has to be done here because there isn't an API to get the 614 * real background color from outside the AWT package. 615 */ 616 jobject bkgrd = env->GetObjectField(target, AwtComponent::backgroundID) ; 617 if (bkgrd != NULL) { 618 JNU_CallMethodByName(env, NULL, peer, "setBackground", 619 "(Ljava/awt/Color;)V", bkgrd); 620 DASSERT(!safe_ExceptionOccurred(env)); 621 } 622 env->DeleteLocalRef(target); 623 env->DeleteLocalRef(bkgrd); 624 } 625 626 /* 627 * Destroy this window's HWND 628 */ 629 void AwtComponent::DestroyHWnd() { 630 if (m_hwnd != NULL) { 631 AwtToolkit::DestroyComponentHWND(m_hwnd); 632 //AwtToolkit::DestroyComponent(this); 633 m_hwnd = NULL; 634 } 635 } 636 637 /* 638 * Returns hwnd for target on non Toolkit thread 639 */ 640 HWND 641 AwtComponent::GetHWnd(JNIEnv* env, jobject target) { 642 if (JNU_IsNull(env, target)) { 643 return 0; 644 } 645 jobject peer = env->GetObjectField(target, AwtComponent::peerID); 646 if (JNU_IsNull(env, peer)) { 647 return 0; 648 } 649 HWND hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR> ( 650 env->GetLongField(peer, AwtComponent::hwndID))); 651 env->DeleteLocalRef(peer); 652 return hwnd; 653 } 654 // 655 // Propagate the background color to synchronize Java field and peer's field. 656 // This is needed to fix 4148334 657 // 658 void AwtComponent::UpdateBackground(JNIEnv *env, jobject target) 659 { 660 if (env->EnsureLocalCapacity(1) < 0) { 661 return; 662 } 663 664 jobject bkgrnd = env->GetObjectField(target, AwtComponent::backgroundID); 665 666 if (bkgrnd == NULL) { 667 bkgrnd = JNU_NewObjectByName(env, "java/awt/Color", "(III)V", 668 GetRValue(m_colorBackground), 669 GetGValue(m_colorBackground), 670 GetBValue(m_colorBackground)); 671 if (bkgrnd != NULL) { 672 env->SetObjectField(target, AwtComponent::backgroundID, bkgrnd); 673 } 674 } 675 env->DeleteLocalRef(bkgrnd); 676 } 677 678 /* 679 * Install our window proc as the proc for our HWND, and save off the 680 * previous proc as the default 681 */ 682 void AwtComponent::SubclassHWND() 683 { 684 if (m_bSubclassed) { 685 return; 686 } 687 const WNDPROC wndproc = WndProc; // let compiler type check WndProc 688 m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc); 689 m_bSubclassed = TRUE; 690 } 691 692 /* 693 * Reinstall the original window proc as the proc for our HWND 694 */ 695 void AwtComponent::UnsubclassHWND() 696 { 697 if (!m_bSubclassed) { 698 return; 699 } 700 ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc); 701 m_bSubclassed = FALSE; 702 } 703 704 ///////////////////////////////////// 705 // (static method) 706 // Determines the top-level ancestor for a given window. If the given 707 // window is a top-level window, return itself. 708 // 709 // 'Top-level' includes dialogs as well. 710 // 711 HWND AwtComponent::GetTopLevelParentForWindow(HWND hwndDescendant) { 712 if (hwndDescendant == NULL) { 713 return NULL; 714 } 715 716 DASSERT(IsWindow(hwndDescendant)); 717 HWND hwnd = hwndDescendant; 718 for(;;) { 719 DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); 720 // a) found a non-child window so terminate 721 // b) found real toplevel window (e.g. EmbeddedFrame 722 // that is child though) 723 if ( (style & WS_CHILD) == 0 || 724 AwtComponent::IsTopLevelHWnd(hwnd) ) 725 { 726 break; 727 } 728 hwnd = ::GetParent(hwnd); 729 } 730 731 return hwnd; 732 } 733 //////////////////// 734 735 jobject AwtComponent::FindHeavyweightUnderCursor(BOOL useCache) { 736 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 737 if (env->EnsureLocalCapacity(1) < 0) { 738 return NULL; 739 } 740 741 HWND hit = NULL; 742 POINT p = { 0, 0 }; 743 AwtComponent *comp = NULL; 744 745 if (useCache) { 746 if (sm_cursorOn == NULL) { 747 return NULL; 748 } 749 750 751 DASSERT(::IsWindow(sm_cursorOn)); 752 VERIFY(::GetCursorPos(&p)); 753 /* 754 * Fix for BugTraq ID 4304024. 755 * Allow a non-default cursor only for the client area. 756 */ 757 comp = AwtComponent::GetComponent(sm_cursorOn); 758 if (comp != NULL && 759 ::SendMessage(sm_cursorOn, WM_NCHITTEST, 0, 760 MAKELPARAM(p.x, p.y)) == HTCLIENT) { 761 goto found; 762 } 763 } 764 765 ::GetCursorPos(&p); 766 hit = ::WindowFromPoint(p); 767 while (hit != NULL) { 768 comp = AwtComponent::GetComponent(hit); 769 770 if (comp != NULL) { 771 INT nHittest = (INT)::SendMessage(hit, WM_NCHITTEST, 772 0, MAKELPARAM(p.x, p.y)); 773 /* 774 * Fix for BugTraq ID 4304024. 775 * Allow a non-default cursor only for the client area. 776 */ 777 if (nHittest != HTCLIENT) { 778 /* 779 * When over the non-client area, send WM_SETCURSOR 780 * to revert the cursor to an arrow. 781 */ 782 ::SendMessage(hit, WM_SETCURSOR, (WPARAM)hit, 783 MAKELPARAM(nHittest, WM_MOUSEMOVE)); 784 return NULL; 785 } else { 786 sm_cursorOn = hit; 787 goto found; 788 } 789 } 790 791 if ((::GetWindowLong(hit, GWL_STYLE) & WS_CHILD) == 0) { 792 return NULL; 793 } 794 hit = ::GetParent(hit); 795 } 796 797 return NULL; 798 799 found: 800 jobject localRef = comp->GetTarget(env); 801 jobject globalRef = env->NewGlobalRef(localRef); 802 env->DeleteLocalRef(localRef); 803 return globalRef; 804 } 805 806 void AwtComponent::SetColor(COLORREF c) 807 { 808 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 809 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 810 if (grayscale != GS_NOTGRAY) { 811 int g; 812 813 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 814 .114 * ((c >> 16) & 0xFF) + 0.5); 815 // c = g | (g << 8) | (g << 16); 816 c = PALETTERGB(g, g, g); 817 } 818 819 if (m_colorForeground == c) { 820 return; 821 } 822 823 m_colorForeground = c; 824 if (m_penForeground != NULL) { 825 m_penForeground->Release(); 826 m_penForeground = NULL; 827 } 828 VERIFY(::InvalidateRect(GetHWnd(), NULL, FALSE)); 829 } 830 831 void AwtComponent::SetBackgroundColor(COLORREF c) 832 { 833 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 834 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 835 if (grayscale != GS_NOTGRAY) { 836 int g; 837 838 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 839 .114 * ((c >> 16) & 0xFF) + 0.5); 840 // c = g | (g << 8) | (g << 16); 841 c = PALETTERGB(g, g, g); 842 } 843 844 if (m_colorBackground == c) { 845 return; 846 } 847 m_colorBackground = c; 848 m_backgroundColorSet = TRUE; 849 if (m_brushBackground != NULL) { 850 m_brushBackground->Release(); 851 m_brushBackground = NULL; 852 } 853 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 854 } 855 856 HPEN AwtComponent::GetForegroundPen() 857 { 858 if (m_penForeground == NULL) { 859 m_penForeground = AwtPen::Get(m_colorForeground); 860 } 861 return (HPEN)m_penForeground->GetHandle(); 862 } 863 864 COLORREF AwtComponent::GetBackgroundColor() 865 { 866 if (m_backgroundColorSet == FALSE) { 867 AwtComponent* c = this; 868 while ((c = c->GetParent()) != NULL) { 869 if (c->IsBackgroundColorSet()) { 870 return c->GetBackgroundColor(); 871 } 872 } 873 } 874 return m_colorBackground; 875 } 876 877 HBRUSH AwtComponent::GetBackgroundBrush() 878 { 879 if (m_backgroundColorSet == FALSE) { 880 if (m_brushBackground != NULL) { 881 m_brushBackground->Release(); 882 m_brushBackground = NULL; 883 } 884 AwtComponent* c = this; 885 while ((c = c->GetParent()) != NULL) { 886 if (c->IsBackgroundColorSet()) { 887 m_brushBackground = 888 AwtBrush::Get(c->GetBackgroundColor()); 889 break; 890 } 891 } 892 } 893 if (m_brushBackground == NULL) { 894 m_brushBackground = AwtBrush::Get(m_colorBackground); 895 } 896 return (HBRUSH)m_brushBackground->GetHandle(); 897 } 898 899 void AwtComponent::SetFont(AwtFont* font) 900 { 901 DASSERT(font != NULL); 902 if (font->GetAscent() < 0) { 903 AwtFont::SetupAscent(font); 904 } 905 SendMessage(WM_SETFONT, (WPARAM)font->GetHFont(), MAKELPARAM(FALSE, 0)); 906 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 907 } 908 909 AwtComponent* AwtComponent::GetParent() 910 { 911 HWND hwnd = ::GetParent(GetHWnd()); 912 if (hwnd == NULL) { 913 return NULL; 914 } 915 return GetComponent(hwnd); 916 } 917 918 AwtWindow* AwtComponent::GetContainer() 919 { 920 AwtComponent* comp = this; 921 while (comp != NULL) { 922 if (comp->IsContainer()) { 923 return (AwtWindow*)comp; 924 } 925 comp = comp->GetParent(); 926 } 927 return NULL; 928 } 929 930 void AwtComponent::Show() 931 { 932 m_visible = true; 933 ::ShowWindow(GetHWnd(), SW_SHOWNA); 934 } 935 936 void AwtComponent::Hide() 937 { 938 m_visible = false; 939 ::ShowWindow(GetHWnd(), SW_HIDE); 940 } 941 942 BOOL 943 AwtComponent::SetWindowPos(HWND wnd, HWND after, 944 int x, int y, int w, int h, UINT flags) 945 { 946 // Conditions we shouldn't handle: 947 // z-order changes, correct window dimensions 948 if (after != NULL || (w < 32767 && h < 32767) 949 || ((::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) == 0)) 950 { 951 return ::SetWindowPos(wnd, after, x, y, w, h, flags); 952 } 953 WINDOWPLACEMENT wp; 954 ::ZeroMemory(&wp, sizeof(wp)); 955 956 wp.length = sizeof(wp); 957 ::GetWindowPlacement(wnd, &wp); 958 wp.rcNormalPosition.left = x; 959 wp.rcNormalPosition.top = y; 960 wp.rcNormalPosition.right = x + w; 961 wp.rcNormalPosition.bottom = y + h; 962 if ( flags & SWP_NOACTIVATE ) { 963 wp.showCmd = SW_SHOWNOACTIVATE; 964 } 965 ::SetWindowPlacement(wnd, &wp); 966 return 1; 967 } 968 969 970 void AwtComponent::Reshape(int x, int y, int w, int h) 971 { 972 #if defined(DEBUG) 973 RECT rc; 974 ::GetWindowRect(GetHWnd(), &rc); 975 ::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2); 976 DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); 977 #endif 978 AwtWindow* container = GetContainer(); 979 AwtComponent* parent = GetParent(); 980 if (container != NULL && container == parent) { 981 container->SubtractInsetPoint(x, y); 982 } 983 DTRACE_PRINTLN4("AwtComponent::Reshape to %d, %d, %d, %d", x, y, w, h); 984 UINT flags = SWP_NOACTIVATE | SWP_NOZORDER; 985 986 RECT r; 987 988 ::GetWindowRect(GetHWnd(), &r); 989 // if the component size is changing , don't copy window bits 990 if (r.right - r.left != w || r.bottom - r.top != h) { 991 flags |= SWP_NOCOPYBITS; 992 } 993 994 if (parent && _tcscmp(parent->GetClassName(), TEXT("SunAwtScrollPane")) == 0) { 995 if (x > 0) { 996 x = 0; 997 } 998 if (y > 0) { 999 y = 0; 1000 } 1001 } 1002 if (m_hdwp != NULL) { 1003 m_hdwp = ::DeferWindowPos(m_hdwp, GetHWnd(), 0, x, y, w, h, flags); 1004 DASSERT(m_hdwp != NULL); 1005 } else { 1006 /* 1007 * Fox for 4046446 1008 * If window has dimensions above the short int limit, ::SetWindowPos doesn't work. 1009 * We should use SetWindowPlacement instead. 1010 */ 1011 SetWindowPos(GetHWnd(), 0, x, y, w, h, flags); 1012 } 1013 } 1014 1015 void AwtComponent::SetScrollValues(UINT bar, int min, int value, int max) 1016 { 1017 int minTmp, maxTmp; 1018 1019 ::GetScrollRange(GetHWnd(), bar, &minTmp, &maxTmp); 1020 if (min == INT_MAX) { 1021 min = minTmp; 1022 } 1023 if (value == INT_MAX) { 1024 value = ::GetScrollPos(GetHWnd(), bar); 1025 } 1026 if (max == INT_MAX) { 1027 max = maxTmp; 1028 } 1029 if (min == max) { 1030 max++; 1031 } 1032 ::SetScrollRange(GetHWnd(), bar, min, max, FALSE); 1033 ::SetScrollPos(GetHWnd(), bar, value, TRUE); 1034 } 1035 1036 /* 1037 * Save Global Reference of sun.awt.windows.WInputMethod object 1038 */ 1039 void AwtComponent::SetInputMethod(jobject im, BOOL useNativeCompWindow) 1040 { 1041 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1042 1043 if (m_InputMethod!=NULL) 1044 env->DeleteGlobalRef(m_InputMethod); 1045 1046 if (im!=NULL){ 1047 m_InputMethod = env->NewGlobalRef(im); 1048 m_useNativeCompWindow = useNativeCompWindow; 1049 } else { 1050 m_InputMethod = NULL; 1051 m_useNativeCompWindow = TRUE; 1052 } 1053 1054 } 1055 1056 /* 1057 * Opportunity to process and/or eat a message before it is dispatched 1058 */ 1059 MsgRouting AwtComponent::PreProcessMsg(MSG& msg) 1060 { 1061 return mrPassAlong; 1062 } 1063 1064 static UINT lastMessage = WM_NULL; 1065 1066 #ifndef SPY_MESSAGES 1067 #define SpyWinMessage(hwin,msg,str) 1068 #else 1069 1070 #define FMT_MSG(x,y) case x: _stprintf(szBuf, \ 1071 "0x%8.8x(%s):%s\n", hwnd, szComment, y); break; 1072 #define WIN_MSG(x) FMT_MSG(x,#x) 1073 1074 void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { 1075 1076 TCHAR szBuf[256]; 1077 1078 switch (message) { 1079 WIN_MSG(WM_NULL) 1080 WIN_MSG(WM_CREATE) 1081 WIN_MSG(WM_DESTROY) 1082 WIN_MSG(WM_MOVE) 1083 WIN_MSG(WM_SIZE) 1084 WIN_MSG(WM_ACTIVATE) 1085 WIN_MSG(WM_SETFOCUS) 1086 WIN_MSG(WM_KILLFOCUS) 1087 WIN_MSG(WM_ENABLE) 1088 WIN_MSG(WM_SETREDRAW) 1089 WIN_MSG(WM_SETTEXT) 1090 WIN_MSG(WM_GETTEXT) 1091 WIN_MSG(WM_GETTEXTLENGTH) 1092 WIN_MSG(WM_PAINT) 1093 WIN_MSG(WM_CLOSE) 1094 WIN_MSG(WM_QUERYENDSESSION) 1095 WIN_MSG(WM_QUIT) 1096 WIN_MSG(WM_QUERYOPEN) 1097 WIN_MSG(WM_ERASEBKGND) 1098 WIN_MSG(WM_SYSCOLORCHANGE) 1099 WIN_MSG(WM_ENDSESSION) 1100 WIN_MSG(WM_SHOWWINDOW) 1101 FMT_MSG(WM_WININICHANGE,"WM_WININICHANGE/WM_SETTINGCHANGE") 1102 WIN_MSG(WM_DEVMODECHANGE) 1103 WIN_MSG(WM_ACTIVATEAPP) 1104 WIN_MSG(WM_FONTCHANGE) 1105 WIN_MSG(WM_TIMECHANGE) 1106 WIN_MSG(WM_CANCELMODE) 1107 WIN_MSG(WM_SETCURSOR) 1108 WIN_MSG(WM_MOUSEACTIVATE) 1109 WIN_MSG(WM_CHILDACTIVATE) 1110 WIN_MSG(WM_QUEUESYNC) 1111 WIN_MSG(WM_GETMINMAXINFO) 1112 WIN_MSG(WM_PAINTICON) 1113 WIN_MSG(WM_ICONERASEBKGND) 1114 WIN_MSG(WM_NEXTDLGCTL) 1115 WIN_MSG(WM_SPOOLERSTATUS) 1116 WIN_MSG(WM_DRAWITEM) 1117 WIN_MSG(WM_MEASUREITEM) 1118 WIN_MSG(WM_DELETEITEM) 1119 WIN_MSG(WM_VKEYTOITEM) 1120 WIN_MSG(WM_CHARTOITEM) 1121 WIN_MSG(WM_SETFONT) 1122 WIN_MSG(WM_GETFONT) 1123 WIN_MSG(WM_SETHOTKEY) 1124 WIN_MSG(WM_GETHOTKEY) 1125 WIN_MSG(WM_QUERYDRAGICON) 1126 WIN_MSG(WM_COMPAREITEM) 1127 FMT_MSG(0x003D, "WM_GETOBJECT") 1128 WIN_MSG(WM_COMPACTING) 1129 WIN_MSG(WM_COMMNOTIFY) 1130 WIN_MSG(WM_WINDOWPOSCHANGING) 1131 WIN_MSG(WM_WINDOWPOSCHANGED) 1132 WIN_MSG(WM_POWER) 1133 WIN_MSG(WM_COPYDATA) 1134 WIN_MSG(WM_CANCELJOURNAL) 1135 WIN_MSG(WM_NOTIFY) 1136 WIN_MSG(WM_INPUTLANGCHANGEREQUEST) 1137 WIN_MSG(WM_INPUTLANGCHANGE) 1138 WIN_MSG(WM_TCARD) 1139 WIN_MSG(WM_HELP) 1140 WIN_MSG(WM_USERCHANGED) 1141 WIN_MSG(WM_NOTIFYFORMAT) 1142 WIN_MSG(WM_CONTEXTMENU) 1143 WIN_MSG(WM_STYLECHANGING) 1144 WIN_MSG(WM_STYLECHANGED) 1145 WIN_MSG(WM_DISPLAYCHANGE) 1146 WIN_MSG(WM_GETICON) 1147 WIN_MSG(WM_SETICON) 1148 WIN_MSG(WM_NCCREATE) 1149 WIN_MSG(WM_NCDESTROY) 1150 WIN_MSG(WM_NCCALCSIZE) 1151 WIN_MSG(WM_NCHITTEST) 1152 WIN_MSG(WM_NCPAINT) 1153 WIN_MSG(WM_NCACTIVATE) 1154 WIN_MSG(WM_GETDLGCODE) 1155 WIN_MSG(WM_SYNCPAINT) 1156 WIN_MSG(WM_NCMOUSEMOVE) 1157 WIN_MSG(WM_NCLBUTTONDOWN) 1158 WIN_MSG(WM_NCLBUTTONUP) 1159 WIN_MSG(WM_NCLBUTTONDBLCLK) 1160 WIN_MSG(WM_NCRBUTTONDOWN) 1161 WIN_MSG(WM_NCRBUTTONUP) 1162 WIN_MSG(WM_NCRBUTTONDBLCLK) 1163 WIN_MSG(WM_NCMBUTTONDOWN) 1164 WIN_MSG(WM_NCMBUTTONUP) 1165 WIN_MSG(WM_NCMBUTTONDBLCLK) 1166 WIN_MSG(WM_KEYDOWN) 1167 WIN_MSG(WM_KEYUP) 1168 WIN_MSG(WM_CHAR) 1169 WIN_MSG(WM_DEADCHAR) 1170 WIN_MSG(WM_SYSKEYDOWN) 1171 WIN_MSG(WM_SYSKEYUP) 1172 WIN_MSG(WM_SYSCHAR) 1173 WIN_MSG(WM_SYSDEADCHAR) 1174 WIN_MSG(WM_IME_STARTCOMPOSITION) 1175 WIN_MSG(WM_IME_ENDCOMPOSITION) 1176 WIN_MSG(WM_IME_COMPOSITION) 1177 WIN_MSG(WM_INITDIALOG) 1178 WIN_MSG(WM_COMMAND) 1179 WIN_MSG(WM_SYSCOMMAND) 1180 WIN_MSG(WM_TIMER) 1181 WIN_MSG(WM_HSCROLL) 1182 WIN_MSG(WM_VSCROLL) 1183 WIN_MSG(WM_INITMENU) 1184 WIN_MSG(WM_INITMENUPOPUP) 1185 WIN_MSG(WM_MENUSELECT) 1186 WIN_MSG(WM_MENUCHAR) 1187 WIN_MSG(WM_ENTERIDLE) 1188 FMT_MSG(0x0122, "WM_MENURBUTTONUP") 1189 FMT_MSG(0x0123, "WM_MENUDRAG") 1190 FMT_MSG(0x0124, "WM_MENUGETOBJECT") 1191 FMT_MSG(0x0125, "WM_UNINITMENUPOPUP") 1192 FMT_MSG(0x0126, "WM_MENUCOMMAND") 1193 WIN_MSG(WM_CTLCOLORMSGBOX) 1194 WIN_MSG(WM_CTLCOLOREDIT) 1195 WIN_MSG(WM_CTLCOLORLISTBOX) 1196 WIN_MSG(WM_CTLCOLORBTN) 1197 WIN_MSG(WM_CTLCOLORDLG) 1198 WIN_MSG(WM_CTLCOLORSCROLLBAR) 1199 WIN_MSG(WM_CTLCOLORSTATIC) 1200 WIN_MSG(WM_MOUSEMOVE) 1201 WIN_MSG(WM_LBUTTONDOWN) 1202 WIN_MSG(WM_LBUTTONUP) 1203 WIN_MSG(WM_LBUTTONDBLCLK) 1204 WIN_MSG(WM_RBUTTONDOWN) 1205 WIN_MSG(WM_RBUTTONUP) 1206 WIN_MSG(WM_RBUTTONDBLCLK) 1207 WIN_MSG(WM_MBUTTONDOWN) 1208 WIN_MSG(WM_MBUTTONUP) 1209 WIN_MSG(WM_MBUTTONDBLCLK) 1210 WIN_MSG(WM_XBUTTONDBLCLK) 1211 WIN_MSG(WM_XBUTTONDOWN) 1212 WIN_MSG(WM_XBUTTONUP) 1213 WIN_MSG(WM_MOUSEWHEEL) 1214 WIN_MSG(WM_PARENTNOTIFY) 1215 WIN_MSG(WM_ENTERMENULOOP) 1216 WIN_MSG(WM_EXITMENULOOP) 1217 WIN_MSG(WM_NEXTMENU) 1218 WIN_MSG(WM_SIZING) 1219 WIN_MSG(WM_CAPTURECHANGED) 1220 WIN_MSG(WM_MOVING) 1221 WIN_MSG(WM_POWERBROADCAST) 1222 WIN_MSG(WM_DEVICECHANGE) 1223 WIN_MSG(WM_MDICREATE) 1224 WIN_MSG(WM_MDIDESTROY) 1225 WIN_MSG(WM_MDIACTIVATE) 1226 WIN_MSG(WM_MDIRESTORE) 1227 WIN_MSG(WM_MDINEXT) 1228 WIN_MSG(WM_MDIMAXIMIZE) 1229 WIN_MSG(WM_MDITILE) 1230 WIN_MSG(WM_MDICASCADE) 1231 WIN_MSG(WM_MDIICONARRANGE) 1232 WIN_MSG(WM_MDIGETACTIVE) 1233 WIN_MSG(WM_MDISETMENU) 1234 WIN_MSG(WM_ENTERSIZEMOVE) 1235 WIN_MSG(WM_EXITSIZEMOVE) 1236 WIN_MSG(WM_DROPFILES) 1237 WIN_MSG(WM_MDIREFRESHMENU) 1238 WIN_MSG(WM_IME_SETCONTEXT) 1239 WIN_MSG(WM_IME_NOTIFY) 1240 WIN_MSG(WM_IME_CONTROL) 1241 WIN_MSG(WM_IME_COMPOSITIONFULL) 1242 WIN_MSG(WM_IME_SELECT) 1243 WIN_MSG(WM_IME_CHAR) 1244 FMT_MSG(WM_IME_REQUEST) 1245 WIN_MSG(WM_IME_KEYDOWN) 1246 WIN_MSG(WM_IME_KEYUP) 1247 FMT_MSG(0x02A1, "WM_MOUSEHOVER") 1248 FMT_MSG(0x02A3, "WM_MOUSELEAVE") 1249 WIN_MSG(WM_CUT) 1250 WIN_MSG(WM_COPY) 1251 WIN_MSG(WM_PASTE) 1252 WIN_MSG(WM_CLEAR) 1253 WIN_MSG(WM_UNDO) 1254 WIN_MSG(WM_RENDERFORMAT) 1255 WIN_MSG(WM_RENDERALLFORMATS) 1256 WIN_MSG(WM_DESTROYCLIPBOARD) 1257 WIN_MSG(WM_DRAWCLIPBOARD) 1258 WIN_MSG(WM_PAINTCLIPBOARD) 1259 WIN_MSG(WM_VSCROLLCLIPBOARD) 1260 WIN_MSG(WM_SIZECLIPBOARD) 1261 WIN_MSG(WM_ASKCBFORMATNAME) 1262 WIN_MSG(WM_CHANGECBCHAIN) 1263 WIN_MSG(WM_HSCROLLCLIPBOARD) 1264 WIN_MSG(WM_QUERYNEWPALETTE) 1265 WIN_MSG(WM_PALETTEISCHANGING) 1266 WIN_MSG(WM_PALETTECHANGED) 1267 WIN_MSG(WM_HOTKEY) 1268 WIN_MSG(WM_PRINT) 1269 WIN_MSG(WM_PRINTCLIENT) 1270 WIN_MSG(WM_HANDHELDFIRST) 1271 WIN_MSG(WM_HANDHELDLAST) 1272 WIN_MSG(WM_AFXFIRST) 1273 WIN_MSG(WM_AFXLAST) 1274 WIN_MSG(WM_PENWINFIRST) 1275 WIN_MSG(WM_PENWINLAST) 1276 WIN_MSG(WM_AWT_COMPONENT_CREATE) 1277 WIN_MSG(WM_AWT_DESTROY_WINDOW) 1278 WIN_MSG(WM_AWT_MOUSEENTER) 1279 WIN_MSG(WM_AWT_MOUSEEXIT) 1280 WIN_MSG(WM_AWT_COMPONENT_SHOW) 1281 WIN_MSG(WM_AWT_COMPONENT_HIDE) 1282 WIN_MSG(WM_AWT_COMPONENT_SETFOCUS) 1283 WIN_MSG(WM_AWT_WINDOW_SETACTIVE) 1284 WIN_MSG(WM_AWT_LIST_SETMULTISELECT) 1285 WIN_MSG(WM_AWT_HANDLE_EVENT) 1286 WIN_MSG(WM_AWT_PRINT_COMPONENT) 1287 WIN_MSG(WM_AWT_RESHAPE_COMPONENT) 1288 WIN_MSG(WM_AWT_SETALWAYSONTOP) 1289 WIN_MSG(WM_AWT_BEGIN_VALIDATE) 1290 WIN_MSG(WM_AWT_END_VALIDATE) 1291 WIN_MSG(WM_AWT_FORWARD_CHAR) 1292 WIN_MSG(WM_AWT_FORWARD_BYTE) 1293 WIN_MSG(WM_AWT_SET_SCROLL_INFO) 1294 WIN_MSG(WM_AWT_CREATECONTEXT) 1295 WIN_MSG(WM_AWT_DESTROYCONTEXT) 1296 WIN_MSG(WM_AWT_ASSOCIATECONTEXT) 1297 WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER) 1298 WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT) 1299 WIN_MSG(WM_AWT_PRE_KEYDOWN) 1300 WIN_MSG(WM_AWT_PRE_KEYUP) 1301 WIN_MSG(WM_AWT_PRE_SYSKEYDOWN) 1302 WIN_MSG(WM_AWT_PRE_SYSKEYUP) 1303 WIN_MSG(WM_AWT_ENDCOMPOSITION,) 1304 WIN_MSG(WM_AWT_DISPOSE,) 1305 WIN_MSG(WM_AWT_DELETEOBJECT,) 1306 WIN_MSG(WM_AWT_SETCONVERSIONSTATUS,) 1307 WIN_MSG(WM_AWT_GETCONVERSIONSTATUS,) 1308 WIN_MSG(WM_AWT_SETOPENSTATUS,) 1309 WIN_MSG(WM_AWT_GETOPENSTATUS) 1310 WIN_MSG(WM_AWT_ACTIVATEKEYBOARDLAYOUT) 1311 WIN_MSG(WM_AWT_OPENCANDIDATEWINDOW) 1312 WIN_MSG(WM_AWT_DLG_SHOWMODAL,) 1313 WIN_MSG(WM_AWT_DLG_ENDMODAL,) 1314 WIN_MSG(WM_AWT_SETCURSOR,) 1315 WIN_MSG(WM_AWT_WAIT_FOR_SINGLE_OBJECT,) 1316 WIN_MSG(WM_AWT_INVOKE_METHOD,) 1317 WIN_MSG(WM_AWT_INVOKE_VOID_METHOD,) 1318 WIN_MSG(WM_AWT_EXECUTE_SYNC,) 1319 WIN_MSG(WM_AWT_CURSOR_SYNC) 1320 WIN_MSG(WM_AWT_GETDC) 1321 WIN_MSG(WM_AWT_RELEASEDC) 1322 WIN_MSG(WM_AWT_RELEASE_ALL_DCS) 1323 WIN_MSG(WM_AWT_SHOWCURSOR) 1324 WIN_MSG(WM_AWT_HIDECURSOR) 1325 WIN_MSG(WM_AWT_CREATE_PRINTED_PIXELS) 1326 WIN_MSG(WM_AWT_OBJECTLISTCLEANUP) 1327 default: 1328 sprintf(szBuf, "0x%8.8x(%s):Unknown message 0x%8.8x\n", 1329 hwnd, szComment, message); 1330 break; 1331 } 1332 printf(szBuf); 1333 } 1334 1335 #endif /* SPY_MESSAGES */ 1336 1337 /* 1338 * Dispatch messages for this window class--general component 1339 */ 1340 LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 1341 { 1342 CounterHelper ch(&m_MessagesProcessing); 1343 1344 JNILocalFrame lframe(AwtToolkit::GetEnv(), 10); 1345 SpyWinMessage(GetHWnd(), message, 1346 (message == WM_AWT_RELEASE_ALL_DCS) ? TEXT("Disposed Component") : GetClassName()); 1347 1348 LRESULT retValue = 0; 1349 MsgRouting mr = mrDoDefault; 1350 AwtToolkit::GetInstance().eventNumber++; 1351 1352 static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg? 1353 1354 lastMessage = message; 1355 1356 if (message == WmAwtIsComponent) { 1357 // special message to identify AWT HWND's without using 1358 // resource hogging ::SetProp 1359 return (LRESULT)TRUE; 1360 } 1361 1362 DWORD curPos = 0; 1363 1364 UINT switchMessage = message; 1365 switch (switchMessage) { 1366 case WM_AWT_GETDC: 1367 { 1368 HDC hDC; 1369 // First, release the DCs scheduled for deletion 1370 ReleaseDCList(GetHWnd(), passiveDCList); 1371 1372 GetDCReturnStruct *returnStruct = new GetDCReturnStruct; 1373 returnStruct->gdiLimitReached = FALSE; 1374 if (AwtGDIObject::IncrementIfAvailable()) { 1375 hDC = ::GetDCEx(GetHWnd(), NULL, 1376 DCX_CACHE | DCX_CLIPCHILDREN | 1377 DCX_CLIPSIBLINGS); 1378 if (hDC != NULL) { 1379 // Add new DC to list of DC's associated with this Component 1380 activeDCList.AddDC(hDC, GetHWnd()); 1381 } else { 1382 // Creation failed; decrement counter in AwtGDIObject 1383 AwtGDIObject::Decrement(); 1384 } 1385 } else { 1386 hDC = NULL; 1387 returnStruct->gdiLimitReached = TRUE; 1388 } 1389 returnStruct->hDC = hDC; 1390 retValue = (LRESULT)returnStruct; 1391 mr = mrConsume; 1392 break; 1393 } 1394 case WM_AWT_RELEASEDC: 1395 { 1396 HDC hDC = (HDC)wParam; 1397 MoveDCToPassiveList(hDC, GetHWnd()); 1398 ReleaseDCList(GetHWnd(), passiveDCList); 1399 mr = mrConsume; 1400 break; 1401 } 1402 case WM_AWT_RELEASE_ALL_DCS: 1403 { 1404 // Called during Component destruction. Gets current list of 1405 // DC's associated with Component and releases each DC. 1406 ReleaseDCList(GetHWnd(), activeDCList); 1407 ReleaseDCList(GetHWnd(), passiveDCList); 1408 mr = mrConsume; 1409 break; 1410 } 1411 case WM_AWT_SHOWCURSOR: 1412 ::ShowCursor(TRUE); 1413 break; 1414 case WM_AWT_HIDECURSOR: 1415 ::ShowCursor(FALSE); 1416 break; 1417 case WM_CREATE: mr = WmCreate(); break; 1418 case WM_CLOSE: mr = WmClose(); break; 1419 case WM_DESTROY: mr = WmDestroy(); break; 1420 case WM_NCDESTROY: mr = WmNcDestroy(); break; 1421 1422 case WM_ERASEBKGND: 1423 mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break; 1424 case WM_PAINT: 1425 CheckFontSmoothingSettings(GetHWnd()); 1426 /* Set draw state */ 1427 SetDrawState(GetDrawState() | JAWT_LOCK_CLIP_CHANGED); 1428 mr = WmPaint((HDC)wParam); 1429 break; 1430 1431 case WM_GETMINMAXINFO: 1432 mr = WmGetMinMaxInfo((LPMINMAXINFO)lParam); 1433 break; 1434 1435 case WM_WINDOWPOSCHANGING: 1436 { 1437 // We process this message so that we can synchronize access to 1438 // a moving window. The Scale/Blt functions in Win32BlitLoops 1439 // take the same windowMoveLock to ensure that a window is not 1440 // moving while we are trying to copy pixels into it. 1441 WINDOWPOS *lpPosInfo = (WINDOWPOS *)lParam; 1442 if ((lpPosInfo->flags & (SWP_NOMOVE | SWP_NOSIZE)) != 1443 (SWP_NOMOVE | SWP_NOSIZE)) 1444 { 1445 // Move or Size command. 1446 // Windows tends to send erroneous events that the window 1447 // is about to move when the coordinates are exactly the 1448 // same as the last time. This can cause problems with 1449 // our windowMoveLock CriticalSection because we enter it 1450 // here and never get to WM_WINDOWPOSCHANGED to release it. 1451 // So make sure this is a real move/size event before bothering 1452 // to grab the critical section. 1453 BOOL takeLock = FALSE; 1454 if (!(lpPosInfo->flags & SWP_NOMOVE) && 1455 ((windowMoveLockPosX != lpPosInfo->x) || 1456 (windowMoveLockPosY != lpPosInfo->y))) 1457 { 1458 // Real move event 1459 takeLock = TRUE; 1460 windowMoveLockPosX = lpPosInfo->x; 1461 windowMoveLockPosY = lpPosInfo->y; 1462 } 1463 if (!(lpPosInfo->flags & SWP_NOSIZE) && 1464 ((windowMoveLockPosCX != lpPosInfo->cx) || 1465 (windowMoveLockPosCY != lpPosInfo->cy))) 1466 { 1467 // Real size event 1468 takeLock = TRUE; 1469 windowMoveLockPosCX = lpPosInfo->cx; 1470 windowMoveLockPosCY = lpPosInfo->cy; 1471 } 1472 if (takeLock) { 1473 if (!windowMoveLockHeld) { 1474 windowMoveLock.Enter(); 1475 windowMoveLockHeld = TRUE; 1476 } 1477 } 1478 } 1479 mr = WmWindowPosChanging(lParam); 1480 break; 1481 } 1482 case WM_WINDOWPOSCHANGED: 1483 { 1484 // Release lock grabbed in the POSCHANGING message 1485 if (windowMoveLockHeld) { 1486 windowMoveLockHeld = FALSE; 1487 windowMoveLock.Leave(); 1488 } 1489 mr = WmWindowPosChanged(lParam); 1490 break; 1491 } 1492 case WM_MOVE: { 1493 RECT r; 1494 ::GetWindowRect(GetHWnd(), &r); 1495 mr = WmMove(r.left, r.top); 1496 break; 1497 } 1498 case WM_SIZE: 1499 { 1500 RECT r; 1501 // fix 4128317 : use GetClientRect for full 32-bit int precision and 1502 // to avoid negative client area dimensions overflowing 16-bit params - robi 1503 ::GetClientRect( GetHWnd(), &r ); 1504 mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top); 1505 //mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam)); 1506 SetCompositionWindow(r); 1507 break; 1508 } 1509 case WM_SIZING: 1510 mr = WmSizing(); 1511 break; 1512 case WM_SHOWWINDOW: 1513 mr = WmShowWindow(static_cast<BOOL>(wParam), 1514 static_cast<UINT>(lParam)); break; 1515 case WM_SYSCOMMAND: 1516 mr = WmSysCommand(static_cast<UINT>(wParam & 0xFFF0), 1517 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1518 break; 1519 case WM_EXITSIZEMOVE: 1520 mr = WmExitSizeMove(); 1521 break; 1522 // Bug #4039858 (Selecting menu item causes bogus mouse click event) 1523 case WM_ENTERMENULOOP: 1524 mr = WmEnterMenuLoop((BOOL)wParam); 1525 sm_bMenuLoop = TRUE; 1526 // we need to release grab if menu is shown 1527 if (AwtWindow::GetGrabbedWindow() != NULL) { 1528 AwtWindow::GetGrabbedWindow()->Ungrab(); 1529 } 1530 break; 1531 case WM_EXITMENULOOP: 1532 mr = WmExitMenuLoop((BOOL)wParam); 1533 sm_bMenuLoop = FALSE; 1534 break; 1535 1536 // We don't expect any focus messages on non-proxy component, 1537 // except those that came from Java. 1538 case WM_SETFOCUS: 1539 if (sm_inSynthesizeFocus) { 1540 mr = WmSetFocus((HWND)wParam); 1541 } else { 1542 mr = mrConsume; 1543 } 1544 break; 1545 case WM_KILLFOCUS: 1546 if (sm_inSynthesizeFocus) { 1547 mr = WmKillFocus((HWND)wParam); 1548 } else { 1549 mr = mrConsume; 1550 } 1551 break; 1552 case WM_ACTIVATE: { 1553 UINT nState = LOWORD(wParam); 1554 BOOL fMinimized = (BOOL)HIWORD(wParam); 1555 mr = mrConsume; 1556 1557 if (!sm_suppressFocusAndActivation && 1558 (!fMinimized || (nState == WA_INACTIVE))) 1559 { 1560 mr = WmActivate(nState, fMinimized, (HWND)lParam); 1561 1562 // When the window is deactivated, send WM_IME_ENDCOMPOSITION 1563 // message to deactivate the composition window so that 1564 // it won't receive keyboard input focus. 1565 HIMC hIMC; 1566 HWND hwnd = ImmGetHWnd(); 1567 if ((hIMC = ImmGetContext(hwnd)) != NULL) { 1568 ImmReleaseContext(hwnd, hIMC); 1569 DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0); 1570 } 1571 } 1572 break; 1573 } 1574 case WM_MOUSEACTIVATE: { 1575 AwtWindow *window = GetContainer(); 1576 if (window && window->IsFocusableWindow()) { 1577 // AWT/Swing will later request focus to a proper component 1578 // on handling the Java mouse event. Anyway, we have to 1579 // activate the window here as it works both for AWT & Swing. 1580 // Do it in our own fassion, 1581 window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/); 1582 } 1583 mr = mrConsume; 1584 retValue = MA_NOACTIVATE; 1585 break; 1586 } 1587 case WM_CTLCOLORMSGBOX: 1588 case WM_CTLCOLOREDIT: 1589 case WM_CTLCOLORLISTBOX: 1590 case WM_CTLCOLORBTN: 1591 case WM_CTLCOLORDLG: 1592 case WM_CTLCOLORSCROLLBAR: 1593 case WM_CTLCOLORSTATIC: 1594 mr = WmCtlColor((HDC)wParam, (HWND)lParam, 1595 message-WM_CTLCOLORMSGBOX+CTLCOLOR_MSGBOX, 1596 *(HBRUSH*)&retValue); 1597 break; 1598 case WM_HSCROLL: 1599 mr = WmHScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1600 break; 1601 case WM_VSCROLL: 1602 mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1603 break; 1604 // 4664415: We're seeing a WM_LBUTTONUP when the user releases the 1605 // mouse button after a WM_NCLBUTTONDBLCLK. We want to ignore this 1606 // WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the 1607 // flag on a WM_LBUTTONUP. -bchristi 1608 case WM_NCLBUTTONDBLCLK: 1609 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON | DBL_CLICK); 1610 if (mr == mrDoDefault) { 1611 ignoreNextLBTNUP = TRUE; 1612 } 1613 break; 1614 case WM_NCLBUTTONDOWN: 1615 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1616 ignoreNextLBTNUP = FALSE; 1617 break; 1618 case WM_NCLBUTTONUP: 1619 mr = WmNcMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1620 break; 1621 case WM_NCRBUTTONDOWN: 1622 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RIGHT_BUTTON); 1623 break; 1624 case WM_LBUTTONUP: 1625 if (ignoreNextLBTNUP) { 1626 ignoreNextLBTNUP = FALSE; 1627 return mrDoDefault; 1628 } 1629 //fall-through 1630 case WM_LBUTTONDOWN: 1631 ignoreNextLBTNUP = FALSE; 1632 //fall-through 1633 case WM_LBUTTONDBLCLK: 1634 case WM_RBUTTONDOWN: 1635 case WM_RBUTTONDBLCLK: 1636 case WM_RBUTTONUP: 1637 case WM_MBUTTONDOWN: 1638 case WM_MBUTTONDBLCLK: 1639 case WM_MBUTTONUP: 1640 case WM_XBUTTONDBLCLK: 1641 case WM_XBUTTONDOWN: 1642 case WM_XBUTTONUP: 1643 case WM_MOUSEMOVE: 1644 case WM_MOUSEWHEEL: 1645 case WM_AWT_MOUSEENTER: 1646 case WM_AWT_MOUSEEXIT: 1647 curPos = ::GetMessagePos(); 1648 POINT myPos; 1649 myPos.x = GET_X_LPARAM(curPos); 1650 myPos.y = GET_Y_LPARAM(curPos); 1651 ::ScreenToClient(GetHWnd(), &myPos); 1652 switch(switchMessage) { 1653 case WM_AWT_MOUSEENTER: 1654 mr = WmMouseEnter(static_cast<UINT>(wParam), myPos.x, myPos.y); 1655 break; 1656 case WM_LBUTTONDOWN: 1657 case WM_LBUTTONDBLCLK: 1658 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1659 LEFT_BUTTON); 1660 break; 1661 case WM_LBUTTONUP: 1662 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1663 LEFT_BUTTON); 1664 break; 1665 case WM_MOUSEMOVE: 1666 mr = WmMouseMove(static_cast<UINT>(wParam), myPos.x, myPos.y); 1667 break; 1668 case WM_MBUTTONDOWN: 1669 case WM_MBUTTONDBLCLK: 1670 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1671 MIDDLE_BUTTON); 1672 break; 1673 case WM_XBUTTONDOWN: 1674 case WM_XBUTTONDBLCLK: 1675 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1676 if (HIWORD(wParam) == 1) { 1677 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1678 X1_BUTTON); 1679 } 1680 if (HIWORD(wParam) == 2) { 1681 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1682 X2_BUTTON); 1683 } 1684 } 1685 break; 1686 case WM_XBUTTONUP: 1687 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1688 if (HIWORD(wParam) == 1) { 1689 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1690 X1_BUTTON); 1691 } 1692 if (HIWORD(wParam) == 2) { 1693 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1694 X2_BUTTON); 1695 } 1696 } 1697 break; 1698 case WM_RBUTTONDOWN: 1699 case WM_RBUTTONDBLCLK: 1700 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1701 RIGHT_BUTTON); 1702 break; 1703 case WM_RBUTTONUP: 1704 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1705 RIGHT_BUTTON); 1706 break; 1707 case WM_MBUTTONUP: 1708 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1709 MIDDLE_BUTTON); 1710 break; 1711 case WM_AWT_MOUSEEXIT: 1712 mr = WmMouseExit(static_cast<UINT>(wParam), myPos.x, myPos.y); 1713 break; 1714 case WM_MOUSEWHEEL: 1715 mr = WmMouseWheel(GET_KEYSTATE_WPARAM(wParam), 1716 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1717 GET_WHEEL_DELTA_WPARAM(wParam)); 1718 break; 1719 } 1720 break; 1721 case WM_TOUCH: 1722 WmTouch(wParam, lParam); 1723 break; 1724 case WM_SETCURSOR: 1725 mr = mrDoDefault; 1726 if (LOWORD(lParam) == HTCLIENT) { 1727 if (AwtComponent* comp = 1728 AwtComponent::GetComponent((HWND)wParam)) { 1729 AwtCursor::UpdateCursor(comp); 1730 mr = mrConsume; 1731 } 1732 } 1733 break; 1734 1735 case WM_KEYDOWN: 1736 mr = WmKeyDown(static_cast<UINT>(wParam), 1737 LOWORD(lParam), HIWORD(lParam), FALSE); 1738 break; 1739 case WM_KEYUP: 1740 mr = WmKeyUp(static_cast<UINT>(wParam), 1741 LOWORD(lParam), HIWORD(lParam), FALSE); 1742 break; 1743 case WM_SYSKEYDOWN: 1744 mr = WmKeyDown(static_cast<UINT>(wParam), 1745 LOWORD(lParam), HIWORD(lParam), TRUE); 1746 break; 1747 case WM_SYSKEYUP: 1748 mr = WmKeyUp(static_cast<UINT>(wParam), 1749 LOWORD(lParam), HIWORD(lParam), TRUE); 1750 break; 1751 case WM_IME_SETCONTEXT: 1752 // lParam is passed as pointer and it can be modified. 1753 mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam); 1754 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1755 break; 1756 case WM_IME_NOTIFY: 1757 mr = WmImeNotify(wParam, lParam); 1758 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1759 break; 1760 case WM_IME_STARTCOMPOSITION: 1761 mr = WmImeStartComposition(); 1762 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1763 break; 1764 case WM_IME_ENDCOMPOSITION: 1765 mr = WmImeEndComposition(); 1766 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1767 break; 1768 case WM_IME_COMPOSITION: { 1769 WORD dbcschar = static_cast<WORD>(wParam); 1770 mr = WmImeComposition(dbcschar, lParam); 1771 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1772 break; 1773 } 1774 case WM_IME_CONTROL: 1775 case WM_IME_COMPOSITIONFULL: 1776 case WM_IME_SELECT: 1777 case WM_IME_KEYUP: 1778 case WM_IME_KEYDOWN: 1779 case WM_IME_REQUEST: 1780 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1781 break; 1782 case WM_CHAR: 1783 mr = WmChar(static_cast<UINT>(wParam), 1784 LOWORD(lParam), HIWORD(lParam), FALSE); 1785 break; 1786 case WM_SYSCHAR: 1787 mr = WmChar(static_cast<UINT>(wParam), 1788 LOWORD(lParam), HIWORD(lParam), TRUE); 1789 break; 1790 case WM_IME_CHAR: 1791 mr = WmIMEChar(static_cast<UINT>(wParam), 1792 LOWORD(lParam), HIWORD(lParam), FALSE); 1793 break; 1794 1795 case WM_INPUTLANGCHANGEREQUEST: { 1796 DTRACE_PRINTLN4("WM_INPUTLANGCHANGEREQUEST: hwnd = 0x%X (%s);"// 1797 "0x%08X -> 0x%08X", 1798 GetHWnd(), GetClassName(), 1799 (UINT_PTR)GetKeyboardLayout(), (UINT_PTR)lParam); 1800 // 4267428: make sure keyboard layout is turned undead. 1801 static BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 1802 AwtToolkit::GetKeyboardState(keyboardState); 1803 WORD ignored; 1804 ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0), 1805 keyboardState, &ignored, 0, GetKeyboardLayout()); 1806 1807 // Set this flag to block ActivateKeyboardLayout from 1808 // WInputMethod.activate() 1809 g_bUserHasChangedInputLang = TRUE; 1810 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1811 break; 1812 } 1813 case WM_INPUTLANGCHANGE: 1814 DTRACE_PRINTLN3("WM_INPUTLANGCHANGE: hwnd = 0x%X (%s);"// 1815 "new = 0x%08X", 1816 GetHWnd(), GetClassName(), (UINT)lParam); 1817 mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam)); 1818 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1819 // should return non-zero if we process this message 1820 retValue = 1; 1821 break; 1822 1823 case WM_AWT_FORWARD_CHAR: 1824 mr = WmForwardChar(LOWORD(wParam), lParam, HIWORD(wParam)); 1825 break; 1826 1827 case WM_AWT_FORWARD_BYTE: 1828 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1829 break; 1830 1831 case WM_PASTE: 1832 mr = WmPaste(); 1833 break; 1834 case WM_TIMER: 1835 mr = WmTimer(wParam); 1836 break; 1837 1838 case WM_COMMAND: 1839 mr = WmCommand(LOWORD(wParam), (HWND)lParam, HIWORD(wParam)); 1840 break; 1841 case WM_COMPAREITEM: 1842 mr = WmCompareItem(static_cast<UINT>(wParam), 1843 *(COMPAREITEMSTRUCT*)lParam, retValue); 1844 break; 1845 case WM_DELETEITEM: 1846 mr = WmDeleteItem(static_cast<UINT>(wParam), 1847 *(DELETEITEMSTRUCT*)lParam); 1848 break; 1849 case WM_DRAWITEM: 1850 mr = WmDrawItem(static_cast<UINT>(wParam), 1851 *(DRAWITEMSTRUCT*)lParam); 1852 break; 1853 case WM_MEASUREITEM: 1854 mr = WmMeasureItem(static_cast<UINT>(wParam), 1855 *(MEASUREITEMSTRUCT*)lParam); 1856 break; 1857 1858 case WM_AWT_HANDLE_EVENT: 1859 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1860 break; 1861 1862 case WM_PRINT: 1863 mr = WmPrint((HDC)wParam, lParam); 1864 break; 1865 case WM_PRINTCLIENT: 1866 mr = WmPrintClient((HDC)wParam, lParam); 1867 break; 1868 1869 case WM_NCCALCSIZE: 1870 mr = WmNcCalcSize((BOOL)wParam, (LPNCCALCSIZE_PARAMS)lParam, 1871 retValue); 1872 break; 1873 case WM_NCPAINT: 1874 mr = WmNcPaint((HRGN)wParam); 1875 break; 1876 case WM_NCHITTEST: 1877 mr = WmNcHitTest(LOWORD(lParam), HIWORD(lParam), retValue); 1878 break; 1879 1880 case WM_AWT_RESHAPE_COMPONENT: { 1881 RECT* r = (RECT*)lParam; 1882 WPARAM checkEmbedded = wParam; 1883 if (checkEmbedded == CHECK_EMBEDDED && IsEmbeddedFrame()) { 1884 ::OffsetRect(r, -r->left, -r->top); 1885 } 1886 Reshape(r->left, r->top, r->right - r->left, r->bottom - r->top); 1887 delete r; 1888 mr = mrConsume; 1889 break; 1890 } 1891 1892 case WM_AWT_SETALWAYSONTOP: { 1893 AwtWindow* w = (AwtWindow*)lParam; 1894 BOOL value = (BOOL)wParam; 1895 UINT flags = SWP_NOMOVE | SWP_NOSIZE; 1896 // transient windows shouldn't change the owner window's position in the z-order 1897 if (w->IsRetainingHierarchyZOrder()) { 1898 flags |= SWP_NOOWNERZORDER; 1899 } 1900 ::SetWindowPos(w->GetHWnd(), (value != 0 ? HWND_TOPMOST : HWND_NOTOPMOST), 1901 0,0,0,0, flags); 1902 break; 1903 } 1904 1905 case WM_AWT_BEGIN_VALIDATE: 1906 BeginValidate(); 1907 mr = mrConsume; 1908 break; 1909 case WM_AWT_END_VALIDATE: 1910 EndValidate(); 1911 mr = mrConsume; 1912 break; 1913 1914 case WM_PALETTEISCHANGING: 1915 mr = WmPaletteIsChanging((HWND)wParam); 1916 mr = mrDoDefault; 1917 break; 1918 case WM_QUERYNEWPALETTE: 1919 mr = WmQueryNewPalette(retValue); 1920 break; 1921 case WM_PALETTECHANGED: 1922 mr = WmPaletteChanged((HWND)wParam); 1923 break; 1924 case WM_STYLECHANGED: 1925 mr = WmStyleChanged(static_cast<int>(wParam), (LPSTYLESTRUCT)lParam); 1926 break; 1927 case WM_SETTINGCHANGE: 1928 CheckFontSmoothingSettings(NULL); 1929 mr = WmSettingChange(static_cast<UINT>(wParam), (LPCTSTR)lParam); 1930 break; 1931 case WM_CONTEXTMENU: 1932 mr = WmContextMenu((HWND)wParam, 1933 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1934 break; 1935 1936 /* 1937 * These messages are used to route Win32 calls to the 1938 * creating thread, since these calls fail unless executed 1939 * there. 1940 */ 1941 case WM_AWT_COMPONENT_SHOW: 1942 Show(); 1943 mr = mrConsume; 1944 break; 1945 case WM_AWT_COMPONENT_HIDE: 1946 Hide(); 1947 mr = mrConsume; 1948 break; 1949 1950 case WM_AWT_COMPONENT_SETFOCUS: 1951 if ((BOOL)wParam) { 1952 retValue = SynthesizeWmSetFocus(GetHWnd(), NULL); 1953 } else { 1954 retValue = SynthesizeWmKillFocus(GetHWnd(), NULL); 1955 } 1956 mr = mrConsume; 1957 break; 1958 case WM_AWT_WINDOW_SETACTIVE: 1959 retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam); 1960 mr = mrConsume; 1961 break; 1962 1963 case WM_AWT_SET_SCROLL_INFO: { 1964 SCROLLINFO *si = (SCROLLINFO *) lParam; 1965 ::SetScrollInfo(GetHWnd(), (int) wParam, si, TRUE); 1966 delete si; 1967 mr = mrConsume; 1968 break; 1969 } 1970 case WM_AWT_CREATE_PRINTED_PIXELS: { 1971 CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam; 1972 SIZE loc = { cpps->srcx, cpps->srcy }; 1973 SIZE size = { cpps->srcw, cpps->srch }; 1974 retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha); 1975 mr = mrConsume; 1976 break; 1977 } 1978 case WM_UNDOCUMENTED_CLICKMENUBAR: 1979 { 1980 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1981 mr = mrConsume; 1982 } 1983 } 1984 } 1985 1986 /* 1987 * If not a specific Consume, it was a specific DoDefault, or a 1988 * PassAlong (since the default is the next in chain), then call the 1989 * default proc. 1990 */ 1991 if (mr != mrConsume) { 1992 retValue = DefWindowProc(message, wParam, lParam); 1993 } 1994 1995 return retValue; 1996 } 1997 /* 1998 * Call this instance's default window proc, or if none set, call the stock 1999 * Window's one. 2000 */ 2001 LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) 2002 { 2003 return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam); 2004 } 2005 2006 /* 2007 * This message should only be received when a window is destroyed by 2008 * Windows, and not Java. Window termination has been reworked so 2009 * this method should never be called during termination. 2010 */ 2011 MsgRouting AwtComponent::WmDestroy() 2012 { 2013 return mrConsume; 2014 } 2015 2016 /* 2017 * This message should only be received when a window is destroyed by 2018 * Windows, and not Java. It is sent only after child windows were destroyed. 2019 */ 2020 MsgRouting AwtComponent::WmNcDestroy() 2021 { 2022 if (m_peerObject != NULL) { // is not being terminating 2023 // Stay in this handler until AwtComponent::Dispose is called. 2024 m_bPauseDestroy = TRUE; 2025 2026 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2027 // Post invocation event for WObjectPeer.dispose to EDT 2028 env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID); 2029 // Wait until AwtComponent::Dispose is called 2030 AwtToolkit::GetInstance().PumpToDestroy(this); 2031 } 2032 2033 return mrConsume; 2034 } 2035 2036 MsgRouting AwtComponent::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 2037 { 2038 return mrDoDefault; 2039 } 2040 2041 MsgRouting AwtComponent::WmMove(int x, int y) 2042 { 2043 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2044 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2045 return mrDoDefault; 2046 } 2047 2048 MsgRouting AwtComponent::WmSize(UINT type, int w, int h) 2049 { 2050 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2051 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2052 return mrDoDefault; 2053 } 2054 2055 MsgRouting AwtComponent::WmSizing() 2056 { 2057 return mrDoDefault; 2058 } 2059 2060 MsgRouting AwtComponent::WmSysCommand(UINT uCmdType, int xPos, int yPos) 2061 { 2062 return mrDoDefault; 2063 } 2064 2065 MsgRouting AwtComponent::WmExitSizeMove() 2066 { 2067 return mrDoDefault; 2068 } 2069 2070 MsgRouting AwtComponent::WmEnterMenuLoop(BOOL isTrackPopupMenu) 2071 { 2072 return mrDoDefault; 2073 } 2074 2075 MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) 2076 { 2077 return mrDoDefault; 2078 } 2079 2080 MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) 2081 { 2082 return mrDoDefault; 2083 } 2084 2085 MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus) 2086 { 2087 m_wheelRotationAmount = 0; 2088 return mrDoDefault; 2089 } 2090 2091 MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus) 2092 { 2093 m_wheelRotationAmount = 0; 2094 return mrDoDefault; 2095 } 2096 2097 MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl, 2098 UINT ctlColor, HBRUSH& retBrush) 2099 { 2100 AwtComponent* child = AwtComponent::GetComponent(hCtrl); 2101 if (child) { 2102 ::SetBkColor(hDC, child->GetBackgroundColor()); 2103 ::SetTextColor(hDC, child->GetColor()); 2104 retBrush = child->GetBackgroundBrush(); 2105 return mrConsume; 2106 } 2107 return mrDoDefault; 2108 /* 2109 switch (ctlColor) { 2110 case CTLCOLOR_MSGBOX: 2111 case CTLCOLOR_EDIT: 2112 case CTLCOLOR_LISTBOX: 2113 case CTLCOLOR_BTN: 2114 case CTLCOLOR_DLG: 2115 case CTLCOLOR_SCROLLBAR: 2116 case CTLCOLOR_STATIC: 2117 } 2118 */ 2119 } 2120 2121 MsgRouting AwtComponent::WmHScroll(UINT scrollCode, UINT pos, 2122 HWND hScrollbar) { 2123 if (hScrollbar && hScrollbar != GetHWnd()) { 2124 /* the last test should never happen */ 2125 AwtComponent* sb = GetComponent(hScrollbar); 2126 if (sb) { 2127 sb->WmHScroll(scrollCode, pos, hScrollbar); 2128 } 2129 } 2130 return mrDoDefault; 2131 } 2132 2133 MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar) 2134 { 2135 if (hScrollbar && hScrollbar != GetHWnd()) { 2136 /* the last test should never happen */ 2137 AwtComponent* sb = GetComponent(hScrollbar); 2138 if (sb) { 2139 sb->WmVScroll(scrollCode, pos, hScrollbar); 2140 } 2141 } 2142 return mrDoDefault; 2143 } 2144 2145 namespace TimeHelper { 2146 // Sometimes the message belongs to another event queue and 2147 // GetMessageTime() may return wrong non-zero value (the case is 2148 // the TrayIcon peer). Using TimeHelper::windowsToUTC(::GetTickCount()) 2149 // could help there. 2150 static DWORD getMessageTimeWindows(){ 2151 DWORD time = ::GetMessageTime(); 2152 // The following 'if' seems to be a unneeded hack. 2153 // Consider removing it. 2154 if (time == 0) { 2155 time = ::GetTickCount(); 2156 } 2157 return time; 2158 } 2159 2160 jlong getMessageTimeUTC() { 2161 return ::JVM_CurrentTimeMillis(NULL, 0); 2162 } 2163 } //TimeHelper 2164 2165 MsgRouting AwtComponent::WmPaint(HDC) 2166 { 2167 /* Get the rectangle that covers all update regions, if any exist. */ 2168 RECT r; 2169 if (::GetUpdateRect(GetHWnd(), &r, FALSE)) { 2170 if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 && 2171 m_peerObject != NULL && m_callbacksEnabled) { 2172 /* 2173 * Always call handlePaint, because the underlying control 2174 * will have painted itself (the "background") before any 2175 * paint method is called. 2176 */ 2177 DoCallback("handlePaint", "(IIII)V", 2178 r.left, r.top, r.right-r.left, r.bottom-r.top); 2179 } 2180 } 2181 return mrDoDefault; 2182 } 2183 2184 void AwtComponent::PaintUpdateRgn(const RECT *insets) 2185 { 2186 // Fix 4530093: Don't Validate if can't actually paint 2187 if (m_peerObject == NULL || !m_callbacksEnabled) { 2188 2189 // Fix 4745222: If we don't ValidateRgn, windows will keep sending 2190 // WM_PAINT messages until we do. This causes java to go into 2191 // a tight loop that increases CPU to 100% and starves main 2192 // thread which needs to complete initialization, but cant. 2193 ::ValidateRgn(GetHWnd(), NULL); 2194 2195 return; 2196 } 2197 2198 HRGN rgn = ::CreateRectRgn(0,0,1,1); 2199 int updated = ::GetUpdateRgn(GetHWnd(), rgn, FALSE); 2200 /* 2201 * Now remove all update regions from this window -- do it 2202 * here instead of after the Java upcall, in case any new 2203 * updating is requested. 2204 */ 2205 ::ValidateRgn(GetHWnd(), NULL); 2206 2207 if (updated == COMPLEXREGION || updated == SIMPLEREGION) { 2208 if (insets != NULL) { 2209 ::OffsetRgn(rgn, insets->left, insets->top); 2210 } 2211 DWORD size = ::GetRegionData(rgn, 0, NULL); 2212 if (size == 0) { 2213 ::DeleteObject((HGDIOBJ)rgn); 2214 return; 2215 } 2216 char* buffer = new char[size]; // safe because sizeof(char)==1 2217 memset(buffer, 0, size); 2218 LPRGNDATA rgndata = (LPRGNDATA)buffer; 2219 rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); 2220 rgndata->rdh.iType = RDH_RECTANGLES; 2221 int retCode = ::GetRegionData(rgn, size, rgndata); 2222 VERIFY(retCode); 2223 if (retCode == 0) { 2224 delete [] buffer; 2225 ::DeleteObject((HGDIOBJ)rgn); 2226 return; 2227 } 2228 /* 2229 * Updating rects are divided into mostly vertical and mostly horizontal 2230 * Each group is united together and if not empty painted separately 2231 */ 2232 RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize); 2233 RECT* un[2] = {0, 0}; 2234 DWORD i; 2235 for (i = 0; i < rgndata->rdh.nCount; i++, r++) { 2236 int width = r->right-r->left; 2237 int height = r->bottom-r->top; 2238 if (width > 0 && height > 0) { 2239 int toAdd = (width > height) ? 0: 1; 2240 if (un[toAdd] != 0) { 2241 ::UnionRect(un[toAdd], un[toAdd], r); 2242 } else { 2243 un[toAdd] = r; 2244 } 2245 } 2246 } 2247 for(i = 0; i < 2; i++) { 2248 if (un[i] != 0) { 2249 DoCallback("handleExpose", "(IIII)V", un[i]->left, un[i]->top, 2250 un[i]->right-un[i]->left, un[i]->bottom-un[i]->top); 2251 } 2252 } 2253 delete [] buffer; 2254 } 2255 ::DeleteObject((HGDIOBJ)rgn); 2256 } 2257 2258 MsgRouting AwtComponent::WmMouseEnter(UINT flags, int x, int y) 2259 { 2260 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_ENTERED, 2261 TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 0, JNI_FALSE); 2262 if ((flags & ALL_MK_BUTTONS) == 0) { 2263 AwtCursor::UpdateCursor(this); 2264 } 2265 sm_cursorOn = GetHWnd(); 2266 return mrConsume; /* Don't pass our synthetic event on! */ 2267 } 2268 2269 MSG* 2270 AwtComponent::CreateMessage(UINT message, WPARAM wParam, LPARAM lParam, 2271 int x = 0, int y = 0) 2272 { 2273 MSG* pMsg = new MSG; 2274 InitMessage(pMsg, message, wParam, lParam, x, y); 2275 return pMsg; 2276 } 2277 2278 2279 jint 2280 AwtComponent::GetDrawState(HWND hwnd) { 2281 return (jint)(INT_PTR)(::GetProp(hwnd, DrawingStateProp)); 2282 } 2283 2284 void 2285 AwtComponent::SetDrawState(HWND hwnd, jint state) { 2286 ::SetProp(hwnd, DrawingStateProp, (HANDLE)(INT_PTR)state); 2287 } 2288 2289 void 2290 AwtComponent::InitMessage(MSG* msg, UINT message, WPARAM wParam, LPARAM lParam, 2291 int x = 0, int y = 0) 2292 { 2293 msg->message = message; 2294 msg->wParam = wParam; 2295 msg->lParam = lParam; 2296 msg->time = TimeHelper::getMessageTimeWindows(); 2297 msg->pt.x = x; 2298 msg->pt.y = y; 2299 } 2300 2301 MsgRouting AwtComponent::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 2302 return mrDoDefault; 2303 } 2304 MsgRouting AwtComponent::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) { 2305 return mrDoDefault; 2306 } 2307 2308 MsgRouting AwtComponent::WmWindowPosChanging(LPARAM windowPos) { 2309 return mrDoDefault; 2310 } 2311 MsgRouting AwtComponent::WmWindowPosChanged(LPARAM windowPos) { 2312 return mrDoDefault; 2313 } 2314 2315 void AwtComponent::WmTouch(WPARAM wParam, LPARAM lParam) { 2316 AwtToolkit& tk = AwtToolkit::GetInstance(); 2317 if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { 2318 return; 2319 } 2320 2321 UINT inputsCount = LOWORD(wParam); 2322 TOUCHINPUT* pInputs = new TOUCHINPUT[inputsCount]; 2323 if (pInputs != NULL) { 2324 if (tk.TIGetTouchInputInfo((HTOUCHINPUT)lParam, inputsCount, pInputs, 2325 sizeof(TOUCHINPUT)) != 0) { 2326 for (UINT i = 0; i < inputsCount; i++) { 2327 TOUCHINPUT ti = pInputs[i]; 2328 if (ti.dwFlags & TOUCHEVENTF_PRIMARY) { 2329 if (ti.dwFlags & TOUCHEVENTF_DOWN) { 2330 m_touchDownPoint.x = ti.x / 100; 2331 m_touchDownPoint.y = ti.y / 100; 2332 ::ScreenToClient(GetHWnd(), &m_touchDownPoint); 2333 m_touchDownOccurred = TRUE; 2334 } else if (ti.dwFlags & TOUCHEVENTF_UP) { 2335 m_touchUpPoint.x = ti.x / 100; 2336 m_touchUpPoint.y = ti.y / 100; 2337 ::ScreenToClient(GetHWnd(), &m_touchUpPoint); 2338 m_touchUpOccurred = TRUE; 2339 } 2340 } 2341 } 2342 } 2343 delete[] pInputs; 2344 } 2345 } 2346 2347 /* Double-click variables. */ 2348 static jlong multiClickTime = ::GetDoubleClickTime(); 2349 static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK); 2350 static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK); 2351 static AwtComponent* lastClickWnd = NULL; 2352 static jlong lastTime = 0; 2353 static int lastClickX = 0; 2354 static int lastClickY = 0; 2355 static int lastButton = 0; 2356 static int clickCount = 0; 2357 2358 // A static method that makes the clickCount available in the derived classes 2359 // overriding WmMouseDown(). 2360 int AwtComponent::GetClickCount() 2361 { 2362 return clickCount; 2363 } 2364 2365 MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button) 2366 { 2367 jlong now = TimeHelper::getMessageTimeUTC(); 2368 2369 if (lastClickWnd == this && 2370 lastButton == button && 2371 (now - lastTime) <= multiClickTime && 2372 abs(x - lastClickX) <= multiClickMaxX && 2373 abs(y - lastClickY) <= multiClickMaxY) 2374 { 2375 clickCount++; 2376 } else { 2377 clickCount = 1; 2378 lastClickWnd = this; 2379 lastButton = button; 2380 lastClickX = x; 2381 lastClickY = y; 2382 } 2383 /* 2384 *Set appropriate bit of the mask on WM_MOUSE_DOWN message. 2385 */ 2386 m_mouseButtonClickAllowed |= GetButtonMK(button); 2387 lastTime = now; 2388 2389 BOOL causedByTouchEvent = FALSE; 2390 if (m_touchDownOccurred && 2391 (abs(m_touchDownPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) && 2392 (abs(m_touchDownPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) { 2393 causedByTouchEvent = TRUE; 2394 m_touchDownOccurred = FALSE; 2395 } 2396 2397 MSG msg; 2398 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2399 2400 AwtWindow *toplevel = GetContainer(); 2401 if (toplevel && !toplevel->IsSimpleWindow()) { 2402 /* 2403 * The frame should be focused by click in case it is 2404 * the active window but not the focused window. See 6886678. 2405 */ 2406 if (toplevel->GetHWnd() == ::GetActiveWindow() && 2407 toplevel->GetHWnd() != AwtComponent::GetFocusedWindow()) 2408 { 2409 toplevel->AwtSetActiveWindow(); 2410 } 2411 } 2412 2413 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y, 2414 GetJavaModifiers(), clickCount, JNI_FALSE, 2415 GetButton(button), &msg, causedByTouchEvent); 2416 /* 2417 * NOTE: this call is intentionally placed after all other code, 2418 * since AwtComponent::WmMouseDown() assumes that the cached id of the 2419 * latest retrieved message (see lastMessage in awt_Component.cpp) 2420 * matches the mouse message being processed. 2421 * SetCapture() sends WM_CAPTURECHANGED and breaks that 2422 * assumption. 2423 */ 2424 SetDragCapture(flags); 2425 2426 AwtWindow * owner = (AwtWindow*)GetComponent(GetTopLevelParentForWindow(GetHWnd())); 2427 if (AwtWindow::GetGrabbedWindow() != NULL && owner != NULL) { 2428 if (!AwtWindow::GetGrabbedWindow()->IsOneOfOwnersOf(owner)) { 2429 AwtWindow::GetGrabbedWindow()->Ungrab(); 2430 } 2431 } 2432 return mrConsume; 2433 } 2434 2435 MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button) 2436 { 2437 BOOL causedByTouchEvent = FALSE; 2438 if (m_touchUpOccurred && 2439 (abs(m_touchUpPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) && 2440 (abs(m_touchUpPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) { 2441 causedByTouchEvent = TRUE; 2442 m_touchUpOccurred = FALSE; 2443 } 2444 2445 MSG msg; 2446 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2447 2448 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::getMessageTimeUTC(), 2449 x, y, GetJavaModifiers(), clickCount, 2450 (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ? 2451 TRUE : FALSE), GetButton(button), &msg, causedByTouchEvent); 2452 /* 2453 * If no movement, then report a click following the button release. 2454 * When WM_MOUSEUP comes to a window without previous WM_MOUSEDOWN, 2455 * spurous MOUSE_CLICK is about to happen. See 6430553. 2456 */ 2457 if ((m_mouseButtonClickAllowed & GetButtonMK(button)) != 0) { //CLICK allowed 2458 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED, 2459 TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 2460 clickCount, JNI_FALSE, GetButton(button)); 2461 } 2462 // Exclude button from allowed to generate CLICK messages 2463 m_mouseButtonClickAllowed &= ~GetButtonMK(button); 2464 2465 if ((flags & ALL_MK_BUTTONS) == 0) { 2466 // only update if all buttons have been released 2467 AwtCursor::UpdateCursor(this); 2468 } 2469 /* 2470 * NOTE: this call is intentionally placed after all other code, 2471 * since AwtComponent::WmMouseUp() assumes that the cached id of the 2472 * latest retrieved message (see lastMessage in awt_Component.cpp) 2473 * matches the mouse message being processed. 2474 * ReleaseCapture() sends WM_CAPTURECHANGED and breaks that 2475 * assumption. 2476 */ 2477 ReleaseDragCapture(flags); 2478 2479 return mrConsume; 2480 } 2481 2482 MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) 2483 { 2484 static AwtComponent* lastComp = NULL; 2485 static int lastX = 0; 2486 static int lastY = 0; 2487 2488 /* 2489 * Only report mouse move and drag events if a move or drag 2490 * actually happened -- Windows sends a WM_MOUSEMOVE in case the 2491 * app wants to modify the cursor. 2492 */ 2493 if (lastComp != this || x != lastX || y != lastY) { 2494 lastComp = this; 2495 lastX = x; 2496 lastY = y; 2497 BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled(); 2498 if (((flags & (ALL_MK_BUTTONS)) != 0) || 2499 (extraButtonsEnabled && (flags & (X_BUTTONS)) != 0)) 2500 // if (( extraButtonsEnabled && ( (flags & (ALL_MK_BUTTONS | X_BUTTONS)) != 0 )) || 2501 // ( !extraButtonsEnabled && (((flags & (ALL_MK_BUTTONS)) != 0 )) && ((flags & (X_BUTTONS)) == 0) )) 2502 { 2503 // 6404008 : if Dragged event fired we shouldn't fire 2504 // Clicked event: m_firstDragSent set to TRUE. 2505 // This is a partial backout of 5039416 fix. 2506 MSG msg; 2507 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2508 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, TimeHelper::getMessageTimeUTC(), x, y, 2509 GetJavaModifiers(), 0, JNI_FALSE, 2510 java_awt_event_MouseEvent_NOBUTTON, &msg); 2511 //dragging means no more CLICKs until next WM_MOUSE_DOWN/WM_MOUSE_UP message sequence 2512 m_mouseButtonClickAllowed = 0; 2513 } else { 2514 MSG msg; 2515 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2516 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::getMessageTimeUTC(), x, y, 2517 GetJavaModifiers(), 0, JNI_FALSE, 2518 java_awt_event_MouseEvent_NOBUTTON, &msg); 2519 } 2520 } 2521 2522 return mrConsume; 2523 } 2524 2525 MsgRouting AwtComponent::WmMouseExit(UINT flags, int x, int y) 2526 { 2527 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, TimeHelper::getMessageTimeUTC(), x, 2528 y, GetJavaModifiers(), 0, JNI_FALSE); 2529 sm_cursorOn = NULL; 2530 return mrConsume; /* Don't pass our synthetic event on! */ 2531 } 2532 2533 MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, 2534 int wheelRotation) 2535 { 2536 // convert coordinates to be Component-relative, not screen relative 2537 // for wheeling when outside the window, this works similar to 2538 // coordinates during a drag 2539 POINT eventPt; 2540 eventPt.x = x; 2541 eventPt.y = y; 2542 DTRACE_PRINT2(" original coords: %i,%i\n", x, y); 2543 ::ScreenToClient(GetHWnd(), &eventPt); 2544 DTRACE_PRINT2(" new coords: %i,%i\n\n", eventPt.x, eventPt.y); 2545 2546 // set some defaults 2547 jint scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL; 2548 jint scrollLines = 3; 2549 2550 BOOL result; 2551 UINT platformLines; 2552 2553 m_wheelRotationAmount += wheelRotation; 2554 2555 // AWT interprets wheel rotation differently than win32, so we need to 2556 // decode wheel amount. 2557 jint roundedWheelRotation = m_wheelRotationAmount / (-1 * WHEEL_DELTA); 2558 jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA); 2559 2560 MSG msg; 2561 result = ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, 2562 &platformLines, 0); 2563 InitMessage(&msg, lastMessage, MAKEWPARAM(flags, wheelRotation), 2564 MAKELPARAM(x, y)); 2565 2566 if (result) { 2567 if (platformLines == WHEEL_PAGESCROLL) { 2568 scrollType = java_awt_event_MouseWheelEvent_WHEEL_BLOCK_SCROLL; 2569 scrollLines = 1; 2570 } 2571 else { 2572 scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL; 2573 scrollLines = platformLines; 2574 } 2575 } 2576 2577 DTRACE_PRINTLN("calling SendMouseWheelEvent"); 2578 2579 SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(), 2580 eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType, 2581 scrollLines, roundedWheelRotation, preciseWheelRotation, &msg); 2582 2583 m_wheelRotationAmount %= WHEEL_DELTA; 2584 // this message could be propagated up to the parent chain 2585 // by the mouse message post processors 2586 return mrConsume; 2587 } 2588 2589 jint AwtComponent::GetKeyLocation(UINT wkey, UINT flags) { 2590 // Rector+Newcomer page 413 2591 // The extended keys are the Alt and Control on the right of 2592 // the space bar, the non-Numpad arrow keys, the non-Numpad 2593 // Insert, PageUp, etc. keys, and the Numpad Divide and Enter keys. 2594 // Note that neither Shift key is extended. 2595 // Although not listed in Rector+Newcomer, both Windows keys 2596 // (91 and 92) are extended keys, the Context Menu key 2597 // (property key or application key - 93) is extended, 2598 // and so is the NumLock key. 2599 2600 // wkey is the wParam, flags is the HIWORD of the lParam 2601 2602 // "Extended" bit is 24th in lParam, so it's 8th in flags = HIWORD(lParam) 2603 BOOL extended = ((1<<8) & flags); 2604 2605 if (IsNumPadKey(wkey, extended)) { 2606 return java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD; 2607 } 2608 2609 switch (wkey) { 2610 case VK_SHIFT: 2611 return AwtComponent::GetShiftKeyLocation(wkey, flags); 2612 case VK_CONTROL: // fall through 2613 case VK_MENU: 2614 if (extended) { 2615 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2616 } else { 2617 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2618 } 2619 case VK_LWIN: 2620 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2621 case VK_RWIN: 2622 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2623 default: 2624 break; 2625 } 2626 2627 // REMIND: if we add keycodes for the windows keys, we'll have to 2628 // include left/right discrimination code for them. 2629 2630 return java_awt_event_KeyEvent_KEY_LOCATION_STANDARD; 2631 } 2632 2633 jint AwtComponent::GetShiftKeyLocation(UINT vkey, UINT flags) 2634 { 2635 // init scancodes to safe values 2636 UINT leftShiftScancode = 0; 2637 UINT rightShiftScancode = 0; 2638 2639 // First 8 bits of flags is the scancode 2640 UINT keyScanCode = flags & 0xFF; 2641 2642 DTRACE_PRINTLN3( 2643 "AwtComponent::GetShiftKeyLocation vkey = %d = 0x%x scan = %d", 2644 vkey, vkey, keyScanCode); 2645 2646 leftShiftScancode = ::MapVirtualKey(VK_LSHIFT, 0); 2647 rightShiftScancode = ::MapVirtualKey(VK_RSHIFT, 0); 2648 2649 if (keyScanCode == leftShiftScancode) { 2650 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2651 } 2652 if (keyScanCode == rightShiftScancode) { 2653 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2654 } 2655 2656 DASSERT(false); 2657 // Note: the above should not fail on NT (or 2000) 2658 2659 // default value 2660 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2661 } 2662 2663 /* Returns Java extended InputEvent modifieres. 2664 * Since ::GetKeyState returns current state and Java modifiers represent 2665 * state before event, modifier on changed key are inverted. 2666 */ 2667 jint 2668 AwtComponent::GetJavaModifiers() 2669 { 2670 jint modifiers = 0; 2671 2672 if (HIBYTE(::GetKeyState(VK_CONTROL)) != 0) { 2673 modifiers |= java_awt_event_InputEvent_CTRL_DOWN_MASK; 2674 } 2675 if (HIBYTE(::GetKeyState(VK_SHIFT)) != 0) { 2676 modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK; 2677 } 2678 if (HIBYTE(::GetKeyState(VK_MENU)) != 0) { 2679 modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK; 2680 } 2681 if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) { 2682 modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK; 2683 } 2684 if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) { 2685 modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK; 2686 } 2687 if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) { 2688 modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK; 2689 } 2690 2691 if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) { 2692 modifiers |= masks[3]; 2693 } 2694 if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) { 2695 modifiers |= masks[4]; 2696 } 2697 return modifiers; 2698 } 2699 2700 jint 2701 AwtComponent::GetButton(int mouseButton) 2702 { 2703 /* Mouse buttons are already set correctly for left/right handedness */ 2704 switch(mouseButton) { 2705 case LEFT_BUTTON: 2706 return java_awt_event_MouseEvent_BUTTON1; 2707 case MIDDLE_BUTTON: 2708 return java_awt_event_MouseEvent_BUTTON2; 2709 case RIGHT_BUTTON: 2710 return java_awt_event_MouseEvent_BUTTON3; 2711 case X1_BUTTON: //16 : 2712 //just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now 2713 return 4; 2714 case X2_BUTTON: //32 2715 return 5; 2716 } 2717 return java_awt_event_MouseEvent_NOBUTTON; 2718 } 2719 2720 UINT 2721 AwtComponent::GetButtonMK(int mouseButton) 2722 { 2723 switch(mouseButton) { 2724 case LEFT_BUTTON: 2725 return MK_LBUTTON; 2726 case MIDDLE_BUTTON: 2727 return MK_MBUTTON; 2728 case RIGHT_BUTTON: 2729 return MK_RBUTTON; 2730 case X1_BUTTON: 2731 return MK_XBUTTON1; 2732 case X2_BUTTON: 2733 return MK_XBUTTON2; 2734 } 2735 return 0; 2736 } 2737 2738 // FIXME: Keyboard related stuff has grown so big and hairy that we 2739 // really need to move it into a class of its own. And, since 2740 // keyboard is a shared resource, AwtComponent is a bad place for it. 2741 2742 // These constants are defined in the Japanese version of VC++5.0, 2743 // but not the US version 2744 #ifndef VK_CONVERT 2745 #define VK_KANA 0x15 2746 #define VK_KANJI 0x19 2747 #define VK_CONVERT 0x1C 2748 #define VK_NONCONVERT 0x1D 2749 #endif 2750 2751 #ifndef VK_XBUTTON1 2752 #define VK_XBUTTON1 0x05 2753 #endif 2754 2755 #ifndef VK_XBUTTON2 2756 #define VK_XBUTTON2 0x06 2757 #endif 2758 2759 typedef struct { 2760 UINT javaKey; 2761 UINT windowsKey; 2762 } KeyMapEntry; 2763 2764 // Static table, arranged more or less spatially. 2765 KeyMapEntry keyMapTable[] = { 2766 // Modifier keys 2767 {java_awt_event_KeyEvent_VK_CAPS_LOCK, VK_CAPITAL}, 2768 {java_awt_event_KeyEvent_VK_SHIFT, VK_SHIFT}, 2769 {java_awt_event_KeyEvent_VK_CONTROL, VK_CONTROL}, 2770 {java_awt_event_KeyEvent_VK_ALT, VK_MENU}, 2771 {java_awt_event_KeyEvent_VK_NUM_LOCK, VK_NUMLOCK}, 2772 2773 // Miscellaneous Windows keys 2774 {java_awt_event_KeyEvent_VK_WINDOWS, VK_LWIN}, 2775 {java_awt_event_KeyEvent_VK_WINDOWS, VK_RWIN}, 2776 {java_awt_event_KeyEvent_VK_CONTEXT_MENU, VK_APPS}, 2777 2778 // Alphabet 2779 {java_awt_event_KeyEvent_VK_A, 'A'}, 2780 {java_awt_event_KeyEvent_VK_B, 'B'}, 2781 {java_awt_event_KeyEvent_VK_C, 'C'}, 2782 {java_awt_event_KeyEvent_VK_D, 'D'}, 2783 {java_awt_event_KeyEvent_VK_E, 'E'}, 2784 {java_awt_event_KeyEvent_VK_F, 'F'}, 2785 {java_awt_event_KeyEvent_VK_G, 'G'}, 2786 {java_awt_event_KeyEvent_VK_H, 'H'}, 2787 {java_awt_event_KeyEvent_VK_I, 'I'}, 2788 {java_awt_event_KeyEvent_VK_J, 'J'}, 2789 {java_awt_event_KeyEvent_VK_K, 'K'}, 2790 {java_awt_event_KeyEvent_VK_L, 'L'}, 2791 {java_awt_event_KeyEvent_VK_M, 'M'}, 2792 {java_awt_event_KeyEvent_VK_N, 'N'}, 2793 {java_awt_event_KeyEvent_VK_O, 'O'}, 2794 {java_awt_event_KeyEvent_VK_P, 'P'}, 2795 {java_awt_event_KeyEvent_VK_Q, 'Q'}, 2796 {java_awt_event_KeyEvent_VK_R, 'R'}, 2797 {java_awt_event_KeyEvent_VK_S, 'S'}, 2798 {java_awt_event_KeyEvent_VK_T, 'T'}, 2799 {java_awt_event_KeyEvent_VK_U, 'U'}, 2800 {java_awt_event_KeyEvent_VK_V, 'V'}, 2801 {java_awt_event_KeyEvent_VK_W, 'W'}, 2802 {java_awt_event_KeyEvent_VK_X, 'X'}, 2803 {java_awt_event_KeyEvent_VK_Y, 'Y'}, 2804 {java_awt_event_KeyEvent_VK_Z, 'Z'}, 2805 2806 // Standard numeric row 2807 {java_awt_event_KeyEvent_VK_0, '0'}, 2808 {java_awt_event_KeyEvent_VK_1, '1'}, 2809 {java_awt_event_KeyEvent_VK_2, '2'}, 2810 {java_awt_event_KeyEvent_VK_3, '3'}, 2811 {java_awt_event_KeyEvent_VK_4, '4'}, 2812 {java_awt_event_KeyEvent_VK_5, '5'}, 2813 {java_awt_event_KeyEvent_VK_6, '6'}, 2814 {java_awt_event_KeyEvent_VK_7, '7'}, 2815 {java_awt_event_KeyEvent_VK_8, '8'}, 2816 {java_awt_event_KeyEvent_VK_9, '9'}, 2817 2818 // Misc key from main block 2819 {java_awt_event_KeyEvent_VK_ENTER, VK_RETURN}, 2820 {java_awt_event_KeyEvent_VK_SPACE, VK_SPACE}, 2821 {java_awt_event_KeyEvent_VK_BACK_SPACE, VK_BACK}, 2822 {java_awt_event_KeyEvent_VK_TAB, VK_TAB}, 2823 {java_awt_event_KeyEvent_VK_ESCAPE, VK_ESCAPE}, 2824 2825 // NumPad with NumLock off & extended block (rectangular) 2826 {java_awt_event_KeyEvent_VK_INSERT, VK_INSERT}, 2827 {java_awt_event_KeyEvent_VK_DELETE, VK_DELETE}, 2828 {java_awt_event_KeyEvent_VK_HOME, VK_HOME}, 2829 {java_awt_event_KeyEvent_VK_END, VK_END}, 2830 {java_awt_event_KeyEvent_VK_PAGE_UP, VK_PRIOR}, 2831 {java_awt_event_KeyEvent_VK_PAGE_DOWN, VK_NEXT}, 2832 {java_awt_event_KeyEvent_VK_CLEAR, VK_CLEAR}, // NumPad 5 2833 2834 // NumPad with NumLock off & extended arrows block (triangular) 2835 {java_awt_event_KeyEvent_VK_LEFT, VK_LEFT}, 2836 {java_awt_event_KeyEvent_VK_RIGHT, VK_RIGHT}, 2837 {java_awt_event_KeyEvent_VK_UP, VK_UP}, 2838 {java_awt_event_KeyEvent_VK_DOWN, VK_DOWN}, 2839 2840 // NumPad with NumLock on: numbers 2841 {java_awt_event_KeyEvent_VK_NUMPAD0, VK_NUMPAD0}, 2842 {java_awt_event_KeyEvent_VK_NUMPAD1, VK_NUMPAD1}, 2843 {java_awt_event_KeyEvent_VK_NUMPAD2, VK_NUMPAD2}, 2844 {java_awt_event_KeyEvent_VK_NUMPAD3, VK_NUMPAD3}, 2845 {java_awt_event_KeyEvent_VK_NUMPAD4, VK_NUMPAD4}, 2846 {java_awt_event_KeyEvent_VK_NUMPAD5, VK_NUMPAD5}, 2847 {java_awt_event_KeyEvent_VK_NUMPAD6, VK_NUMPAD6}, 2848 {java_awt_event_KeyEvent_VK_NUMPAD7, VK_NUMPAD7}, 2849 {java_awt_event_KeyEvent_VK_NUMPAD8, VK_NUMPAD8}, 2850 {java_awt_event_KeyEvent_VK_NUMPAD9, VK_NUMPAD9}, 2851 2852 // NumPad with NumLock on 2853 {java_awt_event_KeyEvent_VK_MULTIPLY, VK_MULTIPLY}, 2854 {java_awt_event_KeyEvent_VK_ADD, VK_ADD}, 2855 {java_awt_event_KeyEvent_VK_SEPARATOR, VK_SEPARATOR}, 2856 {java_awt_event_KeyEvent_VK_SUBTRACT, VK_SUBTRACT}, 2857 {java_awt_event_KeyEvent_VK_DECIMAL, VK_DECIMAL}, 2858 {java_awt_event_KeyEvent_VK_DIVIDE, VK_DIVIDE}, 2859 2860 // Functional keys 2861 {java_awt_event_KeyEvent_VK_F1, VK_F1}, 2862 {java_awt_event_KeyEvent_VK_F2, VK_F2}, 2863 {java_awt_event_KeyEvent_VK_F3, VK_F3}, 2864 {java_awt_event_KeyEvent_VK_F4, VK_F4}, 2865 {java_awt_event_KeyEvent_VK_F5, VK_F5}, 2866 {java_awt_event_KeyEvent_VK_F6, VK_F6}, 2867 {java_awt_event_KeyEvent_VK_F7, VK_F7}, 2868 {java_awt_event_KeyEvent_VK_F8, VK_F8}, 2869 {java_awt_event_KeyEvent_VK_F9, VK_F9}, 2870 {java_awt_event_KeyEvent_VK_F10, VK_F10}, 2871 {java_awt_event_KeyEvent_VK_F11, VK_F11}, 2872 {java_awt_event_KeyEvent_VK_F12, VK_F12}, 2873 {java_awt_event_KeyEvent_VK_F13, VK_F13}, 2874 {java_awt_event_KeyEvent_VK_F14, VK_F14}, 2875 {java_awt_event_KeyEvent_VK_F15, VK_F15}, 2876 {java_awt_event_KeyEvent_VK_F16, VK_F16}, 2877 {java_awt_event_KeyEvent_VK_F17, VK_F17}, 2878 {java_awt_event_KeyEvent_VK_F18, VK_F18}, 2879 {java_awt_event_KeyEvent_VK_F19, VK_F19}, 2880 {java_awt_event_KeyEvent_VK_F20, VK_F20}, 2881 {java_awt_event_KeyEvent_VK_F21, VK_F21}, 2882 {java_awt_event_KeyEvent_VK_F22, VK_F22}, 2883 {java_awt_event_KeyEvent_VK_F23, VK_F23}, 2884 {java_awt_event_KeyEvent_VK_F24, VK_F24}, 2885 2886 {java_awt_event_KeyEvent_VK_PRINTSCREEN, VK_SNAPSHOT}, 2887 {java_awt_event_KeyEvent_VK_SCROLL_LOCK, VK_SCROLL}, 2888 {java_awt_event_KeyEvent_VK_PAUSE, VK_PAUSE}, 2889 {java_awt_event_KeyEvent_VK_CANCEL, VK_CANCEL}, 2890 {java_awt_event_KeyEvent_VK_HELP, VK_HELP}, 2891 2892 // Japanese 2893 {java_awt_event_KeyEvent_VK_CONVERT, VK_CONVERT}, 2894 {java_awt_event_KeyEvent_VK_NONCONVERT, VK_NONCONVERT}, 2895 {java_awt_event_KeyEvent_VK_INPUT_METHOD_ON_OFF, VK_KANJI}, 2896 {java_awt_event_KeyEvent_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC}, 2897 {java_awt_event_KeyEvent_VK_KATAKANA, VK_DBE_KATAKANA}, 2898 {java_awt_event_KeyEvent_VK_HIRAGANA, VK_DBE_HIRAGANA}, 2899 {java_awt_event_KeyEvent_VK_FULL_WIDTH, VK_DBE_DBCSCHAR}, 2900 {java_awt_event_KeyEvent_VK_HALF_WIDTH, VK_DBE_SBCSCHAR}, 2901 {java_awt_event_KeyEvent_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN}, 2902 2903 {java_awt_event_KeyEvent_VK_UNDEFINED, 0} 2904 }; 2905 2906 2907 // Dynamic mapping table for OEM VK codes. This table is refilled 2908 // by BuildDynamicKeyMapTable when keyboard layout is switched. 2909 // (see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values). 2910 struct DynamicKeyMapEntry { 2911 UINT windowsKey; // OEM VK codes known in advance 2912 UINT javaKey; // depends on input langauge (kbd layout) 2913 }; 2914 2915 static DynamicKeyMapEntry dynamicKeyMapTable[] = { 2916 {0x00BA, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_1 2917 {0x00BB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PLUS 2918 {0x00BC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_COMMA 2919 {0x00BD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_MINUS 2920 {0x00BE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PERIOD 2921 {0x00BF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_2 2922 {0x00C0, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_3 2923 {0x00DB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_4 2924 {0x00DC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_5 2925 {0x00DD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_6 2926 {0x00DE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_7 2927 {0x00DF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_8 2928 {0x00E2, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_102 2929 {0, 0} 2930 }; 2931 2932 2933 2934 // Auxiliary tables used to fill the above dynamic table. We first 2935 // find the character for the OEM VK code using ::MapVirtualKey and 2936 // then go through these auxiliary tables to map it to Java VK code. 2937 2938 struct CharToVKEntry { 2939 WCHAR c; 2940 UINT javaKey; 2941 }; 2942 2943 static const CharToVKEntry charToVKTable[] = { 2944 {L'!', java_awt_event_KeyEvent_VK_EXCLAMATION_MARK}, 2945 {L'"', java_awt_event_KeyEvent_VK_QUOTEDBL}, 2946 {L'#', java_awt_event_KeyEvent_VK_NUMBER_SIGN}, 2947 {L'$', java_awt_event_KeyEvent_VK_DOLLAR}, 2948 {L'&', java_awt_event_KeyEvent_VK_AMPERSAND}, 2949 {L'\'', java_awt_event_KeyEvent_VK_QUOTE}, 2950 {L'(', java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS}, 2951 {L')', java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS}, 2952 {L'*', java_awt_event_KeyEvent_VK_ASTERISK}, 2953 {L'+', java_awt_event_KeyEvent_VK_PLUS}, 2954 {L',', java_awt_event_KeyEvent_VK_COMMA}, 2955 {L'-', java_awt_event_KeyEvent_VK_MINUS}, 2956 {L'.', java_awt_event_KeyEvent_VK_PERIOD}, 2957 {L'/', java_awt_event_KeyEvent_VK_SLASH}, 2958 {L':', java_awt_event_KeyEvent_VK_COLON}, 2959 {L';', java_awt_event_KeyEvent_VK_SEMICOLON}, 2960 {L'<', java_awt_event_KeyEvent_VK_LESS}, 2961 {L'=', java_awt_event_KeyEvent_VK_EQUALS}, 2962 {L'>', java_awt_event_KeyEvent_VK_GREATER}, 2963 {L'@', java_awt_event_KeyEvent_VK_AT}, 2964 {L'[', java_awt_event_KeyEvent_VK_OPEN_BRACKET}, 2965 {L'\\', java_awt_event_KeyEvent_VK_BACK_SLASH}, 2966 {L']', java_awt_event_KeyEvent_VK_CLOSE_BRACKET}, 2967 {L'^', java_awt_event_KeyEvent_VK_CIRCUMFLEX}, 2968 {L'_', java_awt_event_KeyEvent_VK_UNDERSCORE}, 2969 {L'`', java_awt_event_KeyEvent_VK_BACK_QUOTE}, 2970 {L'{', java_awt_event_KeyEvent_VK_BRACELEFT}, 2971 {L'}', java_awt_event_KeyEvent_VK_BRACERIGHT}, 2972 {0x00A1, java_awt_event_KeyEvent_VK_INVERTED_EXCLAMATION_MARK}, 2973 {0x20A0, java_awt_event_KeyEvent_VK_EURO_SIGN}, // ???? 2974 {0,0} 2975 }; 2976 2977 // For dead accents some layouts return ASCII punctuation, while some 2978 // return spacing accent chars, so both should be listed. NB: MS docs 2979 // say that conversion routings return spacing accent character, not 2980 // combining. 2981 static const CharToVKEntry charToDeadVKTable[] = { 2982 {L'`', java_awt_event_KeyEvent_VK_DEAD_GRAVE}, 2983 {L'\'', java_awt_event_KeyEvent_VK_DEAD_ACUTE}, 2984 {0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, 2985 {L'^', java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX}, 2986 {L'~', java_awt_event_KeyEvent_VK_DEAD_TILDE}, 2987 {0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE}, 2988 {0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON}, 2989 {0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE}, 2990 {0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT}, 2991 {L'"', java_awt_event_KeyEvent_VK_DEAD_DIAERESIS}, 2992 {0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS}, 2993 {0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING}, 2994 {0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE}, 2995 {0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON}, // aka hacek 2996 {L',', java_awt_event_KeyEvent_VK_DEAD_CEDILLA}, 2997 {0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA}, 2998 {0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK}, 2999 {0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA}, // ASCII ??? 3000 {0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND}, 3001 {0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND}, 3002 {0x0004, java_awt_event_KeyEvent_VK_COMPOSE}, 3003 {0,0} 3004 }; 3005 3006 // The full map of the current keyboard state including 3007 // windows virtual key, scancode, java virtual key, and unicode 3008 // for this key sans modifiers. 3009 // All but first element may be 0. 3010 // XXX in the update releases this is an addition to the unchanged existing code 3011 struct DynPrimaryKeymapEntry { 3012 UINT wkey; 3013 UINT scancode; 3014 UINT jkey; 3015 WCHAR unicode; 3016 }; 3017 3018 static DynPrimaryKeymapEntry dynPrimaryKeymap[256]; 3019 3020 void 3021 AwtComponent::InitDynamicKeyMapTable() 3022 { 3023 static BOOL kbdinited = FALSE; 3024 3025 if (!kbdinited) { 3026 AwtComponent::BuildDynamicKeyMapTable(); 3027 // We cannot build it here since JNI is not available yet: 3028 //AwtComponent::BuildPrimaryDynamicTable(); 3029 kbdinited = TRUE; 3030 } 3031 } 3032 3033 void 3034 AwtComponent::BuildDynamicKeyMapTable() 3035 { 3036 HKL hkl = GetKeyboardLayout(); 3037 3038 DTRACE_PRINTLN2("Building dynamic VK mapping tables: HKL = %08X (CP%d)", 3039 hkl, AwtComponent::GetCodePage()); 3040 3041 // Will need this to reset layout after dead keys. 3042 UINT spaceScanCode = ::MapVirtualKeyEx(VK_SPACE, 0, hkl); 3043 3044 // Entries in dynamic table that maps between Java VK and Windows 3045 // VK are built in three steps: 3046 // 1. Map windows VK to ANSI character (cannot map to unicode 3047 // directly, since ::ToUnicode is not implemented on win9x) 3048 // 2. Convert ANSI char to Unicode char 3049 // 3. Map Unicode char to Java VK via two auxilary tables. 3050 3051 for (DynamicKeyMapEntry *dynamic = dynamicKeyMapTable; 3052 dynamic->windowsKey != 0; 3053 ++dynamic) 3054 { 3055 // Defaults to VK_UNDEFINED 3056 dynamic->javaKey = java_awt_event_KeyEvent_VK_UNDEFINED; 3057 3058 BYTE kbdState[AwtToolkit::KB_STATE_SIZE]; 3059 AwtToolkit::GetKeyboardState(kbdState); 3060 3061 kbdState[dynamic->windowsKey] |= 0x80; // Press the key. 3062 3063 // Unpress modifiers, since they are most likely pressed as 3064 // part of the keyboard switching shortcut. 3065 kbdState[VK_CONTROL] &= ~0x80; 3066 kbdState[VK_SHIFT] &= ~0x80; 3067 kbdState[VK_MENU] &= ~0x80; 3068 3069 char cbuf[2] = { '\0', '\0'}; 3070 UINT scancode = ::MapVirtualKeyEx(dynamic->windowsKey, 0, hkl); 3071 int nchars = ::ToAsciiEx(dynamic->windowsKey, scancode, kbdState, 3072 (WORD*)cbuf, 0, hkl); 3073 3074 // Auxiliary table used to map Unicode character to Java VK. 3075 // Will assign a different table for dead keys (below). 3076 const CharToVKEntry *charMap = charToVKTable; 3077 3078 if (nchars < 0) { // Dead key 3079 // Use a different table for dead chars since different layouts 3080 // return different characters for the same dead key. 3081 charMap = charToDeadVKTable; 3082 3083 // We also need to reset layout so that next translation 3084 // is unaffected by the dead status. We do this by 3085 // translating <SPACE> key. 3086 kbdState[dynamic->windowsKey] &= ~0x80; 3087 kbdState[VK_SPACE] |= 0x80; 3088 3089 char junkbuf[2] = { '\0', '\0'}; 3090 ::ToAsciiEx(VK_SPACE, spaceScanCode, kbdState, 3091 (WORD*)junkbuf, 0, hkl); 3092 } 3093 3094 #ifdef DEBUG 3095 if (nchars == 0) { 3096 DTRACE_PRINTLN1("VK 0x%02X -> cannot convert to ANSI char", 3097 dynamic->windowsKey); 3098 continue; 3099 } 3100 else if (nchars > 1) { // can't happen, see reset code below 3101 DTRACE_PRINTLN3("VK 0x%02X -> converted to <0x%02X,0x%02X>", 3102 dynamic->windowsKey, 3103 (UCHAR)cbuf[0], (UCHAR)cbuf[1]); 3104 continue; 3105 } 3106 #endif 3107 3108 WCHAR ucbuf[2] = { L'\0', L'\0' }; 3109 int nconverted = ::MultiByteToWideChar(AwtComponent::GetCodePage(), 0, 3110 cbuf, 1, ucbuf, 2); 3111 #ifdef DEBUG 3112 if (nconverted < 0) { 3113 DTRACE_PRINTLN3("VK 0x%02X -> ANSI 0x%02X -> MultiByteToWideChar failed (0x%X)", 3114 dynamic->windowsKey, (UCHAR)cbuf[0], 3115 ::GetLastError()); 3116 continue; 3117 } 3118 #endif 3119 3120 WCHAR uc = ucbuf[0]; 3121 for (const CharToVKEntry *map = charMap; map->c != 0; ++map) { 3122 if (uc == map->c) { 3123 dynamic->javaKey = map->javaKey; 3124 break; 3125 } 3126 } 3127 3128 DTRACE_PRINTLN4("VK 0x%02X -> ANSI 0x%02X -> U+%04X -> Java VK 0x%X", 3129 dynamic->windowsKey, (UCHAR)cbuf[0], (UINT)ucbuf[0], 3130 dynamic->javaKey); 3131 } // for each VK_OEM_* 3132 } 3133 3134 3135 static BOOL isKanaLockAvailable() 3136 { 3137 // This method is to determine whether the Kana Lock feature is 3138 // available on the attached keyboard. Kana Lock feature does not 3139 // necessarily require that the real KANA keytop is available on 3140 // keyboard, so using MapVirtualKey(VK_KANA) is not sufficient for testing. 3141 // Instead of that we regard it as Japanese keyboard (w/ Kana Lock) if :- 3142 // 3143 // - the keyboard layout is Japanese (VK_KANA has the same value as VK_HANGUL) 3144 // - the keyboard is Japanese keyboard (keyboard type == 7). 3145 return (LOWORD(GetKeyboardLayout(0)) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) 3146 && (GetKeyboardType(0) == 7); 3147 } 3148 3149 void AwtComponent::JavaKeyToWindowsKey(UINT javaKey, 3150 UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey) 3151 { 3152 // Handle the few cases where a Java VK code corresponds to a Windows 3153 // key/modifier combination or applies only to specific keyboard layouts 3154 switch (javaKey) { 3155 case java_awt_event_KeyEvent_VK_ALL_CANDIDATES: 3156 *windowsKey = VK_CONVERT; 3157 *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK; 3158 return; 3159 case java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE: 3160 *windowsKey = VK_CONVERT; 3161 *modifiers = java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3162 return; 3163 case java_awt_event_KeyEvent_VK_CODE_INPUT: 3164 *windowsKey = VK_DBE_ALPHANUMERIC; 3165 *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK; 3166 return; 3167 case java_awt_event_KeyEvent_VK_KANA_LOCK: 3168 if (isKanaLockAvailable()) { 3169 *windowsKey = VK_KANA; 3170 *modifiers = java_awt_event_InputEvent_CTRL_DOWN_MASK; 3171 return; 3172 } 3173 } 3174 3175 // for the general case, use a bi-directional table 3176 for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { 3177 if (keyMapTable[i].javaKey == javaKey) { 3178 *windowsKey = keyMapTable[i].windowsKey; 3179 *modifiers = 0; 3180 return; 3181 } 3182 } 3183 3184 // Bug 4766655 3185 // Two Windows keys could map to the same Java key, so 3186 // give preference to the originalWindowsKey if it is 3187 // specified (not IGNORE_KEY). 3188 if (originalWindowsKey == IGNORE_KEY) { 3189 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3190 if (dynamicKeyMapTable[j].javaKey == javaKey) { 3191 *windowsKey = dynamicKeyMapTable[j].windowsKey; 3192 *modifiers = 0; 3193 return; 3194 } 3195 } 3196 } else { 3197 BOOL found = false; 3198 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3199 if (dynamicKeyMapTable[j].javaKey == javaKey) { 3200 *windowsKey = dynamicKeyMapTable[j].windowsKey; 3201 *modifiers = 0; 3202 found = true; 3203 if (*windowsKey == originalWindowsKey) { 3204 return; /* if ideal case found return, else keep looking */ 3205 } 3206 } 3207 } 3208 if (found) { 3209 return; 3210 } 3211 } 3212 3213 *windowsKey = 0; 3214 *modifiers = 0; 3215 return; 3216 } 3217 3218 UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey) 3219 3220 { 3221 // Handle the few cases where we need to take the modifier into 3222 // consideration for the Java VK code or where we have to take the keyboard 3223 // layout into consideration so that function keys can get 3224 // recognized in a platform-independent way. 3225 switch (windowsKey) { 3226 case VK_CONVERT: 3227 if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) { 3228 return java_awt_event_KeyEvent_VK_ALL_CANDIDATES; 3229 } 3230 if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) { 3231 return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE; 3232 } 3233 break; 3234 case VK_DBE_ALPHANUMERIC: 3235 if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) { 3236 return java_awt_event_KeyEvent_VK_CODE_INPUT; 3237 } 3238 break; 3239 case VK_KANA: 3240 if (isKanaLockAvailable()) { 3241 return java_awt_event_KeyEvent_VK_KANA_LOCK; 3242 } 3243 break; 3244 }; 3245 3246 // check dead key 3247 if (isDeadKey) { 3248 for (int i = 0; charToDeadVKTable[i].c != 0; i++) { 3249 if (charToDeadVKTable[i].c == character) { 3250 return charToDeadVKTable[i].javaKey; 3251 } 3252 } 3253 } 3254 3255 // for the general case, use a bi-directional table 3256 for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { 3257 if (keyMapTable[i].windowsKey == windowsKey) { 3258 return keyMapTable[i].javaKey; 3259 } 3260 } 3261 3262 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3263 if (dynamicKeyMapTable[j].windowsKey == windowsKey) { 3264 if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) { 3265 return dynamicKeyMapTable[j].javaKey; 3266 }else{ 3267 break; 3268 } 3269 } 3270 } 3271 3272 return java_awt_event_KeyEvent_VK_UNDEFINED; 3273 } 3274 3275 BOOL AwtComponent::IsNavigationKey(UINT wkey) { 3276 switch (wkey) { 3277 case VK_END: 3278 case VK_PRIOR: // PageUp 3279 case VK_NEXT: // PageDown 3280 case VK_HOME: 3281 case VK_LEFT: 3282 case VK_UP: 3283 case VK_RIGHT: 3284 case VK_DOWN: 3285 return TRUE; 3286 } 3287 return FALSE; 3288 } 3289 3290 // determine if a key is a numpad key (distinguishes the numpad 3291 // arrow keys from the non-numpad arrow keys, for example). 3292 BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended) 3293 { 3294 // Note: scancodes are the same for the numpad arrow keys and 3295 // the non-numpad arrow keys (also for PageUp, etc.). 3296 // The scancodes for the numpad divide and the non-numpad slash 3297 // are the same, but the wparams are different 3298 3299 DTRACE_PRINTLN3("AwtComponent::IsNumPadKey vkey = %d = 0x%x extended = %d", 3300 vkey, vkey, extended); 3301 3302 switch (vkey) { 3303 case VK_CLEAR: // numpad 5 with numlock off 3304 case VK_NUMPAD0: 3305 case VK_NUMPAD1: 3306 case VK_NUMPAD2: 3307 case VK_NUMPAD3: 3308 case VK_NUMPAD4: 3309 case VK_NUMPAD5: 3310 case VK_NUMPAD6: 3311 case VK_NUMPAD7: 3312 case VK_NUMPAD8: 3313 case VK_NUMPAD9: 3314 case VK_MULTIPLY: 3315 case VK_ADD: 3316 case VK_SEPARATOR: // numpad , not on US kbds 3317 case VK_SUBTRACT: 3318 case VK_DECIMAL: 3319 case VK_DIVIDE: 3320 case VK_NUMLOCK: 3321 return TRUE; 3322 break; 3323 case VK_END: 3324 case VK_PRIOR: // PageUp 3325 case VK_NEXT: // PageDown 3326 case VK_HOME: 3327 case VK_LEFT: 3328 case VK_UP: 3329 case VK_RIGHT: 3330 case VK_DOWN: 3331 case VK_INSERT: 3332 case VK_DELETE: 3333 // extended if non-numpad 3334 return (!extended); 3335 break; 3336 case VK_RETURN: // extended if on numpad 3337 return (extended); 3338 break; 3339 default: 3340 break; 3341 } 3342 3343 return FALSE; 3344 } 3345 static void 3346 resetKbdState( BYTE kstate[256]) { 3347 BYTE tmpState[256]; 3348 WCHAR wc[2]; 3349 memmove(tmpState, kstate, sizeof(kstate)); 3350 tmpState[VK_SHIFT] = 0; 3351 tmpState[VK_CONTROL] = 0; 3352 tmpState[VK_MENU] = 0; 3353 3354 ::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0, GetKeyboardLayout(0)); 3355 } 3356 3357 // XXX in the update releases this is an addition to the unchanged existing code 3358 // After the call, a table will have a unicode associated with a windows virtual keycode 3359 // sans modifiers. With some further simplification, one can 3360 // derive java keycode from it, and anyway we will pass this unicode value 3361 // all the way up in a comment to a KeyEvent. 3362 void 3363 AwtComponent::BuildPrimaryDynamicTable() { 3364 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3365 // XXX: how about that? 3366 //CriticalSection::Lock l(GetLock()); 3367 //if (GetPeer(env) == NULL) { 3368 // /* event received during termination. */ 3369 // return; 3370 //} 3371 3372 HKL hkl = GetKeyboardLayout(); 3373 UINT sc = 0; 3374 BYTE kbdState[AwtToolkit::KB_STATE_SIZE]; 3375 memset(kbdState, 0, sizeof (kbdState)); 3376 3377 // Use JNI call to obtain java key code. We should keep a list 3378 // of currently available keycodes in a single place. 3379 static jclass extKeyCodesCls; 3380 if( extKeyCodesCls == NULL) { 3381 jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes"); 3382 DASSERT(extKeyCodesClsLocal); 3383 CHECK_NULL(extKeyCodesClsLocal); 3384 extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal); 3385 env->DeleteLocalRef(extKeyCodesClsLocal); 3386 } 3387 static jmethodID getExtendedKeyCodeForChar; 3388 if (getExtendedKeyCodeForChar == NULL) { 3389 getExtendedKeyCodeForChar = 3390 env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I"); 3391 DASSERT(getExtendedKeyCodeForChar); 3392 CHECK_NULL(getExtendedKeyCodeForChar); 3393 } 3394 jint extJKC; //extended Java key code 3395 3396 for (UINT i = 0; i < 256; i++) { 3397 dynPrimaryKeymap[i].wkey = i; 3398 dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED; 3399 dynPrimaryKeymap[i].unicode = 0; 3400 3401 if ((sc = MapVirtualKey (i, 0)) == 0) { 3402 dynPrimaryKeymap[i].scancode = 0; 3403 continue; 3404 } 3405 dynPrimaryKeymap[i].scancode = sc; 3406 3407 // XXX process cases like VK_SHIFT etc. 3408 kbdState[i] = 0x80; // "key pressed". 3409 WCHAR wc[16]; 3410 int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl); 3411 if (k == 1) { 3412 // unicode 3413 dynPrimaryKeymap[i].unicode = wc[0]; 3414 if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3415 // Convert unicode to java keycode. 3416 //dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000); 3417 // 3418 //XXX If this key in on the keypad, we should force a special value equal to 3419 //XXX an old java keycode: but how to say if it is a keypad key? 3420 //XXX We'll do it in WmKeyUp/Down. 3421 extJKC = env->CallStaticIntMethod(extKeyCodesCls, 3422 getExtendedKeyCodeForChar, (jint)(wc[0])); 3423 dynPrimaryKeymap[i].jkey = extJKC; 3424 } 3425 }else if (k == -1) { 3426 // dead key: use charToDeadVKTable 3427 dynPrimaryKeymap[i].unicode = wc[0]; 3428 resetKbdState( kbdState ); 3429 for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) { 3430 if (wc[0] == map->c) { 3431 dynPrimaryKeymap[i].jkey = map->javaKey; 3432 break; 3433 } 3434 } 3435 } else if (k == 0) { 3436 // reset 3437 resetKbdState( kbdState ); 3438 }else { 3439 // k > 1: this key does generate multiple characters. Ignore it. 3440 // An example: Arabic Lam and Alef ligature. 3441 // There will be no extended keycode and thus shortcuts for this key. 3442 // XXX shouldn't we reset the kbd state? 3443 #ifdef DEBUG 3444 DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i); 3445 #endif 3446 } 3447 kbdState[i] = 0; // "key unpressed" 3448 } 3449 } 3450 void 3451 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers) 3452 { 3453 if( wkey && wkey < 256 ) { 3454 if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) { 3455 // At the creation time, 3456 // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /" 3457 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3458 } 3459 if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3460 // E.g. it is non-unicode key 3461 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3462 } 3463 } 3464 } 3465 3466 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey) 3467 { 3468 static Hashtable transTable("VKEY translations"); 3469 static Hashtable deadKeyFlagTable("Dead Key Flags"); 3470 isDeadKey = FALSE; 3471 3472 // Try to translate using last saved translation 3473 if (ops == LOAD) { 3474 void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3475 void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3476 if (value != NULL) { 3477 isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag)); 3478 return static_cast<UINT>(reinterpret_cast<INT_PTR>(value)); 3479 } 3480 } 3481 3482 // If the windows key is a return, wkey will equal 13 ('\r') 3483 // In this case, we want to return 10 ('\n') 3484 // Since ToAscii would convert VK_RETURN to '\r', we need 3485 // to have a special case here. 3486 if (wkey == VK_RETURN) 3487 return '\n'; 3488 3489 // high order bit in keyboardState indicates whether the key is down 3490 static const BYTE KEY_STATE_DOWN = 0x80; 3491 BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 3492 AwtToolkit::GetKeyboardState(keyboardState); 3493 3494 // apply modifiers to keyboard state if necessary 3495 BOOL shiftIsDown = FALSE; 3496 if (modifiers) { 3497 shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3498 BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK; 3499 BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK; 3500 3501 // Windows treats AltGr as Ctrl+Alt 3502 if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) { 3503 altIsDown = TRUE; 3504 ctrlIsDown = TRUE; 3505 } 3506 3507 if (shiftIsDown) { 3508 keyboardState[VK_SHIFT] |= KEY_STATE_DOWN; 3509 } 3510 3511 // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715) 3512 // Here we try to resolve a conflict with ::ToAsciiEx's translating 3513 // ALT+number key combinations. kdm@sarc.spb.su 3514 // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail. 3515 if( IsNavigationKey(wkey) ) { 3516 keyboardState[VK_MENU] &= ~KEY_STATE_DOWN; 3517 } 3518 3519 if (ctrlIsDown) 3520 { 3521 if (altIsDown) { 3522 // bugid 4215009: don't mess with AltGr == Ctrl + Alt 3523 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3524 } 3525 else { 3526 // bugid 4098210: old event model doesn't have KEY_TYPED 3527 // events, so try to provide a meaningful character for 3528 // Ctrl+<key>. Take Ctrl into account only when we know 3529 // that Ctrl+<key> will be an ASCII control. Ignore by 3530 // default. 3531 keyboardState[VK_CONTROL] &= ~KEY_STATE_DOWN; 3532 3533 // Letters have Ctrl+<letter> counterparts. According to 3534 // <winuser.h> VK_A through VK_Z are the same as ASCII 3535 // 'A' through 'Z'. 3536 if (wkey >= 'A' && wkey <= 'Z') { 3537 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3538 } 3539 else { 3540 // Non-letter controls 033 to 037 are: 3541 // ^[ (ESC), ^\ (FS), ^] (GS), ^^ (RS), and ^_ (US) 3542 3543 // Shift state bits returned by ::VkKeyScan in HIBYTE 3544 static const UINT _VKS_SHIFT_MASK = 0x01; 3545 static const UINT _VKS_CTRL_MASK = 0x02; 3546 static const UINT _VKS_ALT_MASK = 0x04; 3547 3548 // Check to see whether there is a meaningful translation 3549 TCHAR ch; 3550 short vk; 3551 for (ch = _T('\033'); ch < _T('\040'); ch++) { 3552 vk = ::VkKeyScan(ch); 3553 if (wkey == LOBYTE(vk)) { 3554 UINT shiftState = HIBYTE(vk); 3555 if ((shiftState & _VKS_CTRL_MASK) || 3556 (!(shiftState & _VKS_SHIFT_MASK) 3557 == !shiftIsDown)) 3558 { 3559 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3560 } 3561 break; 3562 } 3563 } 3564 } 3565 } // ctrlIsDown && altIsDown 3566 } // ctrlIsDown 3567 } // modifiers 3568 3569 WORD wChar[2]; 3570 int converted = 1; 3571 UINT ch = ::MapVirtualKeyEx(wkey, 2, GetKeyboardLayout()); 3572 if (ch & 0x80000000) { 3573 // Dead key which is handled as a normal key 3574 isDeadKey = deadKeyActive = TRUE; 3575 } else if (deadKeyActive) { 3576 // We cannot use ::ToUnicodeEx if dead key is active because this will 3577 // break dead key function 3578 wChar[0] = shiftIsDown ? ch : tolower(ch); 3579 } else { 3580 UINT scancode = ::MapVirtualKey(wkey, 0); 3581 converted = ::ToUnicodeEx(wkey, scancode, keyboardState, 3582 wChar, 2, 0, GetKeyboardLayout()); 3583 } 3584 3585 UINT translation; 3586 BOOL deadKeyFlag = (converted == 2); 3587 3588 // Dead Key 3589 if (converted < 0 || isDeadKey) { 3590 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3591 } else 3592 // No translation available -- try known conversions or else punt. 3593 if (converted == 0) { 3594 if (wkey == VK_DELETE) { 3595 translation = '\177'; 3596 } else 3597 if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) { 3598 translation = '0' + wkey - VK_NUMPAD0; 3599 } else { 3600 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3601 } 3602 } else 3603 // the caller expects a Unicode character. 3604 if (converted > 0) { 3605 translation = wChar[0]; 3606 } 3607 if (ops == SAVE) { 3608 transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3609 reinterpret_cast<void*>(static_cast<INT_PTR>(translation))); 3610 if (deadKeyFlag) { 3611 deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3612 reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag))); 3613 } else { 3614 deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3615 } 3616 } 3617 3618 isDeadKey = deadKeyFlag; 3619 return translation; 3620 } 3621 3622 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 3623 UINT flags, BOOL system) 3624 { 3625 // VK_PROCESSKEY is a special value which means 3626 // "Current IME wants to consume this KeyEvent" 3627 // Real key code is saved by IMM32.DLL and can be retrieved by 3628 // calling ImmGetVirtualKey(); 3629 if (wkey == VK_PROCESSKEY) { 3630 return mrDoDefault; 3631 } 3632 MSG msg; 3633 InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN), 3634 wkey, MAKELPARAM(repCnt, flags)); 3635 3636 UINT modifiers = GetJavaModifiers(); 3637 jint keyLocation = GetKeyLocation(wkey, flags); 3638 BOOL isDeadKey = FALSE; 3639 UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey); 3640 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3641 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3642 3643 3644 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED, 3645 TimeHelper::getMessageTimeUTC(), jkey, character, 3646 modifiers, keyLocation, (jlong)wkey, &msg); 3647 3648 // bugid 4724007: Windows does not create a WM_CHAR for the Del key 3649 // for some reason, so we need to create the KEY_TYPED event on the 3650 // WM_KEYDOWN. Use null msg so the character doesn't get sent back 3651 // to the native window for processing (this event is synthesized 3652 // for Java - we don't want Windows trying to process it). 3653 if (jkey == java_awt_event_KeyEvent_VK_DELETE) { 3654 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3655 TimeHelper::getMessageTimeUTC(), 3656 java_awt_event_KeyEvent_VK_UNDEFINED, 3657 character, modifiers, 3658 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0); 3659 } 3660 3661 return mrConsume; 3662 } 3663 3664 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt, 3665 UINT flags, BOOL system) 3666 { 3667 3668 // VK_PROCESSKEY is a special value which means 3669 // "Current IME wants to consume this KeyEvent" 3670 // Real key code is saved by IMM32.DLL and can be retrieved by 3671 // calling ImmGetVirtualKey(); 3672 if (wkey == VK_PROCESSKEY) { 3673 return mrDoDefault; 3674 } 3675 MSG msg; 3676 InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP), 3677 wkey, MAKELPARAM(repCnt, flags)); 3678 3679 UINT modifiers = GetJavaModifiers(); 3680 jint keyLocation = GetKeyLocation(wkey, flags); 3681 BOOL isDeadKey = FALSE; 3682 UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey); 3683 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3684 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3685 3686 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED, 3687 TimeHelper::getMessageTimeUTC(), jkey, character, 3688 modifiers, keyLocation, (jlong)wkey, &msg); 3689 return mrConsume; 3690 } 3691 3692 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout) 3693 { 3694 // Normally we would be able to use charset and TranslateCharSetInfo 3695 // to get a code page that should be associated with this keyboard 3696 // layout change. However, there seems to be an NT 4.0 bug associated 3697 // with the WM_INPUTLANGCHANGE message, which makes the charset parameter 3698 // unreliable, especially on Asian systems. Our workaround uses the 3699 // keyboard layout handle instead. 3700 m_hkl = hKeyboardLayout; 3701 m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID 3702 m_CodePage = LangToCodePage(m_idLang); 3703 BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM 3704 BuildPrimaryDynamicTable(); 3705 return mrConsume; // do not propagate to children 3706 } 3707 3708 // Convert Language ID to CodePage 3709 UINT AwtComponent::LangToCodePage(LANGID idLang) 3710 { 3711 TCHAR strCodePage[MAX_ACP_STR_LEN]; 3712 // use the LANGID to create a LCID 3713 LCID idLocale = MAKELCID(idLang, SORT_DEFAULT); 3714 // get the ANSI code page associated with this locale 3715 if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE, strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 ) 3716 return _ttoi(strCodePage); 3717 else 3718 return GetACP(); 3719 } 3720 3721 3722 MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL system) 3723 { 3724 // We will simply create Java events here. 3725 WCHAR unicodeChar = character; 3726 MSG msg; 3727 InitMessage(&msg, WM_IME_CHAR, character, 3728 MAKELPARAM(repCnt, flags)); 3729 3730 jint modifiers = GetJavaModifiers(); 3731 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3732 TimeHelper::getMessageTimeUTC(), 3733 java_awt_event_KeyEvent_VK_UNDEFINED, 3734 unicodeChar, modifiers, 3735 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3736 &msg); 3737 return mrConsume; 3738 } 3739 3740 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags, 3741 BOOL system) 3742 { 3743 deadKeyActive = FALSE; 3744 3745 // Will only get WmChar messages with DBCS if we create them for 3746 // an Edit class in the WmForwardChar method. These synthesized 3747 // DBCS chars are ok to pass on directly to the default window 3748 // procedure. They've already been filtered through the Java key 3749 // event queue. We will never get the trail byte since the edit 3750 // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR, 3751 // PM_REMOVE). I would like to be able to pass this character off 3752 // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to 3753 // like that. 3754 3755 // We will simply create Java events here. 3756 UINT message = system ? WM_SYSCHAR : WM_CHAR; 3757 3758 // The Alt modifier is reported in the 29th bit of the lParam, 3759 // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)). 3760 bool alt_is_down = (flags & (1<<13)) != 0; 3761 3762 // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu 3763 // We should not pass this particular combination to Java. 3764 3765 if (system && alt_is_down) { 3766 if (character == VK_SPACE) { 3767 return mrDoDefault; 3768 } 3769 } 3770 3771 // If this is a WM_CHAR (non-system) message, then the Alt flag 3772 // indicates that the character was typed using an AltGr key 3773 // (which Windows treats as Ctrl+Alt), so in this case we do NOT 3774 // pass the Ctrl and Alt modifiers to Java, but instead we 3775 // replace them with Java's AltGraph modifier. Note: the AltGraph 3776 // modifier does not exist in 1.1.x releases. 3777 jint modifiers = GetJavaModifiers(); 3778 if (!system && alt_is_down) { 3779 // character typed with AltGraph 3780 modifiers &= ~(java_awt_event_InputEvent_ALT_DOWN_MASK 3781 | java_awt_event_InputEvent_CTRL_DOWN_MASK); 3782 modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK; 3783 } 3784 3785 WCHAR unicodeChar = character; 3786 3787 // Kludge: Combine pending single byte with this char for some Chinese IMEs 3788 if (m_PendingLeadByte != 0) { 3789 character = (m_PendingLeadByte & 0x00ff) | (character << 8); 3790 m_PendingLeadByte = 0; 3791 ::MultiByteToWideChar(GetCodePage(), 0, (CHAR*)&character, 2, 3792 &unicodeChar, 1); 3793 } 3794 3795 if (unicodeChar == VK_RETURN) { 3796 // Enter key generates \r in windows, but \n is required in java 3797 unicodeChar = java_awt_event_KeyEvent_VK_ENTER; 3798 } 3799 MSG msg; 3800 InitMessage(&msg, message, character, 3801 MAKELPARAM(repCnt, flags)); 3802 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3803 TimeHelper::getMessageTimeUTC(), 3804 java_awt_event_KeyEvent_VK_UNDEFINED, 3805 unicodeChar, modifiers, 3806 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3807 &msg); 3808 return mrConsume; 3809 } 3810 3811 MsgRouting AwtComponent::WmForwardChar(WCHAR character, LPARAM lParam, 3812 BOOL synthetic) 3813 { 3814 // just post WM_CHAR with unicode key value 3815 DefWindowProc(WM_CHAR, (WPARAM)character, lParam); 3816 return mrConsume; 3817 } 3818 3819 MsgRouting AwtComponent::WmPaste() 3820 { 3821 return mrDoDefault; 3822 } 3823 3824 // support IME Composition messages 3825 void AwtComponent::SetCompositionWindow(RECT& r) 3826 { 3827 HWND hwnd = ImmGetHWnd(); 3828 HIMC hIMC = ImmGetContext(hwnd); 3829 if (hIMC == NULL) { 3830 return; 3831 } 3832 COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}}; 3833 ImmSetCompositionWindow(hIMC, &cf); 3834 ImmReleaseContext(hwnd, hIMC); 3835 } 3836 3837 void AwtComponent::OpenCandidateWindow(int x, int y) 3838 { 3839 UINT bits = 1; 3840 POINT p = {0, 0}; // upper left corner of the client area 3841 HWND hWnd = GetHWnd(); 3842 HWND hTop = GetTopLevelParentForWindow(hWnd); 3843 ::ClientToScreen(hTop, &p); 3844 if (!m_bitsCandType) { 3845 SetCandidateWindow(m_bitsCandType, x - p.x, y - p.y); 3846 return; 3847 } 3848 for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) { 3849 if ( m_bitsCandType & bits ) 3850 SetCandidateWindow(iCandType, x - p.x, y - p.y); 3851 } 3852 } 3853 3854 void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) 3855 { 3856 HWND hwnd = ImmGetHWnd(); 3857 HIMC hIMC = ImmGetContext(hwnd); 3858 if (hIMC) { 3859 CANDIDATEFORM cf; 3860 cf.dwStyle = CFS_POINT; 3861 ImmGetCandidateWindow(hIMC, 0, &cf); 3862 if (x != cf.ptCurrentPos.x || y != cf.ptCurrentPos.y) { 3863 cf.dwIndex = iCandType; 3864 cf.dwStyle = CFS_POINT; 3865 cf.ptCurrentPos.x = x; 3866 cf.ptCurrentPos.y = y; 3867 cf.rcArea.left = cf.rcArea.top = cf.rcArea.right = cf.rcArea.bottom = 0; 3868 ImmSetCandidateWindow(hIMC, &cf); 3869 } 3870 COMPOSITIONFORM cfr; 3871 cfr.dwStyle = CFS_POINT; 3872 ImmGetCompositionWindow(hIMC, &cfr); 3873 if (x != cfr.ptCurrentPos.x || y != cfr.ptCurrentPos.y) { 3874 cfr.dwStyle = CFS_POINT; 3875 cfr.ptCurrentPos.x = x; 3876 cfr.ptCurrentPos.y = y; 3877 cf.rcArea.left = cf.rcArea.top = cf.rcArea.right = cf.rcArea.bottom = 0; 3878 ImmSetCompositionWindow(hIMC, &cfr); 3879 } 3880 ImmReleaseContext(hwnd, hIMC); 3881 } 3882 } 3883 3884 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) 3885 { 3886 // If the Windows input context is disabled, do not let Windows 3887 // display any UIs. 3888 HWND hwnd = ImmGetHWnd(); 3889 HIMC hIMC = ImmGetContext(hwnd); 3890 if (hIMC == NULL) { 3891 *lplParam = 0; 3892 return mrDoDefault; 3893 } 3894 ImmReleaseContext(hwnd, hIMC); 3895 3896 if (fSet) { 3897 LPARAM lParam = *lplParam; 3898 if (!m_useNativeCompWindow) { 3899 // stop to draw native composing window. 3900 *lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW; 3901 } 3902 } 3903 return mrDoDefault; 3904 } 3905 3906 MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType) 3907 { 3908 if (!m_useNativeCompWindow) { 3909 if (subMsg == IMN_OPENCANDIDATE || subMsg == IMN_CHANGECANDIDATE) { 3910 m_bitsCandType = bitsCandType; 3911 InquireCandidatePosition(); 3912 } else if (subMsg == IMN_OPENSTATUSWINDOW || 3913 subMsg == WM_IME_STARTCOMPOSITION || 3914 subMsg == IMN_SETCANDIDATEPOS) { 3915 InquireCandidatePosition(); 3916 } 3917 } 3918 return mrDoDefault; 3919 } 3920 3921 MsgRouting AwtComponent::WmImeStartComposition() 3922 { 3923 if (m_useNativeCompWindow) { 3924 RECT rc; 3925 ::GetClientRect(GetHWnd(), &rc); 3926 SetCompositionWindow(rc); 3927 return mrDoDefault; 3928 } else 3929 return mrConsume; 3930 } 3931 3932 MsgRouting AwtComponent::WmImeEndComposition() 3933 { 3934 if (m_useNativeCompWindow) return mrDoDefault; 3935 3936 SendInputMethodEvent( 3937 java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3938 NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 ); 3939 return mrConsume; 3940 } 3941 3942 MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags) 3943 { 3944 if (m_useNativeCompWindow) return mrDoDefault; 3945 3946 int* bndClauseW = NULL; 3947 jstring* readingClauseW = NULL; 3948 int* bndAttrW = NULL; 3949 BYTE* valAttrW = NULL; 3950 int cClauseW = 0; 3951 AwtInputTextInfor* textInfor = NULL; 3952 3953 try { 3954 HWND hwnd = ImmGetHWnd(); 3955 HIMC hIMC = ImmGetContext(hwnd); 3956 DASSERT(hIMC!=0); 3957 3958 textInfor = new AwtInputTextInfor; 3959 textInfor->GetContextData(hIMC, flags); 3960 ImmReleaseContext(hwnd, hIMC); 3961 3962 jstring jtextString = textInfor->GetText(); 3963 /* The conditions to send the input method event to AWT EDT are: 3964 1. Whenever there is a composition message sent regarding whether 3965 the composition text is NULL or not. See details at bug 6222692. 3966 2. When there is a committed message sent, in which case, we have to 3967 check whether the committed string is NULL or not. If the committed string 3968 is NULL, there is no need to send any input method event. 3969 (Minor note: 'jtextString' returned is the merged string in the case of 3970 partial commit.) 3971 */ 3972 if ((flags & GCS_RESULTSTR && jtextString != NULL) || 3973 (flags & GCS_COMPSTR)) { 3974 int cursorPosW = textInfor->GetCursorPosition(); 3975 // In order not to delete the readingClauseW in the catch clause, 3976 // calling GetAttributeInfor before GetClauseInfor. 3977 int cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW); 3978 cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW); 3979 3980 /* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends 3981 the event to AWT EDT. 3982 3983 The last two paremeters are set to equal since we don't have recommendations for 3984 the visible position within the current composed text. See details at 3985 java.awt.event.InputMethodEvent. 3986 */ 3987 SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3988 jtextString, 3989 cClauseW, bndClauseW, readingClauseW, 3990 cAttrW, bndAttrW, valAttrW, 3991 textInfor->GetCommittedTextLength(), 3992 cursorPosW, cursorPosW); 3993 } 3994 } catch (...) { 3995 // since GetClauseInfor and GetAttributeInfor could throw exception, we have to release 3996 // the pointer here. 3997 delete [] bndClauseW; 3998 delete [] readingClauseW; 3999 delete [] bndAttrW; 4000 delete [] valAttrW; 4001 throw; 4002 } 4003 4004 /* Free the storage allocated. Since jtextString won't be passed from threads 4005 * to threads, we just use the local ref and it will be deleted within the destructor 4006 * of AwtInputTextInfor object. 4007 */ 4008 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4009 if (cClauseW && readingClauseW) { 4010 for (int i = 0; i < cClauseW; i ++) { 4011 if (readingClauseW[i]) { 4012 env->DeleteLocalRef(readingClauseW[i]); 4013 } 4014 } 4015 } 4016 delete [] bndClauseW; 4017 delete [] readingClauseW; 4018 delete [] bndAttrW; 4019 delete [] valAttrW; 4020 delete textInfor; 4021 4022 return mrConsume; 4023 } 4024 4025 // 4026 // generate and post InputMethodEvent 4027 // 4028 void AwtComponent::SendInputMethodEvent(jint id, jstring text, 4029 int cClause, int* rgClauseBoundary, jstring* rgClauseReading, 4030 int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue, 4031 int commitedTextLength, int caretPos, int visiblePos) 4032 { 4033 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4034 4035 // assumption for array type casting 4036 DASSERT(sizeof(int)==sizeof(jint)); 4037 DASSERT(sizeof(BYTE)==sizeof(jbyte)); 4038 4039 // caluse information 4040 jintArray clauseBoundary = NULL; 4041 jobjectArray clauseReading = NULL; 4042 if (cClause && rgClauseBoundary && rgClauseReading) { 4043 // convert clause boundary offset array to java array 4044 clauseBoundary = env->NewIntArray(cClause+1); 4045 DASSERT(clauseBoundary); 4046 CHECK_NULL(clauseBoundary); 4047 env->SetIntArrayRegion(clauseBoundary, 0, cClause+1, (jint *)rgClauseBoundary); 4048 DASSERT(!safe_ExceptionOccurred(env)); 4049 4050 // convert clause reading string array to java array 4051 jclass stringCls = JNU_ClassString(env); 4052 DASSERT(stringCls); 4053 CHECK_NULL(stringCls); 4054 clauseReading = env->NewObjectArray(cClause, stringCls, NULL); 4055 DASSERT(clauseReading); 4056 CHECK_NULL(clauseReading); 4057 for (int i=0; i<cClause; i++) env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]); 4058 DASSERT(!safe_ExceptionOccurred(env)); 4059 } 4060 4061 4062 // attrubute value definition in WInputMethod.java must be equal to that in IMM.H 4063 DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT); 4064 DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED); 4065 DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED); 4066 DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED); 4067 DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR); 4068 4069 // attribute information 4070 jintArray attrBoundary = NULL; 4071 jbyteArray attrValue = NULL; 4072 if (cAttrBlock && rgAttrBoundary && rgAttrValue) { 4073 // convert attribute boundary offset array to java array 4074 attrBoundary = env->NewIntArray(cAttrBlock+1); 4075 DASSERT(attrBoundary); 4076 CHECK_NULL(attrBoundary); 4077 env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary); 4078 DASSERT(!safe_ExceptionOccurred(env)); 4079 4080 // convert attribute value byte array to java array 4081 attrValue = env->NewByteArray(cAttrBlock); 4082 DASSERT(attrValue); 4083 CHECK_NULL(attrValue); 4084 env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue); 4085 DASSERT(!safe_ExceptionOccurred(env)); 4086 } 4087 4088 4089 // get global reference of WInputMethod class (run only once) 4090 static jclass wInputMethodCls = NULL; 4091 if (wInputMethodCls == NULL) { 4092 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4093 DASSERT(wInputMethodClsLocal); 4094 CHECK_NULL(wInputMethodClsLocal); 4095 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4096 env->DeleteLocalRef(wInputMethodClsLocal); 4097 } 4098 4099 // get method ID of sendInputMethodEvent() (run only once) 4100 static jmethodID sendIMEventMid = 0; 4101 if (sendIMEventMid == 0) { 4102 sendIMEventMid = env->GetMethodID(wInputMethodCls, "sendInputMethodEvent", 4103 "(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V"); 4104 DASSERT(sendIMEventMid); 4105 CHECK_NULL(sendIMEventMid); 4106 } 4107 4108 // call m_InputMethod.sendInputMethod() 4109 env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, TimeHelper::getMessageTimeUTC(), 4110 text, clauseBoundary, clauseReading, attrBoundary, 4111 attrValue, commitedTextLength, caretPos, visiblePos); 4112 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4113 DASSERT(!safe_ExceptionOccurred(env)); 4114 4115 } 4116 4117 4118 4119 // 4120 // Inquires candidate position according to the composed text 4121 // 4122 void AwtComponent::InquireCandidatePosition() 4123 { 4124 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4125 4126 // get global reference of WInputMethod class (run only once) 4127 static jclass wInputMethodCls = NULL; 4128 if (wInputMethodCls == NULL) { 4129 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4130 DASSERT(wInputMethodClsLocal); 4131 CHECK_NULL(wInputMethodClsLocal); 4132 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4133 env->DeleteLocalRef(wInputMethodClsLocal); 4134 } 4135 4136 // get method ID of sendInputMethodEvent() (run only once) 4137 static jmethodID inqCandPosMid = 0; 4138 if (inqCandPosMid == 0) { 4139 inqCandPosMid = env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", "()V"); 4140 DASSERT(!safe_ExceptionOccurred(env)); 4141 DASSERT(inqCandPosMid); 4142 CHECK_NULL(inqCandPosMid); 4143 } 4144 4145 // call m_InputMethod.sendInputMethod() 4146 jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid); 4147 DASSERT(!safe_ExceptionOccurred(env)); 4148 } 4149 4150 HWND AwtComponent::ImmGetHWnd() 4151 { 4152 HWND proxy = GetProxyFocusOwner(); 4153 return (proxy != NULL) ? proxy : GetHWnd(); 4154 } 4155 4156 HIMC AwtComponent::ImmAssociateContext(HIMC himc) 4157 { 4158 return ::ImmAssociateContext(ImmGetHWnd(), himc); 4159 } 4160 4161 HWND AwtComponent::GetProxyFocusOwner() 4162 { 4163 AwtWindow *window = GetContainer(); 4164 if (window != 0) { 4165 AwtFrame *owner = window->GetOwningFrameOrDialog(); 4166 if (owner != 0) { 4167 return owner->GetProxyFocusOwner(); 4168 } else if (!window->IsSimpleWindow()) { // isn't an owned simple window 4169 return ((AwtFrame*)window)->GetProxyFocusOwner(); 4170 } 4171 } 4172 return (HWND)NULL; 4173 } 4174 4175 /* Redirects message to the focus proxy, if any */ 4176 void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, 4177 LPARAM lParam, LRESULT &retVal, MsgRouting &mr) 4178 { 4179 if (mr != mrConsume) { 4180 HWND proxy = GetProxyFocusOwner(); 4181 if (proxy != NULL && ::IsWindowEnabled(proxy)) { 4182 retVal = ::DefWindowProc(proxy, message, wParam, lParam); 4183 mr = mrConsume; 4184 } 4185 } 4186 } 4187 4188 MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode) 4189 { 4190 /* Menu/Accelerator */ 4191 if (hWndChild == 0) { 4192 AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id); 4193 if (obj == NULL) { 4194 return mrConsume; 4195 } 4196 DASSERT(((AwtMenuItem*)obj)->GetID() == id); 4197 obj->DoCommand(); 4198 return mrConsume; 4199 } 4200 /* Child id notification */ 4201 else { 4202 AwtComponent* child = AwtComponent::GetComponent(hWndChild); 4203 if (child) { 4204 child->WmNotify(notifyCode); 4205 } 4206 } 4207 return mrDoDefault; 4208 } 4209 4210 MsgRouting AwtComponent::WmNotify(UINT notifyCode) 4211 { 4212 return mrDoDefault; 4213 } 4214 4215 MsgRouting AwtComponent::WmCompareItem(UINT ctrlId, 4216 COMPAREITEMSTRUCT &compareInfo, 4217 LRESULT &result) 4218 { 4219 AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem); 4220 if (child == this) { 4221 /* DoCallback("handleItemDelete", */ 4222 } 4223 else if (child) { 4224 return child->WmCompareItem(ctrlId, compareInfo, result); 4225 } 4226 return mrConsume; 4227 } 4228 4229 MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId, 4230 DELETEITEMSTRUCT &deleteInfo) 4231 { 4232 /* 4233 * Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList 4234 * window, a WM_DELETEITEM message is sent to its parent with a window 4235 * handle of one of the list's child windows. The property lookup 4236 * succeeds, but the HWNDs don't match. 4237 */ 4238 if (deleteInfo.hwndItem == NULL) { 4239 return mrConsume; 4240 } 4241 AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem); 4242 4243 if (child && child->GetHWnd() != deleteInfo.hwndItem) { 4244 return mrConsume; 4245 } 4246 4247 if (child == this) { 4248 /*DoCallback("handleItemDelete", */ 4249 } 4250 else if (child) { 4251 return child->WmDeleteItem(ctrlId, deleteInfo); 4252 } 4253 return mrConsume; 4254 } 4255 4256 MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo) 4257 { 4258 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4259 4260 if (drawInfo.CtlType == ODT_MENU) { 4261 if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) { 4262 AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); 4263 menu->DrawItem(drawInfo); 4264 } 4265 } else { 4266 return OwnerDrawItem(ctrlId, drawInfo); 4267 } 4268 return mrConsume; 4269 } 4270 4271 MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId, 4272 MEASUREITEMSTRUCT &measureInfo) 4273 { 4274 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4275 4276 if (measureInfo.CtlType == ODT_MENU) { 4277 if (measureInfo.itemData != 0) { 4278 AwtMenu* menu = (AwtMenu*)(measureInfo.itemData); 4279 HDC hDC = ::GetDC(GetHWnd()); 4280 /* menu->MeasureItem(env, hDC, measureInfo); */ 4281 menu->MeasureItem(hDC, measureInfo); 4282 ::ReleaseDC(GetHWnd(), hDC); 4283 } 4284 } else { 4285 return OwnerMeasureItem(ctrlId, measureInfo); 4286 } 4287 return mrConsume; 4288 } 4289 4290 MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId, 4291 DRAWITEMSTRUCT &drawInfo) 4292 { 4293 AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem); 4294 if (child == this) { 4295 /* DoCallback("handleItemDelete", */ 4296 } else if (child != NULL) { 4297 return child->WmDrawItem(ctrlId, drawInfo); 4298 } 4299 return mrConsume; 4300 } 4301 4302 MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId, 4303 MEASUREITEMSTRUCT &measureInfo) 4304 { 4305 HWND hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID); 4306 AwtComponent* child = AwtComponent::GetComponent(hChild); 4307 /* 4308 * If the parent cannot find the child's instance from its handle, 4309 * maybe the child is in its creation. So the child must be searched 4310 * from the list linked before the child's creation. 4311 */ 4312 if (child == NULL) { 4313 child = SearchChild((UINT)ctrlId); 4314 } 4315 4316 if (child == this) { 4317 /* DoCallback("handleItemDelete", */ 4318 } 4319 else if (child) { 4320 return child->WmMeasureItem(ctrlId, measureInfo); 4321 } 4322 return mrConsume; 4323 } 4324 4325 /* for WmDrawItem method of Label, Button and Checkbox */ 4326 void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text, 4327 int x, int y) 4328 { 4329 int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT); 4330 DASSERT(nOldBkMode != 0); 4331 AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage()); 4332 VERIFY(::SetBkMode(hDC,nOldBkMode)); 4333 } 4334 4335 /* 4336 * Draw text in gray (the color being set to COLOR_GRAYTEXT) when the 4337 * component is disabled. Used only for label, checkbox and button in 4338 * OWNER_DRAW. It draws the text in emboss. 4339 */ 4340 void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text, 4341 int x, int y) 4342 { 4343 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); 4344 AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1); 4345 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 4346 AwtComponent::DrawWindowText(hDC, font, text, x, y); 4347 } 4348 4349 /* for WmMeasureItem method of List and Choice */ 4350 jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index) 4351 { 4352 jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl", 4353 "(I)Ljava/lang/String;", 4354 index).l; 4355 DASSERT(!safe_ExceptionOccurred(env)); 4356 return str; 4357 } 4358 4359 /* for WmMeasureItem method of List and Choice */ 4360 void AwtComponent::MeasureListItem(JNIEnv *env, 4361 MEASUREITEMSTRUCT &measureInfo) 4362 { 4363 if (env->EnsureLocalCapacity(1) < 0) { 4364 return; 4365 } 4366 jobject dimension = PreferredItemSize(env); 4367 DASSERT(dimension); 4368 measureInfo.itemWidth = 4369 env->GetIntField(dimension, AwtDimension::widthID); 4370 measureInfo.itemHeight = 4371 env->GetIntField(dimension, AwtDimension::heightID); 4372 env->DeleteLocalRef(dimension); 4373 } 4374 4375 /* for WmDrawItem method of List and Choice */ 4376 void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) 4377 { 4378 if (env->EnsureLocalCapacity(3) < 0) { 4379 return; 4380 } 4381 jobject peer = GetPeer(env); 4382 jobject target = env->GetObjectField(peer, AwtObject::targetID); 4383 4384 HDC hDC = drawInfo.hDC; 4385 RECT rect = drawInfo.rcItem; 4386 4387 BOOL bEnabled = isEnabled(); 4388 BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable(); 4389 DWORD crBack, crText; 4390 if (drawInfo.itemState & ODS_SELECTED){ 4391 /* Set background and text colors for selected item */ 4392 crBack = ::GetSysColor (COLOR_HIGHLIGHT); 4393 crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT); 4394 } else { 4395 /* Set background and text colors for unselected item */ 4396 crBack = GetBackgroundColor(); 4397 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4398 } 4399 if (unfocusableChoice) { 4400 //6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box. 4401 crBack = GetBackgroundColor(); 4402 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4403 } 4404 4405 /* Fill item rectangle with background color */ 4406 HBRUSH hbrBack = ::CreateSolidBrush (crBack); 4407 DASSERT(hbrBack); 4408 /* 6190728. Shouldn't draw any kind of rectangle around selection field 4409 * (edit control) of an owner-drawn combo box while unfocusable 4410 */ 4411 if (!unfocusableChoice){ 4412 VERIFY(::FillRect (hDC, &rect, hbrBack)); 4413 } 4414 VERIFY(::DeleteObject (hbrBack)); 4415 4416 /* Set current background and text colors */ 4417 ::SetBkColor (hDC, crBack); 4418 ::SetTextColor (hDC, crText); 4419 4420 /*draw string (with left margin of 1 point) */ 4421 if ((int) (drawInfo.itemID) >= 0) { 4422 jobject font = GET_FONT(target, peer); 4423 jstring text = GetItemString(env, target, drawInfo.itemID); 4424 if (env->ExceptionCheck()) { 4425 env->DeleteLocalRef(font); 4426 env->DeleteLocalRef(target); 4427 return; 4428 } 4429 SIZE size = AwtFont::getMFStringSize(hDC, font, text); 4430 AwtFont::drawMFString(hDC, font, text, 4431 (GetRTL()) ? rect.right - size.cx - 1 4432 : rect.left + 1, 4433 (rect.top + rect.bottom - size.cy) / 2, 4434 GetCodePage()); 4435 env->DeleteLocalRef(font); 4436 env->DeleteLocalRef(text); 4437 } 4438 if ((drawInfo.itemState & ODS_FOCUS) && 4439 (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { 4440 if (!unfocusableChoice){ 4441 VERIFY(::DrawFocusRect(hDC, &rect)); 4442 } 4443 } 4444 env->DeleteLocalRef(target); 4445 } 4446 4447 /* for MeasureListItem method and WmDrawItem method of Checkbox */ 4448 jint AwtComponent::GetFontHeight(JNIEnv *env) 4449 { 4450 if (env->EnsureLocalCapacity(4) < 0) { 4451 return NULL; 4452 } 4453 jobject self = GetPeer(env); 4454 jobject target = env->GetObjectField(self, AwtObject::targetID); 4455 4456 jobject font = GET_FONT(target, self); 4457 jobject toolkit = env->CallObjectMethod(target, 4458 AwtComponent::getToolkitMID); 4459 4460 DASSERT(!safe_ExceptionOccurred(env)); 4461 4462 jobject fontMetrics = 4463 env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font); 4464 4465 DASSERT(!safe_ExceptionOccurred(env)); 4466 4467 jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID); 4468 DASSERT(!safe_ExceptionOccurred(env)); 4469 4470 env->DeleteLocalRef(target); 4471 env->DeleteLocalRef(font); 4472 env->DeleteLocalRef(toolkit); 4473 env->DeleteLocalRef(fontMetrics); 4474 4475 return height; 4476 } 4477 4478 // If you override WmPrint, make sure to save a copy of the DC on the GDI 4479 // stack to be restored in WmPrintClient. Windows mangles the DC in 4480 // ::DefWindowProc. 4481 MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags) 4482 { 4483 /* 4484 * DefWindowProc for WM_PRINT changes DC parameters, so we have 4485 * to restore it ourselves. Otherwise it will cause problems 4486 * when several components are printed to the same DC. 4487 */ 4488 int nOriginalDC = ::SaveDC(hDC); 4489 DASSERT(nOriginalDC != 0); 4490 4491 if (flags & PRF_NONCLIENT) { 4492 4493 VERIFY(::SaveDC(hDC)); 4494 4495 DefWindowProc(WM_PRINT, (WPARAM)hDC, 4496 (flags & (PRF_NONCLIENT 4497 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4498 4499 VERIFY(::RestoreDC(hDC, -1)); 4500 4501 // Special case for components with a sunken border. Windows does not 4502 // print the border correctly on PCL printers, so we have to do it ourselves. 4503 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4504 RECT r; 4505 VERIFY(::GetWindowRect(GetHWnd(), &r)); 4506 VERIFY(::OffsetRect(&r, -r.left, -r.top)); 4507 VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT)); 4508 } 4509 } 4510 4511 if (flags & PRF_CLIENT) { 4512 4513 /* 4514 * Special case for components with a sunken border. 4515 * Windows prints a client area without offset to a border width. 4516 * We will first print the non-client area with the original offset, 4517 * then the client area with a corrected offset. 4518 */ 4519 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4520 4521 int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE); 4522 int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE); 4523 4524 VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL)); 4525 4526 // Save a copy of the DC for WmPrintClient 4527 VERIFY(::SaveDC(hDC)); 4528 4529 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4530 (flags & (PRF_CLIENT 4531 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4532 4533 VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL)); 4534 4535 } else { 4536 4537 // Save a copy of the DC for WmPrintClient 4538 VERIFY(::SaveDC(hDC)); 4539 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4540 (flags & (PRF_CLIENT 4541 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4542 } 4543 } 4544 4545 if (flags & (PRF_CHILDREN | PRF_OWNED)) { 4546 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4547 (flags & ~PRF_CLIENT & ~PRF_NONCLIENT)); 4548 } 4549 4550 VERIFY(::RestoreDC(hDC, nOriginalDC)); 4551 4552 return mrConsume; 4553 } 4554 4555 // If you override WmPrintClient, make sure to obtain a valid copy of 4556 // the DC from the GDI stack. The copy of the DC should have been placed 4557 // there by WmPrint. Windows mangles the DC in ::DefWindowProc. 4558 MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM) 4559 { 4560 // obtain valid DC from GDI stack 4561 ::RestoreDC(hDC, -1); 4562 4563 return mrDoDefault; 4564 } 4565 4566 MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects, 4567 LPNCCALCSIZE_PARAMS lpncsp, 4568 LRESULT &retVal) 4569 { 4570 return mrDoDefault; 4571 } 4572 4573 MsgRouting AwtComponent::WmNcPaint(HRGN hrgn) 4574 { 4575 return mrDoDefault; 4576 } 4577 4578 MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal) 4579 { 4580 return mrDoDefault; 4581 } 4582 4583 /** 4584 * WmQueryNewPalette is called whenever our component is coming to 4585 * the foreground; this gives us an opportunity to install our 4586 * custom palette. If this install actually changes entries in 4587 * the system palette, then we get a further call to WmPaletteChanged 4588 * (but note that we only need to realize our palette once). 4589 */ 4590 MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal) 4591 { 4592 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4593 m_QueryNewPaletteCalled = TRUE; 4594 HDC hDC = ::GetDC(GetHWnd()); 4595 DASSERT(hDC); 4596 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4597 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4598 ::ReleaseDC(GetHWnd(), hDC); 4599 // We must realize the palettes of all of our DC's 4600 // There is sometimes a problem where the realization of 4601 // our temporary hDC here does not actually do what 4602 // we want. Not clear why, but presumably fallout from 4603 // our use of several simultaneous hDC's. 4604 activeDCList.RealizePalettes(screen); 4605 // Do not invalidate here; if the palette 4606 // has not changed we will get an extra repaint 4607 retVal = TRUE; 4608 4609 return mrDoDefault; 4610 } 4611 4612 /** 4613 * We should not need to track this event since we handle our 4614 * palette management effectively in the WmQueryNewPalette and 4615 * WmPaletteChanged methods. However, there seems to be a bug 4616 * on some win32 systems (e.g., NT4) whereby the palette 4617 * immediately after a displayChange is not yet updated to its 4618 * final post-display-change values (hence we adjust our palette 4619 * using the wrong system palette entries), then the palette is 4620 * updated, but a WM_PALETTECHANGED message is never sent. 4621 * By tracking the ISCHANGING message as well (and by tracking 4622 * displayChange events in the AwtToolkit object), we can account 4623 * for this error by forcing our WmPaletteChanged method to be 4624 * called and thereby realizing our logical palette and updating 4625 * our dynamic colorModel object. 4626 */ 4627 MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg) 4628 { 4629 if (AwtToolkit::GetInstance().HasDisplayChanged()) { 4630 WmPaletteChanged(hwndPalChg); 4631 AwtToolkit::GetInstance().ResetDisplayChanged(); 4632 } 4633 return mrDoDefault; 4634 } 4635 4636 MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg) 4637 { 4638 // We need to re-realize our palette here (unless we're the one 4639 // that was realizing it in the first place). That will let us match the 4640 // remaining colors in the system palette as best we can. We always 4641 // invalidate because the palette will have changed when we receive this 4642 // message. 4643 4644 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4645 if (hwndPalChg != GetHWnd()) { 4646 HDC hDC = ::GetDC(GetHWnd()); 4647 DASSERT(hDC); 4648 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4649 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4650 ::ReleaseDC(GetHWnd(), hDC); 4651 // We must realize the palettes of all of our DC's 4652 activeDCList.RealizePalettes(screen); 4653 } 4654 if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) { 4655 AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen); 4656 } 4657 Invalidate(NULL); 4658 return mrDoDefault; 4659 } 4660 4661 MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 4662 { 4663 DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT))); 4664 return mrDoDefault; 4665 } 4666 4667 MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection) 4668 { 4669 DASSERT(!IsBadStringPtr(pszSection, 20)); 4670 DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection); 4671 return mrDoDefault; 4672 } 4673 4674 HDC AwtComponent::GetDCFromComponent() 4675 { 4676 GetDCReturnStruct *hdcStruct = 4677 (GetDCReturnStruct*)SendMessage(WM_AWT_GETDC); 4678 HDC hdc; 4679 if (hdcStruct) { 4680 if (hdcStruct->gdiLimitReached) { 4681 if (jvm != NULL) { 4682 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4683 if (env != NULL && !safe_ExceptionOccurred(env)) { 4684 JNU_ThrowByName(env, "java/awt/AWTError", 4685 "HDC creation failure - " \ 4686 "exceeded maximum GDI resources"); 4687 } 4688 } 4689 } 4690 hdc = hdcStruct->hDC; 4691 delete hdcStruct; 4692 } else { 4693 hdc = NULL; 4694 } 4695 return hdc; 4696 } 4697 4698 void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size) 4699 { 4700 RECT eraseR = { 0, 0, size.cx, size.cy }; 4701 VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush())); 4702 } 4703 4704 void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) 4705 { 4706 if (!bitmapBits) { 4707 return; 4708 } 4709 4710 DWORD* dest = (DWORD*)bitmapBits; 4711 //XXX: might be optimized to use one loop (cy*cx -> 0) 4712 for (int i = 0; i < size.cy; i++ ) { 4713 for (int j = 0; j < size.cx; j++ ) { 4714 ((BYTE*)(dest++))[3] = alpha; 4715 } 4716 } 4717 } 4718 4719 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) { 4720 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4721 4722 if (!::IsWindowVisible(GetHWnd())) { 4723 return NULL; 4724 } 4725 4726 HDC hdc = GetDCFromComponent(); 4727 if (!hdc) { 4728 return NULL; 4729 } 4730 HDC hMemoryDC = ::CreateCompatibleDC(hdc); 4731 void *bitmapBits = NULL; 4732 HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits); 4733 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap); 4734 SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc); 4735 4736 FillBackground(hMemoryDC, size); 4737 4738 VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL)); 4739 4740 // Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible 4741 // above. 4742 SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT); 4743 4744 // First make sure the system completed any drawing to the bitmap. 4745 ::GdiFlush(); 4746 4747 // WM_PRINT does not fill the alpha-channel of the ARGB bitmap 4748 // leaving it equal to zero. Hence we need to fill it manually. Otherwise 4749 // the pixels will be considered transparent when interpreting the data. 4750 FillAlpha(bitmapBits, size, alpha); 4751 4752 ::SelectObject(hMemoryDC, hOldBitmap); 4753 4754 BITMAPINFO bmi; 4755 memset(&bmi, 0, sizeof(BITMAPINFO)); 4756 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 4757 bmi.bmiHeader.biWidth = size.cx; 4758 bmi.bmiHeader.biHeight = -size.cy; 4759 bmi.bmiHeader.biPlanes = 1; 4760 bmi.bmiHeader.biBitCount = 32; 4761 bmi.bmiHeader.biCompression = BI_RGB; 4762 4763 jobject localPixelArray = env->NewIntArray(size.cx * size.cy); 4764 jintArray pixelArray = NULL; 4765 if (localPixelArray != NULL) { 4766 pixelArray = (jintArray)env->NewGlobalRef(localPixelArray); 4767 env->DeleteLocalRef(localPixelArray); localPixelArray = NULL; 4768 4769 jboolean isCopy; 4770 jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy); 4771 4772 ::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi, 4773 DIB_RGB_COLORS); 4774 4775 env->ReleaseIntArrayElements(pixelArray, pixels, 0); 4776 } 4777 4778 VERIFY(::DeleteObject(hBitmap)); 4779 VERIFY(::DeleteDC(hMemoryDC)); 4780 4781 return pixelArray; 4782 } 4783 4784 void* AwtComponent::SetNativeFocusOwner(void *self) { 4785 if (self == NULL) { 4786 // It means that the KFM wants to set focus to null 4787 sm_focusOwner = NULL; 4788 return NULL; 4789 } 4790 4791 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4792 4793 AwtComponent *c = NULL; 4794 jobject peer = (jobject)self; 4795 4796 PDATA pData; 4797 JNI_CHECK_NULL_GOTO(peer, "peer", ret); 4798 pData = JNI_GET_PDATA(peer); 4799 if (pData == NULL) { 4800 goto ret; 4801 } 4802 c = (AwtComponent *)pData; 4803 4804 ret: 4805 if (c && ::IsWindow(c->GetHWnd())) { 4806 sm_focusOwner = c->GetHWnd(); 4807 } else { 4808 sm_focusOwner = NULL; 4809 } 4810 env->DeleteGlobalRef(peer); 4811 return NULL; 4812 } 4813 4814 void* AwtComponent::GetNativeFocusedWindow() { 4815 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4816 AwtComponent *comp = 4817 AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 4818 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4819 } 4820 4821 void* AwtComponent::GetNativeFocusOwner() { 4822 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4823 AwtComponent *comp = 4824 AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 4825 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4826 } 4827 4828 AwtComponent* AwtComponent::SearchChild(UINT id) { 4829 ChildListItem* child; 4830 for (child = m_childList; child != NULL;child = child->m_next) { 4831 if (child->m_ID == id) 4832 return child->m_Component; 4833 } 4834 /* 4835 * DASSERT(FALSE); 4836 * This should not be happend if all children are recorded 4837 */ 4838 return NULL; /* make compiler happy */ 4839 } 4840 4841 void AwtComponent::RemoveChild(UINT id) { 4842 ChildListItem* child = m_childList; 4843 ChildListItem* lastChild = NULL; 4844 while (child != NULL) { 4845 if (child->m_ID == id) { 4846 if (lastChild == NULL) { 4847 m_childList = child->m_next; 4848 } else { 4849 lastChild->m_next = child->m_next; 4850 } 4851 child->m_next = NULL; 4852 DASSERT(child != NULL); 4853 delete child; 4854 return; 4855 } 4856 lastChild = child; 4857 child = child->m_next; 4858 } 4859 } 4860 4861 void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked, 4862 jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg) 4863 { 4864 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4865 CriticalSection::Lock l(GetLock()); 4866 if (GetPeer(env) == NULL) { 4867 /* event received during termination. */ 4868 return; 4869 } 4870 4871 static jclass keyEventCls; 4872 if (keyEventCls == NULL) { 4873 jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent"); 4874 DASSERT(keyEventClsLocal); 4875 if (keyEventClsLocal == NULL) { 4876 /* exception already thrown */ 4877 return; 4878 } 4879 keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal); 4880 env->DeleteLocalRef(keyEventClsLocal); 4881 } 4882 4883 static jmethodID keyEventConst; 4884 if (keyEventConst == NULL) { 4885 keyEventConst = env->GetMethodID(keyEventCls, "<init>", 4886 "(Ljava/awt/Component;IJIICI)V"); 4887 DASSERT(keyEventConst); 4888 CHECK_NULL(keyEventConst); 4889 } 4890 if (env->EnsureLocalCapacity(2) < 0) { 4891 return; 4892 } 4893 jobject target = GetTarget(env); 4894 jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target, 4895 id, when, modifiers, raw, cooked, 4896 keyLocation); 4897 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4898 DASSERT(!safe_ExceptionOccurred(env)); 4899 DASSERT(keyEvent != NULL); 4900 if (keyEvent == NULL) { 4901 env->DeleteLocalRef(target); 4902 return; 4903 } 4904 env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode); 4905 if( nativeCode && nativeCode < 256 ) { 4906 env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode)); 4907 env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey)); 4908 if( nativeCode < 255 ) { 4909 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode)); 4910 }else if( pMsg != NULL ) { 4911 // unknown key with virtual keycode 0xFF. 4912 // Its scancode is not in the table, pickup it from the message. 4913 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF)); 4914 } 4915 } 4916 if (pMsg != NULL) { 4917 AwtAWTEvent::saveMSG(env, pMsg, keyEvent); 4918 } 4919 SendEvent(keyEvent); 4920 4921 env->DeleteLocalRef(keyEvent); 4922 env->DeleteLocalRef(target); 4923 } 4924 4925 void 4926 AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when, 4927 jint raw, jint cooked, 4928 jint modifiers, jint keyLocation, 4929 jlong nativeCode, 4930 MSG *msg) 4931 { 4932 /* 4933 * if focus owner is null, but focused window isn't 4934 * we will send key event to focused window 4935 */ 4936 HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow()); 4937 4938 if (hwndTarget == GetHWnd()) { 4939 SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg); 4940 } else { 4941 AwtComponent *target = NULL; 4942 if (hwndTarget != NULL) { 4943 target = AwtComponent::GetComponent(hwndTarget); 4944 if (target == NULL) { 4945 target = this; 4946 } 4947 } 4948 if (target != NULL) { 4949 target->SendKeyEvent(id, when, raw, cooked, modifiers, 4950 keyLocation, nativeCode, msg); 4951 } 4952 } 4953 } 4954 4955 void AwtComponent::SetDragCapture(UINT flags) 4956 { 4957 // don't want to interfere with other controls 4958 if (::GetCapture() == NULL) { 4959 ::SetCapture(GetHWnd()); 4960 } 4961 } 4962 4963 void AwtComponent::ReleaseDragCapture(UINT flags) 4964 { 4965 if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) { 4966 // user has released all buttons, so release the capture 4967 ::ReleaseCapture(); 4968 } 4969 } 4970 4971 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y, 4972 jint modifiers, jint clickCount, 4973 jboolean popupTrigger, jint button, 4974 MSG *pMsg, BOOL causedByTouchEvent) 4975 { 4976 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4977 CriticalSection::Lock l(GetLock()); 4978 if (GetPeer(env) == NULL) { 4979 /* event received during termination. */ 4980 return; 4981 } 4982 4983 static jclass mouseEventCls; 4984 if (mouseEventCls == NULL) { 4985 jclass mouseEventClsLocal = 4986 env->FindClass("java/awt/event/MouseEvent"); 4987 CHECK_NULL(mouseEventClsLocal); 4988 mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal); 4989 env->DeleteLocalRef(mouseEventClsLocal); 4990 } 4991 RECT insets; 4992 GetInsets(&insets); 4993 4994 static jmethodID mouseEventConst; 4995 if (mouseEventConst == NULL) { 4996 mouseEventConst = 4997 env->GetMethodID(mouseEventCls, "<init>", 4998 "(Ljava/awt/Component;IJIIIIIIZI)V"); 4999 DASSERT(mouseEventConst); 5000 CHECK_NULL(mouseEventConst); 5001 } 5002 if (env->EnsureLocalCapacity(2) < 0) { 5003 return; 5004 } 5005 jobject target = GetTarget(env); 5006 DWORD curMousePos = ::GetMessagePos(); 5007 int xAbs = GET_X_LPARAM(curMousePos); 5008 int yAbs = GET_Y_LPARAM(curMousePos); 5009 jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst, 5010 target, 5011 id, when, modifiers, 5012 x+insets.left, y+insets.top, 5013 xAbs, yAbs, 5014 clickCount, popupTrigger, button); 5015 5016 if (safe_ExceptionOccurred(env)) { 5017 env->ExceptionDescribe(); 5018 env->ExceptionClear(); 5019 } 5020 5021 DASSERT(mouseEvent != NULL); 5022 CHECK_NULL(mouseEvent); 5023 if (causedByTouchEvent) { 5024 env->SetBooleanField(mouseEvent, AwtMouseEvent::causedByTouchEventID, 5025 JNI_TRUE); 5026 } 5027 if (pMsg != 0) { 5028 AwtAWTEvent::saveMSG(env, pMsg, mouseEvent); 5029 } 5030 SendEvent(mouseEvent); 5031 5032 env->DeleteLocalRef(mouseEvent); 5033 env->DeleteLocalRef(target); 5034 } 5035 5036 void 5037 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, 5038 jint modifiers, jint clickCount, 5039 jboolean popupTrigger, jint scrollType, 5040 jint scrollAmount, jint roundedWheelRotation, 5041 jdouble preciseWheelRotation, MSG *pMsg) 5042 { 5043 /* Code based not so loosely on AwtComponent::SendMouseEvent */ 5044 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5045 CriticalSection::Lock l(GetLock()); 5046 if (GetPeer(env) == NULL) { 5047 /* event received during termination. */ 5048 return; 5049 } 5050 5051 static jclass mouseWheelEventCls; 5052 if (mouseWheelEventCls == NULL) { 5053 jclass mouseWheelEventClsLocal = 5054 env->FindClass("java/awt/event/MouseWheelEvent"); 5055 CHECK_NULL(mouseWheelEventClsLocal); 5056 mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal); 5057 env->DeleteLocalRef(mouseWheelEventClsLocal); 5058 } 5059 RECT insets; 5060 GetInsets(&insets); 5061 5062 static jmethodID mouseWheelEventConst; 5063 if (mouseWheelEventConst == NULL) { 5064 mouseWheelEventConst = 5065 env->GetMethodID(mouseWheelEventCls, "<init>", 5066 "(Ljava/awt/Component;IJIIIIIIZIIID)V"); 5067 DASSERT(mouseWheelEventConst); 5068 CHECK_NULL(mouseWheelEventConst); 5069 } 5070 if (env->EnsureLocalCapacity(2) < 0) { 5071 return; 5072 } 5073 jobject target = GetTarget(env); 5074 DTRACE_PRINTLN("creating MWE in JNI"); 5075 5076 jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, 5077 mouseWheelEventConst, 5078 target, 5079 id, when, modifiers, 5080 x+insets.left, y+insets.top, 5081 0, 0, 5082 clickCount, popupTrigger, 5083 scrollType, scrollAmount, 5084 roundedWheelRotation, preciseWheelRotation); 5085 5086 DASSERT(mouseWheelEvent != NULL); 5087 if (mouseWheelEvent == NULL || safe_ExceptionOccurred(env)) { 5088 env->ExceptionDescribe(); 5089 env->ExceptionClear(); 5090 env->DeleteLocalRef(target); 5091 return; 5092 } 5093 if (pMsg != NULL) { 5094 AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent); 5095 } 5096 SendEvent(mouseWheelEvent); 5097 5098 env->DeleteLocalRef(mouseWheelEvent); 5099 env->DeleteLocalRef(target); 5100 } 5101 5102 void AwtComponent::SendFocusEvent(jint id, HWND opposite) 5103 { 5104 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5105 5106 CriticalSection::Lock l(GetLock()); 5107 if (GetPeer(env) == NULL) { 5108 /* event received during termination. */ 5109 return; 5110 } 5111 5112 static jclass focusEventCls; 5113 if (focusEventCls == NULL) { 5114 jclass focusEventClsLocal 5115 = env->FindClass("java/awt/event/FocusEvent"); 5116 DASSERT(focusEventClsLocal); 5117 CHECK_NULL(focusEventClsLocal); 5118 focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal); 5119 env->DeleteLocalRef(focusEventClsLocal); 5120 } 5121 5122 static jmethodID focusEventConst; 5123 if (focusEventConst == NULL) { 5124 focusEventConst = 5125 env->GetMethodID(focusEventCls, "<init>", 5126 "(Ljava/awt/Component;IZLjava/awt/Component;)V"); 5127 DASSERT(focusEventConst); 5128 CHECK_NULL(focusEventConst); 5129 } 5130 5131 static jclass sequencedEventCls; 5132 if (sequencedEventCls == NULL) { 5133 jclass sequencedEventClsLocal = 5134 env->FindClass("java/awt/SequencedEvent"); 5135 DASSERT(sequencedEventClsLocal); 5136 CHECK_NULL(sequencedEventClsLocal); 5137 sequencedEventCls = 5138 (jclass)env->NewGlobalRef(sequencedEventClsLocal); 5139 env->DeleteLocalRef(sequencedEventClsLocal); 5140 } 5141 5142 static jmethodID sequencedEventConst; 5143 if (sequencedEventConst == NULL) { 5144 sequencedEventConst = 5145 env->GetMethodID(sequencedEventCls, "<init>", 5146 "(Ljava/awt/AWTEvent;)V"); 5147 DASSERT(sequencedEventConst); 5148 CHECK_NULL(sequencedEventConst); 5149 } 5150 5151 if (env->EnsureLocalCapacity(3) < 0) { 5152 return; 5153 } 5154 5155 jobject target = GetTarget(env); 5156 jobject jOpposite = NULL; 5157 if (opposite != NULL) { 5158 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite); 5159 if (awtOpposite != NULL) { 5160 jOpposite = awtOpposite->GetTarget(env); 5161 } 5162 } 5163 jobject focusEvent = env->NewObject(focusEventCls, focusEventConst, 5164 target, id, JNI_FALSE, jOpposite); 5165 DASSERT(!safe_ExceptionOccurred(env)); 5166 DASSERT(focusEvent != NULL); 5167 if (jOpposite != NULL) { 5168 env->DeleteLocalRef(jOpposite); jOpposite = NULL; 5169 } 5170 env->DeleteLocalRef(target); target = NULL; 5171 CHECK_NULL(focusEvent); 5172 5173 jobject sequencedEvent = env->NewObject(sequencedEventCls, 5174 sequencedEventConst, 5175 focusEvent); 5176 DASSERT(!safe_ExceptionOccurred(env)); 5177 DASSERT(sequencedEvent != NULL); 5178 env->DeleteLocalRef(focusEvent); focusEvent = NULL; 5179 CHECK_NULL(sequencedEvent); 5180 SendEvent(sequencedEvent); 5181 5182 env->DeleteLocalRef(sequencedEvent); 5183 } 5184 5185 /* 5186 * Forward a filtered event directly to the subclassed window. 5187 * This method is needed so that DefWindowProc is invoked on the 5188 * component's owning thread. 5189 */ 5190 MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL) 5191 { 5192 DefWindowProc(msg->message, msg->wParam, msg->lParam); 5193 delete msg; 5194 return mrConsume; 5195 } 5196 5197 /* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent 5198 on the toolkit thread. This method may pre-filter the messages. */ 5199 BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic) 5200 { 5201 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5202 // We should cut off keyboard events to disabled components 5203 // to avoid the components responding visually to keystrokes when disabled. 5204 // we shouldn't cut off WM_SYS* messages as they aren't used for normal activity 5205 // but to activate menus, close windows, etc 5206 switch(msg->message) { 5207 case WM_KEYDOWN: 5208 case WM_KEYUP: 5209 case WM_CHAR: 5210 case WM_DEADCHAR: 5211 { 5212 if (!isRecursivelyEnabled()) { 5213 goto quit; 5214 } 5215 break; 5216 } 5217 } 5218 if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT, 5219 (WPARAM) synthetic, (LPARAM) msg)) { 5220 return TRUE; 5221 } else { 5222 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5223 } 5224 quit: 5225 delete msg; 5226 return FALSE; 5227 } 5228 5229 void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent) 5230 { 5231 jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID); 5232 UINT message; 5233 switch (id) { 5234 case java_awt_event_KeyEvent_KEY_PRESSED: 5235 message = WM_KEYDOWN; 5236 break; 5237 case java_awt_event_KeyEvent_KEY_RELEASED: 5238 message = WM_KEYUP; 5239 break; 5240 case java_awt_event_KeyEvent_KEY_TYPED: 5241 message = WM_CHAR; 5242 break; 5243 default: 5244 return; 5245 } 5246 5247 /* 5248 * KeyEvent.modifiers aren't supported -- the Java apppwd must send separate 5249 * KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys. 5250 */ 5251 if (id == java_awt_event_KeyEvent_KEY_TYPED) { 5252 // WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR 5253 // (for Edit control) 5254 jchar keyChar = (jchar) 5255 (env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID); 5256 5257 // Bugid 4724007. If it is a Delete character, don't send the fake 5258 // KEY_TYPED we created back to the native window: Windows doesn't 5259 // expect a WM_CHAR for Delete in TextFields, so it tries to enter a 5260 // character after deleting. 5261 if (keyChar == '\177') { // the Delete character 5262 return; 5263 } 5264 5265 // Disable forwarding WM_CHAR messages to disabled components 5266 if (isRecursivelyEnabled()) { 5267 if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR, 5268 MAKEWPARAM(keyChar, TRUE), 0)) { 5269 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5270 } 5271 } 5272 } else { 5273 jint keyCode = 5274 (env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID); 5275 UINT key, modifiers; 5276 AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers); 5277 MSG* msg = CreateMessage(message, key, 0); 5278 PostHandleEventMessage(msg, TRUE); 5279 } 5280 } 5281 5282 void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent) 5283 { 5284 /* DebugBreak(); */ 5285 jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID); 5286 jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID); 5287 5288 WPARAM wParam = 0; 5289 WORD wLow = 0; 5290 jint wheelAmt = 0; 5291 jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID); 5292 UINT message; 5293 switch (id) { 5294 case java_awt_event_MouseEvent_MOUSE_PRESSED: { 5295 switch (button) { 5296 case java_awt_event_MouseEvent_BUTTON1: 5297 message = WM_LBUTTONDOWN; break; 5298 case java_awt_event_MouseEvent_BUTTON3: 5299 message = WM_MBUTTONDOWN; break; 5300 case java_awt_event_MouseEvent_BUTTON2: 5301 message = WM_RBUTTONDOWN; break; 5302 default: 5303 return; 5304 } 5305 break; 5306 } 5307 case java_awt_event_MouseEvent_MOUSE_RELEASED: { 5308 switch (button) { 5309 case java_awt_event_MouseEvent_BUTTON1: 5310 message = WM_LBUTTONUP; break; 5311 case java_awt_event_MouseEvent_BUTTON3: 5312 message = WM_MBUTTONUP; break; 5313 case java_awt_event_MouseEvent_BUTTON2: 5314 message = WM_RBUTTONUP; break; 5315 default: 5316 return; 5317 } 5318 break; 5319 } 5320 case java_awt_event_MouseEvent_MOUSE_MOVED: 5321 /* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */ 5322 case java_awt_event_MouseEvent_MOUSE_DRAGGED: 5323 message = WM_MOUSEMOVE; 5324 break; 5325 case java_awt_event_MouseEvent_MOUSE_WHEEL: 5326 if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) { 5327 wLow |= MK_CONTROL; 5328 } 5329 if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) { 5330 wLow |= MK_SHIFT; 5331 } 5332 if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) { 5333 wLow |= MK_LBUTTON; 5334 } 5335 if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) { 5336 wLow |= MK_RBUTTON; 5337 } 5338 if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) { 5339 wLow |= MK_MBUTTON; 5340 } 5341 if (modifiers & X1_BUTTON) { 5342 wLow |= GetButtonMK(X1_BUTTON); 5343 } 5344 if (modifiers & X2_BUTTON) { 5345 wLow |= GetButtonMK(X2_BUTTON); 5346 } 5347 5348 wheelAmt = (jint)JNU_CallMethodByName(env, 5349 NULL, 5350 mouseEvent, 5351 "getWheelRotation", 5352 "()I").i; 5353 DASSERT(!safe_ExceptionOccurred(env)); 5354 JNU_CHECK_EXCEPTION(env); 5355 DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt); 5356 5357 // convert Java wheel amount value to Win32 5358 wheelAmt *= -1 * WHEEL_DELTA; 5359 5360 message = WM_MOUSEWHEEL; 5361 wParam = MAKEWPARAM(wLow, wheelAmt); 5362 5363 break; 5364 default: 5365 return; 5366 } 5367 jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID); 5368 jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID); 5369 MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y); 5370 PostHandleEventMessage(msg, TRUE); 5371 } 5372 5373 BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;} 5374 5375 void AwtComponent::Invalidate(RECT* r) 5376 { 5377 ::InvalidateRect(GetHWnd(), r, FALSE); 5378 } 5379 5380 void AwtComponent::BeginValidate() 5381 { 5382 DASSERT(m_validationNestCount >= 0 && 5383 m_validationNestCount < 1000); // sanity check 5384 5385 if (m_validationNestCount == 0) { 5386 // begin deferred window positioning if we're not inside 5387 // another Begin/EndValidate pair 5388 DASSERT(m_hdwp == NULL); 5389 m_hdwp = ::BeginDeferWindowPos(32); 5390 } 5391 5392 m_validationNestCount++; 5393 } 5394 5395 void AwtComponent::EndValidate() 5396 { 5397 DASSERT(m_validationNestCount > 0 && 5398 m_validationNestCount < 1000); // sanity check 5399 DASSERT(m_hdwp != NULL); 5400 5401 m_validationNestCount--; 5402 if (m_validationNestCount == 0) { 5403 // if this call to EndValidate is not nested inside another 5404 // Begin/EndValidate pair, end deferred window positioning 5405 ::EndDeferWindowPos(m_hdwp); 5406 m_hdwp = NULL; 5407 } 5408 } 5409 5410 /** 5411 * HWND, AwtComponent and Java Peer interaction 5412 */ 5413 5414 /* 5415 *Link the C++, Java peer, and HWNDs together. 5416 */ 5417 void AwtComponent::LinkObjects(JNIEnv *env, jobject peer) 5418 { 5419 /* 5420 * Bind all three objects together thru this C++ object, two-way to each: 5421 * JavaPeer <-> C++ <-> HWND 5422 * 5423 * C++ -> JavaPeer 5424 */ 5425 if (m_peerObject == NULL) { 5426 // This may have already been set up by CreateHWnd 5427 // And we don't want to create two references so we 5428 // will leave the prior one alone 5429 m_peerObject = env->NewGlobalRef(peer); 5430 } 5431 /* JavaPeer -> HWND */ 5432 env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd)); 5433 5434 /* JavaPeer -> C++ */ 5435 JNI_SET_PDATA(peer, this); 5436 5437 /* HWND -> C++ */ 5438 SetComponentInHWND(); 5439 } 5440 5441 /* Cleanup above linking */ 5442 void AwtComponent::UnlinkObjects() 5443 { 5444 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5445 if (m_peerObject) { 5446 env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); 5447 JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL)); 5448 JNI_SET_DESTROYED(m_peerObject); 5449 env->DeleteGlobalRef(m_peerObject); 5450 m_peerObject = NULL; 5451 } 5452 } 5453 5454 void AwtComponent::Enable(BOOL bEnable) 5455 { 5456 if (bEnable && IsTopLevel()) { 5457 // we should not enable blocked toplevels 5458 bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); 5459 } 5460 // Shouldn't trigger native focus change 5461 // (only the proxy may be the native focus owner). 5462 ::EnableWindow(GetHWnd(), bEnable); 5463 5464 CriticalSection::Lock l(GetLock()); 5465 VerifyState(); 5466 } 5467 5468 /* 5469 * associate an AwtDropTarget with this AwtComponent 5470 */ 5471 5472 AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) { 5473 m_dropTarget = new AwtDropTarget(env, this); 5474 m_dropTarget->RegisterTarget(TRUE); 5475 return m_dropTarget; 5476 } 5477 5478 /* 5479 * disassociate an AwtDropTarget with this AwtComponent 5480 */ 5481 5482 void AwtComponent::DestroyDropTarget() { 5483 if (m_dropTarget != NULL) { 5484 m_dropTarget->RegisterTarget(FALSE); 5485 m_dropTarget->Release(); 5486 m_dropTarget = NULL; 5487 } 5488 } 5489 5490 BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) { 5491 return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK; 5492 } 5493 5494 BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) { 5495 return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE; 5496 } 5497 5498 void AwtComponent::_Show(void *param) 5499 { 5500 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5501 5502 jobject self = (jobject)param; 5503 5504 AwtComponent *p; 5505 5506 PDATA pData; 5507 JNI_CHECK_PEER_GOTO(self, ret); 5508 p = (AwtComponent *)pData; 5509 if (::IsWindow(p->GetHWnd())) 5510 { 5511 p->SendMessage(WM_AWT_COMPONENT_SHOW); 5512 } 5513 ret: 5514 env->DeleteGlobalRef(self); 5515 } 5516 5517 void AwtComponent::_Hide(void *param) 5518 { 5519 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5520 5521 jobject self = (jobject)param; 5522 5523 AwtComponent *p; 5524 5525 PDATA pData; 5526 JNI_CHECK_PEER_GOTO(self, ret); 5527 p = (AwtComponent *)pData; 5528 if (::IsWindow(p->GetHWnd())) 5529 { 5530 p->SendMessage(WM_AWT_COMPONENT_HIDE); 5531 } 5532 ret: 5533 env->DeleteGlobalRef(self); 5534 } 5535 5536 void AwtComponent::_Enable(void *param) 5537 { 5538 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5539 5540 jobject self = (jobject)param; 5541 5542 AwtComponent *p; 5543 5544 PDATA pData; 5545 JNI_CHECK_PEER_GOTO(self, ret); 5546 p = (AwtComponent *)pData; 5547 if (::IsWindow(p->GetHWnd())) 5548 { 5549 p->Enable(TRUE); 5550 } 5551 ret: 5552 env->DeleteGlobalRef(self); 5553 } 5554 5555 void AwtComponent::_Disable(void *param) 5556 { 5557 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5558 5559 jobject self = (jobject)param; 5560 5561 AwtComponent *p; 5562 5563 PDATA pData; 5564 JNI_CHECK_PEER_GOTO(self, ret); 5565 p = (AwtComponent *)pData; 5566 if (::IsWindow(p->GetHWnd())) 5567 { 5568 p->Enable(FALSE); 5569 } 5570 ret: 5571 env->DeleteGlobalRef(self); 5572 } 5573 5574 jobject AwtComponent::_GetLocationOnScreen(void *param) 5575 { 5576 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5577 5578 jobject self = (jobject)param; 5579 5580 jobject result = NULL; 5581 AwtComponent *p; 5582 5583 PDATA pData; 5584 JNI_CHECK_PEER_GOTO(self, ret); 5585 p = (AwtComponent *)pData; 5586 if (::IsWindow(p->GetHWnd())) 5587 { 5588 RECT rect; 5589 VERIFY(::GetWindowRect(p->GetHWnd(),&rect)); 5590 result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", 5591 rect.left, rect.top); 5592 } 5593 ret: 5594 env->DeleteGlobalRef(self); 5595 5596 if (result != NULL) 5597 { 5598 jobject resultGlobalRef = env->NewGlobalRef(result); 5599 env->DeleteLocalRef(result); 5600 return resultGlobalRef; 5601 } 5602 else 5603 { 5604 return NULL; 5605 } 5606 } 5607 5608 void AwtComponent::_Reshape(void *param) 5609 { 5610 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5611 5612 ReshapeStruct *rs = (ReshapeStruct*)param; 5613 jobject self = rs->component; 5614 jint x = rs->x; 5615 jint y = rs->y; 5616 jint w = rs->w; 5617 jint h = rs->h; 5618 5619 AwtComponent *p; 5620 5621 PDATA pData; 5622 JNI_CHECK_PEER_GOTO(self, ret); 5623 p = (AwtComponent *)pData; 5624 if (::IsWindow(p->GetHWnd())) 5625 { 5626 RECT* r = new RECT; 5627 ::SetRect(r, x, y, x + w, y + h); 5628 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r); 5629 } 5630 ret: 5631 env->DeleteGlobalRef(self); 5632 5633 delete rs; 5634 } 5635 5636 void AwtComponent::_ReshapeNoCheck(void *param) 5637 { 5638 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5639 5640 ReshapeStruct *rs = (ReshapeStruct*)param; 5641 jobject self = rs->component; 5642 jint x = rs->x; 5643 jint y = rs->y; 5644 jint w = rs->w; 5645 jint h = rs->h; 5646 5647 AwtComponent *p; 5648 5649 PDATA pData; 5650 JNI_CHECK_PEER_GOTO(self, ret); 5651 p = (AwtComponent *)pData; 5652 if (::IsWindow(p->GetHWnd())) 5653 { 5654 RECT* r = new RECT; 5655 ::SetRect(r, x, y, x + w, y + h); 5656 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r); 5657 } 5658 ret: 5659 env->DeleteGlobalRef(self); 5660 5661 delete rs; 5662 } 5663 5664 void AwtComponent::_NativeHandleEvent(void *param) 5665 { 5666 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5667 5668 NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param; 5669 jobject self = nhes->component; 5670 jobject event = nhes->event; 5671 5672 AwtComponent *p; 5673 5674 PDATA pData; 5675 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5676 pData = JNI_GET_PDATA(self); 5677 if (pData == NULL) { 5678 env->DeleteGlobalRef(self); 5679 if (event != NULL) { 5680 env->DeleteGlobalRef(event); 5681 } 5682 delete nhes; 5683 return; 5684 } 5685 JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret); 5686 5687 p = (AwtComponent *)pData; 5688 if (::IsWindow(p->GetHWnd())) 5689 { 5690 if (env->EnsureLocalCapacity(1) < 0) { 5691 env->DeleteGlobalRef(self); 5692 env->DeleteGlobalRef(event); 5693 delete nhes; 5694 return; 5695 } 5696 jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID); 5697 int id = (env)->GetIntField(event, AwtAWTEvent::idID); 5698 DASSERT(!safe_ExceptionOccurred(env)); 5699 if (bdata != 0) { 5700 MSG msg; 5701 (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg); 5702 (env)->DeleteLocalRef(bdata); 5703 static BOOL keyDownConsumed = FALSE; 5704 static BOOL bCharChanged = FALSE; 5705 static WCHAR modifiedChar; 5706 WCHAR unicodeChar; 5707 5708 /* Remember if a KEY_PRESSED event is consumed, as an old model 5709 * program won't consume a subsequent KEY_TYPED event. 5710 */ 5711 jboolean consumed = 5712 (env)->GetBooleanField(event, AwtAWTEvent::consumedID); 5713 DASSERT(!safe_ExceptionOccurred(env)); 5714 5715 if (consumed) { 5716 keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED); 5717 env->DeleteGlobalRef(self); 5718 env->DeleteGlobalRef(event); 5719 delete nhes; 5720 return; 5721 5722 } else if (id == java_awt_event_KeyEvent_KEY_PRESSED) { 5723 // Fix for 6637607: reset consuming 5724 keyDownConsumed = FALSE; 5725 } 5726 5727 /* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support 5728 * the old model. 5729 */ 5730 if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) { 5731 keyDownConsumed = FALSE; 5732 env->DeleteGlobalRef(self); 5733 env->DeleteGlobalRef(event); 5734 delete nhes; 5735 return; 5736 } 5737 5738 /* Modify any event parameters, if necessary. */ 5739 if (self && pData && 5740 id >= java_awt_event_KeyEvent_KEY_FIRST && 5741 id <= java_awt_event_KeyEvent_KEY_LAST) { 5742 5743 AwtComponent* p = (AwtComponent*)pData; 5744 5745 jint keyCode = 5746 (env)->GetIntField(event, AwtKeyEvent::keyCodeID); 5747 jchar keyChar = 5748 (env)->GetCharField(event, AwtKeyEvent::keyCharID); 5749 jint modifiers = 5750 (env)->GetIntField(event, AwtInputEvent::modifiersID); 5751 5752 DASSERT(!safe_ExceptionOccurred(env)); 5753 5754 /* Check to see whether the keyCode or modifiers were changed 5755 on the keyPressed event, and tweak the following keyTyped 5756 event (if any) accodingly. */ 5757 switch (id) { 5758 case java_awt_event_KeyEvent_KEY_PRESSED: 5759 { 5760 UINT winKey = (UINT)msg.wParam; 5761 bCharChanged = FALSE; 5762 5763 if (winKey == VK_PROCESSKEY) { 5764 // Leave it up to IME 5765 break; 5766 } 5767 5768 if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) { 5769 UINT newWinKey, ignored; 5770 p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey); 5771 if (newWinKey != 0) { 5772 winKey = newWinKey; 5773 } 5774 } 5775 5776 BOOL isDeadKey = FALSE; 5777 modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey); 5778 bCharChanged = (keyChar != modifiedChar); 5779 } 5780 break; 5781 5782 case java_awt_event_KeyEvent_KEY_RELEASED: 5783 { 5784 keyDownConsumed = FALSE; 5785 bCharChanged = FALSE; 5786 } 5787 break; 5788 5789 case java_awt_event_KeyEvent_KEY_TYPED: 5790 { 5791 if (bCharChanged) 5792 { 5793 unicodeChar = modifiedChar; 5794 } 5795 else 5796 { 5797 unicodeChar = keyChar; 5798 } 5799 bCharChanged = FALSE; 5800 5801 // Disable forwarding KEY_TYPED messages to peers of 5802 // disabled components 5803 if (p->isRecursivelyEnabled()) { 5804 // send the character back to the native window for 5805 // processing. The WM_AWT_FORWARD_CHAR handler will send 5806 // this character to DefWindowProc 5807 if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR, 5808 MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) { 5809 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5810 } 5811 } 5812 env->DeleteGlobalRef(self); 5813 env->DeleteGlobalRef(event); 5814 delete nhes; 5815 return; 5816 } 5817 break; 5818 5819 default: 5820 break; 5821 } 5822 } 5823 5824 // ignore all InputMethodEvents 5825 if (self && (pData = JNI_GET_PDATA(self)) && 5826 id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && 5827 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) { 5828 env->DeleteGlobalRef(self); 5829 env->DeleteGlobalRef(event); 5830 delete nhes; 5831 return; 5832 } 5833 5834 // Create copy for local msg 5835 MSG* pCopiedMsg = new MSG; 5836 memmove(pCopiedMsg, &msg, sizeof(MSG)); 5837 // Event handler deletes msg 5838 p->PostHandleEventMessage(pCopiedMsg, FALSE); 5839 5840 env->DeleteGlobalRef(self); 5841 env->DeleteGlobalRef(event); 5842 delete nhes; 5843 return; 5844 } 5845 5846 /* Forward any valid synthesized events. Currently only mouse and 5847 * key events are supported. 5848 */ 5849 if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) { 5850 env->DeleteGlobalRef(self); 5851 env->DeleteGlobalRef(event); 5852 delete nhes; 5853 return; 5854 } 5855 5856 AwtComponent* p = (AwtComponent*)pData; 5857 if (id >= java_awt_event_KeyEvent_KEY_FIRST && 5858 id <= java_awt_event_KeyEvent_KEY_LAST) { 5859 p->SynthesizeKeyMessage(env, event); 5860 } else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST && 5861 id <= java_awt_event_MouseEvent_MOUSE_LAST) { 5862 p->SynthesizeMouseMessage(env, event); 5863 } 5864 } 5865 5866 ret: 5867 if (self != NULL) { 5868 env->DeleteGlobalRef(self); 5869 } 5870 if (event != NULL) { 5871 env->DeleteGlobalRef(event); 5872 } 5873 5874 delete nhes; 5875 } 5876 5877 void AwtComponent::_SetForeground(void *param) 5878 { 5879 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5880 5881 SetColorStruct *scs = (SetColorStruct *)param; 5882 jobject self = scs->component; 5883 jint rgb = scs->rgb; 5884 5885 AwtComponent *c = NULL; 5886 5887 PDATA pData; 5888 JNI_CHECK_PEER_GOTO(self, ret); 5889 c = (AwtComponent *)pData; 5890 if (::IsWindow(c->GetHWnd())) 5891 { 5892 c->SetColor(PALETTERGB((rgb>>16)&0xff, 5893 (rgb>>8)&0xff, 5894 (rgb)&0xff)); 5895 c->VerifyState(); 5896 } 5897 ret: 5898 env->DeleteGlobalRef(self); 5899 5900 delete scs; 5901 } 5902 5903 void AwtComponent::_SetBackground(void *param) 5904 { 5905 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5906 5907 SetColorStruct *scs = (SetColorStruct *)param; 5908 jobject self = scs->component; 5909 jint rgb = scs->rgb; 5910 5911 AwtComponent *c = NULL; 5912 5913 PDATA pData; 5914 JNI_CHECK_PEER_GOTO(self, ret); 5915 c = (AwtComponent *)pData; 5916 if (::IsWindow(c->GetHWnd())) 5917 { 5918 c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff, 5919 (rgb>>8)&0xff, 5920 (rgb)&0xff)); 5921 c->VerifyState(); 5922 } 5923 ret: 5924 env->DeleteGlobalRef(self); 5925 5926 delete scs; 5927 } 5928 5929 void AwtComponent::_SetFont(void *param) 5930 { 5931 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5932 5933 SetFontStruct *sfs = (SetFontStruct *)param; 5934 jobject self = sfs->component; 5935 jobject font = sfs->font; 5936 5937 AwtComponent *c = NULL; 5938 5939 PDATA pData; 5940 JNI_CHECK_PEER_GOTO(self, ret); 5941 JNI_CHECK_NULL_GOTO(font, "null font", ret); 5942 c = (AwtComponent *)pData; 5943 if (::IsWindow(c->GetHWnd())) 5944 { 5945 AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID); 5946 if (awtFont == NULL) { 5947 /*arguments of AwtFont::Create are changed for multifont component */ 5948 awtFont = AwtFont::Create(env, font); 5949 } 5950 env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont); 5951 5952 c->SetFont(awtFont); 5953 } 5954 ret: 5955 env->DeleteGlobalRef(self); 5956 env->DeleteGlobalRef(font); 5957 5958 delete sfs; 5959 } 5960 5961 // Sets or kills focus for a component. 5962 void AwtComponent::_SetFocus(void *param) 5963 { 5964 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5965 5966 SetFocusStruct *sfs = (SetFocusStruct *)param; 5967 jobject self = sfs->component; 5968 jboolean doSetFocus = sfs->doSetFocus; 5969 5970 AwtComponent *c = NULL; 5971 5972 PDATA pData; 5973 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5974 pData = JNI_GET_PDATA(self); 5975 if (pData == NULL) { 5976 // do nothing just return false 5977 goto ret; 5978 } 5979 5980 c = (AwtComponent *)pData; 5981 if (::IsWindow(c->GetHWnd())) { 5982 c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0); 5983 } 5984 ret: 5985 env->DeleteGlobalRef(self); 5986 5987 delete sfs; 5988 } 5989 5990 void AwtComponent::_Start(void *param) 5991 { 5992 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5993 5994 jobject self = (jobject)param; 5995 5996 AwtComponent *c = NULL; 5997 5998 PDATA pData; 5999 JNI_CHECK_PEER_GOTO(self, ret); 6000 c = (AwtComponent *)pData; 6001 if (::IsWindow(c->GetHWnd())) 6002 { 6003 jobject target = c->GetTarget(env); 6004 6005 /* Disable window if specified -- windows are enabled by default. */ 6006 jboolean enabled = (jboolean)env->GetBooleanField(target, 6007 AwtComponent::enabledID); 6008 if (!enabled) { 6009 ::EnableWindow(c->GetHWnd(), FALSE); 6010 } 6011 6012 /* The peer is now ready for callbacks, since this is the last 6013 * initialization call 6014 */ 6015 c->EnableCallbacks(TRUE); 6016 6017 // Fix 4745222: we need to invalidate region since we validated it before initialization. 6018 ::InvalidateRgn(c->GetHWnd(), NULL, FALSE); 6019 6020 // Fix 4530093: WM_PAINT after EnableCallbacks 6021 ::UpdateWindow(c->GetHWnd()); 6022 6023 env->DeleteLocalRef(target); 6024 } 6025 ret: 6026 env->DeleteGlobalRef(self); 6027 } 6028 6029 void AwtComponent::_BeginValidate(void *param) 6030 { 6031 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6032 if (AwtToolkit::IsMainThread()) { 6033 jobject self = (jobject)param; 6034 if (self != NULL) { 6035 PDATA pData = JNI_GET_PDATA(self); 6036 if (pData) { 6037 AwtComponent *c = (AwtComponent *)pData; 6038 if (::IsWindow(c->GetHWnd())) { 6039 c->SendMessage(WM_AWT_BEGIN_VALIDATE); 6040 } 6041 } 6042 env->DeleteGlobalRef(self); 6043 } 6044 } else { 6045 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param); 6046 } 6047 } 6048 6049 void AwtComponent::_EndValidate(void *param) 6050 { 6051 if (AwtToolkit::IsMainThread()) { 6052 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6053 jobject self = (jobject)param; 6054 if (self != NULL) { 6055 PDATA pData = JNI_GET_PDATA(self); 6056 if (pData) { 6057 AwtComponent *c = (AwtComponent *)pData; 6058 if (::IsWindow(c->GetHWnd())) { 6059 c->SendMessage(WM_AWT_END_VALIDATE); 6060 } 6061 } 6062 env->DeleteGlobalRef(self); 6063 } 6064 } else { 6065 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param); 6066 } 6067 } 6068 6069 void AwtComponent::_UpdateWindow(void *param) 6070 { 6071 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6072 if (AwtToolkit::IsMainThread()) { 6073 jobject self = (jobject)param; 6074 AwtComponent *c = NULL; 6075 PDATA pData; 6076 JNI_CHECK_PEER_GOTO(self, ret); 6077 c = (AwtComponent *)pData; 6078 if (::IsWindow(c->GetHWnd())) { 6079 ::UpdateWindow(c->GetHWnd()); 6080 } 6081 ret: 6082 env->DeleteGlobalRef(self); 6083 } else { 6084 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param); 6085 } 6086 } 6087 6088 jlong AwtComponent::_AddNativeDropTarget(void *param) 6089 { 6090 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6091 6092 jobject self = (jobject)param; 6093 6094 jlong result = 0; 6095 AwtComponent *c = NULL; 6096 6097 PDATA pData; 6098 JNI_CHECK_PEER_GOTO(self, ret); 6099 c = (AwtComponent *)pData; 6100 if (::IsWindow(c->GetHWnd())) 6101 { 6102 result = (jlong)(c->CreateDropTarget(env)); 6103 } 6104 ret: 6105 env->DeleteGlobalRef(self); 6106 6107 return result; 6108 } 6109 6110 void AwtComponent::_RemoveNativeDropTarget(void *param) 6111 { 6112 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6113 6114 jobject self = (jobject)param; 6115 6116 AwtComponent *c = NULL; 6117 6118 PDATA pData; 6119 JNI_CHECK_PEER_GOTO(self, ret); 6120 c = (AwtComponent *)pData; 6121 if (::IsWindow(c->GetHWnd())) 6122 { 6123 c->DestroyDropTarget(); 6124 } 6125 ret: 6126 env->DeleteGlobalRef(self); 6127 } 6128 6129 jintArray AwtComponent::_CreatePrintedPixels(void *param) 6130 { 6131 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6132 6133 CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param; 6134 jobject self = cpps->component; 6135 6136 jintArray result = NULL; 6137 AwtComponent *c = NULL; 6138 6139 PDATA pData; 6140 JNI_CHECK_PEER_GOTO(self, ret); 6141 c = (AwtComponent *)pData; 6142 if (::IsWindow(c->GetHWnd())) 6143 { 6144 result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0); 6145 } 6146 ret: 6147 env->DeleteGlobalRef(self); 6148 6149 delete cpps; 6150 return result; // this reference is global 6151 } 6152 6153 jboolean AwtComponent::_IsObscured(void *param) 6154 { 6155 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6156 6157 jobject self = (jobject)param; 6158 6159 jboolean result = JNI_FALSE; 6160 AwtComponent *c = NULL; 6161 6162 PDATA pData; 6163 JNI_CHECK_PEER_GOTO(self, ret); 6164 6165 c = (AwtComponent *)pData; 6166 6167 if (::IsWindow(c->GetHWnd())) 6168 { 6169 HWND hWnd = c->GetHWnd(); 6170 HDC hDC = ::GetDC(hWnd); 6171 RECT clipbox; 6172 int callresult = ::GetClipBox(hDC, &clipbox); 6173 switch(callresult) { 6174 case NULLREGION : 6175 result = JNI_FALSE; 6176 break; 6177 case SIMPLEREGION : { 6178 RECT windowRect; 6179 if (!::GetClientRect(hWnd, &windowRect)) { 6180 result = JNI_TRUE; 6181 } else { 6182 result = (jboolean)((clipbox.bottom != windowRect.bottom) 6183 || (clipbox.left != windowRect.left) 6184 || (clipbox.right != windowRect.right) 6185 || (clipbox.top != windowRect.top)); 6186 } 6187 break; 6188 } 6189 case COMPLEXREGION : 6190 default : 6191 result = JNI_TRUE; 6192 break; 6193 } 6194 ::ReleaseDC(hWnd, hDC); 6195 } 6196 ret: 6197 env->DeleteGlobalRef(self); 6198 6199 return result; 6200 } 6201 6202 jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param) 6203 { 6204 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6205 6206 jobject self = (jobject)param; 6207 6208 jboolean result = JNI_FALSE; 6209 AwtComponent *c = NULL; 6210 6211 PDATA pData; 6212 JNI_CHECK_PEER_GOTO(self, ret); 6213 c = (AwtComponent *)pData; 6214 if (::IsWindow(c->GetHWnd())) 6215 { 6216 result = JNI_IS_TRUE(c->InheritsNativeMouseWheelBehavior()); 6217 } 6218 ret: 6219 env->DeleteGlobalRef(self); 6220 6221 return result; 6222 } 6223 6224 void AwtComponent::_SetParent(void * param) 6225 { 6226 if (AwtToolkit::IsMainThread()) { 6227 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6228 SetParentStruct *data = (SetParentStruct*) param; 6229 jobject self = data->component; 6230 jobject parent = data->parentComp; 6231 6232 AwtComponent *awtComponent = NULL; 6233 AwtComponent *awtParent = NULL; 6234 6235 PDATA pData; 6236 JNI_CHECK_PEER_GOTO(self, ret); 6237 awtComponent = (AwtComponent *)pData; 6238 JNI_CHECK_PEER_GOTO(parent, ret); 6239 awtParent = (AwtComponent *)pData; 6240 6241 HWND selfWnd = awtComponent->GetHWnd(); 6242 HWND parentWnd = awtParent->GetHWnd(); 6243 if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) { 6244 // Shouldn't trigger native focus change 6245 // (only the proxy may be the native focus owner). 6246 ::SetParent(selfWnd, parentWnd); 6247 } 6248 ret: 6249 env->DeleteGlobalRef(self); 6250 env->DeleteGlobalRef(parent); 6251 delete data; 6252 } else { 6253 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetParent, param); 6254 } 6255 } 6256 6257 void AwtComponent::_SetRectangularShape(void *param) 6258 { 6259 if (!AwtToolkit::IsMainThread()) { 6260 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param); 6261 } else { 6262 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6263 6264 SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param; 6265 jobject self = data->component; 6266 jint x1 = data->x1; 6267 jint x2 = data->x2; 6268 jint y1 = data->y1; 6269 jint y2 = data->y2; 6270 jobject region = data->region; 6271 6272 AwtComponent *c = NULL; 6273 6274 PDATA pData; 6275 JNI_CHECK_PEER_GOTO(self, ret); 6276 6277 c = (AwtComponent *)pData; 6278 if (::IsWindow(c->GetHWnd())) { 6279 HRGN hRgn = NULL; 6280 6281 // If all the params are zeros, the shape must be simply reset. 6282 // Otherwise, convert it into a region. 6283 if (region || x1 || x2 || y1 || y2) { 6284 RECT_T rects[256]; 6285 RECT_T *pRect = rects; 6286 6287 const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, 6288 region, &pRect, sizeof(rects)/sizeof(rects[0])); 6289 if (!pRect) { 6290 // RegionToYXBandedRectangles doesn't use safe_Malloc(), 6291 // so throw the exception explicitly 6292 throw std::bad_alloc(); 6293 } 6294 6295 RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, 6296 sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects); 6297 memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects); 6298 if (pRect != rects) { 6299 free(pRect); 6300 } 6301 pRect = NULL; 6302 6303 RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData; 6304 pRgnHdr->dwSize = sizeof(RGNDATAHEADER); 6305 pRgnHdr->iType = RDH_RECTANGLES; 6306 pRgnHdr->nRgnSize = 0; 6307 pRgnHdr->rcBound.top = 0; 6308 pRgnHdr->rcBound.left = 0; 6309 pRgnHdr->rcBound.bottom = LONG(y2 - y1); 6310 pRgnHdr->rcBound.right = LONG(x2 - x1); 6311 pRgnHdr->nCount = numrects; 6312 6313 hRgn = ::ExtCreateRegion(NULL, 6314 sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData); 6315 6316 free(pRgnData); 6317 } 6318 6319 ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE); 6320 } 6321 6322 ret: 6323 env->DeleteGlobalRef(self); 6324 if (region) { 6325 env->DeleteGlobalRef(region); 6326 } 6327 6328 delete data; 6329 } 6330 } 6331 6332 void AwtComponent::_SetZOrder(void *param) { 6333 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6334 6335 SetZOrderStruct *data = (SetZOrderStruct *)param; 6336 jobject self = data->component; 6337 HWND above = HWND_TOP; 6338 if (data->above != 0) { 6339 above = reinterpret_cast<HWND>(data->above); 6340 } 6341 6342 AwtComponent *c = NULL; 6343 6344 PDATA pData; 6345 JNI_CHECK_PEER_GOTO(self, ret); 6346 6347 c = (AwtComponent *)pData; 6348 if (::IsWindow(c->GetHWnd())) { 6349 ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0, 6350 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS); 6351 } 6352 6353 ret: 6354 env->DeleteGlobalRef(self); 6355 6356 delete data; 6357 } 6358 6359 void AwtComponent::PostUngrabEvent() { 6360 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6361 jobject target = GetTarget(env); 6362 jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V", 6363 target); 6364 if (safe_ExceptionOccurred(env)) { 6365 env->ExceptionDescribe(); 6366 env->ExceptionClear(); 6367 } 6368 env->DeleteLocalRef(target); 6369 if (event != NULL) { 6370 SendEvent(event); 6371 env->DeleteLocalRef(event); 6372 } 6373 } 6374 6375 void AwtComponent::SetFocusedWindow(HWND window) 6376 { 6377 HWND old = sm_focusedWindow; 6378 sm_focusedWindow = window; 6379 6380 AwtWindow::FocusedWindowChanged(old, window); 6381 } 6382 6383 /************************************************************************ 6384 * Component native methods 6385 */ 6386 6387 extern "C" { 6388 6389 /** 6390 * This method is called from the WGL pipeline when it needs to retrieve 6391 * the HWND associated with a ComponentPeer's C++ level object. 6392 */ 6393 HWND 6394 AwtComponent_GetHWnd(JNIEnv *env, jlong pData) 6395 { 6396 AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData); 6397 if (p == NULL) { 6398 return (HWND)0; 6399 } 6400 return p->GetHWnd(); 6401 } 6402 6403 static void _GetInsets(void* param) 6404 { 6405 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6406 6407 GetInsetsStruct *gis = (GetInsetsStruct *)param; 6408 jobject self = gis->window; 6409 6410 gis->insets->left = gis->insets->top = 6411 gis->insets->right = gis->insets->bottom = 0; 6412 6413 PDATA pData; 6414 JNI_CHECK_PEER_GOTO(self, ret); 6415 AwtComponent *component = (AwtComponent *)pData; 6416 6417 component->GetInsets(gis->insets); 6418 6419 ret: 6420 env->DeleteGlobalRef(self); 6421 delete gis; 6422 } 6423 6424 /** 6425 * This method is called from the WGL pipeline when it needs to retrieve 6426 * the insets associated with a ComponentPeer's C++ level object. 6427 */ 6428 void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets) 6429 { 6430 TRY; 6431 6432 GetInsetsStruct *gis = new GetInsetsStruct; 6433 gis->window = env->NewGlobalRef(peer); 6434 gis->insets = insets; 6435 6436 AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis); 6437 // global refs and mds are deleted in _UpdateWindow 6438 6439 CATCH_BAD_ALLOC; 6440 6441 } 6442 6443 JNIEXPORT void JNICALL 6444 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) 6445 { 6446 TRY; 6447 jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent"); 6448 CHECK_NULL(inputEventClazz); 6449 jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I"); 6450 CHECK_NULL(getButtonDownMasksID); 6451 jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID); 6452 jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE); 6453 CHECK_NULL(tmp); 6454 jsize len = env->GetArrayLength(obj); 6455 AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len); 6456 for (int i = 0; i < len; i++) { 6457 AwtComponent::masks[i] = tmp[i]; 6458 } 6459 env->ReleaseIntArrayElements(obj, tmp, 0); 6460 env->DeleteLocalRef(obj); 6461 6462 /* class ids */ 6463 jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer"); 6464 6465 DASSERT(peerCls); 6466 CHECK_NULL(peerCls); 6467 6468 /* field ids */ 6469 AwtComponent::peerID = 6470 env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;"); 6471 DASSERT(AwtComponent::peerID); 6472 CHECK_NULL(AwtComponent::peerID); 6473 6474 AwtComponent::xID = env->GetFieldID(cls, "x", "I"); 6475 DASSERT(AwtComponent::xID); 6476 CHECK_NULL(AwtComponent::xID); 6477 6478 AwtComponent::yID = env->GetFieldID(cls, "y", "I"); 6479 DASSERT(AwtComponent::yID); 6480 CHECK_NULL(AwtComponent::yID); 6481 6482 AwtComponent::heightID = env->GetFieldID(cls, "height", "I"); 6483 DASSERT(AwtComponent::heightID); 6484 CHECK_NULL(AwtComponent::heightID); 6485 6486 AwtComponent::widthID = env->GetFieldID(cls, "width", "I"); 6487 DASSERT(AwtComponent::widthID); 6488 CHECK_NULL(AwtComponent::widthID); 6489 6490 AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z"); 6491 DASSERT(AwtComponent::visibleID); 6492 CHECK_NULL(AwtComponent::visibleID); 6493 6494 AwtComponent::backgroundID = 6495 env->GetFieldID(cls, "background", "Ljava/awt/Color;"); 6496 DASSERT(AwtComponent::backgroundID); 6497 CHECK_NULL(AwtComponent::backgroundID); 6498 6499 AwtComponent::foregroundID = 6500 env->GetFieldID(cls, "foreground", "Ljava/awt/Color;"); 6501 DASSERT(AwtComponent::foregroundID); 6502 CHECK_NULL(AwtComponent::foregroundID); 6503 6504 AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z"); 6505 DASSERT(AwtComponent::enabledID); 6506 CHECK_NULL(AwtComponent::enabledID); 6507 6508 AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;"); 6509 DASSERT(AwtComponent::parentID); 6510 CHECK_NULL(AwtComponent::parentID); 6511 6512 AwtComponent::graphicsConfigID = 6513 env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;"); 6514 DASSERT(AwtComponent::graphicsConfigID); 6515 CHECK_NULL(AwtComponent::graphicsConfigID); 6516 6517 AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z"); 6518 DASSERT(AwtComponent::focusableID); 6519 CHECK_NULL(AwtComponent::focusableID); 6520 6521 AwtComponent::appContextID = env->GetFieldID(cls, "appContext", 6522 "Lsun/awt/AppContext;"); 6523 DASSERT(AwtComponent::appContextID); 6524 CHECK_NULL(AwtComponent::appContextID); 6525 6526 AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig", 6527 "Lsun/awt/Win32GraphicsConfig;"); 6528 DASSERT(AwtComponent::peerGCID); 6529 CHECK_NULL(AwtComponent::peerGCID); 6530 6531 AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J"); 6532 DASSERT(AwtComponent::hwndID); 6533 CHECK_NULL(AwtComponent::hwndID); 6534 6535 AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;"); 6536 DASSERT(AwtComponent::cursorID); 6537 CHECK_NULL(AwtComponent::cursorID); 6538 6539 /* method ids */ 6540 AwtComponent::getFontMID = 6541 env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;"); 6542 DASSERT(AwtComponent::getFontMID); 6543 CHECK_NULL(AwtComponent::getFontMID); 6544 6545 AwtComponent::getToolkitMID = 6546 env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;"); 6547 DASSERT(AwtComponent::getToolkitMID); 6548 CHECK_NULL(AwtComponent::getToolkitMID); 6549 6550 AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z"); 6551 DASSERT(AwtComponent::isEnabledMID); 6552 CHECK_NULL(AwtComponent::isEnabledMID); 6553 6554 AwtComponent::getLocationOnScreenMID = 6555 env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;"); 6556 DASSERT(AwtComponent::getLocationOnScreenMID); 6557 CHECK_NULL(AwtComponent::getLocationOnScreenMID); 6558 6559 AwtComponent::replaceSurfaceDataMID = 6560 env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); 6561 DASSERT(AwtComponent::replaceSurfaceDataMID); 6562 CHECK_NULL(AwtComponent::replaceSurfaceDataMID); 6563 6564 AwtComponent::replaceSurfaceDataLaterMID = 6565 env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); 6566 DASSERT(AwtComponent::replaceSurfaceDataLaterMID); 6567 CHECK_NULL(AwtComponent::replaceSurfaceDataLaterMID); 6568 6569 AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V"); 6570 DASSERT(AwtComponent::disposeLaterMID); 6571 CHECK_NULL(AwtComponent::disposeLaterMID); 6572 6573 CATCH_BAD_ALLOC; 6574 } 6575 6576 } /* extern "C" */ 6577 6578 6579 /************************************************************************ 6580 * ComponentPeer native methods 6581 */ 6582 6583 extern "C" { 6584 6585 /* 6586 * Class: sun_awt_windows_WComponentPeer 6587 * Method: pShow 6588 * Signature: ()V 6589 */ 6590 JNIEXPORT void JNICALL 6591 Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self) 6592 { 6593 TRY; 6594 6595 jobject selfGlobalRef = env->NewGlobalRef(self); 6596 6597 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef); 6598 // selfGlobalRef is deleted in _Show 6599 6600 CATCH_BAD_ALLOC; 6601 } 6602 6603 /* 6604 * Class: sun_awt_windows_WComponentPeer 6605 * Method: hide 6606 * Signature: ()V 6607 */ 6608 JNIEXPORT void JNICALL 6609 Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self) 6610 { 6611 TRY; 6612 6613 jobject selfGlobalRef = env->NewGlobalRef(self); 6614 6615 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef); 6616 // selfGlobalRef is deleted in _Hide 6617 6618 CATCH_BAD_ALLOC; 6619 } 6620 6621 /* 6622 * Class: sun_awt_windows_WComponentPeer 6623 * Method: enable 6624 * Signature: ()V 6625 */ 6626 JNIEXPORT void JNICALL 6627 Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self) 6628 { 6629 TRY; 6630 6631 jobject selfGlobalRef = env->NewGlobalRef(self); 6632 6633 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef); 6634 // selfGlobalRef is deleted in _Enable 6635 6636 CATCH_BAD_ALLOC; 6637 } 6638 6639 /* 6640 * Class: sun_awt_windows_WComponentPeer 6641 * Method: disable 6642 * Signature: ()V 6643 */ 6644 JNIEXPORT void JNICALL 6645 Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self) 6646 { 6647 TRY; 6648 6649 jobject selfGlobalRef = env->NewGlobalRef(self); 6650 6651 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef); 6652 // selfGlobalRef is deleted in _Disable 6653 6654 CATCH_BAD_ALLOC; 6655 } 6656 6657 /* 6658 * Class: sun_awt_windows_WComponentPeer 6659 * Method: getLocationOnScreen 6660 * Signature: ()Ljava/awt/Point; 6661 */ 6662 JNIEXPORT jobject JNICALL 6663 Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self) 6664 { 6665 TRY; 6666 6667 jobject selfGlobalRef = env->NewGlobalRef(self); 6668 6669 jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall( 6670 (void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef); 6671 // selfGlobalRef is deleted in _GetLocationOnScreen 6672 if (resultGlobalRef != NULL) 6673 { 6674 jobject resultLocalRef = env->NewLocalRef(resultGlobalRef); 6675 env->DeleteGlobalRef(resultGlobalRef); 6676 return resultLocalRef; 6677 } 6678 6679 return NULL; 6680 6681 CATCH_BAD_ALLOC_RET(NULL); 6682 } 6683 6684 /* 6685 * Class: sun_awt_windows_WComponentPeer 6686 * Method: reshape 6687 * Signature: (IIII)V 6688 */ 6689 JNIEXPORT void JNICALL 6690 Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self, 6691 jint x, jint y, jint w, jint h) 6692 { 6693 TRY; 6694 6695 ReshapeStruct *rs = new ReshapeStruct; 6696 rs->component = env->NewGlobalRef(self); 6697 rs->x = x; 6698 rs->y = y; 6699 rs->w = w; 6700 rs->h = h; 6701 6702 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs); 6703 // global ref and rs are deleted in _Reshape 6704 6705 CATCH_BAD_ALLOC; 6706 } 6707 6708 /* 6709 * Class: sun_awt_windows_WComponentPeer 6710 * Method: reshape 6711 * Signature: (IIII)V 6712 */ 6713 JNIEXPORT void JNICALL 6714 Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self, 6715 jint x, jint y, jint w, jint h) 6716 { 6717 TRY; 6718 6719 ReshapeStruct *rs = new ReshapeStruct; 6720 rs->component = env->NewGlobalRef(self); 6721 rs->x = x; 6722 rs->y = y; 6723 rs->w = w; 6724 rs->h = h; 6725 6726 AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs); 6727 // global ref and rs are deleted in _ReshapeNoCheck 6728 6729 CATCH_BAD_ALLOC; 6730 } 6731 6732 6733 /* 6734 * Class: sun_awt_windows_WComponentPeer 6735 * Method: nativeHandleEvent 6736 * Signature: (Ljava/awt/AWTEvent;)V 6737 */ 6738 JNIEXPORT void JNICALL 6739 Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env, 6740 jobject self, 6741 jobject event) 6742 { 6743 TRY; 6744 6745 jobject selfGlobalRef = env->NewGlobalRef(self); 6746 jobject eventGlobalRef = env->NewGlobalRef(event); 6747 6748 NativeHandleEventStruct *nhes = new NativeHandleEventStruct; 6749 nhes->component = selfGlobalRef; 6750 nhes->event = eventGlobalRef; 6751 6752 AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes); 6753 // global refs and nhes are deleted in _NativeHandleEvent 6754 6755 CATCH_BAD_ALLOC; 6756 } 6757 6758 /* 6759 * Class: sun_awt_windows_WComponentPeer 6760 * Method: _dispose 6761 * Signature: ()V 6762 */ 6763 JNIEXPORT void JNICALL 6764 Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) 6765 { 6766 TRY_NO_HANG; 6767 6768 AwtObject::_Dispose(self); 6769 6770 CATCH_BAD_ALLOC; 6771 } 6772 6773 /* 6774 * Class: sun_awt_windows_WComponentPeer 6775 * Method: _setForeground 6776 * Signature: (I)V 6777 */ 6778 JNIEXPORT void JNICALL 6779 Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self, 6780 jint rgb) 6781 { 6782 TRY; 6783 6784 jobject selfGlobalRef = env->NewGlobalRef(self); 6785 6786 SetColorStruct *scs = new SetColorStruct; 6787 scs->component = selfGlobalRef; 6788 scs->rgb = rgb; 6789 6790 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs); 6791 // selfGlobalRef and scs are deleted in _SetForeground() 6792 6793 CATCH_BAD_ALLOC; 6794 } 6795 6796 /* 6797 * Class: sun_awt_windows_WComponentPeer 6798 * Method: _setBackground 6799 * Signature: (I)V 6800 */ 6801 JNIEXPORT void JNICALL 6802 Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self, 6803 jint rgb) 6804 { 6805 TRY; 6806 6807 jobject selfGlobalRef = env->NewGlobalRef(self); 6808 6809 SetColorStruct *scs = new SetColorStruct; 6810 scs->component = selfGlobalRef; 6811 scs->rgb = rgb; 6812 6813 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs); 6814 // selfGlobalRef and scs are deleted in _SetBackground() 6815 6816 CATCH_BAD_ALLOC; 6817 } 6818 6819 /* 6820 * Class: sun_awt_windows_WComponentPeer 6821 * Method: _setFont 6822 * Signature: (Ljava/awt/Font;)V 6823 */ 6824 JNIEXPORT void JNICALL 6825 Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self, 6826 jobject font) 6827 { 6828 TRY; 6829 6830 jobject selfGlobalRef = env->NewGlobalRef(self); 6831 jobject fontGlobalRef = env->NewGlobalRef(font); 6832 6833 SetFontStruct *sfs = new SetFontStruct; 6834 sfs->component = selfGlobalRef; 6835 sfs->font = fontGlobalRef; 6836 6837 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs); 6838 // global refs and sfs are deleted in _SetFont() 6839 6840 CATCH_BAD_ALLOC; 6841 } 6842 6843 /* 6844 * Class: sun_awt_windows_WComponentPeer 6845 * Method: focusGained 6846 * Signature: (Z) 6847 */ 6848 JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus 6849 (JNIEnv *env, jobject self, jboolean doSetFocus) 6850 { 6851 TRY; 6852 6853 jobject selfGlobalRef = env->NewGlobalRef(self); 6854 6855 SetFocusStruct *sfs = new SetFocusStruct; 6856 sfs->component = selfGlobalRef; 6857 sfs->doSetFocus = doSetFocus; 6858 6859 AwtToolkit::GetInstance().SyncCall( 6860 (void*(*)(void*))AwtComponent::_SetFocus, sfs); 6861 // global refs and self are deleted in _SetFocus 6862 6863 CATCH_BAD_ALLOC; 6864 } 6865 6866 /* 6867 * Class: sun_awt_windows_WComponentPeer 6868 * Method: start 6869 * Signature: ()V 6870 */ 6871 JNIEXPORT void JNICALL 6872 Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self) 6873 { 6874 TRY; 6875 6876 jobject selfGlobalRef = env->NewGlobalRef(self); 6877 6878 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef); 6879 // selfGlobalRef is deleted in _Start 6880 6881 CATCH_BAD_ALLOC; 6882 } 6883 6884 /* 6885 * Class: sun_awt_windows_WComponentPeer 6886 * Method: beginValidate 6887 * Signature: ()V 6888 */ 6889 JNIEXPORT void JNICALL 6890 Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self) 6891 { 6892 TRY; 6893 6894 jobject selfGlobalRef = env->NewGlobalRef(self); 6895 6896 AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef); 6897 // selfGlobalRef is deleted in _BeginValidate 6898 6899 CATCH_BAD_ALLOC; 6900 } 6901 6902 /* 6903 * Class: sun_awt_windows_WComponentPeer 6904 * Method: endValidate 6905 * Signature: ()V 6906 */ 6907 JNIEXPORT void JNICALL 6908 Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self) 6909 { 6910 TRY; 6911 6912 jobject selfGlobalRef = env->NewGlobalRef(self); 6913 6914 AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef); 6915 // selfGlobalRef is deleted in _EndValidate 6916 6917 CATCH_BAD_ALLOC; 6918 } 6919 6920 JNIEXPORT void JNICALL 6921 Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self) 6922 { 6923 TRY; 6924 6925 jobject selfGlobalRef = env->NewGlobalRef(self); 6926 6927 AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef); 6928 // selfGlobalRef is deleted in _UpdateWindow 6929 6930 CATCH_BAD_ALLOC; 6931 } 6932 6933 /* 6934 * Class: sun_awt_windows_WComponentPeer 6935 * Method: addNativeDropTarget 6936 * Signature: ()L 6937 */ 6938 6939 JNIEXPORT jlong JNICALL 6940 Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env, 6941 jobject self) 6942 { 6943 TRY; 6944 6945 jobject selfGlobalRef = env->NewGlobalRef(self); 6946 6947 return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall( 6948 (void*(*)(void*))AwtComponent::_AddNativeDropTarget, 6949 (void *)selfGlobalRef)); 6950 // selfGlobalRef is deleted in _AddNativeDropTarget 6951 6952 CATCH_BAD_ALLOC_RET(0); 6953 } 6954 6955 /* 6956 * Class: sun_awt_windows_WComponentPeer 6957 * Method: removeNativeDropTarget 6958 * Signature: ()V 6959 */ 6960 6961 JNIEXPORT void JNICALL 6962 Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env, 6963 jobject self) 6964 { 6965 TRY; 6966 6967 jobject selfGlobalRef = env->NewGlobalRef(self); 6968 6969 AwtToolkit::GetInstance().SyncCall( 6970 AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef); 6971 // selfGlobalRef is deleted in _RemoveNativeDropTarget 6972 6973 CATCH_BAD_ALLOC; 6974 } 6975 6976 /* 6977 * Class: sun_awt_windows_WComponentPeer 6978 * Method: getTargetGC 6979 * Signature: ()Ljava/awt/GraphicsConfiguration; 6980 */ 6981 JNIEXPORT jobject JNICALL 6982 Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis) 6983 { 6984 TRY; 6985 6986 jobject targetObj; 6987 jobject gc = 0; 6988 6989 targetObj = env->GetObjectField(theThis, AwtObject::targetID); 6990 DASSERT(targetObj); 6991 6992 gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID); 6993 return gc; 6994 6995 CATCH_BAD_ALLOC_RET(NULL); 6996 } 6997 6998 /* 6999 * Class: sun_awt_windows_WComponentPeer 7000 * Method: createPrintedPixels 7001 * Signature: (IIIIII)I[ 7002 */ 7003 JNIEXPORT jintArray JNICALL 7004 Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, 7005 jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha) 7006 { 7007 TRY; 7008 7009 jobject selfGlobalRef = env->NewGlobalRef(self); 7010 7011 CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct; 7012 cpps->component = selfGlobalRef; 7013 cpps->srcx = srcX; 7014 cpps->srcy = srcY; 7015 cpps->srcw = srcW; 7016 cpps->srch = srcH; 7017 cpps->alpha = alpha; 7018 7019 jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall( 7020 (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps); 7021 // selfGlobalRef and cpps are deleted in _CreatePrintedPixels 7022 if (globalRef != NULL) 7023 { 7024 jintArray localRef = (jintArray)env->NewLocalRef(globalRef); 7025 env->DeleteGlobalRef(globalRef); 7026 return localRef; 7027 } 7028 else 7029 { 7030 return NULL; 7031 } 7032 7033 CATCH_BAD_ALLOC_RET(NULL); 7034 } 7035 7036 /* 7037 * Class: sun_awt_windows_WComponentPeer 7038 * Method: nativeHandlesWheelScrolling 7039 * Signature: ()Z 7040 */ 7041 JNIEXPORT jboolean JNICALL 7042 Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env, 7043 jobject self) 7044 { 7045 TRY; 7046 7047 return (jboolean)AwtToolkit::GetInstance().SyncCall( 7048 (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling, 7049 env->NewGlobalRef(self)); 7050 // global ref is deleted in _NativeHandlesWheelScrolling 7051 7052 CATCH_BAD_ALLOC_RET(NULL); 7053 } 7054 7055 /* 7056 * Class: sun_awt_windows_WComponentPeer 7057 * Method: isObscured 7058 * Signature: ()Z 7059 */ 7060 JNIEXPORT jboolean JNICALL 7061 Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env, 7062 jobject self) 7063 { 7064 TRY; 7065 7066 jobject selfGlobalRef = env->NewGlobalRef(self); 7067 7068 return (jboolean)AwtToolkit::GetInstance().SyncCall( 7069 (void*(*)(void*))AwtComponent::_IsObscured, 7070 (void *)selfGlobalRef); 7071 // selfGlobalRef is deleted in _IsObscured 7072 7073 CATCH_BAD_ALLOC_RET(NULL); 7074 } 7075 7076 JNIEXPORT void JNICALL 7077 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) { 7078 TRY; 7079 7080 SetParentStruct * data = new SetParentStruct; 7081 data->component = env->NewGlobalRef(self); 7082 data->parentComp = env->NewGlobalRef(parent); 7083 7084 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetParent, data); 7085 // global refs and data are deleted in SetParent 7086 7087 CATCH_BAD_ALLOC; 7088 } 7089 7090 JNIEXPORT void JNICALL 7091 Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self, 7092 jint x1, jint y1, jint x2, jint y2, jobject region) 7093 { 7094 TRY; 7095 7096 SetRectangularShapeStruct * data = new SetRectangularShapeStruct; 7097 data->component = env->NewGlobalRef(self); 7098 data->x1 = x1; 7099 data->x2 = x2; 7100 data->y1 = y1; 7101 data->y2 = y2; 7102 if (region) { 7103 data->region = env->NewGlobalRef(region); 7104 } else { 7105 data->region = NULL; 7106 } 7107 7108 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data); 7109 // global refs and data are deleted in _SetRectangularShape 7110 7111 CATCH_BAD_ALLOC; 7112 } 7113 7114 JNIEXPORT void JNICALL 7115 Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above) 7116 { 7117 TRY; 7118 7119 SetZOrderStruct * data = new SetZOrderStruct; 7120 data->component = env->NewGlobalRef(self); 7121 data->above = above; 7122 7123 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data); 7124 // global refs and data are deleted in _SetLower 7125 7126 CATCH_BAD_ALLOC; 7127 } 7128 7129 } /* extern "C" */ 7130 7131 7132 /************************************************************************ 7133 * Diagnostic routines 7134 */ 7135 7136 #ifdef DEBUG 7137 7138 void AwtComponent::VerifyState() 7139 { 7140 if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { 7141 return; 7142 } 7143 7144 if (m_callbacksEnabled == FALSE) { 7145 /* Component is not fully setup yet. */ 7146 return; 7147 } 7148 7149 /* Get target bounds. */ 7150 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 7151 if (env->PushLocalFrame(10) < 0) 7152 return; 7153 7154 jobject target = GetTarget(env); 7155 7156 jint x = env->GetIntField(target, AwtComponent::xID); 7157 jint y = env->GetIntField(target, AwtComponent::yID); 7158 jint width = env->GetIntField(target, AwtComponent::widthID); 7159 jint height = env->GetIntField(target, AwtComponent::heightID); 7160 7161 /* Convert target origin to absolute coordinates */ 7162 while (TRUE) { 7163 7164 jobject parent = env->GetObjectField(target, AwtComponent::parentID); 7165 if (parent == NULL) { 7166 break; 7167 } 7168 x += env->GetIntField(parent, AwtComponent::xID); 7169 y += env->GetIntField(parent, AwtComponent::yID); 7170 7171 /* If this component has insets, factor them in, but ignore 7172 * top-level windows. 7173 */ 7174 jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID); 7175 if (parent2 != NULL) { 7176 jobject peer = GetPeerForTarget(env, parent); 7177 if (peer != NULL && 7178 JNU_IsInstanceOfByName(env, peer, 7179 "sun/awt/windows/WPanelPeer") > 0) { 7180 jobject insets = 7181 JNU_CallMethodByName(env, NULL, peer,"insets", 7182 "()Ljava/awt/Insets;").l; 7183 x += (env)->GetIntField(insets, AwtInsets::leftID); 7184 y += (env)->GetIntField(insets, AwtInsets::topID); 7185 } 7186 } 7187 env->DeleteLocalRef(target); 7188 target = parent; 7189 } 7190 7191 // Test whether component's bounds match the native window's 7192 RECT rect; 7193 VERIFY(::GetWindowRect(GetHWnd(), &rect)); 7194 #if 0 7195 DASSERT( (x == rect.left) && 7196 (y == rect.top) && 7197 (width == (rect.right-rect.left)) && 7198 (height == (rect.bottom-rect.top)) ); 7199 #else 7200 BOOL fSizeValid = ( (x == rect.left) && 7201 (y == rect.top) && 7202 (width == (rect.right-rect.left)) && 7203 (height == (rect.bottom-rect.top)) ); 7204 #endif 7205 7206 // See if visible state matches 7207 BOOL wndVisible = ::IsWindowVisible(GetHWnd()); 7208 jboolean targetVisible; 7209 // To avoid possibly running client code on the toolkit thread, don't 7210 // do the following check if we're running on the toolkit thread. 7211 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7212 targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env), 7213 "isShowing", "()Z").z; 7214 DASSERT(!safe_ExceptionOccurred(env)); 7215 } else { 7216 targetVisible = wndVisible ? 1 : 0; 7217 } 7218 #if 0 7219 DASSERT( (targetVisible && wndVisible) || 7220 (!targetVisible && !wndVisible) ); 7221 #else 7222 BOOL fVisibleValid = ( (targetVisible && wndVisible) || 7223 (!targetVisible && !wndVisible) ); 7224 #endif 7225 7226 // Check enabled state 7227 BOOL wndEnabled = ::IsWindowEnabled(GetHWnd()); 7228 jboolean enabled = (jboolean)env->GetBooleanField(target, 7229 AwtComponent::enabledID); 7230 #if 0 7231 DASSERT( (enabled && wndEnabled) || 7232 (!enabled && !wndEnabled) ); 7233 #else 7234 BOOL fEnabledValid = ((enabled && wndEnabled) || 7235 (!(enabled && !wndEnabled) )); 7236 7237 if (!fSizeValid || !fVisibleValid || !fEnabledValid) { 7238 printf("AwtComponent::ValidateState() failed:\n"); 7239 // To avoid possibly running client code on the toolkit thread, don't 7240 // do the following call if we're running on the toolkit thread. 7241 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7242 jstring targetStr = 7243 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), 7244 "getName", 7245 "()Ljava/lang/String;").l; 7246 DASSERT(!safe_ExceptionOccurred(env)); 7247 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 7248 printf("\t%S\n", targetStrW); 7249 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 7250 } 7251 printf("\twas: [%d,%d,%dx%d]\n", x, y, width, height); 7252 if (!fSizeValid) { 7253 printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top, 7254 rect.right-rect.left, rect.bottom-rect.top); 7255 } 7256 if (!fVisibleValid) { 7257 printf("\tshould be: %s\n", 7258 (targetVisible) ? "visible" : "hidden"); 7259 } 7260 if (!fEnabledValid) { 7261 printf("\tshould be: %s\n", 7262 enabled ? "enabled" : "disabled"); 7263 } 7264 } 7265 #endif 7266 env->PopLocalFrame(0); 7267 } 7268 #endif //DEBUG 7269 7270 // Methods for globally managed DC list 7271 7272 /** 7273 * Add a new DC to the DC list for this component. 7274 */ 7275 void DCList::AddDC(HDC hDC, HWND hWnd) 7276 { 7277 DCItem *newItem = new DCItem; 7278 newItem->hDC = hDC; 7279 newItem->hWnd = hWnd; 7280 AddDCItem(newItem); 7281 } 7282 7283 void DCList::AddDCItem(DCItem *newItem) 7284 { 7285 listLock.Enter(); 7286 newItem->next = head; 7287 head = newItem; 7288 listLock.Leave(); 7289 } 7290 7291 /** 7292 * Given a DC and window handle, remove the DC from the DC list 7293 * and return TRUE if it exists on the current list. Otherwise 7294 * return FALSE. 7295 * A DC may not exist on the list because it has already 7296 * been released elsewhere (for example, the window 7297 * destruction process may release a DC while a rendering 7298 * thread may also want to release a DC when it notices that 7299 * its DC is obsolete for the current window). 7300 */ 7301 DCItem *DCList::RemoveDC(HDC hDC, HWND hWnd) 7302 { 7303 listLock.Enter(); 7304 DCItem **prevPtrPtr = &head; 7305 DCItem *listPtr = head; 7306 while (listPtr) { 7307 DCItem *nextPtr = listPtr->next; 7308 if (listPtr->hDC == hDC && listPtr->hWnd == hWnd) { 7309 *prevPtrPtr = nextPtr; 7310 break; 7311 } 7312 prevPtrPtr = &listPtr->next; 7313 listPtr = nextPtr; 7314 } 7315 listLock.Leave(); 7316 return listPtr; 7317 } 7318 7319 /** 7320 * Remove all DCs from the DC list which are associated with 7321 * the same window as hWnd. Return the list of those 7322 * DC's to the caller (which will then probably want to 7323 * call ReleaseDC() for the returned DCs). 7324 */ 7325 DCItem *DCList::RemoveAllDCs(HWND hWnd) 7326 { 7327 listLock.Enter(); 7328 DCItem **prevPtrPtr = &head; 7329 DCItem *listPtr = head; 7330 DCItem *newListPtr = NULL; 7331 BOOL ret = FALSE; 7332 while (listPtr) { 7333 DCItem *nextPtr = listPtr->next; 7334 if (listPtr->hWnd == hWnd) { 7335 *prevPtrPtr = nextPtr; 7336 listPtr->next = newListPtr; 7337 newListPtr = listPtr; 7338 } else { 7339 prevPtrPtr = &listPtr->next; 7340 } 7341 listPtr = nextPtr; 7342 } 7343 listLock.Leave(); 7344 return newListPtr; 7345 } 7346 7347 7348 /** 7349 * Realize palettes of all existing HDC objects 7350 */ 7351 void DCList::RealizePalettes(int screen) 7352 { 7353 listLock.Enter(); 7354 DCItem *listPtr = head; 7355 while (listPtr) { 7356 AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen); 7357 listPtr = listPtr->next; 7358 } 7359 listLock.Leave(); 7360 } 7361 7362 void MoveDCToPassiveList(HDC hDC, HWND hWnd) { 7363 DCItem *removedDC; 7364 if ((removedDC = activeDCList.RemoveDC(hDC, hWnd)) != NULL) { 7365 passiveDCList.AddDCItem(removedDC); 7366 } 7367 } 7368 7369 void ReleaseDCList(HWND hwnd, DCList &list) { 7370 DCItem *removedDCs = list.RemoveAllDCs(hwnd); 7371 while (removedDCs) { 7372 DCItem *tmpDCList = removedDCs; 7373 DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC); 7374 int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC); 7375 VERIFY(retValue != 0); 7376 if (retValue != 0) { 7377 // Valid ReleaseDC call; need to decrement GDI object counter 7378 AwtGDIObject::Decrement(); 7379 } 7380 removedDCs = removedDCs->next; 7381 delete tmpDCList; 7382 } 7383 } 7384