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 if (!::IsWindowVisible(hWnd)) { 3843 return; 3844 } 3845 HWND hTop = GetTopLevelParentForWindow(hWnd); 3846 ::ClientToScreen(hTop, &p); 3847 if (!m_bitsCandType) { 3848 SetCandidateWindow(m_bitsCandType, x - p.x, y - p.y); 3849 return; 3850 } 3851 for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) { 3852 if ( m_bitsCandType & bits ) 3853 SetCandidateWindow(iCandType, x - p.x, y - p.y); 3854 } 3855 } 3856 3857 void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) 3858 { 3859 HWND hwnd = ImmGetHWnd(); 3860 HIMC hIMC = ImmGetContext(hwnd); 3861 if (hIMC) { 3862 CANDIDATEFORM cf; 3863 cf.dwStyle = CFS_POINT; 3864 ImmGetCandidateWindow(hIMC, 0, &cf); 3865 if (x != cf.ptCurrentPos.x || y != cf.ptCurrentPos.y) { 3866 cf.dwIndex = iCandType; 3867 cf.dwStyle = CFS_POINT; 3868 cf.ptCurrentPos.x = x; 3869 cf.ptCurrentPos.y = y; 3870 cf.rcArea.left = cf.rcArea.top = cf.rcArea.right = cf.rcArea.bottom = 0; 3871 ImmSetCandidateWindow(hIMC, &cf); 3872 } 3873 COMPOSITIONFORM cfr; 3874 cfr.dwStyle = CFS_POINT; 3875 ImmGetCompositionWindow(hIMC, &cfr); 3876 if (x != cfr.ptCurrentPos.x || y != cfr.ptCurrentPos.y) { 3877 cfr.dwStyle = CFS_POINT; 3878 cfr.ptCurrentPos.x = x; 3879 cfr.ptCurrentPos.y = y; 3880 cfr.rcArea.left = cfr.rcArea.top = cfr.rcArea.right = cfr.rcArea.bottom = 0; 3881 ImmSetCompositionWindow(hIMC, &cfr); 3882 } 3883 ImmReleaseContext(hwnd, hIMC); 3884 } 3885 } 3886 3887 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) 3888 { 3889 // If the Windows input context is disabled, do not let Windows 3890 // display any UIs. 3891 HWND hwnd = ImmGetHWnd(); 3892 HIMC hIMC = ImmGetContext(hwnd); 3893 if (hIMC == NULL) { 3894 *lplParam = 0; 3895 return mrDoDefault; 3896 } 3897 ImmReleaseContext(hwnd, hIMC); 3898 3899 if (fSet) { 3900 LPARAM lParam = *lplParam; 3901 if (!m_useNativeCompWindow) { 3902 // stop to draw native composing window. 3903 *lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW; 3904 } 3905 } 3906 return mrDoDefault; 3907 } 3908 3909 MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType) 3910 { 3911 if (!m_useNativeCompWindow) { 3912 if (subMsg == IMN_OPENCANDIDATE || subMsg == IMN_CHANGECANDIDATE) { 3913 m_bitsCandType = bitsCandType; 3914 InquireCandidatePosition(); 3915 } else if (subMsg == IMN_OPENSTATUSWINDOW || 3916 subMsg == WM_IME_STARTCOMPOSITION || 3917 subMsg == IMN_SETCANDIDATEPOS) { 3918 InquireCandidatePosition(); 3919 } 3920 } 3921 return mrDoDefault; 3922 } 3923 3924 MsgRouting AwtComponent::WmImeStartComposition() 3925 { 3926 if (m_useNativeCompWindow) { 3927 RECT rc; 3928 ::GetClientRect(GetHWnd(), &rc); 3929 SetCompositionWindow(rc); 3930 return mrDoDefault; 3931 } else 3932 return mrConsume; 3933 } 3934 3935 MsgRouting AwtComponent::WmImeEndComposition() 3936 { 3937 if (m_useNativeCompWindow) return mrDoDefault; 3938 3939 SendInputMethodEvent( 3940 java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3941 NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 ); 3942 return mrConsume; 3943 } 3944 3945 MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags) 3946 { 3947 if (m_useNativeCompWindow) return mrDoDefault; 3948 3949 int* bndClauseW = NULL; 3950 jstring* readingClauseW = NULL; 3951 int* bndAttrW = NULL; 3952 BYTE* valAttrW = NULL; 3953 int cClauseW = 0; 3954 AwtInputTextInfor* textInfor = NULL; 3955 3956 try { 3957 HWND hwnd = ImmGetHWnd(); 3958 HIMC hIMC = ImmGetContext(hwnd); 3959 DASSERT(hIMC!=0); 3960 3961 textInfor = new AwtInputTextInfor; 3962 textInfor->GetContextData(hIMC, flags); 3963 ImmReleaseContext(hwnd, hIMC); 3964 3965 jstring jtextString = textInfor->GetText(); 3966 /* The conditions to send the input method event to AWT EDT are: 3967 1. Whenever there is a composition message sent regarding whether 3968 the composition text is NULL or not. See details at bug 6222692. 3969 2. When there is a committed message sent, in which case, we have to 3970 check whether the committed string is NULL or not. If the committed string 3971 is NULL, there is no need to send any input method event. 3972 (Minor note: 'jtextString' returned is the merged string in the case of 3973 partial commit.) 3974 */ 3975 if ((flags & GCS_RESULTSTR && jtextString != NULL) || 3976 (flags & GCS_COMPSTR)) { 3977 int cursorPosW = textInfor->GetCursorPosition(); 3978 // In order not to delete the readingClauseW in the catch clause, 3979 // calling GetAttributeInfor before GetClauseInfor. 3980 int cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW); 3981 cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW); 3982 3983 /* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends 3984 the event to AWT EDT. 3985 3986 The last two paremeters are set to equal since we don't have recommendations for 3987 the visible position within the current composed text. See details at 3988 java.awt.event.InputMethodEvent. 3989 */ 3990 SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3991 jtextString, 3992 cClauseW, bndClauseW, readingClauseW, 3993 cAttrW, bndAttrW, valAttrW, 3994 textInfor->GetCommittedTextLength(), 3995 cursorPosW, cursorPosW); 3996 } 3997 } catch (...) { 3998 // since GetClauseInfor and GetAttributeInfor could throw exception, we have to release 3999 // the pointer here. 4000 delete [] bndClauseW; 4001 delete [] readingClauseW; 4002 delete [] bndAttrW; 4003 delete [] valAttrW; 4004 throw; 4005 } 4006 4007 /* Free the storage allocated. Since jtextString won't be passed from threads 4008 * to threads, we just use the local ref and it will be deleted within the destructor 4009 * of AwtInputTextInfor object. 4010 */ 4011 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4012 if (cClauseW && readingClauseW) { 4013 for (int i = 0; i < cClauseW; i ++) { 4014 if (readingClauseW[i]) { 4015 env->DeleteLocalRef(readingClauseW[i]); 4016 } 4017 } 4018 } 4019 delete [] bndClauseW; 4020 delete [] readingClauseW; 4021 delete [] bndAttrW; 4022 delete [] valAttrW; 4023 delete textInfor; 4024 4025 return mrConsume; 4026 } 4027 4028 // 4029 // generate and post InputMethodEvent 4030 // 4031 void AwtComponent::SendInputMethodEvent(jint id, jstring text, 4032 int cClause, int* rgClauseBoundary, jstring* rgClauseReading, 4033 int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue, 4034 int commitedTextLength, int caretPos, int visiblePos) 4035 { 4036 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4037 4038 // assumption for array type casting 4039 DASSERT(sizeof(int)==sizeof(jint)); 4040 DASSERT(sizeof(BYTE)==sizeof(jbyte)); 4041 4042 // caluse information 4043 jintArray clauseBoundary = NULL; 4044 jobjectArray clauseReading = NULL; 4045 if (cClause && rgClauseBoundary && rgClauseReading) { 4046 // convert clause boundary offset array to java array 4047 clauseBoundary = env->NewIntArray(cClause+1); 4048 DASSERT(clauseBoundary); 4049 CHECK_NULL(clauseBoundary); 4050 env->SetIntArrayRegion(clauseBoundary, 0, cClause+1, (jint *)rgClauseBoundary); 4051 DASSERT(!safe_ExceptionOccurred(env)); 4052 4053 // convert clause reading string array to java array 4054 jclass stringCls = JNU_ClassString(env); 4055 DASSERT(stringCls); 4056 CHECK_NULL(stringCls); 4057 clauseReading = env->NewObjectArray(cClause, stringCls, NULL); 4058 DASSERT(clauseReading); 4059 CHECK_NULL(clauseReading); 4060 for (int i=0; i<cClause; i++) env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]); 4061 DASSERT(!safe_ExceptionOccurred(env)); 4062 } 4063 4064 4065 // attrubute value definition in WInputMethod.java must be equal to that in IMM.H 4066 DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT); 4067 DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED); 4068 DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED); 4069 DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED); 4070 DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR); 4071 4072 // attribute information 4073 jintArray attrBoundary = NULL; 4074 jbyteArray attrValue = NULL; 4075 if (cAttrBlock && rgAttrBoundary && rgAttrValue) { 4076 // convert attribute boundary offset array to java array 4077 attrBoundary = env->NewIntArray(cAttrBlock+1); 4078 DASSERT(attrBoundary); 4079 CHECK_NULL(attrBoundary); 4080 env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary); 4081 DASSERT(!safe_ExceptionOccurred(env)); 4082 4083 // convert attribute value byte array to java array 4084 attrValue = env->NewByteArray(cAttrBlock); 4085 DASSERT(attrValue); 4086 CHECK_NULL(attrValue); 4087 env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue); 4088 DASSERT(!safe_ExceptionOccurred(env)); 4089 } 4090 4091 4092 // get global reference of WInputMethod class (run only once) 4093 static jclass wInputMethodCls = NULL; 4094 if (wInputMethodCls == NULL) { 4095 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4096 DASSERT(wInputMethodClsLocal); 4097 CHECK_NULL(wInputMethodClsLocal); 4098 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4099 env->DeleteLocalRef(wInputMethodClsLocal); 4100 } 4101 4102 // get method ID of sendInputMethodEvent() (run only once) 4103 static jmethodID sendIMEventMid = 0; 4104 if (sendIMEventMid == 0) { 4105 sendIMEventMid = env->GetMethodID(wInputMethodCls, "sendInputMethodEvent", 4106 "(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V"); 4107 DASSERT(sendIMEventMid); 4108 CHECK_NULL(sendIMEventMid); 4109 } 4110 4111 // call m_InputMethod.sendInputMethod() 4112 env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, TimeHelper::getMessageTimeUTC(), 4113 text, clauseBoundary, clauseReading, attrBoundary, 4114 attrValue, commitedTextLength, caretPos, visiblePos); 4115 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4116 DASSERT(!safe_ExceptionOccurred(env)); 4117 4118 } 4119 4120 4121 4122 // 4123 // Inquires candidate position according to the composed text 4124 // 4125 void AwtComponent::InquireCandidatePosition() 4126 { 4127 if (!::IsWindowVisible(GetHWnd())) { 4128 return; 4129 } 4130 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4131 4132 // get global reference of WInputMethod class (run only once) 4133 static jclass wInputMethodCls = NULL; 4134 if (wInputMethodCls == NULL) { 4135 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4136 DASSERT(wInputMethodClsLocal); 4137 CHECK_NULL(wInputMethodClsLocal); 4138 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4139 env->DeleteLocalRef(wInputMethodClsLocal); 4140 } 4141 4142 // get method ID of sendInputMethodEvent() (run only once) 4143 static jmethodID inqCandPosMid = 0; 4144 if (inqCandPosMid == 0) { 4145 inqCandPosMid = env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", "()V"); 4146 DASSERT(!safe_ExceptionOccurred(env)); 4147 DASSERT(inqCandPosMid); 4148 CHECK_NULL(inqCandPosMid); 4149 } 4150 4151 // call m_InputMethod.sendInputMethod() 4152 jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid); 4153 DASSERT(!safe_ExceptionOccurred(env)); 4154 } 4155 4156 HWND AwtComponent::ImmGetHWnd() 4157 { 4158 HWND proxy = GetProxyFocusOwner(); 4159 return (proxy != NULL) ? proxy : GetHWnd(); 4160 } 4161 4162 HIMC AwtComponent::ImmAssociateContext(HIMC himc) 4163 { 4164 return ::ImmAssociateContext(ImmGetHWnd(), himc); 4165 } 4166 4167 HWND AwtComponent::GetProxyFocusOwner() 4168 { 4169 AwtWindow *window = GetContainer(); 4170 if (window != 0) { 4171 AwtFrame *owner = window->GetOwningFrameOrDialog(); 4172 if (owner != 0) { 4173 return owner->GetProxyFocusOwner(); 4174 } else if (!window->IsSimpleWindow()) { // isn't an owned simple window 4175 return ((AwtFrame*)window)->GetProxyFocusOwner(); 4176 } 4177 } 4178 return (HWND)NULL; 4179 } 4180 4181 /* Redirects message to the focus proxy, if any */ 4182 void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, 4183 LPARAM lParam, LRESULT &retVal, MsgRouting &mr) 4184 { 4185 if (mr != mrConsume) { 4186 HWND proxy = GetProxyFocusOwner(); 4187 if (proxy != NULL && ::IsWindowEnabled(proxy)) { 4188 retVal = ::DefWindowProc(proxy, message, wParam, lParam); 4189 mr = mrConsume; 4190 } 4191 } 4192 } 4193 4194 MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode) 4195 { 4196 /* Menu/Accelerator */ 4197 if (hWndChild == 0) { 4198 AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id); 4199 if (obj == NULL) { 4200 return mrConsume; 4201 } 4202 DASSERT(((AwtMenuItem*)obj)->GetID() == id); 4203 obj->DoCommand(); 4204 return mrConsume; 4205 } 4206 /* Child id notification */ 4207 else { 4208 AwtComponent* child = AwtComponent::GetComponent(hWndChild); 4209 if (child) { 4210 child->WmNotify(notifyCode); 4211 } 4212 } 4213 return mrDoDefault; 4214 } 4215 4216 MsgRouting AwtComponent::WmNotify(UINT notifyCode) 4217 { 4218 return mrDoDefault; 4219 } 4220 4221 MsgRouting AwtComponent::WmCompareItem(UINT ctrlId, 4222 COMPAREITEMSTRUCT &compareInfo, 4223 LRESULT &result) 4224 { 4225 AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem); 4226 if (child == this) { 4227 /* DoCallback("handleItemDelete", */ 4228 } 4229 else if (child) { 4230 return child->WmCompareItem(ctrlId, compareInfo, result); 4231 } 4232 return mrConsume; 4233 } 4234 4235 MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId, 4236 DELETEITEMSTRUCT &deleteInfo) 4237 { 4238 /* 4239 * Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList 4240 * window, a WM_DELETEITEM message is sent to its parent with a window 4241 * handle of one of the list's child windows. The property lookup 4242 * succeeds, but the HWNDs don't match. 4243 */ 4244 if (deleteInfo.hwndItem == NULL) { 4245 return mrConsume; 4246 } 4247 AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem); 4248 4249 if (child && child->GetHWnd() != deleteInfo.hwndItem) { 4250 return mrConsume; 4251 } 4252 4253 if (child == this) { 4254 /*DoCallback("handleItemDelete", */ 4255 } 4256 else if (child) { 4257 return child->WmDeleteItem(ctrlId, deleteInfo); 4258 } 4259 return mrConsume; 4260 } 4261 4262 MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo) 4263 { 4264 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4265 4266 if (drawInfo.CtlType == ODT_MENU) { 4267 if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) { 4268 AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); 4269 menu->DrawItem(drawInfo); 4270 } 4271 } else { 4272 return OwnerDrawItem(ctrlId, drawInfo); 4273 } 4274 return mrConsume; 4275 } 4276 4277 MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId, 4278 MEASUREITEMSTRUCT &measureInfo) 4279 { 4280 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4281 4282 if (measureInfo.CtlType == ODT_MENU) { 4283 if (measureInfo.itemData != 0) { 4284 AwtMenu* menu = (AwtMenu*)(measureInfo.itemData); 4285 HDC hDC = ::GetDC(GetHWnd()); 4286 /* menu->MeasureItem(env, hDC, measureInfo); */ 4287 menu->MeasureItem(hDC, measureInfo); 4288 ::ReleaseDC(GetHWnd(), hDC); 4289 } 4290 } else { 4291 return OwnerMeasureItem(ctrlId, measureInfo); 4292 } 4293 return mrConsume; 4294 } 4295 4296 MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId, 4297 DRAWITEMSTRUCT &drawInfo) 4298 { 4299 AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem); 4300 if (child == this) { 4301 /* DoCallback("handleItemDelete", */ 4302 } else if (child != NULL) { 4303 return child->WmDrawItem(ctrlId, drawInfo); 4304 } 4305 return mrConsume; 4306 } 4307 4308 MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId, 4309 MEASUREITEMSTRUCT &measureInfo) 4310 { 4311 HWND hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID); 4312 AwtComponent* child = AwtComponent::GetComponent(hChild); 4313 /* 4314 * If the parent cannot find the child's instance from its handle, 4315 * maybe the child is in its creation. So the child must be searched 4316 * from the list linked before the child's creation. 4317 */ 4318 if (child == NULL) { 4319 child = SearchChild((UINT)ctrlId); 4320 } 4321 4322 if (child == this) { 4323 /* DoCallback("handleItemDelete", */ 4324 } 4325 else if (child) { 4326 return child->WmMeasureItem(ctrlId, measureInfo); 4327 } 4328 return mrConsume; 4329 } 4330 4331 /* for WmDrawItem method of Label, Button and Checkbox */ 4332 void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text, 4333 int x, int y) 4334 { 4335 int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT); 4336 DASSERT(nOldBkMode != 0); 4337 AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage()); 4338 VERIFY(::SetBkMode(hDC,nOldBkMode)); 4339 } 4340 4341 /* 4342 * Draw text in gray (the color being set to COLOR_GRAYTEXT) when the 4343 * component is disabled. Used only for label, checkbox and button in 4344 * OWNER_DRAW. It draws the text in emboss. 4345 */ 4346 void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text, 4347 int x, int y) 4348 { 4349 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); 4350 AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1); 4351 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 4352 AwtComponent::DrawWindowText(hDC, font, text, x, y); 4353 } 4354 4355 /* for WmMeasureItem method of List and Choice */ 4356 jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index) 4357 { 4358 jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl", 4359 "(I)Ljava/lang/String;", 4360 index).l; 4361 DASSERT(!safe_ExceptionOccurred(env)); 4362 return str; 4363 } 4364 4365 /* for WmMeasureItem method of List and Choice */ 4366 void AwtComponent::MeasureListItem(JNIEnv *env, 4367 MEASUREITEMSTRUCT &measureInfo) 4368 { 4369 if (env->EnsureLocalCapacity(1) < 0) { 4370 return; 4371 } 4372 jobject dimension = PreferredItemSize(env); 4373 DASSERT(dimension); 4374 measureInfo.itemWidth = 4375 env->GetIntField(dimension, AwtDimension::widthID); 4376 measureInfo.itemHeight = 4377 env->GetIntField(dimension, AwtDimension::heightID); 4378 env->DeleteLocalRef(dimension); 4379 } 4380 4381 /* for WmDrawItem method of List and Choice */ 4382 void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) 4383 { 4384 if (env->EnsureLocalCapacity(3) < 0) { 4385 return; 4386 } 4387 jobject peer = GetPeer(env); 4388 jobject target = env->GetObjectField(peer, AwtObject::targetID); 4389 4390 HDC hDC = drawInfo.hDC; 4391 RECT rect = drawInfo.rcItem; 4392 4393 BOOL bEnabled = isEnabled(); 4394 BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable(); 4395 DWORD crBack, crText; 4396 if (drawInfo.itemState & ODS_SELECTED){ 4397 /* Set background and text colors for selected item */ 4398 crBack = ::GetSysColor (COLOR_HIGHLIGHT); 4399 crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT); 4400 } else { 4401 /* Set background and text colors for unselected item */ 4402 crBack = GetBackgroundColor(); 4403 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4404 } 4405 if (unfocusableChoice) { 4406 //6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box. 4407 crBack = GetBackgroundColor(); 4408 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4409 } 4410 4411 /* Fill item rectangle with background color */ 4412 HBRUSH hbrBack = ::CreateSolidBrush (crBack); 4413 DASSERT(hbrBack); 4414 /* 6190728. Shouldn't draw any kind of rectangle around selection field 4415 * (edit control) of an owner-drawn combo box while unfocusable 4416 */ 4417 if (!unfocusableChoice){ 4418 VERIFY(::FillRect (hDC, &rect, hbrBack)); 4419 } 4420 VERIFY(::DeleteObject (hbrBack)); 4421 4422 /* Set current background and text colors */ 4423 ::SetBkColor (hDC, crBack); 4424 ::SetTextColor (hDC, crText); 4425 4426 /*draw string (with left margin of 1 point) */ 4427 if ((int) (drawInfo.itemID) >= 0) { 4428 jobject font = GET_FONT(target, peer); 4429 jstring text = GetItemString(env, target, drawInfo.itemID); 4430 if (env->ExceptionCheck()) { 4431 env->DeleteLocalRef(font); 4432 env->DeleteLocalRef(target); 4433 return; 4434 } 4435 SIZE size = AwtFont::getMFStringSize(hDC, font, text); 4436 AwtFont::drawMFString(hDC, font, text, 4437 (GetRTL()) ? rect.right - size.cx - 1 4438 : rect.left + 1, 4439 (rect.top + rect.bottom - size.cy) / 2, 4440 GetCodePage()); 4441 env->DeleteLocalRef(font); 4442 env->DeleteLocalRef(text); 4443 } 4444 if ((drawInfo.itemState & ODS_FOCUS) && 4445 (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { 4446 if (!unfocusableChoice){ 4447 VERIFY(::DrawFocusRect(hDC, &rect)); 4448 } 4449 } 4450 env->DeleteLocalRef(target); 4451 } 4452 4453 /* for MeasureListItem method and WmDrawItem method of Checkbox */ 4454 jint AwtComponent::GetFontHeight(JNIEnv *env) 4455 { 4456 if (env->EnsureLocalCapacity(4) < 0) { 4457 return NULL; 4458 } 4459 jobject self = GetPeer(env); 4460 jobject target = env->GetObjectField(self, AwtObject::targetID); 4461 4462 jobject font = GET_FONT(target, self); 4463 jobject toolkit = env->CallObjectMethod(target, 4464 AwtComponent::getToolkitMID); 4465 4466 DASSERT(!safe_ExceptionOccurred(env)); 4467 4468 jobject fontMetrics = 4469 env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font); 4470 4471 DASSERT(!safe_ExceptionOccurred(env)); 4472 4473 jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID); 4474 DASSERT(!safe_ExceptionOccurred(env)); 4475 4476 env->DeleteLocalRef(target); 4477 env->DeleteLocalRef(font); 4478 env->DeleteLocalRef(toolkit); 4479 env->DeleteLocalRef(fontMetrics); 4480 4481 return height; 4482 } 4483 4484 // If you override WmPrint, make sure to save a copy of the DC on the GDI 4485 // stack to be restored in WmPrintClient. Windows mangles the DC in 4486 // ::DefWindowProc. 4487 MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags) 4488 { 4489 /* 4490 * DefWindowProc for WM_PRINT changes DC parameters, so we have 4491 * to restore it ourselves. Otherwise it will cause problems 4492 * when several components are printed to the same DC. 4493 */ 4494 int nOriginalDC = ::SaveDC(hDC); 4495 DASSERT(nOriginalDC != 0); 4496 4497 if (flags & PRF_NONCLIENT) { 4498 4499 VERIFY(::SaveDC(hDC)); 4500 4501 DefWindowProc(WM_PRINT, (WPARAM)hDC, 4502 (flags & (PRF_NONCLIENT 4503 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4504 4505 VERIFY(::RestoreDC(hDC, -1)); 4506 4507 // Special case for components with a sunken border. Windows does not 4508 // print the border correctly on PCL printers, so we have to do it ourselves. 4509 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4510 RECT r; 4511 VERIFY(::GetWindowRect(GetHWnd(), &r)); 4512 VERIFY(::OffsetRect(&r, -r.left, -r.top)); 4513 VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT)); 4514 } 4515 } 4516 4517 if (flags & PRF_CLIENT) { 4518 4519 /* 4520 * Special case for components with a sunken border. 4521 * Windows prints a client area without offset to a border width. 4522 * We will first print the non-client area with the original offset, 4523 * then the client area with a corrected offset. 4524 */ 4525 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4526 4527 int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE); 4528 int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE); 4529 4530 VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL)); 4531 4532 // Save a copy of the DC for WmPrintClient 4533 VERIFY(::SaveDC(hDC)); 4534 4535 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4536 (flags & (PRF_CLIENT 4537 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4538 4539 VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL)); 4540 4541 } else { 4542 4543 // Save a copy of the DC for WmPrintClient 4544 VERIFY(::SaveDC(hDC)); 4545 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4546 (flags & (PRF_CLIENT 4547 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4548 } 4549 } 4550 4551 if (flags & (PRF_CHILDREN | PRF_OWNED)) { 4552 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4553 (flags & ~PRF_CLIENT & ~PRF_NONCLIENT)); 4554 } 4555 4556 VERIFY(::RestoreDC(hDC, nOriginalDC)); 4557 4558 return mrConsume; 4559 } 4560 4561 // If you override WmPrintClient, make sure to obtain a valid copy of 4562 // the DC from the GDI stack. The copy of the DC should have been placed 4563 // there by WmPrint. Windows mangles the DC in ::DefWindowProc. 4564 MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM) 4565 { 4566 // obtain valid DC from GDI stack 4567 ::RestoreDC(hDC, -1); 4568 4569 return mrDoDefault; 4570 } 4571 4572 MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects, 4573 LPNCCALCSIZE_PARAMS lpncsp, 4574 LRESULT &retVal) 4575 { 4576 return mrDoDefault; 4577 } 4578 4579 MsgRouting AwtComponent::WmNcPaint(HRGN hrgn) 4580 { 4581 return mrDoDefault; 4582 } 4583 4584 MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal) 4585 { 4586 return mrDoDefault; 4587 } 4588 4589 /** 4590 * WmQueryNewPalette is called whenever our component is coming to 4591 * the foreground; this gives us an opportunity to install our 4592 * custom palette. If this install actually changes entries in 4593 * the system palette, then we get a further call to WmPaletteChanged 4594 * (but note that we only need to realize our palette once). 4595 */ 4596 MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal) 4597 { 4598 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4599 m_QueryNewPaletteCalled = TRUE; 4600 HDC hDC = ::GetDC(GetHWnd()); 4601 DASSERT(hDC); 4602 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4603 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4604 ::ReleaseDC(GetHWnd(), hDC); 4605 // We must realize the palettes of all of our DC's 4606 // There is sometimes a problem where the realization of 4607 // our temporary hDC here does not actually do what 4608 // we want. Not clear why, but presumably fallout from 4609 // our use of several simultaneous hDC's. 4610 activeDCList.RealizePalettes(screen); 4611 // Do not invalidate here; if the palette 4612 // has not changed we will get an extra repaint 4613 retVal = TRUE; 4614 4615 return mrDoDefault; 4616 } 4617 4618 /** 4619 * We should not need to track this event since we handle our 4620 * palette management effectively in the WmQueryNewPalette and 4621 * WmPaletteChanged methods. However, there seems to be a bug 4622 * on some win32 systems (e.g., NT4) whereby the palette 4623 * immediately after a displayChange is not yet updated to its 4624 * final post-display-change values (hence we adjust our palette 4625 * using the wrong system palette entries), then the palette is 4626 * updated, but a WM_PALETTECHANGED message is never sent. 4627 * By tracking the ISCHANGING message as well (and by tracking 4628 * displayChange events in the AwtToolkit object), we can account 4629 * for this error by forcing our WmPaletteChanged method to be 4630 * called and thereby realizing our logical palette and updating 4631 * our dynamic colorModel object. 4632 */ 4633 MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg) 4634 { 4635 if (AwtToolkit::GetInstance().HasDisplayChanged()) { 4636 WmPaletteChanged(hwndPalChg); 4637 AwtToolkit::GetInstance().ResetDisplayChanged(); 4638 } 4639 return mrDoDefault; 4640 } 4641 4642 MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg) 4643 { 4644 // We need to re-realize our palette here (unless we're the one 4645 // that was realizing it in the first place). That will let us match the 4646 // remaining colors in the system palette as best we can. We always 4647 // invalidate because the palette will have changed when we receive this 4648 // message. 4649 4650 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4651 if (hwndPalChg != GetHWnd()) { 4652 HDC hDC = ::GetDC(GetHWnd()); 4653 DASSERT(hDC); 4654 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4655 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4656 ::ReleaseDC(GetHWnd(), hDC); 4657 // We must realize the palettes of all of our DC's 4658 activeDCList.RealizePalettes(screen); 4659 } 4660 if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) { 4661 AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen); 4662 } 4663 Invalidate(NULL); 4664 return mrDoDefault; 4665 } 4666 4667 MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 4668 { 4669 DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT))); 4670 return mrDoDefault; 4671 } 4672 4673 MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection) 4674 { 4675 DASSERT(!IsBadStringPtr(pszSection, 20)); 4676 DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection); 4677 return mrDoDefault; 4678 } 4679 4680 HDC AwtComponent::GetDCFromComponent() 4681 { 4682 GetDCReturnStruct *hdcStruct = 4683 (GetDCReturnStruct*)SendMessage(WM_AWT_GETDC); 4684 HDC hdc; 4685 if (hdcStruct) { 4686 if (hdcStruct->gdiLimitReached) { 4687 if (jvm != NULL) { 4688 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4689 if (env != NULL && !safe_ExceptionOccurred(env)) { 4690 JNU_ThrowByName(env, "java/awt/AWTError", 4691 "HDC creation failure - " \ 4692 "exceeded maximum GDI resources"); 4693 } 4694 } 4695 } 4696 hdc = hdcStruct->hDC; 4697 delete hdcStruct; 4698 } else { 4699 hdc = NULL; 4700 } 4701 return hdc; 4702 } 4703 4704 void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size) 4705 { 4706 RECT eraseR = { 0, 0, size.cx, size.cy }; 4707 VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush())); 4708 } 4709 4710 void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) 4711 { 4712 if (!bitmapBits) { 4713 return; 4714 } 4715 4716 DWORD* dest = (DWORD*)bitmapBits; 4717 //XXX: might be optimized to use one loop (cy*cx -> 0) 4718 for (int i = 0; i < size.cy; i++ ) { 4719 for (int j = 0; j < size.cx; j++ ) { 4720 ((BYTE*)(dest++))[3] = alpha; 4721 } 4722 } 4723 } 4724 4725 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) { 4726 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4727 4728 if (!::IsWindowVisible(GetHWnd())) { 4729 return NULL; 4730 } 4731 4732 HDC hdc = GetDCFromComponent(); 4733 if (!hdc) { 4734 return NULL; 4735 } 4736 HDC hMemoryDC = ::CreateCompatibleDC(hdc); 4737 void *bitmapBits = NULL; 4738 HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits); 4739 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap); 4740 SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc); 4741 4742 FillBackground(hMemoryDC, size); 4743 4744 VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL)); 4745 4746 // Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible 4747 // above. 4748 SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT); 4749 4750 // First make sure the system completed any drawing to the bitmap. 4751 ::GdiFlush(); 4752 4753 // WM_PRINT does not fill the alpha-channel of the ARGB bitmap 4754 // leaving it equal to zero. Hence we need to fill it manually. Otherwise 4755 // the pixels will be considered transparent when interpreting the data. 4756 FillAlpha(bitmapBits, size, alpha); 4757 4758 ::SelectObject(hMemoryDC, hOldBitmap); 4759 4760 BITMAPINFO bmi; 4761 memset(&bmi, 0, sizeof(BITMAPINFO)); 4762 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 4763 bmi.bmiHeader.biWidth = size.cx; 4764 bmi.bmiHeader.biHeight = -size.cy; 4765 bmi.bmiHeader.biPlanes = 1; 4766 bmi.bmiHeader.biBitCount = 32; 4767 bmi.bmiHeader.biCompression = BI_RGB; 4768 4769 jobject localPixelArray = env->NewIntArray(size.cx * size.cy); 4770 jintArray pixelArray = NULL; 4771 if (localPixelArray != NULL) { 4772 pixelArray = (jintArray)env->NewGlobalRef(localPixelArray); 4773 env->DeleteLocalRef(localPixelArray); localPixelArray = NULL; 4774 4775 jboolean isCopy; 4776 jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy); 4777 4778 ::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi, 4779 DIB_RGB_COLORS); 4780 4781 env->ReleaseIntArrayElements(pixelArray, pixels, 0); 4782 } 4783 4784 VERIFY(::DeleteObject(hBitmap)); 4785 VERIFY(::DeleteDC(hMemoryDC)); 4786 4787 return pixelArray; 4788 } 4789 4790 void* AwtComponent::SetNativeFocusOwner(void *self) { 4791 if (self == NULL) { 4792 // It means that the KFM wants to set focus to null 4793 sm_focusOwner = NULL; 4794 return NULL; 4795 } 4796 4797 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4798 4799 AwtComponent *c = NULL; 4800 jobject peer = (jobject)self; 4801 4802 PDATA pData; 4803 JNI_CHECK_NULL_GOTO(peer, "peer", ret); 4804 pData = JNI_GET_PDATA(peer); 4805 if (pData == NULL) { 4806 goto ret; 4807 } 4808 c = (AwtComponent *)pData; 4809 4810 ret: 4811 if (c && ::IsWindow(c->GetHWnd())) { 4812 sm_focusOwner = c->GetHWnd(); 4813 } else { 4814 sm_focusOwner = NULL; 4815 } 4816 env->DeleteGlobalRef(peer); 4817 return NULL; 4818 } 4819 4820 void* AwtComponent::GetNativeFocusedWindow() { 4821 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4822 AwtComponent *comp = 4823 AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 4824 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4825 } 4826 4827 void* AwtComponent::GetNativeFocusOwner() { 4828 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4829 AwtComponent *comp = 4830 AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 4831 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4832 } 4833 4834 AwtComponent* AwtComponent::SearchChild(UINT id) { 4835 ChildListItem* child; 4836 for (child = m_childList; child != NULL;child = child->m_next) { 4837 if (child->m_ID == id) 4838 return child->m_Component; 4839 } 4840 /* 4841 * DASSERT(FALSE); 4842 * This should not be happend if all children are recorded 4843 */ 4844 return NULL; /* make compiler happy */ 4845 } 4846 4847 void AwtComponent::RemoveChild(UINT id) { 4848 ChildListItem* child = m_childList; 4849 ChildListItem* lastChild = NULL; 4850 while (child != NULL) { 4851 if (child->m_ID == id) { 4852 if (lastChild == NULL) { 4853 m_childList = child->m_next; 4854 } else { 4855 lastChild->m_next = child->m_next; 4856 } 4857 child->m_next = NULL; 4858 DASSERT(child != NULL); 4859 delete child; 4860 return; 4861 } 4862 lastChild = child; 4863 child = child->m_next; 4864 } 4865 } 4866 4867 void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked, 4868 jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg) 4869 { 4870 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4871 CriticalSection::Lock l(GetLock()); 4872 if (GetPeer(env) == NULL) { 4873 /* event received during termination. */ 4874 return; 4875 } 4876 4877 static jclass keyEventCls; 4878 if (keyEventCls == NULL) { 4879 jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent"); 4880 DASSERT(keyEventClsLocal); 4881 if (keyEventClsLocal == NULL) { 4882 /* exception already thrown */ 4883 return; 4884 } 4885 keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal); 4886 env->DeleteLocalRef(keyEventClsLocal); 4887 } 4888 4889 static jmethodID keyEventConst; 4890 if (keyEventConst == NULL) { 4891 keyEventConst = env->GetMethodID(keyEventCls, "<init>", 4892 "(Ljava/awt/Component;IJIICI)V"); 4893 DASSERT(keyEventConst); 4894 CHECK_NULL(keyEventConst); 4895 } 4896 if (env->EnsureLocalCapacity(2) < 0) { 4897 return; 4898 } 4899 jobject target = GetTarget(env); 4900 jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target, 4901 id, when, modifiers, raw, cooked, 4902 keyLocation); 4903 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4904 DASSERT(!safe_ExceptionOccurred(env)); 4905 DASSERT(keyEvent != NULL); 4906 if (keyEvent == NULL) { 4907 env->DeleteLocalRef(target); 4908 return; 4909 } 4910 env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode); 4911 if( nativeCode && nativeCode < 256 ) { 4912 env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode)); 4913 env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey)); 4914 if( nativeCode < 255 ) { 4915 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode)); 4916 }else if( pMsg != NULL ) { 4917 // unknown key with virtual keycode 0xFF. 4918 // Its scancode is not in the table, pickup it from the message. 4919 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF)); 4920 } 4921 } 4922 if (pMsg != NULL) { 4923 AwtAWTEvent::saveMSG(env, pMsg, keyEvent); 4924 } 4925 SendEvent(keyEvent); 4926 4927 env->DeleteLocalRef(keyEvent); 4928 env->DeleteLocalRef(target); 4929 } 4930 4931 void 4932 AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when, 4933 jint raw, jint cooked, 4934 jint modifiers, jint keyLocation, 4935 jlong nativeCode, 4936 MSG *msg) 4937 { 4938 /* 4939 * if focus owner is null, but focused window isn't 4940 * we will send key event to focused window 4941 */ 4942 HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow()); 4943 4944 if (hwndTarget == GetHWnd()) { 4945 SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg); 4946 } else { 4947 AwtComponent *target = NULL; 4948 if (hwndTarget != NULL) { 4949 target = AwtComponent::GetComponent(hwndTarget); 4950 if (target == NULL) { 4951 target = this; 4952 } 4953 } 4954 if (target != NULL) { 4955 target->SendKeyEvent(id, when, raw, cooked, modifiers, 4956 keyLocation, nativeCode, msg); 4957 } 4958 } 4959 } 4960 4961 void AwtComponent::SetDragCapture(UINT flags) 4962 { 4963 // don't want to interfere with other controls 4964 if (::GetCapture() == NULL) { 4965 ::SetCapture(GetHWnd()); 4966 } 4967 } 4968 4969 void AwtComponent::ReleaseDragCapture(UINT flags) 4970 { 4971 if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) { 4972 // user has released all buttons, so release the capture 4973 ::ReleaseCapture(); 4974 } 4975 } 4976 4977 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y, 4978 jint modifiers, jint clickCount, 4979 jboolean popupTrigger, jint button, 4980 MSG *pMsg, BOOL causedByTouchEvent) 4981 { 4982 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4983 CriticalSection::Lock l(GetLock()); 4984 if (GetPeer(env) == NULL) { 4985 /* event received during termination. */ 4986 return; 4987 } 4988 4989 static jclass mouseEventCls; 4990 if (mouseEventCls == NULL) { 4991 jclass mouseEventClsLocal = 4992 env->FindClass("java/awt/event/MouseEvent"); 4993 CHECK_NULL(mouseEventClsLocal); 4994 mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal); 4995 env->DeleteLocalRef(mouseEventClsLocal); 4996 } 4997 RECT insets; 4998 GetInsets(&insets); 4999 5000 static jmethodID mouseEventConst; 5001 if (mouseEventConst == NULL) { 5002 mouseEventConst = 5003 env->GetMethodID(mouseEventCls, "<init>", 5004 "(Ljava/awt/Component;IJIIIIIIZI)V"); 5005 DASSERT(mouseEventConst); 5006 CHECK_NULL(mouseEventConst); 5007 } 5008 if (env->EnsureLocalCapacity(2) < 0) { 5009 return; 5010 } 5011 jobject target = GetTarget(env); 5012 DWORD curMousePos = ::GetMessagePos(); 5013 int xAbs = GET_X_LPARAM(curMousePos); 5014 int yAbs = GET_Y_LPARAM(curMousePos); 5015 jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst, 5016 target, 5017 id, when, modifiers, 5018 x+insets.left, y+insets.top, 5019 xAbs, yAbs, 5020 clickCount, popupTrigger, button); 5021 5022 if (safe_ExceptionOccurred(env)) { 5023 env->ExceptionDescribe(); 5024 env->ExceptionClear(); 5025 } 5026 5027 DASSERT(mouseEvent != NULL); 5028 CHECK_NULL(mouseEvent); 5029 if (causedByTouchEvent) { 5030 env->SetBooleanField(mouseEvent, AwtMouseEvent::causedByTouchEventID, 5031 JNI_TRUE); 5032 } 5033 if (pMsg != 0) { 5034 AwtAWTEvent::saveMSG(env, pMsg, mouseEvent); 5035 } 5036 SendEvent(mouseEvent); 5037 5038 env->DeleteLocalRef(mouseEvent); 5039 env->DeleteLocalRef(target); 5040 } 5041 5042 void 5043 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, 5044 jint modifiers, jint clickCount, 5045 jboolean popupTrigger, jint scrollType, 5046 jint scrollAmount, jint roundedWheelRotation, 5047 jdouble preciseWheelRotation, MSG *pMsg) 5048 { 5049 /* Code based not so loosely on AwtComponent::SendMouseEvent */ 5050 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5051 CriticalSection::Lock l(GetLock()); 5052 if (GetPeer(env) == NULL) { 5053 /* event received during termination. */ 5054 return; 5055 } 5056 5057 static jclass mouseWheelEventCls; 5058 if (mouseWheelEventCls == NULL) { 5059 jclass mouseWheelEventClsLocal = 5060 env->FindClass("java/awt/event/MouseWheelEvent"); 5061 CHECK_NULL(mouseWheelEventClsLocal); 5062 mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal); 5063 env->DeleteLocalRef(mouseWheelEventClsLocal); 5064 } 5065 RECT insets; 5066 GetInsets(&insets); 5067 5068 static jmethodID mouseWheelEventConst; 5069 if (mouseWheelEventConst == NULL) { 5070 mouseWheelEventConst = 5071 env->GetMethodID(mouseWheelEventCls, "<init>", 5072 "(Ljava/awt/Component;IJIIIIIIZIIID)V"); 5073 DASSERT(mouseWheelEventConst); 5074 CHECK_NULL(mouseWheelEventConst); 5075 } 5076 if (env->EnsureLocalCapacity(2) < 0) { 5077 return; 5078 } 5079 jobject target = GetTarget(env); 5080 DTRACE_PRINTLN("creating MWE in JNI"); 5081 5082 jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, 5083 mouseWheelEventConst, 5084 target, 5085 id, when, modifiers, 5086 x+insets.left, y+insets.top, 5087 0, 0, 5088 clickCount, popupTrigger, 5089 scrollType, scrollAmount, 5090 roundedWheelRotation, preciseWheelRotation); 5091 5092 DASSERT(mouseWheelEvent != NULL); 5093 if (mouseWheelEvent == NULL || safe_ExceptionOccurred(env)) { 5094 env->ExceptionDescribe(); 5095 env->ExceptionClear(); 5096 env->DeleteLocalRef(target); 5097 return; 5098 } 5099 if (pMsg != NULL) { 5100 AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent); 5101 } 5102 SendEvent(mouseWheelEvent); 5103 5104 env->DeleteLocalRef(mouseWheelEvent); 5105 env->DeleteLocalRef(target); 5106 } 5107 5108 void AwtComponent::SendFocusEvent(jint id, HWND opposite) 5109 { 5110 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5111 5112 CriticalSection::Lock l(GetLock()); 5113 if (GetPeer(env) == NULL) { 5114 /* event received during termination. */ 5115 return; 5116 } 5117 5118 static jclass focusEventCls; 5119 if (focusEventCls == NULL) { 5120 jclass focusEventClsLocal 5121 = env->FindClass("java/awt/event/FocusEvent"); 5122 DASSERT(focusEventClsLocal); 5123 CHECK_NULL(focusEventClsLocal); 5124 focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal); 5125 env->DeleteLocalRef(focusEventClsLocal); 5126 } 5127 5128 static jmethodID focusEventConst; 5129 if (focusEventConst == NULL) { 5130 focusEventConst = 5131 env->GetMethodID(focusEventCls, "<init>", 5132 "(Ljava/awt/Component;IZLjava/awt/Component;)V"); 5133 DASSERT(focusEventConst); 5134 CHECK_NULL(focusEventConst); 5135 } 5136 5137 static jclass sequencedEventCls; 5138 if (sequencedEventCls == NULL) { 5139 jclass sequencedEventClsLocal = 5140 env->FindClass("java/awt/SequencedEvent"); 5141 DASSERT(sequencedEventClsLocal); 5142 CHECK_NULL(sequencedEventClsLocal); 5143 sequencedEventCls = 5144 (jclass)env->NewGlobalRef(sequencedEventClsLocal); 5145 env->DeleteLocalRef(sequencedEventClsLocal); 5146 } 5147 5148 static jmethodID sequencedEventConst; 5149 if (sequencedEventConst == NULL) { 5150 sequencedEventConst = 5151 env->GetMethodID(sequencedEventCls, "<init>", 5152 "(Ljava/awt/AWTEvent;)V"); 5153 DASSERT(sequencedEventConst); 5154 CHECK_NULL(sequencedEventConst); 5155 } 5156 5157 if (env->EnsureLocalCapacity(3) < 0) { 5158 return; 5159 } 5160 5161 jobject target = GetTarget(env); 5162 jobject jOpposite = NULL; 5163 if (opposite != NULL) { 5164 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite); 5165 if (awtOpposite != NULL) { 5166 jOpposite = awtOpposite->GetTarget(env); 5167 } 5168 } 5169 jobject focusEvent = env->NewObject(focusEventCls, focusEventConst, 5170 target, id, JNI_FALSE, jOpposite); 5171 DASSERT(!safe_ExceptionOccurred(env)); 5172 DASSERT(focusEvent != NULL); 5173 if (jOpposite != NULL) { 5174 env->DeleteLocalRef(jOpposite); jOpposite = NULL; 5175 } 5176 env->DeleteLocalRef(target); target = NULL; 5177 CHECK_NULL(focusEvent); 5178 5179 jobject sequencedEvent = env->NewObject(sequencedEventCls, 5180 sequencedEventConst, 5181 focusEvent); 5182 DASSERT(!safe_ExceptionOccurred(env)); 5183 DASSERT(sequencedEvent != NULL); 5184 env->DeleteLocalRef(focusEvent); focusEvent = NULL; 5185 CHECK_NULL(sequencedEvent); 5186 SendEvent(sequencedEvent); 5187 5188 env->DeleteLocalRef(sequencedEvent); 5189 } 5190 5191 /* 5192 * Forward a filtered event directly to the subclassed window. 5193 * This method is needed so that DefWindowProc is invoked on the 5194 * component's owning thread. 5195 */ 5196 MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL) 5197 { 5198 DefWindowProc(msg->message, msg->wParam, msg->lParam); 5199 delete msg; 5200 return mrConsume; 5201 } 5202 5203 /* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent 5204 on the toolkit thread. This method may pre-filter the messages. */ 5205 BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic) 5206 { 5207 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5208 // We should cut off keyboard events to disabled components 5209 // to avoid the components responding visually to keystrokes when disabled. 5210 // we shouldn't cut off WM_SYS* messages as they aren't used for normal activity 5211 // but to activate menus, close windows, etc 5212 switch(msg->message) { 5213 case WM_KEYDOWN: 5214 case WM_KEYUP: 5215 case WM_CHAR: 5216 case WM_DEADCHAR: 5217 { 5218 if (!isRecursivelyEnabled()) { 5219 goto quit; 5220 } 5221 break; 5222 } 5223 } 5224 if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT, 5225 (WPARAM) synthetic, (LPARAM) msg)) { 5226 return TRUE; 5227 } else { 5228 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5229 } 5230 quit: 5231 delete msg; 5232 return FALSE; 5233 } 5234 5235 void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent) 5236 { 5237 jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID); 5238 UINT message; 5239 switch (id) { 5240 case java_awt_event_KeyEvent_KEY_PRESSED: 5241 message = WM_KEYDOWN; 5242 break; 5243 case java_awt_event_KeyEvent_KEY_RELEASED: 5244 message = WM_KEYUP; 5245 break; 5246 case java_awt_event_KeyEvent_KEY_TYPED: 5247 message = WM_CHAR; 5248 break; 5249 default: 5250 return; 5251 } 5252 5253 /* 5254 * KeyEvent.modifiers aren't supported -- the Java apppwd must send separate 5255 * KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys. 5256 */ 5257 if (id == java_awt_event_KeyEvent_KEY_TYPED) { 5258 // WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR 5259 // (for Edit control) 5260 jchar keyChar = (jchar) 5261 (env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID); 5262 5263 // Bugid 4724007. If it is a Delete character, don't send the fake 5264 // KEY_TYPED we created back to the native window: Windows doesn't 5265 // expect a WM_CHAR for Delete in TextFields, so it tries to enter a 5266 // character after deleting. 5267 if (keyChar == '\177') { // the Delete character 5268 return; 5269 } 5270 5271 // Disable forwarding WM_CHAR messages to disabled components 5272 if (isRecursivelyEnabled()) { 5273 if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR, 5274 MAKEWPARAM(keyChar, TRUE), 0)) { 5275 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5276 } 5277 } 5278 } else { 5279 jint keyCode = 5280 (env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID); 5281 UINT key, modifiers; 5282 AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers); 5283 MSG* msg = CreateMessage(message, key, 0); 5284 PostHandleEventMessage(msg, TRUE); 5285 } 5286 } 5287 5288 void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent) 5289 { 5290 /* DebugBreak(); */ 5291 jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID); 5292 jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID); 5293 5294 WPARAM wParam = 0; 5295 WORD wLow = 0; 5296 jint wheelAmt = 0; 5297 jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID); 5298 UINT message; 5299 switch (id) { 5300 case java_awt_event_MouseEvent_MOUSE_PRESSED: { 5301 switch (button) { 5302 case java_awt_event_MouseEvent_BUTTON1: 5303 message = WM_LBUTTONDOWN; break; 5304 case java_awt_event_MouseEvent_BUTTON3: 5305 message = WM_MBUTTONDOWN; break; 5306 case java_awt_event_MouseEvent_BUTTON2: 5307 message = WM_RBUTTONDOWN; break; 5308 default: 5309 return; 5310 } 5311 break; 5312 } 5313 case java_awt_event_MouseEvent_MOUSE_RELEASED: { 5314 switch (button) { 5315 case java_awt_event_MouseEvent_BUTTON1: 5316 message = WM_LBUTTONUP; break; 5317 case java_awt_event_MouseEvent_BUTTON3: 5318 message = WM_MBUTTONUP; break; 5319 case java_awt_event_MouseEvent_BUTTON2: 5320 message = WM_RBUTTONUP; break; 5321 default: 5322 return; 5323 } 5324 break; 5325 } 5326 case java_awt_event_MouseEvent_MOUSE_MOVED: 5327 /* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */ 5328 case java_awt_event_MouseEvent_MOUSE_DRAGGED: 5329 message = WM_MOUSEMOVE; 5330 break; 5331 case java_awt_event_MouseEvent_MOUSE_WHEEL: 5332 if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) { 5333 wLow |= MK_CONTROL; 5334 } 5335 if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) { 5336 wLow |= MK_SHIFT; 5337 } 5338 if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) { 5339 wLow |= MK_LBUTTON; 5340 } 5341 if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) { 5342 wLow |= MK_RBUTTON; 5343 } 5344 if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) { 5345 wLow |= MK_MBUTTON; 5346 } 5347 if (modifiers & X1_BUTTON) { 5348 wLow |= GetButtonMK(X1_BUTTON); 5349 } 5350 if (modifiers & X2_BUTTON) { 5351 wLow |= GetButtonMK(X2_BUTTON); 5352 } 5353 5354 wheelAmt = (jint)JNU_CallMethodByName(env, 5355 NULL, 5356 mouseEvent, 5357 "getWheelRotation", 5358 "()I").i; 5359 DASSERT(!safe_ExceptionOccurred(env)); 5360 JNU_CHECK_EXCEPTION(env); 5361 DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt); 5362 5363 // convert Java wheel amount value to Win32 5364 wheelAmt *= -1 * WHEEL_DELTA; 5365 5366 message = WM_MOUSEWHEEL; 5367 wParam = MAKEWPARAM(wLow, wheelAmt); 5368 5369 break; 5370 default: 5371 return; 5372 } 5373 jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID); 5374 jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID); 5375 MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y); 5376 PostHandleEventMessage(msg, TRUE); 5377 } 5378 5379 BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;} 5380 5381 void AwtComponent::Invalidate(RECT* r) 5382 { 5383 ::InvalidateRect(GetHWnd(), r, FALSE); 5384 } 5385 5386 void AwtComponent::BeginValidate() 5387 { 5388 DASSERT(m_validationNestCount >= 0 && 5389 m_validationNestCount < 1000); // sanity check 5390 5391 if (m_validationNestCount == 0) { 5392 // begin deferred window positioning if we're not inside 5393 // another Begin/EndValidate pair 5394 DASSERT(m_hdwp == NULL); 5395 m_hdwp = ::BeginDeferWindowPos(32); 5396 } 5397 5398 m_validationNestCount++; 5399 } 5400 5401 void AwtComponent::EndValidate() 5402 { 5403 DASSERT(m_validationNestCount > 0 && 5404 m_validationNestCount < 1000); // sanity check 5405 DASSERT(m_hdwp != NULL); 5406 5407 m_validationNestCount--; 5408 if (m_validationNestCount == 0) { 5409 // if this call to EndValidate is not nested inside another 5410 // Begin/EndValidate pair, end deferred window positioning 5411 ::EndDeferWindowPos(m_hdwp); 5412 m_hdwp = NULL; 5413 } 5414 } 5415 5416 /** 5417 * HWND, AwtComponent and Java Peer interaction 5418 */ 5419 5420 /* 5421 *Link the C++, Java peer, and HWNDs together. 5422 */ 5423 void AwtComponent::LinkObjects(JNIEnv *env, jobject peer) 5424 { 5425 /* 5426 * Bind all three objects together thru this C++ object, two-way to each: 5427 * JavaPeer <-> C++ <-> HWND 5428 * 5429 * C++ -> JavaPeer 5430 */ 5431 if (m_peerObject == NULL) { 5432 // This may have already been set up by CreateHWnd 5433 // And we don't want to create two references so we 5434 // will leave the prior one alone 5435 m_peerObject = env->NewGlobalRef(peer); 5436 } 5437 /* JavaPeer -> HWND */ 5438 env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd)); 5439 5440 /* JavaPeer -> C++ */ 5441 JNI_SET_PDATA(peer, this); 5442 5443 /* HWND -> C++ */ 5444 SetComponentInHWND(); 5445 } 5446 5447 /* Cleanup above linking */ 5448 void AwtComponent::UnlinkObjects() 5449 { 5450 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5451 if (m_peerObject) { 5452 env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); 5453 JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL)); 5454 JNI_SET_DESTROYED(m_peerObject); 5455 env->DeleteGlobalRef(m_peerObject); 5456 m_peerObject = NULL; 5457 } 5458 } 5459 5460 void AwtComponent::Enable(BOOL bEnable) 5461 { 5462 if (bEnable && IsTopLevel()) { 5463 // we should not enable blocked toplevels 5464 bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); 5465 } 5466 // Shouldn't trigger native focus change 5467 // (only the proxy may be the native focus owner). 5468 ::EnableWindow(GetHWnd(), bEnable); 5469 5470 CriticalSection::Lock l(GetLock()); 5471 VerifyState(); 5472 } 5473 5474 /* 5475 * associate an AwtDropTarget with this AwtComponent 5476 */ 5477 5478 AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) { 5479 m_dropTarget = new AwtDropTarget(env, this); 5480 m_dropTarget->RegisterTarget(TRUE); 5481 return m_dropTarget; 5482 } 5483 5484 /* 5485 * disassociate an AwtDropTarget with this AwtComponent 5486 */ 5487 5488 void AwtComponent::DestroyDropTarget() { 5489 if (m_dropTarget != NULL) { 5490 m_dropTarget->RegisterTarget(FALSE); 5491 m_dropTarget->Release(); 5492 m_dropTarget = NULL; 5493 } 5494 } 5495 5496 BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) { 5497 return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK; 5498 } 5499 5500 BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) { 5501 return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE; 5502 } 5503 5504 void AwtComponent::_Show(void *param) 5505 { 5506 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5507 5508 jobject self = (jobject)param; 5509 5510 AwtComponent *p; 5511 5512 PDATA pData; 5513 JNI_CHECK_PEER_GOTO(self, ret); 5514 p = (AwtComponent *)pData; 5515 if (::IsWindow(p->GetHWnd())) 5516 { 5517 p->SendMessage(WM_AWT_COMPONENT_SHOW); 5518 } 5519 ret: 5520 env->DeleteGlobalRef(self); 5521 } 5522 5523 void AwtComponent::_Hide(void *param) 5524 { 5525 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5526 5527 jobject self = (jobject)param; 5528 5529 AwtComponent *p; 5530 5531 PDATA pData; 5532 JNI_CHECK_PEER_GOTO(self, ret); 5533 p = (AwtComponent *)pData; 5534 if (::IsWindow(p->GetHWnd())) 5535 { 5536 p->SendMessage(WM_AWT_COMPONENT_HIDE); 5537 } 5538 ret: 5539 env->DeleteGlobalRef(self); 5540 } 5541 5542 void AwtComponent::_Enable(void *param) 5543 { 5544 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5545 5546 jobject self = (jobject)param; 5547 5548 AwtComponent *p; 5549 5550 PDATA pData; 5551 JNI_CHECK_PEER_GOTO(self, ret); 5552 p = (AwtComponent *)pData; 5553 if (::IsWindow(p->GetHWnd())) 5554 { 5555 p->Enable(TRUE); 5556 } 5557 ret: 5558 env->DeleteGlobalRef(self); 5559 } 5560 5561 void AwtComponent::_Disable(void *param) 5562 { 5563 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5564 5565 jobject self = (jobject)param; 5566 5567 AwtComponent *p; 5568 5569 PDATA pData; 5570 JNI_CHECK_PEER_GOTO(self, ret); 5571 p = (AwtComponent *)pData; 5572 if (::IsWindow(p->GetHWnd())) 5573 { 5574 p->Enable(FALSE); 5575 } 5576 ret: 5577 env->DeleteGlobalRef(self); 5578 } 5579 5580 jobject AwtComponent::_GetLocationOnScreen(void *param) 5581 { 5582 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5583 5584 jobject self = (jobject)param; 5585 5586 jobject result = NULL; 5587 AwtComponent *p; 5588 5589 PDATA pData; 5590 JNI_CHECK_PEER_GOTO(self, ret); 5591 p = (AwtComponent *)pData; 5592 if (::IsWindow(p->GetHWnd())) 5593 { 5594 RECT rect; 5595 VERIFY(::GetWindowRect(p->GetHWnd(),&rect)); 5596 result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", 5597 rect.left, rect.top); 5598 } 5599 ret: 5600 env->DeleteGlobalRef(self); 5601 5602 if (result != NULL) 5603 { 5604 jobject resultGlobalRef = env->NewGlobalRef(result); 5605 env->DeleteLocalRef(result); 5606 return resultGlobalRef; 5607 } 5608 else 5609 { 5610 return NULL; 5611 } 5612 } 5613 5614 void AwtComponent::_Reshape(void *param) 5615 { 5616 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5617 5618 ReshapeStruct *rs = (ReshapeStruct*)param; 5619 jobject self = rs->component; 5620 jint x = rs->x; 5621 jint y = rs->y; 5622 jint w = rs->w; 5623 jint h = rs->h; 5624 5625 AwtComponent *p; 5626 5627 PDATA pData; 5628 JNI_CHECK_PEER_GOTO(self, ret); 5629 p = (AwtComponent *)pData; 5630 if (::IsWindow(p->GetHWnd())) 5631 { 5632 RECT* r = new RECT; 5633 ::SetRect(r, x, y, x + w, y + h); 5634 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r); 5635 } 5636 ret: 5637 env->DeleteGlobalRef(self); 5638 5639 delete rs; 5640 } 5641 5642 void AwtComponent::_ReshapeNoCheck(void *param) 5643 { 5644 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5645 5646 ReshapeStruct *rs = (ReshapeStruct*)param; 5647 jobject self = rs->component; 5648 jint x = rs->x; 5649 jint y = rs->y; 5650 jint w = rs->w; 5651 jint h = rs->h; 5652 5653 AwtComponent *p; 5654 5655 PDATA pData; 5656 JNI_CHECK_PEER_GOTO(self, ret); 5657 p = (AwtComponent *)pData; 5658 if (::IsWindow(p->GetHWnd())) 5659 { 5660 RECT* r = new RECT; 5661 ::SetRect(r, x, y, x + w, y + h); 5662 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r); 5663 } 5664 ret: 5665 env->DeleteGlobalRef(self); 5666 5667 delete rs; 5668 } 5669 5670 void AwtComponent::_NativeHandleEvent(void *param) 5671 { 5672 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5673 5674 NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param; 5675 jobject self = nhes->component; 5676 jobject event = nhes->event; 5677 5678 AwtComponent *p; 5679 5680 PDATA pData; 5681 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5682 pData = JNI_GET_PDATA(self); 5683 if (pData == NULL) { 5684 env->DeleteGlobalRef(self); 5685 if (event != NULL) { 5686 env->DeleteGlobalRef(event); 5687 } 5688 delete nhes; 5689 return; 5690 } 5691 JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret); 5692 5693 p = (AwtComponent *)pData; 5694 if (::IsWindow(p->GetHWnd())) 5695 { 5696 if (env->EnsureLocalCapacity(1) < 0) { 5697 env->DeleteGlobalRef(self); 5698 env->DeleteGlobalRef(event); 5699 delete nhes; 5700 return; 5701 } 5702 jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID); 5703 int id = (env)->GetIntField(event, AwtAWTEvent::idID); 5704 DASSERT(!safe_ExceptionOccurred(env)); 5705 if (bdata != 0) { 5706 MSG msg; 5707 (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg); 5708 (env)->DeleteLocalRef(bdata); 5709 static BOOL keyDownConsumed = FALSE; 5710 static BOOL bCharChanged = FALSE; 5711 static WCHAR modifiedChar; 5712 WCHAR unicodeChar; 5713 5714 /* Remember if a KEY_PRESSED event is consumed, as an old model 5715 * program won't consume a subsequent KEY_TYPED event. 5716 */ 5717 jboolean consumed = 5718 (env)->GetBooleanField(event, AwtAWTEvent::consumedID); 5719 DASSERT(!safe_ExceptionOccurred(env)); 5720 5721 if (consumed) { 5722 keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED); 5723 env->DeleteGlobalRef(self); 5724 env->DeleteGlobalRef(event); 5725 delete nhes; 5726 return; 5727 5728 } else if (id == java_awt_event_KeyEvent_KEY_PRESSED) { 5729 // Fix for 6637607: reset consuming 5730 keyDownConsumed = FALSE; 5731 } 5732 5733 /* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support 5734 * the old model. 5735 */ 5736 if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) { 5737 keyDownConsumed = FALSE; 5738 env->DeleteGlobalRef(self); 5739 env->DeleteGlobalRef(event); 5740 delete nhes; 5741 return; 5742 } 5743 5744 /* Modify any event parameters, if necessary. */ 5745 if (self && pData && 5746 id >= java_awt_event_KeyEvent_KEY_FIRST && 5747 id <= java_awt_event_KeyEvent_KEY_LAST) { 5748 5749 AwtComponent* p = (AwtComponent*)pData; 5750 5751 jint keyCode = 5752 (env)->GetIntField(event, AwtKeyEvent::keyCodeID); 5753 jchar keyChar = 5754 (env)->GetCharField(event, AwtKeyEvent::keyCharID); 5755 jint modifiers = 5756 (env)->GetIntField(event, AwtInputEvent::modifiersID); 5757 5758 DASSERT(!safe_ExceptionOccurred(env)); 5759 5760 /* Check to see whether the keyCode or modifiers were changed 5761 on the keyPressed event, and tweak the following keyTyped 5762 event (if any) accodingly. */ 5763 switch (id) { 5764 case java_awt_event_KeyEvent_KEY_PRESSED: 5765 { 5766 UINT winKey = (UINT)msg.wParam; 5767 bCharChanged = FALSE; 5768 5769 if (winKey == VK_PROCESSKEY) { 5770 // Leave it up to IME 5771 break; 5772 } 5773 5774 if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) { 5775 UINT newWinKey, ignored; 5776 p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey); 5777 if (newWinKey != 0) { 5778 winKey = newWinKey; 5779 } 5780 } 5781 5782 BOOL isDeadKey = FALSE; 5783 modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey); 5784 bCharChanged = (keyChar != modifiedChar); 5785 } 5786 break; 5787 5788 case java_awt_event_KeyEvent_KEY_RELEASED: 5789 { 5790 keyDownConsumed = FALSE; 5791 bCharChanged = FALSE; 5792 } 5793 break; 5794 5795 case java_awt_event_KeyEvent_KEY_TYPED: 5796 { 5797 if (bCharChanged) 5798 { 5799 unicodeChar = modifiedChar; 5800 } 5801 else 5802 { 5803 unicodeChar = keyChar; 5804 } 5805 bCharChanged = FALSE; 5806 5807 // Disable forwarding KEY_TYPED messages to peers of 5808 // disabled components 5809 if (p->isRecursivelyEnabled()) { 5810 // send the character back to the native window for 5811 // processing. The WM_AWT_FORWARD_CHAR handler will send 5812 // this character to DefWindowProc 5813 if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR, 5814 MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) { 5815 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5816 } 5817 } 5818 env->DeleteGlobalRef(self); 5819 env->DeleteGlobalRef(event); 5820 delete nhes; 5821 return; 5822 } 5823 break; 5824 5825 default: 5826 break; 5827 } 5828 } 5829 5830 // ignore all InputMethodEvents 5831 if (self && (pData = JNI_GET_PDATA(self)) && 5832 id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && 5833 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) { 5834 env->DeleteGlobalRef(self); 5835 env->DeleteGlobalRef(event); 5836 delete nhes; 5837 return; 5838 } 5839 5840 // Create copy for local msg 5841 MSG* pCopiedMsg = new MSG; 5842 memmove(pCopiedMsg, &msg, sizeof(MSG)); 5843 // Event handler deletes msg 5844 p->PostHandleEventMessage(pCopiedMsg, FALSE); 5845 5846 env->DeleteGlobalRef(self); 5847 env->DeleteGlobalRef(event); 5848 delete nhes; 5849 return; 5850 } 5851 5852 /* Forward any valid synthesized events. Currently only mouse and 5853 * key events are supported. 5854 */ 5855 if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) { 5856 env->DeleteGlobalRef(self); 5857 env->DeleteGlobalRef(event); 5858 delete nhes; 5859 return; 5860 } 5861 5862 AwtComponent* p = (AwtComponent*)pData; 5863 if (id >= java_awt_event_KeyEvent_KEY_FIRST && 5864 id <= java_awt_event_KeyEvent_KEY_LAST) { 5865 p->SynthesizeKeyMessage(env, event); 5866 } else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST && 5867 id <= java_awt_event_MouseEvent_MOUSE_LAST) { 5868 p->SynthesizeMouseMessage(env, event); 5869 } 5870 } 5871 5872 ret: 5873 if (self != NULL) { 5874 env->DeleteGlobalRef(self); 5875 } 5876 if (event != NULL) { 5877 env->DeleteGlobalRef(event); 5878 } 5879 5880 delete nhes; 5881 } 5882 5883 void AwtComponent::_SetForeground(void *param) 5884 { 5885 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5886 5887 SetColorStruct *scs = (SetColorStruct *)param; 5888 jobject self = scs->component; 5889 jint rgb = scs->rgb; 5890 5891 AwtComponent *c = NULL; 5892 5893 PDATA pData; 5894 JNI_CHECK_PEER_GOTO(self, ret); 5895 c = (AwtComponent *)pData; 5896 if (::IsWindow(c->GetHWnd())) 5897 { 5898 c->SetColor(PALETTERGB((rgb>>16)&0xff, 5899 (rgb>>8)&0xff, 5900 (rgb)&0xff)); 5901 c->VerifyState(); 5902 } 5903 ret: 5904 env->DeleteGlobalRef(self); 5905 5906 delete scs; 5907 } 5908 5909 void AwtComponent::_SetBackground(void *param) 5910 { 5911 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5912 5913 SetColorStruct *scs = (SetColorStruct *)param; 5914 jobject self = scs->component; 5915 jint rgb = scs->rgb; 5916 5917 AwtComponent *c = NULL; 5918 5919 PDATA pData; 5920 JNI_CHECK_PEER_GOTO(self, ret); 5921 c = (AwtComponent *)pData; 5922 if (::IsWindow(c->GetHWnd())) 5923 { 5924 c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff, 5925 (rgb>>8)&0xff, 5926 (rgb)&0xff)); 5927 c->VerifyState(); 5928 } 5929 ret: 5930 env->DeleteGlobalRef(self); 5931 5932 delete scs; 5933 } 5934 5935 void AwtComponent::_SetFont(void *param) 5936 { 5937 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5938 5939 SetFontStruct *sfs = (SetFontStruct *)param; 5940 jobject self = sfs->component; 5941 jobject font = sfs->font; 5942 5943 AwtComponent *c = NULL; 5944 5945 PDATA pData; 5946 JNI_CHECK_PEER_GOTO(self, ret); 5947 JNI_CHECK_NULL_GOTO(font, "null font", ret); 5948 c = (AwtComponent *)pData; 5949 if (::IsWindow(c->GetHWnd())) 5950 { 5951 AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID); 5952 if (awtFont == NULL) { 5953 /*arguments of AwtFont::Create are changed for multifont component */ 5954 awtFont = AwtFont::Create(env, font); 5955 } 5956 env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont); 5957 5958 c->SetFont(awtFont); 5959 } 5960 ret: 5961 env->DeleteGlobalRef(self); 5962 env->DeleteGlobalRef(font); 5963 5964 delete sfs; 5965 } 5966 5967 // Sets or kills focus for a component. 5968 void AwtComponent::_SetFocus(void *param) 5969 { 5970 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5971 5972 SetFocusStruct *sfs = (SetFocusStruct *)param; 5973 jobject self = sfs->component; 5974 jboolean doSetFocus = sfs->doSetFocus; 5975 5976 AwtComponent *c = NULL; 5977 5978 PDATA pData; 5979 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5980 pData = JNI_GET_PDATA(self); 5981 if (pData == NULL) { 5982 // do nothing just return false 5983 goto ret; 5984 } 5985 5986 c = (AwtComponent *)pData; 5987 if (::IsWindow(c->GetHWnd())) { 5988 c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0); 5989 } 5990 ret: 5991 env->DeleteGlobalRef(self); 5992 5993 delete sfs; 5994 } 5995 5996 void AwtComponent::_Start(void *param) 5997 { 5998 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5999 6000 jobject self = (jobject)param; 6001 6002 AwtComponent *c = NULL; 6003 6004 PDATA pData; 6005 JNI_CHECK_PEER_GOTO(self, ret); 6006 c = (AwtComponent *)pData; 6007 if (::IsWindow(c->GetHWnd())) 6008 { 6009 jobject target = c->GetTarget(env); 6010 6011 /* Disable window if specified -- windows are enabled by default. */ 6012 jboolean enabled = (jboolean)env->GetBooleanField(target, 6013 AwtComponent::enabledID); 6014 if (!enabled) { 6015 ::EnableWindow(c->GetHWnd(), FALSE); 6016 } 6017 6018 /* The peer is now ready for callbacks, since this is the last 6019 * initialization call 6020 */ 6021 c->EnableCallbacks(TRUE); 6022 6023 // Fix 4745222: we need to invalidate region since we validated it before initialization. 6024 ::InvalidateRgn(c->GetHWnd(), NULL, FALSE); 6025 6026 // Fix 4530093: WM_PAINT after EnableCallbacks 6027 ::UpdateWindow(c->GetHWnd()); 6028 6029 env->DeleteLocalRef(target); 6030 } 6031 ret: 6032 env->DeleteGlobalRef(self); 6033 } 6034 6035 void AwtComponent::_BeginValidate(void *param) 6036 { 6037 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6038 if (AwtToolkit::IsMainThread()) { 6039 jobject self = (jobject)param; 6040 if (self != NULL) { 6041 PDATA pData = JNI_GET_PDATA(self); 6042 if (pData) { 6043 AwtComponent *c = (AwtComponent *)pData; 6044 if (::IsWindow(c->GetHWnd())) { 6045 c->SendMessage(WM_AWT_BEGIN_VALIDATE); 6046 } 6047 } 6048 env->DeleteGlobalRef(self); 6049 } 6050 } else { 6051 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param); 6052 } 6053 } 6054 6055 void AwtComponent::_EndValidate(void *param) 6056 { 6057 if (AwtToolkit::IsMainThread()) { 6058 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6059 jobject self = (jobject)param; 6060 if (self != NULL) { 6061 PDATA pData = JNI_GET_PDATA(self); 6062 if (pData) { 6063 AwtComponent *c = (AwtComponent *)pData; 6064 if (::IsWindow(c->GetHWnd())) { 6065 c->SendMessage(WM_AWT_END_VALIDATE); 6066 } 6067 } 6068 env->DeleteGlobalRef(self); 6069 } 6070 } else { 6071 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param); 6072 } 6073 } 6074 6075 void AwtComponent::_UpdateWindow(void *param) 6076 { 6077 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6078 if (AwtToolkit::IsMainThread()) { 6079 jobject self = (jobject)param; 6080 AwtComponent *c = NULL; 6081 PDATA pData; 6082 JNI_CHECK_PEER_GOTO(self, ret); 6083 c = (AwtComponent *)pData; 6084 if (::IsWindow(c->GetHWnd())) { 6085 ::UpdateWindow(c->GetHWnd()); 6086 } 6087 ret: 6088 env->DeleteGlobalRef(self); 6089 } else { 6090 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param); 6091 } 6092 } 6093 6094 jlong AwtComponent::_AddNativeDropTarget(void *param) 6095 { 6096 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6097 6098 jobject self = (jobject)param; 6099 6100 jlong result = 0; 6101 AwtComponent *c = NULL; 6102 6103 PDATA pData; 6104 JNI_CHECK_PEER_GOTO(self, ret); 6105 c = (AwtComponent *)pData; 6106 if (::IsWindow(c->GetHWnd())) 6107 { 6108 result = (jlong)(c->CreateDropTarget(env)); 6109 } 6110 ret: 6111 env->DeleteGlobalRef(self); 6112 6113 return result; 6114 } 6115 6116 void AwtComponent::_RemoveNativeDropTarget(void *param) 6117 { 6118 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6119 6120 jobject self = (jobject)param; 6121 6122 AwtComponent *c = NULL; 6123 6124 PDATA pData; 6125 JNI_CHECK_PEER_GOTO(self, ret); 6126 c = (AwtComponent *)pData; 6127 if (::IsWindow(c->GetHWnd())) 6128 { 6129 c->DestroyDropTarget(); 6130 } 6131 ret: 6132 env->DeleteGlobalRef(self); 6133 } 6134 6135 jintArray AwtComponent::_CreatePrintedPixels(void *param) 6136 { 6137 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6138 6139 CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param; 6140 jobject self = cpps->component; 6141 6142 jintArray result = NULL; 6143 AwtComponent *c = NULL; 6144 6145 PDATA pData; 6146 JNI_CHECK_PEER_GOTO(self, ret); 6147 c = (AwtComponent *)pData; 6148 if (::IsWindow(c->GetHWnd())) 6149 { 6150 result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0); 6151 } 6152 ret: 6153 env->DeleteGlobalRef(self); 6154 6155 delete cpps; 6156 return result; // this reference is global 6157 } 6158 6159 jboolean AwtComponent::_IsObscured(void *param) 6160 { 6161 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6162 6163 jobject self = (jobject)param; 6164 6165 jboolean result = JNI_FALSE; 6166 AwtComponent *c = NULL; 6167 6168 PDATA pData; 6169 JNI_CHECK_PEER_GOTO(self, ret); 6170 6171 c = (AwtComponent *)pData; 6172 6173 if (::IsWindow(c->GetHWnd())) 6174 { 6175 HWND hWnd = c->GetHWnd(); 6176 HDC hDC = ::GetDC(hWnd); 6177 RECT clipbox; 6178 int callresult = ::GetClipBox(hDC, &clipbox); 6179 switch(callresult) { 6180 case NULLREGION : 6181 result = JNI_FALSE; 6182 break; 6183 case SIMPLEREGION : { 6184 RECT windowRect; 6185 if (!::GetClientRect(hWnd, &windowRect)) { 6186 result = JNI_TRUE; 6187 } else { 6188 result = (jboolean)((clipbox.bottom != windowRect.bottom) 6189 || (clipbox.left != windowRect.left) 6190 || (clipbox.right != windowRect.right) 6191 || (clipbox.top != windowRect.top)); 6192 } 6193 break; 6194 } 6195 case COMPLEXREGION : 6196 default : 6197 result = JNI_TRUE; 6198 break; 6199 } 6200 ::ReleaseDC(hWnd, hDC); 6201 } 6202 ret: 6203 env->DeleteGlobalRef(self); 6204 6205 return result; 6206 } 6207 6208 jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param) 6209 { 6210 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6211 6212 jobject self = (jobject)param; 6213 6214 jboolean result = JNI_FALSE; 6215 AwtComponent *c = NULL; 6216 6217 PDATA pData; 6218 JNI_CHECK_PEER_GOTO(self, ret); 6219 c = (AwtComponent *)pData; 6220 if (::IsWindow(c->GetHWnd())) 6221 { 6222 result = JNI_IS_TRUE(c->InheritsNativeMouseWheelBehavior()); 6223 } 6224 ret: 6225 env->DeleteGlobalRef(self); 6226 6227 return result; 6228 } 6229 6230 void AwtComponent::_SetParent(void * param) 6231 { 6232 if (AwtToolkit::IsMainThread()) { 6233 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6234 SetParentStruct *data = (SetParentStruct*) param; 6235 jobject self = data->component; 6236 jobject parent = data->parentComp; 6237 6238 AwtComponent *awtComponent = NULL; 6239 AwtComponent *awtParent = NULL; 6240 6241 PDATA pData; 6242 JNI_CHECK_PEER_GOTO(self, ret); 6243 awtComponent = (AwtComponent *)pData; 6244 JNI_CHECK_PEER_GOTO(parent, ret); 6245 awtParent = (AwtComponent *)pData; 6246 6247 HWND selfWnd = awtComponent->GetHWnd(); 6248 HWND parentWnd = awtParent->GetHWnd(); 6249 if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) { 6250 // Shouldn't trigger native focus change 6251 // (only the proxy may be the native focus owner). 6252 ::SetParent(selfWnd, parentWnd); 6253 } 6254 ret: 6255 env->DeleteGlobalRef(self); 6256 env->DeleteGlobalRef(parent); 6257 delete data; 6258 } else { 6259 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetParent, param); 6260 } 6261 } 6262 6263 void AwtComponent::_SetRectangularShape(void *param) 6264 { 6265 if (!AwtToolkit::IsMainThread()) { 6266 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param); 6267 } else { 6268 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6269 6270 SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param; 6271 jobject self = data->component; 6272 jint x1 = data->x1; 6273 jint x2 = data->x2; 6274 jint y1 = data->y1; 6275 jint y2 = data->y2; 6276 jobject region = data->region; 6277 6278 AwtComponent *c = NULL; 6279 6280 PDATA pData; 6281 JNI_CHECK_PEER_GOTO(self, ret); 6282 6283 c = (AwtComponent *)pData; 6284 if (::IsWindow(c->GetHWnd())) { 6285 HRGN hRgn = NULL; 6286 6287 // If all the params are zeros, the shape must be simply reset. 6288 // Otherwise, convert it into a region. 6289 if (region || x1 || x2 || y1 || y2) { 6290 RECT_T rects[256]; 6291 RECT_T *pRect = rects; 6292 6293 const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, 6294 region, &pRect, sizeof(rects)/sizeof(rects[0])); 6295 if (!pRect) { 6296 // RegionToYXBandedRectangles doesn't use safe_Malloc(), 6297 // so throw the exception explicitly 6298 throw std::bad_alloc(); 6299 } 6300 6301 RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, 6302 sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects); 6303 memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects); 6304 if (pRect != rects) { 6305 free(pRect); 6306 } 6307 pRect = NULL; 6308 6309 RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData; 6310 pRgnHdr->dwSize = sizeof(RGNDATAHEADER); 6311 pRgnHdr->iType = RDH_RECTANGLES; 6312 pRgnHdr->nRgnSize = 0; 6313 pRgnHdr->rcBound.top = 0; 6314 pRgnHdr->rcBound.left = 0; 6315 pRgnHdr->rcBound.bottom = LONG(y2 - y1); 6316 pRgnHdr->rcBound.right = LONG(x2 - x1); 6317 pRgnHdr->nCount = numrects; 6318 6319 hRgn = ::ExtCreateRegion(NULL, 6320 sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData); 6321 6322 free(pRgnData); 6323 } 6324 6325 ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE); 6326 } 6327 6328 ret: 6329 env->DeleteGlobalRef(self); 6330 if (region) { 6331 env->DeleteGlobalRef(region); 6332 } 6333 6334 delete data; 6335 } 6336 } 6337 6338 void AwtComponent::_SetZOrder(void *param) { 6339 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6340 6341 SetZOrderStruct *data = (SetZOrderStruct *)param; 6342 jobject self = data->component; 6343 HWND above = HWND_TOP; 6344 if (data->above != 0) { 6345 above = reinterpret_cast<HWND>(data->above); 6346 } 6347 6348 AwtComponent *c = NULL; 6349 6350 PDATA pData; 6351 JNI_CHECK_PEER_GOTO(self, ret); 6352 6353 c = (AwtComponent *)pData; 6354 if (::IsWindow(c->GetHWnd())) { 6355 ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0, 6356 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS); 6357 } 6358 6359 ret: 6360 env->DeleteGlobalRef(self); 6361 6362 delete data; 6363 } 6364 6365 void AwtComponent::PostUngrabEvent() { 6366 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6367 jobject target = GetTarget(env); 6368 jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V", 6369 target); 6370 if (safe_ExceptionOccurred(env)) { 6371 env->ExceptionDescribe(); 6372 env->ExceptionClear(); 6373 } 6374 env->DeleteLocalRef(target); 6375 if (event != NULL) { 6376 SendEvent(event); 6377 env->DeleteLocalRef(event); 6378 } 6379 } 6380 6381 void AwtComponent::SetFocusedWindow(HWND window) 6382 { 6383 HWND old = sm_focusedWindow; 6384 sm_focusedWindow = window; 6385 6386 AwtWindow::FocusedWindowChanged(old, window); 6387 } 6388 6389 /************************************************************************ 6390 * Component native methods 6391 */ 6392 6393 extern "C" { 6394 6395 /** 6396 * This method is called from the WGL pipeline when it needs to retrieve 6397 * the HWND associated with a ComponentPeer's C++ level object. 6398 */ 6399 HWND 6400 AwtComponent_GetHWnd(JNIEnv *env, jlong pData) 6401 { 6402 AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData); 6403 if (p == NULL) { 6404 return (HWND)0; 6405 } 6406 return p->GetHWnd(); 6407 } 6408 6409 static void _GetInsets(void* param) 6410 { 6411 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6412 6413 GetInsetsStruct *gis = (GetInsetsStruct *)param; 6414 jobject self = gis->window; 6415 6416 gis->insets->left = gis->insets->top = 6417 gis->insets->right = gis->insets->bottom = 0; 6418 6419 PDATA pData; 6420 JNI_CHECK_PEER_GOTO(self, ret); 6421 AwtComponent *component = (AwtComponent *)pData; 6422 6423 component->GetInsets(gis->insets); 6424 6425 ret: 6426 env->DeleteGlobalRef(self); 6427 delete gis; 6428 } 6429 6430 /** 6431 * This method is called from the WGL pipeline when it needs to retrieve 6432 * the insets associated with a ComponentPeer's C++ level object. 6433 */ 6434 void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets) 6435 { 6436 TRY; 6437 6438 GetInsetsStruct *gis = new GetInsetsStruct; 6439 gis->window = env->NewGlobalRef(peer); 6440 gis->insets = insets; 6441 6442 AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis); 6443 // global refs and mds are deleted in _UpdateWindow 6444 6445 CATCH_BAD_ALLOC; 6446 6447 } 6448 6449 JNIEXPORT void JNICALL 6450 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) 6451 { 6452 TRY; 6453 jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent"); 6454 CHECK_NULL(inputEventClazz); 6455 jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I"); 6456 CHECK_NULL(getButtonDownMasksID); 6457 jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID); 6458 jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE); 6459 CHECK_NULL(tmp); 6460 jsize len = env->GetArrayLength(obj); 6461 AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len); 6462 for (int i = 0; i < len; i++) { 6463 AwtComponent::masks[i] = tmp[i]; 6464 } 6465 env->ReleaseIntArrayElements(obj, tmp, 0); 6466 env->DeleteLocalRef(obj); 6467 6468 /* class ids */ 6469 jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer"); 6470 6471 DASSERT(peerCls); 6472 CHECK_NULL(peerCls); 6473 6474 /* field ids */ 6475 AwtComponent::peerID = 6476 env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;"); 6477 DASSERT(AwtComponent::peerID); 6478 CHECK_NULL(AwtComponent::peerID); 6479 6480 AwtComponent::xID = env->GetFieldID(cls, "x", "I"); 6481 DASSERT(AwtComponent::xID); 6482 CHECK_NULL(AwtComponent::xID); 6483 6484 AwtComponent::yID = env->GetFieldID(cls, "y", "I"); 6485 DASSERT(AwtComponent::yID); 6486 CHECK_NULL(AwtComponent::yID); 6487 6488 AwtComponent::heightID = env->GetFieldID(cls, "height", "I"); 6489 DASSERT(AwtComponent::heightID); 6490 CHECK_NULL(AwtComponent::heightID); 6491 6492 AwtComponent::widthID = env->GetFieldID(cls, "width", "I"); 6493 DASSERT(AwtComponent::widthID); 6494 CHECK_NULL(AwtComponent::widthID); 6495 6496 AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z"); 6497 DASSERT(AwtComponent::visibleID); 6498 CHECK_NULL(AwtComponent::visibleID); 6499 6500 AwtComponent::backgroundID = 6501 env->GetFieldID(cls, "background", "Ljava/awt/Color;"); 6502 DASSERT(AwtComponent::backgroundID); 6503 CHECK_NULL(AwtComponent::backgroundID); 6504 6505 AwtComponent::foregroundID = 6506 env->GetFieldID(cls, "foreground", "Ljava/awt/Color;"); 6507 DASSERT(AwtComponent::foregroundID); 6508 CHECK_NULL(AwtComponent::foregroundID); 6509 6510 AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z"); 6511 DASSERT(AwtComponent::enabledID); 6512 CHECK_NULL(AwtComponent::enabledID); 6513 6514 AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;"); 6515 DASSERT(AwtComponent::parentID); 6516 CHECK_NULL(AwtComponent::parentID); 6517 6518 AwtComponent::graphicsConfigID = 6519 env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;"); 6520 DASSERT(AwtComponent::graphicsConfigID); 6521 CHECK_NULL(AwtComponent::graphicsConfigID); 6522 6523 AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z"); 6524 DASSERT(AwtComponent::focusableID); 6525 CHECK_NULL(AwtComponent::focusableID); 6526 6527 AwtComponent::appContextID = env->GetFieldID(cls, "appContext", 6528 "Lsun/awt/AppContext;"); 6529 DASSERT(AwtComponent::appContextID); 6530 CHECK_NULL(AwtComponent::appContextID); 6531 6532 AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig", 6533 "Lsun/awt/Win32GraphicsConfig;"); 6534 DASSERT(AwtComponent::peerGCID); 6535 CHECK_NULL(AwtComponent::peerGCID); 6536 6537 AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J"); 6538 DASSERT(AwtComponent::hwndID); 6539 CHECK_NULL(AwtComponent::hwndID); 6540 6541 AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;"); 6542 DASSERT(AwtComponent::cursorID); 6543 CHECK_NULL(AwtComponent::cursorID); 6544 6545 /* method ids */ 6546 AwtComponent::getFontMID = 6547 env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;"); 6548 DASSERT(AwtComponent::getFontMID); 6549 CHECK_NULL(AwtComponent::getFontMID); 6550 6551 AwtComponent::getToolkitMID = 6552 env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;"); 6553 DASSERT(AwtComponent::getToolkitMID); 6554 CHECK_NULL(AwtComponent::getToolkitMID); 6555 6556 AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z"); 6557 DASSERT(AwtComponent::isEnabledMID); 6558 CHECK_NULL(AwtComponent::isEnabledMID); 6559 6560 AwtComponent::getLocationOnScreenMID = 6561 env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;"); 6562 DASSERT(AwtComponent::getLocationOnScreenMID); 6563 CHECK_NULL(AwtComponent::getLocationOnScreenMID); 6564 6565 AwtComponent::replaceSurfaceDataMID = 6566 env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); 6567 DASSERT(AwtComponent::replaceSurfaceDataMID); 6568 CHECK_NULL(AwtComponent::replaceSurfaceDataMID); 6569 6570 AwtComponent::replaceSurfaceDataLaterMID = 6571 env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); 6572 DASSERT(AwtComponent::replaceSurfaceDataLaterMID); 6573 CHECK_NULL(AwtComponent::replaceSurfaceDataLaterMID); 6574 6575 AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V"); 6576 DASSERT(AwtComponent::disposeLaterMID); 6577 CHECK_NULL(AwtComponent::disposeLaterMID); 6578 6579 CATCH_BAD_ALLOC; 6580 } 6581 6582 } /* extern "C" */ 6583 6584 6585 /************************************************************************ 6586 * ComponentPeer native methods 6587 */ 6588 6589 extern "C" { 6590 6591 /* 6592 * Class: sun_awt_windows_WComponentPeer 6593 * Method: pShow 6594 * Signature: ()V 6595 */ 6596 JNIEXPORT void JNICALL 6597 Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self) 6598 { 6599 TRY; 6600 6601 jobject selfGlobalRef = env->NewGlobalRef(self); 6602 6603 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef); 6604 // selfGlobalRef is deleted in _Show 6605 6606 CATCH_BAD_ALLOC; 6607 } 6608 6609 /* 6610 * Class: sun_awt_windows_WComponentPeer 6611 * Method: hide 6612 * Signature: ()V 6613 */ 6614 JNIEXPORT void JNICALL 6615 Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self) 6616 { 6617 TRY; 6618 6619 jobject selfGlobalRef = env->NewGlobalRef(self); 6620 6621 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef); 6622 // selfGlobalRef is deleted in _Hide 6623 6624 CATCH_BAD_ALLOC; 6625 } 6626 6627 /* 6628 * Class: sun_awt_windows_WComponentPeer 6629 * Method: enable 6630 * Signature: ()V 6631 */ 6632 JNIEXPORT void JNICALL 6633 Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self) 6634 { 6635 TRY; 6636 6637 jobject selfGlobalRef = env->NewGlobalRef(self); 6638 6639 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef); 6640 // selfGlobalRef is deleted in _Enable 6641 6642 CATCH_BAD_ALLOC; 6643 } 6644 6645 /* 6646 * Class: sun_awt_windows_WComponentPeer 6647 * Method: disable 6648 * Signature: ()V 6649 */ 6650 JNIEXPORT void JNICALL 6651 Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self) 6652 { 6653 TRY; 6654 6655 jobject selfGlobalRef = env->NewGlobalRef(self); 6656 6657 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef); 6658 // selfGlobalRef is deleted in _Disable 6659 6660 CATCH_BAD_ALLOC; 6661 } 6662 6663 /* 6664 * Class: sun_awt_windows_WComponentPeer 6665 * Method: getLocationOnScreen 6666 * Signature: ()Ljava/awt/Point; 6667 */ 6668 JNIEXPORT jobject JNICALL 6669 Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self) 6670 { 6671 TRY; 6672 6673 jobject selfGlobalRef = env->NewGlobalRef(self); 6674 6675 jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall( 6676 (void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef); 6677 // selfGlobalRef is deleted in _GetLocationOnScreen 6678 if (resultGlobalRef != NULL) 6679 { 6680 jobject resultLocalRef = env->NewLocalRef(resultGlobalRef); 6681 env->DeleteGlobalRef(resultGlobalRef); 6682 return resultLocalRef; 6683 } 6684 6685 return NULL; 6686 6687 CATCH_BAD_ALLOC_RET(NULL); 6688 } 6689 6690 /* 6691 * Class: sun_awt_windows_WComponentPeer 6692 * Method: reshape 6693 * Signature: (IIII)V 6694 */ 6695 JNIEXPORT void JNICALL 6696 Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self, 6697 jint x, jint y, jint w, jint h) 6698 { 6699 TRY; 6700 6701 ReshapeStruct *rs = new ReshapeStruct; 6702 rs->component = env->NewGlobalRef(self); 6703 rs->x = x; 6704 rs->y = y; 6705 rs->w = w; 6706 rs->h = h; 6707 6708 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs); 6709 // global ref and rs are deleted in _Reshape 6710 6711 CATCH_BAD_ALLOC; 6712 } 6713 6714 /* 6715 * Class: sun_awt_windows_WComponentPeer 6716 * Method: reshape 6717 * Signature: (IIII)V 6718 */ 6719 JNIEXPORT void JNICALL 6720 Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self, 6721 jint x, jint y, jint w, jint h) 6722 { 6723 TRY; 6724 6725 ReshapeStruct *rs = new ReshapeStruct; 6726 rs->component = env->NewGlobalRef(self); 6727 rs->x = x; 6728 rs->y = y; 6729 rs->w = w; 6730 rs->h = h; 6731 6732 AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs); 6733 // global ref and rs are deleted in _ReshapeNoCheck 6734 6735 CATCH_BAD_ALLOC; 6736 } 6737 6738 6739 /* 6740 * Class: sun_awt_windows_WComponentPeer 6741 * Method: nativeHandleEvent 6742 * Signature: (Ljava/awt/AWTEvent;)V 6743 */ 6744 JNIEXPORT void JNICALL 6745 Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env, 6746 jobject self, 6747 jobject event) 6748 { 6749 TRY; 6750 6751 jobject selfGlobalRef = env->NewGlobalRef(self); 6752 jobject eventGlobalRef = env->NewGlobalRef(event); 6753 6754 NativeHandleEventStruct *nhes = new NativeHandleEventStruct; 6755 nhes->component = selfGlobalRef; 6756 nhes->event = eventGlobalRef; 6757 6758 AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes); 6759 // global refs and nhes are deleted in _NativeHandleEvent 6760 6761 CATCH_BAD_ALLOC; 6762 } 6763 6764 /* 6765 * Class: sun_awt_windows_WComponentPeer 6766 * Method: _dispose 6767 * Signature: ()V 6768 */ 6769 JNIEXPORT void JNICALL 6770 Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) 6771 { 6772 TRY_NO_HANG; 6773 6774 AwtObject::_Dispose(self); 6775 6776 CATCH_BAD_ALLOC; 6777 } 6778 6779 /* 6780 * Class: sun_awt_windows_WComponentPeer 6781 * Method: _setForeground 6782 * Signature: (I)V 6783 */ 6784 JNIEXPORT void JNICALL 6785 Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self, 6786 jint rgb) 6787 { 6788 TRY; 6789 6790 jobject selfGlobalRef = env->NewGlobalRef(self); 6791 6792 SetColorStruct *scs = new SetColorStruct; 6793 scs->component = selfGlobalRef; 6794 scs->rgb = rgb; 6795 6796 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs); 6797 // selfGlobalRef and scs are deleted in _SetForeground() 6798 6799 CATCH_BAD_ALLOC; 6800 } 6801 6802 /* 6803 * Class: sun_awt_windows_WComponentPeer 6804 * Method: _setBackground 6805 * Signature: (I)V 6806 */ 6807 JNIEXPORT void JNICALL 6808 Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self, 6809 jint rgb) 6810 { 6811 TRY; 6812 6813 jobject selfGlobalRef = env->NewGlobalRef(self); 6814 6815 SetColorStruct *scs = new SetColorStruct; 6816 scs->component = selfGlobalRef; 6817 scs->rgb = rgb; 6818 6819 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs); 6820 // selfGlobalRef and scs are deleted in _SetBackground() 6821 6822 CATCH_BAD_ALLOC; 6823 } 6824 6825 /* 6826 * Class: sun_awt_windows_WComponentPeer 6827 * Method: _setFont 6828 * Signature: (Ljava/awt/Font;)V 6829 */ 6830 JNIEXPORT void JNICALL 6831 Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self, 6832 jobject font) 6833 { 6834 TRY; 6835 6836 jobject selfGlobalRef = env->NewGlobalRef(self); 6837 jobject fontGlobalRef = env->NewGlobalRef(font); 6838 6839 SetFontStruct *sfs = new SetFontStruct; 6840 sfs->component = selfGlobalRef; 6841 sfs->font = fontGlobalRef; 6842 6843 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs); 6844 // global refs and sfs are deleted in _SetFont() 6845 6846 CATCH_BAD_ALLOC; 6847 } 6848 6849 /* 6850 * Class: sun_awt_windows_WComponentPeer 6851 * Method: focusGained 6852 * Signature: (Z) 6853 */ 6854 JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus 6855 (JNIEnv *env, jobject self, jboolean doSetFocus) 6856 { 6857 TRY; 6858 6859 jobject selfGlobalRef = env->NewGlobalRef(self); 6860 6861 SetFocusStruct *sfs = new SetFocusStruct; 6862 sfs->component = selfGlobalRef; 6863 sfs->doSetFocus = doSetFocus; 6864 6865 AwtToolkit::GetInstance().SyncCall( 6866 (void*(*)(void*))AwtComponent::_SetFocus, sfs); 6867 // global refs and self are deleted in _SetFocus 6868 6869 CATCH_BAD_ALLOC; 6870 } 6871 6872 /* 6873 * Class: sun_awt_windows_WComponentPeer 6874 * Method: start 6875 * Signature: ()V 6876 */ 6877 JNIEXPORT void JNICALL 6878 Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self) 6879 { 6880 TRY; 6881 6882 jobject selfGlobalRef = env->NewGlobalRef(self); 6883 6884 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef); 6885 // selfGlobalRef is deleted in _Start 6886 6887 CATCH_BAD_ALLOC; 6888 } 6889 6890 /* 6891 * Class: sun_awt_windows_WComponentPeer 6892 * Method: beginValidate 6893 * Signature: ()V 6894 */ 6895 JNIEXPORT void JNICALL 6896 Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self) 6897 { 6898 TRY; 6899 6900 jobject selfGlobalRef = env->NewGlobalRef(self); 6901 6902 AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef); 6903 // selfGlobalRef is deleted in _BeginValidate 6904 6905 CATCH_BAD_ALLOC; 6906 } 6907 6908 /* 6909 * Class: sun_awt_windows_WComponentPeer 6910 * Method: endValidate 6911 * Signature: ()V 6912 */ 6913 JNIEXPORT void JNICALL 6914 Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self) 6915 { 6916 TRY; 6917 6918 jobject selfGlobalRef = env->NewGlobalRef(self); 6919 6920 AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef); 6921 // selfGlobalRef is deleted in _EndValidate 6922 6923 CATCH_BAD_ALLOC; 6924 } 6925 6926 JNIEXPORT void JNICALL 6927 Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self) 6928 { 6929 TRY; 6930 6931 jobject selfGlobalRef = env->NewGlobalRef(self); 6932 6933 AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef); 6934 // selfGlobalRef is deleted in _UpdateWindow 6935 6936 CATCH_BAD_ALLOC; 6937 } 6938 6939 /* 6940 * Class: sun_awt_windows_WComponentPeer 6941 * Method: addNativeDropTarget 6942 * Signature: ()L 6943 */ 6944 6945 JNIEXPORT jlong JNICALL 6946 Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env, 6947 jobject self) 6948 { 6949 TRY; 6950 6951 jobject selfGlobalRef = env->NewGlobalRef(self); 6952 6953 return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall( 6954 (void*(*)(void*))AwtComponent::_AddNativeDropTarget, 6955 (void *)selfGlobalRef)); 6956 // selfGlobalRef is deleted in _AddNativeDropTarget 6957 6958 CATCH_BAD_ALLOC_RET(0); 6959 } 6960 6961 /* 6962 * Class: sun_awt_windows_WComponentPeer 6963 * Method: removeNativeDropTarget 6964 * Signature: ()V 6965 */ 6966 6967 JNIEXPORT void JNICALL 6968 Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env, 6969 jobject self) 6970 { 6971 TRY; 6972 6973 jobject selfGlobalRef = env->NewGlobalRef(self); 6974 6975 AwtToolkit::GetInstance().SyncCall( 6976 AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef); 6977 // selfGlobalRef is deleted in _RemoveNativeDropTarget 6978 6979 CATCH_BAD_ALLOC; 6980 } 6981 6982 /* 6983 * Class: sun_awt_windows_WComponentPeer 6984 * Method: getTargetGC 6985 * Signature: ()Ljava/awt/GraphicsConfiguration; 6986 */ 6987 JNIEXPORT jobject JNICALL 6988 Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis) 6989 { 6990 TRY; 6991 6992 jobject targetObj; 6993 jobject gc = 0; 6994 6995 targetObj = env->GetObjectField(theThis, AwtObject::targetID); 6996 DASSERT(targetObj); 6997 6998 gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID); 6999 return gc; 7000 7001 CATCH_BAD_ALLOC_RET(NULL); 7002 } 7003 7004 /* 7005 * Class: sun_awt_windows_WComponentPeer 7006 * Method: createPrintedPixels 7007 * Signature: (IIIIII)I[ 7008 */ 7009 JNIEXPORT jintArray JNICALL 7010 Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, 7011 jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha) 7012 { 7013 TRY; 7014 7015 jobject selfGlobalRef = env->NewGlobalRef(self); 7016 7017 CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct; 7018 cpps->component = selfGlobalRef; 7019 cpps->srcx = srcX; 7020 cpps->srcy = srcY; 7021 cpps->srcw = srcW; 7022 cpps->srch = srcH; 7023 cpps->alpha = alpha; 7024 7025 jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall( 7026 (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps); 7027 // selfGlobalRef and cpps are deleted in _CreatePrintedPixels 7028 if (globalRef != NULL) 7029 { 7030 jintArray localRef = (jintArray)env->NewLocalRef(globalRef); 7031 env->DeleteGlobalRef(globalRef); 7032 return localRef; 7033 } 7034 else 7035 { 7036 return NULL; 7037 } 7038 7039 CATCH_BAD_ALLOC_RET(NULL); 7040 } 7041 7042 /* 7043 * Class: sun_awt_windows_WComponentPeer 7044 * Method: nativeHandlesWheelScrolling 7045 * Signature: ()Z 7046 */ 7047 JNIEXPORT jboolean JNICALL 7048 Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env, 7049 jobject self) 7050 { 7051 TRY; 7052 7053 return (jboolean)AwtToolkit::GetInstance().SyncCall( 7054 (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling, 7055 env->NewGlobalRef(self)); 7056 // global ref is deleted in _NativeHandlesWheelScrolling 7057 7058 CATCH_BAD_ALLOC_RET(NULL); 7059 } 7060 7061 /* 7062 * Class: sun_awt_windows_WComponentPeer 7063 * Method: isObscured 7064 * Signature: ()Z 7065 */ 7066 JNIEXPORT jboolean JNICALL 7067 Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env, 7068 jobject self) 7069 { 7070 TRY; 7071 7072 jobject selfGlobalRef = env->NewGlobalRef(self); 7073 7074 return (jboolean)AwtToolkit::GetInstance().SyncCall( 7075 (void*(*)(void*))AwtComponent::_IsObscured, 7076 (void *)selfGlobalRef); 7077 // selfGlobalRef is deleted in _IsObscured 7078 7079 CATCH_BAD_ALLOC_RET(NULL); 7080 } 7081 7082 JNIEXPORT void JNICALL 7083 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) { 7084 TRY; 7085 7086 SetParentStruct * data = new SetParentStruct; 7087 data->component = env->NewGlobalRef(self); 7088 data->parentComp = env->NewGlobalRef(parent); 7089 7090 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetParent, data); 7091 // global refs and data are deleted in SetParent 7092 7093 CATCH_BAD_ALLOC; 7094 } 7095 7096 JNIEXPORT void JNICALL 7097 Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self, 7098 jint x1, jint y1, jint x2, jint y2, jobject region) 7099 { 7100 TRY; 7101 7102 SetRectangularShapeStruct * data = new SetRectangularShapeStruct; 7103 data->component = env->NewGlobalRef(self); 7104 data->x1 = x1; 7105 data->x2 = x2; 7106 data->y1 = y1; 7107 data->y2 = y2; 7108 if (region) { 7109 data->region = env->NewGlobalRef(region); 7110 } else { 7111 data->region = NULL; 7112 } 7113 7114 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data); 7115 // global refs and data are deleted in _SetRectangularShape 7116 7117 CATCH_BAD_ALLOC; 7118 } 7119 7120 JNIEXPORT void JNICALL 7121 Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above) 7122 { 7123 TRY; 7124 7125 SetZOrderStruct * data = new SetZOrderStruct; 7126 data->component = env->NewGlobalRef(self); 7127 data->above = above; 7128 7129 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data); 7130 // global refs and data are deleted in _SetLower 7131 7132 CATCH_BAD_ALLOC; 7133 } 7134 7135 } /* extern "C" */ 7136 7137 7138 /************************************************************************ 7139 * Diagnostic routines 7140 */ 7141 7142 #ifdef DEBUG 7143 7144 void AwtComponent::VerifyState() 7145 { 7146 if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { 7147 return; 7148 } 7149 7150 if (m_callbacksEnabled == FALSE) { 7151 /* Component is not fully setup yet. */ 7152 return; 7153 } 7154 7155 /* Get target bounds. */ 7156 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 7157 if (env->PushLocalFrame(10) < 0) 7158 return; 7159 7160 jobject target = GetTarget(env); 7161 7162 jint x = env->GetIntField(target, AwtComponent::xID); 7163 jint y = env->GetIntField(target, AwtComponent::yID); 7164 jint width = env->GetIntField(target, AwtComponent::widthID); 7165 jint height = env->GetIntField(target, AwtComponent::heightID); 7166 7167 /* Convert target origin to absolute coordinates */ 7168 while (TRUE) { 7169 7170 jobject parent = env->GetObjectField(target, AwtComponent::parentID); 7171 if (parent == NULL) { 7172 break; 7173 } 7174 x += env->GetIntField(parent, AwtComponent::xID); 7175 y += env->GetIntField(parent, AwtComponent::yID); 7176 7177 /* If this component has insets, factor them in, but ignore 7178 * top-level windows. 7179 */ 7180 jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID); 7181 if (parent2 != NULL) { 7182 jobject peer = GetPeerForTarget(env, parent); 7183 if (peer != NULL && 7184 JNU_IsInstanceOfByName(env, peer, 7185 "sun/awt/windows/WPanelPeer") > 0) { 7186 jobject insets = 7187 JNU_CallMethodByName(env, NULL, peer,"insets", 7188 "()Ljava/awt/Insets;").l; 7189 x += (env)->GetIntField(insets, AwtInsets::leftID); 7190 y += (env)->GetIntField(insets, AwtInsets::topID); 7191 } 7192 } 7193 env->DeleteLocalRef(target); 7194 target = parent; 7195 } 7196 7197 // Test whether component's bounds match the native window's 7198 RECT rect; 7199 VERIFY(::GetWindowRect(GetHWnd(), &rect)); 7200 #if 0 7201 DASSERT( (x == rect.left) && 7202 (y == rect.top) && 7203 (width == (rect.right-rect.left)) && 7204 (height == (rect.bottom-rect.top)) ); 7205 #else 7206 BOOL fSizeValid = ( (x == rect.left) && 7207 (y == rect.top) && 7208 (width == (rect.right-rect.left)) && 7209 (height == (rect.bottom-rect.top)) ); 7210 #endif 7211 7212 // See if visible state matches 7213 BOOL wndVisible = ::IsWindowVisible(GetHWnd()); 7214 jboolean targetVisible; 7215 // To avoid possibly running client code on the toolkit thread, don't 7216 // do the following check if we're running on the toolkit thread. 7217 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7218 targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env), 7219 "isShowing", "()Z").z; 7220 DASSERT(!safe_ExceptionOccurred(env)); 7221 } else { 7222 targetVisible = wndVisible ? 1 : 0; 7223 } 7224 #if 0 7225 DASSERT( (targetVisible && wndVisible) || 7226 (!targetVisible && !wndVisible) ); 7227 #else 7228 BOOL fVisibleValid = ( (targetVisible && wndVisible) || 7229 (!targetVisible && !wndVisible) ); 7230 #endif 7231 7232 // Check enabled state 7233 BOOL wndEnabled = ::IsWindowEnabled(GetHWnd()); 7234 jboolean enabled = (jboolean)env->GetBooleanField(target, 7235 AwtComponent::enabledID); 7236 #if 0 7237 DASSERT( (enabled && wndEnabled) || 7238 (!enabled && !wndEnabled) ); 7239 #else 7240 BOOL fEnabledValid = ((enabled && wndEnabled) || 7241 (!(enabled && !wndEnabled) )); 7242 7243 if (!fSizeValid || !fVisibleValid || !fEnabledValid) { 7244 printf("AwtComponent::ValidateState() failed:\n"); 7245 // To avoid possibly running client code on the toolkit thread, don't 7246 // do the following call if we're running on the toolkit thread. 7247 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7248 jstring targetStr = 7249 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), 7250 "getName", 7251 "()Ljava/lang/String;").l; 7252 DASSERT(!safe_ExceptionOccurred(env)); 7253 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 7254 printf("\t%S\n", targetStrW); 7255 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 7256 } 7257 printf("\twas: [%d,%d,%dx%d]\n", x, y, width, height); 7258 if (!fSizeValid) { 7259 printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top, 7260 rect.right-rect.left, rect.bottom-rect.top); 7261 } 7262 if (!fVisibleValid) { 7263 printf("\tshould be: %s\n", 7264 (targetVisible) ? "visible" : "hidden"); 7265 } 7266 if (!fEnabledValid) { 7267 printf("\tshould be: %s\n", 7268 enabled ? "enabled" : "disabled"); 7269 } 7270 } 7271 #endif 7272 env->PopLocalFrame(0); 7273 } 7274 #endif //DEBUG 7275 7276 // Methods for globally managed DC list 7277 7278 /** 7279 * Add a new DC to the DC list for this component. 7280 */ 7281 void DCList::AddDC(HDC hDC, HWND hWnd) 7282 { 7283 DCItem *newItem = new DCItem; 7284 newItem->hDC = hDC; 7285 newItem->hWnd = hWnd; 7286 AddDCItem(newItem); 7287 } 7288 7289 void DCList::AddDCItem(DCItem *newItem) 7290 { 7291 listLock.Enter(); 7292 newItem->next = head; 7293 head = newItem; 7294 listLock.Leave(); 7295 } 7296 7297 /** 7298 * Given a DC and window handle, remove the DC from the DC list 7299 * and return TRUE if it exists on the current list. Otherwise 7300 * return FALSE. 7301 * A DC may not exist on the list because it has already 7302 * been released elsewhere (for example, the window 7303 * destruction process may release a DC while a rendering 7304 * thread may also want to release a DC when it notices that 7305 * its DC is obsolete for the current window). 7306 */ 7307 DCItem *DCList::RemoveDC(HDC hDC, HWND hWnd) 7308 { 7309 listLock.Enter(); 7310 DCItem **prevPtrPtr = &head; 7311 DCItem *listPtr = head; 7312 while (listPtr) { 7313 DCItem *nextPtr = listPtr->next; 7314 if (listPtr->hDC == hDC && listPtr->hWnd == hWnd) { 7315 *prevPtrPtr = nextPtr; 7316 break; 7317 } 7318 prevPtrPtr = &listPtr->next; 7319 listPtr = nextPtr; 7320 } 7321 listLock.Leave(); 7322 return listPtr; 7323 } 7324 7325 /** 7326 * Remove all DCs from the DC list which are associated with 7327 * the same window as hWnd. Return the list of those 7328 * DC's to the caller (which will then probably want to 7329 * call ReleaseDC() for the returned DCs). 7330 */ 7331 DCItem *DCList::RemoveAllDCs(HWND hWnd) 7332 { 7333 listLock.Enter(); 7334 DCItem **prevPtrPtr = &head; 7335 DCItem *listPtr = head; 7336 DCItem *newListPtr = NULL; 7337 BOOL ret = FALSE; 7338 while (listPtr) { 7339 DCItem *nextPtr = listPtr->next; 7340 if (listPtr->hWnd == hWnd) { 7341 *prevPtrPtr = nextPtr; 7342 listPtr->next = newListPtr; 7343 newListPtr = listPtr; 7344 } else { 7345 prevPtrPtr = &listPtr->next; 7346 } 7347 listPtr = nextPtr; 7348 } 7349 listLock.Leave(); 7350 return newListPtr; 7351 } 7352 7353 7354 /** 7355 * Realize palettes of all existing HDC objects 7356 */ 7357 void DCList::RealizePalettes(int screen) 7358 { 7359 listLock.Enter(); 7360 DCItem *listPtr = head; 7361 while (listPtr) { 7362 AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen); 7363 listPtr = listPtr->next; 7364 } 7365 listLock.Leave(); 7366 } 7367 7368 void MoveDCToPassiveList(HDC hDC, HWND hWnd) { 7369 DCItem *removedDC; 7370 if ((removedDC = activeDCList.RemoveDC(hDC, hWnd)) != NULL) { 7371 passiveDCList.AddDCItem(removedDC); 7372 } 7373 } 7374 7375 void ReleaseDCList(HWND hwnd, DCList &list) { 7376 DCItem *removedDCs = list.RemoveAllDCs(hwnd); 7377 while (removedDCs) { 7378 DCItem *tmpDCList = removedDCs; 7379 DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC); 7380 int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC); 7381 VERIFY(retValue != 0); 7382 if (retValue != 0) { 7383 // Valid ReleaseDC call; need to decrement GDI object counter 7384 AwtGDIObject::Decrement(); 7385 } 7386 removedDCs = removedDCs->next; 7387 delete tmpDCList; 7388 } 7389 } 7390