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